diff options
33 files changed, 746 insertions, 412 deletions
diff --git a/.travis.yml b/.travis.yml index 8d10a43f0..940435172 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -4,42 +4,49 @@ before_cache: | |||
4 | - rm -fr ./target/debug/{deps,.fingerprint}/{*ra_*,*test*,*tools*,*gen_lsp*,*thread_worker*} | 4 | - rm -fr ./target/debug/{deps,.fingerprint}/{*ra_*,*test*,*tools*,*gen_lsp*,*thread_worker*} |
5 | - rm -f ./target/.rustc_info.json | 5 | - rm -f ./target/.rustc_info.json |
6 | 6 | ||
7 | build: &rust_build | ||
8 | language: rust | ||
9 | rust: stable | ||
10 | script: | ||
11 | - rustup component add rustfmt | ||
12 | - rustup component add rust-src | ||
13 | - cargo test --no-run # let's measure compile time separately | ||
14 | - cargo test | ||
15 | env: | ||
16 | - RUSTFLAGS="-D warnings", CARGO_INCREMENTAL=0 | ||
17 | |||
18 | matrix: | 7 | matrix: |
19 | include: | 8 | include: |
20 | - os: linux | 9 | - os: linux |
21 | <<: *rust_build | 10 | language: rust |
22 | - language: node_js | 11 | rust: stable |
23 | node_js: node | ||
24 | before_script: false | ||
25 | script: | 12 | script: |
26 | - cd editors/code && npm ci && npm run travis | 13 | - rustup component add rustfmt |
14 | - rustup component add rust-src | ||
15 | - cargo test --no-run # let's measure compile time separately | ||
16 | - cargo test | ||
17 | env: | ||
18 | - RUSTFLAGS="-D warnings", CARGO_INCREMENTAL=0 | ||
27 | 19 | ||
28 | - os: windows | 20 | - os: linux |
29 | if: branch = master AND type = push | 21 | if: branch = master AND type = push |
30 | before_script: | 22 | before_script: |
31 | - dos2unix ./crates/ra_syntax/tests/data/parser/**/*.txt | 23 | - DEPLOY_DOCS=1 |
32 | - dos2unix ./crates/ra_syntax/tests/data/parser/**/*.rs | 24 | language: rust |
33 | <<: *rust_build | 25 | rust: stable |
26 | script: | ||
27 | - cargo doc --all --no-deps | ||
28 | env: | ||
29 | - RUSTFLAGS="-D warnings", CARGO_INCREMENTAL=0 | ||
34 | 30 | ||
35 | allow_failures: | 31 | - language: node_js |
36 | # Because Travis-Windows-Rust can be flaky | 32 | node_js: node |
37 | # We still support Windows and want the tests to be succeeding, | 33 | before_script: false |
38 | # but there are too many spurious failures | 34 | script: |
39 | - os: windows | 35 | - cd editors/code && npm ci && npm run travis |
40 | 36 | ||
41 | branches: | 37 | branches: |
42 | only: | 38 | only: |
43 | - staging | 39 | - staging |
44 | - master | 40 | - master |
45 | - trying | 41 | - trying |
42 | |||
43 | deploy: | ||
44 | provider: pages | ||
45 | skip-cleanup: true | ||
46 | github-token: $DOCS_TOKEN # Set in the settings page of your repository, as a secure variable | ||
47 | keep-history: true | ||
48 | local-dir: target/doc | ||
49 | branch: gh-pages | ||
50 | on: | ||
51 | branch: master | ||
52 | condition: $DEPLOY_DOCS = 1 | ||
diff --git a/Cargo.lock b/Cargo.lock index 1b5de271e..3bc5f261c 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -76,15 +76,15 @@ dependencies = [ | |||
76 | 76 | ||
77 | [[package]] | 77 | [[package]] |
78 | name = "bit-set" | 78 | name = "bit-set" |
79 | version = "0.5.0" | 79 | version = "0.5.1" |
80 | source = "registry+https://github.com/rust-lang/crates.io-index" | 80 | source = "registry+https://github.com/rust-lang/crates.io-index" |
81 | dependencies = [ | 81 | dependencies = [ |
82 | "bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", | 82 | "bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", |
83 | ] | 83 | ] |
84 | 84 | ||
85 | [[package]] | 85 | [[package]] |
86 | name = "bit-vec" | 86 | name = "bit-vec" |
87 | version = "0.5.0" | 87 | version = "0.5.1" |
88 | source = "registry+https://github.com/rust-lang/crates.io-index" | 88 | source = "registry+https://github.com/rust-lang/crates.io-index" |
89 | 89 | ||
90 | [[package]] | 90 | [[package]] |
@@ -118,7 +118,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
118 | 118 | ||
119 | [[package]] | 119 | [[package]] |
120 | name = "cargo_metadata" | 120 | name = "cargo_metadata" |
121 | version = "0.7.3" | 121 | version = "0.7.4" |
122 | source = "registry+https://github.com/rust-lang/crates.io-index" | 122 | source = "registry+https://github.com/rust-lang/crates.io-index" |
123 | dependencies = [ | 123 | dependencies = [ |
124 | "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", | 124 | "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -359,11 +359,11 @@ dependencies = [ | |||
359 | 359 | ||
360 | [[package]] | 360 | [[package]] |
361 | name = "flexi_logger" | 361 | name = "flexi_logger" |
362 | version = "0.11.1" | 362 | version = "0.11.2" |
363 | source = "registry+https://github.com/rust-lang/crates.io-index" | 363 | source = "registry+https://github.com/rust-lang/crates.io-index" |
364 | dependencies = [ | 364 | dependencies = [ |
365 | "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 365 | "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
366 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", | 366 | "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
367 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 367 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
368 | "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | 368 | "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", |
369 | ] | 369 | ] |
@@ -444,6 +444,11 @@ version = "0.2.11" | |||
444 | source = "registry+https://github.com/rust-lang/crates.io-index" | 444 | source = "registry+https://github.com/rust-lang/crates.io-index" |
445 | 445 | ||
446 | [[package]] | 446 | [[package]] |
447 | name = "glob" | ||
448 | version = "0.3.0" | ||
449 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
450 | |||
451 | [[package]] | ||
447 | name = "heck" | 452 | name = "heck" |
448 | version = "0.3.1" | 453 | version = "0.3.1" |
449 | source = "registry+https://github.com/rust-lang/crates.io-index" | 454 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -503,7 +508,7 @@ dependencies = [ | |||
503 | 508 | ||
504 | [[package]] | 509 | [[package]] |
505 | name = "insta" | 510 | name = "insta" |
506 | version = "0.7.1" | 511 | version = "0.7.4" |
507 | source = "registry+https://github.com/rust-lang/crates.io-index" | 512 | source = "registry+https://github.com/rust-lang/crates.io-index" |
508 | dependencies = [ | 513 | dependencies = [ |
509 | "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 514 | "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -518,7 +523,7 @@ dependencies = [ | |||
518 | "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", | 523 | "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", |
519 | "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", | 524 | "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", |
520 | "serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", | 525 | "serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", |
521 | "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 526 | "uuid 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |
522 | ] | 527 | ] |
523 | 528 | ||
524 | [[package]] | 529 | [[package]] |
@@ -589,9 +594,6 @@ dependencies = [ | |||
589 | name = "lazy_static" | 594 | name = "lazy_static" |
590 | version = "1.3.0" | 595 | version = "1.3.0" |
591 | source = "registry+https://github.com/rust-lang/crates.io-index" | 596 | source = "registry+https://github.com/rust-lang/crates.io-index" |
592 | dependencies = [ | ||
593 | "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
594 | ] | ||
595 | 597 | ||
596 | [[package]] | 598 | [[package]] |
597 | name = "lazycell" | 599 | name = "lazycell" |
@@ -605,7 +607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
605 | 607 | ||
606 | [[package]] | 608 | [[package]] |
607 | name = "linked-hash-map" | 609 | name = "linked-hash-map" |
608 | version = "0.5.1" | 610 | version = "0.5.2" |
609 | source = "registry+https://github.com/rust-lang/crates.io-index" | 611 | source = "registry+https://github.com/rust-lang/crates.io-index" |
610 | 612 | ||
611 | [[package]] | 613 | [[package]] |
@@ -855,10 +857,10 @@ dependencies = [ | |||
855 | 857 | ||
856 | [[package]] | 858 | [[package]] |
857 | name = "proptest" | 859 | name = "proptest" |
858 | version = "0.9.1" | 860 | version = "0.9.2" |
859 | source = "registry+https://github.com/rust-lang/crates.io-index" | 861 | source = "registry+https://github.com/rust-lang/crates.io-index" |
860 | dependencies = [ | 862 | dependencies = [ |
861 | "bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", | 863 | "bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", |
862 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", | 864 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", |
863 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 865 | "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
864 | "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | 866 | "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -922,14 +924,13 @@ version = "0.1.0" | |||
922 | dependencies = [ | 924 | dependencies = [ |
923 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", | 925 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", |
924 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 926 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
925 | "flexi_logger 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", | 927 | "flexi_logger 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", |
926 | "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | 928 | "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |
927 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | 929 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
928 | "ra_batch 0.1.0", | 930 | "ra_batch 0.1.0", |
929 | "ra_db 0.1.0", | 931 | "ra_db 0.1.0", |
930 | "ra_hir 0.1.0", | 932 | "ra_hir 0.1.0", |
931 | "ra_ide_api 0.1.0", | 933 | "ra_ide_api 0.1.0", |
932 | "ra_ide_api_light 0.1.0", | ||
933 | "ra_syntax 0.1.0", | 934 | "ra_syntax 0.1.0", |
934 | "tools 0.1.0", | 935 | "tools 0.1.0", |
935 | ] | 936 | ] |
@@ -961,8 +962,8 @@ version = "0.1.0" | |||
961 | dependencies = [ | 962 | dependencies = [ |
962 | "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", | 963 | "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", |
963 | "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | 964 | "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |
964 | "flexi_logger 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", | 965 | "flexi_logger 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", |
965 | "insta 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 966 | "insta 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", |
966 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | 967 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
967 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 968 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
968 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 969 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -981,19 +982,18 @@ name = "ra_ide_api" | |||
981 | version = "0.1.0" | 982 | version = "0.1.0" |
982 | dependencies = [ | 983 | dependencies = [ |
983 | "fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", | 984 | "fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", |
984 | "insta 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 985 | "insta 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", |
985 | "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | 986 | "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
986 | "jemalloc-ctl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 987 | "jemalloc-ctl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
987 | "jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", | 988 | "jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", |
988 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | 989 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
989 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 990 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
990 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 991 | "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", |
991 | "proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", | 992 | "proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", |
992 | "ra_assists 0.1.0", | 993 | "ra_assists 0.1.0", |
993 | "ra_db 0.1.0", | 994 | "ra_db 0.1.0", |
994 | "ra_fmt 0.1.0", | 995 | "ra_fmt 0.1.0", |
995 | "ra_hir 0.1.0", | 996 | "ra_hir 0.1.0", |
996 | "ra_ide_api_light 0.1.0", | ||
997 | "ra_syntax 0.1.0", | 997 | "ra_syntax 0.1.0", |
998 | "ra_text_edit 0.1.0", | 998 | "ra_text_edit 0.1.0", |
999 | "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", | 999 | "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1005,29 +1005,13 @@ dependencies = [ | |||
1005 | ] | 1005 | ] |
1006 | 1006 | ||
1007 | [[package]] | 1007 | [[package]] |
1008 | name = "ra_ide_api_light" | ||
1009 | version = "0.1.0" | ||
1010 | dependencies = [ | ||
1011 | "insta 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1012 | "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1013 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1014 | "proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1015 | "ra_fmt 0.1.0", | ||
1016 | "ra_syntax 0.1.0", | ||
1017 | "ra_text_edit 0.1.0", | ||
1018 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1019 | "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1020 | "test_utils 0.1.0", | ||
1021 | ] | ||
1022 | |||
1023 | [[package]] | ||
1024 | name = "ra_lsp_server" | 1008 | name = "ra_lsp_server" |
1025 | version = "0.1.0" | 1009 | version = "0.1.0" |
1026 | dependencies = [ | 1010 | dependencies = [ |
1027 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1011 | "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1028 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1012 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
1029 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1013 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
1030 | "flexi_logger 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1014 | "flexi_logger 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1031 | "gen_lsp_server 0.1.0", | 1015 | "gen_lsp_server 0.1.0", |
1032 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1016 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1033 | "lsp-types 0.56.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1017 | "lsp-types 0.56.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1070,7 +1054,7 @@ dependencies = [ | |||
1070 | name = "ra_project_model" | 1054 | name = "ra_project_model" |
1071 | version = "0.1.0" | 1055 | version = "0.1.0" |
1072 | dependencies = [ | 1056 | dependencies = [ |
1073 | "cargo_metadata 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1057 | "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", |
1074 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1058 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
1075 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1059 | "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1076 | "ra_arena 0.1.0", | 1060 | "ra_arena 0.1.0", |
@@ -1105,7 +1089,7 @@ dependencies = [ | |||
1105 | name = "ra_text_edit" | 1089 | name = "ra_text_edit" |
1106 | version = "0.1.0" | 1090 | version = "0.1.0" |
1107 | dependencies = [ | 1091 | dependencies = [ |
1108 | "proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1092 | "proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1109 | "test_utils 0.1.0", | 1093 | "test_utils 0.1.0", |
1110 | "text_unit 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1094 | "text_unit 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1111 | ] | 1095 | ] |
@@ -1436,7 +1420,7 @@ version = "0.8.8" | |||
1436 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1437 | dependencies = [ | 1421 | dependencies = [ |
1438 | "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1422 | "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1439 | "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1423 | "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1440 | "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", | 1424 | "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", |
1441 | "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1425 | "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1442 | ] | 1426 | ] |
@@ -1479,11 +1463,6 @@ dependencies = [ | |||
1479 | ] | 1463 | ] |
1480 | 1464 | ||
1481 | [[package]] | 1465 | [[package]] |
1482 | name = "spin" | ||
1483 | version = "0.5.0" | ||
1484 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1485 | |||
1486 | [[package]] | ||
1487 | name = "stable_deref_trait" | 1466 | name = "stable_deref_trait" |
1488 | version = "1.1.1" | 1467 | version = "1.1.1" |
1489 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1776,7 +1755,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1776 | 1755 | ||
1777 | [[package]] | 1756 | [[package]] |
1778 | name = "uuid" | 1757 | name = "uuid" |
1779 | version = "0.7.2" | 1758 | version = "0.7.3" |
1780 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1759 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1781 | dependencies = [ | 1760 | dependencies = [ |
1782 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1761 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1854,7 +1833,7 @@ name = "yaml-rust" | |||
1854 | version = "0.4.3" | 1833 | version = "0.4.3" |
1855 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1834 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1856 | dependencies = [ | 1835 | dependencies = [ |
1857 | "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1836 | "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1858 | ] | 1837 | ] |
1859 | 1838 | ||
1860 | [metadata] | 1839 | [metadata] |
@@ -1867,14 +1846,14 @@ dependencies = [ | |||
1867 | "checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" | 1846 | "checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" |
1868 | "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" | 1847 | "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" |
1869 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" | 1848 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" |
1870 | "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a" | 1849 | "checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" |
1871 | "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf" | 1850 | "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" |
1872 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" | 1851 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" |
1873 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" | 1852 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" |
1874 | "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" | 1853 | "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" |
1875 | "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" | 1854 | "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" |
1876 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" | 1855 | "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" |
1877 | "checksum cargo_metadata 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bc796c7161c220089dfc7159e13324979181532850a237576b8fb907dd087c0d" | 1856 | "checksum cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "178d62b240c34223f265a4c1e275e37d62da163d421fc8d7f7e3ee340f803c57" |
1878 | "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" | 1857 | "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" |
1879 | "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" | 1858 | "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" |
1880 | "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" | 1859 | "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" |
@@ -1903,7 +1882,7 @@ dependencies = [ | |||
1903 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" | 1882 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" |
1904 | "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" | 1883 | "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" |
1905 | "checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646" | 1884 | "checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646" |
1906 | "checksum flexi_logger 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7878fc9e06c948c6f9cddf571758e0c44786a509e646a094ef13ade3b1aab7" | 1885 | "checksum flexi_logger 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "005c01dd6942ca46283b7304d14c6d04ec2c87a62f6e62e17c06fb812a574f4a" |
1907 | "checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" | 1886 | "checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" |
1908 | "checksum fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c4bbbf71584aeed076100b5665ac14e3d85eeb31fdbb45fbd41ef9a682b5ec05" | 1887 | "checksum fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c4bbbf71584aeed076100b5665ac14e3d85eeb31fdbb45fbd41ef9a682b5ec05" |
1909 | "checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874" | 1888 | "checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874" |
@@ -1913,6 +1892,7 @@ dependencies = [ | |||
1913 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" | 1892 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" |
1914 | "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" | 1893 | "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" |
1915 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" | 1894 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" |
1895 | "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" | ||
1916 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" | 1896 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" |
1917 | "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" | 1897 | "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" |
1918 | "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" | 1898 | "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" |
@@ -1920,7 +1900,7 @@ dependencies = [ | |||
1920 | "checksum indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c60da1c9abea75996b70a931bba6c750730399005b61ccd853cee50ef3d0d0c" | 1900 | "checksum indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c60da1c9abea75996b70a931bba6c750730399005b61ccd853cee50ef3d0d0c" |
1921 | "checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" | 1901 | "checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" |
1922 | "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" | 1902 | "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" |
1923 | "checksum insta 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be9f00370d23dc7bd32a4d4506b1a14fb922fa39c576c3300fd25ce5b5dab18f" | 1903 | "checksum insta 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "03e7d88a87d342ce8bd698516151be43e6eb2e84b683db528696cb4a382f734a" |
1924 | "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" | 1904 | "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" |
1925 | "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" | 1905 | "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" |
1926 | "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" | 1906 | "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" |
@@ -1932,7 +1912,7 @@ dependencies = [ | |||
1932 | "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" | 1912 | "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" |
1933 | "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" | 1913 | "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" |
1934 | "checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" | 1914 | "checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" |
1935 | "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" | 1915 | "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" |
1936 | "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" | 1916 | "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" |
1937 | "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" | 1917 | "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" |
1938 | "checksum lsp-types 0.56.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31954f2cf354421e6f99a48fdcfd5c3113c675a0db311960ffdac0b8d45cf09c" | 1918 | "checksum lsp-types 0.56.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31954f2cf354421e6f99a48fdcfd5c3113c675a0db311960ffdac0b8d45cf09c" |
@@ -1960,7 +1940,7 @@ dependencies = [ | |||
1960 | "checksum pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646" | 1940 | "checksum pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646" |
1961 | "checksum pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e" | 1941 | "checksum pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e" |
1962 | "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" | 1942 | "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" |
1963 | "checksum proptest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea66c78d75f2c6e9f304269eaef90899798daecc69f1a625d5a3dd793ff3522" | 1943 | "checksum proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24f5844db2f839e97e3021980975f6ebf8691d9b9b2ca67ed3feb38dc3edb52c" |
1964 | "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" | 1944 | "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" |
1965 | "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" | 1945 | "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" |
1966 | "checksum ra_vfs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1839e4e003d865b58b8b6c231aae6c463dfcd01bfbbddffbdb7662a7b5a627" | 1946 | "checksum ra_vfs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1839e4e003d865b58b8b6c231aae6c463dfcd01bfbbddffbdb7662a7b5a627" |
@@ -2004,7 +1984,6 @@ dependencies = [ | |||
2004 | "checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" | 1984 | "checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" |
2005 | "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" | 1985 | "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" |
2006 | "checksum smol_str 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9af1035bc5d742ab6b7ab16713e41cc2ffe78cb474f6f43cd696b2d16052007e" | 1986 | "checksum smol_str 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9af1035bc5d742ab6b7ab16713e41cc2ffe78cb474f6f43cd696b2d16052007e" |
2007 | "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" | ||
2008 | "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" | 1987 | "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" |
2009 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" | 1988 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" |
2010 | "checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" | 1989 | "checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" |
@@ -2038,7 +2017,7 @@ dependencies = [ | |||
2038 | "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" | 2017 | "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" |
2039 | "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" | 2018 | "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" |
2040 | "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" | 2019 | "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" |
2041 | "checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768" | 2020 | "checksum uuid 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "600ef8213e9f8a0ac1f876e470e90780ae0478eabce7f76aff41b0f4ef0fd5c0" |
2042 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" | 2021 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" |
2043 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" | 2022 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" |
2044 | "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" | 2023 | "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" |
diff --git a/crates/ra_assists/src/flip_eq_operands.rs b/crates/ra_assists/src/flip_eq_operands.rs new file mode 100644 index 000000000..df0bb689d --- /dev/null +++ b/crates/ra_assists/src/flip_eq_operands.rs | |||
@@ -0,0 +1,86 @@ | |||
1 | use hir::db::HirDatabase; | ||
2 | use ra_syntax::ast::{AstNode, BinExpr, BinOp}; | ||
3 | |||
4 | use crate::{AssistCtx, Assist, AssistId}; | ||
5 | |||
6 | pub(crate) fn flip_eq_operands(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | ||
7 | let expr = ctx.node_at_offset::<BinExpr>()?; | ||
8 | let lhs = expr.lhs()?.syntax(); | ||
9 | let rhs = expr.rhs()?.syntax(); | ||
10 | let op_range = expr.op()?.range(); | ||
11 | let cursor_in_range = ctx.frange.range.is_subrange(&op_range); | ||
12 | let allowed_ops = [BinOp::EqualityTest, BinOp::NegatedEqualityTest]; | ||
13 | let expr_op = expr.op_kind()?; | ||
14 | if !cursor_in_range || !allowed_ops.iter().any(|o| *o == expr_op) { | ||
15 | return None; | ||
16 | } | ||
17 | ctx.add_action(AssistId("flip_eq_operands"), "flip equality operands", |edit| { | ||
18 | edit.target(op_range); | ||
19 | edit.replace(lhs.range(), rhs.text()); | ||
20 | edit.replace(rhs.range(), lhs.text()); | ||
21 | }); | ||
22 | |||
23 | ctx.build() | ||
24 | } | ||
25 | |||
26 | #[cfg(test)] | ||
27 | mod tests { | ||
28 | use super::*; | ||
29 | |||
30 | use crate::helpers::{check_assist, check_assist_target}; | ||
31 | |||
32 | #[test] | ||
33 | fn flip_eq_operands_for_simple_stmt() { | ||
34 | check_assist( | ||
35 | flip_eq_operands, | ||
36 | "fn f() { let res = 1 ==<|> 2; }", | ||
37 | "fn f() { let res = 2 ==<|> 1; }", | ||
38 | ) | ||
39 | } | ||
40 | |||
41 | #[test] | ||
42 | fn flip_neq_operands_for_simple_stmt() { | ||
43 | check_assist( | ||
44 | flip_eq_operands, | ||
45 | "fn f() { let res = 1 !=<|> 2; }", | ||
46 | "fn f() { let res = 2 !=<|> 1; }", | ||
47 | ) | ||
48 | } | ||
49 | |||
50 | #[test] | ||
51 | fn flip_eq_operands_for_complex_stmt() { | ||
52 | check_assist( | ||
53 | flip_eq_operands, | ||
54 | "fn f() { let res = (1 + 1) ==<|> (2 + 2); }", | ||
55 | "fn f() { let res = (2 + 2) ==<|> (1 + 1); }", | ||
56 | ) | ||
57 | } | ||
58 | |||
59 | #[test] | ||
60 | fn flip_eq_operands_in_match_expr() { | ||
61 | check_assist( | ||
62 | flip_eq_operands, | ||
63 | r#" | ||
64 | fn dyn_eq(&self, other: &dyn Diagnostic) -> bool { | ||
65 | match other.downcast_ref::<Self>() { | ||
66 | None => false, | ||
67 | Some(it) => it ==<|> self, | ||
68 | } | ||
69 | } | ||
70 | "#, | ||
71 | r#" | ||
72 | fn dyn_eq(&self, other: &dyn Diagnostic) -> bool { | ||
73 | match other.downcast_ref::<Self>() { | ||
74 | None => false, | ||
75 | Some(it) => self ==<|> it, | ||
76 | } | ||
77 | } | ||
78 | "#, | ||
79 | ) | ||
80 | } | ||
81 | |||
82 | #[test] | ||
83 | fn flip_eq_operands_target() { | ||
84 | check_assist_target(flip_eq_operands, "fn f() { let res = 1 ==<|> 2; }", "==") | ||
85 | } | ||
86 | } | ||
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index 378470ac8..2e47b5215 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -88,6 +88,7 @@ where | |||
88 | mod add_derive; | 88 | mod add_derive; |
89 | mod add_impl; | 89 | mod add_impl; |
90 | mod flip_comma; | 90 | mod flip_comma; |
91 | mod flip_eq_operands; | ||
91 | mod change_visibility; | 92 | mod change_visibility; |
92 | mod fill_match_arms; | 93 | mod fill_match_arms; |
93 | mod fill_struct_fields; | 94 | mod fill_struct_fields; |
@@ -107,6 +108,7 @@ fn all_assists<DB: HirDatabase>() -> &'static [fn(AssistCtx<DB>) -> Option<Assis | |||
107 | fill_match_arms::fill_match_arms, | 108 | fill_match_arms::fill_match_arms, |
108 | fill_struct_fields::fill_struct_fields, | 109 | fill_struct_fields::fill_struct_fields, |
109 | flip_comma::flip_comma, | 110 | flip_comma::flip_comma, |
111 | flip_eq_operands::flip_eq_operands, | ||
110 | introduce_variable::introduce_variable, | 112 | introduce_variable::introduce_variable, |
111 | replace_if_let_with_match::replace_if_let_with_match, | 113 | replace_if_let_with_match::replace_if_let_with_match, |
112 | split_import::split_import, | 114 | split_import::split_import, |
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index 4c666f556..467628236 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml | |||
@@ -14,7 +14,6 @@ indicatif = "0.11.0" | |||
14 | 14 | ||
15 | ra_syntax = { path = "../ra_syntax" } | 15 | ra_syntax = { path = "../ra_syntax" } |
16 | ra_ide_api = { path = "../ra_ide_api" } | 16 | ra_ide_api = { path = "../ra_ide_api" } |
17 | ra_ide_api_light = { path = "../ra_ide_api_light" } | ||
18 | tools = { path = "../tools" } | 17 | tools = { path = "../tools" } |
19 | ra_batch = { path = "../ra_batch" } | 18 | ra_batch = { path = "../ra_batch" } |
20 | ra_hir = { path = "../ra_hir" } | 19 | ra_hir = { path = "../ra_hir" } |
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 5285f1f28..11f5541eb 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -5,7 +5,7 @@ use std::{fs, io::Read, path::Path, time::Instant}; | |||
5 | use clap::{App, Arg, SubCommand}; | 5 | use clap::{App, Arg, SubCommand}; |
6 | use join_to_string::join; | 6 | use join_to_string::join; |
7 | use ra_ide_api::{Analysis, FileRange}; | 7 | use ra_ide_api::{Analysis, FileRange}; |
8 | use ra_ide_api_light::file_structure; | 8 | use ra_ide_api::file_structure; |
9 | use ra_syntax::{SourceFile, TextRange, TreeArc, AstNode}; | 9 | use ra_syntax::{SourceFile, TextRange, TreeArc, AstNode}; |
10 | use tools::collect_tests; | 10 | use tools::collect_tests; |
11 | use flexi_logger::Logger; | 11 | use flexi_logger::Logger; |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 45fa4cd11..5437133b8 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -1,8 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use relative_path::RelativePathBuf; | ||
4 | use ra_db::{CrateId, SourceRootId, Edition}; | 3 | use ra_db::{CrateId, SourceRootId, Edition}; |
5 | use ra_syntax::{ast::self, TreeArc, SyntaxNode}; | 4 | use ra_syntax::{ast::self, TreeArc}; |
6 | 5 | ||
7 | use crate::{ | 6 | use crate::{ |
8 | Name, ScopesWithSourceMap, Ty, HirFileId, | 7 | Name, ScopesWithSourceMap, Ty, HirFileId, |
@@ -17,6 +16,7 @@ use crate::{ | |||
17 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, | 16 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, |
18 | impl_block::ImplBlock, | 17 | impl_block::ImplBlock, |
19 | resolve::Resolver, | 18 | resolve::Resolver, |
19 | diagnostics::DiagnosticSink, | ||
20 | }; | 20 | }; |
21 | 21 | ||
22 | /// hir::Crate describes a single crate. It's the main interface with which | 22 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -95,11 +95,6 @@ pub enum ModuleSource { | |||
95 | Module(TreeArc<ast::Module>), | 95 | Module(TreeArc<ast::Module>), |
96 | } | 96 | } |
97 | 97 | ||
98 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] | ||
99 | pub enum Problem { | ||
100 | UnresolvedModule { candidate: RelativePathBuf }, | ||
101 | } | ||
102 | |||
103 | impl Module { | 98 | impl Module { |
104 | /// Name of this module. | 99 | /// Name of this module. |
105 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { | 100 | pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { |
@@ -171,8 +166,24 @@ impl Module { | |||
171 | db.crate_def_map(self.krate)[self.module_id].scope.clone() | 166 | db.crate_def_map(self.krate)[self.module_id].scope.clone() |
172 | } | 167 | } |
173 | 168 | ||
174 | pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> { | 169 | pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
175 | self.problems_impl(db) | 170 | db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); |
171 | for decl in self.declarations(db) { | ||
172 | match decl { | ||
173 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), | ||
174 | crate::ModuleDef::Module(f) => f.diagnostics(db, sink), | ||
175 | _ => (), | ||
176 | } | ||
177 | } | ||
178 | |||
179 | for impl_block in self.impl_blocks(db) { | ||
180 | for item in impl_block.items(db) { | ||
181 | match item { | ||
182 | crate::ImplItem::Method(f) => f.diagnostics(db, sink), | ||
183 | _ => (), | ||
184 | } | ||
185 | } | ||
186 | } | ||
176 | } | 187 | } |
177 | 188 | ||
178 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 189 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
@@ -519,6 +530,10 @@ impl Function { | |||
519 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | 530 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
520 | r | 531 | r |
521 | } | 532 | } |
533 | |||
534 | pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | ||
535 | self.infer(db).add_diagnostics(db, *self, sink); | ||
536 | } | ||
522 | } | 537 | } |
523 | 538 | ||
524 | impl Docs for Function { | 539 | impl Docs for Function { |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 52a33e981..14237060c 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | use ra_db::FileId; | 1 | use ra_db::FileId; |
2 | use ra_syntax::{ast, SyntaxNode, TreeArc, AstNode}; | 2 | use ra_syntax::{ast, TreeArc, AstNode}; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Problem, Name, | 5 | Module, ModuleSource, Name, |
6 | nameres::{CrateModuleId, ImportId}, | 6 | nameres::{CrateModuleId, ImportId}, |
7 | HirDatabase, DefDatabase, | 7 | HirDatabase, DefDatabase, |
8 | HirFileId, SourceItemId, | 8 | HirFileId, SourceItemId, |
@@ -108,19 +108,4 @@ impl Module { | |||
108 | let parent_id = def_map[self.module_id].parent?; | 108 | let parent_id = def_map[self.module_id].parent?; |
109 | Some(self.with_module_id(parent_id)) | 109 | Some(self.with_module_id(parent_id)) |
110 | } | 110 | } |
111 | |||
112 | pub(crate) fn problems_impl( | ||
113 | &self, | ||
114 | db: &impl HirDatabase, | ||
115 | ) -> Vec<(TreeArc<SyntaxNode>, Problem)> { | ||
116 | let def_map = db.crate_def_map(self.krate); | ||
117 | let (my_file_id, _) = self.definition_source(db); | ||
118 | // FIXME: not entirely corret filterint by module | ||
119 | def_map | ||
120 | .problems() | ||
121 | .iter() | ||
122 | .filter(|(source_item_id, _problem)| my_file_id == source_item_id.file_id) | ||
123 | .map(|(source_item_id, problem)| (db.file_item(*source_item_id), problem.clone())) | ||
124 | .collect() | ||
125 | } | ||
126 | } | 111 | } |
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs new file mode 100644 index 000000000..d6a51b833 --- /dev/null +++ b/crates/ra_hir/src/diagnostics.rs | |||
@@ -0,0 +1,115 @@ | |||
1 | use std::{fmt, any::Any}; | ||
2 | |||
3 | use ra_syntax::{SyntaxNodePtr, TreeArc, AstPtr, TextRange, ast, SyntaxNode}; | ||
4 | use relative_path::RelativePathBuf; | ||
5 | |||
6 | use crate::{HirFileId, HirDatabase}; | ||
7 | |||
8 | /// Diagnostic defines hir API for errors and warnings. | ||
9 | /// | ||
10 | /// It is used as a `dyn` object, which you can downcast to a concrete | ||
11 | /// diagnostic. DiagnosticSink are structured, meaning that they include rich | ||
12 | /// information which can be used by IDE to create fixes. DiagnosticSink are | ||
13 | /// expressed in terms of macro-expanded syntax tree nodes (so, it's a bad idea | ||
14 | /// to diagnostic in a salsa value). | ||
15 | /// | ||
16 | /// Internally, various subsystems of hir produce diagnostics specific to a | ||
17 | /// subsystem (typically, an `enum`), which are safe to store in salsa but do not | ||
18 | /// include source locations. Such internal diagnostic are transformed into an | ||
19 | /// instance of `Diagnostic` on demand. | ||
20 | pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static { | ||
21 | fn message(&self) -> String; | ||
22 | fn file(&self) -> HirFileId; | ||
23 | fn syntax_node_ptr(&self) -> SyntaxNodePtr; | ||
24 | fn highlight_range(&self) -> TextRange { | ||
25 | self.syntax_node_ptr().range() | ||
26 | } | ||
27 | fn as_any(&self) -> &(dyn Any + Send + 'static); | ||
28 | } | ||
29 | |||
30 | impl dyn Diagnostic { | ||
31 | pub fn syntax_node(&self, db: &impl HirDatabase) -> TreeArc<SyntaxNode> { | ||
32 | let source_file = db.hir_parse(self.file()); | ||
33 | self.syntax_node_ptr().to_node(&source_file).to_owned() | ||
34 | } | ||
35 | pub fn downcast_ref<D: Diagnostic>(&self) -> Option<&D> { | ||
36 | self.as_any().downcast_ref() | ||
37 | } | ||
38 | } | ||
39 | |||
40 | pub struct DiagnosticSink<'a> { | ||
41 | callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>, | ||
42 | default_callback: Box<dyn FnMut(&dyn Diagnostic) + 'a>, | ||
43 | } | ||
44 | |||
45 | impl<'a> DiagnosticSink<'a> { | ||
46 | pub fn new(cb: impl FnMut(&dyn Diagnostic) + 'a) -> DiagnosticSink<'a> { | ||
47 | DiagnosticSink { callbacks: Vec::new(), default_callback: Box::new(cb) } | ||
48 | } | ||
49 | |||
50 | pub fn on<D: Diagnostic, F: FnMut(&D) + 'a>(mut self, mut cb: F) -> DiagnosticSink<'a> { | ||
51 | let cb = move |diag: &dyn Diagnostic| match diag.downcast_ref::<D>() { | ||
52 | Some(d) => { | ||
53 | cb(d); | ||
54 | Ok(()) | ||
55 | } | ||
56 | None => Err(()), | ||
57 | }; | ||
58 | self.callbacks.push(Box::new(cb)); | ||
59 | self | ||
60 | } | ||
61 | |||
62 | pub(crate) fn push(&mut self, d: impl Diagnostic) { | ||
63 | let d: &dyn Diagnostic = &d; | ||
64 | for cb in self.callbacks.iter_mut() { | ||
65 | match cb(d) { | ||
66 | Ok(()) => return, | ||
67 | Err(()) => (), | ||
68 | } | ||
69 | } | ||
70 | (self.default_callback)(d) | ||
71 | } | ||
72 | } | ||
73 | |||
74 | #[derive(Debug)] | ||
75 | pub struct NoSuchField { | ||
76 | pub file: HirFileId, | ||
77 | pub field: AstPtr<ast::NamedField>, | ||
78 | } | ||
79 | |||
80 | impl Diagnostic for NoSuchField { | ||
81 | fn message(&self) -> String { | ||
82 | "no such field".to_string() | ||
83 | } | ||
84 | fn file(&self) -> HirFileId { | ||
85 | self.file | ||
86 | } | ||
87 | fn syntax_node_ptr(&self) -> SyntaxNodePtr { | ||
88 | self.field.into() | ||
89 | } | ||
90 | fn as_any(&self) -> &(Any + Send + 'static) { | ||
91 | self | ||
92 | } | ||
93 | } | ||
94 | |||
95 | #[derive(Debug)] | ||
96 | pub struct UnresolvedModule { | ||
97 | pub file: HirFileId, | ||
98 | pub decl: AstPtr<ast::Module>, | ||
99 | pub candidate: RelativePathBuf, | ||
100 | } | ||
101 | |||
102 | impl Diagnostic for UnresolvedModule { | ||
103 | fn message(&self) -> String { | ||
104 | "unresolved module".to_string() | ||
105 | } | ||
106 | fn file(&self) -> HirFileId { | ||
107 | self.file | ||
108 | } | ||
109 | fn syntax_node_ptr(&self) -> SyntaxNodePtr { | ||
110 | self.decl.into() | ||
111 | } | ||
112 | fn as_any(&self) -> &(Any + Send + 'static) { | ||
113 | self | ||
114 | } | ||
115 | } | ||
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 703d99d9b..a85422955 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -5,7 +5,7 @@ use rustc_hash::FxHashMap; | |||
5 | 5 | ||
6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | SyntaxNodePtr, AstNode, | 8 | SyntaxNodePtr, AstPtr, AstNode, |
9 | ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor, TypeAscriptionOwner} | 9 | ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor, TypeAscriptionOwner} |
10 | }; | 10 | }; |
11 | 11 | ||
@@ -54,6 +54,7 @@ pub struct BodySourceMap { | |||
54 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, | 54 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, |
55 | pat_map: FxHashMap<SyntaxNodePtr, PatId>, | 55 | pat_map: FxHashMap<SyntaxNodePtr, PatId>, |
56 | pat_map_back: ArenaMap<PatId, SyntaxNodePtr>, | 56 | pat_map_back: ArenaMap<PatId, SyntaxNodePtr>, |
57 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::NamedField>>, | ||
57 | } | 58 | } |
58 | 59 | ||
59 | impl Body { | 60 | impl Body { |
@@ -138,6 +139,10 @@ impl BodySourceMap { | |||
138 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 139 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
139 | self.pat_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | 140 | self.pat_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
140 | } | 141 | } |
142 | |||
143 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::NamedField> { | ||
144 | self.field_map[&(expr, field)].clone() | ||
145 | } | ||
141 | } | 146 | } |
142 | 147 | ||
143 | #[derive(Debug, Clone, Eq, PartialEq)] | 148 | #[derive(Debug, Clone, Eq, PartialEq)] |
@@ -629,8 +634,10 @@ impl ExprCollector { | |||
629 | } | 634 | } |
630 | ast::ExprKind::StructLit(e) => { | 635 | ast::ExprKind::StructLit(e) => { |
631 | let path = e.path().and_then(Path::from_ast); | 636 | let path = e.path().and_then(Path::from_ast); |
637 | let mut field_ptrs = Vec::new(); | ||
632 | let fields = if let Some(nfl) = e.named_field_list() { | 638 | let fields = if let Some(nfl) = e.named_field_list() { |
633 | nfl.fields() | 639 | nfl.fields() |
640 | .inspect(|field| field_ptrs.push(AstPtr::new(*field))) | ||
634 | .map(|field| StructLitField { | 641 | .map(|field| StructLitField { |
635 | name: field | 642 | name: field |
636 | .name_ref() | 643 | .name_ref() |
@@ -657,7 +664,11 @@ impl ExprCollector { | |||
657 | Vec::new() | 664 | Vec::new() |
658 | }; | 665 | }; |
659 | let spread = e.spread().map(|s| self.collect_expr(s)); | 666 | let spread = e.spread().map(|s| self.collect_expr(s)); |
660 | self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr) | 667 | let res = self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr); |
668 | for (i, ptr) in field_ptrs.into_iter().enumerate() { | ||
669 | self.source_map.field_map.insert((res, i), ptr); | ||
670 | } | ||
671 | res | ||
661 | } | 672 | } |
662 | ast::ExprKind::FieldExpr(e) => { | 673 | ast::ExprKind::FieldExpr(e) => { |
663 | let expr = self.collect_expr_opt(e.expr()); | 674 | let expr = self.collect_expr_opt(e.expr()); |
@@ -680,7 +691,7 @@ impl ExprCollector { | |||
680 | } | 691 | } |
681 | ast::ExprKind::PrefixExpr(e) => { | 692 | ast::ExprKind::PrefixExpr(e) => { |
682 | let expr = self.collect_expr_opt(e.expr()); | 693 | let expr = self.collect_expr_opt(e.expr()); |
683 | if let Some(op) = e.op() { | 694 | if let Some(op) = e.op_kind() { |
684 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) | 695 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) |
685 | } else { | 696 | } else { |
686 | self.alloc_expr(Expr::Missing, syntax_ptr) | 697 | self.alloc_expr(Expr::Missing, syntax_ptr) |
@@ -703,7 +714,7 @@ impl ExprCollector { | |||
703 | ast::ExprKind::BinExpr(e) => { | 714 | ast::ExprKind::BinExpr(e) => { |
704 | let lhs = self.collect_expr_opt(e.lhs()); | 715 | let lhs = self.collect_expr_opt(e.lhs()); |
705 | let rhs = self.collect_expr_opt(e.rhs()); | 716 | let rhs = self.collect_expr_opt(e.rhs()); |
706 | let op = e.op(); | 717 | let op = e.op_kind(); |
707 | self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) | 718 | self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) |
708 | } | 719 | } |
709 | ast::ExprKind::TupleExpr(e) => { | 720 | ast::ExprKind::TupleExpr(e) => { |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index a89c916f8..ce54d7608 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -35,6 +35,7 @@ mod expr; | |||
35 | mod generics; | 35 | mod generics; |
36 | mod docs; | 36 | mod docs; |
37 | mod resolve; | 37 | mod resolve; |
38 | pub mod diagnostics; | ||
38 | 39 | ||
39 | mod code_model_api; | 40 | mod code_model_api; |
40 | mod code_model_impl; | 41 | mod code_model_impl; |
@@ -63,7 +64,7 @@ pub use self::{ | |||
63 | 64 | ||
64 | pub use self::code_model_api::{ | 65 | pub use self::code_model_api::{ |
65 | Crate, CrateDependency, | 66 | Crate, CrateDependency, |
66 | Module, ModuleDef, ModuleSource, Problem, | 67 | Module, ModuleDef, ModuleSource, |
67 | Struct, Enum, EnumVariant, | 68 | Struct, Enum, EnumVariant, |
68 | Function, FnSignature, | 69 | Function, FnSignature, |
69 | StructField, FieldSource, | 70 | StructField, FieldSource, |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 10d4c1b8c..aeab6b180 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -9,7 +9,7 @@ use relative_path::RelativePathBuf; | |||
9 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; | 9 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; |
10 | use rustc_hash::FxHashMap; | 10 | use rustc_hash::FxHashMap; |
11 | 11 | ||
12 | use crate::{db, HirInterner}; | 12 | use crate::{db, HirInterner, diagnostics::DiagnosticSink}; |
13 | 13 | ||
14 | pub const WORKSPACE: SourceRootId = SourceRootId(0); | 14 | pub const WORKSPACE: SourceRootId = SourceRootId(0); |
15 | 15 | ||
@@ -70,6 +70,22 @@ impl MockDatabase { | |||
70 | self.set_crate_graph(Arc::new(crate_graph)) | 70 | self.set_crate_graph(Arc::new(crate_graph)) |
71 | } | 71 | } |
72 | 72 | ||
73 | pub fn diagnostics(&self) -> String { | ||
74 | let mut buf = String::from("\n"); | ||
75 | let mut files: Vec<FileId> = self.files.values().map(|&it| it).collect(); | ||
76 | files.sort(); | ||
77 | for file in files { | ||
78 | let module = crate::source_binder::module_from_file_id(self, file).unwrap(); | ||
79 | module.diagnostics( | ||
80 | self, | ||
81 | &mut DiagnosticSink::new(|d| { | ||
82 | buf += &format!("{:?}: {}\n", d.syntax_node(self).text(), d.message()); | ||
83 | }), | ||
84 | ) | ||
85 | } | ||
86 | buf | ||
87 | } | ||
88 | |||
73 | fn from_fixture(fixture: &str) -> (MockDatabase, Option<FilePosition>) { | 89 | fn from_fixture(fixture: &str) -> (MockDatabase, Option<FilePosition>) { |
74 | let mut db = MockDatabase::default(); | 90 | let mut db = MockDatabase::default(); |
75 | 91 | ||
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index d361cf9e6..56ed872d5 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -61,9 +61,11 @@ use ra_db::{FileId, Edition}; | |||
61 | use test_utils::tested_by; | 61 | use test_utils::tested_by; |
62 | 62 | ||
63 | use crate::{ | 63 | use crate::{ |
64 | ModuleDef, Name, Crate, Module, Problem, | 64 | ModuleDef, Name, Crate, Module, |
65 | DefDatabase, Path, PathKind, HirFileId, | 65 | DefDatabase, Path, PathKind, HirFileId, |
66 | ids::{SourceItemId, SourceFileItemId, MacroCallId}, | 66 | ids::{SourceItemId, SourceFileItemId, MacroCallId}, |
67 | diagnostics::DiagnosticSink, | ||
68 | nameres::diagnostics::DefDiagnostic, | ||
67 | }; | 69 | }; |
68 | 70 | ||
69 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; | 71 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; |
@@ -85,7 +87,7 @@ pub struct CrateDefMap { | |||
85 | macros: Arena<CrateMacroId, mbe::MacroRules>, | 87 | macros: Arena<CrateMacroId, mbe::MacroRules>, |
86 | public_macros: FxHashMap<Name, CrateMacroId>, | 88 | public_macros: FxHashMap<Name, CrateMacroId>, |
87 | macro_resolutions: FxHashMap<MacroCallId, (Crate, CrateMacroId)>, | 89 | macro_resolutions: FxHashMap<MacroCallId, (Crate, CrateMacroId)>, |
88 | problems: CrateDefMapProblems, | 90 | diagnostics: Vec<DefDiagnostic>, |
89 | } | 91 | } |
90 | 92 | ||
91 | impl std::ops::Index<CrateModuleId> for CrateDefMap { | 93 | impl std::ops::Index<CrateModuleId> for CrateDefMap { |
@@ -125,21 +127,6 @@ pub(crate) struct ModuleData { | |||
125 | pub(crate) definition: Option<FileId>, | 127 | pub(crate) definition: Option<FileId>, |
126 | } | 128 | } |
127 | 129 | ||
128 | #[derive(Default, Debug, PartialEq, Eq)] | ||
129 | pub(crate) struct CrateDefMapProblems { | ||
130 | problems: Vec<(SourceItemId, Problem)>, | ||
131 | } | ||
132 | |||
133 | impl CrateDefMapProblems { | ||
134 | fn add(&mut self, source_item_id: SourceItemId, problem: Problem) { | ||
135 | self.problems.push((source_item_id, problem)) | ||
136 | } | ||
137 | |||
138 | pub(crate) fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a SourceItemId, &'a Problem)> + 'a { | ||
139 | self.problems.iter().map(|(s, p)| (s, p)) | ||
140 | } | ||
141 | } | ||
142 | |||
143 | #[derive(Debug, Default, PartialEq, Eq, Clone)] | 130 | #[derive(Debug, Default, PartialEq, Eq, Clone)] |
144 | pub struct ModuleScope { | 131 | pub struct ModuleScope { |
145 | items: FxHashMap<Name, Resolution>, | 132 | items: FxHashMap<Name, Resolution>, |
@@ -212,7 +199,7 @@ impl CrateDefMap { | |||
212 | macros: Arena::default(), | 199 | macros: Arena::default(), |
213 | public_macros: FxHashMap::default(), | 200 | public_macros: FxHashMap::default(), |
214 | macro_resolutions: FxHashMap::default(), | 201 | macro_resolutions: FxHashMap::default(), |
215 | problems: CrateDefMapProblems::default(), | 202 | diagnostics: Vec::new(), |
216 | } | 203 | } |
217 | }; | 204 | }; |
218 | let def_map = collector::collect_defs(db, def_map); | 205 | let def_map = collector::collect_defs(db, def_map); |
@@ -224,10 +211,6 @@ impl CrateDefMap { | |||
224 | self.root | 211 | self.root |
225 | } | 212 | } |
226 | 213 | ||
227 | pub(crate) fn problems(&self) -> &CrateDefMapProblems { | ||
228 | &self.problems | ||
229 | } | ||
230 | |||
231 | pub(crate) fn mk_module(&self, module_id: CrateModuleId) -> Module { | 214 | pub(crate) fn mk_module(&self, module_id: CrateModuleId) -> Module { |
232 | Module { krate: self.krate, module_id } | 215 | Module { krate: self.krate, module_id } |
233 | } | 216 | } |
@@ -240,6 +223,15 @@ impl CrateDefMap { | |||
240 | &self.extern_prelude | 223 | &self.extern_prelude |
241 | } | 224 | } |
242 | 225 | ||
226 | pub(crate) fn add_diagnostics( | ||
227 | &self, | ||
228 | db: &impl DefDatabase, | ||
229 | module: CrateModuleId, | ||
230 | sink: &mut DiagnosticSink, | ||
231 | ) { | ||
232 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) | ||
233 | } | ||
234 | |||
243 | pub(crate) fn resolve_macro( | 235 | pub(crate) fn resolve_macro( |
244 | &self, | 236 | &self, |
245 | macro_call_id: MacroCallId, | 237 | macro_call_id: MacroCallId, |
@@ -452,3 +444,48 @@ impl CrateDefMap { | |||
452 | } | 444 | } |
453 | } | 445 | } |
454 | } | 446 | } |
447 | |||
448 | mod diagnostics { | ||
449 | use relative_path::RelativePathBuf; | ||
450 | use ra_syntax::{AstPtr, AstNode, ast}; | ||
451 | |||
452 | use crate::{ | ||
453 | SourceItemId, DefDatabase, | ||
454 | nameres::CrateModuleId, | ||
455 | diagnostics::{DiagnosticSink, UnresolvedModule}, | ||
456 | }; | ||
457 | |||
458 | #[derive(Debug, PartialEq, Eq)] | ||
459 | pub(super) enum DefDiagnostic { | ||
460 | UnresolvedModule { | ||
461 | module: CrateModuleId, | ||
462 | declaration: SourceItemId, | ||
463 | candidate: RelativePathBuf, | ||
464 | }, | ||
465 | } | ||
466 | |||
467 | impl DefDiagnostic { | ||
468 | pub(super) fn add_to( | ||
469 | &self, | ||
470 | db: &impl DefDatabase, | ||
471 | target_module: CrateModuleId, | ||
472 | sink: &mut DiagnosticSink, | ||
473 | ) { | ||
474 | match self { | ||
475 | DefDiagnostic::UnresolvedModule { module, declaration, candidate } => { | ||
476 | if *module != target_module { | ||
477 | return; | ||
478 | } | ||
479 | let syntax = db.file_item(*declaration); | ||
480 | let decl = ast::Module::cast(&syntax).unwrap(); | ||
481 | sink.push(UnresolvedModule { | ||
482 | file: declaration.file_id, | ||
483 | decl: AstPtr::new(&decl), | ||
484 | candidate: candidate.clone(), | ||
485 | }) | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | |||
491 | } | ||
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index c5b73cfbe..8830b4624 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -6,14 +6,17 @@ use ra_db::FileId; | |||
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, | 8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, |
9 | DefDatabase, HirFileId, Name, Path, Problem, Crate, | 9 | DefDatabase, HirFileId, Name, Path, Crate, |
10 | KnownName, | 10 | KnownName, |
11 | nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw}, | 11 | nameres::{ |
12 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, | ||
13 | CrateDefMap, CrateModuleId, ModuleData, CrateMacroId, | ||
14 | diagnostics::DefDiagnostic, | ||
15 | raw, | ||
16 | }, | ||
12 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, | 17 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, |
13 | }; | 18 | }; |
14 | 19 | ||
15 | use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId}; | ||
16 | |||
17 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 20 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
18 | // populate external prelude | 21 | // populate external prelude |
19 | for dep in def_map.krate.dependencies(db) { | 22 | for dep in def_map.krate.dependencies(db) { |
@@ -405,25 +408,27 @@ where | |||
405 | raw::ModuleData::Declaration { name, source_item_id } => { | 408 | raw::ModuleData::Declaration { name, source_item_id } => { |
406 | let source_item_id = source_item_id.with_file_id(self.file_id); | 409 | let source_item_id = source_item_id.with_file_id(self.file_id); |
407 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); | 410 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); |
408 | let (file_ids, problem) = | 411 | match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { |
409 | resolve_submodule(self.def_collector.db, self.file_id, name, is_root); | 412 | Ok(file_id) => { |
410 | 413 | let module_id = | |
411 | if let Some(problem) = problem { | 414 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); |
412 | self.def_collector.def_map.problems.add(source_item_id, problem) | 415 | let raw_items = self.def_collector.db.raw_items(file_id); |
413 | } | 416 | ModCollector { |
414 | 417 | def_collector: &mut *self.def_collector, | |
415 | if let Some(&file_id) = file_ids.first() { | 418 | module_id, |
416 | let module_id = | 419 | file_id: file_id.into(), |
417 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); | 420 | raw_items: &raw_items, |
418 | let raw_items = self.def_collector.db.raw_items(file_id); | 421 | } |
419 | ModCollector { | 422 | .collect(raw_items.items()) |
420 | def_collector: &mut *self.def_collector, | ||
421 | module_id, | ||
422 | file_id: file_id.into(), | ||
423 | raw_items: &raw_items, | ||
424 | } | 423 | } |
425 | .collect(raw_items.items()) | 424 | Err(candidate) => self.def_collector.def_map.diagnostics.push( |
426 | } | 425 | DefDiagnostic::UnresolvedModule { |
426 | module: self.module_id, | ||
427 | declaration: source_item_id, | ||
428 | candidate, | ||
429 | }, | ||
430 | ), | ||
431 | }; | ||
427 | } | 432 | } |
428 | } | 433 | } |
429 | } | 434 | } |
@@ -524,7 +529,7 @@ fn resolve_submodule( | |||
524 | file_id: HirFileId, | 529 | file_id: HirFileId, |
525 | name: &Name, | 530 | name: &Name, |
526 | is_root: bool, | 531 | is_root: bool, |
527 | ) -> (Vec<FileId>, Option<Problem>) { | 532 | ) -> Result<FileId, RelativePathBuf> { |
528 | // FIXME: handle submodules of inline modules properly | 533 | // FIXME: handle submodules of inline modules properly |
529 | let file_id = file_id.original_file(db); | 534 | let file_id = file_id.original_file(db); |
530 | let source_root_id = db.file_source_root(file_id); | 535 | let source_root_id = db.file_source_root(file_id); |
@@ -545,17 +550,10 @@ fn resolve_submodule( | |||
545 | candidates.push(file_dir_mod.clone()); | 550 | candidates.push(file_dir_mod.clone()); |
546 | }; | 551 | }; |
547 | let sr = db.source_root(source_root_id); | 552 | let sr = db.source_root(source_root_id); |
548 | let points_to = candidates | 553 | let mut points_to = candidates.into_iter().filter_map(|path| sr.files.get(&path)).map(|&it| it); |
549 | .into_iter() | 554 | // FIXME: handle ambiguity |
550 | .filter_map(|path| sr.files.get(&path)) | 555 | match points_to.next() { |
551 | .map(|&it| it) | 556 | Some(file_id) => Ok(file_id), |
552 | .collect::<Vec<_>>(); | 557 | None => Err(if is_dir_owner { file_mod } else { file_dir_mod }), |
553 | let problem = if points_to.is_empty() { | 558 | } |
554 | Some(Problem::UnresolvedModule { | ||
555 | candidate: if is_dir_owner { file_mod } else { file_dir_mod }, | ||
556 | }) | ||
557 | } else { | ||
558 | None | ||
559 | }; | ||
560 | (points_to, problem) | ||
561 | } | 559 | } |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index ac9b88520..572bd1bf7 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -552,3 +552,22 @@ foo: v | |||
552 | "### | 552 | "### |
553 | ); | 553 | ); |
554 | } | 554 | } |
555 | |||
556 | #[test] | ||
557 | fn unresolved_module_diagnostics() { | ||
558 | let diagnostics = MockDatabase::with_files( | ||
559 | r" | ||
560 | //- /lib.rs | ||
561 | mod foo; | ||
562 | mod bar; | ||
563 | mod baz {} | ||
564 | //- /foo.rs | ||
565 | ", | ||
566 | ) | ||
567 | .diagnostics(); | ||
568 | |||
569 | assert_snapshot_matches!(diagnostics, @r###" | ||
570 | "mod bar;": unresolved module | ||
571 | "### | ||
572 | ); | ||
573 | } | ||
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index cff7e7481..5fd602a9e 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -36,7 +36,9 @@ use crate::{ | |||
36 | path::{GenericArgs, GenericArg}, | 36 | path::{GenericArgs, GenericArg}, |
37 | adt::VariantDef, | 37 | adt::VariantDef, |
38 | resolve::{Resolver, Resolution}, | 38 | resolve::{Resolver, Resolution}, |
39 | nameres::Namespace | 39 | nameres::Namespace, |
40 | ty::infer::diagnostics::InferenceDiagnostic, | ||
41 | diagnostics::DiagnosticSink, | ||
40 | }; | 42 | }; |
41 | use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; | 43 | use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor}; |
42 | 44 | ||
@@ -96,6 +98,7 @@ pub struct InferenceResult { | |||
96 | field_resolutions: FxHashMap<ExprId, StructField>, | 98 | field_resolutions: FxHashMap<ExprId, StructField>, |
97 | /// For each associated item record what it resolves to | 99 | /// For each associated item record what it resolves to |
98 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, | 100 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, |
101 | diagnostics: Vec<InferenceDiagnostic>, | ||
99 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, | 102 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, |
100 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, | 103 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, |
101 | } | 104 | } |
@@ -113,6 +116,14 @@ impl InferenceResult { | |||
113 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { | 116 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { |
114 | self.assoc_resolutions.get(&id.into()).map(|it| *it) | 117 | self.assoc_resolutions.get(&id.into()).map(|it| *it) |
115 | } | 118 | } |
119 | pub(crate) fn add_diagnostics( | ||
120 | &self, | ||
121 | db: &impl HirDatabase, | ||
122 | owner: Function, | ||
123 | sink: &mut DiagnosticSink, | ||
124 | ) { | ||
125 | self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) | ||
126 | } | ||
116 | } | 127 | } |
117 | 128 | ||
118 | impl Index<ExprId> for InferenceResult { | 129 | impl Index<ExprId> for InferenceResult { |
@@ -143,6 +154,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
143 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, | 154 | assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, |
144 | type_of_expr: ArenaMap<ExprId, Ty>, | 155 | type_of_expr: ArenaMap<ExprId, Ty>, |
145 | type_of_pat: ArenaMap<PatId, Ty>, | 156 | type_of_pat: ArenaMap<PatId, Ty>, |
157 | diagnostics: Vec<InferenceDiagnostic>, | ||
146 | /// The return type of the function being inferred. | 158 | /// The return type of the function being inferred. |
147 | return_ty: Ty, | 159 | return_ty: Ty, |
148 | } | 160 | } |
@@ -155,6 +167,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
155 | assoc_resolutions: FxHashMap::default(), | 167 | assoc_resolutions: FxHashMap::default(), |
156 | type_of_expr: ArenaMap::default(), | 168 | type_of_expr: ArenaMap::default(), |
157 | type_of_pat: ArenaMap::default(), | 169 | type_of_pat: ArenaMap::default(), |
170 | diagnostics: Vec::default(), | ||
158 | var_unification_table: InPlaceUnificationTable::new(), | 171 | var_unification_table: InPlaceUnificationTable::new(), |
159 | return_ty: Ty::Unknown, // set in collect_fn_signature | 172 | return_ty: Ty::Unknown, // set in collect_fn_signature |
160 | db, | 173 | db, |
@@ -181,6 +194,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
181 | assoc_resolutions: self.assoc_resolutions, | 194 | assoc_resolutions: self.assoc_resolutions, |
182 | type_of_expr: expr_types, | 195 | type_of_expr: expr_types, |
183 | type_of_pat: pat_types, | 196 | type_of_pat: pat_types, |
197 | diagnostics: self.diagnostics, | ||
184 | } | 198 | } |
185 | } | 199 | } |
186 | 200 | ||
@@ -915,9 +929,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
915 | Expr::StructLit { path, fields, spread } => { | 929 | Expr::StructLit { path, fields, spread } => { |
916 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 930 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
917 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 931 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
918 | for field in fields { | 932 | for (field_idx, field) in fields.into_iter().enumerate() { |
919 | let field_ty = def_id | 933 | let field_ty = def_id |
920 | .and_then(|it| it.field(self.db, &field.name)) | 934 | .and_then(|it| match it.field(self.db, &field.name) { |
935 | Some(field) => Some(field), | ||
936 | None => { | ||
937 | self.diagnostics.push(InferenceDiagnostic::NoSuchField { | ||
938 | expr: tgt_expr, | ||
939 | field: field_idx, | ||
940 | }); | ||
941 | None | ||
942 | } | ||
943 | }) | ||
921 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 944 | .map_or(Ty::Unknown, |field| field.ty(self.db)) |
922 | .subst(&substs); | 945 | .subst(&substs); |
923 | self.infer_expr(field.expr, &Expectation::has_type(field_ty)); | 946 | self.infer_expr(field.expr, &Expectation::has_type(field_ty)); |
@@ -1244,3 +1267,29 @@ impl Expectation { | |||
1244 | Expectation { ty: Ty::Unknown } | 1267 | Expectation { ty: Ty::Unknown } |
1245 | } | 1268 | } |
1246 | } | 1269 | } |
1270 | |||
1271 | mod diagnostics { | ||
1272 | use crate::{expr::ExprId, diagnostics::{DiagnosticSink, NoSuchField}, HirDatabase, Function}; | ||
1273 | |||
1274 | #[derive(Debug, PartialEq, Eq, Clone)] | ||
1275 | pub(super) enum InferenceDiagnostic { | ||
1276 | NoSuchField { expr: ExprId, field: usize }, | ||
1277 | } | ||
1278 | |||
1279 | impl InferenceDiagnostic { | ||
1280 | pub(super) fn add_to( | ||
1281 | &self, | ||
1282 | db: &impl HirDatabase, | ||
1283 | owner: Function, | ||
1284 | sink: &mut DiagnosticSink, | ||
1285 | ) { | ||
1286 | match self { | ||
1287 | InferenceDiagnostic::NoSuchField { expr, field } => { | ||
1288 | let (file, _) = owner.source(db); | ||
1289 | let field = owner.body_source_map(db).field_syntax(*expr, *field); | ||
1290 | sink.push(NoSuchField { file, field }) | ||
1291 | } | ||
1292 | } | ||
1293 | } | ||
1294 | } | ||
1295 | } | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 5d8ad4aa7..3aedba243 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2319,3 +2319,27 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
2319 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) | 2319 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) |
2320 | } | 2320 | } |
2321 | } | 2321 | } |
2322 | |||
2323 | #[test] | ||
2324 | fn no_such_field_diagnostics() { | ||
2325 | let diagnostics = MockDatabase::with_files( | ||
2326 | r" | ||
2327 | //- /lib.rs | ||
2328 | struct S { foo: i32, bar: () } | ||
2329 | impl S { | ||
2330 | fn new() -> S { | ||
2331 | S { | ||
2332 | foo: 92, | ||
2333 | baz: 62, | ||
2334 | } | ||
2335 | } | ||
2336 | } | ||
2337 | ", | ||
2338 | ) | ||
2339 | .diagnostics(); | ||
2340 | |||
2341 | assert_snapshot_matches!(diagnostics, @r###" | ||
2342 | "baz: 62": no such field | ||
2343 | "### | ||
2344 | ); | ||
2345 | } | ||
diff --git a/crates/ra_ide_api/Cargo.toml b/crates/ra_ide_api/Cargo.toml index c64226801..45bab4e28 100644 --- a/crates/ra_ide_api/Cargo.toml +++ b/crates/ra_ide_api/Cargo.toml | |||
@@ -20,7 +20,6 @@ jemallocator = { version = "0.1.9", optional = true } | |||
20 | jemalloc-ctl = { version = "0.2.0", optional = true } | 20 | jemalloc-ctl = { version = "0.2.0", optional = true } |
21 | 21 | ||
22 | ra_syntax = { path = "../ra_syntax" } | 22 | ra_syntax = { path = "../ra_syntax" } |
23 | ra_ide_api_light = { path = "../ra_ide_api_light" } | ||
24 | ra_text_edit = { path = "../ra_text_edit" } | 23 | ra_text_edit = { path = "../ra_text_edit" } |
25 | ra_db = { path = "../ra_db" } | 24 | ra_db = { path = "../ra_db" } |
26 | ra_fmt = { path = "../ra_fmt" } | 25 | ra_fmt = { path = "../ra_fmt" } |
diff --git a/crates/ra_ide_api/src/assists.rs b/crates/ra_ide_api/src/assists.rs index 3c0475a51..355c0a42a 100644 --- a/crates/ra_ide_api/src/assists.rs +++ b/crates/ra_ide_api/src/assists.rs | |||
@@ -17,14 +17,9 @@ pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<Assist> { | |||
17 | let file_id = frange.file_id; | 17 | let file_id = frange.file_id; |
18 | let file_edit = SourceFileEdit { file_id, edit: action.edit }; | 18 | let file_edit = SourceFileEdit { file_id, edit: action.edit }; |
19 | let id = label.id; | 19 | let id = label.id; |
20 | let change = SourceChange { | 20 | let change = SourceChange::source_file_edit(label.label, file_edit).with_cursor_opt( |
21 | label: label.label, | 21 | action.cursor_position.map(|offset| FilePosition { offset, file_id }), |
22 | source_file_edits: vec![file_edit], | 22 | ); |
23 | file_system_edits: vec![], | ||
24 | cursor_position: action | ||
25 | .cursor_position | ||
26 | .map(|offset| FilePosition { offset, file_id }), | ||
27 | }; | ||
28 | Assist { id, change } | 23 | Assist { id, change } |
29 | }) | 24 | }) |
30 | .collect() | 25 | .collect() |
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index b9dc424c6..5a78e94d8 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -1,10 +1,11 @@ | |||
1 | use std::cell::RefCell; | ||
2 | |||
1 | use itertools::Itertools; | 3 | use itertools::Itertools; |
2 | use hir::{Problem, source_binder}; | 4 | use hir::{source_binder, diagnostics::{Diagnostic as _, DiagnosticSink}}; |
3 | use ra_db::SourceDatabase; | 5 | use ra_db::SourceDatabase; |
4 | use ra_syntax::{ | 6 | use ra_syntax::{ |
5 | Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, | 7 | Location, SourceFile, SyntaxKind, TextRange, SyntaxNode, |
6 | ast::{self, AstNode}, | 8 | ast::{self, AstNode}, |
7 | |||
8 | }; | 9 | }; |
9 | use ra_text_edit::{TextEdit, TextEditBuilder}; | 10 | use ra_text_edit::{TextEdit, TextEditBuilder}; |
10 | 11 | ||
@@ -26,11 +27,31 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
26 | check_unnecessary_braces_in_use_statement(&mut res, file_id, node); | 27 | check_unnecessary_braces_in_use_statement(&mut res, file_id, node); |
27 | check_struct_shorthand_initialization(&mut res, file_id, node); | 28 | check_struct_shorthand_initialization(&mut res, file_id, node); |
28 | } | 29 | } |
29 | 30 | let res = RefCell::new(res); | |
31 | let mut sink = DiagnosticSink::new(|d| { | ||
32 | res.borrow_mut().push(Diagnostic { | ||
33 | message: d.message(), | ||
34 | range: d.highlight_range(), | ||
35 | severity: Severity::Error, | ||
36 | fix: None, | ||
37 | }) | ||
38 | }) | ||
39 | .on::<hir::diagnostics::UnresolvedModule, _>(|d| { | ||
40 | let source_root = db.file_source_root(d.file().original_file(db)); | ||
41 | let create_file = FileSystemEdit::CreateFile { source_root, path: d.candidate.clone() }; | ||
42 | let fix = SourceChange::file_system_edit("create module", create_file); | ||
43 | res.borrow_mut().push(Diagnostic { | ||
44 | range: d.highlight_range(), | ||
45 | message: d.message(), | ||
46 | severity: Severity::Error, | ||
47 | fix: Some(fix), | ||
48 | }) | ||
49 | }); | ||
30 | if let Some(m) = source_binder::module_from_file_id(db, file_id) { | 50 | if let Some(m) = source_binder::module_from_file_id(db, file_id) { |
31 | check_module(&mut res, db, file_id, m); | 51 | m.diagnostics(db, &mut sink); |
32 | }; | 52 | }; |
33 | res | 53 | drop(sink); |
54 | res.into_inner() | ||
34 | } | 55 | } |
35 | 56 | ||
36 | fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) { | 57 | fn syntax_errors(acc: &mut Vec<Diagnostic>, source_file: &SourceFile) { |
@@ -71,12 +92,10 @@ fn check_unnecessary_braces_in_use_statement( | |||
71 | range, | 92 | range, |
72 | message: format!("Unnecessary braces in use statement"), | 93 | message: format!("Unnecessary braces in use statement"), |
73 | severity: Severity::WeakWarning, | 94 | severity: Severity::WeakWarning, |
74 | fix: Some(SourceChange { | 95 | fix: Some(SourceChange::source_file_edit( |
75 | label: "Remove unnecessary braces".to_string(), | 96 | "Remove unnecessary braces", |
76 | source_file_edits: vec![SourceFileEdit { file_id, edit }], | 97 | SourceFileEdit { file_id, edit }, |
77 | file_system_edits: Vec::new(), | 98 | )), |
78 | cursor_position: None, | ||
79 | }), | ||
80 | }); | 99 | }); |
81 | } | 100 | } |
82 | 101 | ||
@@ -119,12 +138,10 @@ fn check_struct_shorthand_initialization( | |||
119 | range: named_field.syntax().range(), | 138 | range: named_field.syntax().range(), |
120 | message: format!("Shorthand struct initialization"), | 139 | message: format!("Shorthand struct initialization"), |
121 | severity: Severity::WeakWarning, | 140 | severity: Severity::WeakWarning, |
122 | fix: Some(SourceChange { | 141 | fix: Some(SourceChange::source_file_edit( |
123 | label: "use struct shorthand initialization".to_string(), | 142 | "use struct shorthand initialization", |
124 | source_file_edits: vec![SourceFileEdit { file_id, edit }], | 143 | SourceFileEdit { file_id, edit }, |
125 | file_system_edits: Vec::new(), | 144 | )), |
126 | cursor_position: None, | ||
127 | }), | ||
128 | }); | 145 | }); |
129 | } | 146 | } |
130 | } | 147 | } |
@@ -132,39 +149,12 @@ fn check_struct_shorthand_initialization( | |||
132 | Some(()) | 149 | Some(()) |
133 | } | 150 | } |
134 | 151 | ||
135 | fn check_module( | ||
136 | acc: &mut Vec<Diagnostic>, | ||
137 | db: &RootDatabase, | ||
138 | file_id: FileId, | ||
139 | module: hir::Module, | ||
140 | ) { | ||
141 | let source_root = db.file_source_root(file_id); | ||
142 | for (name_node, problem) in module.problems(db) { | ||
143 | let diag = match problem { | ||
144 | Problem::UnresolvedModule { candidate } => { | ||
145 | let create_file = | ||
146 | FileSystemEdit::CreateFile { source_root, path: candidate.clone() }; | ||
147 | let fix = SourceChange { | ||
148 | label: "create module".to_string(), | ||
149 | source_file_edits: Vec::new(), | ||
150 | file_system_edits: vec![create_file], | ||
151 | cursor_position: None, | ||
152 | }; | ||
153 | Diagnostic { | ||
154 | range: name_node.range(), | ||
155 | message: "unresolved module".to_string(), | ||
156 | severity: Severity::Error, | ||
157 | fix: Some(fix), | ||
158 | } | ||
159 | } | ||
160 | }; | ||
161 | acc.push(diag) | ||
162 | } | ||
163 | } | ||
164 | |||
165 | #[cfg(test)] | 152 | #[cfg(test)] |
166 | mod tests { | 153 | mod tests { |
167 | use test_utils::assert_eq_text; | 154 | use test_utils::assert_eq_text; |
155 | use insta::assert_debug_snapshot_matches; | ||
156 | |||
157 | use crate::mock_analysis::single_file; | ||
168 | 158 | ||
169 | use super::*; | 159 | use super::*; |
170 | 160 | ||
@@ -194,6 +184,34 @@ mod tests { | |||
194 | } | 184 | } |
195 | 185 | ||
196 | #[test] | 186 | #[test] |
187 | fn test_unresolved_module_diagnostic() { | ||
188 | let (analysis, file_id) = single_file("mod foo;"); | ||
189 | let diagnostics = analysis.diagnostics(file_id).unwrap(); | ||
190 | assert_debug_snapshot_matches!(diagnostics, @r####"[ | ||
191 | Diagnostic { | ||
192 | message: "unresolved module", | ||
193 | range: [0; 8), | ||
194 | fix: Some( | ||
195 | SourceChange { | ||
196 | label: "create module", | ||
197 | source_file_edits: [], | ||
198 | file_system_edits: [ | ||
199 | CreateFile { | ||
200 | source_root: SourceRootId( | ||
201 | 0 | ||
202 | ), | ||
203 | path: "foo.rs" | ||
204 | } | ||
205 | ], | ||
206 | cursor_position: None | ||
207 | } | ||
208 | ), | ||
209 | severity: Error | ||
210 | } | ||
211 | ]"####); | ||
212 | } | ||
213 | |||
214 | #[test] | ||
197 | fn test_check_unnecessary_braces_in_use_statement() { | 215 | fn test_check_unnecessary_braces_in_use_statement() { |
198 | check_not_applicable( | 216 | check_not_applicable( |
199 | " | 217 | " |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 99f18b6b8..9063f78a9 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -6,9 +6,6 @@ | |||
6 | //! database, and the `ra_hir` crate, where majority of the analysis happens. | 6 | //! database, and the `ra_hir` crate, where majority of the analysis happens. |
7 | //! However, IDE specific bits of the analysis (most notably completion) happen | 7 | //! However, IDE specific bits of the analysis (most notably completion) happen |
8 | //! in this crate. | 8 | //! in this crate. |
9 | //! | ||
10 | //! The sibling `ra_ide_api_light` handles those bits of IDE functionality | ||
11 | //! which are restricted to a single file and need only syntax. | ||
12 | 9 | ||
13 | // For proving that RootDatabase is RefUnwindSafe. | 10 | // For proving that RootDatabase is RefUnwindSafe. |
14 | #![recursion_limit = "128"] | 11 | #![recursion_limit = "128"] |
@@ -33,10 +30,11 @@ mod impls; | |||
33 | mod assists; | 30 | mod assists; |
34 | mod diagnostics; | 31 | mod diagnostics; |
35 | mod syntax_tree; | 32 | mod syntax_tree; |
36 | mod line_index; | ||
37 | mod folding_ranges; | 33 | mod folding_ranges; |
34 | mod line_index; | ||
38 | mod line_index_utils; | 35 | mod line_index_utils; |
39 | mod join_lines; | 36 | mod join_lines; |
37 | mod structure; | ||
40 | mod typing; | 38 | mod typing; |
41 | mod matching_brace; | 39 | mod matching_brace; |
42 | 40 | ||
@@ -72,9 +70,10 @@ pub use crate::{ | |||
72 | line_index_utils::translate_offset_with_edit, | 70 | line_index_utils::translate_offset_with_edit, |
73 | folding_ranges::{Fold, FoldKind}, | 71 | folding_ranges::{Fold, FoldKind}, |
74 | syntax_highlighting::HighlightedRange, | 72 | syntax_highlighting::HighlightedRange, |
73 | structure::{StructureNode, file_structure}, | ||
75 | diagnostics::Severity, | 74 | diagnostics::Severity, |
76 | }; | 75 | }; |
77 | pub use ra_ide_api_light::StructureNode; | 76 | |
78 | pub use ra_db::{ | 77 | pub use ra_db::{ |
79 | Canceled, CrateGraph, CrateId, FileId, FilePosition, FileRange, SourceRootId, | 78 | Canceled, CrateGraph, CrateId, FileId, FilePosition, FileRange, SourceRootId, |
80 | Edition | 79 | Edition |
@@ -97,6 +96,79 @@ pub struct SourceChange { | |||
97 | pub cursor_position: Option<FilePosition>, | 96 | pub cursor_position: Option<FilePosition>, |
98 | } | 97 | } |
99 | 98 | ||
99 | impl SourceChange { | ||
100 | /// Creates a new SourceChange with the given label | ||
101 | /// from the edits. | ||
102 | pub(crate) fn from_edits<L: Into<String>>( | ||
103 | label: L, | ||
104 | source_file_edits: Vec<SourceFileEdit>, | ||
105 | file_system_edits: Vec<FileSystemEdit>, | ||
106 | ) -> Self { | ||
107 | SourceChange { | ||
108 | label: label.into(), | ||
109 | source_file_edits, | ||
110 | file_system_edits, | ||
111 | cursor_position: None, | ||
112 | } | ||
113 | } | ||
114 | |||
115 | /// Creates a new SourceChange with the given label, | ||
116 | /// containing only the given `SourceFileEdits`. | ||
117 | pub(crate) fn source_file_edits<L: Into<String>>(label: L, edits: Vec<SourceFileEdit>) -> Self { | ||
118 | SourceChange { | ||
119 | label: label.into(), | ||
120 | source_file_edits: edits, | ||
121 | file_system_edits: vec![], | ||
122 | cursor_position: None, | ||
123 | } | ||
124 | } | ||
125 | |||
126 | /// Creates a new SourceChange with the given label, | ||
127 | /// containing only the given `FileSystemEdits`. | ||
128 | pub(crate) fn file_system_edits<L: Into<String>>(label: L, edits: Vec<FileSystemEdit>) -> Self { | ||
129 | SourceChange { | ||
130 | label: label.into(), | ||
131 | source_file_edits: vec![], | ||
132 | file_system_edits: edits, | ||
133 | cursor_position: None, | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /// Creates a new SourceChange with the given label, | ||
138 | /// containing only a single `SourceFileEdit`. | ||
139 | pub(crate) fn source_file_edit<L: Into<String>>(label: L, edit: SourceFileEdit) -> Self { | ||
140 | SourceChange::source_file_edits(label, vec![edit]) | ||
141 | } | ||
142 | |||
143 | /// Creates a new SourceChange with the given label | ||
144 | /// from the given `FileId` and `TextEdit` | ||
145 | pub(crate) fn source_file_edit_from<L: Into<String>>( | ||
146 | label: L, | ||
147 | file_id: FileId, | ||
148 | edit: TextEdit, | ||
149 | ) -> Self { | ||
150 | SourceChange::source_file_edit(label, SourceFileEdit { file_id, edit }) | ||
151 | } | ||
152 | |||
153 | /// Creates a new SourceChange with the given label | ||
154 | /// from the given `FileId` and `TextEdit` | ||
155 | pub(crate) fn file_system_edit<L: Into<String>>(label: L, edit: FileSystemEdit) -> Self { | ||
156 | SourceChange::file_system_edits(label, vec![edit]) | ||
157 | } | ||
158 | |||
159 | /// Sets the cursor position to the given `FilePosition` | ||
160 | pub(crate) fn with_cursor(mut self, cursor_position: FilePosition) -> Self { | ||
161 | self.cursor_position = Some(cursor_position); | ||
162 | self | ||
163 | } | ||
164 | |||
165 | /// Sets the cursor position to the given `FilePosition` | ||
166 | pub(crate) fn with_cursor_opt(mut self, cursor_position: Option<FilePosition>) -> Self { | ||
167 | self.cursor_position = cursor_position; | ||
168 | self | ||
169 | } | ||
170 | } | ||
171 | |||
100 | #[derive(Debug)] | 172 | #[derive(Debug)] |
101 | pub struct SourceFileEdit { | 173 | pub struct SourceFileEdit { |
102 | pub file_id: FileId, | 174 | pub file_id: FileId, |
@@ -285,12 +357,7 @@ impl Analysis { | |||
285 | file_id: frange.file_id, | 357 | file_id: frange.file_id, |
286 | edit: join_lines::join_lines(&file, frange.range), | 358 | edit: join_lines::join_lines(&file, frange.range), |
287 | }; | 359 | }; |
288 | SourceChange { | 360 | SourceChange::source_file_edit("join lines", file_edit) |
289 | label: "join lines".to_string(), | ||
290 | source_file_edits: vec![file_edit], | ||
291 | file_system_edits: vec![], | ||
292 | cursor_position: None, | ||
293 | } | ||
294 | } | 361 | } |
295 | 362 | ||
296 | /// Returns an edit which should be applied when opening a new line, fixing | 363 | /// Returns an edit which should be applied when opening a new line, fixing |
@@ -305,12 +372,10 @@ impl Analysis { | |||
305 | pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { | 372 | pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { |
306 | let file = self.db.parse(position.file_id); | 373 | let file = self.db.parse(position.file_id); |
307 | let edit = typing::on_eq_typed(&file, position.offset)?; | 374 | let edit = typing::on_eq_typed(&file, position.offset)?; |
308 | Some(SourceChange { | 375 | Some(SourceChange::source_file_edit( |
309 | label: "add semicolon".to_string(), | 376 | "add semicolon", |
310 | source_file_edits: vec![SourceFileEdit { edit, file_id: position.file_id }], | 377 | SourceFileEdit { edit, file_id: position.file_id }, |
311 | file_system_edits: vec![], | 378 | )) |
312 | cursor_position: None, | ||
313 | }) | ||
314 | } | 379 | } |
315 | 380 | ||
316 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. | 381 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. |
@@ -322,7 +387,7 @@ impl Analysis { | |||
322 | /// file outline. | 387 | /// file outline. |
323 | pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { | 388 | pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { |
324 | let file = self.db.parse(file_id); | 389 | let file = self.db.parse(file_id); |
325 | ra_ide_api_light::file_structure(&file) | 390 | structure::file_structure(&file) |
326 | } | 391 | } |
327 | 392 | ||
328 | /// Returns the set of folding ranges. | 393 | /// Returns the set of folding ranges. |
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index b7784e577..22741445a 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs | |||
@@ -187,12 +187,7 @@ fn rename_mod( | |||
187 | }; | 187 | }; |
188 | source_file_edits.push(edit); | 188 | source_file_edits.push(edit); |
189 | 189 | ||
190 | Some(SourceChange { | 190 | Some(SourceChange::from_edits("rename", source_file_edits, file_system_edits)) |
191 | label: "rename".to_string(), | ||
192 | source_file_edits, | ||
193 | file_system_edits, | ||
194 | cursor_position: None, | ||
195 | }) | ||
196 | } | 191 | } |
197 | 192 | ||
198 | fn rename_reference( | 193 | fn rename_reference( |
@@ -211,12 +206,7 @@ fn rename_reference( | |||
211 | return None; | 206 | return None; |
212 | } | 207 | } |
213 | 208 | ||
214 | Some(SourceChange { | 209 | Some(SourceChange::source_file_edits("rename", edit)) |
215 | label: "rename".to_string(), | ||
216 | source_file_edits: edit, | ||
217 | file_system_edits: Vec::new(), | ||
218 | cursor_position: None, | ||
219 | }) | ||
220 | } | 210 | } |
221 | 211 | ||
222 | #[cfg(test)] | 212 | #[cfg(test)] |
diff --git a/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap b/crates/ra_ide_api/src/snapshots/tests__file_structure.snap index 8e4184b31..2efa8e22c 100644 --- a/crates/ra_ide_api_light/src/snapshots/tests__file_structure.snap +++ b/crates/ra_ide_api/src/snapshots/tests__file_structure.snap | |||
@@ -1,7 +1,7 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-02-05T22:03:50.763530100Z" | 2 | created: "2019-02-05T22:03:50.763530100Z" |
3 | creator: [email protected] | 3 | creator: [email protected] |
4 | source: crates/ra_ide_api_light/src/structure.rs | 4 | source: crates/ra_ide_api/src/structure.rs |
5 | expression: structure | 5 | expression: structure |
6 | --- | 6 | --- |
7 | [ | 7 | [ |
diff --git a/crates/ra_ide_api_light/src/structure.rs b/crates/ra_ide_api/src/structure.rs index ec2c9bbc6..ec2c9bbc6 100644 --- a/crates/ra_ide_api_light/src/structure.rs +++ b/crates/ra_ide_api/src/structure.rs | |||
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs index 94b228466..501d44dbb 100644 --- a/crates/ra_ide_api/src/typing.rs +++ b/crates/ra_ide_api/src/typing.rs | |||
@@ -31,12 +31,14 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour | |||
31 | let cursor_position = position.offset + TextUnit::of_str(&inserted); | 31 | let cursor_position = position.offset + TextUnit::of_str(&inserted); |
32 | let mut edit = TextEditBuilder::default(); | 32 | let mut edit = TextEditBuilder::default(); |
33 | edit.insert(position.offset, inserted); | 33 | edit.insert(position.offset, inserted); |
34 | Some(SourceChange { | 34 | |
35 | label: "on enter".to_string(), | 35 | Some( |
36 | source_file_edits: vec![SourceFileEdit { edit: edit.finish(), file_id: position.file_id }], | 36 | SourceChange::source_file_edit( |
37 | file_system_edits: vec![], | 37 | "on enter", |
38 | cursor_position: Some(FilePosition { offset: cursor_position, file_id: position.file_id }), | 38 | SourceFileEdit { edit: edit.finish(), file_id: position.file_id }, |
39 | }) | 39 | ) |
40 | .with_cursor(FilePosition { offset: cursor_position, file_id: position.file_id }), | ||
41 | ) | ||
40 | } | 42 | } |
41 | 43 | ||
42 | fn node_indent<'a>(file: &'a SourceFile, node: &SyntaxNode) -> Option<&'a str> { | 44 | fn node_indent<'a>(file: &'a SourceFile, node: &SyntaxNode) -> Option<&'a str> { |
@@ -110,16 +112,14 @@ pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option< | |||
110 | TextRange::from_to(position.offset - current_indent_len, position.offset), | 112 | TextRange::from_to(position.offset - current_indent_len, position.offset), |
111 | target_indent.into(), | 113 | target_indent.into(), |
112 | ); | 114 | ); |
113 | let res = SourceChange { | 115 | |
114 | label: "reindent dot".to_string(), | 116 | let res = SourceChange::source_file_edit_from("reindent dot", position.file_id, edit.finish()) |
115 | source_file_edits: vec![SourceFileEdit { edit: edit.finish(), file_id: position.file_id }], | 117 | .with_cursor(FilePosition { |
116 | file_system_edits: vec![], | ||
117 | cursor_position: Some(FilePosition { | ||
118 | offset: position.offset + target_indent_len - current_indent_len | 118 | offset: position.offset + target_indent_len - current_indent_len |
119 | + TextUnit::of_char('.'), | 119 | + TextUnit::of_char('.'), |
120 | file_id: position.file_id, | 120 | file_id: position.file_id, |
121 | }), | 121 | }); |
122 | }; | 122 | |
123 | Some(res) | 123 | Some(res) |
124 | } | 124 | } |
125 | 125 | ||
diff --git a/crates/ra_ide_api/tests/test/main.rs b/crates/ra_ide_api/tests/test/main.rs index 0f0766f62..d4ff21c09 100644 --- a/crates/ra_ide_api/tests/test/main.rs +++ b/crates/ra_ide_api/tests/test/main.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | use insta::assert_debug_snapshot_matches; | ||
2 | use ra_ide_api::{ | 1 | use ra_ide_api::{ |
3 | mock_analysis::{single_file, single_file_with_position, single_file_with_range, MockAnalysis}, | 2 | mock_analysis::{single_file, single_file_with_position, single_file_with_range, MockAnalysis}, |
4 | AnalysisChange, CrateGraph, Edition::Edition2018, Query, NavigationTarget, | 3 | AnalysisChange, CrateGraph, Edition::Edition2018, Query, NavigationTarget, |
@@ -7,21 +6,6 @@ use ra_ide_api::{ | |||
7 | use ra_syntax::SmolStr; | 6 | use ra_syntax::SmolStr; |
8 | 7 | ||
9 | #[test] | 8 | #[test] |
10 | fn test_unresolved_module_diagnostic() { | ||
11 | let (analysis, file_id) = single_file("mod foo;"); | ||
12 | let diagnostics = analysis.diagnostics(file_id).unwrap(); | ||
13 | assert_debug_snapshot_matches!("unresolved_module_diagnostic", &diagnostics); | ||
14 | } | ||
15 | |||
16 | // FIXME: move this test to hir | ||
17 | #[test] | ||
18 | fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { | ||
19 | let (analysis, file_id) = single_file("mod foo {}"); | ||
20 | let diagnostics = analysis.diagnostics(file_id).unwrap(); | ||
21 | assert!(diagnostics.is_empty()); | ||
22 | } | ||
23 | |||
24 | #[test] | ||
25 | fn test_resolve_crate_root() { | 9 | fn test_resolve_crate_root() { |
26 | let mock = MockAnalysis::with_files( | 10 | let mock = MockAnalysis::with_files( |
27 | " | 11 | " |
diff --git a/crates/ra_ide_api/tests/test/snapshots/test__unresolved_module_diagnostic.snap b/crates/ra_ide_api/tests/test/snapshots/test__unresolved_module_diagnostic.snap deleted file mode 100644 index 5bb953892..000000000 --- a/crates/ra_ide_api/tests/test/snapshots/test__unresolved_module_diagnostic.snap +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | --- | ||
2 | created: "2019-01-22T14:45:01.486985900+00:00" | ||
3 | creator: [email protected] | ||
4 | expression: "&diagnostics" | ||
5 | source: "crates\\ra_ide_api\\tests\\test\\main.rs" | ||
6 | --- | ||
7 | [ | ||
8 | Diagnostic { | ||
9 | message: "unresolved module", | ||
10 | range: [0; 8), | ||
11 | fix: Some( | ||
12 | SourceChange { | ||
13 | label: "create module", | ||
14 | source_file_edits: [], | ||
15 | file_system_edits: [ | ||
16 | CreateFile { | ||
17 | source_root: SourceRootId( | ||
18 | 0 | ||
19 | ), | ||
20 | path: "foo.rs" | ||
21 | } | ||
22 | ], | ||
23 | cursor_position: None | ||
24 | } | ||
25 | ), | ||
26 | severity: Error | ||
27 | } | ||
28 | ] | ||
diff --git a/crates/ra_ide_api_light/Cargo.toml b/crates/ra_ide_api_light/Cargo.toml deleted file mode 100644 index 4e69f5325..000000000 --- a/crates/ra_ide_api_light/Cargo.toml +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | [package] | ||
2 | edition = "2018" | ||
3 | name = "ra_ide_api_light" | ||
4 | version = "0.1.0" | ||
5 | authors = ["rust-analyzer developers"] | ||
6 | publish = false | ||
7 | |||
8 | [dependencies] | ||
9 | itertools = "0.8.0" | ||
10 | superslice = "1.0.0" | ||
11 | join_to_string = "0.1.1" | ||
12 | rustc-hash = "1.0" | ||
13 | |||
14 | ra_syntax = { path = "../ra_syntax" } | ||
15 | ra_text_edit = { path = "../ra_text_edit" } | ||
16 | ra_fmt = { path = "../ra_fmt" } | ||
17 | |||
18 | [dev-dependencies] | ||
19 | test_utils = { path = "../test_utils" } | ||
20 | insta = "0.7.0" | ||
21 | |||
22 | [dev-dependencies.proptest] | ||
23 | version = "0.9.0" | ||
24 | # Disable `fork` feature to allow compiling on webassembly | ||
25 | default-features = false | ||
26 | features = ["std", "bit-set", "break-dead-code"] | ||
diff --git a/crates/ra_ide_api_light/src/lib.rs b/crates/ra_ide_api_light/src/lib.rs deleted file mode 100644 index df7f144b6..000000000 --- a/crates/ra_ide_api_light/src/lib.rs +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | //! This crate provides those IDE features which use only a single file. | ||
2 | //! | ||
3 | //! This usually means functions which take syntax tree as an input and produce | ||
4 | //! an edit or some auxiliary info. | ||
5 | |||
6 | mod structure; | ||
7 | |||
8 | use ra_syntax::TextRange; | ||
9 | |||
10 | pub use crate::{ | ||
11 | structure::{file_structure, StructureNode}, | ||
12 | }; | ||
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index d8c2cb063..a6fac07c4 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -521,7 +521,7 @@ pub enum PrefixOp { | |||
521 | } | 521 | } |
522 | 522 | ||
523 | impl PrefixExpr { | 523 | impl PrefixExpr { |
524 | pub fn op(&self) -> Option<PrefixOp> { | 524 | pub fn op_kind(&self) -> Option<PrefixOp> { |
525 | match self.syntax().first_child()?.kind() { | 525 | match self.syntax().first_child()?.kind() { |
526 | STAR => Some(PrefixOp::Deref), | 526 | STAR => Some(PrefixOp::Deref), |
527 | EXCL => Some(PrefixOp::Not), | 527 | EXCL => Some(PrefixOp::Not), |
@@ -529,6 +529,10 @@ impl PrefixExpr { | |||
529 | _ => None, | 529 | _ => None, |
530 | } | 530 | } |
531 | } | 531 | } |
532 | |||
533 | pub fn op(&self) -> Option<&SyntaxNode> { | ||
534 | self.syntax().first_child() | ||
535 | } | ||
532 | } | 536 | } |
533 | 537 | ||
534 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | 538 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] |
@@ -598,44 +602,49 @@ pub enum BinOp { | |||
598 | } | 602 | } |
599 | 603 | ||
600 | impl BinExpr { | 604 | impl BinExpr { |
601 | pub fn op(&self) -> Option<BinOp> { | 605 | fn op_details(&self) -> Option<(&SyntaxNode, BinOp)> { |
602 | self.syntax() | 606 | self.syntax().children().find_map(|c| match c.kind() { |
603 | .children() | 607 | PIPEPIPE => Some((c, BinOp::BooleanOr)), |
604 | .filter_map(|c| match c.kind() { | 608 | AMPAMP => Some((c, BinOp::BooleanAnd)), |
605 | PIPEPIPE => Some(BinOp::BooleanOr), | 609 | EQEQ => Some((c, BinOp::EqualityTest)), |
606 | AMPAMP => Some(BinOp::BooleanAnd), | 610 | NEQ => Some((c, BinOp::NegatedEqualityTest)), |
607 | EQEQ => Some(BinOp::EqualityTest), | 611 | LTEQ => Some((c, BinOp::LesserEqualTest)), |
608 | NEQ => Some(BinOp::NegatedEqualityTest), | 612 | GTEQ => Some((c, BinOp::GreaterEqualTest)), |
609 | LTEQ => Some(BinOp::LesserEqualTest), | 613 | L_ANGLE => Some((c, BinOp::LesserTest)), |
610 | GTEQ => Some(BinOp::GreaterEqualTest), | 614 | R_ANGLE => Some((c, BinOp::GreaterTest)), |
611 | L_ANGLE => Some(BinOp::LesserTest), | 615 | PLUS => Some((c, BinOp::Addition)), |
612 | R_ANGLE => Some(BinOp::GreaterTest), | 616 | STAR => Some((c, BinOp::Multiplication)), |
613 | PLUS => Some(BinOp::Addition), | 617 | MINUS => Some((c, BinOp::Subtraction)), |
614 | STAR => Some(BinOp::Multiplication), | 618 | SLASH => Some((c, BinOp::Division)), |
615 | MINUS => Some(BinOp::Subtraction), | 619 | PERCENT => Some((c, BinOp::Remainder)), |
616 | SLASH => Some(BinOp::Division), | 620 | SHL => Some((c, BinOp::LeftShift)), |
617 | PERCENT => Some(BinOp::Remainder), | 621 | SHR => Some((c, BinOp::RightShift)), |
618 | SHL => Some(BinOp::LeftShift), | 622 | CARET => Some((c, BinOp::BitwiseXor)), |
619 | SHR => Some(BinOp::RightShift), | 623 | PIPE => Some((c, BinOp::BitwiseOr)), |
620 | CARET => Some(BinOp::BitwiseXor), | 624 | AMP => Some((c, BinOp::BitwiseAnd)), |
621 | PIPE => Some(BinOp::BitwiseOr), | 625 | DOTDOT => Some((c, BinOp::RangeRightOpen)), |
622 | AMP => Some(BinOp::BitwiseAnd), | 626 | DOTDOTEQ => Some((c, BinOp::RangeRightClosed)), |
623 | DOTDOT => Some(BinOp::RangeRightOpen), | 627 | EQ => Some((c, BinOp::Assignment)), |
624 | DOTDOTEQ => Some(BinOp::RangeRightClosed), | 628 | PLUSEQ => Some((c, BinOp::AddAssign)), |
625 | EQ => Some(BinOp::Assignment), | 629 | SLASHEQ => Some((c, BinOp::DivAssign)), |
626 | PLUSEQ => Some(BinOp::AddAssign), | 630 | STAREQ => Some((c, BinOp::MulAssign)), |
627 | SLASHEQ => Some(BinOp::DivAssign), | 631 | PERCENTEQ => Some((c, BinOp::RemAssign)), |
628 | STAREQ => Some(BinOp::MulAssign), | 632 | SHREQ => Some((c, BinOp::ShrAssign)), |
629 | PERCENTEQ => Some(BinOp::RemAssign), | 633 | SHLEQ => Some((c, BinOp::ShlAssign)), |
630 | SHREQ => Some(BinOp::ShrAssign), | 634 | MINUSEQ => Some((c, BinOp::SubAssign)), |
631 | SHLEQ => Some(BinOp::ShlAssign), | 635 | PIPEEQ => Some((c, BinOp::BitOrAssign)), |
632 | MINUSEQ => Some(BinOp::SubAssign), | 636 | AMPEQ => Some((c, BinOp::BitAndAssign)), |
633 | PIPEEQ => Some(BinOp::BitOrAssign), | 637 | CARETEQ => Some((c, BinOp::BitXorAssign)), |
634 | AMPEQ => Some(BinOp::BitAndAssign), | 638 | _ => None, |
635 | CARETEQ => Some(BinOp::BitXorAssign), | 639 | }) |
636 | _ => None, | 640 | } |
637 | }) | 641 | |
638 | .next() | 642 | pub fn op_kind(&self) -> Option<BinOp> { |
643 | self.op_details().map(|t| t.1) | ||
644 | } | ||
645 | |||
646 | pub fn op(&self) -> Option<&SyntaxNode> { | ||
647 | self.op_details().map(|t| t.0) | ||
639 | } | 648 | } |
640 | 649 | ||
641 | pub fn lhs(&self) -> Option<&Expr> { | 650 | pub fn lhs(&self) -> Option<&Expr> { |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs index aae590cb6..d8de1c4c1 100644 --- a/crates/ra_syntax/src/ptr.rs +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -64,6 +64,12 @@ impl<N: AstNode> AstPtr<N> { | |||
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | impl<N: AstNode> From<AstPtr<N>> for SyntaxNodePtr { | ||
68 | fn from(ptr: AstPtr<N>) -> SyntaxNodePtr { | ||
69 | ptr.raw | ||
70 | } | ||
71 | } | ||
72 | |||
67 | #[test] | 73 | #[test] |
68 | fn test_local_syntax_ptr() { | 74 | fn test_local_syntax_ptr() { |
69 | use crate::{ast, AstNode}; | 75 | use crate::{ast, AstNode}; |
diff --git a/docs/dev/README.md b/docs/dev/README.md index 104dd703d..d81c2f70d 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md | |||
@@ -12,7 +12,11 @@ should be enough to get you started! | |||
12 | To learn more about how rust-analyzer works, see | 12 | To learn more about how rust-analyzer works, see |
13 | [./architecture.md](./architecture.md) document. | 13 | [./architecture.md](./architecture.md) document. |
14 | 14 | ||
15 | Various organizational and process issues are discussed here. | 15 | We also publish rustdoc docs to pages: |
16 | |||
17 | https://rust-analyzer.github.io/rust-analyzer/ra_ide_api/index.html | ||
18 | |||
19 | Various organizational and process issues are discussed in this document. | ||
16 | 20 | ||
17 | # Getting in Touch | 21 | # Getting in Touch |
18 | 22 | ||
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md index f990d5bf0..890b18fcd 100644 --- a/docs/dev/architecture.md +++ b/docs/dev/architecture.md | |||
@@ -130,19 +130,6 @@ APIs in this crate are IDE centric: they take text offsets as input and produce | |||
130 | offsets and strings as output. This works on top of rich code model powered by | 130 | offsets and strings as output. This works on top of rich code model powered by |
131 | `hir`. | 131 | `hir`. |
132 | 132 | ||
133 | ### `crates/ra_ide_api_light` | ||
134 | |||
135 | All IDE features which can be implemented if you only have access to a single | ||
136 | file. `ra_ide_api_light` could be used to enhance editing of Rust code without | ||
137 | the need to fiddle with build-systems, file synchronization and such. | ||
138 | |||
139 | In a sense, `ra_ide_api_light` is just a bunch of pure functions which take a | ||
140 | syntax tree as input. | ||
141 | |||
142 | The tests for `ra_ide_api_light` are `#[cfg(test)] mod tests` unit-tests spread | ||
143 | throughout its modules. | ||
144 | |||
145 | |||
146 | ### `crates/ra_lsp_server` | 133 | ### `crates/ra_lsp_server` |
147 | 134 | ||
148 | An LSP implementation which wraps `ra_ide_api` into a langauge server protocol. | 135 | An LSP implementation which wraps `ra_ide_api` into a langauge server protocol. |