diff options
115 files changed, 6321 insertions, 1820 deletions
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 49d3ee0e9..395ce1ef4 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml | |||
@@ -5,8 +5,8 @@ on: | |||
5 | - release | 5 | - release |
6 | 6 | ||
7 | jobs: | 7 | jobs: |
8 | rust: | 8 | build-server: |
9 | name: Rust | 9 | name: build-server |
10 | runs-on: ${{ matrix.os }} | 10 | runs-on: ${{ matrix.os }} |
11 | strategy: | 11 | strategy: |
12 | matrix: | 12 | matrix: |
@@ -34,29 +34,39 @@ jobs: | |||
34 | with: | 34 | with: |
35 | toolchain: stable | 35 | toolchain: stable |
36 | profile: minimal | 36 | profile: minimal |
37 | target: x86_64-unknown-linux-musl | ||
37 | override: true | 38 | override: true |
38 | components: rustfmt, rust-src | ||
39 | 39 | ||
40 | - name: Build | 40 | - name: Build |
41 | if: matrix.os == 'ubuntu-latest' | ||
41 | uses: actions-rs/cargo@v1 | 42 | uses: actions-rs/cargo@v1 |
43 | env: | ||
44 | CC: clang | ||
42 | with: | 45 | with: |
43 | command: build | 46 | command: build |
44 | args: --release --package ra_lsp_server --bin ra_lsp_server | 47 | args: --package ra_lsp_server --bin ra_lsp_server --release --target x86_64-unknown-linux-musl |
45 | 48 | ||
46 | - name: Strip symbols | 49 | - name: Build |
47 | if: matrix.os == 'ubuntu-latest' | 50 | if: matrix.os != 'ubuntu-latest' |
48 | run: strip ./target/release/ra_lsp_server | 51 | uses: actions-rs/cargo@v1 |
52 | with: | ||
53 | command: build | ||
54 | args: --package ra_lsp_server --bin ra_lsp_server --release | ||
49 | 55 | ||
50 | - name: Create distribution dir | 56 | - name: Create distribution dir |
51 | run: mkdir ./dist | 57 | run: mkdir ./dist |
52 | 58 | ||
53 | - name: Copy binaries (unix) | 59 | - name: Copy binary |
54 | if: matrix.os != 'windows-latest' | 60 | if: matrix.os == 'ubuntu-latest' |
55 | run: cp ./target/release/ra_lsp_server ./dist | 61 | run: cp ./target/x86_64-unknown-linux-musl/release/ra_lsp_server ./dist/ra_lsp_server-linux && strip ./dist/ra_lsp_server-linux |
62 | |||
63 | - name: Copy binary | ||
64 | if: matrix.os == 'macos-latest' | ||
65 | run: cp ./target/release/ra_lsp_server ./dist/ra_lsp_server-mac | ||
56 | 66 | ||
57 | - name: Copy binaries (win) | 67 | - name: Copy binary |
58 | if: matrix.os == 'windows-latest' | 68 | if: matrix.os == 'windows-latest' |
59 | run: copy ./target/release/ra_lsp_server.exe ./dist | 69 | run: copy ./target/release/ra_lsp_server.exe ./dist/ra_lsp_server-windows.exe |
60 | 70 | ||
61 | - name: Upload artifacts | 71 | - name: Upload artifacts |
62 | uses: actions/upload-artifact@v1 | 72 | uses: actions/upload-artifact@v1 |
@@ -64,8 +74,8 @@ jobs: | |||
64 | name: server-${{ matrix.os }} | 74 | name: server-${{ matrix.os }} |
65 | path: ./dist | 75 | path: ./dist |
66 | 76 | ||
67 | type-script: | 77 | build-clients: |
68 | name: TypeScript | 78 | name: build-clients |
69 | runs-on: ubuntu-latest | 79 | runs-on: ubuntu-latest |
70 | steps: | 80 | steps: |
71 | - name: Checkout repository | 81 | - name: Checkout repository |
@@ -83,13 +93,95 @@ jobs: | |||
83 | working-directory: ./editors/code | 93 | working-directory: ./editors/code |
84 | 94 | ||
85 | - name: Copy vscode extension | 95 | - name: Copy vscode extension |
86 | run: mkdir -p ./dist/code && cp ./editors/code/*.vsix ./dist/code/ | 96 | run: mkdir -p ./dist/code && cp ./editors/code/*.vsix ./dist/ |
87 | 97 | ||
88 | - name: Copy emacs mode | 98 | - name: Copy emacs mode |
89 | run: cp -R ./editors/emacs ./dist/ | 99 | run: cp ./editors/emacs/rust-analyzer.el ./dist/rust-analyzer.el |
90 | 100 | ||
91 | - name: Upload artifacts | 101 | - name: Upload artifacts |
92 | uses: actions/upload-artifact@v1 | 102 | uses: actions/upload-artifact@v1 |
93 | with: | 103 | with: |
94 | name: editor-plugins | 104 | name: editor-plugins |
95 | path: ./dist | 105 | path: ./dist |
106 | |||
107 | make-release: | ||
108 | name: make-release | ||
109 | runs-on: ubuntu-latest | ||
110 | needs: ['build-server', 'build-clients'] | ||
111 | steps: | ||
112 | - uses: actions/download-artifact@v1 | ||
113 | with: | ||
114 | name: editor-plugins | ||
115 | path: dist | ||
116 | - uses: actions/download-artifact@v1 | ||
117 | with: | ||
118 | name: server-macos-latest | ||
119 | path: dist | ||
120 | - uses: actions/download-artifact@v1 | ||
121 | with: | ||
122 | name: server-ubuntu-latest | ||
123 | path: dist | ||
124 | - uses: actions/download-artifact@v1 | ||
125 | with: | ||
126 | name: server-windows-latest | ||
127 | path: dist | ||
128 | - run: ls -all ./dist | ||
129 | |||
130 | - run: echo "::set-env name=TAG::$(date --iso)" | ||
131 | - run: 'echo "TAG: $TAG"' | ||
132 | |||
133 | - name: Create Release | ||
134 | id: create_release | ||
135 | uses: actions/create-release@v1 | ||
136 | env: | ||
137 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
138 | with: | ||
139 | tag_name: ${{ env.TAG }} | ||
140 | release_name: ${{ env.TAG }} | ||
141 | draft: false | ||
142 | prerelease: false | ||
143 | |||
144 | - uses: actions/[email protected] | ||
145 | env: | ||
146 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
147 | with: | ||
148 | upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
149 | asset_path: ./dist/ra_lsp_server-linux | ||
150 | asset_name: ra_lsp_server-linux | ||
151 | asset_content_type: application/octet-stream | ||
152 | |||
153 | - uses: actions/[email protected] | ||
154 | env: | ||
155 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
156 | with: | ||
157 | upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
158 | asset_path: ./dist/ra_lsp_server-mac | ||
159 | asset_name: ra_lsp_server-mac | ||
160 | asset_content_type: application/octet-stream | ||
161 | |||
162 | - uses: actions/[email protected] | ||
163 | env: | ||
164 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
165 | with: | ||
166 | upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
167 | asset_path: ./dist/ra_lsp_server-windows.exe | ||
168 | asset_name: ra_lsp_server-windows.exe | ||
169 | asset_content_type: application/octet-stream | ||
170 | |||
171 | - uses: actions/[email protected] | ||
172 | env: | ||
173 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
174 | with: | ||
175 | upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
176 | asset_path: ./dist/rust-analyzer-0.1.0.vsix | ||
177 | asset_name: rust-analyzer-0.1.0.vsix | ||
178 | asset_content_type: application/octet-stream | ||
179 | |||
180 | - uses: actions/[email protected] | ||
181 | env: | ||
182 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
183 | with: | ||
184 | upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
185 | asset_path: ./dist/rust-analyzer.el | ||
186 | asset_name: rust-analyzer.el | ||
187 | asset_content_type: text/plain | ||
diff --git a/Cargo.lock b/Cargo.lock index 90c505f40..67822cb8a 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -5,7 +5,7 @@ name = "aho-corasick" | |||
5 | version = "0.7.6" | 5 | version = "0.7.6" |
6 | source = "registry+https://github.com/rust-lang/crates.io-index" | 6 | source = "registry+https://github.com/rust-lang/crates.io-index" |
7 | dependencies = [ | 7 | dependencies = [ |
8 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 8 | "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
9 | ] | 9 | ] |
10 | 10 | ||
11 | [[package]] | 11 | [[package]] |
@@ -39,8 +39,13 @@ version = "0.1.7" | |||
39 | source = "registry+https://github.com/rust-lang/crates.io-index" | 39 | source = "registry+https://github.com/rust-lang/crates.io-index" |
40 | 40 | ||
41 | [[package]] | 41 | [[package]] |
42 | name = "autocfg" | ||
43 | version = "1.0.0" | ||
44 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
45 | |||
46 | [[package]] | ||
42 | name = "backtrace" | 47 | name = "backtrace" |
43 | version = "0.3.40" | 48 | version = "0.3.42" |
44 | source = "registry+https://github.com/rust-lang/crates.io-index" | 49 | source = "registry+https://github.com/rust-lang/crates.io-index" |
45 | dependencies = [ | 50 | dependencies = [ |
46 | "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", | 51 | "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -54,7 +59,7 @@ name = "backtrace-sys" | |||
54 | version = "0.1.32" | 59 | version = "0.1.32" |
55 | source = "registry+https://github.com/rust-lang/crates.io-index" | 60 | source = "registry+https://github.com/rust-lang/crates.io-index" |
56 | dependencies = [ | 61 | dependencies = [ |
57 | "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)", | 62 | "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", |
58 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", | 63 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", |
59 | ] | 64 | ] |
60 | 65 | ||
@@ -83,10 +88,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
83 | 88 | ||
84 | [[package]] | 89 | [[package]] |
85 | name = "bstr" | 90 | name = "bstr" |
86 | version = "0.2.8" | 91 | version = "0.2.9" |
87 | source = "registry+https://github.com/rust-lang/crates.io-index" | 92 | source = "registry+https://github.com/rust-lang/crates.io-index" |
88 | dependencies = [ | 93 | dependencies = [ |
89 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 94 | "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
90 | ] | 95 | ] |
91 | 96 | ||
92 | [[package]] | 97 | [[package]] |
@@ -115,7 +120,7 @@ dependencies = [ | |||
115 | 120 | ||
116 | [[package]] | 121 | [[package]] |
117 | name = "cc" | 122 | name = "cc" |
118 | version = "1.0.49" | 123 | version = "1.0.50" |
119 | source = "registry+https://github.com/rust-lang/crates.io-index" | 124 | source = "registry+https://github.com/rust-lang/crates.io-index" |
120 | 125 | ||
121 | [[package]] | 126 | [[package]] |
@@ -216,7 +221,7 @@ dependencies = [ | |||
216 | "encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | 221 | "encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", |
217 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 222 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
218 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", | 223 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", |
219 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 224 | "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", |
220 | "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 225 | "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
221 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 226 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
222 | ] | 227 | ] |
@@ -416,10 +421,10 @@ version = "0.4.4" | |||
416 | source = "registry+https://github.com/rust-lang/crates.io-index" | 421 | source = "registry+https://github.com/rust-lang/crates.io-index" |
417 | dependencies = [ | 422 | dependencies = [ |
418 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", | 423 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", |
419 | "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | 424 | "bstr 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", |
420 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | 425 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", |
421 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 426 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
422 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 427 | "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", |
423 | ] | 428 | ] |
424 | 429 | ||
425 | [[package]] | 430 | [[package]] |
@@ -458,10 +463,10 @@ dependencies = [ | |||
458 | 463 | ||
459 | [[package]] | 464 | [[package]] |
460 | name = "indexmap" | 465 | name = "indexmap" |
461 | version = "1.3.0" | 466 | version = "1.3.1" |
462 | source = "registry+https://github.com/rust-lang/crates.io-index" | 467 | source = "registry+https://github.com/rust-lang/crates.io-index" |
463 | dependencies = [ | 468 | dependencies = [ |
464 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | 469 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |
465 | ] | 470 | ] |
466 | 471 | ||
467 | [[package]] | 472 | [[package]] |
@@ -532,7 +537,7 @@ name = "jemalloc-sys" | |||
532 | version = "0.3.2" | 537 | version = "0.3.2" |
533 | source = "registry+https://github.com/rust-lang/crates.io-index" | 538 | source = "registry+https://github.com/rust-lang/crates.io-index" |
534 | dependencies = [ | 539 | dependencies = [ |
535 | "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)", | 540 | "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", |
536 | "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 541 | "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
537 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", | 542 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", |
538 | ] | 543 | ] |
@@ -619,7 +624,7 @@ dependencies = [ | |||
619 | 624 | ||
620 | [[package]] | 625 | [[package]] |
621 | name = "lsp-types" | 626 | name = "lsp-types" |
622 | version = "0.68.1" | 627 | version = "0.69.0" |
623 | source = "registry+https://github.com/rust-lang/crates.io-index" | 628 | source = "registry+https://github.com/rust-lang/crates.io-index" |
624 | dependencies = [ | 629 | dependencies = [ |
625 | "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | 630 | "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -627,7 +632,7 @@ dependencies = [ | |||
627 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", | 632 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", |
628 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", | 633 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", |
629 | "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 634 | "serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
630 | "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 635 | "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |
631 | ] | 636 | ] |
632 | 637 | ||
633 | [[package]] | 638 | [[package]] |
@@ -637,7 +642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
637 | 642 | ||
638 | [[package]] | 643 | [[package]] |
639 | name = "memchr" | 644 | name = "memchr" |
640 | version = "2.2.1" | 645 | version = "2.3.0" |
641 | source = "registry+https://github.com/rust-lang/crates.io-index" | 646 | source = "registry+https://github.com/rust-lang/crates.io-index" |
642 | 647 | ||
643 | [[package]] | 648 | [[package]] |
@@ -711,21 +716,21 @@ dependencies = [ | |||
711 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", | 716 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", |
712 | "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", | 717 | "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", |
713 | "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | 718 | "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", |
714 | "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", | 719 | "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
715 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 720 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
716 | ] | 721 | ] |
717 | 722 | ||
718 | [[package]] | 723 | [[package]] |
719 | name = "num-traits" | 724 | name = "num-traits" |
720 | version = "0.2.10" | 725 | version = "0.2.11" |
721 | source = "registry+https://github.com/rust-lang/crates.io-index" | 726 | source = "registry+https://github.com/rust-lang/crates.io-index" |
722 | dependencies = [ | 727 | dependencies = [ |
723 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | 728 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |
724 | ] | 729 | ] |
725 | 730 | ||
726 | [[package]] | 731 | [[package]] |
727 | name = "num_cpus" | 732 | name = "num_cpus" |
728 | version = "1.11.1" | 733 | version = "1.12.0" |
729 | source = "registry+https://github.com/rust-lang/crates.io-index" | 734 | source = "registry+https://github.com/rust-lang/crates.io-index" |
730 | dependencies = [ | 735 | dependencies = [ |
731 | "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | 736 | "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -734,7 +739,7 @@ dependencies = [ | |||
734 | 739 | ||
735 | [[package]] | 740 | [[package]] |
736 | name = "once_cell" | 741 | name = "once_cell" |
737 | version = "1.2.0" | 742 | version = "1.3.0" |
738 | source = "registry+https://github.com/rust-lang/crates.io-index" | 743 | source = "registry+https://github.com/rust-lang/crates.io-index" |
739 | 744 | ||
740 | [[package]] | 745 | [[package]] |
@@ -835,12 +840,12 @@ dependencies = [ | |||
835 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 840 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", |
836 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", | 841 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", |
837 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 842 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
838 | "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", | 843 | "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", |
839 | "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", | 844 | "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", |
840 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", | 845 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", |
841 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | 846 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |
842 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | 847 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |
843 | "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", | 848 | "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", |
844 | ] | 849 | ] |
845 | 850 | ||
846 | [[package]] | 851 | [[package]] |
@@ -864,8 +869,8 @@ version = "0.1.0" | |||
864 | name = "ra_assists" | 869 | name = "ra_assists" |
865 | version = "0.1.0" | 870 | version = "0.1.0" |
866 | dependencies = [ | 871 | dependencies = [ |
872 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
867 | "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | 873 | "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |
868 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
869 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | 874 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
870 | "ra_db 0.1.0", | 875 | "ra_db 0.1.0", |
871 | "ra_fmt 0.1.0", | 876 | "ra_fmt 0.1.0", |
@@ -900,7 +905,7 @@ dependencies = [ | |||
900 | "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", | 905 | "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", |
901 | "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 906 | "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
902 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 907 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
903 | "lsp-types 0.68.1 (registry+https://github.com/rust-lang/crates.io-index)", | 908 | "lsp-types 0.69.0 (registry+https://github.com/rust-lang/crates.io-index)", |
904 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", | 909 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", |
905 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", | 910 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", |
906 | ] | 911 | ] |
@@ -976,7 +981,7 @@ dependencies = [ | |||
976 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", | 981 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", |
977 | "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", | 982 | "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", |
978 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 983 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
979 | "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 984 | "once_cell 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
980 | "ra_arena 0.1.0", | 985 | "ra_arena 0.1.0", |
981 | "ra_cfg 0.1.0", | 986 | "ra_cfg 0.1.0", |
982 | "ra_db 0.1.0", | 987 | "ra_db 0.1.0", |
@@ -1033,12 +1038,12 @@ dependencies = [ | |||
1033 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1038 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1034 | "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1039 | "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1035 | "fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1040 | "fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", |
1036 | "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1041 | "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1037 | "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1042 | "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1038 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1043 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1039 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1044 | "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1040 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1045 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1041 | "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1046 | "once_cell 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1042 | "proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", | 1047 | "proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)", |
1043 | "ra_assists 0.1.0", | 1048 | "ra_assists 0.1.0", |
1044 | "ra_cfg 0.1.0", | 1049 | "ra_cfg 0.1.0", |
@@ -1048,7 +1053,7 @@ dependencies = [ | |||
1048 | "ra_prof 0.1.0", | 1053 | "ra_prof 0.1.0", |
1049 | "ra_syntax 0.1.0", | 1054 | "ra_syntax 0.1.0", |
1050 | "ra_text_edit 0.1.0", | 1055 | "ra_text_edit 0.1.0", |
1051 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1056 | "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1052 | "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1057 | "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1053 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1058 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1054 | "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1059 | "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1061,11 +1066,12 @@ name = "ra_lsp_server" | |||
1061 | version = "0.1.0" | 1066 | version = "0.1.0" |
1062 | dependencies = [ | 1067 | dependencies = [ |
1063 | "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1068 | "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1069 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1064 | "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1070 | "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1065 | "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1071 | "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1066 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1072 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1067 | "lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1073 | "lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1068 | "lsp-types 0.68.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1074 | "lsp-types 0.69.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1069 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1075 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1070 | "ra_cargo_watch 0.1.0", | 1076 | "ra_cargo_watch 0.1.0", |
1071 | "ra_ide 0.1.0", | 1077 | "ra_ide 0.1.0", |
@@ -1108,11 +1114,11 @@ dependencies = [ | |||
1108 | name = "ra_prof" | 1114 | name = "ra_prof" |
1109 | version = "0.1.0" | 1115 | version = "0.1.0" |
1110 | dependencies = [ | 1116 | dependencies = [ |
1111 | "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", | 1117 | "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", |
1112 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1118 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1113 | "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1119 | "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1114 | "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1120 | "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1115 | "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1121 | "once_cell 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1116 | ] | 1122 | ] |
1117 | 1123 | ||
1118 | [[package]] | 1124 | [[package]] |
@@ -1135,7 +1141,7 @@ version = "0.1.0" | |||
1135 | dependencies = [ | 1141 | dependencies = [ |
1136 | "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1142 | "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1137 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1143 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1138 | "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1144 | "once_cell 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1139 | "ra_parser 0.1.0", | 1145 | "ra_parser 0.1.0", |
1140 | "ra_text_edit 0.1.0", | 1146 | "ra_text_edit 0.1.0", |
1141 | "rowan 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1147 | "rowan 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1144,7 +1150,7 @@ dependencies = [ | |||
1144 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", | 1150 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", |
1145 | "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", | 1151 | "smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", |
1146 | "test_utils 0.1.0", | 1152 | "test_utils 0.1.0", |
1147 | "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", | 1153 | "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1148 | ] | 1154 | ] |
1149 | 1155 | ||
1150 | [[package]] | 1156 | [[package]] |
@@ -1175,7 +1181,7 @@ dependencies = [ | |||
1175 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1181 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1176 | "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1182 | "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1177 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1183 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1178 | "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", | 1184 | "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1179 | ] | 1185 | ] |
1180 | 1186 | ||
1181 | [[package]] | 1187 | [[package]] |
@@ -1206,7 +1212,7 @@ dependencies = [ | |||
1206 | 1212 | ||
1207 | [[package]] | 1213 | [[package]] |
1208 | name = "rand" | 1214 | name = "rand" |
1209 | version = "0.7.2" | 1215 | version = "0.7.3" |
1210 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1211 | dependencies = [ | 1217 | dependencies = [ |
1212 | "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", | 1218 | "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1347,7 +1353,7 @@ dependencies = [ | |||
1347 | "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1353 | "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1348 | "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1354 | "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1349 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1355 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1350 | "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1356 | "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1351 | ] | 1357 | ] |
1352 | 1358 | ||
1353 | [[package]] | 1359 | [[package]] |
@@ -1365,18 +1371,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1365 | 1371 | ||
1366 | [[package]] | 1372 | [[package]] |
1367 | name = "regex" | 1373 | name = "regex" |
1368 | version = "1.3.1" | 1374 | version = "1.3.3" |
1369 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1370 | dependencies = [ | 1376 | dependencies = [ |
1371 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1377 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1372 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1378 | "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1373 | "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", | 1379 | "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", |
1374 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | 1380 | "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1375 | ] | 1381 | ] |
1376 | 1382 | ||
1377 | [[package]] | 1383 | [[package]] |
1378 | name = "regex-syntax" | 1384 | name = "regex-syntax" |
1379 | version = "0.6.12" | 1385 | version = "0.6.13" |
1380 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1386 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1381 | 1387 | ||
1382 | [[package]] | 1388 | [[package]] |
@@ -1443,10 +1449,10 @@ version = "0.14.1" | |||
1443 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1444 | dependencies = [ | 1450 | dependencies = [ |
1445 | "crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", | 1451 | "crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1446 | "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1452 | "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1447 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1453 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1448 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1454 | "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1449 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1455 | "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1450 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1456 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1451 | "salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1457 | "salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1452 | "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1458 | "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1465,10 +1471,10 @@ dependencies = [ | |||
1465 | 1471 | ||
1466 | [[package]] | 1472 | [[package]] |
1467 | name = "same-file" | 1473 | name = "same-file" |
1468 | version = "1.0.5" | 1474 | version = "1.0.6" |
1469 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1470 | dependencies = [ | 1476 | dependencies = [ |
1471 | "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1477 | "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1472 | ] | 1478 | ] |
1473 | 1479 | ||
1474 | [[package]] | 1480 | [[package]] |
@@ -1579,7 +1585,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1579 | dependencies = [ | 1585 | dependencies = [ |
1580 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", | 1586 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", |
1581 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", | 1587 | "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", |
1582 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1588 | "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1583 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", | 1589 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", |
1584 | "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1590 | "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1585 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1591 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1614,7 +1620,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1614 | 1620 | ||
1615 | [[package]] | 1621 | [[package]] |
1616 | name = "thread_local" | 1622 | name = "thread_local" |
1617 | version = "0.3.6" | 1623 | version = "1.0.1" |
1618 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1624 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1619 | dependencies = [ | 1625 | dependencies = [ |
1620 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1626 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1625,7 +1631,7 @@ name = "threadpool" | |||
1625 | version = "1.7.1" | 1631 | version = "1.7.1" |
1626 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1632 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1627 | dependencies = [ | 1633 | dependencies = [ |
1628 | "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1634 | "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1629 | ] | 1635 | ] |
1630 | 1636 | ||
1631 | [[package]] | 1637 | [[package]] |
@@ -1664,7 +1670,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1664 | 1670 | ||
1665 | [[package]] | 1671 | [[package]] |
1666 | name = "url" | 1672 | name = "url" |
1667 | version = "2.1.0" | 1673 | version = "2.1.1" |
1668 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1674 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1669 | dependencies = [ | 1675 | dependencies = [ |
1670 | "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1676 | "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1678,7 +1684,7 @@ name = "uuid" | |||
1678 | version = "0.8.1" | 1684 | version = "0.8.1" |
1679 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1685 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1680 | dependencies = [ | 1686 | dependencies = [ |
1681 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1687 | "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1682 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", | 1688 | "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", |
1683 | ] | 1689 | ] |
1684 | 1690 | ||
@@ -1689,12 +1695,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1689 | 1695 | ||
1690 | [[package]] | 1696 | [[package]] |
1691 | name = "walkdir" | 1697 | name = "walkdir" |
1692 | version = "2.2.9" | 1698 | version = "2.3.1" |
1693 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1699 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1694 | dependencies = [ | 1700 | dependencies = [ |
1695 | "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | 1701 | "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", |
1696 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1702 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1697 | "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1703 | "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
1698 | ] | 1704 | ] |
1699 | 1705 | ||
1700 | [[package]] | 1706 | [[package]] |
@@ -1728,7 +1734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1728 | 1734 | ||
1729 | [[package]] | 1735 | [[package]] |
1730 | name = "winapi-util" | 1736 | name = "winapi-util" |
1731 | version = "0.1.2" | 1737 | version = "0.1.3" |
1732 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1738 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1733 | dependencies = [ | 1739 | dependencies = [ |
1734 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1740 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1756,7 +1762,7 @@ dependencies = [ | |||
1756 | "pico-args 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1762 | "pico-args 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1757 | "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", | 1763 | "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", |
1758 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | 1764 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", |
1759 | "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", | 1765 | "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1760 | ] | 1766 | ] |
1761 | 1767 | ||
1762 | [[package]] | 1768 | [[package]] |
@@ -1774,17 +1780,18 @@ dependencies = [ | |||
1774 | "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" | 1780 | "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" |
1775 | "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" | 1781 | "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" |
1776 | "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" | 1782 | "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" |
1777 | "checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" | 1783 | "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" |
1784 | "checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" | ||
1778 | "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" | 1785 | "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" |
1779 | "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" | 1786 | "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" |
1780 | "checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" | 1787 | "checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" |
1781 | "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" | 1788 | "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" |
1782 | "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" | 1789 | "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" |
1783 | "checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" | 1790 | "checksum bstr 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3ede750122d9d1f87919570cb2cccee38c84fbc8c5599b25c289af40625b7030" |
1784 | "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" | 1791 | "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" |
1785 | "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" | 1792 | "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" |
1786 | "checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" | 1793 | "checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" |
1787 | "checksum cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)" = "e450b8da92aa6f274e7c6437692f9f2ce6d701fb73bacfcf87897b3f89a4c20e" | 1794 | "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" |
1788 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | 1795 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" |
1789 | "checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>" | 1796 | "checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>" |
1790 | "checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>" | 1797 | "checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>" |
@@ -1825,7 +1832,7 @@ dependencies = [ | |||
1825 | "checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" | 1832 | "checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" |
1826 | "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" | 1833 | "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" |
1827 | "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" | 1834 | "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" |
1828 | "checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" | 1835 | "checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" |
1829 | "checksum inotify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24e40d6fd5d64e2082e0c796495c8ef5ad667a96d03e5aaa0becfd9d47bcbfb8" | 1836 | "checksum inotify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24e40d6fd5d64e2082e0c796495c8ef5ad667a96d03e5aaa0becfd9d47bcbfb8" |
1830 | "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" | 1837 | "checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" |
1831 | "checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349" | 1838 | "checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349" |
@@ -1846,18 +1853,18 @@ dependencies = [ | |||
1846 | "checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" | 1853 | "checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" |
1847 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" | 1854 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" |
1848 | "checksum lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5383e043329615624bbf45e1ba27bd75c176762b2592855c659bc28ac580a06b" | 1855 | "checksum lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5383e043329615624bbf45e1ba27bd75c176762b2592855c659bc28ac580a06b" |
1849 | "checksum lsp-types 0.68.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19b79f72914b929daa263483134b8974962cdebc731593b11508afb7f9acec80" | 1856 | "checksum lsp-types 0.69.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd78b254376c0734bb75c200616e256adbf2c3685497fcc1124db9daf5958630" |
1850 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" | 1857 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" |
1851 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" | 1858 | "checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" |
1852 | "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" | 1859 | "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" |
1853 | "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" | 1860 | "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" |
1854 | "checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" | 1861 | "checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" |
1855 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" | 1862 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" |
1856 | "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" | 1863 | "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" |
1857 | "checksum notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd" | 1864 | "checksum notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd" |
1858 | "checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" | 1865 | "checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" |
1859 | "checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" | 1866 | "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" |
1860 | "checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" | 1867 | "checksum once_cell 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5941ec2d5ee5916c709580d71553b81a633df245bcc73c04dcbd62152ceefc4" |
1861 | "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" | 1868 | "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" |
1862 | "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" | 1869 | "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" |
1863 | "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" | 1870 | "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" |
@@ -1874,7 +1881,7 @@ dependencies = [ | |||
1874 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" | 1881 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" |
1875 | "checksum ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc898f237e4b4498959ae0100c688793a23e77624d44ef710ba70094217f98e0" | 1882 | "checksum ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc898f237e4b4498959ae0100c688793a23e77624d44ef710ba70094217f98e0" |
1876 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" | 1883 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" |
1877 | "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" | 1884 | "checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" |
1878 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" | 1885 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" |
1879 | "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" | 1886 | "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" |
1880 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" | 1887 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" |
@@ -1892,8 +1899,8 @@ dependencies = [ | |||
1892 | "checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" | 1899 | "checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" |
1893 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" | 1900 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" |
1894 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" | 1901 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" |
1895 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" | 1902 | "checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87" |
1896 | "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" | 1903 | "checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90" |
1897 | "checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954" | 1904 | "checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954" |
1898 | "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" | 1905 | "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" |
1899 | "checksum rowan 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d03d4eff7a4e8dcc362e4c06bb2b1b33af4bcd64336c7f40a31a05850336b6c" | 1906 | "checksum rowan 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d03d4eff7a4e8dcc362e4c06bb2b1b33af4bcd64336c7f40a31a05850336b6c" |
@@ -1904,7 +1911,7 @@ dependencies = [ | |||
1904 | "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" | 1911 | "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" |
1905 | "checksum salsa 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a006c56096acaaa5e82e5974c28d05ff1e84aa70615f19c53fecf8a1afb2fd2" | 1912 | "checksum salsa 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a006c56096acaaa5e82e5974c28d05ff1e84aa70615f19c53fecf8a1afb2fd2" |
1906 | "checksum salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "038a09b6271446f1123f142fe7e5bef6d4687c4cf82e6986be574c2af3745530" | 1913 | "checksum salsa-macros 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "038a09b6271446f1123f142fe7e5bef6d4687c4cf82e6986be574c2af3745530" |
1907 | "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" | 1914 | "checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" |
1908 | "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" | 1915 | "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" |
1909 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" | 1916 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" |
1910 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" | 1917 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" |
@@ -1922,23 +1929,23 @@ dependencies = [ | |||
1922 | "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" | 1929 | "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" |
1923 | "checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579" | 1930 | "checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579" |
1924 | "checksum thin-dst 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c52fd98a9e4913c466d83381a59245691875d2f3e04611fca57f964bd8aa96e1" | 1931 | "checksum thin-dst 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c52fd98a9e4913c466d83381a59245691875d2f3e04611fca57f964bd8aa96e1" |
1925 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" | 1932 | "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" |
1926 | "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" | 1933 | "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" |
1927 | "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" | 1934 | "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" |
1928 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" | 1935 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" |
1929 | "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" | 1936 | "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" |
1930 | "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" | 1937 | "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" |
1931 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" | 1938 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" |
1932 | "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" | 1939 | "checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" |
1933 | "checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" | 1940 | "checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" |
1934 | "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" | 1941 | "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" |
1935 | "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" | 1942 | "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" |
1936 | "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" | 1943 | "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" |
1937 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" | 1944 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" |
1938 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" | 1945 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" |
1939 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" | 1946 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" |
1940 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | 1947 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" |
1941 | "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" | 1948 | "checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" |
1942 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | 1949 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
1943 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" | 1950 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" |
1944 | "checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" | 1951 | "checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" |
@@ -1,4 +1,6 @@ | |||
1 | # Rust Analyzer | 1 | <p align="center"> |
2 | <img src="https://user-images.githubusercontent.com/1711539/72443316-5a79f280-37ae-11ea-858f-035209ece2dd.png" alt="rust-analyzer logo"> | ||
3 | </p> | ||
2 | 4 | ||
3 | Rust Analyzer is an **experimental** modular compiler frontend for the Rust | 5 | Rust Analyzer is an **experimental** modular compiler frontend for the Rust |
4 | language. It is a part of a larger rls-2.0 effort to create excellent IDE | 6 | language. It is a part of a larger rls-2.0 effort to create excellent IDE |
@@ -1,6 +1,6 @@ | |||
1 | status = [ | 1 | status = [ |
2 | "Rust (ubuntu-latest)", | 2 | "Rust (ubuntu-latest)", |
3 | "Rust (windows-latest)", | 3 | # "Rust (windows-latest)", |
4 | "Rust (macos-latest)", | 4 | "Rust (macos-latest)", |
5 | "TypeScript" | 5 | "TypeScript" |
6 | ] | 6 | ] |
diff --git a/crates/ra_assists/Cargo.toml b/crates/ra_assists/Cargo.toml index 50be8d9bc..0d2109e4e 100644 --- a/crates/ra_assists/Cargo.toml +++ b/crates/ra_assists/Cargo.toml | |||
@@ -11,7 +11,7 @@ doctest = false | |||
11 | format-buf = "1.0.0" | 11 | format-buf = "1.0.0" |
12 | join_to_string = "0.1.3" | 12 | join_to_string = "0.1.3" |
13 | rustc-hash = "1.0" | 13 | rustc-hash = "1.0" |
14 | itertools = "0.8.0" | 14 | either = "1.5" |
15 | 15 | ||
16 | ra_syntax = { path = "../ra_syntax" } | 16 | ra_syntax = { path = "../ra_syntax" } |
17 | ra_text_edit = { path = "../ra_text_edit" } | 17 | ra_text_edit = { path = "../ra_text_edit" } |
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index 28152f724..43f0d664b 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | //! This module defines `AssistCtx` -- the API surface that is exposed to assists. | 1 | //! This module defines `AssistCtx` -- the API surface that is exposed to assists. |
2 | use hir::{db::HirDatabase, InFile, SourceAnalyzer}; | 2 | use either::Either; |
3 | use hir::{db::HirDatabase, InFile, SourceAnalyzer, SourceBinder}; | ||
3 | use ra_db::FileRange; | 4 | use ra_db::FileRange; |
4 | use ra_fmt::{leading_indent, reindent}; | 5 | use ra_fmt::{leading_indent, reindent}; |
5 | use ra_syntax::{ | 6 | use ra_syntax::{ |
@@ -9,12 +10,12 @@ use ra_syntax::{ | |||
9 | }; | 10 | }; |
10 | use ra_text_edit::TextEditBuilder; | 11 | use ra_text_edit::TextEditBuilder; |
11 | 12 | ||
12 | use crate::{AssistAction, AssistId, AssistLabel}; | 13 | use crate::{AssistAction, AssistId, AssistLabel, ResolvedAssist}; |
13 | 14 | ||
14 | #[derive(Clone, Debug)] | 15 | #[derive(Clone, Debug)] |
15 | pub(crate) enum Assist { | 16 | pub(crate) enum Assist { |
16 | Unresolved { label: AssistLabel }, | 17 | Unresolved { label: AssistLabel }, |
17 | Resolved { label: AssistLabel, action: AssistAction }, | 18 | Resolved { assist: ResolvedAssist }, |
18 | } | 19 | } |
19 | 20 | ||
20 | /// `AssistCtx` allows to apply an assist or check if it could be applied. | 21 | /// `AssistCtx` allows to apply an assist or check if it could be applied. |
@@ -81,16 +82,45 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
81 | self, | 82 | self, |
82 | id: AssistId, | 83 | id: AssistId, |
83 | label: impl Into<String>, | 84 | label: impl Into<String>, |
84 | f: impl FnOnce(&mut AssistBuilder), | 85 | f: impl FnOnce(&mut ActionBuilder), |
85 | ) -> Option<Assist> { | 86 | ) -> Option<Assist> { |
86 | let label = AssistLabel { label: label.into(), id }; | 87 | let label = AssistLabel { label: label.into(), id }; |
88 | assert!(label.label.chars().nth(0).unwrap().is_uppercase()); | ||
89 | |||
87 | let assist = if self.should_compute_edit { | 90 | let assist = if self.should_compute_edit { |
88 | let action = { | 91 | let action = { |
89 | let mut edit = AssistBuilder::default(); | 92 | let mut edit = ActionBuilder::default(); |
90 | f(&mut edit); | 93 | f(&mut edit); |
91 | edit.build() | 94 | edit.build() |
92 | }; | 95 | }; |
93 | Assist::Resolved { label, action } | 96 | Assist::Resolved { assist: ResolvedAssist { label, action_data: Either::Left(action) } } |
97 | } else { | ||
98 | Assist::Unresolved { label } | ||
99 | }; | ||
100 | |||
101 | Some(assist) | ||
102 | } | ||
103 | |||
104 | #[allow(dead_code)] // will be used for auto import assist with multiple actions | ||
105 | pub(crate) fn add_assist_group( | ||
106 | self, | ||
107 | id: AssistId, | ||
108 | label: impl Into<String>, | ||
109 | f: impl FnOnce() -> Vec<ActionBuilder>, | ||
110 | ) -> Option<Assist> { | ||
111 | let label = AssistLabel { label: label.into(), id }; | ||
112 | let assist = if self.should_compute_edit { | ||
113 | let actions = f(); | ||
114 | assert!(!actions.is_empty(), "Assist cannot have no"); | ||
115 | |||
116 | Assist::Resolved { | ||
117 | assist: ResolvedAssist { | ||
118 | label, | ||
119 | action_data: Either::Right( | ||
120 | actions.into_iter().map(ActionBuilder::build).collect(), | ||
121 | ), | ||
122 | }, | ||
123 | } | ||
94 | } else { | 124 | } else { |
95 | Assist::Unresolved { label } | 125 | Assist::Unresolved { label } |
96 | }; | 126 | }; |
@@ -112,12 +142,16 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
112 | pub(crate) fn covering_element(&self) -> SyntaxElement { | 142 | pub(crate) fn covering_element(&self) -> SyntaxElement { |
113 | find_covering_element(self.source_file.syntax(), self.frange.range) | 143 | find_covering_element(self.source_file.syntax(), self.frange.range) |
114 | } | 144 | } |
145 | pub(crate) fn source_binder(&self) -> SourceBinder<'a, DB> { | ||
146 | SourceBinder::new(self.db) | ||
147 | } | ||
115 | pub(crate) fn source_analyzer( | 148 | pub(crate) fn source_analyzer( |
116 | &self, | 149 | &self, |
117 | node: &SyntaxNode, | 150 | node: &SyntaxNode, |
118 | offset: Option<TextUnit>, | 151 | offset: Option<TextUnit>, |
119 | ) -> SourceAnalyzer { | 152 | ) -> SourceAnalyzer { |
120 | SourceAnalyzer::new(self.db, InFile::new(self.frange.file_id.into(), node), offset) | 153 | let src = InFile::new(self.frange.file_id.into(), node); |
154 | self.source_binder().analyze(src, offset) | ||
121 | } | 155 | } |
122 | 156 | ||
123 | pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { | 157 | pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { |
@@ -126,13 +160,20 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> { | |||
126 | } | 160 | } |
127 | 161 | ||
128 | #[derive(Default)] | 162 | #[derive(Default)] |
129 | pub(crate) struct AssistBuilder { | 163 | pub(crate) struct ActionBuilder { |
130 | edit: TextEditBuilder, | 164 | edit: TextEditBuilder, |
131 | cursor_position: Option<TextUnit>, | 165 | cursor_position: Option<TextUnit>, |
132 | target: Option<TextRange>, | 166 | target: Option<TextRange>, |
167 | label: Option<String>, | ||
133 | } | 168 | } |
134 | 169 | ||
135 | impl AssistBuilder { | 170 | impl ActionBuilder { |
171 | #[allow(dead_code)] | ||
172 | /// Adds a custom label to the action, if it needs to be different from the assist label | ||
173 | pub(crate) fn label(&mut self, label: impl Into<String>) { | ||
174 | self.label = Some(label.into()) | ||
175 | } | ||
176 | |||
136 | /// Replaces specified `range` of text with a given string. | 177 | /// Replaces specified `range` of text with a given string. |
137 | pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) { | 178 | pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) { |
138 | self.edit.replace(range, replace_with.into()) | 179 | self.edit.replace(range, replace_with.into()) |
@@ -191,6 +232,7 @@ impl AssistBuilder { | |||
191 | edit: self.edit.finish(), | 232 | edit: self.edit.finish(), |
192 | cursor_position: self.cursor_position, | 233 | cursor_position: self.cursor_position, |
193 | target: self.target, | 234 | target: self.target, |
235 | label: self.label, | ||
194 | } | 236 | } |
195 | } | 237 | } |
196 | } | 238 | } |
diff --git a/crates/ra_assists/src/assists/add_custom_impl.rs b/crates/ra_assists/src/assists/add_custom_impl.rs index 037306fd6..f91034967 100644 --- a/crates/ra_assists/src/assists/add_custom_impl.rs +++ b/crates/ra_assists/src/assists/add_custom_impl.rs | |||
@@ -10,7 +10,7 @@ use ra_syntax::{ | |||
10 | TextRange, TextUnit, | 10 | TextRange, TextUnit, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | const DERIVE_TRAIT: &'static str = "derive"; | 13 | const DERIVE_TRAIT: &str = "derive"; |
14 | 14 | ||
15 | // Assist: add_custom_impl | 15 | // Assist: add_custom_impl |
16 | // | 16 | // |
@@ -49,7 +49,10 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
49 | let annotated_name = annotated.syntax().text().to_string(); | 49 | let annotated_name = annotated.syntax().text().to_string(); |
50 | let start_offset = annotated.syntax().parent()?.text_range().end(); | 50 | let start_offset = annotated.syntax().parent()?.text_range().end(); |
51 | 51 | ||
52 | ctx.add_assist(AssistId("add_custom_impl"), "add custom impl", |edit| { | 52 | let label = |
53 | format!("Add custom impl '{}' for '{}'", trait_token.text().as_str(), annotated_name); | ||
54 | |||
55 | ctx.add_assist(AssistId("add_custom_impl"), label, |edit| { | ||
53 | edit.target(attr.syntax().text_range()); | 56 | edit.target(attr.syntax().text_range()); |
54 | 57 | ||
55 | let new_attr_input = input | 58 | let new_attr_input = input |
diff --git a/crates/ra_assists/src/assists/add_derive.rs b/crates/ra_assists/src/assists/add_derive.rs index 764b17bd8..6d9af3905 100644 --- a/crates/ra_assists/src/assists/add_derive.rs +++ b/crates/ra_assists/src/assists/add_derive.rs | |||
@@ -28,7 +28,7 @@ use crate::{Assist, AssistCtx, AssistId}; | |||
28 | pub(crate) fn add_derive(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 28 | pub(crate) fn add_derive(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
29 | let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?; | 29 | let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?; |
30 | let node_start = derive_insertion_offset(&nominal)?; | 30 | let node_start = derive_insertion_offset(&nominal)?; |
31 | ctx.add_assist(AssistId("add_derive"), "add `#[derive]`", |edit| { | 31 | ctx.add_assist(AssistId("add_derive"), "Add `#[derive]`", |edit| { |
32 | let derive_attr = nominal | 32 | let derive_attr = nominal |
33 | .attrs() | 33 | .attrs() |
34 | .filter_map(|x| x.as_simple_call()) | 34 | .filter_map(|x| x.as_simple_call()) |
diff --git a/crates/ra_assists/src/assists/add_explicit_type.rs b/crates/ra_assists/src/assists/add_explicit_type.rs index 2c602a79e..f9f826b88 100644 --- a/crates/ra_assists/src/assists/add_explicit_type.rs +++ b/crates/ra_assists/src/assists/add_explicit_type.rs | |||
@@ -47,10 +47,14 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx<impl HirDatabase>) -> Option<Assi | |||
47 | return None; | 47 | return None; |
48 | } | 48 | } |
49 | 49 | ||
50 | ctx.add_assist(AssistId("add_explicit_type"), "add explicit type", |edit| { | 50 | ctx.add_assist( |
51 | edit.target(pat_range); | 51 | AssistId("add_explicit_type"), |
52 | edit.insert(name_range.end(), format!(": {}", ty.display(db))); | 52 | format!("Insert explicit type '{}'", ty.display(db)), |
53 | }) | 53 | |edit| { |
54 | edit.target(pat_range); | ||
55 | edit.insert(name_range.end(), format!(": {}", ty.display(db))); | ||
56 | }, | ||
57 | ) | ||
54 | } | 58 | } |
55 | 59 | ||
56 | #[cfg(test)] | 60 | #[cfg(test)] |
diff --git a/crates/ra_assists/src/assists/add_impl.rs b/crates/ra_assists/src/assists/add_impl.rs index 7da0cfd0d..4b326c837 100644 --- a/crates/ra_assists/src/assists/add_impl.rs +++ b/crates/ra_assists/src/assists/add_impl.rs | |||
@@ -30,7 +30,7 @@ use crate::{Assist, AssistCtx, AssistId}; | |||
30 | pub(crate) fn add_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 30 | pub(crate) fn add_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
31 | let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?; | 31 | let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?; |
32 | let name = nominal.name()?; | 32 | let name = nominal.name()?; |
33 | ctx.add_assist(AssistId("add_impl"), "add impl", |edit| { | 33 | ctx.add_assist(AssistId("add_impl"), format!("Implement {}", name.text().as_str()), |edit| { |
34 | edit.target(nominal.syntax().text_range()); | 34 | edit.target(nominal.syntax().text_range()); |
35 | let type_params = nominal.type_param_list(); | 35 | let type_params = nominal.type_param_list(); |
36 | let start_offset = nominal.syntax().text_range().end(); | 36 | let start_offset = nominal.syntax().text_range().end(); |
diff --git a/crates/ra_assists/src/assists/add_import.rs b/crates/ra_assists/src/assists/add_import.rs index b8752cbad..bf6cfe865 100644 --- a/crates/ra_assists/src/assists/add_import.rs +++ b/crates/ra_assists/src/assists/add_import.rs | |||
@@ -72,7 +72,7 @@ pub(crate) fn add_import(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
72 | } | 72 | } |
73 | }; | 73 | }; |
74 | 74 | ||
75 | ctx.add_assist(AssistId("add_import"), format!("import {}", fmt_segments(&segments)), |edit| { | 75 | ctx.add_assist(AssistId("add_import"), format!("Import {}", fmt_segments(&segments)), |edit| { |
76 | apply_auto_import(&position, &path, &segments, edit.text_edit_builder()); | 76 | apply_auto_import(&position, &path, &segments, edit.text_edit_builder()); |
77 | }) | 77 | }) |
78 | } | 78 | } |
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs index bf1136193..5bb937bde 100644 --- a/crates/ra_assists/src/assists/add_missing_impl_members.rs +++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs | |||
@@ -48,7 +48,7 @@ pub(crate) fn add_missing_impl_members(ctx: AssistCtx<impl HirDatabase>) -> Opti | |||
48 | ctx, | 48 | ctx, |
49 | AddMissingImplMembersMode::NoDefaultMethods, | 49 | AddMissingImplMembersMode::NoDefaultMethods, |
50 | "add_impl_missing_members", | 50 | "add_impl_missing_members", |
51 | "add missing impl members", | 51 | "Implement missing members", |
52 | ) | 52 | ) |
53 | } | 53 | } |
54 | 54 | ||
@@ -89,7 +89,7 @@ pub(crate) fn add_missing_default_members(ctx: AssistCtx<impl HirDatabase>) -> O | |||
89 | ctx, | 89 | ctx, |
90 | AddMissingImplMembersMode::DefaultMethodsOnly, | 90 | AddMissingImplMembersMode::DefaultMethodsOnly, |
91 | "add_impl_default_members", | 91 | "add_impl_default_members", |
92 | "add impl default members", | 92 | "Implement default members", |
93 | ) | 93 | ) |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs index b2f946fac..8db63f762 100644 --- a/crates/ra_assists/src/assists/add_new.rs +++ b/crates/ra_assists/src/assists/add_new.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use format_buf::format; | 1 | use format_buf::format; |
2 | use hir::{db::HirDatabase, FromSource, InFile}; | 2 | use hir::{db::HirDatabase, InFile}; |
3 | use join_to_string::join; | 3 | use join_to_string::join; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
5 | ast::{ | 5 | ast::{ |
@@ -43,7 +43,7 @@ pub(crate) fn add_new(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
43 | // Return early if we've found an existing new fn | 43 | // Return early if we've found an existing new fn |
44 | let impl_block = find_struct_impl(&ctx, &strukt)?; | 44 | let impl_block = find_struct_impl(&ctx, &strukt)?; |
45 | 45 | ||
46 | ctx.add_assist(AssistId("add_new"), "add new fn", |edit| { | 46 | ctx.add_assist(AssistId("add_new"), "Add default constructor", |edit| { |
47 | edit.target(strukt.syntax().text_range()); | 47 | edit.target(strukt.syntax().text_range()); |
48 | 48 | ||
49 | let mut buf = String::with_capacity(512); | 49 | let mut buf = String::with_capacity(512); |
@@ -136,15 +136,16 @@ fn find_struct_impl( | |||
136 | let module = strukt.syntax().ancestors().find(|node| { | 136 | let module = strukt.syntax().ancestors().find(|node| { |
137 | ast::Module::can_cast(node.kind()) || ast::SourceFile::can_cast(node.kind()) | 137 | ast::Module::can_cast(node.kind()) || ast::SourceFile::can_cast(node.kind()) |
138 | })?; | 138 | })?; |
139 | let mut sb = ctx.source_binder(); | ||
139 | 140 | ||
140 | let struct_ty = { | 141 | let struct_ty = { |
141 | let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() }; | 142 | let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() }; |
142 | hir::Struct::from_source(db, src)?.ty(db) | 143 | sb.to_def(src)?.ty(db) |
143 | }; | 144 | }; |
144 | 145 | ||
145 | let block = module.descendants().filter_map(ast::ImplBlock::cast).find_map(|impl_blk| { | 146 | let block = module.descendants().filter_map(ast::ImplBlock::cast).find_map(|impl_blk| { |
146 | let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() }; | 147 | let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() }; |
147 | let blk = hir::ImplBlock::from_source(db, src)?; | 148 | let blk = sb.to_def(src)?; |
148 | 149 | ||
149 | let same_ty = blk.target_ty(db) == struct_ty; | 150 | let same_ty = blk.target_ty(db) == struct_ty; |
150 | let not_trait_impl = blk.target_trait(db).is_none(); | 151 | let not_trait_impl = blk.target_trait(db).is_none(); |
diff --git a/crates/ra_assists/src/assists/apply_demorgan.rs b/crates/ra_assists/src/assists/apply_demorgan.rs index 7c57c0560..666dce4e6 100644 --- a/crates/ra_assists/src/assists/apply_demorgan.rs +++ b/crates/ra_assists/src/assists/apply_demorgan.rs | |||
@@ -39,7 +39,7 @@ pub(crate) fn apply_demorgan(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> | |||
39 | let not_lhs = invert_boolean_expression(&lhs)?; | 39 | let not_lhs = invert_boolean_expression(&lhs)?; |
40 | let not_rhs = invert_boolean_expression(&rhs)?; | 40 | let not_rhs = invert_boolean_expression(&rhs)?; |
41 | 41 | ||
42 | ctx.add_assist(AssistId("apply_demorgan"), "apply demorgan's law", |edit| { | 42 | ctx.add_assist(AssistId("apply_demorgan"), "Apply De Morgan's law", |edit| { |
43 | edit.target(op_range); | 43 | edit.target(op_range); |
44 | edit.replace(op_range, opposite_op); | 44 | edit.replace(op_range, opposite_op); |
45 | edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text())); | 45 | edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text())); |
diff --git a/crates/ra_assists/src/assists/change_visibility.rs b/crates/ra_assists/src/assists/change_visibility.rs index 132c9dc1d..fd766bb46 100644 --- a/crates/ra_assists/src/assists/change_visibility.rs +++ b/crates/ra_assists/src/assists/change_visibility.rs | |||
@@ -57,7 +57,7 @@ fn add_vis(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
57 | (vis_offset(field.syntax()), ident.text_range()) | 57 | (vis_offset(field.syntax()), ident.text_range()) |
58 | }; | 58 | }; |
59 | 59 | ||
60 | ctx.add_assist(AssistId("change_visibility"), "make pub(crate)", |edit| { | 60 | ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| { |
61 | edit.target(target); | 61 | edit.target(target); |
62 | edit.insert(offset, "pub(crate) "); | 62 | edit.insert(offset, "pub(crate) "); |
63 | edit.set_cursor(offset); | 63 | edit.set_cursor(offset); |
@@ -77,14 +77,18 @@ fn vis_offset(node: &SyntaxNode) -> TextUnit { | |||
77 | 77 | ||
78 | fn change_vis(ctx: AssistCtx<impl HirDatabase>, vis: ast::Visibility) -> Option<Assist> { | 78 | fn change_vis(ctx: AssistCtx<impl HirDatabase>, vis: ast::Visibility) -> Option<Assist> { |
79 | if vis.syntax().text() == "pub" { | 79 | if vis.syntax().text() == "pub" { |
80 | return ctx.add_assist(AssistId("change_visibility"), "change to pub(crate)", |edit| { | 80 | return ctx.add_assist( |
81 | edit.target(vis.syntax().text_range()); | 81 | AssistId("change_visibility"), |
82 | edit.replace(vis.syntax().text_range(), "pub(crate)"); | 82 | "Change Visibility to pub(crate)", |
83 | edit.set_cursor(vis.syntax().text_range().start()) | 83 | |edit| { |
84 | }); | 84 | edit.target(vis.syntax().text_range()); |
85 | edit.replace(vis.syntax().text_range(), "pub(crate)"); | ||
86 | edit.set_cursor(vis.syntax().text_range().start()) | ||
87 | }, | ||
88 | ); | ||
85 | } | 89 | } |
86 | if vis.syntax().text() == "pub(crate)" { | 90 | if vis.syntax().text() == "pub(crate)" { |
87 | return ctx.add_assist(AssistId("change_visibility"), "change to pub", |edit| { | 91 | return ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub", |edit| { |
88 | edit.target(vis.syntax().text_range()); | 92 | edit.target(vis.syntax().text_range()); |
89 | edit.replace(vis.syntax().text_range(), "pub"); | 93 | edit.replace(vis.syntax().text_range(), "pub"); |
90 | edit.set_cursor(vis.syntax().text_range().start()); | 94 | edit.set_cursor(vis.syntax().text_range().start()); |
diff --git a/crates/ra_assists/src/assists/early_return.rs b/crates/ra_assists/src/assists/early_return.rs index 023917aca..487ee9eef 100644 --- a/crates/ra_assists/src/assists/early_return.rs +++ b/crates/ra_assists/src/assists/early_return.rs | |||
@@ -95,7 +95,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Opt | |||
95 | then_block.syntax().last_child_or_token().filter(|t| t.kind() == R_CURLY)?; | 95 | then_block.syntax().last_child_or_token().filter(|t| t.kind() == R_CURLY)?; |
96 | let cursor_position = ctx.frange.range.start(); | 96 | let cursor_position = ctx.frange.range.start(); |
97 | 97 | ||
98 | ctx.add_assist(AssistId("convert_to_guarded_return"), "convert to guarded return", |edit| { | 98 | ctx.add_assist(AssistId("convert_to_guarded_return"), "Convert to guarded return", |edit| { |
99 | let if_indent_level = IndentLevel::from_node(&if_expr.syntax()); | 99 | let if_indent_level = IndentLevel::from_node(&if_expr.syntax()); |
100 | let new_block = match if_let_pat { | 100 | let new_block = match if_let_pat { |
101 | None => { | 101 | None => { |
diff --git a/crates/ra_assists/src/assists/fill_match_arms.rs b/crates/ra_assists/src/assists/fill_match_arms.rs index 99d80998c..01758d23a 100644 --- a/crates/ra_assists/src/assists/fill_match_arms.rs +++ b/crates/ra_assists/src/assists/fill_match_arms.rs | |||
@@ -57,7 +57,7 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
57 | 57 | ||
58 | let db = ctx.db; | 58 | let db = ctx.db; |
59 | 59 | ||
60 | ctx.add_assist(AssistId("fill_match_arms"), "fill match arms", |edit| { | 60 | ctx.add_assist(AssistId("fill_match_arms"), "Fill match arms", |edit| { |
61 | let indent_level = IndentLevel::from_node(match_arm_list.syntax()); | 61 | let indent_level = IndentLevel::from_node(match_arm_list.syntax()); |
62 | 62 | ||
63 | let new_arm_list = { | 63 | let new_arm_list = { |
diff --git a/crates/ra_assists/src/assists/flip_binexpr.rs b/crates/ra_assists/src/assists/flip_binexpr.rs index 2d91b2a7e..2074087cd 100644 --- a/crates/ra_assists/src/assists/flip_binexpr.rs +++ b/crates/ra_assists/src/assists/flip_binexpr.rs | |||
@@ -34,7 +34,7 @@ pub(crate) fn flip_binexpr(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
34 | return None; | 34 | return None; |
35 | } | 35 | } |
36 | 36 | ||
37 | ctx.add_assist(AssistId("flip_binexpr"), "flip binary expression", |edit| { | 37 | ctx.add_assist(AssistId("flip_binexpr"), "Flip binary expression", |edit| { |
38 | edit.target(op_range); | 38 | edit.target(op_range); |
39 | if let FlipAction::FlipAndReplaceOp(new_op) = action { | 39 | if let FlipAction::FlipAndReplaceOp(new_op) = action { |
40 | edit.replace(op_range, new_op); | 40 | edit.replace(op_range, new_op); |
diff --git a/crates/ra_assists/src/assists/flip_comma.rs b/crates/ra_assists/src/assists/flip_comma.rs index 9be1c1dc6..dd0c405ed 100644 --- a/crates/ra_assists/src/assists/flip_comma.rs +++ b/crates/ra_assists/src/assists/flip_comma.rs | |||
@@ -29,7 +29,7 @@ pub(crate) fn flip_comma(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
29 | return None; | 29 | return None; |
30 | } | 30 | } |
31 | 31 | ||
32 | ctx.add_assist(AssistId("flip_comma"), "flip comma", |edit| { | 32 | ctx.add_assist(AssistId("flip_comma"), "Flip comma", |edit| { |
33 | edit.target(comma.text_range()); | 33 | edit.target(comma.text_range()); |
34 | edit.replace(prev.text_range(), next.to_string()); | 34 | edit.replace(prev.text_range(), next.to_string()); |
35 | edit.replace(next.text_range(), prev.to_string()); | 35 | edit.replace(next.text_range(), prev.to_string()); |
diff --git a/crates/ra_assists/src/assists/flip_trait_bound.rs b/crates/ra_assists/src/assists/flip_trait_bound.rs index 6017b39dd..50b3fa492 100644 --- a/crates/ra_assists/src/assists/flip_trait_bound.rs +++ b/crates/ra_assists/src/assists/flip_trait_bound.rs | |||
@@ -33,7 +33,7 @@ pub(crate) fn flip_trait_bound(ctx: AssistCtx<impl HirDatabase>) -> Option<Assis | |||
33 | non_trivia_sibling(plus.clone().into(), Direction::Next)?, | 33 | non_trivia_sibling(plus.clone().into(), Direction::Next)?, |
34 | ); | 34 | ); |
35 | 35 | ||
36 | ctx.add_assist(AssistId("flip_trait_bound"), "flip trait bound", |edit| { | 36 | ctx.add_assist(AssistId("flip_trait_bound"), "Flip trait bounds", |edit| { |
37 | edit.target(plus.text_range()); | 37 | edit.target(plus.text_range()); |
38 | edit.replace(before.text_range(), after.to_string()); | 38 | edit.replace(before.text_range(), after.to_string()); |
39 | edit.replace(after.text_range(), before.to_string()); | 39 | edit.replace(after.text_range(), before.to_string()); |
diff --git a/crates/ra_assists/src/assists/inline_local_variable.rs b/crates/ra_assists/src/assists/inline_local_variable.rs index 18a34502c..45e0f983f 100644 --- a/crates/ra_assists/src/assists/inline_local_variable.rs +++ b/crates/ra_assists/src/assists/inline_local_variable.rs | |||
@@ -4,7 +4,7 @@ use ra_syntax::{ | |||
4 | TextRange, | 4 | TextRange, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | use crate::assist_ctx::AssistBuilder; | 7 | use crate::assist_ctx::ActionBuilder; |
8 | use crate::{Assist, AssistCtx, AssistId}; | 8 | use crate::{Assist, AssistCtx, AssistId}; |
9 | 9 | ||
10 | // Assist: inline_local_variable | 10 | // Assist: inline_local_variable |
@@ -93,8 +93,8 @@ pub(crate) fn inline_local_varialbe(ctx: AssistCtx<impl HirDatabase>) -> Option< | |||
93 | 93 | ||
94 | ctx.add_assist( | 94 | ctx.add_assist( |
95 | AssistId("inline_local_variable"), | 95 | AssistId("inline_local_variable"), |
96 | "inline local variable", | 96 | "Inline variable", |
97 | move |edit: &mut AssistBuilder| { | 97 | move |edit: &mut ActionBuilder| { |
98 | edit.delete(delete_range); | 98 | edit.delete(delete_range); |
99 | for (desc, should_wrap) in refs.iter().zip(wrap_in_parens) { | 99 | for (desc, should_wrap) in refs.iter().zip(wrap_in_parens) { |
100 | if should_wrap { | 100 | if should_wrap { |
diff --git a/crates/ra_assists/src/assists/introduce_variable.rs b/crates/ra_assists/src/assists/introduce_variable.rs index 0623d4475..19e211e0f 100644 --- a/crates/ra_assists/src/assists/introduce_variable.rs +++ b/crates/ra_assists/src/assists/introduce_variable.rs | |||
@@ -43,7 +43,7 @@ pub(crate) fn introduce_variable(ctx: AssistCtx<impl HirDatabase>) -> Option<Ass | |||
43 | if indent.kind() != WHITESPACE { | 43 | if indent.kind() != WHITESPACE { |
44 | return None; | 44 | return None; |
45 | } | 45 | } |
46 | ctx.add_assist(AssistId("introduce_variable"), "introduce variable", move |edit| { | 46 | ctx.add_assist(AssistId("introduce_variable"), "Extract into variable", move |edit| { |
47 | let mut buf = String::new(); | 47 | let mut buf = String::new(); |
48 | 48 | ||
49 | let cursor_offset = if wrap_in_block { | 49 | let cursor_offset = if wrap_in_block { |
diff --git a/crates/ra_assists/src/assists/invert_if.rs b/crates/ra_assists/src/assists/invert_if.rs index bababa3e2..16352c040 100644 --- a/crates/ra_assists/src/assists/invert_if.rs +++ b/crates/ra_assists/src/assists/invert_if.rs | |||
@@ -41,7 +41,7 @@ pub(crate) fn invert_if(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
41 | let else_node = else_block.syntax(); | 41 | let else_node = else_block.syntax(); |
42 | let else_range = else_node.text_range(); | 42 | let else_range = else_node.text_range(); |
43 | let then_range = then_node.text_range(); | 43 | let then_range = then_node.text_range(); |
44 | return ctx.add_assist(AssistId("invert_if"), "invert if branches", |edit| { | 44 | return ctx.add_assist(AssistId("invert_if"), "Invert if", |edit| { |
45 | edit.target(if_range); | 45 | edit.target(if_range); |
46 | edit.replace(cond_range, flip_cond.syntax().text()); | 46 | edit.replace(cond_range, flip_cond.syntax().text()); |
47 | edit.replace(else_range, then_node.text()); | 47 | edit.replace(else_range, then_node.text()); |
diff --git a/crates/ra_assists/src/assists/merge_match_arms.rs b/crates/ra_assists/src/assists/merge_match_arms.rs index e9f2cae91..aca391155 100644 --- a/crates/ra_assists/src/assists/merge_match_arms.rs +++ b/crates/ra_assists/src/assists/merge_match_arms.rs | |||
@@ -52,7 +52,7 @@ pub(crate) fn merge_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assis | |||
52 | 52 | ||
53 | let cursor_to_end = current_arm.syntax().text_range().end() - ctx.frange.range.start(); | 53 | let cursor_to_end = current_arm.syntax().text_range().end() - ctx.frange.range.start(); |
54 | 54 | ||
55 | ctx.add_assist(AssistId("merge_match_arms"), "merge match arms", |edit| { | 55 | ctx.add_assist(AssistId("merge_match_arms"), "Merge match arms", |edit| { |
56 | fn contains_placeholder(a: &MatchArm) -> bool { | 56 | fn contains_placeholder(a: &MatchArm) -> bool { |
57 | a.pats().any(|x| match x { | 57 | a.pats().any(|x| match x { |
58 | ra_syntax::ast::Pat::PlaceholderPat(..) => true, | 58 | ra_syntax::ast::Pat::PlaceholderPat(..) => true, |
diff --git a/crates/ra_assists/src/assists/move_bounds.rs b/crates/ra_assists/src/assists/move_bounds.rs index 3145d7625..355adddc3 100644 --- a/crates/ra_assists/src/assists/move_bounds.rs +++ b/crates/ra_assists/src/assists/move_bounds.rs | |||
@@ -46,7 +46,7 @@ pub(crate) fn move_bounds_to_where_clause(ctx: AssistCtx<impl HirDatabase>) -> O | |||
46 | _ => return None, | 46 | _ => return None, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | ctx.add_assist(AssistId("move_bounds_to_where_clause"), "move_bounds_to_where_clause", |edit| { | 49 | ctx.add_assist(AssistId("move_bounds_to_where_clause"), "Move to where clause", |edit| { |
50 | let new_params = type_param_list | 50 | let new_params = type_param_list |
51 | .type_params() | 51 | .type_params() |
52 | .filter(|it| it.type_bound_list().is_some()) | 52 | .filter(|it| it.type_bound_list().is_some()) |
diff --git a/crates/ra_assists/src/assists/move_guard.rs b/crates/ra_assists/src/assists/move_guard.rs index b49ec6172..41a31e677 100644 --- a/crates/ra_assists/src/assists/move_guard.rs +++ b/crates/ra_assists/src/assists/move_guard.rs | |||
@@ -41,7 +41,7 @@ pub(crate) fn move_guard_to_arm_body(ctx: AssistCtx<impl HirDatabase>) -> Option | |||
41 | let arm_expr = match_arm.expr()?; | 41 | let arm_expr = match_arm.expr()?; |
42 | let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text()); | 42 | let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text()); |
43 | 43 | ||
44 | ctx.add_assist(AssistId("move_guard_to_arm_body"), "move guard to arm body", |edit| { | 44 | ctx.add_assist(AssistId("move_guard_to_arm_body"), "Move guard to arm body", |edit| { |
45 | edit.target(guard.syntax().text_range()); | 45 | edit.target(guard.syntax().text_range()); |
46 | let offseting_amount = match space_before_guard.and_then(|it| it.into_token()) { | 46 | let offseting_amount = match space_before_guard.and_then(|it| it.into_token()) { |
47 | Some(tok) => { | 47 | Some(tok) => { |
@@ -111,7 +111,7 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx<impl HirDatabase>) -> | |||
111 | 111 | ||
112 | ctx.add_assist( | 112 | ctx.add_assist( |
113 | AssistId("move_arm_cond_to_match_guard"), | 113 | AssistId("move_arm_cond_to_match_guard"), |
114 | "move condition to match guard", | 114 | "Move condition to match guard", |
115 | |edit| { | 115 | |edit| { |
116 | edit.target(if_expr.syntax().text_range()); | 116 | edit.target(if_expr.syntax().text_range()); |
117 | let then_only_expr = then_block.block().and_then(|it| it.statements().next()).is_none(); | 117 | let then_only_expr = then_block.block().and_then(|it| it.statements().next()).is_none(); |
diff --git a/crates/ra_assists/src/assists/raw_string.rs b/crates/ra_assists/src/assists/raw_string.rs index 93912a470..e79c51673 100644 --- a/crates/ra_assists/src/assists/raw_string.rs +++ b/crates/ra_assists/src/assists/raw_string.rs | |||
@@ -25,7 +25,7 @@ use crate::{Assist, AssistCtx, AssistId}; | |||
25 | pub(crate) fn make_raw_string(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 25 | pub(crate) fn make_raw_string(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
26 | let token = ctx.find_token_at_offset(STRING).and_then(ast::String::cast)?; | 26 | let token = ctx.find_token_at_offset(STRING).and_then(ast::String::cast)?; |
27 | let value = token.value()?; | 27 | let value = token.value()?; |
28 | ctx.add_assist(AssistId("make_raw_string"), "make raw string", |edit| { | 28 | ctx.add_assist(AssistId("make_raw_string"), "Rewrite as raw string", |edit| { |
29 | edit.target(token.syntax().text_range()); | 29 | edit.target(token.syntax().text_range()); |
30 | let max_hash_streak = count_hashes(&value); | 30 | let max_hash_streak = count_hashes(&value); |
31 | let mut hashes = String::with_capacity(max_hash_streak + 1); | 31 | let mut hashes = String::with_capacity(max_hash_streak + 1); |
@@ -54,7 +54,7 @@ pub(crate) fn make_raw_string(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
54 | pub(crate) fn make_usual_string(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 54 | pub(crate) fn make_usual_string(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
55 | let token = ctx.find_token_at_offset(RAW_STRING).and_then(ast::RawString::cast)?; | 55 | let token = ctx.find_token_at_offset(RAW_STRING).and_then(ast::RawString::cast)?; |
56 | let value = token.value()?; | 56 | let value = token.value()?; |
57 | ctx.add_assist(AssistId("make_usual_string"), "make usual string", |edit| { | 57 | ctx.add_assist(AssistId("make_usual_string"), "Rewrite as regular string", |edit| { |
58 | edit.target(token.syntax().text_range()); | 58 | edit.target(token.syntax().text_range()); |
59 | // parse inside string to escape `"` | 59 | // parse inside string to escape `"` |
60 | let escaped = value.escape_default().to_string(); | 60 | let escaped = value.escape_default().to_string(); |
@@ -79,7 +79,7 @@ pub(crate) fn make_usual_string(ctx: AssistCtx<impl HirDatabase>) -> Option<Assi | |||
79 | // ``` | 79 | // ``` |
80 | pub(crate) fn add_hash(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 80 | pub(crate) fn add_hash(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
81 | let token = ctx.find_token_at_offset(RAW_STRING)?; | 81 | let token = ctx.find_token_at_offset(RAW_STRING)?; |
82 | ctx.add_assist(AssistId("add_hash"), "add hash to raw string", |edit| { | 82 | ctx.add_assist(AssistId("add_hash"), "Add # to raw string", |edit| { |
83 | edit.target(token.text_range()); | 83 | edit.target(token.text_range()); |
84 | edit.insert(token.text_range().start() + TextUnit::of_char('r'), "#"); | 84 | edit.insert(token.text_range().start() + TextUnit::of_char('r'), "#"); |
85 | edit.insert(token.text_range().end(), "#"); | 85 | edit.insert(token.text_range().end(), "#"); |
@@ -108,7 +108,7 @@ pub(crate) fn remove_hash(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
108 | // no hash to remove | 108 | // no hash to remove |
109 | return None; | 109 | return None; |
110 | } | 110 | } |
111 | ctx.add_assist(AssistId("remove_hash"), "remove hash from raw string", |edit| { | 111 | ctx.add_assist(AssistId("remove_hash"), "Remove hash from raw string", |edit| { |
112 | edit.target(token.text_range()); | 112 | edit.target(token.text_range()); |
113 | let result = &text[2..text.len() - 1]; | 113 | let result = &text[2..text.len() - 1]; |
114 | let result = if result.starts_with('\"') { | 114 | let result = if result.starts_with('\"') { |
diff --git a/crates/ra_assists/src/assists/remove_dbg.rs b/crates/ra_assists/src/assists/remove_dbg.rs index aedf8747f..cf211ab84 100644 --- a/crates/ra_assists/src/assists/remove_dbg.rs +++ b/crates/ra_assists/src/assists/remove_dbg.rs | |||
@@ -58,7 +58,7 @@ pub(crate) fn remove_dbg(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
58 | text.slice(without_parens).to_string() | 58 | text.slice(without_parens).to_string() |
59 | }; | 59 | }; |
60 | 60 | ||
61 | ctx.add_assist(AssistId("remove_dbg"), "remove dbg!()", |edit| { | 61 | ctx.add_assist(AssistId("remove_dbg"), "Remove dbg!()", |edit| { |
62 | edit.target(macro_call.syntax().text_range()); | 62 | edit.target(macro_call.syntax().text_range()); |
63 | edit.replace(macro_range, macro_content); | 63 | edit.replace(macro_range, macro_content); |
64 | edit.set_cursor(cursor_pos); | 64 | edit.set_cursor(cursor_pos); |
diff --git a/crates/ra_assists/src/assists/replace_if_let_with_match.rs b/crates/ra_assists/src/assists/replace_if_let_with_match.rs index 3272801ff..c9b62e5ff 100644 --- a/crates/ra_assists/src/assists/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/assists/replace_if_let_with_match.rs | |||
@@ -42,7 +42,7 @@ pub(crate) fn replace_if_let_with_match(ctx: AssistCtx<impl HirDatabase>) -> Opt | |||
42 | ast::ElseBranch::IfExpr(_) => return None, | 42 | ast::ElseBranch::IfExpr(_) => return None, |
43 | }; | 43 | }; |
44 | 44 | ||
45 | ctx.add_assist(AssistId("replace_if_let_with_match"), "replace with match", |edit| { | 45 | ctx.add_assist(AssistId("replace_if_let_with_match"), "Replace with match", |edit| { |
46 | let match_expr = build_match_expr(expr, pat, then_block, else_block); | 46 | let match_expr = build_match_expr(expr, pat, then_block, else_block); |
47 | edit.target(if_expr.syntax().text_range()); | 47 | edit.target(if_expr.syntax().text_range()); |
48 | edit.replace_node_and_indent(if_expr.syntax(), match_expr); | 48 | edit.replace_node_and_indent(if_expr.syntax(), match_expr); |
diff --git a/crates/ra_assists/src/assists/split_import.rs b/crates/ra_assists/src/assists/split_import.rs index 5f8d6b0be..6038c4858 100644 --- a/crates/ra_assists/src/assists/split_import.rs +++ b/crates/ra_assists/src/assists/split_import.rs | |||
@@ -32,7 +32,7 @@ pub(crate) fn split_import(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | |||
32 | None => top_path.syntax().text_range().end(), | 32 | None => top_path.syntax().text_range().end(), |
33 | }; | 33 | }; |
34 | 34 | ||
35 | ctx.add_assist(AssistId("split_import"), "split import", |edit| { | 35 | ctx.add_assist(AssistId("split_import"), "Split import", |edit| { |
36 | edit.target(colon_colon.text_range()); | 36 | edit.target(colon_colon.text_range()); |
37 | edit.insert(l_curly, "{"); | 37 | edit.insert(l_curly, "{"); |
38 | edit.insert(r_curly, "}"); | 38 | edit.insert(r_curly, "}"); |
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs index eac2903d1..56b7588ef 100644 --- a/crates/ra_assists/src/ast_transform.rs +++ b/crates/ra_assists/src/ast_transform.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | use rustc_hash::FxHashMap; | 2 | use rustc_hash::FxHashMap; |
3 | 3 | ||
4 | use hir::{db::HirDatabase, InFile, PathResolution}; | 4 | use hir::{db::HirDatabase, InFile, PathResolution}; |
5 | use ra_syntax::ast::{self, make, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | 6 | ||
7 | pub trait AstTransform<'a> { | 7 | pub trait AstTransform<'a> { |
8 | fn get_substitution( | 8 | fn get_substitution( |
@@ -134,11 +134,18 @@ impl<'a, DB: HirDatabase> QualifyPaths<'a, DB> { | |||
134 | match resolution { | 134 | match resolution { |
135 | PathResolution::Def(def) => { | 135 | PathResolution::Def(def) => { |
136 | let found_path = from.find_use_path(self.db, def)?; | 136 | let found_path = from.find_use_path(self.db, def)?; |
137 | let args = p | 137 | let mut path = path_to_ast(found_path); |
138 | |||
139 | let type_args = p | ||
138 | .segment() | 140 | .segment() |
139 | .and_then(|s| s.type_arg_list()) | 141 | .and_then(|s| s.type_arg_list()) |
140 | .map(|arg_list| apply(self, node.with_value(arg_list))); | 142 | .map(|arg_list| apply(self, node.with_value(arg_list))); |
141 | Some(make::path_with_type_arg_list(path_to_ast(found_path), args).syntax().clone()) | 143 | if let Some(type_args) = type_args { |
144 | let last_segment = path.segment().unwrap(); | ||
145 | path = path.with_segment(last_segment.with_type_args(type_args)) | ||
146 | } | ||
147 | |||
148 | Some(path.syntax().clone()) | ||
142 | } | 149 | } |
143 | PathResolution::Local(_) | 150 | PathResolution::Local(_) |
144 | | PathResolution::TypeParam(_) | 151 | | PathResolution::TypeParam(_) |
diff --git a/crates/ra_assists/src/doc_tests.rs b/crates/ra_assists/src/doc_tests.rs index a8f8446cb..5dc1ee233 100644 --- a/crates/ra_assists/src/doc_tests.rs +++ b/crates/ra_assists/src/doc_tests.rs | |||
@@ -15,21 +15,21 @@ fn check(assist_id: &str, before: &str, after: &str) { | |||
15 | let (db, file_id) = TestDB::with_single_file(&before); | 15 | let (db, file_id) = TestDB::with_single_file(&before); |
16 | let frange = FileRange { file_id, range: selection.into() }; | 16 | let frange = FileRange { file_id, range: selection.into() }; |
17 | 17 | ||
18 | let (_assist_id, action) = crate::assists(&db, frange) | 18 | let assist = crate::assists(&db, frange) |
19 | .into_iter() | 19 | .into_iter() |
20 | .find(|(id, _)| id.id.0 == assist_id) | 20 | .find(|assist| assist.label.id.0 == assist_id) |
21 | .unwrap_or_else(|| { | 21 | .unwrap_or_else(|| { |
22 | panic!( | 22 | panic!( |
23 | "\n\nAssist is not applicable: {}\nAvailable assists: {}", | 23 | "\n\nAssist is not applicable: {}\nAvailable assists: {}", |
24 | assist_id, | 24 | assist_id, |
25 | crate::assists(&db, frange) | 25 | crate::assists(&db, frange) |
26 | .into_iter() | 26 | .into_iter() |
27 | .map(|(id, _)| id.id.0) | 27 | .map(|assist| assist.label.id.0) |
28 | .collect::<Vec<_>>() | 28 | .collect::<Vec<_>>() |
29 | .join(", ") | 29 | .join(", ") |
30 | ) | 30 | ) |
31 | }); | 31 | }); |
32 | 32 | ||
33 | let actual = action.edit.apply(&before); | 33 | let actual = assist.get_first_action().edit.apply(&before); |
34 | assert_eq_text!(after, &actual); | 34 | assert_eq_text!(after, &actual); |
35 | } | 35 | } |
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index 712ff6f6a..d45b58966 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -13,6 +13,7 @@ mod doc_tests; | |||
13 | mod test_db; | 13 | mod test_db; |
14 | pub mod ast_transform; | 14 | pub mod ast_transform; |
15 | 15 | ||
16 | use either::Either; | ||
16 | use hir::db::HirDatabase; | 17 | use hir::db::HirDatabase; |
17 | use ra_db::FileRange; | 18 | use ra_db::FileRange; |
18 | use ra_syntax::{TextRange, TextUnit}; | 19 | use ra_syntax::{TextRange, TextUnit}; |
@@ -35,11 +36,27 @@ pub struct AssistLabel { | |||
35 | 36 | ||
36 | #[derive(Debug, Clone)] | 37 | #[derive(Debug, Clone)] |
37 | pub struct AssistAction { | 38 | pub struct AssistAction { |
39 | pub label: Option<String>, | ||
38 | pub edit: TextEdit, | 40 | pub edit: TextEdit, |
39 | pub cursor_position: Option<TextUnit>, | 41 | pub cursor_position: Option<TextUnit>, |
40 | pub target: Option<TextRange>, | 42 | pub target: Option<TextRange>, |
41 | } | 43 | } |
42 | 44 | ||
45 | #[derive(Debug, Clone)] | ||
46 | pub struct ResolvedAssist { | ||
47 | pub label: AssistLabel, | ||
48 | pub action_data: Either<AssistAction, Vec<AssistAction>>, | ||
49 | } | ||
50 | |||
51 | impl ResolvedAssist { | ||
52 | pub fn get_first_action(&self) -> AssistAction { | ||
53 | match &self.action_data { | ||
54 | Either::Left(action) => action.clone(), | ||
55 | Either::Right(actions) => actions[0].clone(), | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
43 | /// Return all the assists applicable at the given position. | 60 | /// Return all the assists applicable at the given position. |
44 | /// | 61 | /// |
45 | /// Assists are returned in the "unresolved" state, that is only labels are | 62 | /// Assists are returned in the "unresolved" state, that is only labels are |
@@ -64,7 +81,7 @@ where | |||
64 | /// | 81 | /// |
65 | /// Assists are returned in the "resolved" state, that is with edit fully | 82 | /// Assists are returned in the "resolved" state, that is with edit fully |
66 | /// computed. | 83 | /// computed. |
67 | pub fn assists<H>(db: &H, range: FileRange) -> Vec<(AssistLabel, AssistAction)> | 84 | pub fn assists<H>(db: &H, range: FileRange) -> Vec<ResolvedAssist> |
68 | where | 85 | where |
69 | H: HirDatabase + 'static, | 86 | H: HirDatabase + 'static, |
70 | { | 87 | { |
@@ -75,11 +92,11 @@ where | |||
75 | .iter() | 92 | .iter() |
76 | .filter_map(|f| f(ctx.clone())) | 93 | .filter_map(|f| f(ctx.clone())) |
77 | .map(|a| match a { | 94 | .map(|a| match a { |
78 | Assist::Resolved { label, action } => (label, action), | 95 | Assist::Resolved { assist } => assist, |
79 | Assist::Unresolved { .. } => unreachable!(), | 96 | Assist::Unresolved { .. } => unreachable!(), |
80 | }) | 97 | }) |
81 | .collect::<Vec<_>>(); | 98 | .collect::<Vec<_>>(); |
82 | a.sort_by(|a, b| match (a.1.target, b.1.target) { | 99 | a.sort_by(|a, b| match (a.get_first_action().target, b.get_first_action().target) { |
83 | (Some(a), Some(b)) => a.len().cmp(&b.len()), | 100 | (Some(a), Some(b)) => a.len().cmp(&b.len()), |
84 | (Some(_), None) => Ordering::Less, | 101 | (Some(_), None) => Ordering::Less, |
85 | (None, Some(_)) => Ordering::Greater, | 102 | (None, Some(_)) => Ordering::Greater, |
@@ -174,7 +191,7 @@ mod helpers { | |||
174 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); | 191 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); |
175 | let action = match assist { | 192 | let action = match assist { |
176 | Assist::Unresolved { .. } => unreachable!(), | 193 | Assist::Unresolved { .. } => unreachable!(), |
177 | Assist::Resolved { action, .. } => action, | 194 | Assist::Resolved { assist } => assist.get_first_action(), |
178 | }; | 195 | }; |
179 | 196 | ||
180 | let actual = action.edit.apply(&before); | 197 | let actual = action.edit.apply(&before); |
@@ -201,7 +218,7 @@ mod helpers { | |||
201 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); | 218 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); |
202 | let action = match assist { | 219 | let action = match assist { |
203 | Assist::Unresolved { .. } => unreachable!(), | 220 | Assist::Unresolved { .. } => unreachable!(), |
204 | Assist::Resolved { action, .. } => action, | 221 | Assist::Resolved { assist } => assist.get_first_action(), |
205 | }; | 222 | }; |
206 | 223 | ||
207 | let mut actual = action.edit.apply(&before); | 224 | let mut actual = action.edit.apply(&before); |
@@ -224,7 +241,7 @@ mod helpers { | |||
224 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); | 241 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); |
225 | let action = match assist { | 242 | let action = match assist { |
226 | Assist::Unresolved { .. } => unreachable!(), | 243 | Assist::Unresolved { .. } => unreachable!(), |
227 | Assist::Resolved { action, .. } => action, | 244 | Assist::Resolved { assist } => assist.get_first_action(), |
228 | }; | 245 | }; |
229 | 246 | ||
230 | let range = action.target.expect("expected target on action"); | 247 | let range = action.target.expect("expected target on action"); |
@@ -243,7 +260,7 @@ mod helpers { | |||
243 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); | 260 | AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable"); |
244 | let action = match assist { | 261 | let action = match assist { |
245 | Assist::Unresolved { .. } => unreachable!(), | 262 | Assist::Unresolved { .. } => unreachable!(), |
246 | Assist::Resolved { action, .. } => action, | 263 | Assist::Resolved { assist } => assist.get_first_action(), |
247 | }; | 264 | }; |
248 | 265 | ||
249 | let range = action.target.expect("expected target on action"); | 266 | let range = action.target.expect("expected target on action"); |
@@ -292,8 +309,11 @@ mod tests { | |||
292 | let assists = super::assists(&db, frange); | 309 | let assists = super::assists(&db, frange); |
293 | let mut assists = assists.iter(); | 310 | let mut assists = assists.iter(); |
294 | 311 | ||
295 | assert_eq!(assists.next().expect("expected assist").0.label, "make pub(crate)"); | 312 | assert_eq!( |
296 | assert_eq!(assists.next().expect("expected assist").0.label, "add `#[derive]`"); | 313 | assists.next().expect("expected assist").label.label, |
314 | "Change visibility to pub(crate)" | ||
315 | ); | ||
316 | assert_eq!(assists.next().expect("expected assist").label.label, "Add `#[derive]`"); | ||
297 | } | 317 | } |
298 | 318 | ||
299 | #[test] | 319 | #[test] |
@@ -312,7 +332,7 @@ mod tests { | |||
312 | let assists = super::assists(&db, frange); | 332 | let assists = super::assists(&db, frange); |
313 | let mut assists = assists.iter(); | 333 | let mut assists = assists.iter(); |
314 | 334 | ||
315 | assert_eq!(assists.next().expect("expected assist").0.label, "introduce variable"); | 335 | assert_eq!(assists.next().expect("expected assist").label.label, "Extract into variable"); |
316 | assert_eq!(assists.next().expect("expected assist").0.label, "replace with match"); | 336 | assert_eq!(assists.next().expect("expected assist").label.label, "Replace with match"); |
317 | } | 337 | } |
318 | } | 338 | } |
diff --git a/crates/ra_cargo_watch/Cargo.toml b/crates/ra_cargo_watch/Cargo.toml index 2e411d23b..9ead48abf 100644 --- a/crates/ra_cargo_watch/Cargo.toml +++ b/crates/ra_cargo_watch/Cargo.toml | |||
@@ -6,7 +6,7 @@ authors = ["rust-analyzer developers"] | |||
6 | 6 | ||
7 | [dependencies] | 7 | [dependencies] |
8 | crossbeam-channel = "0.4" | 8 | crossbeam-channel = "0.4" |
9 | lsp-types = { version = "0.68.0", features = ["proposed"] } | 9 | lsp-types = { version = "0.69.0", features = ["proposed"] } |
10 | log = "0.4.3" | 10 | log = "0.4.3" |
11 | cargo_metadata = "0.9.1" | 11 | cargo_metadata = "0.9.1" |
12 | jod-thread = "0.1.0" | 12 | jod-thread = "0.1.0" |
diff --git a/crates/ra_cargo_watch/src/lib.rs b/crates/ra_cargo_watch/src/lib.rs index cb0856aa4..7f4c9280c 100644 --- a/crates/ra_cargo_watch/src/lib.rs +++ b/crates/ra_cargo_watch/src/lib.rs | |||
@@ -38,7 +38,7 @@ pub struct CheckOptions { | |||
38 | #[derive(Debug)] | 38 | #[derive(Debug)] |
39 | pub struct CheckWatcher { | 39 | pub struct CheckWatcher { |
40 | pub task_recv: Receiver<CheckTask>, | 40 | pub task_recv: Receiver<CheckTask>, |
41 | pub shared: Arc<RwLock<CheckWatcherSharedState>>, | 41 | pub state: Arc<RwLock<CheckState>>, |
42 | cmd_send: Option<Sender<CheckCommand>>, | 42 | cmd_send: Option<Sender<CheckCommand>>, |
43 | handle: Option<JoinHandle<()>>, | 43 | handle: Option<JoinHandle<()>>, |
44 | } | 44 | } |
@@ -46,22 +46,21 @@ pub struct CheckWatcher { | |||
46 | impl CheckWatcher { | 46 | impl CheckWatcher { |
47 | pub fn new(options: &CheckOptions, workspace_root: PathBuf) -> CheckWatcher { | 47 | pub fn new(options: &CheckOptions, workspace_root: PathBuf) -> CheckWatcher { |
48 | let options = options.clone(); | 48 | let options = options.clone(); |
49 | let shared = Arc::new(RwLock::new(CheckWatcherSharedState::new())); | 49 | let state = Arc::new(RwLock::new(CheckState::new())); |
50 | 50 | ||
51 | let (task_send, task_recv) = unbounded::<CheckTask>(); | 51 | let (task_send, task_recv) = unbounded::<CheckTask>(); |
52 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); | 52 | let (cmd_send, cmd_recv) = unbounded::<CheckCommand>(); |
53 | let shared_ = shared.clone(); | ||
54 | let handle = std::thread::spawn(move || { | 53 | let handle = std::thread::spawn(move || { |
55 | let mut check = CheckWatcherState::new(options, workspace_root, shared_); | 54 | let mut check = CheckWatcherThread::new(options, workspace_root); |
56 | check.run(&task_send, &cmd_recv); | 55 | check.run(&task_send, &cmd_recv); |
57 | }); | 56 | }); |
58 | CheckWatcher { task_recv, cmd_send: Some(cmd_send), handle: Some(handle), shared } | 57 | CheckWatcher { task_recv, cmd_send: Some(cmd_send), handle: Some(handle), state } |
59 | } | 58 | } |
60 | 59 | ||
61 | /// Returns a CheckWatcher that doesn't actually do anything | 60 | /// Returns a CheckWatcher that doesn't actually do anything |
62 | pub fn dummy() -> CheckWatcher { | 61 | pub fn dummy() -> CheckWatcher { |
63 | let shared = Arc::new(RwLock::new(CheckWatcherSharedState::new())); | 62 | let state = Arc::new(RwLock::new(CheckState::new())); |
64 | CheckWatcher { task_recv: never(), cmd_send: None, handle: None, shared } | 63 | CheckWatcher { task_recv: never(), cmd_send: None, handle: None, state } |
65 | } | 64 | } |
66 | 65 | ||
67 | /// Schedule a re-start of the cargo check worker. | 66 | /// Schedule a re-start of the cargo check worker. |
@@ -89,14 +88,14 @@ impl std::ops::Drop for CheckWatcher { | |||
89 | } | 88 | } |
90 | 89 | ||
91 | #[derive(Debug)] | 90 | #[derive(Debug)] |
92 | pub struct CheckWatcherSharedState { | 91 | pub struct CheckState { |
93 | diagnostic_collection: HashMap<Url, Vec<Diagnostic>>, | 92 | diagnostic_collection: HashMap<Url, Vec<Diagnostic>>, |
94 | suggested_fix_collection: HashMap<Url, Vec<SuggestedFix>>, | 93 | suggested_fix_collection: HashMap<Url, Vec<SuggestedFix>>, |
95 | } | 94 | } |
96 | 95 | ||
97 | impl CheckWatcherSharedState { | 96 | impl CheckState { |
98 | fn new() -> CheckWatcherSharedState { | 97 | fn new() -> CheckState { |
99 | CheckWatcherSharedState { | 98 | CheckState { |
100 | diagnostic_collection: HashMap::new(), | 99 | diagnostic_collection: HashMap::new(), |
101 | suggested_fix_collection: HashMap::new(), | 100 | suggested_fix_collection: HashMap::new(), |
102 | } | 101 | } |
@@ -104,15 +103,11 @@ impl CheckWatcherSharedState { | |||
104 | 103 | ||
105 | /// Clear the cached diagnostics, and schedule updating diagnostics by the | 104 | /// Clear the cached diagnostics, and schedule updating diagnostics by the |
106 | /// server, to clear stale results. | 105 | /// server, to clear stale results. |
107 | pub fn clear(&mut self, task_send: &Sender<CheckTask>) { | 106 | pub fn clear(&mut self) -> Vec<Url> { |
108 | let cleared_files: Vec<Url> = self.diagnostic_collection.keys().cloned().collect(); | 107 | let cleared_files: Vec<Url> = self.diagnostic_collection.keys().cloned().collect(); |
109 | |||
110 | self.diagnostic_collection.clear(); | 108 | self.diagnostic_collection.clear(); |
111 | self.suggested_fix_collection.clear(); | 109 | self.suggested_fix_collection.clear(); |
112 | 110 | cleared_files | |
113 | for uri in cleared_files { | ||
114 | task_send.send(CheckTask::Update(uri.clone())).unwrap(); | ||
115 | } | ||
116 | } | 111 | } |
117 | 112 | ||
118 | pub fn diagnostics_for(&self, uri: &Url) -> Option<&[Diagnostic]> { | 113 | pub fn diagnostics_for(&self, uri: &Url) -> Option<&[Diagnostic]> { |
@@ -123,6 +118,13 @@ impl CheckWatcherSharedState { | |||
123 | self.suggested_fix_collection.get(uri).map(|d| d.as_slice()) | 118 | self.suggested_fix_collection.get(uri).map(|d| d.as_slice()) |
124 | } | 119 | } |
125 | 120 | ||
121 | pub fn add_diagnostic_with_fixes(&mut self, file_uri: Url, diagnostic: DiagnosticWithFixes) { | ||
122 | for fix in diagnostic.suggested_fixes { | ||
123 | self.add_suggested_fix_for_diagnostic(fix, &diagnostic.diagnostic); | ||
124 | } | ||
125 | self.add_diagnostic(file_uri, diagnostic.diagnostic); | ||
126 | } | ||
127 | |||
126 | fn add_diagnostic(&mut self, file_uri: Url, diagnostic: Diagnostic) { | 128 | fn add_diagnostic(&mut self, file_uri: Url, diagnostic: Diagnostic) { |
127 | let diagnostics = self.diagnostic_collection.entry(file_uri).or_default(); | 129 | let diagnostics = self.diagnostic_collection.entry(file_uri).or_default(); |
128 | 130 | ||
@@ -158,8 +160,11 @@ impl CheckWatcherSharedState { | |||
158 | 160 | ||
159 | #[derive(Debug)] | 161 | #[derive(Debug)] |
160 | pub enum CheckTask { | 162 | pub enum CheckTask { |
161 | /// Request a update of the given files diagnostics | 163 | /// Request a clearing of all cached diagnostics from the check watcher |
162 | Update(Url), | 164 | ClearDiagnostics, |
165 | |||
166 | /// Request adding a diagnostic with fixes included to a file | ||
167 | AddDiagnostic(Url, DiagnosticWithFixes), | ||
163 | 168 | ||
164 | /// Request check progress notification to client | 169 | /// Request check progress notification to client |
165 | Status(WorkDoneProgress), | 170 | Status(WorkDoneProgress), |
@@ -170,22 +175,21 @@ pub enum CheckCommand { | |||
170 | Update, | 175 | Update, |
171 | } | 176 | } |
172 | 177 | ||
173 | struct CheckWatcherState { | 178 | struct CheckWatcherThread { |
174 | options: CheckOptions, | 179 | options: CheckOptions, |
175 | workspace_root: PathBuf, | 180 | workspace_root: PathBuf, |
176 | watcher: WatchThread, | 181 | watcher: WatchThread, |
177 | last_update_req: Option<Instant>, | 182 | last_update_req: Option<Instant>, |
178 | shared: Arc<RwLock<CheckWatcherSharedState>>, | ||
179 | } | 183 | } |
180 | 184 | ||
181 | impl CheckWatcherState { | 185 | impl CheckWatcherThread { |
182 | fn new( | 186 | fn new(options: CheckOptions, workspace_root: PathBuf) -> CheckWatcherThread { |
183 | options: CheckOptions, | 187 | CheckWatcherThread { |
184 | workspace_root: PathBuf, | 188 | options, |
185 | shared: Arc<RwLock<CheckWatcherSharedState>>, | 189 | workspace_root, |
186 | ) -> CheckWatcherState { | 190 | watcher: WatchThread::dummy(), |
187 | let watcher = WatchThread::new(&options, &workspace_root); | 191 | last_update_req: None, |
188 | CheckWatcherState { options, workspace_root, watcher, last_update_req: None, shared } | 192 | } |
189 | } | 193 | } |
190 | 194 | ||
191 | fn run(&mut self, task_send: &Sender<CheckTask>, cmd_recv: &Receiver<CheckCommand>) { | 195 | fn run(&mut self, task_send: &Sender<CheckTask>, cmd_recv: &Receiver<CheckCommand>) { |
@@ -210,7 +214,7 @@ impl CheckWatcherState { | |||
210 | 214 | ||
211 | if self.should_recheck() { | 215 | if self.should_recheck() { |
212 | self.last_update_req.take(); | 216 | self.last_update_req.take(); |
213 | self.shared.write().clear(task_send); | 217 | task_send.send(CheckTask::ClearDiagnostics).unwrap(); |
214 | 218 | ||
215 | // By replacing the watcher, we drop the previous one which | 219 | // By replacing the watcher, we drop the previous one which |
216 | // causes it to shut down automatically. | 220 | // causes it to shut down automatically. |
@@ -235,7 +239,7 @@ impl CheckWatcherState { | |||
235 | } | 239 | } |
236 | } | 240 | } |
237 | 241 | ||
238 | fn handle_message(&mut self, msg: CheckEvent, task_send: &Sender<CheckTask>) { | 242 | fn handle_message(&self, msg: CheckEvent, task_send: &Sender<CheckTask>) { |
239 | match msg { | 243 | match msg { |
240 | CheckEvent::Begin => { | 244 | CheckEvent::Begin => { |
241 | task_send | 245 | task_send |
@@ -274,18 +278,9 @@ impl CheckWatcherState { | |||
274 | }; | 278 | }; |
275 | 279 | ||
276 | let MappedRustDiagnostic { location, diagnostic, suggested_fixes } = map_result; | 280 | let MappedRustDiagnostic { location, diagnostic, suggested_fixes } = map_result; |
277 | let file_uri = location.uri.clone(); | ||
278 | 281 | ||
279 | if !suggested_fixes.is_empty() { | 282 | let diagnostic = DiagnosticWithFixes { diagnostic, suggested_fixes }; |
280 | for suggested_fix in suggested_fixes { | 283 | task_send.send(CheckTask::AddDiagnostic(location.uri, diagnostic)).unwrap(); |
281 | self.shared | ||
282 | .write() | ||
283 | .add_suggested_fix_for_diagnostic(suggested_fix, &diagnostic); | ||
284 | } | ||
285 | } | ||
286 | self.shared.write().add_diagnostic(file_uri, diagnostic); | ||
287 | |||
288 | task_send.send(CheckTask::Update(location.uri)).unwrap(); | ||
289 | } | 284 | } |
290 | 285 | ||
291 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} | 286 | CheckEvent::Msg(Message::BuildScriptExecuted(_msg)) => {} |
@@ -294,6 +289,12 @@ impl CheckWatcherState { | |||
294 | } | 289 | } |
295 | } | 290 | } |
296 | 291 | ||
292 | #[derive(Debug)] | ||
293 | pub struct DiagnosticWithFixes { | ||
294 | diagnostic: Diagnostic, | ||
295 | suggested_fixes: Vec<SuggestedFix>, | ||
296 | } | ||
297 | |||
297 | /// WatchThread exists to wrap around the communication needed to be able to | 298 | /// WatchThread exists to wrap around the communication needed to be able to |
298 | /// run `cargo check` without blocking. Currently the Rust standard library | 299 | /// run `cargo check` without blocking. Currently the Rust standard library |
299 | /// doesn't provide a way to read sub-process output without blocking, so we | 300 | /// doesn't provide a way to read sub-process output without blocking, so we |
@@ -313,6 +314,10 @@ enum CheckEvent { | |||
313 | } | 314 | } |
314 | 315 | ||
315 | impl WatchThread { | 316 | impl WatchThread { |
317 | fn dummy() -> WatchThread { | ||
318 | WatchThread { handle: None, message_recv: never() } | ||
319 | } | ||
320 | |||
316 | fn new(options: &CheckOptions, workspace_root: &PathBuf) -> WatchThread { | 321 | fn new(options: &CheckOptions, workspace_root: &PathBuf) -> WatchThread { |
317 | let mut args: Vec<String> = vec![ | 322 | let mut args: Vec<String> = vec![ |
318 | options.command.clone(), | 323 | options.command.clone(), |
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index ac65415a5..fd0027691 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -183,7 +183,6 @@ pub fn run( | |||
183 | println!("Total: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); | 183 | println!("Total: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); |
184 | 184 | ||
185 | if memory_usage { | 185 | if memory_usage { |
186 | drop(db); | ||
187 | for (name, bytes) in host.per_query_memory_usage() { | 186 | for (name, bytes) in host.per_query_memory_usage() { |
188 | println!("{:>8} {}", bytes, name) | 187 | println!("{:>8} {}", bytes, name) |
189 | } | 188 | } |
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 3808590ab..806612c2c 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -22,7 +22,7 @@ pub enum Verbosity { | |||
22 | } | 22 | } |
23 | 23 | ||
24 | impl Verbosity { | 24 | impl Verbosity { |
25 | fn is_verbose(&self) -> bool { | 25 | fn is_verbose(self) -> bool { |
26 | match self { | 26 | match self { |
27 | Verbosity::Verbose => true, | 27 | Verbosity::Verbose => true, |
28 | _ => false, | 28 | _ => false, |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a177cebca..500b34c17 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -7,7 +7,6 @@ use hir_def::{ | |||
7 | builtin_type::BuiltinType, | 7 | builtin_type::BuiltinType, |
8 | docs::Documentation, | 8 | docs::Documentation, |
9 | expr::{BindingAnnotation, Pat, PatId}, | 9 | expr::{BindingAnnotation, Pat, PatId}, |
10 | nameres::ModuleSource, | ||
11 | per_ns::PerNs, | 10 | per_ns::PerNs, |
12 | resolver::HasResolver, | 11 | resolver::HasResolver, |
13 | type_ref::{Mutability, TypeRef}, | 12 | type_ref::{Mutability, TypeRef}, |
@@ -21,8 +20,8 @@ use hir_expand::{ | |||
21 | MacroDefId, | 20 | MacroDefId, |
22 | }; | 21 | }; |
23 | use hir_ty::{ | 22 | use hir_ty::{ |
24 | autoderef, display::HirFormatter, expr::ExprValidator, ApplicationTy, Canonical, InEnvironment, | 23 | autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, |
25 | TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, | 24 | Canonical, InEnvironment, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, |
26 | }; | 25 | }; |
27 | use ra_db::{CrateId, Edition, FileId}; | 26 | use ra_db::{CrateId, Edition, FileId}; |
28 | use ra_prof::profile; | 27 | use ra_prof::profile; |
@@ -120,7 +119,8 @@ impl_froms!( | |||
120 | BuiltinType | 119 | BuiltinType |
121 | ); | 120 | ); |
122 | 121 | ||
123 | pub use hir_def::{attr::Attrs, visibility::Visibility}; | 122 | pub use hir_def::{attr::Attrs, visibility::Visibility, AssocItemId}; |
123 | use rustc_hash::FxHashSet; | ||
124 | 124 | ||
125 | impl Module { | 125 | impl Module { |
126 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { | 126 | pub(crate) fn new(krate: Crate, crate_module_id: LocalModuleId) -> Module { |
@@ -192,13 +192,14 @@ impl Module { | |||
192 | 192 | ||
193 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 193 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
194 | let _p = profile("Module::diagnostics"); | 194 | let _p = profile("Module::diagnostics"); |
195 | db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink); | 195 | let crate_def_map = db.crate_def_map(self.id.krate); |
196 | crate_def_map.add_diagnostics(db, self.id.local_id, sink); | ||
196 | for decl in self.declarations(db) { | 197 | for decl in self.declarations(db) { |
197 | match decl { | 198 | match decl { |
198 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), | 199 | crate::ModuleDef::Function(f) => f.diagnostics(db, sink), |
199 | crate::ModuleDef::Module(m) => { | 200 | crate::ModuleDef::Module(m) => { |
200 | // Only add diagnostics from inline modules | 201 | // Only add diagnostics from inline modules |
201 | if let ModuleSource::Module(_) = m.definition_source(db).value { | 202 | if crate_def_map[m.id.local_id].origin.is_inline() { |
202 | m.diagnostics(db, sink) | 203 | m.diagnostics(db, sink) |
203 | } | 204 | } |
204 | } | 205 | } |
@@ -878,6 +879,28 @@ impl Type { | |||
878 | } | 879 | } |
879 | } | 880 | } |
880 | 881 | ||
882 | /// Checks that particular type `ty` implements `std::future::Future`. | ||
883 | /// This function is used in `.await` syntax completion. | ||
884 | pub fn impls_future(&self, db: &impl HirDatabase) -> bool { | ||
885 | let krate = self.krate; | ||
886 | |||
887 | let std_future_trait = | ||
888 | db.lang_item(krate, "future_trait".into()).and_then(|it| it.as_trait()); | ||
889 | let std_future_trait = match std_future_trait { | ||
890 | Some(it) => it, | ||
891 | None => return false, | ||
892 | }; | ||
893 | |||
894 | let canonical_ty = Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
895 | method_resolution::implements_trait( | ||
896 | &canonical_ty, | ||
897 | db, | ||
898 | self.ty.environment.clone(), | ||
899 | krate, | ||
900 | std_future_trait, | ||
901 | ) | ||
902 | } | ||
903 | |||
881 | // FIXME: this method is broken, as it doesn't take closures into account. | 904 | // FIXME: this method is broken, as it doesn't take closures into account. |
882 | pub fn as_callable(&self) -> Option<CallableDef> { | 905 | pub fn as_callable(&self) -> Option<CallableDef> { |
883 | Some(self.ty.value.as_callable()?.0) | 906 | Some(self.ty.value.as_callable()?.0) |
@@ -986,6 +1009,65 @@ impl Type { | |||
986 | None | 1009 | None |
987 | } | 1010 | } |
988 | 1011 | ||
1012 | pub fn iterate_method_candidates<T>( | ||
1013 | &self, | ||
1014 | db: &impl HirDatabase, | ||
1015 | krate: Crate, | ||
1016 | traits_in_scope: &FxHashSet<TraitId>, | ||
1017 | name: Option<&Name>, | ||
1018 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | ||
1019 | ) -> Option<T> { | ||
1020 | // There should be no inference vars in types passed here | ||
1021 | // FIXME check that? | ||
1022 | // FIXME replace Unknown by bound vars here | ||
1023 | let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
1024 | |||
1025 | let env = self.ty.environment.clone(); | ||
1026 | let krate = krate.id; | ||
1027 | |||
1028 | method_resolution::iterate_method_candidates( | ||
1029 | &canonical, | ||
1030 | db, | ||
1031 | env, | ||
1032 | krate, | ||
1033 | traits_in_scope, | ||
1034 | name, | ||
1035 | method_resolution::LookupMode::MethodCall, | ||
1036 | |ty, it| match it { | ||
1037 | AssocItemId::FunctionId(f) => callback(ty, f.into()), | ||
1038 | _ => None, | ||
1039 | }, | ||
1040 | ) | ||
1041 | } | ||
1042 | |||
1043 | pub fn iterate_path_candidates<T>( | ||
1044 | &self, | ||
1045 | db: &impl HirDatabase, | ||
1046 | krate: Crate, | ||
1047 | traits_in_scope: &FxHashSet<TraitId>, | ||
1048 | name: Option<&Name>, | ||
1049 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | ||
1050 | ) -> Option<T> { | ||
1051 | // There should be no inference vars in types passed here | ||
1052 | // FIXME check that? | ||
1053 | // FIXME replace Unknown by bound vars here | ||
1054 | let canonical = Canonical { value: self.ty.value.clone(), num_vars: 0 }; | ||
1055 | |||
1056 | let env = self.ty.environment.clone(); | ||
1057 | let krate = krate.id; | ||
1058 | |||
1059 | method_resolution::iterate_method_candidates( | ||
1060 | &canonical, | ||
1061 | db, | ||
1062 | env, | ||
1063 | krate, | ||
1064 | traits_in_scope, | ||
1065 | name, | ||
1066 | method_resolution::LookupMode::Path, | ||
1067 | |ty, it| callback(ty, it.into()), | ||
1068 | ) | ||
1069 | } | ||
1070 | |||
989 | pub fn as_adt(&self) -> Option<Adt> { | 1071 | pub fn as_adt(&self) -> Option<Adt> { |
990 | let (adt, _subst) = self.ty.value.as_adt()?; | 1072 | let (adt, _subst) = self.ty.value.as_adt()?; |
991 | Some(adt.into()) | 1073 | Some(adt.into()) |
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs deleted file mode 100644 index 6314be8d4..000000000 --- a/crates/ra_hir/src/from_source.rs +++ /dev/null | |||
@@ -1,265 +0,0 @@ | |||
1 | //! Finds a corresponding hir data structure for a syntax node in a specific | ||
2 | //! file. | ||
3 | |||
4 | use hir_def::{ | ||
5 | child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, | ||
6 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, | ||
7 | StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, | ||
8 | }; | ||
9 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | ||
10 | use ra_db::FileId; | ||
11 | use ra_prof::profile; | ||
12 | use ra_syntax::{ | ||
13 | ast::{self, AstNode, NameOwner}, | ||
14 | match_ast, SyntaxNode, | ||
15 | }; | ||
16 | |||
17 | use crate::{ | ||
18 | db::{DefDatabase, HirDatabase}, | ||
19 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local, | ||
20 | MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, | ||
21 | }; | ||
22 | |||
23 | pub trait FromSource: Sized { | ||
24 | type Ast; | ||
25 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>; | ||
26 | } | ||
27 | |||
28 | pub trait FromSourceByContainer: Sized { | ||
29 | type Ast: AstNode + 'static; | ||
30 | type Id: Copy + 'static; | ||
31 | const KEY: Key<Self::Ast, Self::Id>; | ||
32 | } | ||
33 | |||
34 | impl<T: FromSourceByContainer> FromSource for T | ||
35 | where | ||
36 | T: From<<T as FromSourceByContainer>::Id>, | ||
37 | { | ||
38 | type Ast = <T as FromSourceByContainer>::Ast; | ||
39 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { | ||
40 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] | ||
41 | .get(&src) | ||
42 | .copied() | ||
43 | .map(Self::from) | ||
44 | } | ||
45 | } | ||
46 | |||
47 | macro_rules! from_source_by_container_impls { | ||
48 | ($(($hir:ident, $id:ident, $ast:path, $key:path)),* ,) => {$( | ||
49 | impl FromSourceByContainer for $hir { | ||
50 | type Ast = $ast; | ||
51 | type Id = $id; | ||
52 | const KEY: Key<Self::Ast, Self::Id> = $key; | ||
53 | } | ||
54 | )*} | ||
55 | } | ||
56 | |||
57 | from_source_by_container_impls![ | ||
58 | (Struct, StructId, ast::StructDef, keys::STRUCT), | ||
59 | (Union, UnionId, ast::UnionDef, keys::UNION), | ||
60 | (Enum, EnumId, ast::EnumDef, keys::ENUM), | ||
61 | (Trait, TraitId, ast::TraitDef, keys::TRAIT), | ||
62 | (Function, FunctionId, ast::FnDef, keys::FUNCTION), | ||
63 | (Static, StaticId, ast::StaticDef, keys::STATIC), | ||
64 | (Const, ConstId, ast::ConstDef, keys::CONST), | ||
65 | (TypeAlias, TypeAliasId, ast::TypeAliasDef, keys::TYPE_ALIAS), | ||
66 | (ImplBlock, ImplId, ast::ImplBlock, keys::IMPL), | ||
67 | ]; | ||
68 | |||
69 | impl FromSource for MacroDef { | ||
70 | type Ast = ast::MacroCall; | ||
71 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { | ||
72 | let kind = MacroDefKind::Declarative; | ||
73 | |||
74 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | ||
75 | let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?; | ||
76 | let krate = Some(module.krate().id); | ||
77 | |||
78 | let ast_id = Some(AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value))); | ||
79 | |||
80 | let id: MacroDefId = MacroDefId { krate, ast_id, kind }; | ||
81 | Some(MacroDef { id }) | ||
82 | } | ||
83 | } | ||
84 | |||
85 | impl FromSource for EnumVariant { | ||
86 | type Ast = ast::EnumVariant; | ||
87 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { | ||
88 | let parent_enum = src.value.parent_enum(); | ||
89 | let src_enum = InFile { file_id: src.file_id, value: parent_enum }; | ||
90 | let parent_enum = Enum::from_source(db, src_enum)?; | ||
91 | parent_enum.id.child_by_source(db)[keys::ENUM_VARIANT] | ||
92 | .get(&src) | ||
93 | .copied() | ||
94 | .map(EnumVariant::from) | ||
95 | } | ||
96 | } | ||
97 | |||
98 | impl FromSource for StructField { | ||
99 | type Ast = FieldSource; | ||
100 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { | ||
101 | let src = src.as_ref(); | ||
102 | |||
103 | // FIXME this is buggy | ||
104 | let variant_id: VariantId = match src.value { | ||
105 | FieldSource::Named(field) => { | ||
106 | let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?; | ||
107 | let src = InFile { file_id: src.file_id, value }; | ||
108 | let def = Struct::from_source(db, src)?; | ||
109 | def.id.into() | ||
110 | } | ||
111 | FieldSource::Pos(field) => { | ||
112 | let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; | ||
113 | let src = InFile { file_id: src.file_id, value }; | ||
114 | let def = EnumVariant::from_source(db, src)?; | ||
115 | EnumVariantId::from(def).into() | ||
116 | } | ||
117 | }; | ||
118 | |||
119 | let dyn_map = variant_id.child_by_source(db); | ||
120 | match src.value { | ||
121 | FieldSource::Pos(it) => dyn_map[keys::TUPLE_FIELD].get(&src.with_value(it.clone())), | ||
122 | FieldSource::Named(it) => dyn_map[keys::RECORD_FIELD].get(&src.with_value(it.clone())), | ||
123 | } | ||
124 | .copied() | ||
125 | .map(StructField::from) | ||
126 | } | ||
127 | } | ||
128 | |||
129 | impl Local { | ||
130 | pub fn from_source(db: &impl HirDatabase, src: InFile<ast::BindPat>) -> Option<Self> { | ||
131 | let file_id = src.file_id; | ||
132 | let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| { | ||
133 | let res = match_ast! { | ||
134 | match it { | ||
135 | ast::ConstDef(value) => { Const::from_source(db, InFile { value, file_id})?.into() }, | ||
136 | ast::StaticDef(value) => { Static::from_source(db, InFile { value, file_id})?.into() }, | ||
137 | ast::FnDef(value) => { Function::from_source(db, InFile { value, file_id})?.into() }, | ||
138 | _ => return None, | ||
139 | } | ||
140 | }; | ||
141 | Some(res) | ||
142 | })?; | ||
143 | let (_body, source_map) = db.body_with_source_map(parent.into()); | ||
144 | let src = src.map(ast::Pat::from); | ||
145 | let pat_id = source_map.node_pat(src.as_ref())?; | ||
146 | Some(Local { parent, pat_id }) | ||
147 | } | ||
148 | } | ||
149 | |||
150 | impl TypeParam { | ||
151 | pub fn from_source(db: &impl HirDatabase, src: InFile<ast::TypeParam>) -> Option<Self> { | ||
152 | let file_id = src.file_id; | ||
153 | let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| { | ||
154 | let res = match_ast! { | ||
155 | match it { | ||
156 | ast::FnDef(value) => { Function::from_source(db, InFile { value, file_id})?.id.into() }, | ||
157 | ast::StructDef(value) => { Struct::from_source(db, InFile { value, file_id})?.id.into() }, | ||
158 | ast::EnumDef(value) => { Enum::from_source(db, InFile { value, file_id})?.id.into() }, | ||
159 | ast::TraitDef(value) => { Trait::from_source(db, InFile { value, file_id})?.id.into() }, | ||
160 | ast::TypeAliasDef(value) => { TypeAlias::from_source(db, InFile { value, file_id})?.id.into() }, | ||
161 | ast::ImplBlock(value) => { ImplBlock::from_source(db, InFile { value, file_id})?.id.into() }, | ||
162 | _ => return None, | ||
163 | } | ||
164 | }; | ||
165 | Some(res) | ||
166 | })?; | ||
167 | let &id = parent.child_by_source(db)[keys::TYPE_PARAM].get(&src)?; | ||
168 | Some(TypeParam { id }) | ||
169 | } | ||
170 | } | ||
171 | |||
172 | impl Module { | ||
173 | pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> { | ||
174 | let _p = profile("Module::from_declaration"); | ||
175 | let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); | ||
176 | |||
177 | let parent_module = match parent_declaration { | ||
178 | Some(parent_declaration) => { | ||
179 | let src_parent = InFile { file_id: src.file_id, value: parent_declaration }; | ||
180 | Module::from_declaration(db, src_parent) | ||
181 | } | ||
182 | None => { | ||
183 | let source_file = db.parse(src.file_id.original_file(db)).tree(); | ||
184 | let src_parent = | ||
185 | InFile { file_id: src.file_id, value: ModuleSource::SourceFile(source_file) }; | ||
186 | Module::from_definition(db, src_parent) | ||
187 | } | ||
188 | }?; | ||
189 | |||
190 | let child_name = src.value.name()?.as_name(); | ||
191 | let def_map = db.crate_def_map(parent_module.id.krate); | ||
192 | let child_id = def_map[parent_module.id.local_id].children.get(&child_name)?; | ||
193 | Some(parent_module.with_module_id(*child_id)) | ||
194 | } | ||
195 | |||
196 | pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> { | ||
197 | let _p = profile("Module::from_definition"); | ||
198 | match src.value { | ||
199 | ModuleSource::Module(ref module) => { | ||
200 | assert!(!module.has_semi()); | ||
201 | return Module::from_declaration( | ||
202 | db, | ||
203 | InFile { file_id: src.file_id, value: module.clone() }, | ||
204 | ); | ||
205 | } | ||
206 | ModuleSource::SourceFile(_) => (), | ||
207 | }; | ||
208 | |||
209 | let original_file = src.file_id.original_file(db); | ||
210 | Module::from_file(db, original_file) | ||
211 | } | ||
212 | |||
213 | fn from_file(db: &impl DefDatabase, file: FileId) -> Option<Self> { | ||
214 | let _p = profile("Module::from_file"); | ||
215 | let (krate, local_id) = db.relevant_crates(file).iter().find_map(|&crate_id| { | ||
216 | let crate_def_map = db.crate_def_map(crate_id); | ||
217 | let local_id = crate_def_map.modules_for_file(file).next()?; | ||
218 | Some((crate_id, local_id)) | ||
219 | })?; | ||
220 | Some(Module { id: ModuleId { krate, local_id } }) | ||
221 | } | ||
222 | } | ||
223 | |||
224 | fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { | ||
225 | let _p = profile("analyze_container"); | ||
226 | return child_by_source(db, src).unwrap_or_default(); | ||
227 | |||
228 | fn child_by_source(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { | ||
229 | for container in src.value.ancestors().skip(1) { | ||
230 | let res = match_ast! { | ||
231 | match container { | ||
232 | ast::TraitDef(it) => { | ||
233 | let def = Trait::from_source(db, src.with_value(it))?; | ||
234 | def.id.child_by_source(db) | ||
235 | }, | ||
236 | ast::ImplBlock(it) => { | ||
237 | let def = ImplBlock::from_source(db, src.with_value(it))?; | ||
238 | def.id.child_by_source(db) | ||
239 | }, | ||
240 | ast::FnDef(it) => { | ||
241 | let def = Function::from_source(db, src.with_value(it))?; | ||
242 | DefWithBodyId::from(def.id) | ||
243 | .child_by_source(db) | ||
244 | }, | ||
245 | ast::StaticDef(it) => { | ||
246 | let def = Static::from_source(db, src.with_value(it))?; | ||
247 | DefWithBodyId::from(def.id) | ||
248 | .child_by_source(db) | ||
249 | }, | ||
250 | ast::ConstDef(it) => { | ||
251 | let def = Const::from_source(db, src.with_value(it))?; | ||
252 | DefWithBodyId::from(def.id) | ||
253 | .child_by_source(db) | ||
254 | }, | ||
255 | _ => { continue }, | ||
256 | } | ||
257 | }; | ||
258 | return Some(res); | ||
259 | } | ||
260 | |||
261 | let module_source = ModuleSource::from_child_node(db, src); | ||
262 | let c = Module::from_definition(db, src.with_value(module_source))?; | ||
263 | Some(c.id.child_by_source(db)) | ||
264 | } | ||
265 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 3d13978d4..e1c7b7a20 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -8,7 +8,7 @@ | |||
8 | #![recursion_limit = "512"] | 8 | #![recursion_limit = "512"] |
9 | 9 | ||
10 | macro_rules! impl_froms { | 10 | macro_rules! impl_froms { |
11 | ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { | 11 | ($e:ident: $($v:ident $(($($sv:ident),*))?),*$(,)?) => { |
12 | $( | 12 | $( |
13 | impl From<$v> for $e { | 13 | impl From<$v> for $e { |
14 | fn from(it: $v) -> $e { | 14 | fn from(it: $v) -> $e { |
@@ -27,6 +27,7 @@ macro_rules! impl_froms { | |||
27 | } | 27 | } |
28 | 28 | ||
29 | pub mod db; | 29 | pub mod db; |
30 | pub mod source_analyzer; | ||
30 | pub mod source_binder; | 31 | pub mod source_binder; |
31 | 32 | ||
32 | pub mod diagnostics; | 33 | pub mod diagnostics; |
@@ -35,7 +36,6 @@ mod from_id; | |||
35 | mod code_model; | 36 | mod code_model; |
36 | 37 | ||
37 | mod has_source; | 38 | mod has_source; |
38 | mod from_source; | ||
39 | 39 | ||
40 | pub use crate::{ | 40 | pub use crate::{ |
41 | code_model::{ | 41 | code_model::{ |
@@ -44,9 +44,9 @@ pub use crate::{ | |||
44 | MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, | 44 | MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, |
45 | TypeParam, Union, VariantDef, | 45 | TypeParam, Union, VariantDef, |
46 | }, | 46 | }, |
47 | from_source::FromSource, | ||
48 | has_source::HasSource, | 47 | has_source::HasSource, |
49 | source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 48 | source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
49 | source_binder::SourceBinder, | ||
50 | }; | 50 | }; |
51 | 51 | ||
52 | pub use hir_def::{ | 52 | pub use hir_def::{ |
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs new file mode 100644 index 000000000..4f8fc9602 --- /dev/null +++ b/crates/ra_hir/src/source_analyzer.rs | |||
@@ -0,0 +1,450 @@ | |||
1 | //! Lookup hir elements using positions in the source code. This is a lossy | ||
2 | //! transformation: in general, a single source might correspond to several | ||
3 | //! modules, functions, etc, due to macros, cfgs and `#[path=]` attributes on | ||
4 | //! modules. | ||
5 | //! | ||
6 | //! So, this modules should not be used during hir construction, it exists | ||
7 | //! purely for "IDE needs". | ||
8 | use std::sync::Arc; | ||
9 | |||
10 | use either::Either; | ||
11 | use hir_def::{ | ||
12 | body::{ | ||
13 | scope::{ExprScopes, ScopeId}, | ||
14 | BodySourceMap, | ||
15 | }, | ||
16 | expr::{ExprId, PatId}, | ||
17 | resolver::{self, resolver_for_scope, Resolver, TypeNs, ValueNs}, | ||
18 | DefWithBodyId, TraitId, | ||
19 | }; | ||
20 | use hir_expand::{ | ||
21 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, | ||
22 | }; | ||
23 | use hir_ty::{InEnvironment, InferenceResult, TraitEnvironment}; | ||
24 | use ra_syntax::{ | ||
25 | ast::{self, AstNode}, | ||
26 | AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextUnit, | ||
27 | }; | ||
28 | use rustc_hash::FxHashSet; | ||
29 | |||
30 | use crate::{ | ||
31 | db::HirDatabase, Adt, Const, DefWithBody, EnumVariant, Function, Local, MacroDef, Name, Path, | ||
32 | ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, | ||
33 | }; | ||
34 | |||
35 | /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of | ||
36 | /// original source files. It should not be used inside the HIR itself. | ||
37 | #[derive(Debug)] | ||
38 | pub struct SourceAnalyzer { | ||
39 | file_id: HirFileId, | ||
40 | resolver: Resolver, | ||
41 | body_owner: Option<DefWithBody>, | ||
42 | body_source_map: Option<Arc<BodySourceMap>>, | ||
43 | infer: Option<Arc<InferenceResult>>, | ||
44 | scopes: Option<Arc<ExprScopes>>, | ||
45 | } | ||
46 | |||
47 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
48 | pub enum PathResolution { | ||
49 | /// An item | ||
50 | Def(crate::ModuleDef), | ||
51 | /// A local binding (only value namespace) | ||
52 | Local(Local), | ||
53 | /// A generic parameter | ||
54 | TypeParam(TypeParam), | ||
55 | SelfType(crate::ImplBlock), | ||
56 | Macro(MacroDef), | ||
57 | AssocItem(crate::AssocItem), | ||
58 | } | ||
59 | |||
60 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
61 | pub struct ScopeEntryWithSyntax { | ||
62 | pub(crate) name: Name, | ||
63 | pub(crate) ptr: Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>, | ||
64 | } | ||
65 | |||
66 | impl ScopeEntryWithSyntax { | ||
67 | pub fn name(&self) -> &Name { | ||
68 | &self.name | ||
69 | } | ||
70 | |||
71 | pub fn ptr(&self) -> Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>> { | ||
72 | self.ptr | ||
73 | } | ||
74 | } | ||
75 | |||
76 | #[derive(Debug)] | ||
77 | pub struct ReferenceDescriptor { | ||
78 | pub range: TextRange, | ||
79 | pub name: String, | ||
80 | } | ||
81 | |||
82 | #[derive(Debug)] | ||
83 | pub struct Expansion { | ||
84 | macro_call_id: MacroCallId, | ||
85 | } | ||
86 | |||
87 | impl Expansion { | ||
88 | pub fn map_token_down( | ||
89 | &self, | ||
90 | db: &impl HirDatabase, | ||
91 | token: InFile<&SyntaxToken>, | ||
92 | ) -> Option<InFile<SyntaxToken>> { | ||
93 | let exp_info = self.file_id().expansion_info(db)?; | ||
94 | exp_info.map_token_down(token) | ||
95 | } | ||
96 | |||
97 | pub fn file_id(&self) -> HirFileId { | ||
98 | self.macro_call_id.as_file() | ||
99 | } | ||
100 | } | ||
101 | |||
102 | impl SourceAnalyzer { | ||
103 | pub fn new( | ||
104 | db: &impl HirDatabase, | ||
105 | node: InFile<&SyntaxNode>, | ||
106 | offset: Option<TextUnit>, | ||
107 | ) -> SourceAnalyzer { | ||
108 | crate::source_binder::SourceBinder::new(db).analyze(node, offset) | ||
109 | } | ||
110 | |||
111 | pub(crate) fn new_for_body( | ||
112 | db: &impl HirDatabase, | ||
113 | def: DefWithBodyId, | ||
114 | node: InFile<&SyntaxNode>, | ||
115 | offset: Option<TextUnit>, | ||
116 | ) -> SourceAnalyzer { | ||
117 | let (_body, source_map) = db.body_with_source_map(def); | ||
118 | let scopes = db.expr_scopes(def); | ||
119 | let scope = match offset { | ||
120 | None => scope_for(&scopes, &source_map, node), | ||
121 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), | ||
122 | }; | ||
123 | let resolver = resolver_for_scope(db, def, scope); | ||
124 | SourceAnalyzer { | ||
125 | resolver, | ||
126 | body_owner: Some(def.into()), | ||
127 | body_source_map: Some(source_map), | ||
128 | infer: Some(db.infer(def)), | ||
129 | scopes: Some(scopes), | ||
130 | file_id: node.file_id, | ||
131 | } | ||
132 | } | ||
133 | |||
134 | pub(crate) fn new_for_resolver( | ||
135 | resolver: Resolver, | ||
136 | node: InFile<&SyntaxNode>, | ||
137 | ) -> SourceAnalyzer { | ||
138 | SourceAnalyzer { | ||
139 | resolver, | ||
140 | body_owner: None, | ||
141 | body_source_map: None, | ||
142 | infer: None, | ||
143 | scopes: None, | ||
144 | file_id: node.file_id, | ||
145 | } | ||
146 | } | ||
147 | |||
148 | pub fn module(&self) -> Option<crate::code_model::Module> { | ||
149 | Some(crate::code_model::Module { id: self.resolver.module()? }) | ||
150 | } | ||
151 | |||
152 | fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { | ||
153 | let src = InFile { file_id: self.file_id, value: expr }; | ||
154 | self.body_source_map.as_ref()?.node_expr(src) | ||
155 | } | ||
156 | |||
157 | fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { | ||
158 | let src = InFile { file_id: self.file_id, value: pat }; | ||
159 | self.body_source_map.as_ref()?.node_pat(src) | ||
160 | } | ||
161 | |||
162 | fn expand_expr( | ||
163 | &self, | ||
164 | db: &impl HirDatabase, | ||
165 | expr: InFile<&ast::Expr>, | ||
166 | ) -> Option<InFile<ast::Expr>> { | ||
167 | let macro_call = ast::MacroCall::cast(expr.value.syntax().clone())?; | ||
168 | let macro_file = | ||
169 | self.body_source_map.as_ref()?.node_macro_file(expr.with_value(¯o_call))?; | ||
170 | let expanded = db.parse_or_expand(macro_file)?; | ||
171 | let kind = expanded.kind(); | ||
172 | let expr = InFile::new(macro_file, ast::Expr::cast(expanded)?); | ||
173 | |||
174 | if ast::MacroCall::can_cast(kind) { | ||
175 | self.expand_expr(db, expr.as_ref()) | ||
176 | } else { | ||
177 | Some(expr) | ||
178 | } | ||
179 | } | ||
180 | |||
181 | pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { | ||
182 | let expr_id = if let Some(expr) = self.expand_expr(db, InFile::new(self.file_id, expr)) { | ||
183 | self.body_source_map.as_ref()?.node_expr(expr.as_ref())? | ||
184 | } else { | ||
185 | self.expr_id(expr)? | ||
186 | }; | ||
187 | |||
188 | let ty = self.infer.as_ref()?[expr_id].clone(); | ||
189 | let environment = TraitEnvironment::lower(db, &self.resolver); | ||
190 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | ||
191 | } | ||
192 | |||
193 | pub fn type_of_pat(&self, db: &impl HirDatabase, pat: &ast::Pat) -> Option<Type> { | ||
194 | let pat_id = self.pat_id(pat)?; | ||
195 | let ty = self.infer.as_ref()?[pat_id].clone(); | ||
196 | let environment = TraitEnvironment::lower(db, &self.resolver); | ||
197 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | ||
198 | } | ||
199 | |||
200 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | ||
201 | let expr_id = self.expr_id(&call.clone().into())?; | ||
202 | self.infer.as_ref()?.method_resolution(expr_id).map(Function::from) | ||
203 | } | ||
204 | |||
205 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> { | ||
206 | let expr_id = self.expr_id(&field.clone().into())?; | ||
207 | self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into()) | ||
208 | } | ||
209 | |||
210 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { | ||
211 | let expr_id = match field.expr() { | ||
212 | Some(it) => self.expr_id(&it)?, | ||
213 | None => { | ||
214 | let src = InFile { file_id: self.file_id, value: field }; | ||
215 | self.body_source_map.as_ref()?.field_init_shorthand_expr(src)? | ||
216 | } | ||
217 | }; | ||
218 | self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) | ||
219 | } | ||
220 | |||
221 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { | ||
222 | let expr_id = self.expr_id(&record_lit.clone().into())?; | ||
223 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id).map(|it| it.into()) | ||
224 | } | ||
225 | |||
226 | pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option<crate::VariantDef> { | ||
227 | let pat_id = self.pat_id(&record_pat.clone().into())?; | ||
228 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id).map(|it| it.into()) | ||
229 | } | ||
230 | |||
231 | pub fn resolve_macro_call( | ||
232 | &self, | ||
233 | db: &impl HirDatabase, | ||
234 | macro_call: InFile<&ast::MacroCall>, | ||
235 | ) -> Option<MacroDef> { | ||
236 | let hygiene = Hygiene::new(db, macro_call.file_id); | ||
237 | let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; | ||
238 | self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into()) | ||
239 | } | ||
240 | |||
241 | pub fn resolve_hir_path( | ||
242 | &self, | ||
243 | db: &impl HirDatabase, | ||
244 | path: &crate::Path, | ||
245 | ) -> Option<PathResolution> { | ||
246 | let types = | ||
247 | self.resolver.resolve_path_in_type_ns_fully(db, path.mod_path()).map(|ty| match ty { | ||
248 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | ||
249 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), | ||
250 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | ||
251 | PathResolution::Def(Adt::from(it).into()) | ||
252 | } | ||
253 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
254 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | ||
255 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | ||
256 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | ||
257 | }); | ||
258 | let values = | ||
259 | self.resolver.resolve_path_in_value_ns_fully(db, path.mod_path()).and_then(|val| { | ||
260 | let res = match val { | ||
261 | ValueNs::LocalBinding(pat_id) => { | ||
262 | let var = Local { parent: self.body_owner?, pat_id }; | ||
263 | PathResolution::Local(var) | ||
264 | } | ||
265 | ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), | ||
266 | ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), | ||
267 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), | ||
268 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | ||
269 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
270 | }; | ||
271 | Some(res) | ||
272 | }); | ||
273 | |||
274 | let items = self | ||
275 | .resolver | ||
276 | .resolve_module_path_in_items(db, path.mod_path()) | ||
277 | .take_types() | ||
278 | .map(|it| PathResolution::Def(it.into())); | ||
279 | types.or(values).or(items).or_else(|| { | ||
280 | self.resolver | ||
281 | .resolve_path_as_macro(db, path.mod_path()) | ||
282 | .map(|def| PathResolution::Macro(def.into())) | ||
283 | }) | ||
284 | } | ||
285 | |||
286 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &ast::Path) -> Option<PathResolution> { | ||
287 | if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { | ||
288 | let expr_id = self.expr_id(&path_expr.into())?; | ||
289 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { | ||
290 | return Some(PathResolution::AssocItem(assoc.into())); | ||
291 | } | ||
292 | } | ||
293 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { | ||
294 | let pat_id = self.pat_id(&path_pat.into())?; | ||
295 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { | ||
296 | return Some(PathResolution::AssocItem(assoc.into())); | ||
297 | } | ||
298 | } | ||
299 | // This must be a normal source file rather than macro file. | ||
300 | let hir_path = crate::Path::from_ast(path.clone())?; | ||
301 | self.resolve_hir_path(db, &hir_path) | ||
302 | } | ||
303 | |||
304 | fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> { | ||
305 | let name = name_ref.as_name(); | ||
306 | let source_map = self.body_source_map.as_ref()?; | ||
307 | let scopes = self.scopes.as_ref()?; | ||
308 | let scope = scope_for(scopes, source_map, InFile::new(self.file_id, name_ref.syntax()))?; | ||
309 | let entry = scopes.resolve_name_in_scope(scope, &name)?; | ||
310 | Some(ScopeEntryWithSyntax { | ||
311 | name: entry.name().clone(), | ||
312 | ptr: source_map.pat_syntax(entry.pat())?.value, | ||
313 | }) | ||
314 | } | ||
315 | |||
316 | pub fn process_all_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { | ||
317 | self.resolver.process_all_names(db, &mut |name, def| { | ||
318 | let def = match def { | ||
319 | resolver::ScopeDef::PerNs(it) => it.into(), | ||
320 | resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), | ||
321 | resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), | ||
322 | resolver::ScopeDef::GenericParam(id) => ScopeDef::GenericParam(TypeParam { id }), | ||
323 | resolver::ScopeDef::Local(pat_id) => { | ||
324 | let parent = self.resolver.body_owner().unwrap().into(); | ||
325 | ScopeDef::Local(Local { parent, pat_id }) | ||
326 | } | ||
327 | }; | ||
328 | f(name, def) | ||
329 | }) | ||
330 | } | ||
331 | |||
332 | // FIXME: we only use this in `inline_local_variable` assist, ideally, we | ||
333 | // should switch to general reference search infra there. | ||
334 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | ||
335 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | ||
336 | let ptr = Either::Left(AstPtr::new(&ast::Pat::from(pat.clone()))); | ||
337 | fn_def | ||
338 | .syntax() | ||
339 | .descendants() | ||
340 | .filter_map(ast::NameRef::cast) | ||
341 | .filter(|name_ref| match self.resolve_local_name(&name_ref) { | ||
342 | None => false, | ||
343 | Some(entry) => entry.ptr() == ptr, | ||
344 | }) | ||
345 | .map(|name_ref| ReferenceDescriptor { | ||
346 | name: name_ref.text().to_string(), | ||
347 | range: name_ref.syntax().text_range(), | ||
348 | }) | ||
349 | .collect() | ||
350 | } | ||
351 | |||
352 | /// Note: `FxHashSet<TraitId>` should be treated as an opaque type, passed into `Type | ||
353 | pub fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<TraitId> { | ||
354 | self.resolver.traits_in_scope(db) | ||
355 | } | ||
356 | |||
357 | pub fn expand( | ||
358 | &self, | ||
359 | db: &impl HirDatabase, | ||
360 | macro_call: InFile<&ast::MacroCall>, | ||
361 | ) -> Option<Expansion> { | ||
362 | let def = self.resolve_macro_call(db, macro_call)?.id; | ||
363 | let ast_id = AstId::new( | ||
364 | macro_call.file_id, | ||
365 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | ||
366 | ); | ||
367 | Some(Expansion { macro_call_id: def.as_call_id(db, MacroCallKind::FnLike(ast_id)) }) | ||
368 | } | ||
369 | } | ||
370 | |||
371 | fn scope_for( | ||
372 | scopes: &ExprScopes, | ||
373 | source_map: &BodySourceMap, | ||
374 | node: InFile<&SyntaxNode>, | ||
375 | ) -> Option<ScopeId> { | ||
376 | node.value | ||
377 | .ancestors() | ||
378 | .filter_map(ast::Expr::cast) | ||
379 | .filter_map(|it| source_map.node_expr(InFile::new(node.file_id, &it))) | ||
380 | .find_map(|it| scopes.scope_for(it)) | ||
381 | } | ||
382 | |||
383 | fn scope_for_offset( | ||
384 | scopes: &ExprScopes, | ||
385 | source_map: &BodySourceMap, | ||
386 | offset: InFile<TextUnit>, | ||
387 | ) -> Option<ScopeId> { | ||
388 | scopes | ||
389 | .scope_by_expr() | ||
390 | .iter() | ||
391 | .filter_map(|(id, scope)| { | ||
392 | let source = source_map.expr_syntax(*id)?; | ||
393 | // FIXME: correctly handle macro expansion | ||
394 | if source.file_id != offset.file_id { | ||
395 | return None; | ||
396 | } | ||
397 | let syntax_node_ptr = | ||
398 | source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | ||
399 | Some((syntax_node_ptr, scope)) | ||
400 | }) | ||
401 | // find containing scope | ||
402 | .min_by_key(|(ptr, _scope)| { | ||
403 | ( | ||
404 | !(ptr.range().start() <= offset.value && offset.value <= ptr.range().end()), | ||
405 | ptr.range().len(), | ||
406 | ) | ||
407 | }) | ||
408 | .map(|(ptr, scope)| { | ||
409 | adjust(scopes, source_map, ptr, offset.file_id, offset.value).unwrap_or(*scope) | ||
410 | }) | ||
411 | } | ||
412 | |||
413 | // XXX: during completion, cursor might be outside of any particular | ||
414 | // expression. Try to figure out the correct scope... | ||
415 | fn adjust( | ||
416 | scopes: &ExprScopes, | ||
417 | source_map: &BodySourceMap, | ||
418 | ptr: SyntaxNodePtr, | ||
419 | file_id: HirFileId, | ||
420 | offset: TextUnit, | ||
421 | ) -> Option<ScopeId> { | ||
422 | let r = ptr.range(); | ||
423 | let child_scopes = scopes | ||
424 | .scope_by_expr() | ||
425 | .iter() | ||
426 | .filter_map(|(id, scope)| { | ||
427 | let source = source_map.expr_syntax(*id)?; | ||
428 | // FIXME: correctly handle macro expansion | ||
429 | if source.file_id != file_id { | ||
430 | return None; | ||
431 | } | ||
432 | let syntax_node_ptr = | ||
433 | source.value.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | ||
434 | Some((syntax_node_ptr, scope)) | ||
435 | }) | ||
436 | .map(|(ptr, scope)| (ptr.range(), scope)) | ||
437 | .filter(|(range, _)| range.start() <= offset && range.is_subrange(&r) && *range != r); | ||
438 | |||
439 | child_scopes | ||
440 | .max_by(|(r1, _), (r2, _)| { | ||
441 | if r2.is_subrange(&r1) { | ||
442 | std::cmp::Ordering::Greater | ||
443 | } else if r1.is_subrange(&r2) { | ||
444 | std::cmp::Ordering::Less | ||
445 | } else { | ||
446 | r1.start().cmp(&r2.start()) | ||
447 | } | ||
448 | }) | ||
449 | .map(|(_ptr, scope)| *scope) | ||
450 | } | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index a2a9d968c..f3150f578 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -1,569 +1,357 @@ | |||
1 | //! Lookup hir elements using positions in the source code. This is a lossy | 1 | //! `SourceBinder` is the main entry point for getting info about source code. |
2 | //! transformation: in general, a single source might correspond to several | 2 | //! It's main task is to map source syntax trees to hir-level IDs. |
3 | //! modules, functions, etc, due to macros, cfgs and `#[path=]` attributes on | 3 | |
4 | //! modules. | ||
5 | //! | ||
6 | //! So, this modules should not be used during hir construction, it exists | ||
7 | //! purely for "IDE needs". | ||
8 | use std::sync::Arc; | ||
9 | |||
10 | use either::Either; | ||
11 | use hir_def::{ | 4 | use hir_def::{ |
12 | body::{ | 5 | child_by_source::ChildBySource, |
13 | scope::{ExprScopes, ScopeId}, | 6 | dyn_map::DynMap, |
14 | BodySourceMap, | 7 | keys::{self, Key}, |
15 | }, | 8 | resolver::{HasResolver, Resolver}, |
16 | expr::{ExprId, PatId}, | 9 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, |