aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--ARCHITECTURE.md2
-rw-r--r--Cargo.lock186
-rw-r--r--Cargo.toml1
-rw-r--r--crates/ra_analysis/Cargo.toml3
-rw-r--r--crates/ra_analysis/src/completion/complete_dot.rs15
-rw-r--r--crates/ra_analysis/src/db.rs1
-rw-r--r--crates/ra_analysis/src/goto_defenition.rs73
-rw-r--r--crates/ra_analysis/src/imp.rs40
-rw-r--r--crates/ra_analysis/src/lib.rs13
-rw-r--r--crates/ra_analysis/src/mock_analysis.rs7
-rw-r--r--crates/ra_analysis/src/symbol_index.rs78
-rw-r--r--crates/ra_analysis/src/syntax_highlighting.rs10
-rw-r--r--crates/ra_analysis/tests/test/main.rs (renamed from crates/ra_analysis/tests/tests.rs)35
-rw-r--r--crates/ra_analysis/tests/test/runnables.rs (renamed from crates/ra_analysis/tests/runnables.rs)11
-rw-r--r--crates/ra_analysis/tests/test/type_of.rs (renamed from crates/ra_analysis/tests/type_of.rs)4
-rw-r--r--crates/ra_arena/Cargo.toml5
-rw-r--r--crates/ra_arena/src/lib.rs97
-rw-r--r--crates/ra_db/Cargo.toml2
-rw-r--r--crates/ra_editor/src/assists.rs188
-rw-r--r--crates/ra_editor/src/assists/add_derive.rs84
-rw-r--r--crates/ra_editor/src/assists/add_impl.rs66
-rw-r--r--crates/ra_editor/src/assists/change_visibility.rs116
-rw-r--r--crates/ra_editor/src/assists/flip_comma.rs31
-rw-r--r--crates/ra_editor/src/assists/introduce_variable.rs144
-rw-r--r--crates/ra_editor/src/assists/split_import.rs44
-rw-r--r--crates/ra_editor/src/code_actions.rs415
-rw-r--r--crates/ra_editor/src/diagnostics.rs6
-rw-r--r--crates/ra_editor/src/lib.rs6
-rw-r--r--crates/ra_editor/src/structure.rs6
-rw-r--r--crates/ra_editor/src/typing.rs68
-rw-r--r--crates/ra_hir/Cargo.toml4
-rw-r--r--crates/ra_hir/src/arena.rs66
-rw-r--r--crates/ra_hir/src/db.rs6
-rw-r--r--crates/ra_hir/src/function.rs17
-rw-r--r--crates/ra_hir/src/function/scope.rs12
-rw-r--r--crates/ra_hir/src/ids.rs31
-rw-r--r--crates/ra_hir/src/impl_block.rs180
-rw-r--r--crates/ra_hir/src/krate.rs2
-rw-r--r--crates/ra_hir/src/lib.rs3
-rw-r--r--crates/ra_hir/src/macros.rs18
-rw-r--r--crates/ra_hir/src/mock.rs5
-rw-r--r--crates/ra_hir/src/module.rs32
-rw-r--r--crates/ra_hir/src/module/nameres.rs10
-rw-r--r--crates/ra_hir/src/name.rs5
-rw-r--r--crates/ra_hir/src/path.rs5
-rw-r--r--crates/ra_hir/src/source_binder.rs39
-rw-r--r--crates/ra_hir/src/ty.rs168
-rw-r--r--crates/ra_hir/src/ty/tests.rs19
-rw-r--r--crates/ra_hir/src/ty/tests/data/0007_self.txt6
-rw-r--r--crates/ra_lsp_server/src/conv.rs53
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs4
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs5
-rw-r--r--crates/ra_lsp_server/src/req.rs22
-rw-r--r--crates/ra_lsp_server/src/server_world.rs32
-rw-r--r--crates/ra_lsp_server/tests/heavy_tests/main.rs23
-rw-r--r--crates/ra_syntax/src/ast.rs70
-rw-r--r--crates/ra_syntax/src/ast/generated.rs166
-rw-r--r--crates/ra_syntax/src/grammar.ron28
-rw-r--r--crates/ra_syntax/src/grammar/items.rs4
-rw-r--r--crates/ra_syntax/src/grammar/items/traits.rs6
-rw-r--r--crates/ra_syntax/src/parser_api.rs21
-rw-r--r--crates/ra_syntax/src/parser_impl.rs71
-rw-r--r--crates/ra_syntax/src/parser_impl/event.rs53
-rw-r--r--crates/ra_syntax/src/parser_impl/input.rs27
-rw-r--r--crates/ra_syntax/src/reparsing.rs2
-rw-r--r--crates/ra_syntax/src/syntax_kinds/generated.rs4
-rw-r--r--crates/ra_syntax/src/yellow/builder.rs4
-rw-r--r--crates/ra_syntax/src/yellow/syntax_text.rs24
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt12
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0001_trait_item_list.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0006_self_param.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0018_arb_self_types.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0021_impl_item_list.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0047_unsafe_default_impl.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_block_neg.rs (renamed from crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_item_neg.rs)0
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_block_neg.txt (renamed from crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_item_neg.txt)2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_block.rs (renamed from crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_item.rs)0
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_block.txt (renamed from crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_item.txt)2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0087_unsafe_impl.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0097_default_impl.txt2
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0037_mod.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0037_mod.txt16
-rw-r--r--crates/ra_text_edit/src/text_edit.rs5
-rw-r--r--crates/ra_vfs/Cargo.toml1
-rw-r--r--crates/ra_vfs/src/arena.rs53
-rw-r--r--crates/ra_vfs/src/lib.rs34
-rw-r--r--editors/code/package-lock.json872
-rw-r--r--editors/code/package.json2
-rw-r--r--editors/code/src/commands/apply_source_change.ts46
94 files changed, 2595 insertions, 1486 deletions
diff --git a/.travis.yml b/.travis.yml
index 04bb3be37..86bce93d6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,7 @@ build: &rust_build
10 script: 10 script:
11 - cargo gen-tests --verify 11 - cargo gen-tests --verify
12 - cargo gen-syntax --verify 12 - cargo gen-syntax --verify
13 - cargo test --no-run # let's measure compile time separately
13 - cargo test 14 - cargo test
14 env: 15 env:
15 - RUSTFLAGS="-D warnings", CARGO_INCREMENTAL=0 16 - RUSTFLAGS="-D warnings", CARGO_INCREMENTAL=0
@@ -25,7 +26,7 @@ matrix:
25 - cd editors/code && npm ci && npm run travis 26 - cd editors/code && npm ci && npm run travis
26 27
27 - os: windows 28 - os: windows
28 if: branch = master 29 if: branch = master AND type = push
29 before_script: 30 before_script:
30 - dos2unix ./crates/ra_syntax/tests/data/parser/**/*.txt 31 - dos2unix ./crates/ra_syntax/tests/data/parser/**/*.txt
31 - dos2unix ./crates/ra_syntax/tests/data/parser/**/*.rs 32 - dos2unix ./crates/ra_syntax/tests/data/parser/**/*.rs
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index b326f9c71..277b29c12 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -87,7 +87,7 @@ fixes a bug in the grammar.
87 87
88### `crates/ra_db` 88### `crates/ra_db`
89 89
90We use [salsa][https://github.com/salsa-rs/salsa] crate for incremental and 90We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and
91on-demand computation. Roughly, you can think of salsa as a key-value store, but 91on-demand computation. Roughly, you can think of salsa as a key-value store, but
92it also can compute derived values using specified functions. The `ra_db` crate 92it also can compute derived values using specified functions. The `ra_db` crate
93provides a basic infrastructure for interacting with salsa. Crucially, it 93provides a basic infrastructure for interacting with salsa. Crucially, it
diff --git a/Cargo.lock b/Cargo.lock
index 5f82e92f4..dbadfc64e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -32,7 +32,7 @@ name = "atty"
32version = "0.2.11" 32version = "0.2.11"
33source = "registry+https://github.com/rust-lang/crates.io-index" 33source = "registry+https://github.com/rust-lang/crates.io-index"
34dependencies = [ 34dependencies = [
35 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 35 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
36 "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 36 "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
37 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 37 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
38] 38]
@@ -50,8 +50,8 @@ dependencies = [
50 "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 50 "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
51 "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", 51 "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
52 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 52 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
53 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 53 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
54 "rustc-demangle 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 54 "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
55 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 55 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
56] 56]
57 57
@@ -61,7 +61,7 @@ version = "0.1.28"
61source = "registry+https://github.com/rust-lang/crates.io-index" 61source = "registry+https://github.com/rust-lang/crates.io-index"
62dependencies = [ 62dependencies = [
63 "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 63 "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
64 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 64 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
65] 65]
66 66
67[[package]] 67[[package]]
@@ -170,8 +170,8 @@ version = "0.3.6"
170source = "registry+https://github.com/rust-lang/crates.io-index" 170source = "registry+https://github.com/rust-lang/crates.io-index"
171dependencies = [ 171dependencies = [
172 "crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", 172 "crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
173 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 173 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
174 "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 174 "rand 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
175 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", 175 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
176] 176]
177 177
@@ -270,16 +270,16 @@ dependencies = [
270 270
271[[package]] 271[[package]]
272name = "failure" 272name = "failure"
273version = "0.1.4" 273version = "0.1.5"
274source = "registry+https://github.com/rust-lang/crates.io-index" 274source = "registry+https://github.com/rust-lang/crates.io-index"
275dependencies = [ 275dependencies = [
276 "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 276 "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
277 "failure_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 277 "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
278] 278]
279 279
280[[package]] 280[[package]]
281name = "failure_derive" 281name = "failure_derive"
282version = "0.1.4" 282version = "0.1.5"
283source = "registry+https://github.com/rust-lang/crates.io-index" 283source = "registry+https://github.com/rust-lang/crates.io-index"
284dependencies = [ 284dependencies = [
285 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", 285 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -337,7 +337,7 @@ name = "gen_lsp_server"
337version = "0.1.0" 337version = "0.1.0"
338dependencies = [ 338dependencies = [
339 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 339 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
340 "failure 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 340 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
341 "languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)", 341 "languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)",
342 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 342 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
343 "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", 343 "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -371,11 +371,6 @@ version = "1.1.0"
371source = "registry+https://github.com/rust-lang/crates.io-index" 371source = "registry+https://github.com/rust-lang/crates.io-index"
372 372
373[[package]] 373[[package]]
374name = "id-arena"
375version = "2.0.0"
376source = "registry+https://github.com/rust-lang/crates.io-index"
377
378[[package]]
379name = "idna" 374name = "idna"
380version = "0.1.5" 375version = "0.1.5"
381source = "registry+https://github.com/rust-lang/crates.io-index" 376source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -439,7 +434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
439 434
440[[package]] 435[[package]]
441name = "libc" 436name = "libc"
442version = "0.2.45" 437version = "0.2.46"
443source = "registry+https://github.com/rust-lang/crates.io-index" 438source = "registry+https://github.com/rust-lang/crates.io-index"
444 439
445[[package]] 440[[package]]
@@ -475,7 +470,7 @@ version = "2.1.2"
475source = "registry+https://github.com/rust-lang/crates.io-index" 470source = "registry+https://github.com/rust-lang/crates.io-index"
476dependencies = [ 471dependencies = [
477 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 472 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
478 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 473 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
479 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 474 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
480] 475]
481 476
@@ -484,7 +479,7 @@ name = "memmap"
484version = "0.6.2" 479version = "0.6.2"
485source = "registry+https://github.com/rust-lang/crates.io-index" 480source = "registry+https://github.com/rust-lang/crates.io-index"
486dependencies = [ 481dependencies = [
487 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 482 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
488 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 483 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
489] 484]
490 485
@@ -527,7 +522,7 @@ name = "num_cpus"
527version = "1.9.0" 522version = "1.9.0"
528source = "registry+https://github.com/rust-lang/crates.io-index" 523source = "registry+https://github.com/rust-lang/crates.io-index"
529dependencies = [ 524dependencies = [
530 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 525 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
531] 526]
532 527
533[[package]] 528[[package]]
@@ -540,16 +535,7 @@ dependencies = [
540 535
541[[package]] 536[[package]]
542name = "parking_lot" 537name = "parking_lot"
543version = "0.6.4" 538version = "0.7.1"
544source = "registry+https://github.com/rust-lang/crates.io-index"
545dependencies = [
546 "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
547 "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
548]
549
550[[package]]
551name = "parking_lot"
552version = "0.7.0"
553source = "registry+https://github.com/rust-lang/crates.io-index" 539source = "registry+https://github.com/rust-lang/crates.io-index"
554dependencies = [ 540dependencies = [
555 "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 541 "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -558,23 +544,11 @@ dependencies = [
558 544
559[[package]] 545[[package]]
560name = "parking_lot_core" 546name = "parking_lot_core"
561version = "0.3.1"
562source = "registry+https://github.com/rust-lang/crates.io-index"
563dependencies = [
564 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
565 "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
566 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
567 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
568 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
569]
570
571[[package]]
572name = "parking_lot_core"
573version = "0.4.0" 547version = "0.4.0"
574source = "registry+https://github.com/rust-lang/crates.io-index" 548source = "registry+https://github.com/rust-lang/crates.io-index"
575dependencies = [ 549dependencies = [
576 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 550 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
577 "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 551 "rand 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
578 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 552 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
579 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", 553 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
580 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 554 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -669,7 +643,7 @@ dependencies = [
669 "fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 643 "fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
670 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 644 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
671 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 645 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
672 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 646 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
673 "ra_db 0.1.0", 647 "ra_db 0.1.0",
674 "ra_editor 0.1.0", 648 "ra_editor 0.1.0",
675 "ra_hir 0.1.0", 649 "ra_hir 0.1.0",
@@ -678,16 +652,21 @@ dependencies = [
678 "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 652 "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
679 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 653 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
680 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 654 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
681 "salsa 0.9.0 (git+https://github.com/matklad/salsa.git?branch=transitive-untracked)", 655 "salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
682 "test_utils 0.1.0", 656 "test_utils 0.1.0",
657 "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
683] 658]
684 659
685[[package]] 660[[package]]
661name = "ra_arena"
662version = "0.1.0"
663
664[[package]]
686name = "ra_cli" 665name = "ra_cli"
687version = "0.1.0" 666version = "0.1.0"
688dependencies = [ 667dependencies = [
689 "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", 668 "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
690 "failure 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 669 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
691 "join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 670 "join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
692 "ra_editor 0.1.0", 671 "ra_editor 0.1.0",
693 "ra_syntax 0.1.0", 672 "ra_syntax 0.1.0",
@@ -698,12 +677,12 @@ dependencies = [
698name = "ra_db" 677name = "ra_db"
699version = "0.1.0" 678version = "0.1.0"
700dependencies = [ 679dependencies = [
701 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 680 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
702 "ra_editor 0.1.0", 681 "ra_editor 0.1.0",
703 "ra_syntax 0.1.0", 682 "ra_syntax 0.1.0",
704 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 683 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
705 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 684 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
706 "salsa 0.9.0 (git+https://github.com/matklad/salsa.git?branch=transitive-untracked)", 685 "salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
707 "test_utils 0.1.0", 686 "test_utils 0.1.0",
708] 687]
709 688
@@ -728,15 +707,15 @@ dependencies = [
728 "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 707 "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
729 "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 708 "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
730 "flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", 709 "flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
731 "id-arena 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
732 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 710 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
733 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 711 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
712 "ra_arena 0.1.0",
734 "ra_db 0.1.0", 713 "ra_db 0.1.0",
735 "ra_editor 0.1.0", 714 "ra_editor 0.1.0",
736 "ra_syntax 0.1.0", 715 "ra_syntax 0.1.0",
737 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 716 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
738 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 717 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
739 "salsa 0.9.0 (git+https://github.com/matklad/salsa.git?branch=transitive-untracked)", 718 "salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
740 "test_utils 0.1.0", 719 "test_utils 0.1.0",
741] 720]
742 721
@@ -747,14 +726,14 @@ dependencies = [
747 "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 726 "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
748 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 727 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
749 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 728 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
750 "failure 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 729 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
751 "failure_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 730 "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
752 "flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", 731 "flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
753 "gen_lsp_server 0.1.0", 732 "gen_lsp_server 0.1.0",
754 "im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 733 "im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
755 "languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)", 734 "languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)",
756 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 735 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
757 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 736 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
758 "ra_analysis 0.1.0", 737 "ra_analysis 0.1.0",
759 "ra_editor 0.1.0", 738 "ra_editor 0.1.0",
760 "ra_syntax 0.1.0", 739 "ra_syntax 0.1.0",
@@ -783,9 +762,9 @@ dependencies = [
783 "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 762 "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
784 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 763 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
785 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 764 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
786 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 765 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
787 "ra_text_edit 0.1.0", 766 "ra_text_edit 0.1.0",
788 "rowan 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 767 "rowan 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
789 "test_utils 0.1.0", 768 "test_utils 0.1.0",
790 "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 769 "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
791 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 770 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -807,6 +786,7 @@ version = "0.1.0"
807dependencies = [ 786dependencies = [
808 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 787 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
809 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 788 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
789 "ra_arena 0.1.0",
810 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 790 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
811 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 791 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
812 "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 792 "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -821,36 +801,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
821dependencies = [ 801dependencies = [
822 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 802 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
823 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 803 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
824 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 804 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
825 "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 805 "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
826 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 806 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
827] 807]
828 808
829[[package]] 809[[package]]
830name = "rand" 810name = "rand"
831version = "0.6.1" 811version = "0.6.3"
832source = "registry+https://github.com/rust-lang/crates.io-index" 812source = "registry+https://github.com/rust-lang/crates.io-index"
833dependencies = [ 813dependencies = [
834 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 814 "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
835 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 815 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
836 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 816 "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
837 "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
838 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 817 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
839 "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 818 "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
840 "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 819 "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
820 "rand_os 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
841 "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 821 "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
842 "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 822 "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
843 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
844 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 823 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
845] 824]
846 825
847[[package]] 826[[package]]
848name = "rand_chacha" 827name = "rand_chacha"
849version = "0.1.0" 828version = "0.1.1"
850source = "registry+https://github.com/rust-lang/crates.io-index" 829source = "registry+https://github.com/rust-lang/crates.io-index"
851dependencies = [ 830dependencies = [
831 "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
852 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 832 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
853 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
854] 833]
855 834
856[[package]] 835[[package]]
@@ -883,6 +862,18 @@ dependencies = [
883] 862]
884 863
885[[package]] 864[[package]]
865name = "rand_os"
866version = "0.1.0"
867source = "registry+https://github.com/rust-lang/crates.io-index"
868dependencies = [
869 "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
870 "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
871 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
872 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
873 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
874]
875
876[[package]]
886name = "rand_pcg" 877name = "rand_pcg"
887version = "0.1.1" 878version = "0.1.1"
888source = "registry+https://github.com/rust-lang/crates.io-index" 879source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -893,7 +884,7 @@ dependencies = [
893 884
894[[package]] 885[[package]]
895name = "rand_xorshift" 886name = "rand_xorshift"
896version = "0.1.0" 887version = "0.1.1"
897source = "registry+https://github.com/rust-lang/crates.io-index" 888source = "registry+https://github.com/rust-lang/crates.io-index"
898dependencies = [ 889dependencies = [
899 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 890 "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -916,7 +907,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
916dependencies = [ 907dependencies = [
917 "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 908 "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
918 "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 909 "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
919 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 910 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
920 "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 911 "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
921] 912]
922 913
@@ -978,17 +969,17 @@ dependencies = [
978 969
979[[package]] 970[[package]]
980name = "rowan" 971name = "rowan"
981version = "0.1.3" 972version = "0.1.4"
982source = "registry+https://github.com/rust-lang/crates.io-index" 973source = "registry+https://github.com/rust-lang/crates.io-index"
983dependencies = [ 974dependencies = [
984 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 975 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
985 "smol_str 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 976 "smol_str 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
986 "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 977 "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
987] 978]
988 979
989[[package]] 980[[package]]
990name = "rustc-demangle" 981name = "rustc-demangle"
991version = "0.1.11" 982version = "0.1.13"
992source = "registry+https://github.com/rust-lang/crates.io-index" 983source = "registry+https://github.com/rust-lang/crates.io-index"
993 984
994[[package]] 985[[package]]
@@ -1030,14 +1021,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1030 1021
1031[[package]] 1022[[package]]
1032name = "salsa" 1023name = "salsa"
1033version = "0.9.0" 1024version = "0.9.1"
1034source = "git+https://github.com/matklad/salsa.git?branch=transitive-untracked#a2198f1f8a1d09894b842035a1af6b0b4c133c93" 1025source = "registry+https://github.com/rust-lang/crates.io-index"
1035dependencies = [ 1026dependencies = [
1036 "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", 1027 "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
1037 "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1028 "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1038 "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1029 "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
1039 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 1030 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1040 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1031 "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
1041 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1032 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1042 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", 1033 "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
1043] 1034]
@@ -1174,8 +1165,8 @@ version = "3.0.5"
1174source = "registry+https://github.com/rust-lang/crates.io-index" 1165source = "registry+https://github.com/rust-lang/crates.io-index"
1175dependencies = [ 1166dependencies = [
1176 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1167 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
1177 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 1168 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
1178 "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 1169 "rand 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
1179 "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)", 1170 "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)",
1180 "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1171 "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1181 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 1172 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1206,7 +1197,7 @@ name = "teraron"
1206version = "0.0.1" 1197version = "0.0.1"
1207source = "registry+https://github.com/rust-lang/crates.io-index" 1198source = "registry+https://github.com/rust-lang/crates.io-index"
1208dependencies = [ 1199dependencies = [
1209 "failure 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1200 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
1210 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1201 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
1211 "ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1202 "ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1212 "tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)", 1203 "tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1217,7 +1208,7 @@ name = "termion"
1217version = "1.5.1" 1208version = "1.5.1"
1218source = "registry+https://github.com/rust-lang/crates.io-index" 1209source = "registry+https://github.com/rust-lang/crates.io-index"
1219dependencies = [ 1210dependencies = [
1220 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 1211 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
1221 "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)", 1212 "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)",
1222 "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1213 "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
1223] 1214]
@@ -1278,7 +1269,7 @@ name = "time"
1278version = "0.1.41" 1269version = "0.1.41"
1279source = "registry+https://github.com/rust-lang/crates.io-index" 1270source = "registry+https://github.com/rust-lang/crates.io-index"
1280dependencies = [ 1271dependencies = [
1281 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 1272 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
1282 "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)", 1273 "redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)",
1283 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 1274 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
1284] 1275]
@@ -1288,7 +1279,7 @@ name = "tools"
1288version = "0.1.0" 1279version = "0.1.0"
1289dependencies = [ 1280dependencies = [
1290 "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", 1281 "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
1291 "failure 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1282 "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
1292 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1283 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1293 "teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1284 "teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1294 "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 1285 "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1354,6 +1345,14 @@ dependencies = [
1354] 1345]
1355 1346
1356[[package]] 1347[[package]]
1348name = "unicase"
1349version = "2.2.0"
1350source = "registry+https://github.com/rust-lang/crates.io-index"
1351dependencies = [
1352 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
1353]
1354
1355[[package]]
1357name = "unicode-bidi" 1356name = "unicode-bidi"
1358version = "0.3.4" 1357version = "0.3.4"
1359source = "registry+https://github.com/rust-lang/crates.io-index" 1358source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1433,7 +1432,7 @@ name = "wait-timeout"
1433version = "0.1.5" 1432version = "0.1.5"
1434source = "registry+https://github.com/rust-lang/crates.io-index" 1433source = "registry+https://github.com/rust-lang/crates.io-index"
1435dependencies = [ 1434dependencies = [
1436 "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", 1435 "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
1437] 1436]
1438 1437
1439[[package]] 1438[[package]]
@@ -1508,8 +1507,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1508"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" 1507"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
1509"checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00" 1508"checksum ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f56c93cc076508c549d9bb747f79aa9b4eb098be7b8cad8830c3137ef52d1e00"
1510"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" 1509"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
1511"checksum failure 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e945b93ec214c6e97b520ec6c5d80267fc97af327658ee5b9f35984626e51fbf" 1510"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
1512"checksum failure_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c395a14ab27b42704e85bf2435c5c51f334ad7a96e16fe23c6e63a1cad6cc12" 1511"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
1513"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" 1512"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
1514"checksum flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dda06444ccc8b0a6da19d939989b4a4e83f328710ada449eedaed48c8b903cd" 1513"checksum flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dda06444ccc8b0a6da19d939989b4a4e83f328710ada449eedaed48c8b903cd"
1515"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 1514"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
@@ -1520,7 +1519,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1520"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 1519"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
1521"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 1520"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
1522"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" 1521"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
1523"checksum id-arena 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a7250033feafee46a1cecd2c2616a64aec1d064f38c9ae2bdd297728542843e"
1524"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1522"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
1525"checksum im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9c7f9bb8aee47fc16d535a705f7867a9fc83bb822e5e1043bb98e77ffeed3c" 1523"checksum im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9c7f9bb8aee47fc16d535a705f7867a9fc83bb822e5e1043bb98e77ffeed3c"
1526"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" 1524"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
@@ -1529,7 +1527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1529"checksum join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7bddc885f3fd69dd4b5d747c2efe6dd2c36d795ea9938281ed50910e32c95e31" 1527"checksum join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7bddc885f3fd69dd4b5d747c2efe6dd2c36d795ea9938281ed50910e32c95e31"
1530"checksum languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7c01845f71b8b3b3557a8179af4434a4b2570829da12371f05272d28183a06ce" 1528"checksum languageserver-types 0.53.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7c01845f71b8b3b3557a8179af4434a4b2570829da12371f05272d28183a06ce"
1531"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" 1529"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
1532"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" 1530"checksum libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)" = "023a4cd09b2ff695f9734c1934145a315594b7986398496841c7031a5a1bbdbd"
1533"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" 1531"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
1534"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" 1532"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
1535"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" 1533"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
@@ -1543,9 +1541,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1543"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" 1541"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
1544"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" 1542"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238"
1545"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" 1543"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
1546"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" 1544"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
1547"checksum parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9723236a9525c757d9725b993511e3fc941e33f27751942232f0058298297edf"
1548"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
1549"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" 1545"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
1550"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1546"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
1551"checksum pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54f0c72a98d8ab3c99560bfd16df8059cc10e1f9a8e83e6e3b97718dd766e9c3" 1547"checksum pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54f0c72a98d8ab3c99560bfd16df8059cc10e1f9a8e83e6e3b97718dd766e9c3"
@@ -1557,14 +1553,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1557"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" 1553"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
1558"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" 1554"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
1559"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" 1555"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
1560"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" 1556"checksum rand 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b65e163105a6284f841bd23100a015895f54340e88a5ffc9ca7b8b33827cfce0"
1561"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" 1557"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
1562"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" 1558"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
1563"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" 1559"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
1564"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1560"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
1565"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1561"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
1562"checksum rand_os 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de5ac4de1c2973e1391dc305cb0fbf8788cb58068e98255439b7485a77022273"
1566"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" 1563"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05"
1567"checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" 1564"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
1568"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" 1565"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473"
1569"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" 1566"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
1570"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2" 1567"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2"
@@ -1574,14 +1571,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1574"checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c" 1571"checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c"
1575"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" 1572"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
1576"checksum ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48677d8a9247a4e0d1f3f9cb4b0a8e29167fdc3c04f383a5e669cd7a960ae0f" 1573"checksum ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48677d8a9247a4e0d1f3f9cb4b0a8e29167fdc3c04f383a5e669cd7a960ae0f"
1577"checksum rowan 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9ccca91953e9c549cac18e8f41daa5d49dad1c9a4c9bb977ac42718bb34e1bf" 1574"checksum rowan 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c218b4430ab922850b71b14fa9bca224425097f935f6155c0b6a4b1f398a54f0"
1578"checksum rustc-demangle 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "01b90379b8664dd83460d59bdc5dd1fd3172b8913788db483ed1325171eab2f7" 1575"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
1579"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" 1576"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
1580"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1577"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
1581"checksum rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c" 1578"checksum rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c"
1582"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" 1579"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
1583"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" 1580"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
1584"checksum salsa 0.9.0 (git+https://github.com/matklad/salsa.git?branch=transitive-untracked)" = "<none>" 1581"checksum salsa 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "442ef4acdb48c0e24ddaf4f3b62555af2d1da7047f2f26acd54ae73010aa0c02"
1585"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" 1582"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
1586"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 1583"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
1587"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1584"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
@@ -1616,6 +1613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1616"checksum unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ca47cbb09fb5fcd066b5867d11dc528302fa465277882797d6a836e1ee6f9e" 1613"checksum unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ca47cbb09fb5fcd066b5867d11dc528302fa465277882797d6a836e1ee6f9e"
1617"checksum unic-ucd-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48f1a08ce0409a9e391b88d1930118eec48af12742fc538bcec55f775865776e" 1614"checksum unic-ucd-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48f1a08ce0409a9e391b88d1930118eec48af12742fc538bcec55f775865776e"
1618"checksum unic-ucd-version 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1f5e6c6c53c2d0ece4a5964bc55fcff8602153063cb4fab20958ff32998ff6" 1615"checksum unic-ucd-version 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1f5e6c6c53c2d0ece4a5964bc55fcff8602153063cb4fab20958ff32998ff6"
1616"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90"
1619"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1617"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
1620"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" 1618"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
1621"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" 1619"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
diff --git a/Cargo.toml b/Cargo.toml
index dd8499c06..c5155e899 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,4 +6,3 @@ incremental = true
6debug = true 6debug = true
7 7
8[patch.'crates-io'] 8[patch.'crates-io']
9salsa = { git = "https://github.com/matklad/salsa.git", branch = "transitive-untracked" }
diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml
index c0174cdc5..11c78ced8 100644
--- a/crates/ra_analysis/Cargo.toml
+++ b/crates/ra_analysis/Cargo.toml
@@ -10,9 +10,10 @@ log = "0.4.5"
10relative-path = "0.4.0" 10relative-path = "0.4.0"
11rayon = "1.0.2" 11rayon = "1.0.2"
12fst = "0.3.1" 12fst = "0.3.1"
13salsa = "0.9.0" 13salsa = "0.9.1"
14rustc-hash = "1.0" 14rustc-hash = "1.0"
15parking_lot = "0.7.0" 15parking_lot = "0.7.0"
16unicase = "2.2.0"
16 17
17ra_syntax = { path = "../ra_syntax" } 18ra_syntax = { path = "../ra_syntax" }
18ra_editor = { path = "../ra_editor" } 19ra_editor = { path = "../ra_editor" }
diff --git a/crates/ra_analysis/src/completion/complete_dot.rs b/crates/ra_analysis/src/completion/complete_dot.rs
index f24835d17..031d8b98f 100644
--- a/crates/ra_analysis/src/completion/complete_dot.rs
+++ b/crates/ra_analysis/src/completion/complete_dot.rs
@@ -73,6 +73,21 @@ mod tests {
73 } 73 }
74 74
75 #[test] 75 #[test]
76 fn test_struct_field_completion_self() {
77 check_ref_completion(
78 r"
79 struct A { the_field: u32 }
80 impl A {
81 fn foo(self) {
82 self.<|>
83 }
84 }
85 ",
86 r#"the_field"#,
87 );
88 }
89
90 #[test]
76 fn test_no_struct_field_completion_for_method_call() { 91 fn test_no_struct_field_completion_for_method_call() {
77 check_ref_completion( 92 check_ref_completion(
78 r" 93 r"
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs
index d7740f0c4..5422a400b 100644
--- a/crates/ra_analysis/src/db.rs
+++ b/crates/ra_analysis/src/db.rs
@@ -105,6 +105,7 @@ salsa::database_storage! {
105 fn type_for_field() for hir::db::TypeForFieldQuery; 105 fn type_for_field() for hir::db::TypeForFieldQuery;
106 fn struct_data() for hir::db::StructDataQuery; 106 fn struct_data() for hir::db::StructDataQuery;
107 fn enum_data() for hir::db::EnumDataQuery; 107 fn enum_data() for hir::db::EnumDataQuery;
108 fn impls_in_module() for hir::db::ImplsInModuleQuery;
108 } 109 }
109 } 110 }
110} 111}
diff --git a/crates/ra_analysis/src/goto_defenition.rs b/crates/ra_analysis/src/goto_defenition.rs
new file mode 100644
index 000000000..607a25115
--- /dev/null
+++ b/crates/ra_analysis/src/goto_defenition.rs
@@ -0,0 +1,73 @@
1use ra_db::FileId;
2use ra_syntax::ast;
3
4use crate::db::RootDatabase;
5
6pub fn goto_defenition(db: &RootDatabase, position: FilePosition,
7) -> Cancelable<Option<Vec<NavigationTarget>>> {
8 let file = db.source_file(position.file_id);
9 let syntax = file.syntax();
10 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
11 return Ok(Some(reference_defenition(db, position.file_id, name_ref)));
12 }
13 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) {
14 return Ok(Some(name_defenition(db, position.file_idname)));
15 }
16 Ok(None)
17}
18
19fn reference_defenition(db: &RootDatabase, file_id: FileId, name_ref: ast::NameRef) -> Cancelable<Vec<Nav>> {
20 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
21 let mut rr = ReferenceResolution::new(name_ref.syntax().range());
22 if let Some(fn_descr) =
23 source_binder::function_from_child_node(self, position.file_id, name_ref.syntax())?
24 {
25 let scope = fn_descr.scopes(self);
26 // First try to resolve the symbol locally
27 if let Some(entry) = scope.resolve_local_name(name_ref) {
28 rr.resolves_to.push(NavigationTarget {
29 file_id: position.file_id,
30 name: entry.name().to_string().into(),
31 range: entry.ptr().range(),
32 kind: NAME,
33 ptr: None,
34 });
35 return Ok(Some(rr));
36 };
37 }
38 // If that fails try the index based approach.
39 rr.resolves_to.extend(
40 self.index_resolve(name_ref)?
41 .into_iter()
42 .map(NavigationTarget::from_symbol),
43 );
44 return Ok(Some(rr));
45 }
46 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) {
47 let mut rr = ReferenceResolution::new(name.syntax().range());
48 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
49 if module.has_semi() {
50 if let Some(child_module) =
51 source_binder::module_from_declaration(self, position.file_id, module)?
52 {
53 let file_id = child_module.file_id();
54 let name = match child_module.name() {
55 Some(name) => name.to_string().into(),
56 None => "".into(),
57 };
58 let symbol = NavigationTarget {
59 file_id,
60 name,
61 range: TextRange::offset_len(0.into(), 0.into()),
62 kind: MODULE,
63 ptr: None,
64 };
65 rr.resolves_to.push(symbol);
66 return Ok(Some(rr));
67 }
68 }
69 }
70 }
71 Ok(None)
72
73}
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index b812c3441..eae73c2c4 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -6,7 +6,7 @@ use hir::{
6 self, FnSignatureInfo, Problem, source_binder, 6 self, FnSignatureInfo, Problem, source_binder,
7}; 7};
8use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; 8use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase};
9use ra_editor::{self, find_node_at_offset, LocalEdit, Severity}; 9use ra_editor::{self, find_node_at_offset, assists, LocalEdit, Severity};
10use ra_syntax::{ 10use ra_syntax::{
11 algo::{find_covering_node, visit::{visitor, Visitor}}, 11 algo::{find_covering_node, visit::{visitor, Visitor}},
12 ast::{self, ArgListOwner, Expr, FnDef, NameOwner}, 12 ast::{self, ArgListOwner, Expr, FnDef, NameOwner},
@@ -165,9 +165,11 @@ impl db::RootDatabase {
165 }; 165 };
166 } 166 }
167 // If that fails try the index based approach. 167 // If that fails try the index based approach.
168 for (file_id, symbol) in self.index_resolve(name_ref)? { 168 rr.resolves_to.extend(
169 rr.add_resolution(file_id, symbol); 169 self.index_resolve(name_ref)?
170 } 170 .into_iter()
171 .map(NavigationTarget::from_symbol),
172 );
171 return Ok(Some(rr)); 173 return Ok(Some(rr));
172 } 174 }
173 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { 175 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) {
@@ -333,19 +335,9 @@ impl db::RootDatabase {
333 335
334 pub(crate) fn assists(&self, frange: FileRange) -> Vec<SourceChange> { 336 pub(crate) fn assists(&self, frange: FileRange) -> Vec<SourceChange> {
335 let file = self.source_file(frange.file_id); 337 let file = self.source_file(frange.file_id);
336 let offset = frange.range.start(); 338 assists::assists(&file, frange.range)
337 let actions = vec![
338 ra_editor::flip_comma(&file, offset).map(|f| f()),
339 ra_editor::add_derive(&file, offset).map(|f| f()),
340 ra_editor::add_impl(&file, offset).map(|f| f()),
341 ra_editor::make_pub_crate(&file, offset).map(|f| f()),
342 ra_editor::introduce_variable(&file, frange.range).map(|f| f()),
343 ];
344 actions
345 .into_iter() 339 .into_iter()
346 .filter_map(|local_edit| { 340 .map(|local_edit| SourceChange::from_local_edit(frange.file_id, local_edit))
347 Some(SourceChange::from_local_edit(frange.file_id, local_edit?))
348 })
349 .collect() 341 .collect()
350 } 342 }
351 343
@@ -362,13 +354,15 @@ impl db::RootDatabase {
362 354
363 // Resolve the function's NameRef (NOTE: this isn't entirely accurate). 355 // Resolve the function's NameRef (NOTE: this isn't entirely accurate).
364 let file_symbols = self.index_resolve(name_ref)?; 356 let file_symbols = self.index_resolve(name_ref)?;
365 for (fn_file_id, fs) in file_symbols { 357 for symbol in file_symbols {
366 if fs.ptr.kind() == FN_DEF { 358 if symbol.ptr.kind() == FN_DEF {
367 let fn_file = self.source_file(fn_file_id); 359 let fn_file = self.source_file(symbol.file_id);
368 let fn_def = fs.ptr.resolve(&fn_file); 360 let fn_def = symbol.ptr.resolve(&fn_file);
369 let fn_def = ast::FnDef::cast(fn_def.borrowed()).unwrap(); 361 let fn_def = ast::FnDef::cast(fn_def.borrowed()).unwrap();
370 let descr = ctry!(source_binder::function_from_source( 362 let descr = ctry!(source_binder::function_from_source(
371 self, fn_file_id, fn_def 363 self,
364 symbol.file_id,
365 fn_def
372 )?); 366 )?);
373 if let Some(descriptor) = descr.signature_info(self) { 367 if let Some(descriptor) = descr.signature_info(self) {
374 // If we have a calling expression let's find which argument we are on 368 // If we have a calling expression let's find which argument we are on
@@ -440,7 +434,7 @@ impl db::RootDatabase {
440 .map(|(file_id, text_range)| SourceFileEdit { 434 .map(|(file_id, text_range)| SourceFileEdit {
441 file_id: *file_id, 435 file_id: *file_id,
442 edit: { 436 edit: {
443 let mut builder = ra_text_edit::TextEditBuilder::new(); 437 let mut builder = ra_text_edit::TextEditBuilder::default();
444 builder.replace(*text_range, new_name.into()); 438 builder.replace(*text_range, new_name.into());
445 builder.finish() 439 builder.finish()
446 }, 440 },
@@ -448,7 +442,7 @@ impl db::RootDatabase {
448 .collect::<Vec<_>>(); 442 .collect::<Vec<_>>();
449 Ok(res) 443 Ok(res)
450 } 444 }
451 fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<(FileId, FileSymbol)>> { 445 fn index_resolve(&self, name_ref: ast::NameRef) -> Cancelable<Vec<FileSymbol>> {
452 let name = name_ref.text(); 446 let name = name_ref.text();
453 let mut query = Query::new(name.to_string()); 447 let mut query = Query::new(name.to_string());
454 query.exact(); 448 query.exact();
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 61af676b2..1e26a2889 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -237,11 +237,11 @@ pub struct NavigationTarget {
237} 237}
238 238
239impl NavigationTarget { 239impl NavigationTarget {
240 fn from_symbol(file_id: FileId, symbol: FileSymbol) -> NavigationTarget { 240 fn from_symbol(symbol: FileSymbol) -> NavigationTarget {
241 NavigationTarget { 241 NavigationTarget {
242 file_id: symbol.file_id,
242 name: symbol.name.clone(), 243 name: symbol.name.clone(),
243 kind: symbol.ptr.kind(), 244 kind: symbol.ptr.kind(),
244 file_id,
245 range: symbol.ptr.range(), 245 range: symbol.ptr.range(),
246 ptr: Some(symbol.ptr.clone()), 246 ptr: Some(symbol.ptr.clone()),
247 } 247 }
@@ -278,11 +278,6 @@ impl ReferenceResolution {
278 resolves_to: Vec::new(), 278 resolves_to: Vec::new(),
279 } 279 }
280 } 280 }
281
282 fn add_resolution(&mut self, file_id: FileId, symbol: FileSymbol) {
283 self.resolves_to
284 .push(NavigationTarget::from_symbol(file_id, symbol))
285 }
286} 281}
287 282
288/// `AnalysisHost` stores the current state of the world. 283/// `AnalysisHost` stores the current state of the world.
@@ -380,7 +375,7 @@ impl Analysis {
380 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> { 375 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> {
381 let res = symbol_index::world_symbols(&*self.db, query)? 376 let res = symbol_index::world_symbols(&*self.db, query)?
382 .into_iter() 377 .into_iter()
383 .map(|(file_id, symbol)| NavigationTarget::from_symbol(file_id, symbol)) 378 .map(NavigationTarget::from_symbol)
384 .collect(); 379 .collect();
385 Ok(res) 380 Ok(res)
386 } 381 }
@@ -399,7 +394,7 @@ impl Analysis {
399 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> { 394 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
400 self.db.doc_text_for(nav) 395 self.db.doc_text_for(nav)
401 } 396 }
402 /// Returns a `mod name;` declaration whihc created the current module. 397 /// Returns a `mod name;` declaration which created the current module.
403 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { 398 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
404 self.db.parent_module(position) 399 self.db.parent_module(position)
405 } 400 }
diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs
index 960529404..846c76cfe 100644
--- a/crates/ra_analysis/src/mock_analysis.rs
+++ b/crates/ra_analysis/src/mock_analysis.rs
@@ -4,7 +4,7 @@ use relative_path::RelativePathBuf;
4use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER}; 4use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER};
5use ra_db::mock::FileMap; 5use ra_db::mock::FileMap;
6 6
7use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition, FileRange, SourceRootId}; 7use crate::{Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, FilePosition, FileRange, SourceRootId};
8 8
9/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis 9/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis
10/// from a set of in-memory files. 10/// from a set of in-memory files.
@@ -87,12 +87,17 @@ impl MockAnalysis {
87 let source_root = SourceRootId(0); 87 let source_root = SourceRootId(0);
88 let mut change = AnalysisChange::new(); 88 let mut change = AnalysisChange::new();
89 change.add_root(source_root, true); 89 change.add_root(source_root, true);
90 let mut crate_graph = CrateGraph::default();
90 for (path, contents) in self.files.into_iter() { 91 for (path, contents) in self.files.into_iter() {
91 assert!(path.starts_with('/')); 92 assert!(path.starts_with('/'));
92 let path = RelativePathBuf::from_path(&path[1..]).unwrap(); 93 let path = RelativePathBuf::from_path(&path[1..]).unwrap();
93 let file_id = file_map.add(path.clone()); 94 let file_id = file_map.add(path.clone());
95 if path == "/lib.rs" || path == "/main.rs" {
96 crate_graph.add_crate_root(file_id);
97 }
94 change.add_file(source_root, file_id, path, Arc::new(contents)); 98 change.add_file(source_root, file_id, path, Arc::new(contents));
95 } 99 }
100 change.set_crate_graph(crate_graph);
96 // change.set_file_resolver(Arc::new(file_map)); 101 // change.set_file_resolver(Arc::new(file_map));
97 host.apply_change(change); 102 host.apply_change(change);
98 host 103 host
diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs
index 10d8e8059..e2b1c88fe 100644
--- a/crates/ra_analysis/src/symbol_index.rs
+++ b/crates/ra_analysis/src/symbol_index.rs
@@ -20,6 +20,7 @@
20//! file in the current workspace, and run a query aginst the union of all 20//! file in the current workspace, and run a query aginst the union of all
21//! thouse fsts. 21//! thouse fsts.
22use std::{ 22use std::{
23 cmp::Ordering,
23 hash::{Hash, Hasher}, 24 hash::{Hash, Hasher},
24 sync::Arc, 25 sync::Arc,
25}; 26};
@@ -27,11 +28,11 @@ use std::{
27use fst::{self, Streamer}; 28use fst::{self, Streamer};
28use ra_syntax::{ 29use ra_syntax::{
29 SyntaxNodeRef, SourceFileNode, SmolStr, 30 SyntaxNodeRef, SourceFileNode, SmolStr,
30 algo::visit::{visitor, Visitor}, 31 algo::{visit::{visitor, Visitor}, find_covering_node},
31 SyntaxKind::{self, *}, 32 SyntaxKind::{self, *},
32 ast::{self, NameOwner}, 33 ast::{self, NameOwner},
33}; 34};
34use ra_db::{SyntaxDatabase, SourceRootId, FilesDatabase, LocalSyntaxPtr}; 35use ra_db::{SourceRootId, FilesDatabase, LocalSyntaxPtr};
35use salsa::ParallelDatabase; 36use salsa::ParallelDatabase;
36use rayon::prelude::*; 37use rayon::prelude::*;
37 38
@@ -41,7 +42,7 @@ use crate::{
41}; 42};
42 43
43salsa::query_group! { 44salsa::query_group! {
44 pub(crate) trait SymbolsDatabase: SyntaxDatabase { 45 pub(crate) trait SymbolsDatabase: hir::db::HirDatabase {
45 fn file_symbols(file_id: FileId) -> Cancelable<Arc<SymbolIndex>> { 46 fn file_symbols(file_id: FileId) -> Cancelable<Arc<SymbolIndex>> {
46 type FileSymbolsQuery; 47 type FileSymbolsQuery;
47 } 48 }
@@ -52,16 +53,26 @@ salsa::query_group! {
52 } 53 }
53} 54}
54 55
55fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Cancelable<Arc<SymbolIndex>> { 56fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Cancelable<Arc<SymbolIndex>> {
56 db.check_canceled()?; 57 db.check_canceled()?;
57 let syntax = db.source_file(file_id); 58 let source_file = db.source_file(file_id);
58 Ok(Arc::new(SymbolIndex::for_file(file_id, syntax))) 59 let mut symbols = source_file
60 .syntax()
61 .descendants()
62 .filter_map(to_symbol)
63 .map(move |(name, ptr)| FileSymbol { name, ptr, file_id })
64 .collect::<Vec<_>>();
65
66 for (name, text_range) in hir::source_binder::macro_symbols(db, file_id)? {
67 let node = find_covering_node(source_file.syntax(), text_range);
68 let ptr = LocalSyntaxPtr::new(node);
69 symbols.push(FileSymbol { file_id, name, ptr })
70 }
71
72 Ok(Arc::new(SymbolIndex::new(symbols)))
59} 73}
60 74
61pub(crate) fn world_symbols( 75pub(crate) fn world_symbols(db: &RootDatabase, query: Query) -> Cancelable<Vec<FileSymbol>> {
62 db: &RootDatabase,
63 query: Query,
64) -> Cancelable<Vec<(FileId, FileSymbol)>> {
65 /// Need to wrap Snapshot to provide `Clone` impl for `map_with` 76 /// Need to wrap Snapshot to provide `Clone` impl for `map_with`
66 struct Snap(salsa::Snapshot<RootDatabase>); 77 struct Snap(salsa::Snapshot<RootDatabase>);
67 impl Clone for Snap { 78 impl Clone for Snap {
@@ -95,7 +106,7 @@ pub(crate) fn world_symbols(
95 106
96#[derive(Default, Debug)] 107#[derive(Default, Debug)]
97pub(crate) struct SymbolIndex { 108pub(crate) struct SymbolIndex {
98 symbols: Vec<(FileId, FileSymbol)>, 109 symbols: Vec<FileSymbol>,
99 map: fst::Map, 110 map: fst::Map,
100} 111}
101 112
@@ -114,6 +125,17 @@ impl Hash for SymbolIndex {
114} 125}
115 126
116impl SymbolIndex { 127impl SymbolIndex {
128 fn new(mut symbols: Vec<FileSymbol>) -> SymbolIndex {
129 fn cmp(s1: &FileSymbol, s2: &FileSymbol) -> Ordering {
130 unicase::Ascii::new(s1.name.as_str()).cmp(&unicase::Ascii::new(s2.name.as_str()))
131 }
132 symbols.par_sort_by(cmp);
133 symbols.dedup_by(|s1, s2| cmp(s1, s2) == Ordering::Equal);
134 let names = symbols.iter().map(|it| it.name.as_str().to_lowercase());
135 let map = fst::Map::from_iter(names.into_iter().zip(0u64..)).unwrap();
136 SymbolIndex { symbols, map }
137 }
138
117 pub(crate) fn len(&self) -> usize { 139 pub(crate) fn len(&self) -> usize {
118 self.symbols.len() 140 self.symbols.len()
119 } 141 }
@@ -121,30 +143,21 @@ impl SymbolIndex {
121 pub(crate) fn for_files( 143 pub(crate) fn for_files(
122 files: impl ParallelIterator<Item = (FileId, SourceFileNode)>, 144 files: impl ParallelIterator<Item = (FileId, SourceFileNode)>,
123 ) -> SymbolIndex { 145 ) -> SymbolIndex {
124 let mut symbols = files 146 let symbols = files
125 .flat_map(|(file_id, file)| { 147 .flat_map(|(file_id, file)| {
126 file.syntax() 148 file.syntax()
127 .descendants() 149 .descendants()
128 .filter_map(to_symbol) 150 .filter_map(to_symbol)
129 .map(move |symbol| (symbol.name.as_str().to_lowercase(), (file_id, symbol))) 151 .map(move |(name, ptr)| FileSymbol { name, ptr, file_id })
130 .collect::<Vec<_>>() 152 .collect::<Vec<_>>()
131 }) 153 })
132 .collect::<Vec<_>>(); 154 .collect::<Vec<_>>();
133 symbols.par_sort_by(|s1, s2| s1.0.cmp(&s2.0)); 155 SymbolIndex::new(symbols)
134 symbols.dedup_by(|s1, s2| s1.0 == s2.0);
135 let (names, symbols): (Vec<String>, Vec<(FileId, FileSymbol)>) =
136 symbols.into_iter().unzip();
137 let map = fst::Map::from_iter(names.into_iter().zip(0u64..)).unwrap();
138 SymbolIndex { symbols, map }
139 }
140
141 pub(crate) fn for_file(file_id: FileId, file: SourceFileNode) -> SymbolIndex {
142 SymbolIndex::for_files(rayon::iter::once((file_id, file)))
143 } 156 }
144} 157}
145 158
146impl Query { 159impl Query {
147 pub(crate) fn search(self, indices: &[Arc<SymbolIndex>]) -> Vec<(FileId, FileSymbol)> { 160 pub(crate) fn search(self, indices: &[Arc<SymbolIndex>]) -> Vec<FileSymbol> {
148 let mut op = fst::map::OpBuilder::new(); 161 let mut op = fst::map::OpBuilder::new();
149 for file_symbols in indices.iter() { 162 for file_symbols in indices.iter() {
150 let automaton = fst::automaton::Subsequence::new(&self.lowercased); 163 let automaton = fst::automaton::Subsequence::new(&self.lowercased);
@@ -160,14 +173,14 @@ impl Query {
160 let file_symbols = &indices[indexed_value.index]; 173 let file_symbols = &indices[indexed_value.index];
161 let idx = indexed_value.value as usize; 174 let idx = indexed_value.value as usize;
162 175
163 let (file_id, symbol) = &file_symbols.symbols[idx]; 176 let symbol = &file_symbols.symbols[idx];
164 if self.only_types && !is_type(symbol.ptr.kind()) { 177 if self.only_types && !is_type(symbol.ptr.kind()) {
165 continue; 178 continue;
166 } 179 }
167 if self.exact && symbol.name != self.query { 180 if self.exact && symbol.name != self.query {
168 continue; 181 continue;
169 } 182 }
170 res.push((*file_id, symbol.clone())); 183 res.push(symbol.clone());
171 } 184 }
172 } 185 }
173 res 186 res
@@ -185,17 +198,16 @@ fn is_type(kind: SyntaxKind) -> bool {
185/// possible. 198/// possible.
186#[derive(Debug, Clone, PartialEq, Eq, Hash)] 199#[derive(Debug, Clone, PartialEq, Eq, Hash)]
187pub(crate) struct FileSymbol { 200pub(crate) struct FileSymbol {
201 pub(crate) file_id: FileId,
188 pub(crate) name: SmolStr, 202 pub(crate) name: SmolStr,
189 pub(crate) ptr: LocalSyntaxPtr, 203 pub(crate) ptr: LocalSyntaxPtr,
190} 204}
191 205
192fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> { 206fn to_symbol(node: SyntaxNodeRef) -> Option<(SmolStr, LocalSyntaxPtr)> {
193 fn decl<'a, N: NameOwner<'a>>(node: N) -> Option<FileSymbol> { 207 fn decl<'a, N: NameOwner<'a>>(node: N) -> Option<(SmolStr, LocalSyntaxPtr)> {
194 let name = node.name()?; 208 let name = node.name()?.text();
195 Some(FileSymbol { 209 let ptr = LocalSyntaxPtr::new(node.syntax());
196 name: name.text(), 210 Some((name, ptr))
197 ptr: LocalSyntaxPtr::new(node.syntax()),
198 })
199 } 211 }
200 visitor() 212 visitor()
201 .visit(decl::<ast::FnDef>) 213 .visit(decl::<ast::FnDef>)
diff --git a/crates/ra_analysis/src/syntax_highlighting.rs b/crates/ra_analysis/src/syntax_highlighting.rs
index ccea4aee3..35e153ca0 100644
--- a/crates/ra_analysis/src/syntax_highlighting.rs
+++ b/crates/ra_analysis/src/syntax_highlighting.rs
@@ -43,6 +43,7 @@ mod tests {
43 " 43 "
44 fn main() { 44 fn main() {
45 ctry!({ let x = 92; x}); 45 ctry!({ let x = 92; x});
46 vec![{ let x = 92; x}];
46 } 47 }
47 ", 48 ",
48 ); 49 );
@@ -53,10 +54,17 @@ mod tests {
53 HighlightedRange { range: [41; 46), tag: "macro" }, 54 HighlightedRange { range: [41; 46), tag: "macro" },
54 HighlightedRange { range: [49; 52), tag: "keyword" }, 55 HighlightedRange { range: [49; 52), tag: "keyword" },
55 HighlightedRange { range: [57; 59), tag: "literal" }, 56 HighlightedRange { range: [57; 59), tag: "literal" },
57 HighlightedRange { range: [82; 86), tag: "macro" },
58 HighlightedRange { range: [89; 92), tag: "keyword" },
59 HighlightedRange { range: [97; 99), tag: "literal" },
56 HighlightedRange { range: [49; 52), tag: "keyword" }, 60 HighlightedRange { range: [49; 52), tag: "keyword" },
57 HighlightedRange { range: [53; 54), tag: "function" }, 61 HighlightedRange { range: [53; 54), tag: "function" },
58 HighlightedRange { range: [57; 59), tag: "literal" }, 62 HighlightedRange { range: [57; 59), tag: "literal" },
59 HighlightedRange { range: [61; 62), tag: "text" }]"#, 63 HighlightedRange { range: [61; 62), tag: "text" },
64 HighlightedRange { range: [89; 92), tag: "keyword" },
65 HighlightedRange { range: [93; 94), tag: "function" },
66 HighlightedRange { range: [97; 99), tag: "literal" },
67 HighlightedRange { range: [101; 102), tag: "text" }]"#,
60 &highlights, 68 &highlights,
61 ) 69 )
62 } 70 }
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/test/main.rs
index bcf29d29c..beeae1e19 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/test/main.rs
@@ -1,9 +1,12 @@
1mod runnables;
2mod type_of;
3
1use ra_syntax::TextRange; 4use ra_syntax::TextRange;
2use test_utils::{assert_eq_dbg, assert_eq_text}; 5use test_utils::{assert_eq_dbg, assert_eq_text};
3 6
4use ra_analysis::{ 7use ra_analysis::{
5 mock_analysis::{analysis_and_position, single_file, single_file_with_position, MockAnalysis}, 8 mock_analysis::{analysis_and_position, single_file, single_file_with_position, MockAnalysis},
6 AnalysisChange, CrateGraph, FileId, FnSignatureInfo, 9 AnalysisChange, CrateGraph, FileId, FnSignatureInfo, Query
7}; 10};
8 11
9fn get_signature(text: &str) -> (FnSignatureInfo, Option<usize>) { 12fn get_signature(text: &str) -> (FnSignatureInfo, Option<usize>) {
@@ -135,14 +138,14 @@ fn test_resolve_parent_module_for_inline() {
135fn test_resolve_crate_root() { 138fn test_resolve_crate_root() {
136 let mock = MockAnalysis::with_files( 139 let mock = MockAnalysis::with_files(
137 " 140 "
138 //- /lib.rs 141 //- /bar.rs
139 mod foo; 142 mod foo;
140 //- /foo.rs 143 //- /bar/foo.rs
141 // emtpy <|> 144 // emtpy <|>
142 ", 145 ",
143 ); 146 );
144 let root_file = mock.id_of("/lib.rs"); 147 let root_file = mock.id_of("/bar.rs");
145 let mod_file = mock.id_of("/foo.rs"); 148 let mod_file = mock.id_of("/bar/foo.rs");
146 let mut host = mock.analysis_host(); 149 let mut host = mock.analysis_host();
147 assert!(host.analysis().crate_for(mod_file).unwrap().is_empty()); 150 assert!(host.analysis().crate_for(mod_file).unwrap().is_empty());
148 151
@@ -246,7 +249,8 @@ fn bar() {
246fn test_fn_signature_with_docs_simple() { 249fn test_fn_signature_with_docs_simple() {
247 let (desc, param) = get_signature( 250 let (desc, param) = get_signature(
248 r#" 251 r#"
249// test 252/// test
253// non-doc-comment
250fn foo(j: u32) -> u32 { 254fn foo(j: u32) -> u32 {
251 j 255 j
252} 256}
@@ -528,10 +532,11 @@ fn test_rename_for_mut_param() {
528 }"#, 532 }"#,
529 ); 533 );
530} 534}
535
531fn test_rename(text: &str, new_name: &str, expected: &str) { 536fn test_rename(text: &str, new_name: &str, expected: &str) {
532 let (analysis, position) = single_file_with_position(text); 537 let (analysis, position) = single_file_with_position(text);
533 let edits = analysis.rename(position, new_name).unwrap(); 538 let edits = analysis.rename(position, new_name).unwrap();
534 let mut text_edit_bulder = ra_text_edit::TextEditBuilder::new(); 539 let mut text_edit_bulder = ra_text_edit::TextEditBuilder::default();
535 let mut file_id: Option<FileId> = None; 540 let mut file_id: Option<FileId> = None;
536 for edit in edits { 541 for edit in edits {
537 file_id = Some(edit.file_id); 542 file_id = Some(edit.file_id);
@@ -544,3 +549,19 @@ fn test_rename(text: &str, new_name: &str, expected: &str) {
544 .apply(&*analysis.file_text(file_id.unwrap())); 549 .apply(&*analysis.file_text(file_id.unwrap()));
545 assert_eq_text!(expected, &*result); 550 assert_eq_text!(expected, &*result);
546} 551}
552
553#[test]
554fn world_symbols_include_stuff_from_macros() {
555 let (analysis, _) = single_file(
556 "
557salsa::query_group! {
558pub trait HirDatabase: SyntaxDatabase {}
559}
560 ",
561 );
562
563 let mut symbols = analysis.symbol_search(Query::new("Hir".into())).unwrap();
564 let s = symbols.pop().unwrap();
565 assert_eq!(s.name(), "HirDatabase");
566 assert_eq!(s.range(), TextRange::from_to(33.into(), 44.into()));
567}
diff --git a/crates/ra_analysis/tests/runnables.rs b/crates/ra_analysis/tests/test/runnables.rs
index 9e5342c46..e6e0afbc3 100644
--- a/crates/ra_analysis/tests/runnables.rs
+++ b/crates/ra_analysis/tests/test/runnables.rs
@@ -1,15 +1,6 @@
1extern crate ra_analysis;
2extern crate ra_editor;
3extern crate ra_syntax;
4extern crate relative_path;
5extern crate rustc_hash;
6extern crate test_utils;
7
8use test_utils::assert_eq_dbg; 1use test_utils::assert_eq_dbg;
9 2
10use ra_analysis::{ 3use ra_analysis::mock_analysis::analysis_and_position;
11 mock_analysis::{analysis_and_position},
12};
13 4
14#[test] 5#[test]
15fn test_runnables() { 6fn test_runnables() {
diff --git a/crates/ra_analysis/tests/type_of.rs b/crates/ra_analysis/tests/test/type_of.rs
index 375f808bb..9d15b52a8 100644
--- a/crates/ra_analysis/tests/type_of.rs
+++ b/crates/ra_analysis/tests/test/type_of.rs
@@ -1,6 +1,4 @@
1use ra_analysis::{ 1use ra_analysis::mock_analysis::single_file_with_range;
2 mock_analysis::{single_file_with_range},
3};
4 2
5#[test] 3#[test]
6fn test_type_of_for_function() { 4fn test_type_of_for_function() {
diff --git a/crates/ra_arena/Cargo.toml b/crates/ra_arena/Cargo.toml
new file mode 100644
index 000000000..9594e2d0f
--- /dev/null
+++ b/crates/ra_arena/Cargo.toml
@@ -0,0 +1,5 @@
1[package]
2edition = "2018"
3name = "ra_arena"
4version = "0.1.0"
5authors = ["Aleksey Kladov <[email protected]>"]
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs
new file mode 100644
index 000000000..a5eeb4118
--- /dev/null
+++ b/crates/ra_arena/src/lib.rs
@@ -0,0 +1,97 @@
1//! Yet another index-based arena.
2
3use std::{
4 fmt,
5 marker::PhantomData,
6 ops::{Index, IndexMut},
7};
8
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct RawId(u32);
11
12impl From<RawId> for u32 {
13 fn from(raw: RawId) -> u32 {
14 raw.0
15 }
16}
17
18impl From<u32> for RawId {
19 fn from(id: u32) -> RawId {
20 RawId(id)
21 }
22}
23
24impl fmt::Debug for RawId {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 self.0.fmt(f)
27 }
28}
29
30impl fmt::Display for RawId {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 self.0.fmt(f)
33 }
34}
35
36#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct Arena<ID: ArenaId, T> {
38 data: Vec<T>,
39 _ty: PhantomData<ID>,
40}
41
42#[macro_export]
43macro_rules! impl_arena_id {
44 ($name:ident) => {
45 impl $crate::ArenaId for $name {
46 fn from_raw(raw: $crate::RawId) -> Self {
47 $name(raw)
48 }
49 fn into_raw(self) -> $crate::RawId {
50 self.0
51 }
52 }
53 };
54}
55
56pub trait ArenaId {
57 fn from_raw(raw: RawId) -> Self;
58 fn into_raw(self) -> RawId;
59}
60
61impl<ID: ArenaId, T> Arena<ID, T> {
62 pub fn alloc(&mut self, value: T) -> ID {
63 let id = RawId(self.data.len() as u32);
64 self.data.push(value);
65 ID::from_raw(id)
66 }
67 pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> {
68 self.data
69 .iter()
70 .enumerate()
71 .map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value))
72 }
73}
74
75impl<ID: ArenaId, T> Default for Arena<ID, T> {
76 fn default() -> Arena<ID, T> {
77 Arena {
78 data: Vec::new(),
79 _ty: PhantomData,
80 }
81 }
82}
83
84impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> {
85 type Output = T;
86 fn index(&self, idx: ID) -> &T {
87 let idx = idx.into_raw().0 as usize;
88 &self.data[idx]
89 }
90}
91
92impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> {
93 fn index_mut(&mut self, idx: ID) -> &mut T {
94 let idx = idx.into_raw().0 as usize;
95 &mut self.data[idx]
96 }
97}
diff --git a/crates/ra_db/Cargo.toml b/crates/ra_db/Cargo.toml
index ecc56d953..c0e83a140 100644
--- a/crates/ra_db/Cargo.toml
+++ b/crates/ra_db/Cargo.toml
@@ -6,7 +6,7 @@ authors = ["Aleksey Kladov <[email protected]>"]
6 6
7[dependencies] 7[dependencies]
8relative-path = "0.4.0" 8relative-path = "0.4.0"
9salsa = "0.9.0" 9salsa = "0.9.1"
10rustc-hash = "1.0" 10rustc-hash = "1.0"
11parking_lot = "0.7.0" 11parking_lot = "0.7.0"
12ra_syntax = { path = "../ra_syntax" } 12ra_syntax = { path = "../ra_syntax" }
diff --git a/crates/ra_editor/src/assists.rs b/crates/ra_editor/src/assists.rs
new file mode 100644
index 000000000..57b78342a
--- /dev/null
+++ b/crates/ra_editor/src/assists.rs
@@ -0,0 +1,188 @@
1//! This modules contains various "assits": suggestions for source code edits
2//! which are likely to occur at a given cursor positon. For example, if the
3//! cursor is on the `,`, a possible assist is swapping the elments around the
4//! comma.
5
6mod flip_comma;
7mod add_derive;
8mod add_impl;
9mod introduce_variable;
10mod change_visibility;
11mod split_import;
12
13use ra_text_edit::{TextEdit, TextEditBuilder};
14use ra_syntax::{
15 Direction, SyntaxNodeRef, TextUnit, TextRange,SourceFileNode, AstNode,
16 algo::{find_leaf_at_offset, find_covering_node, LeafAtOffset},
17};
18
19use crate::find_node_at_offset;
20
21pub use self::{
22 flip_comma::flip_comma,
23 add_derive::add_derive,
24 add_impl::add_impl,
25 introduce_variable::introduce_variable,
26 change_visibility::change_visibility,
27 split_import::split_import,
28};
29
30/// Return all the assists applicable at the given position.
31pub fn assists(file: &SourceFileNode, range: TextRange) -> Vec<LocalEdit> {
32 let ctx = AssistCtx::new(file, range);
33 [
34 flip_comma,
35 add_derive,
36 add_impl,
37 introduce_variable,
38 change_visibility,
39 split_import,
40 ]
41 .iter()
42 .filter_map(|&assist| ctx.clone().apply(assist))
43 .collect()
44}
45
46#[derive(Debug)]
47pub struct LocalEdit {
48 pub label: String,
49 pub edit: TextEdit,
50 pub cursor_position: Option<TextUnit>,
51}
52
53fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> {
54 node.siblings(direction)
55 .skip(1)
56 .find(|node| !node.kind().is_trivia())
57}
58
59/// `AssistCtx` allows to apply an assist or check if it could be applied.
60///
61/// Assists use a somewhat overengeneered approach, given the current needs. The
62/// assists workflow consists of two phases. In the first phase, a user asks for
63/// the list of available assists. In the second phase, the user picks a
64/// particular assist and it gets applied.
65///
66/// There are two peculiarities here:
67///
68/// * first, we ideally avoid computing more things then neccessary to answer
69/// "is assist applicable" in the first phase.
70/// * second, when we are appling assist, we don't have a gurantee that there
71/// weren't any changes between the point when user asked for assists and when
72/// they applied a particular assist. So, when applying assist, we need to do
73/// all the checks from scratch.
74///
75/// To avoid repeating the same code twice for both "check" and "apply"
76/// functions, we use an approach remeniscent of that of Django's function based
77/// views dealing with forms. Each assist receives a runtime parameter,
78/// `should_compute_edit`. It first check if an edit is applicable (potentially
79/// computing info required to compute the actual edit). If it is applicable,
80/// and `should_compute_edit` is `true`, it then computes the actual edit.
81///
82/// So, to implement the original assists workflow, we can first apply each edit
83/// with `should_compute_edit = false`, and then applying the selected edit
84/// again, with `should_compute_edit = true` this time.
85///
86/// Note, however, that we don't actually use such two-phase logic at the
87/// moment, because the LSP API is pretty awkward in this place, and it's much
88/// easier to just compute the edit eagarly :-)
89#[derive(Debug, Clone)]
90pub struct AssistCtx<'a> {
91 source_file: &'a SourceFileNode,
92 range: TextRange,
93 should_compute_edit: bool,
94}
95
96#[derive(Debug)]
97pub enum Assist {
98 Applicable,
99 Edit(LocalEdit),
100}
101
102#[derive(Default)]
103struct AssistBuilder {
104 edit: TextEditBuilder,
105 cursor_position: Option<TextUnit>,
106}
107
108impl<'a> AssistCtx<'a> {
109 pub fn new(source_file: &'a SourceFileNode, range: TextRange) -> AssistCtx {
110 AssistCtx {
111 source_file,
112 range,
113 should_compute_edit: false,
114 }
115 }
116
117 pub fn apply(mut self, assist: fn(AssistCtx) -> Option<Assist>) -> Option<LocalEdit> {
118 self.should_compute_edit = true;
119 match assist(self) {
120 None => None,
121 Some(Assist::Edit(e)) => Some(e),
122 Some(Assist::Applicable) => unreachable!(),
123 }
124 }
125
126 pub fn check(mut self, assist: fn(AssistCtx) -> Option<Assist>) -> bool {
127 self.should_compute_edit = false;
128 match assist(self) {
129 None => false,
130 Some(Assist::Edit(_)) => unreachable!(),
131 Some(Assist::Applicable) => true,
132 }
133 }
134
135 fn build(self, label: impl Into<String>, f: impl FnOnce(&mut AssistBuilder)) -> Option<Assist> {
136 if !self.should_compute_edit {
137 return Some(Assist::Applicable);
138 }
139 let mut edit = AssistBuilder::default();
140 f(&mut edit);
141 Some(Assist::Edit(LocalEdit {
142 label: label.into(),
143 edit: edit.edit.finish(),
144 cursor_position: edit.cursor_position,
145 }))
146 }
147
148 pub(crate) fn leaf_at_offset(&self) -> LeafAtOffset<SyntaxNodeRef<'a>> {
149 find_leaf_at_offset(self.source_file.syntax(), self.range.start())
150 }
151 pub(crate) fn node_at_offset<N: AstNode<'a>>(&self) -> Option<N> {
152 find_node_at_offset(self.source_file.syntax(), self.range.start())
153 }
154 pub(crate) fn covering_node(&self) -> SyntaxNodeRef<'a> {
155 find_covering_node(self.source_file.syntax(), self.range)
156 }
157}
158
159impl AssistBuilder {
160 fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
161 self.edit.replace(range, replace_with.into())
162 }
163 #[allow(unused)]
164 fn delete(&mut self, range: TextRange) {
165 self.edit.delete(range)
166 }
167 fn insert(&mut self, offset: TextUnit, text: impl Into<String>) {
168 self.edit.insert(offset, text.into())
169 }
170 fn set_cursor(&mut self, offset: TextUnit) {
171 self.cursor_position = Some(offset)
172 }
173}
174
175#[cfg(test)]
176fn check_assist(assist: fn(AssistCtx) -> Option<Assist>, before: &str, after: &str) {
177 crate::test_utils::check_action(before, after, |file, off| {
178 let range = TextRange::offset_len(off, 0.into());
179 AssistCtx::new(file, range).apply(assist)
180 })
181}
182
183#[cfg(test)]
184fn check_assist_range(assist: fn(AssistCtx) -> Option<Assist>, before: &str, after: &str) {
185 crate::test_utils::check_action_range(before, after, |file, range| {
186 AssistCtx::new(file, range).apply(assist)
187 })
188}
diff --git a/crates/ra_editor/src/assists/add_derive.rs b/crates/ra_editor/src/assists/add_derive.rs
new file mode 100644
index 000000000..1e2cd4f30
--- /dev/null
+++ b/crates/ra_editor/src/assists/add_derive.rs
@@ -0,0 +1,84 @@
1use ra_syntax::{
2 ast::{self, AstNode, AttrsOwner},
3 SyntaxKind::{WHITESPACE, COMMENT},
4 TextUnit,
5};
6
7use crate::assists::{AssistCtx, Assist};
8
9pub fn add_derive(ctx: AssistCtx) -> Option<Assist> {
10 let nominal = ctx.node_at_offset::<ast::NominalDef>()?;
11 let node_start = derive_insertion_offset(nominal)?;
12 ctx.build("add `#[derive]`", |edit| {
13 let derive_attr = nominal
14 .attrs()
15 .filter_map(|x| x.as_call())
16 .filter(|(name, _arg)| name == "derive")
17 .map(|(_name, arg)| arg)
18 .next();
19 let offset = match derive_attr {
20 None => {
21 edit.insert(node_start, "#[derive()]\n");
22 node_start + TextUnit::of_str("#[derive(")
23 }
24 Some(tt) => tt.syntax().range().end() - TextUnit::of_char(')'),
25 };
26 edit.set_cursor(offset)
27 })
28}
29
30// Insert `derive` after doc comments.
31fn derive_insertion_offset(nominal: ast::NominalDef) -> Option<TextUnit> {
32 let non_ws_child = nominal
33 .syntax()
34 .children()
35 .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?;
36 Some(non_ws_child.range().start())
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::assists::check_assist;
43
44 #[test]
45 fn add_derive_new() {
46 check_assist(
47 add_derive,
48 "struct Foo { a: i32, <|>}",
49 "#[derive(<|>)]\nstruct Foo { a: i32, }",
50 );
51 check_assist(
52 add_derive,
53 "struct Foo { <|> a: i32, }",
54 "#[derive(<|>)]\nstruct Foo { a: i32, }",
55 );
56 }
57
58 #[test]
59 fn add_derive_existing() {
60 check_assist(
61 add_derive,
62 "#[derive(Clone)]\nstruct Foo { a: i32<|>, }",
63 "#[derive(Clone<|>)]\nstruct Foo { a: i32, }",
64 );
65 }
66
67 #[test]
68 fn add_derive_new_with_doc_comment() {
69 check_assist(
70 add_derive,
71 "
72/// `Foo` is a pretty important struct.
73/// It does stuff.
74struct Foo { a: i32<|>, }
75 ",
76 "
77/// `Foo` is a pretty important struct.
78/// It does stuff.
79#[derive(<|>)]
80struct Foo { a: i32, }
81 ",
82 );
83 }
84}
diff --git a/crates/ra_editor/src/assists/add_impl.rs b/crates/ra_editor/src/assists/add_impl.rs
new file mode 100644
index 000000000..9353e2717
--- /dev/null
+++ b/crates/ra_editor/src/assists/add_impl.rs
@@ -0,0 +1,66 @@
1use join_to_string::join;
2use ra_syntax::{
3 ast::{self, AstNode, NameOwner, TypeParamsOwner},
4 TextUnit,
5};
6
7use crate::assists::{AssistCtx, Assist};
8
9pub fn add_impl(ctx: AssistCtx) -> Option<Assist> {
10 let nominal = ctx.node_at_offset::<ast::NominalDef>()?;
11 let name = nominal.name()?;
12 ctx.build("add impl", |edit| {
13 let type_params = nominal.type_param_list();
14 let start_offset = nominal.syntax().range().end();
15 let mut buf = String::new();
16 buf.push_str("\n\nimpl");
17 if let Some(type_params) = type_params {
18 type_params.syntax().text().push_to(&mut buf);
19 }
20 buf.push_str(" ");
21 buf.push_str(name.text().as_str());
22 if let Some(type_params) = type_params {
23 let lifetime_params = type_params
24 .lifetime_params()
25 .filter_map(|it| it.lifetime())
26 .map(|it| it.text());
27 let type_params = type_params
28 .type_params()
29 .filter_map(|it| it.name())
30 .map(|it| it.text());
31 join(lifetime_params.chain(type_params))
32 .surround_with("<", ">")
33 .to_buf(&mut buf);
34 }
35 buf.push_str(" {\n");
36 edit.set_cursor(start_offset + TextUnit::of_str(&buf));
37 buf.push_str("\n}");
38 edit.insert(start_offset, buf);
39 })
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::assists::check_assist;
46
47 #[test]
48 fn test_add_impl() {
49 check_assist(
50 add_impl,
51 "struct Foo {<|>}\n",
52 "struct Foo {}\n\nimpl Foo {\n<|>\n}\n",
53 );
54 check_assist(
55 add_impl,
56 "struct Foo<T: Clone> {<|>}",
57 "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n<|>\n}",
58 );
59 check_assist(
60 add_impl,
61 "struct Foo<'a, T: Foo<'a>> {<|>}",
62 "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n<|>\n}",
63 );
64 }
65
66}
diff --git a/crates/ra_editor/src/assists/change_visibility.rs b/crates/ra_editor/src/assists/change_visibility.rs
new file mode 100644
index 000000000..6c8466394
--- /dev/null
+++ b/crates/ra_editor/src/assists/change_visibility.rs
@@ -0,0 +1,116 @@
1use ra_syntax::{
2 AstNode,
3 ast::{self, VisibilityOwner, NameOwner},
4 SyntaxKind::{VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF, IDENT},
5};
6
7use crate::assists::{AssistCtx, Assist};
8
9pub fn change_visibility(ctx: AssistCtx) -> Option<Assist> {
10 if let Some(vis) = ctx.node_at_offset::<ast::Visibility>() {
11 return change_vis(ctx, vis);
12 }
13 add_vis(ctx)
14}
15
16fn add_vis(ctx: AssistCtx) -> Option<Assist> {
17 let item_keyword = ctx.leaf_at_offset().find(|leaf| match leaf.kind() {
18 FN_KW | MOD_KW | STRUCT_KW | ENUM_KW | TRAIT_KW => true,
19 _ => false,
20 });
21
22 let offset = if let Some(keyword) = item_keyword {
23 let parent = keyword.parent()?;
24 let def_kws = vec![FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF];
25 // Parent is not a definition, can't add visibility
26 if !def_kws.iter().any(|&def_kw| def_kw == parent.kind()) {
27 return None;
28 }
29 // Already have visibility, do nothing
30 if parent.children().any(|child| child.kind() == VISIBILITY) {
31 return None;
32 }
33 parent.range().start()
34 } else {
35 let ident = ctx.leaf_at_offset().find(|leaf| leaf.kind() == IDENT)?;
36 let field = ident.ancestors().find_map(ast::NamedFieldDef::cast)?;
37 if field.name()?.syntax().range() != ident.range() && field.visibility().is_some() {
38 return None;
39 }
40 field.syntax().range().start()
41 };
42
43 ctx.build("make pub(crate)", |edit| {
44 edit.insert(offset, "pub(crate) ");
45 edit.set_cursor(offset);
46 })
47}
48
49fn change_vis(ctx: AssistCtx, vis: ast::Visibility) -> Option<Assist> {
50 if vis.syntax().text() != "pub" {
51 return None;
52 }
53 ctx.build("chage to pub(crate)", |edit| {
54 edit.replace(vis.syntax().range(), "pub(crate)");
55 edit.set_cursor(vis.syntax().range().start());
56 })
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use crate::assists::check_assist;
63
64 #[test]
65 fn change_visibility_adds_pub_crate_to_items() {
66 check_assist(
67 change_visibility,
68 "<|>fn foo() {}",
69 "<|>pub(crate) fn foo() {}",
70 );
71 check_assist(
72 change_visibility,
73 "f<|>n foo() {}",
74 "<|>pub(crate) fn foo() {}",
75 );
76 check_assist(
77 change_visibility,
78 "<|>struct Foo {}",
79 "<|>pub(crate) struct Foo {}",
80 );
81 check_assist(
82 change_visibility,
83 "<|>mod foo {}",
84 "<|>pub(crate) mod foo {}",
85 );
86 check_assist(
87 change_visibility,
88 "<|>trait Foo {}",
89 "<|>pub(crate) trait Foo {}",
90 );
91 check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}");
92 check_assist(
93 change_visibility,
94 "unsafe f<|>n foo() {}",
95 "<|>pub(crate) unsafe fn foo() {}",
96 );
97 }
98
99 #[test]
100 fn change_visibility_works_with_struct_fields() {
101 check_assist(
102 change_visibility,
103 "struct S { <|>field: u32 }",
104 "struct S { <|>pub(crate) field: u32 }",
105 )
106 }
107
108 #[test]
109 fn change_visibility_pub_to_pub_crate() {
110 check_assist(
111 change_visibility,
112 "<|>pub fn foo() {}",
113 "<|>pub(crate) fn foo() {}",
114 )
115 }
116}
diff --git a/crates/ra_editor/src/assists/flip_comma.rs b/crates/ra_editor/src/assists/flip_comma.rs
new file mode 100644
index 000000000..a343413cc
--- /dev/null
+++ b/crates/ra_editor/src/assists/flip_comma.rs
@@ -0,0 +1,31 @@
1use ra_syntax::{
2 Direction,
3 SyntaxKind::COMMA,
4};
5
6use crate::assists::{non_trivia_sibling, AssistCtx, Assist};
7
8pub fn flip_comma(ctx: AssistCtx) -> Option<Assist> {
9 let comma = ctx.leaf_at_offset().find(|leaf| leaf.kind() == COMMA)?;
10 let prev = non_trivia_sibling(comma, Direction::Prev)?;
11 let next = non_trivia_sibling(comma, Direction::Next)?;
12 ctx.build("flip comma", |edit| {
13 edit.replace(prev.range(), next.text());
14 edit.replace(next.range(), prev.text());
15 })
16}
17
18#[cfg(test)]
19mod tests {
20 use super::*;
21 use crate::assists::check_assist;
22
23 #[test]
24 fn flip_comma_works_for_function_parameters() {
25 check_assist(
26 flip_comma,
27 "fn foo(x: i32,<|> y: Result<(), ()>) {}",
28 "fn foo(y: Result<(), ()>,<|> x: i32) {}",
29 )
30 }
31}
diff --git a/crates/ra_editor/src/assists/introduce_variable.rs b/crates/ra_editor/src/assists/introduce_variable.rs
new file mode 100644
index 000000000..782861023
--- /dev/null
+++ b/crates/ra_editor/src/assists/introduce_variable.rs
@@ -0,0 +1,144 @@
1use ra_syntax::{
2 ast::{self, AstNode},
3 SyntaxKind::WHITESPACE,
4 SyntaxNodeRef, TextUnit,
5};
6
7use crate::assists::{AssistCtx, Assist};
8
9pub fn introduce_variable<'a>(ctx: AssistCtx) -> Option<Assist> {
10 let node = ctx.covering_node();
11 let expr = node.ancestors().filter_map(ast::Expr::cast).next()?;
12
13 let anchor_stmt = anchor_stmt(expr)?;
14 let indent = anchor_stmt.prev_sibling()?;
15 if indent.kind() != WHITESPACE {
16 return None;
17 }
18 ctx.build("introduce variable", move |edit| {
19 let mut buf = String::new();
20
21 buf.push_str("let var_name = ");
22 expr.syntax().text().push_to(&mut buf);
23 let is_full_stmt = if let Some(expr_stmt) = ast::ExprStmt::cast(anchor_stmt) {
24 Some(expr.syntax()) == expr_stmt.expr().map(|e| e.syntax())
25 } else {
26 false
27 };
28 if is_full_stmt {
29 edit.replace(expr.syntax().range(), buf);
30 } else {
31 buf.push_str(";");
32 indent.text().push_to(&mut buf);
33 edit.replace(expr.syntax().range(), "var_name".to_string());
34 edit.insert(anchor_stmt.range().start(), buf);
35 }
36 edit.set_cursor(anchor_stmt.range().start() + TextUnit::of_str("let "));
37 })
38}
39
40/// Statement or last in the block expression, which will follow
41/// the freshly introduced var.
42fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> {
43 expr.syntax().ancestors().find(|&node| {
44 if ast::Stmt::cast(node).is_some() {
45 return true;
46 }
47 if let Some(expr) = node
48 .parent()
49 .and_then(ast::Block::cast)
50 .and_then(|it| it.expr())
51 {
52 if expr.syntax() == node {
53 return true;
54 }
55 }
56 false
57 })
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use crate::assists::check_assist_range;
64
65 #[test]
66 fn test_introduce_var_simple() {
67 check_assist_range(
68 introduce_variable,
69 "
70fn foo() {
71 foo(<|>1 + 1<|>);
72}",
73 "
74fn foo() {
75 let <|>var_name = 1 + 1;
76 foo(var_name);
77}",
78 );
79 }
80
81 #[test]
82 fn test_introduce_var_expr_stmt() {
83 check_assist_range(
84 introduce_variable,
85 "
86fn foo() {
87 <|>1 + 1<|>;
88}",
89 "
90fn foo() {
91 let <|>var_name = 1 + 1;
92}",
93 );
94 }
95
96 #[test]
97 fn test_introduce_var_part_of_expr_stmt() {
98 check_assist_range(
99 introduce_variable,
100 "
101fn foo() {
102 <|>1<|> + 1;
103}",
104 "
105fn foo() {
106 let <|>var_name = 1;
107 var_name + 1;
108}",
109 );
110 }
111
112 #[test]
113 fn test_introduce_var_last_expr() {
114 check_assist_range(
115 introduce_variable,
116 "
117fn foo() {
118 bar(<|>1 + 1<|>)
119}",
120 "
121fn foo() {
122 let <|>var_name = 1 + 1;
123 bar(var_name)
124}",
125 );
126 }
127
128 #[test]
129 fn test_introduce_var_last_full_expr() {
130 check_assist_range(
131 introduce_variable,
132 "
133fn foo() {
134 <|>bar(1 + 1)<|>
135}",
136 "
137fn foo() {
138 let <|>var_name = bar(1 + 1);
139 var_name
140}",
141 );
142 }
143
144}
diff --git a/crates/ra_editor/src/assists/split_import.rs b/crates/ra_editor/src/assists/split_import.rs
new file mode 100644
index 000000000..75f9e8dfb
--- /dev/null
+++ b/crates/ra_editor/src/assists/split_import.rs
@@ -0,0 +1,44 @@
1use ra_syntax::{
2 TextUnit, AstNode, SyntaxKind::COLONCOLON,
3 ast,
4 algo::generate,
5};
6
7use crate::assists::{AssistCtx, Assist};
8
9pub fn split_import(ctx: AssistCtx) -> Option<Assist> {
10 let colon_colon = ctx
11 .leaf_at_offset()
12 .find(|leaf| leaf.kind() == COLONCOLON)?;
13 let path = colon_colon.parent().and_then(ast::Path::cast)?;
14 let top_path = generate(Some(path), |it| it.parent_path()).last()?;
15
16 let use_tree = top_path.syntax().ancestors().find_map(ast::UseTree::cast);
17 if use_tree.is_none() {
18 return None;
19 }
20
21 let l_curly = colon_colon.range().end();
22 let r_curly = top_path.syntax().range().end();
23
24 ctx.build("split import", |edit| {
25 edit.insert(l_curly, "{");
26 edit.insert(r_curly, "}");
27 edit.set_cursor(l_curly + TextUnit::of_str("{"));
28 })
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::assists::check_assist;
35
36 #[test]
37 fn test_split_import() {
38 check_assist(
39 split_import,
40 "use crate::<|>db::RootDatabase;",
41 "use crate::{<|>db::RootDatabase};",
42 )
43 }
44}
diff --git a/crates/ra_editor/src/code_actions.rs b/crates/ra_editor/src/code_actions.rs
deleted file mode 100644
index 7615f37a6..000000000
--- a/crates/ra_editor/src/code_actions.rs
+++ /dev/null
@@ -1,415 +0,0 @@
1use join_to_string::join;
2
3use ra_syntax::{
4 algo::{find_covering_node, find_leaf_at_offset},
5 ast::{self, AstNode, AttrsOwner, NameOwner, TypeParamsOwner},
6 Direction, SourceFileNode,
7 SyntaxKind::{COMMA, WHITESPACE, COMMENT, VISIBILITY, FN_KW, MOD_KW, STRUCT_KW, ENUM_KW, TRAIT_KW, FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF},
8 SyntaxNodeRef, TextRange, TextUnit,
9};
10
11use crate::{find_node_at_offset, TextEdit, TextEditBuilder};
12
13#[derive(Debug)]
14pub struct LocalEdit {
15 pub label: String,
16 pub edit: TextEdit,
17 pub cursor_position: Option<TextUnit>,
18}
19
20pub fn flip_comma<'a>(
21 file: &'a SourceFileNode,
22 offset: TextUnit,
23) -> Option<impl FnOnce() -> LocalEdit + 'a> {
24 let syntax = file.syntax();
25
26 let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?;
27 let prev = non_trivia_sibling(comma, Direction::Prev)?;
28 let next = non_trivia_sibling(comma, Direction::Next)?;
29 Some(move || {
30 let mut edit = TextEditBuilder::new();
31 edit.replace(prev.range(), next.text().to_string());
32 edit.replace(next.range(), prev.text().to_string());
33 LocalEdit {
34 label: "flip comma".to_string(),
35 edit: edit.finish(),
36 cursor_position: None,
37 }
38 })
39}
40
41pub fn add_derive<'a>(
42 file: &'a SourceFileNode,
43 offset: TextUnit,
44) -> Option<impl FnOnce() -> LocalEdit + 'a> {
45 let nominal = find_node_at_offset::<ast::NominalDef>(file.syntax(), offset)?;
46 let node_start = derive_insertion_offset(nominal)?;
47 return Some(move || {
48 let derive_attr = nominal
49 .attrs()
50 .filter_map(|x| x.as_call())
51 .filter(|(name, _arg)| name == "derive")
52 .map(|(_name, arg)| arg)
53 .next();
54 let mut edit = TextEditBuilder::new();
55 let offset = match derive_attr {
56 None => {
57 edit.insert(node_start, "#[derive()]\n".to_string());
58 node_start + TextUnit::of_str("#[derive(")
59 }
60 Some(tt) => tt.syntax().range().end() - TextUnit::of_char(')'),
61 };
62 LocalEdit {
63 label: "add `#[derive]`".to_string(),
64 edit: edit.finish(),
65 cursor_position: Some(offset),
66 }
67 });
68
69 // Insert `derive` after doc comments.
70 fn derive_insertion_offset(nominal: ast::NominalDef) -> Option<TextUnit> {
71 let non_ws_child = nominal
72 .syntax()
73 .children()
74 .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?;
75 Some(non_ws_child.range().start())
76 }
77}
78
79pub fn add_impl<'a>(
80 file: &'a SourceFileNode,
81 offset: TextUnit,
82) -> Option<impl FnOnce() -> LocalEdit + 'a> {
83 let nominal = find_node_at_offset::<ast::NominalDef>(file.syntax(), offset)?;
84 let name = nominal.name()?;
85
86 Some(move || {
87 let type_params = nominal.type_param_list();
88 let mut edit = TextEditBuilder::new();
89 let start_offset = nominal.syntax().range().end();
90 let mut buf = String::new();
91 buf.push_str("\n\nimpl");
92 if let Some(type_params) = type_params {
93 type_params.syntax().text().push_to(&mut buf);
94 }
95 buf.push_str(" ");
96 buf.push_str(name.text().as_str());
97 if let Some(type_params) = type_params {
98 let lifetime_params = type_params
99 .lifetime_params()
100 .filter_map(|it| it.lifetime())
101 .map(|it| it.text());
102 let type_params = type_params
103 .type_params()
104 .filter_map(|it| it.name())
105 .map(|it| it.text());
106 join(lifetime_params.chain(type_params))
107 .surround_with("<", ">")
108 .to_buf(&mut buf);
109 }
110 buf.push_str(" {\n");
111 let offset = start_offset + TextUnit::of_str(&buf);
112 buf.push_str("\n}");
113 edit.insert(start_offset, buf);
114 LocalEdit {
115 label: "add impl".to_string(),
116 edit: edit.finish(),
117 cursor_position: Some(offset),
118 }
119 })
120}
121
122pub fn introduce_variable<'a>(
123 file: &'a SourceFileNode,
124 range: TextRange,
125) -> Option<impl FnOnce() -> LocalEdit + 'a> {
126 let node = find_covering_node(file.syntax(), range);
127 let expr = node.ancestors().filter_map(ast::Expr::cast).next()?;
128
129 let anchor_stmt = anchor_stmt(expr)?;
130 let indent = anchor_stmt.prev_sibling()?;
131 if indent.kind() != WHITESPACE {
132 return None;
133 }
134 return Some(move || {
135 let mut buf = String::new();
136 let mut edit = TextEditBuilder::new();
137
138 buf.push_str("let var_name = ");
139 expr.syntax().text().push_to(&mut buf);
140 let is_full_stmt = if let Some(expr_stmt) = ast::ExprStmt::cast(anchor_stmt) {
141 Some(expr.syntax()) == expr_stmt.expr().map(|e| e.syntax())
142 } else {
143 false
144 };
145 if is_full_stmt {
146 edit.replace(expr.syntax().range(), buf);
147 } else {
148 buf.push_str(";");
149 indent.text().push_to(&mut buf);
150 edit.replace(expr.syntax().range(), "var_name".to_string());
151 edit.insert(anchor_stmt.range().start(), buf);
152 }
153 let cursor_position = anchor_stmt.range().start() + TextUnit::of_str("let ");
154 LocalEdit {
155 label: "introduce variable".to_string(),
156 edit: edit.finish(),
157 cursor_position: Some(cursor_position),
158 }
159 });
160
161 /// Statement or last in the block expression, which will follow
162 /// the freshly introduced var.
163 fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> {
164 expr.syntax().ancestors().find(|&node| {
165 if ast::Stmt::cast(node).is_some() {
166 return true;
167 }
168 if let Some(expr) = node
169 .parent()
170 .and_then(ast::Block::cast)
171 .and_then(|it| it.expr())
172 {
173 if expr.syntax() == node {
174 return true;
175 }
176 }
177 false
178 })
179 }
180}
181
182pub fn make_pub_crate<'a>(
183 file: &'a SourceFileNode,
184 offset: TextUnit,
185) -> Option<impl FnOnce() -> LocalEdit + 'a> {
186 let syntax = file.syntax();
187
188 let keyword = find_leaf_at_offset(syntax, offset).find(|leaf| match leaf.kind() {
189 FN_KW | MOD_KW | STRUCT_KW | ENUM_KW | TRAIT_KW => true,
190 _ => false,
191 })?;
192 let parent = keyword.parent()?;
193 let def_kws = vec![FN_DEF, MODULE, STRUCT_DEF, ENUM_DEF, TRAIT_DEF];
194 let node_start = parent.range().start();
195 Some(move || {
196 let mut edit = TextEditBuilder::new();
197
198 if !def_kws.iter().any(|&def_kw| def_kw == parent.kind())
199 || parent.children().any(|child| child.kind() == VISIBILITY)
200 {
201 return LocalEdit {
202 label: "make pub crate".to_string(),
203 edit: edit.finish(),
204 cursor_position: Some(offset),
205 };
206 }
207
208 edit.insert(node_start, "pub(crate) ".to_string());
209 LocalEdit {
210 label: "make pub crate".to_string(),
211 edit: edit.finish(),
212 cursor_position: Some(node_start),
213 }
214 })
215}
216
217fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> {
218 node.siblings(direction)
219 .skip(1)
220 .find(|node| !node.kind().is_trivia())
221}
222
223#[cfg(test)]
224mod tests {
225 use super::*;
226 use crate::test_utils::{check_action, check_action_range};
227
228 #[test]
229 fn test_swap_comma() {
230 check_action(
231 "fn foo(x: i32,<|> y: Result<(), ()>) {}",
232 "fn foo(y: Result<(), ()>,<|> x: i32) {}",
233 |file, off| flip_comma(file, off).map(|f| f()),
234 )
235 }
236
237 #[test]
238 fn add_derive_new() {
239 check_action(
240 "struct Foo { a: i32, <|>}",
241 "#[derive(<|>)]\nstruct Foo { a: i32, }",
242 |file, off| add_derive(file, off).map(|f| f()),
243 );
244 check_action(
245 "struct Foo { <|> a: i32, }",
246 "#[derive(<|>)]\nstruct Foo { a: i32, }",
247 |file, off| add_derive(file, off).map(|f| f()),
248 );
249 }
250
251 #[test]
252 fn add_derive_existing() {
253 check_action(
254 "#[derive(Clone)]\nstruct Foo { a: i32<|>, }",
255 "#[derive(Clone<|>)]\nstruct Foo { a: i32, }",
256 |file, off| add_derive(file, off).map(|f| f()),
257 );
258 }
259
260 #[test]
261 fn add_derive_new_with_doc_comment() {
262 check_action(
263 "
264/// `Foo` is a pretty important struct.
265/// It does stuff.
266struct Foo { a: i32<|>, }
267 ",
268 "
269/// `Foo` is a pretty important struct.
270/// It does stuff.
271#[derive(<|>)]
272struct Foo { a: i32, }
273 ",
274 |file, off| add_derive(file, off).map(|f| f()),
275 );
276 }
277
278 #[test]
279 fn test_add_impl() {
280 check_action(
281 "struct Foo {<|>}\n",
282 "struct Foo {}\n\nimpl Foo {\n<|>\n}\n",
283 |file, off| add_impl(file, off).map(|f| f()),
284 );
285 check_action(
286 "struct Foo<T: Clone> {<|>}",
287 "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n<|>\n}",
288 |file, off| add_impl(file, off).map(|f| f()),
289 );
290 check_action(
291 "struct Foo<'a, T: Foo<'a>> {<|>}",
292 "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n<|>\n}",
293 |file, off| add_impl(file, off).map(|f| f()),
294 );
295 }
296
297 #[test]
298 fn test_introduce_var_simple() {
299 check_action_range(
300 "
301fn foo() {
302 foo(<|>1 + 1<|>);
303}",
304 "
305fn foo() {
306 let <|>var_name = 1 + 1;
307 foo(var_name);
308}",
309 |file, range| introduce_variable(file, range).map(|f| f()),
310 );
311 }
312
313 #[test]
314 fn test_introduce_var_expr_stmt() {
315 check_action_range(
316 "
317fn foo() {
318 <|>1 + 1<|>;
319}",
320 "
321fn foo() {
322 let <|>var_name = 1 + 1;
323}",
324 |file, range| introduce_variable(file, range).map(|f| f()),
325 );
326 }
327
328 #[test]
329 fn test_introduce_var_part_of_expr_stmt() {
330 check_action_range(
331 "
332fn foo() {
333 <|>1<|> + 1;
334}",
335 "
336fn foo() {
337 let <|>var_name = 1;
338 var_name + 1;
339}",
340 |file, range| introduce_variable(file, range).map(|f| f()),
341 );
342 }
343
344 #[test]
345 fn test_introduce_var_last_expr() {
346 check_action_range(
347 "
348fn foo() {
349 bar(<|>1 + 1<|>)
350}",
351 "
352fn foo() {
353 let <|>var_name = 1 + 1;
354 bar(var_name)
355}",
356 |file, range| introduce_variable(file, range).map(|f| f()),
357 );
358 }
359
360 #[test]
361 fn test_introduce_var_last_full_expr() {
362 check_action_range(
363 "
364fn foo() {
365 <|>bar(1 + 1)<|>
366}",
367 "
368fn foo() {
369 let <|>var_name = bar(1 + 1);
370 var_name
371}",
372 |file, range| introduce_variable(file, range).map(|f| f()),
373 );
374 }
375
376 #[test]
377 fn test_make_pub_crate() {
378 check_action(
379 "<|>fn foo() {}",
380 "<|>pub(crate) fn foo() {}",
381 |file, off| make_pub_crate(file, off).map(|f| f()),
382 );
383 check_action(
384 "f<|>n foo() {}",
385 "<|>pub(crate) fn foo() {}",
386 |file, off| make_pub_crate(file, off).map(|f| f()),
387 );
388 check_action(
389 "<|>struct Foo {}",
390 "<|>pub(crate) struct Foo {}",
391 |file, off| make_pub_crate(file, off).map(|f| f()),
392 );
393 check_action("<|>mod foo {}", "<|>pub(crate) mod foo {}", |file, off| {
394 make_pub_crate(file, off).map(|f| f())
395 });
396 check_action(
397 "<|>trait Foo {}",
398 "<|>pub(crate) trait Foo {}",
399 |file, off| make_pub_crate(file, off).map(|f| f()),
400 );
401 check_action("m<|>od {}", "<|>pub(crate) mod {}", |file, off| {
402 make_pub_crate(file, off).map(|f| f())
403 });
404 check_action(
405 "pub(crate) f<|>n foo() {}",
406 "pub(crate) f<|>n foo() {}",
407 |file, off| make_pub_crate(file, off).map(|f| f()),
408 );
409 check_action(
410 "unsafe f<|>n foo() {}",
411 "<|>pub(crate) unsafe fn foo() {}",
412 |file, off| make_pub_crate(file, off).map(|f| f()),
413 );
414 }
415}
diff --git a/crates/ra_editor/src/diagnostics.rs b/crates/ra_editor/src/diagnostics.rs
index 1b336cfe2..199b0e502 100644
--- a/crates/ra_editor/src/diagnostics.rs
+++ b/crates/ra_editor/src/diagnostics.rs
@@ -57,7 +57,7 @@ fn check_unnecessary_braces_in_use_statement(
57 text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(single_use_tree) 57 text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(single_use_tree)
58 .unwrap_or_else(|| { 58 .unwrap_or_else(|| {
59 let to_replace = single_use_tree.syntax().text().to_string(); 59 let to_replace = single_use_tree.syntax().text().to_string();
60 let mut edit_builder = TextEditBuilder::new(); 60 let mut edit_builder = TextEditBuilder::default();
61 edit_builder.delete(range); 61 edit_builder.delete(range);
62 edit_builder.insert(range.start(), to_replace); 62 edit_builder.insert(range.start(), to_replace);
63 edit_builder.finish() 63 edit_builder.finish()
@@ -93,7 +93,7 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
93 let start = use_tree_list_node.prev_sibling()?.range().start(); 93 let start = use_tree_list_node.prev_sibling()?.range().start();
94 let end = use_tree_list_node.range().end(); 94 let end = use_tree_list_node.range().end();
95 let range = TextRange::from_to(start, end); 95 let range = TextRange::from_to(start, end);
96 let mut edit_builder = TextEditBuilder::new(); 96 let mut edit_builder = TextEditBuilder::default();
97 edit_builder.delete(range); 97 edit_builder.delete(range);
98 return Some(edit_builder.finish()); 98 return Some(edit_builder.finish());
99 } 99 }
@@ -111,7 +111,7 @@ fn check_struct_shorthand_initialization(
111 let field_name = name_ref.syntax().text().to_string(); 111 let field_name = name_ref.syntax().text().to_string();
112 let field_expr = expr.syntax().text().to_string(); 112 let field_expr = expr.syntax().text().to_string();
113 if field_name == field_expr { 113 if field_name == field_expr {
114 let mut edit_builder = TextEditBuilder::new(); 114 let mut edit_builder = TextEditBuilder::default();
115 edit_builder.delete(named_field.syntax().range()); 115 edit_builder.delete(named_field.syntax().range());
116 edit_builder.insert(named_field.syntax().range().start(), field_name); 116 edit_builder.insert(named_field.syntax().range().start(), field_name);
117 let edit = edit_builder.finish(); 117 let edit = edit_builder.finish();
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs
index bfc745e58..ac283e2e0 100644
--- a/crates/ra_editor/src/lib.rs
+++ b/crates/ra_editor/src/lib.rs
@@ -1,4 +1,4 @@
1mod code_actions; 1pub mod assists;
2mod extend_selection; 2mod extend_selection;
3mod folding_ranges; 3mod folding_ranges;
4mod line_index; 4mod line_index;
@@ -10,7 +10,7 @@ mod typing;
10mod diagnostics; 10mod diagnostics;
11 11
12pub use self::{ 12pub use self::{
13 code_actions::{add_derive, add_impl, flip_comma, introduce_variable, make_pub_crate, LocalEdit}, 13 assists::LocalEdit,
14 extend_selection::extend_selection, 14 extend_selection::extend_selection,
15 folding_ranges::{folding_ranges, Fold, FoldKind}, 15 folding_ranges::{folding_ranges, Fold, FoldKind},
16 line_index::{LineCol, LineIndex}, 16 line_index::{LineCol, LineIndex},
@@ -19,7 +19,7 @@ pub use self::{
19 typing::{join_lines, on_enter, on_eq_typed}, 19 typing::{join_lines, on_enter, on_eq_typed},
20 diagnostics::diagnostics 20 diagnostics::diagnostics
21}; 21};
22use ra_text_edit::{TextEdit, TextEditBuilder}; 22use ra_text_edit::TextEditBuilder;
23use ra_syntax::{ 23use ra_syntax::{
24 algo::find_leaf_at_offset, 24 algo::find_leaf_at_offset,
25 ast::{self, AstNode}, 25 ast::{self, AstNode},
diff --git a/crates/ra_editor/src/structure.rs b/crates/ra_editor/src/structure.rs
index 2292b1ddf..32d59e335 100644
--- a/crates/ra_editor/src/structure.rs
+++ b/crates/ra_editor/src/structure.rs
@@ -60,7 +60,7 @@ fn structure_node(node: SyntaxNodeRef) -> Option<StructureNode> {
60 .visit(decl::<ast::TypeDef>) 60 .visit(decl::<ast::TypeDef>)
61 .visit(decl::<ast::ConstDef>) 61 .visit(decl::<ast::ConstDef>)
62 .visit(decl::<ast::StaticDef>) 62 .visit(decl::<ast::StaticDef>)
63 .visit(|im: ast::ImplItem| { 63 .visit(|im: ast::ImplBlock| {
64 let target_type = im.target_type()?; 64 let target_type = im.target_type()?;
65 let target_trait = im.target_trait(); 65 let target_trait = im.target_trait();
66 let label = match target_trait { 66 let label = match target_trait {
@@ -121,8 +121,8 @@ impl fmt::Debug for E {}
121 StructureNode { parent: None, label: "T", navigation_range: [81; 82), node_range: [76; 88), kind: TYPE_DEF }, 121 StructureNode { parent: None, label: "T", navigation_range: [81; 82), node_range: [76; 88), kind: TYPE_DEF },
122 StructureNode { parent: None, label: "S", navigation_range: [96; 97), node_range: [89; 108), kind: STATIC_DEF }, 122 StructureNode { parent: None, label: "S", navigation_range: [96; 97), node_range: [89; 108), kind: STATIC_DEF },
123 StructureNode { parent: None, label: "C", navigation_range: [115; 116), node_range: [109; 127), kind: CONST_DEF }, 123 StructureNode { parent: None, label: "C", navigation_range: [115; 116), node_range: [109; 127), kind: CONST_DEF },
124 StructureNode { parent: None, label: "impl E", navigation_range: [134; 135), node_range: [129; 138), kind: IMPL_ITEM }, 124 StructureNode { parent: None, label: "impl E", navigation_range: [134; 135), node_range: [129; 138), kind: IMPL_BLOCK },
125 StructureNode { parent: None, label: "impl fmt::Debug for E", navigation_range: [160; 161), node_range: [140; 164), kind: IMPL_ITEM }]"#, 125 StructureNode { parent: None, label: "impl fmt::Debug for E", navigation_range: [160; 161), node_range: [140; 164), kind: IMPL_BLOCK }]"#,
126 &structure, 126 &structure,
127 ) 127 )
128 } 128 }
diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs
index 21d068a7b..1b568e96c 100644
--- a/crates/ra_editor/src/typing.rs
+++ b/crates/ra_editor/src/typing.rs
@@ -21,7 +21,7 @@ pub fn join_lines(file: &SourceFileNode, range: TextRange) -> LocalEdit {
21 None => { 21 None => {
22 return LocalEdit { 22 return LocalEdit {
23 label: "join lines".to_string(), 23 label: "join lines".to_string(),
24 edit: TextEditBuilder::new().finish(), 24 edit: TextEditBuilder::default().finish(),
25 cursor_position: None, 25 cursor_position: None,
26 }; 26 };
27 } 27 }
@@ -33,7 +33,7 @@ pub fn join_lines(file: &SourceFileNode, range: TextRange) -> LocalEdit {
33 }; 33 };
34 34
35 let node = find_covering_node(file.syntax(), range); 35 let node = find_covering_node(file.syntax(), range);
36 let mut edit = TextEditBuilder::new(); 36 let mut edit = TextEditBuilder::default();
37 for node in node.descendants() { 37 for node in node.descendants() {
38 let text = match node.leaf_text() { 38 let text = match node.leaf_text() {
39 Some(text) => text, 39 Some(text) => text,
@@ -76,7 +76,7 @@ pub fn on_enter(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit> {
76 let indent = node_indent(file, comment.syntax())?; 76 let indent = node_indent(file, comment.syntax())?;
77 let inserted = format!("\n{}{} ", indent, prefix); 77 let inserted = format!("\n{}{} ", indent, prefix);
78 let cursor_position = offset + TextUnit::of_str(&inserted); 78 let cursor_position = offset + TextUnit::of_str(&inserted);
79 let mut edit = TextEditBuilder::new(); 79 let mut edit = TextEditBuilder::default();
80 edit.insert(offset, inserted); 80 edit.insert(offset, inserted);
81 Some(LocalEdit { 81 Some(LocalEdit {
82 label: "on enter".to_string(), 82 label: "on enter".to_string(),
@@ -127,7 +127,7 @@ pub fn on_eq_typed(file: &SourceFileNode, offset: TextUnit) -> Option<LocalEdit>
127 return None; 127 return None;
128 } 128 }
129 let offset = let_stmt.syntax().range().end(); 129 let offset = let_stmt.syntax().range().end();
130 let mut edit = TextEditBuilder::new(); 130 let mut edit = TextEditBuilder::default();
131 edit.insert(offset, ";".to_string()); 131 edit.insert(offset, ";".to_string());
132 Some(LocalEdit { 132 Some(LocalEdit {
133 label: "add semicolon".to_string(), 133 label: "add semicolon".to_string(),
@@ -188,10 +188,14 @@ fn remove_newline(
188 edit.delete(TextRange::from_to(prev.range().start(), node.range().end())); 188 edit.delete(TextRange::from_to(prev.range().start(), node.range().end()));
189 } else if prev.kind() == COMMA && next.kind() == R_CURLY { 189 } else if prev.kind() == COMMA && next.kind() == R_CURLY {
190 // Removes: comma, newline (incl. surrounding whitespace) 190 // Removes: comma, newline (incl. surrounding whitespace)
191 // Adds: a single whitespace 191 let space = if let Some(left) = prev.prev_sibling() {
192 compute_ws(left, next)
193 } else {
194 " "
195 };
192 edit.replace( 196 edit.replace(
193 TextRange::from_to(prev.range().start(), node.range().end()), 197 TextRange::from_to(prev.range().start(), node.range().end()),
194 " ".to_string(), 198 space.to_string(),
195 ); 199 );
196 } else if let (Some(_), Some(next)) = (ast::Comment::cast(prev), ast::Comment::cast(next)) { 200 } else if let (Some(_), Some(next)) = (ast::Comment::cast(prev), ast::Comment::cast(next)) {
197 // Removes: newline (incl. surrounding whitespace), start of the next comment 201 // Removes: newline (incl. surrounding whitespace), start of the next comment
@@ -256,10 +260,20 @@ fn join_single_use_tree(edit: &mut TextEditBuilder, node: SyntaxNodeRef) -> Opti
256fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str { 260fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str {
257 match left.kind() { 261 match left.kind() {
258 L_PAREN | L_BRACK => return "", 262 L_PAREN | L_BRACK => return "",
263 L_CURLY => {
264 if let USE_TREE = right.kind() {
265 return "";
266 }
267 }
259 _ => (), 268 _ => (),
260 } 269 }
261 match right.kind() { 270 match right.kind() {
262 R_PAREN | R_BRACK => return "", 271 R_PAREN | R_BRACK => return "",
272 R_CURLY => {
273 if let USE_TREE = left.kind() {
274 return "";
275 }
276 }
263 DOT => return "", 277 DOT => return "",
264 _ => (), 278 _ => (),
265 } 279 }
@@ -331,6 +345,48 @@ fn foo() {
331 } 345 }
332 346
333 #[test] 347 #[test]
348 fn test_join_lines_use_items_left() {
349 // No space after the '{'
350 check_join_lines(
351 r"
352<|>use ra_syntax::{
353 TextUnit, TextRange,
354};",
355 r"
356<|>use ra_syntax::{TextUnit, TextRange,
357};",
358 );
359 }
360
361 #[test]
362 fn test_join_lines_use_items_right() {
363 // No space after the '}'
364 check_join_lines(
365 r"
366use ra_syntax::{
367<|> TextUnit, TextRange
368};",
369 r"
370use ra_syntax::{
371<|> TextUnit, TextRange};",
372 );
373 }
374
375 #[test]
376 fn test_join_lines_use_items_right_comma() {
377 // No space after the '}'
378 check_join_lines(
379 r"
380use ra_syntax::{
381<|> TextUnit, TextRange,
382};",
383 r"
384use ra_syntax::{
385<|> TextUnit, TextRange};",
386 );
387 }
388
389 #[test]
334 fn test_join_lines_use_tree() { 390 fn test_join_lines_use_tree() {
335 check_join_lines( 391 check_join_lines(
336 r" 392 r"
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index c3fbd327d..245a21ce3 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -8,12 +8,12 @@ authors = ["Aleksey Kladov <[email protected]>"]
8arrayvec = "0.4.10" 8arrayvec = "0.4.10"
9log = "0.4.5" 9log = "0.4.5"
10relative-path = "0.4.0" 10relative-path = "0.4.0"
11salsa = "0.9.0" 11salsa = "0.9.1"
12rustc-hash = "1.0" 12rustc-hash = "1.0"
13parking_lot = "0.7.0" 13parking_lot = "0.7.0"
14id-arena = "2.0"
15ena = "0.11" 14ena = "0.11"
16ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
16ra_arena = { path = "../ra_arena" }
17ra_editor = { path = "../ra_editor" } 17ra_editor = { path = "../ra_editor" }
18ra_db = { path = "../ra_db" } 18ra_db = { path = "../ra_db" }
19test_utils = { path = "../test_utils" } 19test_utils = { path = "../test_utils" }
diff --git a/crates/ra_hir/src/arena.rs b/crates/ra_hir/src/arena.rs
deleted file mode 100644
index d4f9d9cb9..000000000
--- a/crates/ra_hir/src/arena.rs
+++ /dev/null
@@ -1,66 +0,0 @@
1//! A simple id-based arena, similar to https://github.com/fitzgen/id-arena.
2//! We use our own version for more compact id's and to allow inherent impls
3//! on Ids.
4
5use std::{
6 fmt,
7 hash::{Hash, Hasher},
8 marker::PhantomData,
9};
10
11pub struct Id<T> {
12 idx: u32,
13 _ty: PhantomData<fn() -> T>,
14}
15
16impl<T> fmt::Debug for Id<T> {
17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18 f.debug_tuple("Id").field(&self.idx).finish()
19 }
20}
21impl<T> Copy for Id<T> {}
22impl<T> Clone for Id<T> {
23 fn clone(&self) -> Id<T> {
24 *self
25 }
26}
27
28impl<T> PartialEq for Id<T> {
29 fn eq(&self, other: &Id<T>) -> bool {
30 self.idx == other.idx
31 }
32}
33
34impl<T> Eq for Id<T> {}
35
36impl<T> Hash for Id<T> {
37 fn hash<H: Hasher>(&self, h: &mut H) {
38 self.idx.hash(h);
39 }
40}
41
42#[derive(Debug, PartialEq, Eq)]
43pub(crate) struct ArenaBehavior<T> {
44 _ty: PhantomData<T>,
45}
46
47impl<T> id_arena::ArenaBehavior for ArenaBehavior<T> {
48 type Id = Id<T>;
49 fn new_arena_id() -> u32 {
50 0
51 }
52 fn new_id(_arena_id: u32, index: usize) -> Id<T> {
53 Id {
54 idx: index as u32,
55 _ty: PhantomData,
56 }
57 }
58 fn index(id: Id<T>) -> usize {
59 id.idx as usize
60 }
61 fn arena_id(_id: Id<T>) -> u32 {
62 0
63 }
64}
65
66pub(crate) type Arena<T> = id_arena::Arena<T, ArenaBehavior<T>>;
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 73a4cdc5c..58296fc6f 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -13,6 +13,7 @@ use crate::{
13 nameres::{ItemMap, InputModuleItems}}, 13 nameres::{ItemMap, InputModuleItems}},
14 ty::{InferenceResult, Ty}, 14 ty::{InferenceResult, Ty},
15 adt::{StructData, EnumData}, 15 adt::{StructData, EnumData},
16 impl_block::ModuleImplBlocks,
16}; 17};
17 18
18salsa::query_group! { 19salsa::query_group! {
@@ -87,6 +88,11 @@ pub trait HirDatabase: SyntaxDatabase
87 type ModuleTreeQuery; 88 type ModuleTreeQuery;
88 use fn crate::module::imp::module_tree; 89 use fn crate::module::imp::module_tree;
89 } 90 }
91
92 fn impls_in_module(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<ModuleImplBlocks>> {
93 type ImplsInModuleQuery;
94 use fn crate::impl_block::impls_in_module;
95 }
90} 96}
91 97
92} 98}
diff --git a/crates/ra_hir/src/function.rs b/crates/ra_hir/src/function.rs
index 5a44132fc..75ef308ae 100644
--- a/crates/ra_hir/src/function.rs
+++ b/crates/ra_hir/src/function.rs
@@ -11,11 +11,11 @@ use ra_syntax::{
11 ast::{self, AstNode, DocCommentsOwner, NameOwner}, 11 ast::{self, AstNode, DocCommentsOwner, NameOwner},
12}; 12};
13 13
14use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module}; 14use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock};
15 15
16pub use self::scope::FnScopes; 16pub use self::scope::FnScopes;
17 17
18#[derive(Debug)] 18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct Function { 19pub struct Function {
20 def_id: DefId, 20 def_id: DefId,
21} 21}
@@ -25,6 +25,10 @@ impl Function {
25 Function { def_id } 25 Function { def_id }
26 } 26 }
27 27
28 pub fn def_id(&self) -> DefId {
29 self.def_id
30 }
31
28 pub fn syntax(&self, db: &impl HirDatabase) -> ast::FnDefNode { 32 pub fn syntax(&self, db: &impl HirDatabase) -> ast::FnDefNode {
29 let def_loc = self.def_id.loc(db); 33 let def_loc = self.def_id.loc(db);
30 assert!(def_loc.kind == DefKind::Function); 34 assert!(def_loc.kind == DefKind::Function);
@@ -48,6 +52,15 @@ impl Function {
48 pub fn module(&self, db: &impl HirDatabase) -> Cancelable<Module> { 52 pub fn module(&self, db: &impl HirDatabase) -> Cancelable<Module> {
49 self.def_id.module(db) 53 self.def_id.module(db)
50 } 54 }
55
56 pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> {
57 self.def_id.krate(db)
58 }
59
60 /// The containing impl block, if this is a method.
61 pub fn impl_block(&self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> {
62 self.def_id.impl_block(db)
63 }
51} 64}
52 65
53#[derive(Debug, Clone)] 66#[derive(Debug, Clone)]
diff --git a/crates/ra_hir/src/function/scope.rs b/crates/ra_hir/src/function/scope.rs
index 3e4cfad0c..42bfe4f32 100644
--- a/crates/ra_hir/src/function/scope.rs
+++ b/crates/ra_hir/src/function/scope.rs
@@ -5,19 +5,19 @@ use ra_syntax::{
5 algo::generate, 5 algo::generate,
6 ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, 6 ast::{self, ArgListOwner, LoopBodyOwner, NameOwner},
7}; 7};
8use ra_arena::{Arena, RawId, impl_arena_id};
8use ra_db::LocalSyntaxPtr; 9use ra_db::LocalSyntaxPtr;
9 10
10use crate::{ 11use crate::{Name, AsName};
11 arena::{Arena, Id},
12 Name, AsName,
13};
14 12
15pub(crate) type ScopeId = Id<ScopeData>; 13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct ScopeId(RawId);
15impl_arena_id!(ScopeId);
16 16
17#[derive(Debug, PartialEq, Eq)] 17#[derive(Debug, PartialEq, Eq)]
18pub struct FnScopes { 18pub struct FnScopes {
19 pub self_param: Option<LocalSyntaxPtr>, 19 pub self_param: Option<LocalSyntaxPtr>,
20 scopes: Arena<ScopeData>, 20 scopes: Arena<ScopeId, ScopeData>,
21 scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>, 21 scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>,
22} 22}
23 23
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index a09dee8b1..4d6378e02 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -1,10 +1,8 @@
1use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId}; 1use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId};
2use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast}; 2use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast};
3use ra_arena::{Arena, RawId, impl_arena_id};
3 4
4use crate::{ 5use crate::{HirDatabase, PerNs, ModuleId, Module, Def, Function, Struct, Enum, ImplBlock, Crate};
5 HirDatabase, PerNs, ModuleId, Module, Def, Function, Struct, Enum,
6 arena::{Arena, Id},
7};
8 6
9/// hir makes a heavy use of ids: integer (u32) handlers to various things. You 7/// hir makes a heavy use of ids: integer (u32) handlers to various things. You
10/// can think of id as a pointer (but without a lifetime) or a file descriptor 8/// can think of id as a pointer (but without a lifetime) or a file descriptor
@@ -48,6 +46,13 @@ impl HirFileId {
48 } 46 }
49 } 47 }
50 48
49 pub(crate) fn as_macro_call_id(self) -> Option<MacroCallId> {
50 match self.0 {
51 HirFileIdRepr::Macro(it) => Some(it),
52 _ => None,
53 }
54 }
55
51 pub(crate) fn hir_source_file(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode { 56 pub(crate) fn hir_source_file(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode {
52 match file_id.0 { 57 match file_id.0 {
53 HirFileIdRepr::File(file_id) => db.source_file(file_id), 58 HirFileIdRepr::File(file_id) => db.source_file(file_id),
@@ -172,6 +177,18 @@ impl DefId {
172 let loc = self.loc(db); 177 let loc = self.loc(db);
173 Module::new(db, loc.source_root_id, loc.module_id) 178 Module::new(db, loc.source_root_id, loc.module_id)
174 } 179 }
180
181 /// Returns the containing crate.
182 pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> {
183 Ok(self.module(db)?.krate(db))
184 }
185
186 /// Returns the containing impl block, if this is an impl item.
187 pub fn impl_block(self, db: &impl HirDatabase) -> Cancelable<Option<ImplBlock>> {
188 let loc = self.loc(db);
189 let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id)?;
190 Ok(ImplBlock::containing(module_impls, self))
191 }
175} 192}
176 193
177impl DefLoc { 194impl DefLoc {
@@ -199,7 +216,9 @@ impl DefKind {
199 216
200/// Identifier of item within a specific file. This is stable over reparses, so 217/// Identifier of item within a specific file. This is stable over reparses, so
201/// it's OK to use it as a salsa key/value. 218/// it's OK to use it as a salsa key/value.
202pub(crate) type SourceFileItemId = Id<SyntaxNode>; 219#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
220pub struct SourceFileItemId(RawId);
221impl_arena_id!(SourceFileItemId);
203 222
204#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 223#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
205pub struct SourceItemId { 224pub struct SourceItemId {
@@ -212,7 +231,7 @@ pub struct SourceItemId {
212#[derive(Debug, PartialEq, Eq)] 231#[derive(Debug, PartialEq, Eq)]
213pub struct SourceFileItems { 232pub struct SourceFileItems {
214 file_id: HirFileId, 233 file_id: HirFileId,
215 arena: Arena<SyntaxNode>, 234 arena: Arena<SourceFileItemId, SyntaxNode>,
216} 235}
217 236
218impl SourceFileItems { 237impl SourceFileItems {
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
new file mode 100644
index 000000000..01afa84c4
--- /dev/null
+++ b/crates/ra_hir/src/impl_block.rs
@@ -0,0 +1,180 @@
1use std::sync::Arc;
2use rustc_hash::FxHashMap;
3
4use ra_arena::{Arena, RawId, impl_arena_id};
5use ra_syntax::ast::{self, AstNode};
6use ra_db::{LocationIntener, Cancelable, SourceRootId};
7
8use crate::{
9 DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
10 Module, Function,
11 db::HirDatabase,
12 type_ref::TypeRef,
13 module::{ModuleSourceNode, ModuleId},
14};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct ImplBlock {
18 module_impl_blocks: Arc<ModuleImplBlocks>,
19 impl_id: ImplId,
20}
21
22impl ImplBlock {
23 pub(crate) fn containing(
24 module_impl_blocks: Arc<ModuleImplBlocks>,
25 def_id: DefId,
26 ) -> Option<ImplBlock> {
27 let impl_id = *module_impl_blocks.impls_by_def.get(&def_id)?;
28 Some(ImplBlock {
29 module_impl_blocks,
30 impl_id,
31 })
32 }
33
34 fn impl_data(&self) -> &ImplData {
35 &self.module_impl_blocks.impls[self.impl_id]
36 }
37
38 pub fn target_trait(&self) -> Option<&TypeRef> {
39 self.impl_data().target_trait.as_ref()
40 }
41
42 pub fn target_type(&self) -> &TypeRef {
43 &self.impl_data().target_type
44 }
45
46 pub fn items(&self) -> &[ImplItem] {
47 &self.impl_data().items
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct ImplData {
53 target_trait: Option<TypeRef>,
54 target_type: TypeRef,
55 items: Vec<ImplItem>,
56}
57
58impl ImplData {
59 pub(crate) fn from_ast(
60 db: &impl AsRef<LocationIntener<DefLoc, DefId>>,
61 file_items: &SourceFileItems,
62 module: &Module,
63 node: ast::ImplBlock,
64 ) -> Self {
65 let target_trait = node.target_type().map(TypeRef::from_ast);
66 let target_type = TypeRef::from_ast_opt(node.target_type());
67 let file_id = module.source().file_id();
68 let items = if let Some(item_list) = node.item_list() {
69 item_list
70 .impl_items()
71 .map(|item_node| {
72 let kind = match item_node {
73 ast::ImplItem::FnDef(..) => DefKind::Function,
74 ast::ImplItem::ConstDef(..) => DefKind::Item,
75 ast::ImplItem::TypeDef(..) => DefKind::Item,
76 };
77 let item_id = file_items.id_of_unchecked(item_node.syntax());
78 let def_loc = DefLoc {
79 kind,
80 source_root_id: module.source_root_id,
81 module_id: module.module_id,
82 source_item_id: SourceItemId {
83 file_id,
84 item_id: Some(item_id),
85 },
86 };
87 let def_id = def_loc.id(db);
88 match item_node {
89 ast::ImplItem::FnDef(..) => ImplItem::Method(Function::new(def_id)),
90 ast::ImplItem::ConstDef(..) => ImplItem::Const(def_id),
91 ast::ImplItem::TypeDef(..) => ImplItem::Type(def_id),
92 }
93 })
94 .collect()
95 } else {
96 Vec::new()
97 };
98 ImplData {
99 target_trait,
100 target_type,
101 items,
102 }
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub enum ImplItem {
108 Method(Function),
109 // these don't have their own types yet
110 Const(DefId),
111 Type(DefId),
112 // Existential
113}
114
115impl ImplItem {
116 pub fn def_id(&self) -> DefId {
117 match self {
118 ImplItem::Method(f) => f.def_id(),
119 ImplItem::Const(def_id) => *def_id,
120 ImplItem::Type(def_id) => *def_id,
121 }
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
126pub struct ImplId(pub RawId);
127impl_arena_id!(ImplId);
128
129/// Collection of impl blocks is a two-step process: First we collect the blocks
130/// per-module; then we build an index of all impl blocks in the crate. This
131/// way, we avoid having to do this process for the whole crate whenever someone
132/// types in any file; as long as the impl blocks in the file don't change, we
133/// don't need to do the second step again.
134///
135/// (The second step does not yet exist currently.)
136#[derive(Debug, PartialEq, Eq)]
137pub struct ModuleImplBlocks {
138 impls: Arena<ImplId, ImplData>,
139 impls_by_def: FxHashMap<DefId, ImplId>,
140}
141
142impl ModuleImplBlocks {
143 fn new() -> Self {
144 ModuleImplBlocks {
145 impls: Arena::default(),
146 impls_by_def: FxHashMap::default(),
147 }
148 }
149
150 fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> {
151 let module_source_node = module.source().resolve(db);
152 let node = match &module_source_node {
153 ModuleSourceNode::SourceFile(node) => node.borrowed().syntax(),
154 ModuleSourceNode::Module(node) => node.borrowed().syntax(),
155 };
156
157 let source_file_items = db.file_items(module.source().file_id());
158
159 for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) {
160 let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast);
161 let id = self.impls.alloc(impl_block);
162 for impl_item in &self.impls[id].items {
163 self.impls_by_def.insert(impl_item.def_id(), id);
164 }
165 }
166
167 Ok(())
168 }
169}
170
171pub(crate) fn impls_in_module(
172 db: &impl HirDatabase,
173 source_root_id: SourceRootId,
174 module_id: ModuleId,
175) -> Cancelable<Arc<ModuleImplBlocks>> {
176 let mut result = ModuleImplBlocks::new();
177 let module = Module::new(db, source_root_id, module_id)?;
178 result.collect(db, module)?;
179 Ok(Arc::new(result))
180}
diff --git a/crates/ra_hir/src/krate.rs b/crates/ra_hir/src/krate.rs
index a0821d15d..5194e280b 100644
--- a/crates/ra_hir/src/krate.rs
+++ b/crates/ra_hir/src/krate.rs
@@ -5,7 +5,7 @@ use crate::{HirDatabase, Module, Name, AsName, HirFileId};
5/// hir::Crate describes a single crate. It's the main inteface with which 5/// hir::Crate describes a single crate. It's the main inteface with which
6/// crate's dependencies interact. Mostly, it should be just a proxy for the 6/// crate's dependencies interact. Mostly, it should be just a proxy for the
7/// root module. 7/// root module.
8#[derive(Debug)] 8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct Crate { 9pub struct Crate {
10 crate_id: CrateId, 10 crate_id: CrateId,
11} 11}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 8ee52a466..2abcec441 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -19,7 +19,6 @@ pub mod db;
19mod mock; 19mod mock;
20mod query_definitions; 20mod query_definitions;
21mod path; 21mod path;
22mod arena;
23pub mod source_binder; 22pub mod source_binder;
24 23
25mod ids; 24mod ids;
@@ -32,6 +31,7 @@ mod function;
32mod adt; 31mod adt;
33mod type_ref; 32mod type_ref;
34mod ty; 33mod ty;
34mod impl_block;
35 35
36use crate::{ 36use crate::{
37 db::HirDatabase, 37 db::HirDatabase,
@@ -49,6 +49,7 @@ pub use self::{
49 function::{Function, FnScopes}, 49 function::{Function, FnScopes},
50 adt::{Struct, Enum}, 50 adt::{Struct, Enum},
51 ty::Ty, 51 ty::Ty,
52 impl_block::{ImplBlock, ImplItem},
52}; 53};
53 54
54pub use self::function::FnSignatureInfo; 55pub use self::function::FnSignatureInfo;
diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs
index b7b75e702..1b378c977 100644
--- a/crates/ra_hir/src/macros.rs
+++ b/crates/ra_hir/src/macros.rs
@@ -21,6 +21,7 @@ use crate::{HirDatabase, MacroCallId};
21#[derive(Debug, Clone, PartialEq, Eq, Hash)] 21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub enum MacroDef { 22pub enum MacroDef {
23 CTry, 23 CTry,
24 Vec,
24 QueryGroup, 25 QueryGroup,
25} 26}
26 27
@@ -40,6 +41,8 @@ impl MacroDef {
40 let name_ref = path.segment()?.name_ref()?; 41 let name_ref = path.segment()?.name_ref()?;
41 if name_ref.text() == "ctry" { 42 if name_ref.text() == "ctry" {
42 MacroDef::CTry 43 MacroDef::CTry
44 } else if name_ref.text() == "vec" {
45 MacroDef::Vec
43 } else if name_ref.text() == "query_group" { 46 } else if name_ref.text() == "query_group" {
44 MacroDef::QueryGroup 47 MacroDef::QueryGroup
45 } else { 48 } else {
@@ -59,6 +62,7 @@ impl MacroDef {
59 fn expand(self, input: MacroInput) -> Option<MacroExpansion> { 62 fn expand(self, input: MacroInput) -> Option<MacroExpansion> {
60 match self { 63 match self {
61 MacroDef::CTry => self.expand_ctry(input), 64 MacroDef::CTry => self.expand_ctry(input),
65 MacroDef::Vec => self.expand_vec(input),
62 MacroDef::QueryGroup => self.expand_query_group(input), 66 MacroDef::QueryGroup => self.expand_query_group(input),
63 } 67 }
64 } 68 }
@@ -86,6 +90,20 @@ impl MacroDef {
86 }; 90 };
87 Some(res) 91 Some(res)
88 } 92 }
93 fn expand_vec(self, input: MacroInput) -> Option<MacroExpansion> {
94 let text = format!(r"fn dummy() {{ {}; }}", input.text);
95 let file = SourceFileNode::parse(&text);
96 let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?;
97 let ptr = LocalSyntaxPtr::new(array_expr.syntax());
98 let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text));
99 let ranges_map = vec![(src_range, array_expr.syntax().range())];
100 let res = MacroExpansion {
101 text,
102 ranges_map,
103 ptr,
104 };
105 Some(res)
106 }
89 fn expand_query_group(self, input: MacroInput) -> Option<MacroExpansion> { 107 fn expand_query_group(self, input: MacroInput) -> Option<MacroExpansion> {
90 let anchor = "trait "; 108 let anchor = "trait ";
91 let pos = input.text.find(anchor)? + anchor.len(); 109 let pos = input.text.find(anchor)? + anchor.len();
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 89b18194a..a9db932ff 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -30,6 +30,10 @@ impl MockDatabase {
30 let file_id = db.add_file(&mut source_root, "/main.rs", text); 30 let file_id = db.add_file(&mut source_root, "/main.rs", text);
31 db.query_mut(ra_db::SourceRootQuery) 31 db.query_mut(ra_db::SourceRootQuery)
32 .set(WORKSPACE, Arc::new(source_root.clone())); 32 .set(WORKSPACE, Arc::new(source_root.clone()));
33
34 let mut crate_graph = CrateGraph::default();
35 crate_graph.add_crate_root(file_id);
36 db.set_crate_graph(crate_graph);
33 (db, source_root, file_id) 37 (db, source_root, file_id)
34 } 38 }
35 39
@@ -203,6 +207,7 @@ salsa::database_storage! {
203 fn type_for_field() for db::TypeForFieldQuery; 207 fn type_for_field() for db::TypeForFieldQuery;
204 fn struct_data() for db::StructDataQuery; 208 fn struct_data() for db::StructDataQuery;
205 fn enum_data() for db::EnumDataQuery; 209 fn enum_data() for db::EnumDataQuery;
210 fn impls_in_module() for db::ImplsInModuleQuery;
206 } 211 }
207 } 212 }
208} 213}
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs
index a53b69d20..b9821115c 100644
--- a/crates/ra_hir/src/module.rs
+++ b/crates/ra_hir/src/module.rs
@@ -9,6 +9,7 @@ use ra_syntax::{
9 ast::{self, AstNode, NameOwner}, 9 ast::{self, AstNode, NameOwner},
10 SyntaxNode, 10 SyntaxNode,
11}; 11};
12use ra_arena::{Arena, RawId, impl_arena_id};
12use ra_db::{SourceRootId, FileId, Cancelable}; 13use ra_db::{SourceRootId, FileId, Cancelable};
13use relative_path::RelativePathBuf; 14use relative_path::RelativePathBuf;
14 15
@@ -16,7 +17,6 @@ use crate::{
16 Def, DefKind, DefLoc, DefId, 17 Def, DefKind, DefLoc, DefId,
17 Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, 18 Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate,
18 HirFileId, 19 HirFileId,
19 arena::{Arena, Id},
20}; 20};
21 21
22pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; 22pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs};
@@ -71,6 +71,21 @@ impl Module {
71 }) 71 })
72 } 72 }
73 73
74 /// Returns an iterator of all children of this module.
75 pub fn children<'a>(&'a self) -> impl Iterator<Item = (Name, Module)> + 'a {
76 self.module_id
77 .children(&self.tree)
78 .map(move |(name, module_id)| {
79 (
80 name,
81 Module {
82 module_id,
83 ..self.clone()
84 },
85 )
86 })
87 }
88
74 /// Returns the crate this module is part of. 89 /// Returns the crate this module is part of.
75 pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { 90 pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
76 let root_id = self.module_id.crate_root(&self.tree); 91 let root_id = self.module_id.crate_root(&self.tree);
@@ -173,6 +188,14 @@ impl Module {
173 } 188 }
174} 189}
175 190
191#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
192pub struct ModuleId(RawId);
193impl_arena_id!(ModuleId);
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
196pub struct LinkId(RawId);
197impl_arena_id!(LinkId);
198
176/// Physically, rust source is organized as a set of files, but logically it is 199/// Physically, rust source is organized as a set of files, but logically it is
177/// organized as a tree of modules. Usually, a single file corresponds to a 200/// organized as a tree of modules. Usually, a single file corresponds to a
178/// single module, but it is not nessary the case. 201/// single module, but it is not nessary the case.
@@ -182,8 +205,8 @@ impl Module {
182/// always have one parent). 205/// always have one parent).
183#[derive(Default, Debug, PartialEq, Eq)] 206#[derive(Default, Debug, PartialEq, Eq)]
184pub struct ModuleTree { 207pub struct ModuleTree {
185 mods: Arena<ModuleData>, 208 mods: Arena<ModuleId, ModuleData>,
186 links: Arena<LinkData>, 209 links: Arena<LinkId, LinkData>,
187} 210}
188 211
189impl ModuleTree { 212impl ModuleTree {
@@ -210,9 +233,6 @@ pub(crate) enum ModuleSourceNode {
210 Module(ast::ModuleNode), 233 Module(ast::ModuleNode),
211} 234}
212 235
213pub type ModuleId = Id<ModuleData>;
214type LinkId = Id<LinkData>;
215
216#[derive(Clone, Debug, Hash, PartialEq, Eq)] 236#[derive(Clone, Debug, Hash, PartialEq, Eq)]
217pub enum Problem { 237pub enum Problem {
218 UnresolvedModule { 238 UnresolvedModule {
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs
index 40aa33ffa..3c6851a0a 100644
--- a/crates/ra_hir/src/module/nameres.rs
+++ b/crates/ra_hir/src/module/nameres.rs
@@ -64,14 +64,14 @@ impl ModuleScope {
64/// running name resolution. 64/// running name resolution.
65#[derive(Debug, Default, PartialEq, Eq)] 65#[derive(Debug, Default, PartialEq, Eq)]
66pub struct InputModuleItems { 66pub struct InputModuleItems {
67 items: Vec<ModuleItem>, 67 pub(crate) items: Vec<ModuleItem>,
68 imports: Vec<Import>, 68 imports: Vec<Import>,
69} 69}
70 70
71#[derive(Debug, PartialEq, Eq)] 71#[derive(Debug, PartialEq, Eq)]
72struct ModuleItem { 72pub(crate) struct ModuleItem {
73 id: SourceItemId, 73 pub(crate) id: SourceItemId,
74 name: Name, 74 pub(crate) name: Name,
75 kind: SyntaxKind, 75 kind: SyntaxKind,
76 vis: Vis, 76 vis: Vis,
77} 77}
@@ -233,7 +233,7 @@ impl InputModuleItems {
233 ast::ModuleItem::TypeDef(it) => { 233 ast::ModuleItem::TypeDef(it) => {
234 self.items.push(ModuleItem::new(file_id, file_items, it)?) 234 self.items.push(ModuleItem::new(file_id, file_items, it)?)
235 } 235 }
236 ast::ModuleItem::ImplItem(_) => { 236 ast::ModuleItem::ImplBlock(_) => {
237 // impls don't define items 237 // impls don't define items
238 } 238 }
239 ast::ModuleItem::UseItem(it) => self.add_use_item(file_items, it), 239 ast::ModuleItem::UseItem(it) => self.add_use_item(file_items, it),
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index 51e8b3da8..017caf442 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -51,6 +51,7 @@ impl Name {
51 "u128" => KnownName::U128, 51 "u128" => KnownName::U128,
52 "f32" => KnownName::F32, 52 "f32" => KnownName::F32,
53 "f64" => KnownName::F64, 53 "f64" => KnownName::F64,
54 "Self" => KnownName::Self_,
54 _ => return None, 55 _ => return None,
55 }; 56 };
56 Some(name) 57 Some(name)
@@ -84,7 +85,7 @@ impl AsName for ra_db::Dependency {
84// const ISIZE: Name = Name::new("isize") 85// const ISIZE: Name = Name::new("isize")
85// ``` 86// ```
86// but const-fn is not that powerful yet. 87// but const-fn is not that powerful yet.
87#[derive(Debug)] 88#[derive(Debug, PartialEq, Eq)]
88pub(crate) enum KnownName { 89pub(crate) enum KnownName {
89 Isize, 90 Isize,
90 I8, 91 I8,
@@ -102,4 +103,6 @@ pub(crate) enum KnownName {
102 103
103 F32, 104 F32,
104 F64, 105 F64,
106
107 Self_,
105} 108}
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 93f7203fe..9fdfa0d13 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -70,6 +70,11 @@ impl Path {
70 self.kind == PathKind::Plain && self.segments.len() == 1 70 self.kind == PathKind::Plain && self.segments.len() == 1
71 } 71 }
72 72
73 /// `true` if this path is just a standalone `self`
74 pub fn is_self(&self) -> bool {
75 self.kind == PathKind::Self_ && self.segments.len() == 0
76 }
77
73 /// If this path is a single identifier, like `foo`, return its name. 78 /// If this path is a single identifier, like `foo`, return its name.
74 pub fn as_ident(&self) -> Option<&Name> { 79 pub fn as_ident(&self) -> Option<&Name> {
75 if self.kind != PathKind::Plain || self.segments.len() > 1 { 80 if self.kind != PathKind::Plain || self.segments.len() > 1 {
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 24490d119..85bd84469 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -8,8 +8,8 @@
8use ra_db::{FileId, FilePosition, Cancelable}; 8use ra_db::{FileId, FilePosition, Cancelable};
9use ra_editor::find_node_at_offset; 9use ra_editor::find_node_at_offset;
10use ra_syntax::{ 10use ra_syntax::{
11 SmolStr, TextRange, SyntaxNodeRef,
11 ast::{self, AstNode, NameOwner}, 12 ast::{self, AstNode, NameOwner},
12 SyntaxNodeRef,
13}; 13};
14 14
15use crate::{ 15use crate::{
@@ -126,3 +126,40 @@ pub fn function_from_child_node(
126 let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast)); 126 let fn_def = ctry!(node.ancestors().find_map(ast::FnDef::cast));
127 function_from_source(db, file_id, fn_def) 127 function_from_source(db, file_id, fn_def)
128} 128}
129
130pub fn macro_symbols(
131 db: &impl HirDatabase,
132 file_id: FileId,
133) -> Cancelable<Vec<(SmolStr, TextRange)>> {
134 let module = match module_from_file_id(db, file_id)? {
135 Some(it) => it,
136 None => return Ok(Vec::new()),
137 };
138 let items = db.input_module_items(module.source_root_id, module.module_id)?;
139 let mut res = Vec::new();
140
141 for macro_call_id in items
142 .items
143 .iter()
144 .filter_map(|it| it.id.file_id.as_macro_call_id())
145 {
146 if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
147 let loc = macro_call_id.loc(db);
148 let syntax = db.file_item(loc.source_item_id);
149 let syntax = syntax.borrowed();
150 let macro_call = ast::MacroCall::cast(syntax).unwrap();
151 let off = macro_call.token_tree().unwrap().syntax().range().start();
152 let file = exp.file();
153 for trait_def in file.syntax().descendants().filter_map(ast::TraitDef::cast) {
154 if let Some(name) = trait_def.name() {
155 let dst_range = name.syntax().range();
156 if let Some(src_range) = exp.map_range_back(dst_range) {
157 res.push((name.text(), src_range + off))
158 }
159 }
160 }
161 }
162 }
163
164 Ok(res)
165}
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 719b3f7cd..e33762e0d 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -31,9 +31,10 @@ use ra_syntax::{
31}; 31};
32 32
33use crate::{ 33use crate::{
34 Def, DefId, FnScopes, Module, Function, Struct, Enum, Path, Name, AsName, 34 Def, DefId, FnScopes, Module, Function, Struct, Enum, Path, Name, AsName, ImplBlock,
35 db::HirDatabase, 35 db::HirDatabase,
36 type_ref::{TypeRef, Mutability}, 36 type_ref::{TypeRef, Mutability},
37 name::KnownName,
37}; 38};
38 39
39/// The ID of a type variable. 40/// The ID of a type variable.
@@ -235,6 +236,7 @@ impl Ty {
235 pub(crate) fn from_hir( 236 pub(crate) fn from_hir(
236 db: &impl HirDatabase, 237 db: &impl HirDatabase,
237 module: &Module, 238 module: &Module,
239 impl_block: Option<&ImplBlock>,
238 type_ref: &TypeRef, 240 type_ref: &TypeRef,
239 ) -> Cancelable<Self> { 241 ) -> Cancelable<Self> {
240 Ok(match type_ref { 242 Ok(match type_ref {
@@ -242,29 +244,29 @@ impl Ty {
242 TypeRef::Tuple(inner) => { 244 TypeRef::Tuple(inner) => {
243 let inner_tys = inner 245 let inner_tys = inner
244 .iter() 246 .iter()
245 .map(|tr| Ty::from_hir(db, module, tr)) 247 .map(|tr| Ty::from_hir(db, module, impl_block, tr))
246 .collect::<Cancelable<Vec<_>>>()?; 248 .collect::<Cancelable<Vec<_>>>()?;
247 Ty::Tuple(inner_tys.into()) 249 Ty::Tuple(inner_tys.into())
248 } 250 }
249 TypeRef::Path(path) => Ty::from_hir_path(db, module, path)?, 251 TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, path)?,
250 TypeRef::RawPtr(inner, mutability) => { 252 TypeRef::RawPtr(inner, mutability) => {
251 let inner_ty = Ty::from_hir(db, module, inner)?; 253 let inner_ty = Ty::from_hir(db, module, impl_block, inner)?;
252 Ty::RawPtr(Arc::new(inner_ty), *mutability) 254 Ty::RawPtr(Arc::new(inner_ty), *mutability)
253 } 255 }
254 TypeRef::Array(_inner) => Ty::Unknown, // TODO 256 TypeRef::Array(_inner) => Ty::Unknown, // TODO
255 TypeRef::Slice(inner) => { 257 TypeRef::Slice(inner) => {
256 let inner_ty = Ty::from_hir(db, module, inner)?; 258 let inner_ty = Ty::from_hir(db, module, impl_block, inner)?;
257 Ty::Slice(Arc::new(inner_ty)) 259 Ty::Slice(Arc::new(inner_ty))
258 } 260 }
259 TypeRef::Reference(inner, mutability) => { 261 TypeRef::Reference(inner, mutability) => {
260 let inner_ty = Ty::from_hir(db, module, inner)?; 262 let inner_ty = Ty::from_hir(db, module, impl_block, inner)?;
261 Ty::Ref(Arc::new(inner_ty), *mutability) 263 Ty::Ref(Arc::new(inner_ty), *mutability)
262 } 264 }
263 TypeRef::Placeholder => Ty::Unknown, 265 TypeRef::Placeholder => Ty::Unknown,
264 TypeRef::Fn(params) => { 266 TypeRef::Fn(params) => {
265 let mut inner_tys = params 267 let mut inner_tys = params
266 .iter() 268 .iter()
267 .map(|tr| Ty::from_hir(db, module, tr)) 269 .map(|tr| Ty::from_hir(db, module, impl_block, tr))
268 .collect::<Cancelable<Vec<_>>>()?; 270 .collect::<Cancelable<Vec<_>>>()?;
269 let return_ty = inner_tys 271 let return_ty = inner_tys
270 .pop() 272 .pop()
@@ -279,9 +281,21 @@ impl Ty {
279 }) 281 })
280 } 282 }
281 283
284 pub(crate) fn from_hir_opt(
285 db: &impl HirDatabase,
286 module: &Module,
287 impl_block: Option<&ImplBlock>,
288 type_ref: Option<&TypeRef>,
289 ) -> Cancelable<Self> {
290 type_ref
291 .map(|t| Ty::from_hir(db, module, impl_block, t))
292 .unwrap_or(Ok(Ty::Unknown))
293 }
294
282 pub(crate) fn from_hir_path( 295 pub(crate) fn from_hir_path(
283 db: &impl HirDatabase, 296 db: &impl HirDatabase,
284 module: &Module, 297 module: &Module,
298 impl_block: Option<&ImplBlock>,
285 path: &Path, 299 path: &Path,
286 ) -> Cancelable<Self> { 300 ) -> Cancelable<Self> {
287 if let Some(name) = path.as_ident() { 301 if let Some(name) = path.as_ident() {
@@ -291,6 +305,8 @@ impl Ty {
291 return Ok(Ty::Uint(uint_ty)); 305 return Ok(Ty::Uint(uint_ty));
292 } else if let Some(float_ty) = primitive::FloatTy::from_name(name) { 306 } else if let Some(float_ty) = primitive::FloatTy::from_name(name) {
293 return Ok(Ty::Float(float_ty)); 307 return Ok(Ty::Float(float_ty));
308 } else if name.as_known_name() == Some(KnownName::Self_) {
309 return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type()));
294 } 310 }
295 } 311 }
296 312
@@ -308,18 +324,20 @@ impl Ty {
308 pub(crate) fn from_ast_opt( 324 pub(crate) fn from_ast_opt(
309 db: &impl HirDatabase, 325 db: &impl HirDatabase,
310 module: &Module, 326 module: &Module,
327 impl_block: Option<&ImplBlock>,
311 node: Option<ast::TypeRef>, 328 node: Option<ast::TypeRef>,
312 ) -> Cancelable<Self> { 329 ) -> Cancelable<Self> {
313 node.map(|n| Ty::from_ast(db, module, n)) 330 node.map(|n| Ty::from_ast(db, module, impl_block, n))
314 .unwrap_or(Ok(Ty::Unknown)) 331 .unwrap_or(Ok(Ty::Unknown))
315 } 332 }
316 333
317 pub(crate) fn from_ast( 334 pub(crate) fn from_ast(
318 db: &impl HirDatabase, 335 db: &impl HirDatabase,
319 module: &Module, 336 module: &Module,
337 impl_block: Option<&ImplBlock>,
320 node: ast::TypeRef, 338 node: ast::TypeRef,
321 ) -> Cancelable<Self> { 339 ) -> Cancelable<Self> {
322 Ty::from_hir(db, module, &TypeRef::from_ast(node)) 340 Ty::from_hir(db, module, impl_block, &TypeRef::from_ast(node))
323 } 341 }
324 342
325 pub fn unit() -> Self { 343 pub fn unit() -> Self {
@@ -402,18 +420,19 @@ impl fmt::Display for Ty {
402fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { 420fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> {
403 let syntax = f.syntax(db); 421 let syntax = f.syntax(db);
404 let module = f.module(db)?; 422 let module = f.module(db)?;
423 let impl_block = f.impl_block(db)?;
405 let node = syntax.borrowed(); 424 let node = syntax.borrowed();
406 // TODO we ignore type parameters for now 425 // TODO we ignore type parameters for now
407 let input = node 426 let input = node
408 .param_list() 427 .param_list()
409 .map(|pl| { 428 .map(|pl| {
410 pl.params() 429 pl.params()
411 .map(|p| Ty::from_ast_opt(db, &module, p.type_ref())) 430 .map(|p| Ty::from_ast_opt(db, &module, impl_block.as_ref(), p.type_ref()))
412 .collect() 431 .collect()
413 }) 432 })
414 .unwrap_or_else(|| Ok(Vec::new()))?; 433 .unwrap_or_else(|| Ok(Vec::new()))?;
415 let output = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { 434 let output = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) {
416 Ty::from_ast(db, &module, type_ref)? 435 Ty::from_ast(db, &module, impl_block.as_ref(), type_ref)?
417 } else { 436 } else {
418 Ty::unit() 437 Ty::unit()
419 }; 438 };
@@ -467,12 +486,13 @@ pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name)
467 ), 486 ),
468 }; 487 };
469 let module = def_id.module(db)?; 488 let module = def_id.module(db)?;
489 let impl_block = def_id.impl_block(db)?;
470 let type_ref = if let Some(tr) = variant_data.get_field_type_ref(&field) { 490 let type_ref = if let Some(tr) = variant_data.get_field_type_ref(&field) {
471 tr 491 tr
472 } else { 492 } else {
473 return Ok(Ty::Unknown); 493 return Ok(Ty::Unknown);
474 }; 494 };
475 Ty::from_hir(db, &module, &type_ref) 495 Ty::from_hir(db, &module, impl_block.as_ref(), &type_ref)
476} 496}
477 497
478/// The result of type inference: A mapping from expressions and patterns to types. 498/// The result of type inference: A mapping from expressions and patterns to types.
@@ -496,19 +516,32 @@ impl InferenceResult {
496struct InferenceContext<'a, D: HirDatabase> { 516struct InferenceContext<'a, D: HirDatabase> {
497 db: &'a D, 517 db: &'a D,
498 scopes: Arc<FnScopes>, 518 scopes: Arc<FnScopes>,
519 /// The self param for the current method, if it exists.
520 self_param: Option<LocalSyntaxPtr>,
499 module: Module, 521 module: Module,
522 impl_block: Option<ImplBlock>,
500 var_unification_table: InPlaceUnificationTable<TypeVarId>, 523 var_unification_table: InPlaceUnificationTable<TypeVarId>,
501 type_of: FxHashMap<LocalSyntaxPtr, Ty>, 524 type_of: FxHashMap<LocalSyntaxPtr, Ty>,
525 /// The return type of the function being inferred.
526 return_ty: Ty,
502} 527}
503 528
504impl<'a, D: HirDatabase> InferenceContext<'a, D> { 529impl<'a, D: HirDatabase> InferenceContext<'a, D> {
505 fn new(db: &'a D, scopes: Arc<FnScopes>, module: Module) -> Self { 530 fn new(
531 db: &'a D,
532 scopes: Arc<FnScopes>,
533 module: Module,
534 impl_block: Option<ImplBlock>,
535 ) -> Self {
506 InferenceContext { 536 InferenceContext {
507 type_of: FxHashMap::default(), 537 type_of: FxHashMap::default(),
508 var_unification_table: InPlaceUnificationTable::new(), 538 var_unification_table: InPlaceUnificationTable::new(),
539 self_param: None, // set during parameter typing
540 return_ty: Ty::Unknown, // set in collect_fn_signature
509 db, 541 db,
510 scopes, 542 scopes,
511 module, 543 module,
544 impl_block,
512 } 545 }
513 } 546 }
514 547
@@ -525,6 +558,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
525 self.type_of.insert(LocalSyntaxPtr::new(node), ty); 558 self.type_of.insert(LocalSyntaxPtr::new(node), ty);
526 } 559 }
527 560
561 fn make_ty(&self, type_ref: &TypeRef) -> Cancelable<Ty> {
562 Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref)
563 }
564
565 fn make_ty_opt(&self, type_ref: Option<&TypeRef>) -> Cancelable<Ty> {
566 Ty::from_hir_opt(self.db, &self.module, self.impl_block.as_ref(), type_ref)
567 }
568
528 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 569 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
529 match (ty1, ty2) { 570 match (ty1, ty2) {
530 (Ty::Unknown, ..) => true, 571 (Ty::Unknown, ..) => true,
@@ -628,6 +669,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
628 let ty = self.resolve_ty_as_possible(ty.clone()); 669 let ty = self.resolve_ty_as_possible(ty.clone());
629 return Ok(Some(ty)); 670 return Ok(Some(ty));
630 }; 671 };
672 } else if path.is_self() {
673 // resolve `self` param
674 let self_param = ctry!(self.self_param);
675 let ty = ctry!(self.type_of.get(&self_param));
676 let ty = self.resolve_ty_as_possible(ty.clone());
677 return Ok(Some(ty));
631 }; 678 };
632 679
633 // resolve in module 680 // resolve in module
@@ -826,7 +873,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
826 } 873 }
827 ast::Expr::CastExpr(e) => { 874 ast::Expr::CastExpr(e) => {
828 let _inner_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?; 875 let _inner_ty = self.infer_expr_opt(e.expr(), &Expectation::none())?;
829 let cast_ty = Ty::from_ast_opt(self.db, &self.module, e.type_ref())?; 876 let cast_ty = Ty::from_ast_opt(
877 self.db,
878 &self.module,
879 self.impl_block.as_ref(),
880 e.type_ref(),
881 )?;
830 let cast_ty = self.insert_type_vars(cast_ty); 882 let cast_ty = self.insert_type_vars(cast_ty);
831 // TODO do the coercion... 883 // TODO do the coercion...
832 cast_ty 884 cast_ty
@@ -880,7 +932,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
880 for stmt in node.statements() { 932 for stmt in node.statements() {
881 match stmt { 933 match stmt {
882 ast::Stmt::LetStmt(stmt) => { 934 ast::Stmt::LetStmt(stmt) => {
883 let decl_ty = Ty::from_ast_opt(self.db, &self.module, stmt.type_ref())?; 935 let decl_ty = Ty::from_ast_opt(
936 self.db,
937 &self.module,
938 self.impl_block.as_ref(),
939 stmt.type_ref(),
940 )?;
884 let decl_ty = self.insert_type_vars(decl_ty); 941 let decl_ty = self.insert_type_vars(decl_ty);
885 let ty = if let Some(expr) = stmt.initializer() { 942 let ty = if let Some(expr) = stmt.initializer() {
886 let expr_ty = self.infer_expr(expr, &Expectation::has_type(decl_ty))?; 943 let expr_ty = self.infer_expr(expr, &Expectation::has_type(decl_ty))?;
@@ -906,46 +963,71 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
906 self.write_ty(node.syntax(), ty.clone()); 963 self.write_ty(node.syntax(), ty.clone());
907 Ok(ty) 964 Ok(ty)
908 } 965 }
966
967 fn collect_fn_signature(&mut self, node: ast::FnDef) -> Cancelable<()> {
968 if let Some(param_list) = node.param_list() {
969 if let Some(self_param) = param_list.self_param() {
970 let self_type = if let Some(type_ref) = self_param.type_ref() {
971 let ty = self.make_ty(&TypeRef::from_ast(type_ref))?;
972 self.insert_type_vars(ty)
973 } else {
974 // TODO this should be handled by desugaring during HIR conversion
975 let ty = self.make_ty_opt(self.impl_block.as_ref().map(|i| i.target_type()))?;
976 let ty = match self_param.flavor() {
977 ast::SelfParamFlavor::Owned => ty,
978 ast::SelfParamFlavor::Ref => Ty::Ref(Arc::new(ty), Mutability::Shared),
979 ast::SelfParamFlavor::MutRef => Ty::Ref(Arc::new(ty), Mutability::Mut),
980 };
981 self.insert_type_vars(ty)
982 };
983 if let Some(self_kw) = self_param.self_kw() {
984 let self_param = LocalSyntaxPtr::new(self_kw.syntax());
985 self.self_param = Some(self_param);
986 self.type_of.insert(self_param, self_type);
987 }
988 }
989 for param in param_list.params() {
990 let pat = if let Some(pat) = param.pat() {
991 pat
992 } else {
993 continue;
994 };
995 let ty = if let Some(type_ref) = param.type_ref() {
996 let ty = self.make_ty(&TypeRef::from_ast(type_ref))?;
997 self.insert_type_vars(ty)
998 } else {
999 // missing type annotation
1000 self.new_type_var()
1001 };
1002 self.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty);
1003 }
1004 }
1005
1006 self.return_ty = if let Some(type_ref) = node.ret_type().and_then(|n| n.type_ref()) {
1007 let ty = self.make_ty(&TypeRef::from_ast(type_ref))?;
1008 self.insert_type_vars(ty)
1009 } else {
1010 Ty::unit()
1011 };
1012
1013 Ok(())
1014 }
909} 1015}
910 1016
911pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> { 1017pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> {
912 let function = Function::new(def_id); // TODO: consts also need inference 1018 let function = Function::new(def_id); // TODO: consts also need inference
913 let scopes = function.scopes(db); 1019 let scopes = function.scopes(db);
914 let module = function.module(db)?; 1020 let module = function.module(db)?;
915 let mut ctx = InferenceContext::new(db, scopes, module); 1021 let impl_block = function.impl_block(db)?;
1022 let mut ctx = InferenceContext::new(db, scopes, module, impl_block);
916 1023
917 let syntax = function.syntax(db); 1024 let syntax = function.syntax(db);
918 let node = syntax.borrowed(); 1025 let node = syntax.borrowed();
919 1026
920 if let Some(param_list) = node.param_list() { 1027 ctx.collect_fn_signature(node)?;
921 for param in param_list.params() {
922 let pat = if let Some(pat) = param.pat() {
923 pat
924 } else {
925 continue;
926 };
927 if let Some(type_ref) = param.type_ref() {
928 let ty = Ty::from_ast(db, &ctx.module, type_ref)?;
929 let ty = ctx.insert_type_vars(ty);
930 ctx.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty);
931 } else {
932 // TODO self param
933 let type_var = ctx.new_type_var();
934 ctx.type_of
935 .insert(LocalSyntaxPtr::new(pat.syntax()), type_var);
936 };
937 }
938 }
939
940 let ret_ty = if let Some(type_ref) = node.ret_type().and_then(|n| n.type_ref()) {
941 let ty = Ty::from_ast(db, &ctx.module, type_ref)?;
942 ctx.insert_type_vars(ty)
943 } else {
944 Ty::unit()
945 };
946 1028
947 if let Some(block) = node.body() { 1029 if let Some(block) = node.body() {
948 ctx.infer_block(block, &Expectation::has_type(ret_ty))?; 1030 ctx.infer_block(block, &Expectation::has_type(ctx.return_ty.clone()))?;
949 } 1031 }
950 1032
951 Ok(Arc::new(ctx.resolve_all())) 1033 Ok(Arc::new(ctx.resolve_all()))
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 93bf431c4..fb53fcf0b 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -134,6 +134,25 @@ fn test() -> &mut &f64 {
134 ); 134 );
135} 135}
136 136
137#[test]
138fn infer_self() {
139 check_inference(
140 r#"
141struct S;
142
143impl S {
144 fn test(&self) {
145 self;
146 }
147 fn test2(self: &Self) {
148 self;
149 }
150}
151"#,
152 "0007_self.txt",
153 );
154}
155
137fn infer(content: &str) -> String { 156fn infer(content: &str) -> String {
138 let (db, _, file_id) = MockDatabase::with_single_file(content); 157 let (db, _, file_id) = MockDatabase::with_single_file(content);
139 let source_file = db.source_file(file_id); 158 let source_file = db.source_file(file_id);
diff --git a/crates/ra_hir/src/ty/tests/data/0007_self.txt b/crates/ra_hir/src/ty/tests/data/0007_self.txt
new file mode 100644
index 000000000..db4ba17d0
--- /dev/null
+++ b/crates/ra_hir/src/ty/tests/data/0007_self.txt
@@ -0,0 +1,6 @@
1[50; 54) 'self': &S
2[34; 38) 'self': &S
3[40; 61) '{ ... }': ()
4[88; 109) '{ ... }': ()
5[98; 102) 'self': &S
6[75; 79) 'self': &S
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 1107ffc8b..e8eb3940f 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -1,11 +1,16 @@
1use languageserver_types::{ 1use languageserver_types::{
2 self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, 2 self, CreateFile, DocumentChangeOperation, DocumentChanges, InsertTextFormat, Location,
3 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat, 3 Position, Range, RenameFile, ResourceOp, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
4 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier,
5 WorkspaceEdit,
4}; 6};
5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition,FileRange, CompletionItem, CompletionItemKind, InsertText, NavigationTarget}; 7use ra_analysis::{
6use ra_editor::{LineCol, LineIndex, translate_offset_with_edit}; 8 CompletionItem, CompletionItemKind, FileId, FilePosition, FileRange, FileSystemEdit,
7use ra_text_edit::{AtomTextEdit, TextEdit}; 9 InsertText, NavigationTarget, SourceChange, SourceFileEdit,
10};
11use ra_editor::{translate_offset_with_edit, LineCol, LineIndex};
8use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 12use ra_syntax::{SyntaxKind, TextRange, TextUnit};
13use ra_text_edit::{AtomTextEdit, TextEdit};
9 14
10use crate::{req, server_world::ServerWorld, Result}; 15use crate::{req, server_world::ServerWorld, Result};
11 16
@@ -39,7 +44,7 @@ impl Conv for SyntaxKind {
39 SyntaxKind::TYPE_DEF => SymbolKind::TypeParameter, 44 SyntaxKind::TYPE_DEF => SymbolKind::TypeParameter,
40 SyntaxKind::STATIC_DEF => SymbolKind::Constant, 45 SyntaxKind::STATIC_DEF => SymbolKind::Constant,
41 SyntaxKind::CONST_DEF => SymbolKind::Constant, 46 SyntaxKind::CONST_DEF => SymbolKind::Constant,
42 SyntaxKind::IMPL_ITEM => SymbolKind::Object, 47 SyntaxKind::IMPL_BLOCK => SymbolKind::Object,
43 _ => SymbolKind::Variable, 48 _ => SymbolKind::Variable,
44 } 49 }
45 } 50 }
@@ -49,7 +54,7 @@ impl Conv for CompletionItemKind {
49 type Output = ::languageserver_types::CompletionItemKind; 54 type Output = ::languageserver_types::CompletionItemKind;
50 55
51 fn conv(self) -> <Self as Conv>::Output { 56 fn conv(self) -> <Self as Conv>::Output {
52 use ::languageserver_types::CompletionItemKind::*; 57 use languageserver_types::CompletionItemKind::*;
53 match self { 58 match self {
54 CompletionItemKind::Keyword => Keyword, 59 CompletionItemKind::Keyword => Keyword,
55 CompletionItemKind::Snippet => Snippet, 60 CompletionItemKind::Snippet => Snippet,
@@ -266,12 +271,20 @@ impl TryConvWith for SourceChange {
266 }) 271 })
267 } 272 }
268 }; 273 };
269 let source_file_edits = self.source_file_edits.try_conv_with(world)?; 274 let mut document_changes: Vec<DocumentChangeOperation> = Vec::new();
270 let file_system_edits = self.file_system_edits.try_conv_with(world)?; 275 for resource_op in self.file_system_edits.try_conv_with(world)? {
276 document_changes.push(DocumentChangeOperation::Op(resource_op));
277 }
278 for text_document_edit in self.source_file_edits.try_conv_with(world)? {
279 document_changes.push(DocumentChangeOperation::Edit(text_document_edit));
280 }
281 let workspace_edit = WorkspaceEdit {
282 changes: None,
283 document_changes: Some(DocumentChanges::Operations(document_changes)),
284 };
271 Ok(req::SourceChange { 285 Ok(req::SourceChange {
272 label: self.label, 286 label: self.label,
273 source_file_edits, 287 workspace_edit,
274 file_system_edits,
275 cursor_position, 288 cursor_position,
276 }) 289 })
277 } 290 }
@@ -301,21 +314,25 @@ impl TryConvWith for SourceFileEdit {
301 314
302impl TryConvWith for FileSystemEdit { 315impl TryConvWith for FileSystemEdit {
303 type Ctx = ServerWorld; 316 type Ctx = ServerWorld;
304 type Output = req::FileSystemEdit; 317 type Output = ResourceOp;
305 fn try_conv_with(self, world: &ServerWorld) -> Result<req::FileSystemEdit> { 318 fn try_conv_with(self, world: &ServerWorld) -> Result<ResourceOp> {
306 let res = match self { 319 let res = match self {
307 FileSystemEdit::CreateFile { source_root, path } => { 320 FileSystemEdit::CreateFile { source_root, path } => {
308 let uri = world.path_to_uri(source_root, &path)?; 321 let uri = world.path_to_uri(source_root, &path)?.to_string();
309 req::FileSystemEdit::CreateFile { uri } 322 ResourceOp::Create(CreateFile { uri, options: None })
310 } 323 }
311 FileSystemEdit::MoveFile { 324 FileSystemEdit::MoveFile {
312 src, 325 src,
313 dst_source_root, 326 dst_source_root,
314 dst_path, 327 dst_path,
315 } => { 328 } => {
316 let src = world.file_id_to_uri(src)?; 329 let old_uri = world.file_id_to_uri(src)?.to_string();
317 let dst = world.path_to_uri(dst_source_root, &dst_path)?; 330 let new_uri = world.path_to_uri(dst_source_root, &dst_path)?.to_string();
318 req::FileSystemEdit::MoveFile { src, dst } 331 ResourceOp::Rename(RenameFile {
332 old_uri,
333 new_uri,
334 options: None,
335 })
319 } 336 }
320 }; 337 };
321 Ok(res) 338 Ok(res)
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 06dd373c0..60d9671de 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -350,7 +350,7 @@ fn on_notification(
350 .write() 350 .write()
351 .add_file_overlay(&path, params.text_document.text) 351 .add_file_overlay(&path, params.text_document.text)
352 { 352 {
353 subs.add_sub(FileId(file_id.0)); 353 subs.add_sub(FileId(file_id.0.into()));
354 } 354 }
355 return Ok(()); 355 return Ok(());
356 } 356 }
@@ -379,7 +379,7 @@ fn on_notification(
379 .to_file_path() 379 .to_file_path()
380 .map_err(|()| format_err!("invalid uri: {}", uri))?; 380 .map_err(|()| format_err!("invalid uri: {}", uri))?;
381 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { 381 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) {
382 subs.remove_sub(FileId(file_id.0)); 382 subs.remove_sub(FileId(file_id.0.into()));
383 } 383 }
384 let params = req::PublishDiagnosticsParams { 384 let params = req::PublishDiagnosticsParams {
385 uri, 385 uri,
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 06ae9a64a..2fc4d3649 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -337,7 +337,10 @@ pub fn handle_runnables(
337 None => return Ok(None), 337 None => return Ok(None),
338 }; 338 };
339 let file_id = world.analysis().crate_root(crate_id)?; 339 let file_id = world.analysis().crate_root(crate_id)?;
340 let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0)); 340 let path = world
341 .vfs
342 .read()
343 .file2path(ra_vfs::VfsFile(file_id.0.into()));
341 let res = world.workspaces.iter().find_map(|ws| { 344 let res = world.workspaces.iter().find_map(|ws| {
342 let tgt = ws.target_by_root(&path)?; 345 let tgt = ws.target_by_root(&path)?;
343 let res = CargoTargetSpec { 346 let res = CargoTargetSpec {
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index 747ab8a8c..b41e90328 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -1,6 +1,6 @@
1use serde::{Serialize, Deserialize};
2use languageserver_types::{Location, Position, Range, TextDocumentIdentifier, Url}; 1use languageserver_types::{Location, Position, Range, TextDocumentIdentifier, Url};
3use rustc_hash::FxHashMap; 2use rustc_hash::FxHashMap;
3use serde::{Deserialize, Serialize};
4use url_serde; 4use url_serde;
5 5
6pub use languageserver_types::{ 6pub use languageserver_types::{
@@ -8,7 +8,7 @@ pub use languageserver_types::{
8 CompletionResponse, DocumentOnTypeFormattingParams, DocumentSymbolParams, 8 CompletionResponse, DocumentOnTypeFormattingParams, DocumentSymbolParams,
9 DocumentSymbolResponse, ExecuteCommandParams, Hover, InitializeResult, 9 DocumentSymbolResponse, ExecuteCommandParams, Hover, InitializeResult,
10 PublishDiagnosticsParams, ReferenceParams, SignatureHelp, TextDocumentEdit, 10 PublishDiagnosticsParams, ReferenceParams, SignatureHelp, TextDocumentEdit,
11 TextDocumentPositionParams, TextEdit, WorkspaceSymbolParams, 11 TextDocumentPositionParams, TextEdit, WorkspaceEdit, WorkspaceSymbolParams,
12}; 12};
13 13
14pub enum SyntaxTree {} 14pub enum SyntaxTree {}
@@ -151,26 +151,10 @@ pub struct Runnable {
151#[serde(rename_all = "camelCase")] 151#[serde(rename_all = "camelCase")]
152pub struct SourceChange { 152pub struct SourceChange {
153 pub label: String, 153 pub label: String,
154 pub source_file_edits: Vec<TextDocumentEdit>, 154 pub workspace_edit: WorkspaceEdit,
155 pub file_system_edits: Vec<FileSystemEdit>,
156 pub cursor_position: Option<TextDocumentPositionParams>, 155 pub cursor_position: Option<TextDocumentPositionParams>,
157} 156}
158 157
159#[derive(Serialize, Debug)]
160#[serde(tag = "type", rename_all = "camelCase")]
161pub enum FileSystemEdit {
162 CreateFile {
163 #[serde(with = "url_serde")]
164 uri: Url,
165 },
166 MoveFile {
167 #[serde(with = "url_serde")]
168 src: Url,
169 #[serde(with = "url_serde")]
170 dst: Url,
171 },
172}
173
174pub enum InternalFeedback {} 158pub enum InternalFeedback {}
175 159
176impl Notification for InternalFeedback { 160impl Notification for InternalFeedback {
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index c183c25af..ebf2b15cc 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -49,7 +49,7 @@ impl ServerWorldState {
49 let (mut vfs, roots) = Vfs::new(roots); 49 let (mut vfs, roots) = Vfs::new(roots);
50 for r in roots { 50 for r in roots {
51 let is_local = vfs.root2path(r).starts_with(&root); 51 let is_local = vfs.root2path(r).starts_with(&root);
52 change.add_root(SourceRootId(r.0), is_local); 52 change.add_root(SourceRootId(r.0.into()), is_local);
53 } 53 }
54 54
55 let mut crate_graph = CrateGraph::default(); 55 let mut crate_graph = CrateGraph::default();
@@ -60,7 +60,7 @@ impl ServerWorldState {
60 for tgt in pkg.targets(ws) { 60 for tgt in pkg.targets(ws) {
61 let root = tgt.root(ws); 61 let root = tgt.root(ws);
62 if let Some(file_id) = vfs.load(root) { 62 if let Some(file_id) = vfs.load(root) {
63 let file_id = FileId(file_id.0); 63 let file_id = FileId(file_id.0.into());
64 let crate_id = crate_graph.add_crate_root(file_id); 64 let crate_id = crate_graph.add_crate_root(file_id);
65 if tgt.kind(ws) == TargetKind::Lib { 65 if tgt.kind(ws) == TargetKind::Lib {
66 pkg_to_lib_crate.insert(pkg, crate_id); 66 pkg_to_lib_crate.insert(pkg, crate_id);
@@ -113,14 +113,19 @@ impl ServerWorldState {
113 if root_path.starts_with(&self.root) { 113 if root_path.starts_with(&self.root) {
114 self.roots_to_scan -= 1; 114 self.roots_to_scan -= 1;
115 for (file, path, text) in files { 115 for (file, path, text) in files {
116 change.add_file(SourceRootId(root.0), FileId(file.0), path, text); 116 change.add_file(
117 SourceRootId(root.0.into()),
118 FileId(file.0.into()),
119 path,
120 text,
121 );
117 } 122 }
118 } else { 123 } else {
119 let files = files 124 let files = files
120 .into_iter() 125 .into_iter()
121 .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) 126 .map(|(vfsfile, path, text)| (FileId(vfsfile.0.into()), path, text))
122 .collect(); 127 .collect();
123 libs.push((SourceRootId(root.0), files)); 128 libs.push((SourceRootId(root.0.into()), files));
124 } 129 }
125 } 130 }
126 VfsChange::AddFile { 131 VfsChange::AddFile {
@@ -129,13 +134,18 @@ impl ServerWorldState {
129 path, 134 path,
130 text, 135 text,
131 } => { 136 } => {
132 change.add_file(SourceRootId(root.0), FileId(file.0), path, text); 137 change.add_file(
138 SourceRootId(root.0.into()),
139 FileId(file.0.into()),
140 path,
141 text,
142 );
133 } 143 }
134 VfsChange::RemoveFile { root, file, path } => { 144 VfsChange::RemoveFile { root, file, path } => {
135 change.remove_file(SourceRootId(root.0), FileId(file.0), path) 145 change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path)
136 } 146 }
137 VfsChange::ChangeFile { file, text } => { 147 VfsChange::ChangeFile { file, text } => {
138 change.change_file(FileId(file.0), text); 148 change.change_file(FileId(file.0.into()), text);
139 } 149 }
140 } 150 }
141 } 151 }
@@ -173,18 +183,18 @@ impl ServerWorld {
173 .read() 183 .read()
174 .path2file(&path) 184 .path2file(&path)
175 .ok_or_else(|| format_err!("unknown file: {}", path.display()))?; 185 .ok_or_else(|| format_err!("unknown file: {}", path.display()))?;
176 Ok(FileId(file.0)) 186 Ok(FileId(file.0.into()))
177 } 187 }
178 188
179 pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { 189 pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> {
180 let path = self.vfs.read().file2path(VfsFile(id.0)); 190 let path = self.vfs.read().file2path(VfsFile(id.0.into()));
181 let url = Url::from_file_path(&path) 191 let url = Url::from_file_path(&path)
182 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; 192 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;
183 Ok(url) 193 Ok(url)
184 } 194 }
185 195
186 pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { 196 pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> {
187 let base = self.vfs.read().root2path(VfsRoot(root.0)); 197 let base = self.vfs.read().root2path(VfsRoot(root.0.into()));
188 let path = path.to_path(base); 198 let path = path.to_path(base);
189 let url = Url::from_file_path(&path) 199 let url = Url::from_file_path(&path)
190 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; 200 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;
diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs
index b0e1e65b6..4cae44eab 100644
--- a/crates/ra_lsp_server/tests/heavy_tests/main.rs
+++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs
@@ -1,8 +1,12 @@
1mod support; 1mod support;
2 2
3use languageserver_types::{
4 CodeActionContext, DocumentFormattingParams, FormattingOptions, Position, Range,
5};
6use ra_lsp_server::req::{
7 CodeActionParams, CodeActionRequest, Formatting, Runnables, RunnablesParams,
8};
3use serde_json::json; 9use serde_json::json;
4use ra_lsp_server::req::{Runnables, RunnablesParams, CodeActionRequest, CodeActionParams, Formatting};
5use languageserver_types::{Position, Range, CodeActionContext, DocumentFormattingParams, FormattingOptions};
6 10
7use crate::support::project; 11use crate::support::project;
8 12
@@ -203,14 +207,15 @@ fn main() {}
203 "arguments": [ 207 "arguments": [
204 { 208 {
205 "cursorPosition": null, 209 "cursorPosition": null,
206 "fileSystemEdits": [ 210 "workspaceEdit": {
207 { 211 "documentChanges": [
208 "type": "createFile", 212 {
213 "kind": "create",
209 "uri": "file:///[..]/src/bar.rs" 214 "uri": "file:///[..]/src/bar.rs"
210 } 215 }
211 ], 216 ]
212 "label": "create module", 217 },
213 "sourceFileEdits": [] 218 "label": "create module"
214 } 219 }
215 ], 220 ],
216 "command": "ra-lsp.applySourceChange", 221 "command": "ra-lsp.applySourceChange",
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 3e948800e..c10169d90 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -30,6 +30,12 @@ pub trait NameOwner<'a>: AstNode<'a> {
30 } 30 }
31} 31}
32 32
33pub trait VisibilityOwner<'a>: AstNode<'a> {
34 fn visibility(self) -> Option<Visibility<'a>> {
35 child_opt(self)
36 }
37}
38
33pub trait LoopBodyOwner<'a>: AstNode<'a> { 39pub trait LoopBodyOwner<'a>: AstNode<'a> {
34 fn loop_body(self) -> Option<Block<'a>> { 40 fn loop_body(self) -> Option<Block<'a>> {
35 child_opt(self) 41 child_opt(self)
@@ -109,6 +115,7 @@ pub trait DocCommentsOwner<'a>: AstNode<'a> {
109 /// That is, strips leading `///` and joins lines 115 /// That is, strips leading `///` and joins lines
110 fn doc_comment_text(self) -> RustString { 116 fn doc_comment_text(self) -> RustString {
111 self.doc_comments() 117 self.doc_comments()
118 .filter(|comment| comment.is_doc_comment())
112 .map(|comment| { 119 .map(|comment| {
113 let prefix = comment.prefix(); 120 let prefix = comment.prefix();
114 let trimmed = comment 121 let trimmed = comment
@@ -200,6 +207,10 @@ impl<'a> Comment<'a> {
200 } 207 }
201 } 208 }
202 209
210 pub fn is_doc_comment(&self) -> bool {
211 self.flavor().is_doc_comment()
212 }
213
203 pub fn prefix(&self) -> &'static str { 214 pub fn prefix(&self) -> &'static str {
204 self.flavor().prefix() 215 self.flavor().prefix()
205 } 216 }
@@ -231,6 +242,13 @@ impl CommentFlavor {
231 Multiline => "/*", 242 Multiline => "/*",
232 } 243 }
233 } 244 }
245
246 pub fn is_doc_comment(&self) -> bool {
247 match self {
248 CommentFlavor::Doc | CommentFlavor::ModuleDoc => true,
249 _ => false,
250 }
251 }
234} 252}
235 253
236impl<'a> Whitespace<'a> { 254impl<'a> Whitespace<'a> {
@@ -261,7 +279,7 @@ impl<'a> NameRef<'a> {
261 } 279 }
262} 280}
263 281
264impl<'a> ImplItem<'a> { 282impl<'a> ImplBlock<'a> {
265 pub fn target_type(self) -> Option<TypeRef<'a>> { 283 pub fn target_type(self) -> Option<TypeRef<'a>> {
266 match self.target() { 284 match self.target() {
267 (Some(t), None) | (_, Some(t)) => Some(t), 285 (Some(t), None) | (_, Some(t)) => Some(t),
@@ -345,6 +363,12 @@ impl<'a> PathSegment<'a> {
345 } 363 }
346} 364}
347 365
366impl<'a> Path<'a> {
367 pub fn parent_path(self) -> Option<Path<'a>> {
368 self.syntax().parent().and_then(Path::cast)
369 }
370}
371
348impl<'a> UseTree<'a> { 372impl<'a> UseTree<'a> {
349 pub fn has_star(self) -> bool { 373 pub fn has_star(self) -> bool {
350 self.syntax().children().any(|it| it.kind() == STAR) 374 self.syntax().children().any(|it| it.kind() == STAR)
@@ -463,3 +487,47 @@ impl<'a> PrefixExpr<'a> {
463 } 487 }
464 } 488 }
465} 489}
490
491#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
492pub enum SelfParamFlavor {
493 /// self
494 Owned,
495 /// &self
496 Ref,
497 /// &mut self
498 MutRef,
499}
500
501impl<'a> SelfParam<'a> {
502 pub fn flavor(&self) -> SelfParamFlavor {
503 let borrowed = self.syntax().children().any(|n| n.kind() == AMP);
504 if borrowed {
505 // check for a `mut` coming after the & -- `mut &self` != `&mut self`
506 if self
507 .syntax()
508 .children()
509 .skip_while(|n| n.kind() != AMP)
510 .any(|n| n.kind() == MUT_KW)
511 {
512 SelfParamFlavor::MutRef
513 } else {
514 SelfParamFlavor::Ref
515 }
516 } else {
517 SelfParamFlavor::Owned
518 }
519 }
520}
521
522#[test]
523fn test_doc_comment_of_items() {
524 let file = SourceFileNode::parse(
525 r#"
526 //! doc
527 // non-doc
528 mod foo {}
529 "#,
530 );
531 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
532 assert_eq!("doc", module.doc_comment_text());
533}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index c5ac90a62..7df6a9c46 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -695,6 +695,7 @@ impl<R: TreeRoot<RaTypes>> ConstDefNode<R> {
695} 695}
696 696
697 697
698impl<'a> ast::VisibilityOwner<'a> for ConstDef<'a> {}
698impl<'a> ast::NameOwner<'a> for ConstDef<'a> {} 699impl<'a> ast::NameOwner<'a> for ConstDef<'a> {}
699impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {} 700impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {}
700impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {} 701impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {}
@@ -810,6 +811,7 @@ impl<R: TreeRoot<RaTypes>> EnumDefNode<R> {
810} 811}
811 812
812 813
814impl<'a> ast::VisibilityOwner<'a> for EnumDef<'a> {}
813impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} 815impl<'a> ast::NameOwner<'a> for EnumDef<'a> {}
814impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} 816impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {}
815impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} 817impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {}
@@ -1213,6 +1215,7 @@ impl<R: TreeRoot<RaTypes>> FnDefNode<R> {
1213} 1215}
1214 1216
1215 1217
1218impl<'a> ast::VisibilityOwner<'a> for FnDef<'a> {}
1216impl<'a> ast::NameOwner<'a> for FnDef<'a> {} 1219impl<'a> ast::NameOwner<'a> for FnDef<'a> {}
1217impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {} 1220impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {}
1218impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {} 1221impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {}
@@ -1404,40 +1407,72 @@ impl<'a> IfExpr<'a> {
1404 } 1407 }
1405} 1408}
1406 1409
1407// ImplItem 1410// ImplBlock
1408#[derive(Debug, Clone, Copy,)] 1411#[derive(Debug, Clone, Copy,)]
1409pub struct ImplItemNode<R: TreeRoot<RaTypes> = OwnedRoot> { 1412pub struct ImplBlockNode<R: TreeRoot<RaTypes> = OwnedRoot> {
1410 pub(crate) syntax: SyntaxNode<R>, 1413 pub(crate) syntax: SyntaxNode<R>,
1411} 1414}
1412pub type ImplItem<'a> = ImplItemNode<RefRoot<'a>>; 1415pub type ImplBlock<'a> = ImplBlockNode<RefRoot<'a>>;
1413 1416
1414impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<ImplItemNode<R1>> for ImplItemNode<R2> { 1417impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<ImplBlockNode<R1>> for ImplBlockNode<R2> {
1415 fn eq(&self, other: &ImplItemNode<R1>) -> bool { self.syntax == other.syntax } 1418 fn eq(&self, other: &ImplBlockNode<R1>) -> bool { self.syntax == other.syntax }
1416} 1419}
1417impl<R: TreeRoot<RaTypes>> Eq for ImplItemNode<R> {} 1420impl<R: TreeRoot<RaTypes>> Eq for ImplBlockNode<R> {}
1418impl<R: TreeRoot<RaTypes>> Hash for ImplItemNode<R> { 1421impl<R: TreeRoot<RaTypes>> Hash for ImplBlockNode<R> {
1419 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) } 1422 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
1420} 1423}
1421 1424
1422impl<'a> AstNode<'a> for ImplItem<'a> { 1425impl<'a> AstNode<'a> for ImplBlock<'a> {
1423 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { 1426 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1424 match syntax.kind() { 1427 match syntax.kind() {
1425 IMPL_ITEM => Some(ImplItem { syntax }), 1428 IMPL_BLOCK => Some(ImplBlock { syntax }),
1426 _ => None, 1429 _ => None,
1427 } 1430 }
1428 } 1431 }
1429 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } 1432 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1430} 1433}
1431 1434
1432impl<R: TreeRoot<RaTypes>> ImplItemNode<R> { 1435impl<R: TreeRoot<RaTypes>> ImplBlockNode<R> {
1433 pub fn borrowed(&self) -> ImplItem { 1436 pub fn borrowed(&self) -> ImplBlock {
1434 ImplItemNode { syntax: self.syntax.borrowed() } 1437 ImplBlockNode { syntax: self.syntax.borrowed() }
1438 }
1439 pub fn owned(&self) -> ImplBlockNode {
1440 ImplBlockNode { syntax: self.syntax.owned() }
1435 } 1441 }
1436 pub fn owned(&self) -> ImplItemNode { 1442}
1437 ImplItemNode { syntax: self.syntax.owned() } 1443
1444
1445impl<'a> ImplBlock<'a> {
1446 pub fn item_list(self) -> Option<ItemList<'a>> {
1447 super::child_opt(self)
1438 } 1448 }
1439} 1449}
1440 1450
1451// ImplItem
1452#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1453pub enum ImplItem<'a> {
1454 FnDef(FnDef<'a>),
1455 TypeDef(TypeDef<'a>),
1456 ConstDef(ConstDef<'a>),
1457}
1458
1459impl<'a> AstNode<'a> for ImplItem<'a> {
1460 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1461 match syntax.kind() {
1462 FN_DEF => Some(ImplItem::FnDef(FnDef { syntax })),
1463 TYPE_DEF => Some(ImplItem::TypeDef(TypeDef { syntax })),
1464 CONST_DEF => Some(ImplItem::ConstDef(ConstDef { syntax })),
1465 _ => None,
1466 }
1467 }
1468 fn syntax(self) -> SyntaxNodeRef<'a> {
1469 match self {
1470 ImplItem::FnDef(inner) => inner.syntax(),
1471 ImplItem::TypeDef(inner) => inner.syntax(),
1472 ImplItem::ConstDef(inner) => inner.syntax(),
1473 }
1474 }
1475}
1441 1476
1442impl<'a> ImplItem<'a> {} 1477impl<'a> ImplItem<'a> {}
1443 1478
@@ -1552,7 +1587,11 @@ impl<R: TreeRoot<RaTypes>> ItemListNode<R> {
1552 1587
1553impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} 1588impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {}
1554impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} 1589impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {}
1555impl<'a> ItemList<'a> {} 1590impl<'a> ItemList<'a> {
1591 pub fn impl_items(self) -> impl Iterator<Item = ImplItem<'a>> + 'a {
1592 super::children(self)
1593 }
1594}
1556 1595
1557// Label 1596// Label
1558#[derive(Debug, Clone, Copy,)] 1597#[derive(Debug, Clone, Copy,)]
@@ -2136,6 +2175,7 @@ impl<R: TreeRoot<RaTypes>> ModuleNode<R> {
2136} 2175}
2137 2176
2138 2177
2178impl<'a> ast::VisibilityOwner<'a> for Module<'a> {}
2139impl<'a> ast::NameOwner<'a> for Module<'a> {} 2179impl<'a> ast::NameOwner<'a> for Module<'a> {}
2140impl<'a> ast::AttrsOwner<'a> for Module<'a> {} 2180impl<'a> ast::AttrsOwner<'a> for Module<'a> {}
2141impl<'a> ast::DocCommentsOwner<'a> for Module<'a> {} 2181impl<'a> ast::DocCommentsOwner<'a> for Module<'a> {}
@@ -2153,7 +2193,7 @@ pub enum ModuleItem<'a> {
2153 FnDef(FnDef<'a>), 2193 FnDef(FnDef<'a>),
2154 TraitDef(TraitDef<'a>), 2194 TraitDef(TraitDef<'a>),
2155 TypeDef(TypeDef<'a>), 2195 TypeDef(TypeDef<'a>),
2156 ImplItem(ImplItem<'a>), 2196 ImplBlock(ImplBlock<'a>),
2157 UseItem(UseItem<'a>), 2197 UseItem(UseItem<'a>),
2158 ExternCrateItem(ExternCrateItem<'a>), 2198 ExternCrateItem(ExternCrateItem<'a>),
2159 ConstDef(ConstDef<'a>), 2199 ConstDef(ConstDef<'a>),
@@ -2169,7 +2209,7 @@ impl<'a> AstNode<'a> for ModuleItem<'a> {
2169 FN_DEF => Some(ModuleItem::FnDef(FnDef { syntax })), 2209 FN_DEF => Some(ModuleItem::FnDef(FnDef { syntax })),
2170 TRAIT_DEF => Some(ModuleItem::TraitDef(TraitDef { syntax })), 2210 TRAIT_DEF => Some(ModuleItem::TraitDef(TraitDef { syntax })),
2171 TYPE_DEF => Some(ModuleItem::TypeDef(TypeDef { syntax })), 2211 TYPE_DEF => Some(ModuleItem::TypeDef(TypeDef { syntax })),
2172 IMPL_ITEM => Some(ModuleItem::ImplItem(ImplItem { syntax })), 2212 IMPL_BLOCK => Some(ModuleItem::ImplBlock(ImplBlock { syntax })),
2173 USE_ITEM => Some(ModuleItem::UseItem(UseItem { syntax })), 2213 USE_ITEM => Some(ModuleItem::UseItem(UseItem { syntax })),
2174 EXTERN_CRATE_ITEM => Some(ModuleItem::ExternCrateItem(ExternCrateItem { syntax })), 2214 EXTERN_CRATE_ITEM => Some(ModuleItem::ExternCrateItem(ExternCrateItem { syntax })),
2175 CONST_DEF => Some(ModuleItem::ConstDef(ConstDef { syntax })), 2215 CONST_DEF => Some(ModuleItem::ConstDef(ConstDef { syntax })),
@@ -2185,7 +2225,7 @@ impl<'a> AstNode<'a> for ModuleItem<'a> {
2185 ModuleItem::FnDef(inner) => inner.syntax(), 2225 ModuleItem::FnDef(inner) => inner.syntax(),
2186 ModuleItem::TraitDef(inner) => inner.syntax(), 2226 ModuleItem::TraitDef(inner) => inner.syntax(),
2187 ModuleItem::TypeDef(inner) => inner.syntax(), 2227 ModuleItem::TypeDef(inner) => inner.syntax(),
2188 ModuleItem::ImplItem(inner) => inner.syntax(), 2228 ModuleItem::ImplBlock(inner) => inner.syntax(),
2189 ModuleItem::UseItem(inner) => inner.syntax(), 2229 ModuleItem::UseItem(inner) => inner.syntax(),
2190 ModuleItem::ExternCrateItem(inner) => inner.syntax(), 2230 ModuleItem::ExternCrateItem(inner) => inner.syntax(),
2191 ModuleItem::ConstDef(inner) => inner.syntax(), 2231 ModuleItem::ConstDef(inner) => inner.syntax(),
@@ -2351,6 +2391,7 @@ impl<R: TreeRoot<RaTypes>> NamedFieldDefNode<R> {
2351} 2391}
2352 2392
2353 2393
2394impl<'a> ast::VisibilityOwner<'a> for NamedFieldDef<'a> {}
2354impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} 2395impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {}
2355impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} 2396impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {}
2356impl<'a> NamedFieldDef<'a> { 2397impl<'a> NamedFieldDef<'a> {
@@ -3082,6 +3123,7 @@ impl<R: TreeRoot<RaTypes>> PosFieldNode<R> {
3082} 3123}
3083 3124
3084 3125
3126impl<'a> ast::VisibilityOwner<'a> for PosField<'a> {}
3085impl<'a> ast::AttrsOwner<'a> for PosField<'a> {} 3127impl<'a> ast::AttrsOwner<'a> for PosField<'a> {}
3086impl<'a> PosField<'a> { 3128impl<'a> PosField<'a> {
3087 pub fn type_ref(self) -> Option<TypeRef<'a>> { 3129 pub fn type_ref(self) -> Option<TypeRef<'a>> {
@@ -3446,6 +3488,43 @@ impl<'a> ReturnExpr<'a> {
3446 } 3488 }
3447} 3489}
3448 3490
3491// SelfKw
3492#[derive(Debug, Clone, Copy,)]
3493pub struct SelfKwNode<R: TreeRoot<RaTypes> = OwnedRoot> {
3494 pub(crate) syntax: SyntaxNode<R>,
3495}
3496pub type SelfKw<'a> = SelfKwNode<RefRoot<'a>>;
3497
3498impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<SelfKwNode<R1>> for SelfKwNode<R2> {
3499 fn eq(&self, other: &SelfKwNode<R1>) -> bool { self.syntax == other.syntax }
3500}
3501impl<R: TreeRoot<RaTypes>> Eq for SelfKwNode<R> {}
3502impl<R: TreeRoot<RaTypes>> Hash for SelfKwNode<R> {
3503 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
3504}
3505
3506impl<'a> AstNode<'a> for SelfKw<'a> {
3507 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
3508 match syntax.kind() {
3509 SELF_KW => Some(SelfKw { syntax }),
3510 _ => None,
3511 }
3512 }
3513 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
3514}
3515
3516impl<R: TreeRoot<RaTypes>> SelfKwNode<R> {
3517 pub fn borrowed(&self) -> SelfKw {
3518 SelfKwNode { syntax: self.syntax.borrowed() }
3519 }
3520 pub fn owned(&self) -> SelfKwNode {
3521 SelfKwNode { syntax: self.syntax.owned() }
3522 }
3523}
3524
3525
3526impl<'a> SelfKw<'a> {}
3527
3449// SelfParam 3528// SelfParam
3450#[derive(Debug, Clone, Copy,)] 3529#[derive(Debug, Clone, Copy,)]
3451pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> { 3530pub struct SelfParamNode<R: TreeRoot<RaTypes> = OwnedRoot> {
@@ -3481,7 +3560,15 @@ impl<R: TreeRoot<RaTypes>> SelfParamNode<R> {
3481} 3560}
3482 3561
3483 3562
3484impl<'a> SelfParam<'a> {} 3563impl<'a> SelfParam<'a> {
3564 pub fn type_ref(self) -> Option<TypeRef<'a>> {
3565 super::child_opt(self)
3566 }
3567
3568 pub fn self_kw(self) -> Option<SelfKw<'a>> {
3569 super::child_opt(self)
3570 }
3571}
3485 3572
3486// SlicePat 3573// SlicePat
3487#[derive(Debug, Clone, Copy,)] 3574#[derive(Debug, Clone, Copy,)]
@@ -3639,6 +3726,7 @@ impl<R: TreeRoot<RaTypes>> StaticDefNode<R> {
3639} 3726}
3640 3727
3641 3728
3729impl<'a> ast::VisibilityOwner<'a> for StaticDef<'a> {}
3642impl<'a> ast::NameOwner<'a> for StaticDef<'a> {} 3730impl<'a> ast::NameOwner<'a> for StaticDef<'a> {}
3643impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {} 3731impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {}
3644impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {} 3732impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {}
@@ -3742,6 +3830,7 @@ impl<R: TreeRoot<RaTypes>> StructDefNode<R> {
3742} 3830}
3743 3831
3744 3832
3833impl<'a> ast::VisibilityOwner<'a> for StructDef<'a> {}
3745impl<'a> ast::NameOwner<'a> for StructDef<'a> {} 3834impl<'a> ast::NameOwner<'a> for StructDef<'a> {}
3746impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} 3835impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {}
3747impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} 3836impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {}
@@ -3902,6 +3991,7 @@ impl<R: TreeRoot<RaTypes>> TraitDefNode<R> {
3902} 3991}
3903 3992
3904 3993
3994impl<'a> ast::VisibilityOwner<'a> for TraitDef<'a> {}
3905impl<'a> ast::NameOwner<'a> for TraitDef<'a> {} 3995impl<'a> ast::NameOwner<'a> for TraitDef<'a> {}
3906impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {} 3996impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {}
3907impl<'a> ast::DocCommentsOwner<'a> for TraitDef<'a> {} 3997impl<'a> ast::DocCommentsOwner<'a> for TraitDef<'a> {}
@@ -4135,6 +4225,7 @@ impl<R: TreeRoot<RaTypes>> TypeDefNode<R> {
4135} 4225}
4136 4226
4137 4227
4228impl<'a> ast::VisibilityOwner<'a> for TypeDef<'a> {}
4138impl<'a> ast::NameOwner<'a> for TypeDef<'a> {} 4229impl<'a> ast::NameOwner<'a> for TypeDef<'a> {}
4139impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {} 4230impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {}
4140impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {} 4231impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {}
@@ -4409,6 +4500,43 @@ impl<'a> UseTreeList<'a> {
4409 } 4500 }
4410} 4501}
4411 4502
4503// Visibility
4504#[derive(Debug, Clone, Copy,)]
4505pub struct VisibilityNode<R: TreeRoot<RaTypes> = OwnedRoot> {
4506 pub(crate) syntax: SyntaxNode<R>,
4507}
4508pub type Visibility<'a> = VisibilityNode<RefRoot<'a>>;
4509
4510impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<VisibilityNode<R1>> for VisibilityNode<R2> {
4511 fn eq(&self, other: &VisibilityNode<R1>) -> bool { self.syntax == other.syntax }
4512}
4513impl<R: TreeRoot<RaTypes>> Eq for VisibilityNode<R> {}
4514impl<R: TreeRoot<RaTypes>> Hash for VisibilityNode<R> {
4515 fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
4516}
4517
4518impl<'a> AstNode<'a> for Visibility<'a> {
4519 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
4520 match syntax.kind() {
4521 VISIBILITY => Some(Visibility { syntax }),
4522 _ => None,
4523 }
4524 }
4525 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
4526}
4527
4528impl<R: TreeRoot<RaTypes>> VisibilityNode<R> {
4529 pub fn borrowed(&self) -> Visibility {
4530 VisibilityNode { syntax: self.syntax.borrowed() }
4531 }
4532 pub fn owned(&self) -> VisibilityNode {
4533 VisibilityNode { syntax: self.syntax.owned() }
4534 }
4535}
4536
4537
4538impl<'a> Visibility<'a> {}
4539
4412// WhereClause 4540// WhereClause
4413#[derive(Debug, Clone, Copy,)] 4541#[derive(Debug, Clone, Copy,)]
4414pub struct WhereClauseNode<R: TreeRoot<RaTypes> = OwnedRoot> { 4542pub struct WhereClauseNode<R: TreeRoot<RaTypes> = OwnedRoot> {
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index aab4839a9..c55e9e07a 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -128,7 +128,7 @@ Grammar(
128 "STATIC_DEF", 128 "STATIC_DEF",
129 "CONST_DEF", 129 "CONST_DEF",
130 "TRAIT_DEF", 130 "TRAIT_DEF",
131 "IMPL_ITEM", 131 "IMPL_BLOCK",
132 "TYPE_DEF", 132 "TYPE_DEF",
133 "MACRO_CALL", 133 "MACRO_CALL",
134 "TOKEN_TREE", 134 "TOKEN_TREE",
@@ -247,6 +247,7 @@ Grammar(
247 ), 247 ),
248 "FnDef": ( 248 "FnDef": (
249 traits: [ 249 traits: [
250 "VisibilityOwner",
250 "NameOwner", 251 "NameOwner",
251 "TypeParamsOwner", 252 "TypeParamsOwner",
252 "AttrsOwner", 253 "AttrsOwner",
@@ -257,6 +258,7 @@ Grammar(
257 "RetType": (options: ["TypeRef"]), 258 "RetType": (options: ["TypeRef"]),
258 "StructDef": ( 259 "StructDef": (
259 traits: [ 260 traits: [
261 "VisibilityOwner",
260 "NameOwner", 262 "NameOwner",
261 "TypeParamsOwner", 263 "TypeParamsOwner",
262 "AttrsOwner", 264 "AttrsOwner",
@@ -264,10 +266,11 @@ Grammar(
264 ] 266 ]
265 ), 267 ),
266 "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]), 268 "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]),
267 "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"], options: ["TypeRef"] ), 269 "NamedFieldDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner"], options: ["TypeRef"] ),
268 "PosFieldList": (collections: [["fields", "PosField"]]), 270 "PosFieldList": (collections: [["fields", "PosField"]]),
269 "PosField": ( traits: ["AttrsOwner"], options: ["TypeRef"]), 271 "PosField": ( traits: ["VisibilityOwner", "AttrsOwner"], options: ["TypeRef"]),
270 "EnumDef": ( traits: [ 272 "EnumDef": ( traits: [
273 "VisibilityOwner",
271 "NameOwner", 274 "NameOwner",
272 "TypeParamsOwner", 275 "TypeParamsOwner",
273 "AttrsOwner", 276 "AttrsOwner",
@@ -275,33 +278,37 @@ Grammar(
275 ], options: [["variant_list", "EnumVariantList"]] ), 278 ], options: [["variant_list", "EnumVariantList"]] ),
276 "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ), 279 "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ),
277 "EnumVariant": ( traits: ["NameOwner"], options: ["Expr"] ), 280 "EnumVariant": ( traits: ["NameOwner"], options: ["Expr"] ),
278 "TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ), 281 "TraitDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner"] ),
279 "Module": ( 282 "Module": (
280 traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ], 283 traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner" ],
281 options: [ "ItemList" ] 284 options: [ "ItemList" ]
282 ), 285 ),
283 "ItemList": ( 286 "ItemList": (
287 collections: [["impl_items", "ImplItem"]],
284 traits: [ "FnDefOwner", "ModuleItemOwner" ], 288 traits: [ "FnDefOwner", "ModuleItemOwner" ],
285 ), 289 ),
286 "ConstDef": ( traits: [ 290 "ConstDef": ( traits: [
291 "VisibilityOwner",
287 "NameOwner", 292 "NameOwner",
288 "TypeParamsOwner", 293 "TypeParamsOwner",
289 "AttrsOwner", 294 "AttrsOwner",
290 "DocCommentsOwner" 295 "DocCommentsOwner"
291 ] ), 296 ] ),
292 "StaticDef": ( traits: [ 297 "StaticDef": ( traits: [
298 "VisibilityOwner",
293 "NameOwner", 299 "NameOwner",
294 "TypeParamsOwner", 300 "TypeParamsOwner",
295 "AttrsOwner", 301 "AttrsOwner",
296 "DocCommentsOwner" 302 "DocCommentsOwner"
297 ] ), 303 ] ),
298 "TypeDef": ( traits: [ 304 "TypeDef": ( traits: [
305 "VisibilityOwner",
299 "NameOwner", 306 "NameOwner",
300 "TypeParamsOwner", 307 "TypeParamsOwner",
301 "AttrsOwner", 308 "AttrsOwner",
302 "DocCommentsOwner" 309 "DocCommentsOwner"
303 ] ), 310 ] ),
304 "ImplItem": (), 311 "ImplBlock": (options: ["ItemList"]),
305 312
306 "ParenType": (options: ["TypeRef"]), 313 "ParenType": (options: ["TypeRef"]),
307 "TupleType": ( collections: [["fields", "TypeRef"]] ), 314 "TupleType": ( collections: [["fields", "TypeRef"]] ),
@@ -342,9 +349,12 @@ Grammar(
342 ], 349 ],
343 ), 350 ),
344 "ModuleItem": ( 351 "ModuleItem": (
345 enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplItem", 352 enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplBlock",
346 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] 353 "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ]
347 ), 354 ),
355 "ImplItem": (
356 enum: ["FnDef", "TypeDef", "ConstDef"]
357 ),
348 358
349 "TupleExpr": (), 359 "TupleExpr": (),
350 "ArrayExpr": (), 360 "ArrayExpr": (),
@@ -482,6 +492,7 @@ Grammar(
482 ], 492 ],
483 ), 493 ),
484 494
495 "Visibility": (),
485 "Name": (), 496 "Name": (),
486 "NameRef": (), 497 "NameRef": (),
487 "MacroCall": ( options: [ "TokenTree", "Path" ] ), 498 "MacroCall": ( options: [ "TokenTree", "Path" ] ),
@@ -523,7 +534,8 @@ Grammar(
523 ["params", "Param"] 534 ["params", "Param"]
524 ] 535 ]
525 ), 536 ),
526 "SelfParam": (), 537 "SelfParam": (options: ["TypeRef", "SelfKw"]),
538 "SelfKw": (),
527 "Param": ( 539 "Param": (
528 options: [ "Pat", "TypeRef" ], 540 options: [ "Pat", "TypeRef" ],
529 ), 541 ),
diff --git a/crates/ra_syntax/src/grammar/items.rs b/crates/ra_syntax/src/grammar/items.rs
index aa5fe0777..265e84570 100644
--- a/crates/ra_syntax/src/grammar/items.rs
+++ b/crates/ra_syntax/src/grammar/items.rs
@@ -151,8 +151,8 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem {
151 // test unsafe_default_impl 151 // test unsafe_default_impl
152 // unsafe default impl Foo {} 152 // unsafe default impl Foo {}
153 IMPL_KW => { 153 IMPL_KW => {
154 traits::impl_item(p); 154 traits::impl_block(p);
155 IMPL_ITEM 155 IMPL_BLOCK
156 } 156 }
157 _ => { 157 _ => {
158 return if has_mods { 158 return if has_mods {
diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs
index d4da8b2f7..0a0621753 100644
--- a/crates/ra_syntax/src/grammar/items/traits.rs
+++ b/crates/ra_syntax/src/grammar/items/traits.rs
@@ -40,9 +40,9 @@ pub(crate) fn trait_item_list(p: &mut Parser) {
40 m.complete(p, ITEM_LIST); 40 m.complete(p, ITEM_LIST);
41} 41}
42 42
43// test impl_item 43// test impl_block
44// impl Foo {} 44// impl Foo {}
45pub(super) fn impl_item(p: &mut Parser) { 45pub(super) fn impl_block(p: &mut Parser) {
46 assert!(p.at(IMPL_KW)); 46 assert!(p.at(IMPL_KW));
47 p.bump(); 47 p.bump();
48 if choose_type_params_over_qpath(p) { 48 if choose_type_params_over_qpath(p) {
@@ -52,7 +52,7 @@ pub(super) fn impl_item(p: &mut Parser) {
52 // TODO: never type 52 // TODO: never type
53 // impl ! {} 53 // impl ! {}
54 54
55 // test impl_item_neg 55 // test impl_block_neg
56 // impl !Send for X {} 56 // impl !Send for X {}
57 p.eat(EXCL); 57 p.eat(EXCL);
58 impl_type(p); 58 impl_type(p);
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs
index 02421def1..3487aef85 100644
--- a/crates/ra_syntax/src/parser_api.rs
+++ b/crates/ra_syntax/src/parser_api.rs
@@ -61,7 +61,7 @@ impl<'t> Parser<'t> {
61 Marker::new(self.0.start()) 61 Marker::new(self.0.start())
62 } 62 }
63 63
64 /// Advances the parser by one token. 64 /// Advances the parser by one token unconditionally.
65 pub(crate) fn bump(&mut self) { 65 pub(crate) fn bump(&mut self) {
66 self.0.bump(); 66 self.0.bump();
67 } 67 }
@@ -91,7 +91,7 @@ impl<'t> Parser<'t> {
91 self.0.error(message.into()) 91 self.0.error(message.into())
92 } 92 }
93 93
94 /// Consume the next token if it is `kind`. 94 /// Consume the next token if `kind` matches.
95 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool { 95 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
96 if !self.at(kind) { 96 if !self.at(kind) {
97 return false; 97 return false;
@@ -142,11 +142,13 @@ impl Marker {
142 } 142 }
143 } 143 }
144 144
145 /// Finishes the syntax tree node and assigns `kind` to it. 145 /// Finishes the syntax tree node and assigns `kind` to it,
146 /// and mark the create a `CompletedMarker` for possible future
147 /// operation like `.precede()` to deal with forward_parent.
146 pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { 148 pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
147 self.bomb.defuse(); 149 self.bomb.defuse();
148 p.0.complete(self.pos, kind); 150 p.0.complete(self.pos, kind);
149 CompletedMarker(self.pos, kind) 151 CompletedMarker::new(self.pos, kind)
150 } 152 }
151 153
152 /// Abandons the syntax tree node. All its children 154 /// Abandons the syntax tree node. All its children
@@ -160,13 +162,22 @@ impl Marker {
160pub(crate) struct CompletedMarker(u32, SyntaxKind); 162pub(crate) struct CompletedMarker(u32, SyntaxKind);
161 163
162impl CompletedMarker { 164impl CompletedMarker {
163 /// This one is tricky :-) 165 fn new(pos: u32, kind: SyntaxKind) -> Self {
166 CompletedMarker(pos, kind)
167 }
168
164 /// This method allows to create a new node which starts 169 /// This method allows to create a new node which starts
165 /// *before* the current one. That is, parser could start 170 /// *before* the current one. That is, parser could start
166 /// node `A`, then complete it, and then after parsing the 171 /// node `A`, then complete it, and then after parsing the
167 /// whole `A`, decide that it should have started some node 172 /// whole `A`, decide that it should have started some node
168 /// `B` before starting `A`. `precede` allows to do exactly 173 /// `B` before starting `A`. `precede` allows to do exactly
169 /// that. See also docs about `forward_parent` in `Event::Start`. 174 /// that. See also docs about `forward_parent` in `Event::Start`.
175 ///
176 /// Given completed events `[START, FINISH]` and its corresponding
177 /// `CompletedMarker(pos: 0, _)`.
178 /// Append a new `START` events as `[START, FINISH, NEWSTART]`,
179 /// then mark `NEWSTART` as `START`'s parent with saving its relative
180 /// distance to `NEWSTART` into forward_parent(=2 in this case);
170 pub(crate) fn precede(self, p: &mut Parser) -> Marker { 181 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
171 Marker::new(p.0.precede(self.0)) 182 Marker::new(p.0.precede(self.0))
172 } 183 }
diff --git a/crates/ra_syntax/src/parser_impl.rs b/crates/ra_syntax/src/parser_impl.rs
index cb6e370ac..01a51cd8d 100644
--- a/crates/ra_syntax/src/parser_impl.rs
+++ b/crates/ra_syntax/src/parser_impl.rs
@@ -22,10 +22,21 @@ use crate::SyntaxKind::{self, EOF, TOMBSTONE};
22pub(crate) trait Sink { 22pub(crate) trait Sink {
23 type Tree; 23 type Tree;
24 24
25 /// Adds new leaf to the current branch.
25 fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); 26 fn leaf(&mut self, kind: SyntaxKind, text: SmolStr);
26 fn start_internal(&mut self, kind: SyntaxKind); 27
27 fn finish_internal(&mut self); 28 /// Start new branch and make it current.
29 fn start_branch(&mut self, kind: SyntaxKind);
30
31 /// Finish current branch and restore previous
32 /// branch as current.
33 fn finish_branch(&mut self);
34
28 fn error(&mut self, error: SyntaxError); 35 fn error(&mut self, error: SyntaxError);
36
37 /// Complete tree building. Make sure that
38 /// `start_branch` and `finish_branch` calls
39 /// are paired!
29 fn finish(self) -> Self::Tree; 40 fn finish(self) -> Self::Tree;
30} 41}
31 42
@@ -52,8 +63,7 @@ pub(crate) fn parse_with<S: Sink>(
52/// to a separate struct in order not to pollute 63/// to a separate struct in order not to pollute
53/// the public API of the `Parser`. 64/// the public API of the `Parser`.
54pub(crate) struct ParserImpl<'t> { 65pub(crate) struct ParserImpl<'t> {
55 inp: &'t ParserInput<'t>, 66 parser_input: &'t ParserInput<'t>,
56
57 pos: InputPosition, 67 pos: InputPosition,
58 events: Vec<Event>, 68 events: Vec<Event>,
59 steps: Cell<u32>, 69 steps: Cell<u32>,
@@ -62,8 +72,7 @@ pub(crate) struct ParserImpl<'t> {
62impl<'t> ParserImpl<'t> { 72impl<'t> ParserImpl<'t> {
63 pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> { 73 pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> {
64 ParserImpl { 74 ParserImpl {
65 inp, 75 parser_input: inp,
66
67 pos: InputPosition::new(), 76 pos: InputPosition::new(),
68 events: Vec::new(), 77 events: Vec::new(),
69 steps: Cell::new(0), 78 steps: Cell::new(0),
@@ -76,9 +85,11 @@ impl<'t> ParserImpl<'t> {
76 } 85 }
77 86
78 pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> { 87 pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
79 let c1 = self.inp.kind(self.pos); 88 let c1 = self.parser_input.kind(self.pos);
80 let c2 = self.inp.kind(self.pos + 1); 89 let c2 = self.parser_input.kind(self.pos + 1);
81 if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) { 90 if self.parser_input.token_start_at(self.pos + 1)
91 == self.parser_input.token_start_at(self.pos) + self.parser_input.token_len(self.pos)
92 {
82 Some((c1, c2)) 93 Some((c1, c2))
83 } else { 94 } else {
84 None 95 None
@@ -86,12 +97,14 @@ impl<'t> ParserImpl<'t> {
86 } 97 }
87 98
88 pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { 99 pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
89 let c1 = self.inp.kind(self.pos); 100 let c1 = self.parser_input.kind(self.pos);
90 let c2 = self.inp.kind(self.pos + 1); 101 let c2 = self.parser_input.kind(self.pos + 1);
91 let c3 = self.inp.kind(self.pos + 2); 102 let c3 = self.parser_input.kind(self.pos + 2);
92 if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) 103 if self.parser_input.token_start_at(self.pos + 1)
93 && self.inp.start(self.pos + 2) 104 == self.parser_input.token_start_at(self.pos) + self.parser_input.token_len(self.pos)
94 == self.inp.start(self.pos + 1) + self.inp.len(self.pos + 1) 105 && self.parser_input.token_start_at(self.pos + 2)
106 == self.parser_input.token_start_at(self.pos + 1)
107 + self.parser_input.token_len(self.pos + 1)
95 { 108 {
96 Some((c1, c2, c3)) 109 Some((c1, c2, c3))
97 } else { 110 } else {
@@ -99,29 +112,27 @@ impl<'t> ParserImpl<'t> {
99 } 112 }
100 } 113 }
101 114
115 /// Get the syntax kind of the nth token.
102 pub(super) fn nth(&self, n: u32) -> SyntaxKind { 116 pub(super) fn nth(&self, n: u32) -> SyntaxKind {
103 let steps = self.steps.get(); 117 let steps = self.steps.get();
104 if steps > 10_000_000 { 118 assert!(steps <= 10_000_000, "the parser seems stuck");
105 panic!("the parser seems stuck");
106 }
107 self.steps.set(steps + 1); 119 self.steps.set(steps + 1);
108 120
109 self.inp.kind(self.pos + n) 121 self.parser_input.kind(self.pos + n)
110 } 122 }
111 123
112 pub(super) fn at_kw(&self, t: &str) -> bool { 124 pub(super) fn at_kw(&self, t: &str) -> bool {
113 self.inp.text(self.pos) == t 125 self.parser_input.token_text(self.pos) == t
114 } 126 }
115 127
128 /// Start parsing right behind the last event.
116 pub(super) fn start(&mut self) -> u32 { 129 pub(super) fn start(&mut self) -> u32 {
117 let pos = self.events.len() as u32; 130 let pos = self.events.len() as u32;
118 self.event(Event::Start { 131 self.push_event(Event::tombstone());
119 kind: TOMBSTONE,
120 forward_parent: None,
121 });
122 pos 132 pos
123 } 133 }
124 134
135 /// Advances the parser by one token unconditionally.
125 pub(super) fn bump(&mut self) { 136 pub(super) fn bump(&mut self) {
126 let kind = self.nth(0); 137 let kind = self.nth(0);
127 if kind == EOF { 138 if kind == EOF {
@@ -144,15 +155,17 @@ impl<'t> ParserImpl<'t> {
144 155
145 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { 156 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
146 self.pos += u32::from(n_raw_tokens); 157 self.pos += u32::from(n_raw_tokens);
147 self.event(Event::Token { kind, n_raw_tokens }); 158 self.push_event(Event::Token { kind, n_raw_tokens });
148 } 159 }
149 160
161 /// Append one Error event to the back of events.
150 pub(super) fn error(&mut self, msg: String) { 162 pub(super) fn error(&mut self, msg: String) {
151 self.event(Event::Error { 163 self.push_event(Event::Error {
152 msg: ParseError(msg), 164 msg: ParseError(msg),
153 }) 165 })
154 } 166 }
155 167
168 /// Complete an event with appending a `Finish` event.
156 pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { 169 pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) {
157 match self.events[pos as usize] { 170 match self.events[pos as usize] {
158 Event::Start { 171 Event::Start {
@@ -162,9 +175,10 @@ impl<'t> ParserImpl<'t> {
162 } 175 }
163 _ => unreachable!(), 176 _ => unreachable!(),
164 } 177 }
165 self.event(Event::Finish); 178 self.push_event(Event::Finish);
166 } 179 }
167 180
181 /// Ignore the dummy `Start` event.
168 pub(super) fn abandon(&mut self, pos: u32) { 182 pub(super) fn abandon(&mut self, pos: u32) {
169 let idx = pos as usize; 183 let idx = pos as usize;
170 if idx == self.events.len() - 1 { 184 if idx == self.events.len() - 1 {
@@ -178,6 +192,7 @@ impl<'t> ParserImpl<'t> {
178 } 192 }
179 } 193 }
180 194
195 /// Save the relative distance of a completed event to its forward_parent.
181 pub(super) fn precede(&mut self, pos: u32) -> u32 { 196 pub(super) fn precede(&mut self, pos: u32) -> u32 {
182 let new_pos = self.start(); 197 let new_pos = self.start();
183 match self.events[pos as usize] { 198 match self.events[pos as usize] {
@@ -192,7 +207,7 @@ impl<'t> ParserImpl<'t> {
192 new_pos 207 new_pos
193 } 208 }
194 209
195 fn event(&mut self, event: Event) { 210 fn push_event(&mut self, event: Event) {
196 self.events.push(event) 211 self.events.push(event)
197 } 212 }
198} 213}
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs
index 3d8b062d5..73dd6e02b 100644
--- a/crates/ra_syntax/src/parser_impl/event.rs
+++ b/crates/ra_syntax/src/parser_impl/event.rs
@@ -36,7 +36,7 @@ pub(crate) enum Event {
36 /// 36 ///
37 /// For left-recursive syntactic constructs, the parser produces 37 /// For left-recursive syntactic constructs, the parser produces
38 /// a child node before it sees a parent. `forward_parent` 38 /// a child node before it sees a parent. `forward_parent`
39 /// exists to allow to tweak parent-child relationships. 39 /// saves the position of current event's parent.
40 /// 40 ///
41 /// Consider this path 41 /// Consider this path
42 /// 42 ///
@@ -84,6 +84,15 @@ pub(crate) enum Event {
84 }, 84 },
85} 85}
86 86
87impl Event {
88 pub(crate) fn tombstone() -> Self {
89 Event::Start {
90 kind: TOMBSTONE,
91 forward_parent: None,
92 }
93 }
94}
95
87pub(super) struct EventProcessor<'a, S: Sink> { 96pub(super) struct EventProcessor<'a, S: Sink> {
88 sink: S, 97 sink: S,
89 text_pos: TextUnit, 98 text_pos: TextUnit,
@@ -110,17 +119,12 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
110 } 119 }
111 } 120 }
112 121
122 /// Generate the syntax tree with the control of events.
113 pub(super) fn process(mut self) -> S { 123 pub(super) fn process(mut self) -> S {
114 fn tombstone() -> Event {
115 Event::Start {
116 kind: TOMBSTONE,
117 forward_parent: None,
118 }
119 }
120 let mut forward_parents = Vec::new(); 124 let mut forward_parents = Vec::new();
121 125
122 for i in 0..self.events.len() { 126 for i in 0..self.events.len() {
123 match mem::replace(&mut self.events[i], tombstone()) { 127 match mem::replace(&mut self.events[i], Event::tombstone()) {
124 Event::Start { 128 Event::Start {
125 kind: TOMBSTONE, .. 129 kind: TOMBSTONE, ..
126 } => (), 130 } => (),
@@ -129,12 +133,18 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
129 kind, 133 kind,
130 forward_parent, 134 forward_parent,
131 } => { 135 } => {
136 // For events[A, B, C], B is A's forward_parent, C is B's forward_parent,
137 // in the normal control flow, the parent-child relation: `A -> B -> C`,
138 // while with the magic forward_parent, it writes: `C <- B <- A`.
139
140 // append `A` into parents.
132 forward_parents.push(kind); 141 forward_parents.push(kind);
133 let mut idx = i; 142 let mut idx = i;
134 let mut fp = forward_parent; 143 let mut fp = forward_parent;
135 while let Some(fwd) = fp { 144 while let Some(fwd) = fp {
136 idx += fwd as usize; 145 idx += fwd as usize;
137 fp = match mem::replace(&mut self.events[idx], tombstone()) { 146 // append `A`'s forward_parent `B`
147 fp = match mem::replace(&mut self.events[idx], Event::tombstone()) {
138 Event::Start { 148 Event::Start {
139 kind, 149 kind,
140 forward_parent, 150 forward_parent,
@@ -144,17 +154,19 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
144 } 154 }
145 _ => unreachable!(), 155 _ => unreachable!(),
146 }; 156 };
157 // append `B`'s forward_parent `C` in the next stage.
147 } 158 }
159
148 for kind in forward_parents.drain(..).rev() { 160 for kind in forward_parents.drain(..).rev() {
149 self.start(kind); 161 self.start(kind);
150 } 162 }
151 } 163 }
152 Event::Finish => { 164 Event::Finish => {
153 let last = i == self.events.len() - 1; 165 let is_last = i == self.events.len() - 1;
154 self.finish(last); 166 self.finish(is_last);
155 } 167 }
156 Event::Token { kind, n_raw_tokens } => { 168 Event::Token { kind, n_raw_tokens } => {
157 self.eat_ws(); 169 self.eat_trivias();
158 let n_raw_tokens = n_raw_tokens as usize; 170 let n_raw_tokens = n_raw_tokens as usize;
159 let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens] 171 let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens]
160 .iter() 172 .iter()
@@ -171,9 +183,10 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
171 self.sink 183 self.sink
172 } 184 }
173 185
186 /// Add the node into syntax tree but discard the comments/whitespaces.
174 fn start(&mut self, kind: SyntaxKind) { 187 fn start(&mut self, kind: SyntaxKind) {
175 if kind == SOURCE_FILE { 188 if kind == SOURCE_FILE {
176 self.sink.start_internal(kind); 189 self.sink.start_branch(kind);
177 return; 190 return;
178 } 191 }
179 let n_trivias = self.tokens[self.token_pos..] 192 let n_trivias = self.tokens[self.token_pos..]
@@ -194,18 +207,18 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
194 n_attached_trivias(kind, leading_trivias) 207 n_attached_trivias(kind, leading_trivias)
195 }; 208 };
196 self.eat_n_trivias(n_trivias - n_attached_trivias); 209 self.eat_n_trivias(n_trivias - n_attached_trivias);
197 self.sink.start_internal(kind); 210 self.sink.start_branch(kind);
198 self.eat_n_trivias(n_attached_trivias); 211 self.eat_n_trivias(n_attached_trivias);
199 } 212 }
200 213
201 fn finish(&mut self, last: bool) { 214 fn finish(&mut self, is_last: bool) {
202 if last { 215 if is_last {
203 self.eat_ws() 216 self.eat_trivias()
204 } 217 }
205 self.sink.finish_internal(); 218 self.sink.finish_branch();
206 } 219 }
207 220
208 fn eat_ws(&mut self) { 221 fn eat_trivias(&mut self) {
209 while let Some(&token) = self.tokens.get(self.token_pos) { 222 while let Some(&token) = self.tokens.get(self.token_pos) {
210 if !token.kind.is_trivia() { 223 if !token.kind.is_trivia() {
211 break; 224 break;
@@ -236,7 +249,7 @@ fn n_attached_trivias<'a>(
236 trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, 249 trivias: impl Iterator<Item = (SyntaxKind, &'a str)>,
237) -> usize { 250) -> usize {
238 match kind { 251 match kind {
239 STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => { 252 CONST_DEF | TYPE_DEF | STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => {
240 let mut res = 0; 253 let mut res = 0;
241 for (i, (kind, text)) in trivias.enumerate() { 254 for (i, (kind, text)) in trivias.enumerate() {
242 match kind { 255 match kind {
diff --git a/crates/ra_syntax/src/parser_impl/input.rs b/crates/ra_syntax/src/parser_impl/input.rs
index ac6d900d8..7fde5b3ab 100644
--- a/crates/ra_syntax/src/parser_impl/input.rs
+++ b/crates/ra_syntax/src/parser_impl/input.rs
@@ -4,11 +4,26 @@ use std::ops::{Add, AddAssign};
4 4
5pub(crate) struct ParserInput<'t> { 5pub(crate) struct ParserInput<'t> {
6 text: &'t str, 6 text: &'t str,
7 /// start position of each token(expect whitespace and comment)
8 /// ```non-rust
9 /// struct Foo;
10 /// ^------^---
11 /// | | ^-
12 /// 0 7 10
13 /// ```
14 /// (token, start_offset): `[(struct, 0), (Foo, 7), (;, 10)]`
7 start_offsets: Vec<TextUnit>, 15 start_offsets: Vec<TextUnit>,
8 tokens: Vec<Token>, // non-whitespace tokens 16 /// non-whitespace/comment tokens
17 /// ```non-rust
18 /// struct Foo {}
19 /// ^^^^^^ ^^^ ^^
20 /// ```
21 /// tokens: `[struct, Foo, {, }]`
22 tokens: Vec<Token>,
9} 23}
10 24
11impl<'t> ParserInput<'t> { 25impl<'t> ParserInput<'t> {
26 /// Generate input from tokens(expect comment and whitespace).
12 pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> ParserInput<'t> { 27 pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> ParserInput<'t> {
13 let mut tokens = Vec::new(); 28 let mut tokens = Vec::new();
14 let mut start_offsets = Vec::new(); 29 let mut start_offsets = Vec::new();
@@ -28,6 +43,7 @@ impl<'t> ParserInput<'t> {
28 } 43 }
29 } 44 }
30 45
46 /// Get the syntax kind of token at given input position.
31 pub fn kind(&self, pos: InputPosition) -> SyntaxKind { 47 pub fn kind(&self, pos: InputPosition) -> SyntaxKind {
32 let idx = pos.0 as usize; 48 let idx = pos.0 as usize;
33 if !(idx < self.tokens.len()) { 49 if !(idx < self.tokens.len()) {
@@ -36,7 +52,8 @@ impl<'t> ParserInput<'t> {
36 self.tokens[idx].kind 52 self.tokens[idx].kind
37 } 53 }
38 54
39 pub fn len(&self, pos: InputPosition) -> TextUnit { 55 /// Get the length of a token at given input position.
56 pub fn token_len(&self, pos: InputPosition) -> TextUnit {
40 let idx = pos.0 as usize; 57 let idx = pos.0 as usize;
41 if !(idx < self.tokens.len()) { 58 if !(idx < self.tokens.len()) {
42 return 0.into(); 59 return 0.into();
@@ -44,7 +61,8 @@ impl<'t> ParserInput<'t> {
44 self.tokens[idx].len 61 self.tokens[idx].len
45 } 62 }
46 63
47 pub fn start(&self, pos: InputPosition) -> TextUnit { 64 /// Get the start position of a taken at given input position.
65 pub fn token_start_at(&self, pos: InputPosition) -> TextUnit {
48 let idx = pos.0 as usize; 66 let idx = pos.0 as usize;
49 if !(idx < self.tokens.len()) { 67 if !(idx < self.tokens.len()) {
50 return 0.into(); 68 return 0.into();
@@ -52,7 +70,8 @@ impl<'t> ParserInput<'t> {
52 self.start_offsets[idx] 70 self.start_offsets[idx]
53 } 71 }
54 72
55 pub fn text(&self, pos: InputPosition) -> &'t str { 73 /// Get the raw text of a token at given input position.
74 pub fn token_text(&self, pos: InputPosition) -> &'t str {
56 let idx = pos.0 as usize; 75 let idx = pos.0 as usize;
57 if !(idx < self.tokens.len()) { 76 if !(idx < self.tokens.len()) {
58 return ""; 77 return "";
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs
index 208cae5c8..7ee71a1b6 100644
--- a/crates/ra_syntax/src/reparsing.rs
+++ b/crates/ra_syntax/src/reparsing.rs
@@ -100,7 +100,7 @@ fn find_reparsable_node(
100 ITEM_LIST => { 100 ITEM_LIST => {
101 let parent = node.parent().unwrap(); 101 let parent = node.parent().unwrap();
102 match parent.kind() { 102 match parent.kind() {
103 IMPL_ITEM => grammar::impl_item_list, 103 IMPL_BLOCK => grammar::impl_item_list,
104 TRAIT_DEF => grammar::trait_item_list, 104 TRAIT_DEF => grammar::trait_item_list,
105 MODULE => grammar::mod_item_list, 105 MODULE => grammar::mod_item_list,
106 _ => return None, 106 _ => return None,
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs
index 3a869ad34..ef4588d93 100644
--- a/crates/ra_syntax/src/syntax_kinds/generated.rs
+++ b/crates/ra_syntax/src/syntax_kinds/generated.rs
@@ -128,7 +128,7 @@ pub enum SyntaxKind {
128 STATIC_DEF, 128 STATIC_DEF,
129 CONST_DEF, 129 CONST_DEF,
130 TRAIT_DEF, 130 TRAIT_DEF,
131 IMPL_ITEM, 131 IMPL_BLOCK,
132 TYPE_DEF, 132 TYPE_DEF,
133 MACRO_CALL, 133 MACRO_CALL,
134 TOKEN_TREE, 134 TOKEN_TREE,
@@ -389,7 +389,7 @@ impl SyntaxKind {
389 STATIC_DEF => &SyntaxInfo { name: "STATIC_DEF" }, 389 STATIC_DEF => &SyntaxInfo { name: "STATIC_DEF" },
390 CONST_DEF => &SyntaxInfo { name: "CONST_DEF" }, 390 CONST_DEF => &SyntaxInfo { name: "CONST_DEF" },
391 TRAIT_DEF => &SyntaxInfo { name: "TRAIT_DEF" }, 391 TRAIT_DEF => &SyntaxInfo { name: "TRAIT_DEF" },
392 IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, 392 IMPL_BLOCK => &SyntaxInfo { name: "IMPL_BLOCK" },
393 TYPE_DEF => &SyntaxInfo { name: "TYPE_DEF" }, 393 TYPE_DEF => &SyntaxInfo { name: "TYPE_DEF" },
394 MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" }, 394 MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" },
395 TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" }, 395 TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" },
diff --git a/crates/ra_syntax/src/yellow/builder.rs b/crates/ra_syntax/src/yellow/builder.rs
index 9fcebfb93..37ae6329b 100644
--- a/crates/ra_syntax/src/yellow/builder.rs
+++ b/crates/ra_syntax/src/yellow/builder.rs
@@ -26,11 +26,11 @@ impl Sink for GreenBuilder {
26 self.inner.leaf(kind, text); 26 self.inner.leaf(kind, text);
27 } 27 }
28 28
29 fn start_internal(&mut self, kind: SyntaxKind) { 29 fn start_branch(&mut self, kind: SyntaxKind) {
30 self.inner.start_internal(kind) 30 self.inner.start_internal(kind)
31 } 31 }
32 32
33 fn finish_internal(&mut self) { 33 fn finish_branch(&mut self) {
34 self.inner.finish_internal(); 34 self.inner.finish_internal();
35 } 35 }
36 36
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs
index 46bde9a08..279a83b61 100644
--- a/crates/ra_syntax/src/yellow/syntax_text.rs
+++ b/crates/ra_syntax/src/yellow/syntax_text.rs
@@ -119,3 +119,27 @@ impl SyntaxTextSlice for ops::Range<TextUnit> {
119 TextRange::from_to(self.start, self.end).restrict(range) 119 TextRange::from_to(self.start, self.end).restrict(range)
120 } 120 }
121} 121}
122
123impl From<SyntaxText<'_>> for String {
124 fn from(text: SyntaxText) -> String {
125 text.to_string()
126 }
127}
128
129impl PartialEq<str> for SyntaxText<'_> {
130 fn eq(&self, mut rhs: &str) -> bool {
131 for chunk in self.chunks() {
132 if !rhs.starts_with(chunk) {
133 return false;
134 }
135 rhs = &rhs[chunk.len()..];
136 }
137 rhs.is_empty()
138 }
139}
140
141impl PartialEq<&'_ str> for SyntaxText<'_> {
142 fn eq(&self, rhs: &&str) -> bool {
143 self == *rhs
144 }
145}
diff --git a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
index 3937be255..262cbba1e 100644
--- a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 183) 1SOURCE_FILE@[0; 183)
2 IMPL_ITEM@[0; 182) 2 IMPL_BLOCK@[0; 182)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 13) 5 PATH_TYPE@[5; 13)
diff --git a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
index 55999c160..da3894133 100644
--- a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt
@@ -94,7 +94,7 @@ SOURCE_FILE@[0; 112)
94 COMMA@[54; 55) 94 COMMA@[54; 55)
95 err: `expected SEMI` 95 err: `expected SEMI`
96 WHITESPACE@[55; 56) 96 WHITESPACE@[55; 56)
97 IMPL_ITEM@[56; 60) 97 IMPL_BLOCK@[56; 60)
98 IMPL_KW@[56; 60) 98 IMPL_KW@[56; 60)
99 err: `expected type` 99 err: `expected type`
100 err: `expected `{`` 100 err: `expected `{``
diff --git a/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt
index 82683f6ee..9b5fadcf7 100644
--- a/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt
+++ b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 38) 1SOURCE_FILE@[0; 38)
2 IMPL_ITEM@[0; 14) 2 IMPL_BLOCK@[0; 14)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 TYPE_PARAM_LIST@[4; 14) 4 TYPE_PARAM_LIST@[4; 14)
5 L_ANGLE@[4; 5) 5 L_ANGLE@[4; 5)
@@ -17,7 +17,7 @@ SOURCE_FILE@[0; 38)
17 err: `expected trait or type` 17 err: `expected trait or type`
18 err: `expected `{`` 18 err: `expected `{``
19 WHITESPACE@[14; 15) 19 WHITESPACE@[14; 15)
20 IMPL_ITEM@[15; 37) 20 IMPL_BLOCK@[15; 37)
21 IMPL_KW@[15; 19) 21 IMPL_KW@[15; 19)
22 TYPE_PARAM_LIST@[19; 22) 22 TYPE_PARAM_LIST@[19; 22)
23 L_ANGLE@[19; 20) 23 L_ANGLE@[19; 20)
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt b/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt
index 75533ecc1..8021aee00 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0002_misplaced_label_err.txt
@@ -19,7 +19,7 @@ SOURCE_FILE@[0; 30)
19 err: `expected a loop` 19 err: `expected a loop`
20 err: `expected SEMI` 20 err: `expected SEMI`
21 WHITESPACE@[22; 23) 21 WHITESPACE@[22; 23)
22 IMPL_ITEM@[23; 27) 22 IMPL_BLOCK@[23; 27)
23 IMPL_KW@[23; 27) 23 IMPL_KW@[23; 27)
24 err: `expected type` 24 err: `expected type`
25 err: `expected `{`` 25 err: `expected `{``
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt b/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt
index 7279d5cae..6875ed016 100644
--- a/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0004_impl_type.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 87) 1SOURCE_FILE@[0; 87)
2 IMPL_ITEM@[0; 12) 2 IMPL_BLOCK@[0; 12)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 9) 5 PATH_TYPE@[5; 9)
@@ -12,7 +12,7 @@ SOURCE_FILE@[0; 87)
12 L_CURLY@[10; 11) 12 L_CURLY@[10; 11)
13 R_CURLY@[11; 12) 13 R_CURLY@[11; 12)
14 WHITESPACE@[12; 13) 14 WHITESPACE@[12; 13)
15 IMPL_ITEM@[13; 33) 15 IMPL_BLOCK@[13; 33)
16 IMPL_KW@[13; 17) 16 IMPL_KW@[13; 17)
17 WHITESPACE@[17; 18) 17 WHITESPACE@[17; 18)
18 PATH_TYPE@[18; 24) 18 PATH_TYPE@[18; 24)
@@ -33,12 +33,12 @@ SOURCE_FILE@[0; 87)
33 L_CURLY@[31; 32) 33 L_CURLY@[31; 32)
34 R_CURLY@[32; 33) 34 R_CURLY@[32; 33)
35 WHITESPACE@[33; 34) 35 WHITESPACE@[33; 34)
36 IMPL_ITEM@[34; 38) 36 IMPL_BLOCK@[34; 38)
37 IMPL_KW@[34; 38) 37 IMPL_KW@[34; 38)
38 err: `expected trait or type` 38 err: `expected trait or type`
39 err: `expected `{`` 39 err: `expected `{``
40 WHITESPACE@[38; 39) 40 WHITESPACE@[38; 39)
41 IMPL_ITEM@[39; 54) 41 IMPL_BLOCK@[39; 54)
42 IMPL_KW@[39; 43) 42 IMPL_KW@[39; 43)
43 WHITESPACE@[43; 44) 43 WHITESPACE@[43; 44)
44 PATH_TYPE@[44; 51) 44 PATH_TYPE@[44; 51)
@@ -51,7 +51,7 @@ SOURCE_FILE@[0; 87)
51 L_CURLY@[52; 53) 51 L_CURLY@[52; 53)
52 R_CURLY@[53; 54) 52 R_CURLY@[53; 54)
53 WHITESPACE@[54; 55) 53 WHITESPACE@[54; 55)
54 IMPL_ITEM@[55; 70) 54 IMPL_BLOCK@[55; 70)
55 IMPL_KW@[55; 59) 55 IMPL_KW@[55; 59)
56 WHITESPACE@[59; 60) 56 WHITESPACE@[59; 60)
57 PATH_TYPE@[60; 66) 57 PATH_TYPE@[60; 66)
@@ -64,7 +64,7 @@ SOURCE_FILE@[0; 87)
64 err: `expected trait or type` 64 err: `expected trait or type`
65 err: `expected `{`` 65 err: `expected `{``
66 WHITESPACE@[70; 71) 66 WHITESPACE@[70; 71)
67 IMPL_ITEM@[71; 86) 67 IMPL_BLOCK@[71; 86)
68 IMPL_KW@[71; 75) 68 IMPL_KW@[71; 75)
69 WHITESPACE@[75; 76) 69 WHITESPACE@[75; 76)
70 PATH_TYPE@[76; 83) 70 PATH_TYPE@[76; 83)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0001_trait_item_list.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0001_trait_item_list.txt
index 998ac3da9..de7df7312 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0001_trait_item_list.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0001_trait_item_list.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 83) 1SOURCE_FILE@[0; 83)
2 IMPL_ITEM@[0; 82) 2 IMPL_BLOCK@[0; 82)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6) 5 PATH_TYPE@[5; 6)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0006_self_param.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0006_self_param.txt
index 53027c852..4df01c6e5 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0006_self_param.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0006_self_param.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 128) 1SOURCE_FILE@[0; 128)
2 IMPL_ITEM@[0; 127) 2 IMPL_BLOCK@[0; 127)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6) 5 PATH_TYPE@[5; 6)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0018_arb_self_types.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0018_arb_self_types.txt
index b2f04ea7b..03139f7a4 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0018_arb_self_types.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0018_arb_self_types.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 69) 1SOURCE_FILE@[0; 69)
2 IMPL_ITEM@[0; 68) 2 IMPL_BLOCK@[0; 68)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6) 5 PATH_TYPE@[5; 6)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0021_impl_item_list.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0021_impl_item_list.txt
index b15f93cd2..50426bdfe 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0021_impl_item_list.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0021_impl_item_list.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 89) 1SOURCE_FILE@[0; 89)
2 IMPL_ITEM@[0; 88) 2 IMPL_BLOCK@[0; 88)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 6) 5 PATH_TYPE@[5; 6)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0047_unsafe_default_impl.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0047_unsafe_default_impl.txt
index 6003ba645..5d68e88d6 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0047_unsafe_default_impl.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0047_unsafe_default_impl.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 27) 1SOURCE_FILE@[0; 27)
2 IMPL_ITEM@[0; 26) 2 IMPL_BLOCK@[0; 26)
3 UNSAFE_KW@[0; 6) 3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7) 4 WHITESPACE@[6; 7)
5 DEFAULT_KW@[7; 14) 5 DEFAULT_KW@[7; 14)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_item_neg.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_block_neg.rs
index b7527c870..b7527c870 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_item_neg.rs
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_block_neg.rs
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_item_neg.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_block_neg.txt
index b83db380e..563e43508 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_item_neg.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0063_impl_block_neg.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 20) 1SOURCE_FILE@[0; 20)
2 IMPL_ITEM@[0; 19) 2 IMPL_BLOCK@[0; 19)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 EXCL@[5; 6) 5 EXCL@[5; 6)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_item.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_block.rs
index d6337f6b3..d6337f6b3 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_item.rs
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_block.rs
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_item.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_block.txt
index 1b9a8aa0e..a2c218aa9 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_item.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0079_impl_block.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 12) 1SOURCE_FILE@[0; 12)
2 IMPL_ITEM@[0; 11) 2 IMPL_BLOCK@[0; 11)
3 IMPL_KW@[0; 4) 3 IMPL_KW@[0; 4)
4 WHITESPACE@[4; 5) 4 WHITESPACE@[4; 5)
5 PATH_TYPE@[5; 8) 5 PATH_TYPE@[5; 8)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0087_unsafe_impl.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0087_unsafe_impl.txt
index f9c96c242..d93c0df4d 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0087_unsafe_impl.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0087_unsafe_impl.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 19) 1SOURCE_FILE@[0; 19)
2 IMPL_ITEM@[0; 18) 2 IMPL_BLOCK@[0; 18)
3 UNSAFE_KW@[0; 6) 3 UNSAFE_KW@[0; 6)
4 WHITESPACE@[6; 7) 4 WHITESPACE@[6; 7)
5 IMPL_KW@[7; 11) 5 IMPL_KW@[7; 11)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0097_default_impl.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0097_default_impl.txt
index f45b6251f..0b9af800b 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0097_default_impl.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0097_default_impl.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 20) 1SOURCE_FILE@[0; 20)
2 IMPL_ITEM@[0; 19) 2 IMPL_BLOCK@[0; 19)
3 DEFAULT_KW@[0; 7) 3 DEFAULT_KW@[0; 7)
4 WHITESPACE@[7; 8) 4 WHITESPACE@[7; 8)
5 IMPL_KW@[8; 12) 5 IMPL_KW@[8; 12)
diff --git a/crates/ra_syntax/tests/data/parser/ok/0037_mod.rs b/crates/ra_syntax/tests/data/parser/ok/0037_mod.rs
new file mode 100644
index 000000000..7e5a1b835
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0037_mod.rs
@@ -0,0 +1,5 @@
1// https://github.com/rust-analyzer/rust-analyzer/issues/357
2
3//! docs
4// non-docs
5mod foo {} \ No newline at end of file
diff --git a/crates/ra_syntax/tests/data/parser/ok/0037_mod.txt b/crates/ra_syntax/tests/data/parser/ok/0037_mod.txt
new file mode 100644
index 000000000..f8a20ac53
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0037_mod.txt
@@ -0,0 +1,16 @@
1SOURCE_FILE@[0; 93)
2 COMMENT@[0; 60)
3 WHITESPACE@[60; 62)
4 MODULE@[62; 93)
5 COMMENT@[62; 70)
6 WHITESPACE@[70; 71)
7 COMMENT@[71; 82)
8 WHITESPACE@[82; 83)
9 MOD_KW@[83; 86)
10 WHITESPACE@[86; 87)
11 NAME@[87; 90)
12 IDENT@[87; 90) "foo"
13 WHITESPACE@[90; 91)
14 ITEM_LIST@[91; 93)
15 L_CURLY@[91; 92)
16 R_CURLY@[92; 93)
diff --git a/crates/ra_text_edit/src/text_edit.rs b/crates/ra_text_edit/src/text_edit.rs
index 0881f3e1c..a288a990d 100644
--- a/crates/ra_text_edit/src/text_edit.rs
+++ b/crates/ra_text_edit/src/text_edit.rs
@@ -7,15 +7,12 @@ pub struct TextEdit {
7 atoms: Vec<AtomTextEdit>, 7 atoms: Vec<AtomTextEdit>,
8} 8}
9 9
10#[derive(Debug)] 10#[derive(Debug, Default)]
11pub struct TextEditBuilder { 11pub struct TextEditBuilder {
12 atoms: Vec<AtomTextEdit>, 12 atoms: Vec<AtomTextEdit>,
13} 13}
14 14
15impl TextEditBuilder { 15impl TextEditBuilder {
16 pub fn new() -> TextEditBuilder {
17 TextEditBuilder { atoms: Vec::new() }
18 }
19 pub fn replace(&mut self, range: TextRange, replace_with: String) { 16 pub fn replace(&mut self, range: TextRange, replace_with: String) {
20 self.atoms.push(AtomTextEdit::replace(range, replace_with)) 17 self.atoms.push(AtomTextEdit::replace(range, replace_with))
21 } 18 }
diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml
index 7c170cdfc..e637063c9 100644
--- a/crates/ra_vfs/Cargo.toml
+++ b/crates/ra_vfs/Cargo.toml
@@ -12,6 +12,7 @@ crossbeam-channel = "0.3.5"
12log = "0.4.6" 12log = "0.4.6"
13 13
14thread_worker = { path = "../thread_worker" } 14thread_worker = { path = "../thread_worker" }
15ra_arena = { path = "../ra_arena" }
15 16
16[dev-dependencies] 17[dev-dependencies]
17tempfile = "3" 18tempfile = "3"
diff --git a/crates/ra_vfs/src/arena.rs b/crates/ra_vfs/src/arena.rs
deleted file mode 100644
index 6b42ae26d..000000000
--- a/crates/ra_vfs/src/arena.rs
+++ /dev/null
@@ -1,53 +0,0 @@
1use std::{
2 marker::PhantomData,
3 ops::{Index, IndexMut},
4};
5
6#[derive(Clone, Debug)]
7pub(crate) struct Arena<ID: ArenaId, T> {
8 data: Vec<T>,
9 _ty: PhantomData<ID>,
10}
11
12pub(crate) trait ArenaId {
13 fn from_u32(id: u32) -> Self;
14 fn to_u32(self) -> u32;
15}
16
17impl<ID: ArenaId, T> Arena<ID, T> {
18 pub fn alloc(&mut self, value: T) -> ID {
19 let id = self.data.len() as u32;
20 self.data.push(value);
21 ID::from_u32(id)
22 }
23 pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> {
24 self.data
25 .iter()
26 .enumerate()
27 .map(|(idx, value)| (ID::from_u32(idx as u32), value))
28 }
29}
30
31impl<ID: ArenaId, T> Default for Arena<ID, T> {
32 fn default() -> Arena<ID, T> {
33 Arena {
34 data: Vec::new(),
35 _ty: PhantomData,
36 }
37 }
38}
39
40impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> {
41 type Output = T;
42 fn index(&self, idx: ID) -> &T {
43 let idx = idx.to_u32() as usize;
44 &self.data[idx]
45 }
46}
47
48impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> {
49 fn index_mut(&mut self, idx: ID) -> &mut T {
50 let idx = idx.to_u32() as usize;
51 &mut self.data[idx]
52 }
53}
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs
index 5bbc3e993..cdea18d73 100644
--- a/crates/ra_vfs/src/lib.rs
+++ b/crates/ra_vfs/src/lib.rs
@@ -13,7 +13,6 @@
13//! VFS is based on a concept of roots: a set of directories on the file system 13//! VFS is based on a concept of roots: a set of directories on the file system
14//! which are watched for changes. Typically, there will be a root for each 14//! which are watched for changes. Typically, there will be a root for each
15//! Cargo package. 15//! Cargo package.
16mod arena;
17mod io; 16mod io;
18 17
19use std::{ 18use std::{
@@ -32,10 +31,7 @@ use relative_path::RelativePathBuf;
32use crossbeam_channel::Receiver; 31use crossbeam_channel::Receiver;
33use walkdir::DirEntry; 32use walkdir::DirEntry;
34use thread_worker::WorkerHandle; 33use thread_worker::WorkerHandle;
35 34use ra_arena::{Arena, RawId, impl_arena_id};
36use crate::{
37 arena::{ArenaId, Arena},
38};
39 35
40pub use crate::io::TaskResult as VfsTask; 36pub use crate::io::TaskResult as VfsTask;
41 37
@@ -68,29 +64,13 @@ fn has_rs_extension(p: &Path) -> bool {
68 p.extension() == Some(OsStr::new("rs")) 64 p.extension() == Some(OsStr::new("rs"))
69} 65}
70 66
71#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 67#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
72pub struct VfsRoot(pub u32); 68pub struct VfsRoot(pub RawId);
73 69impl_arena_id!(VfsRoot);
74impl ArenaId for VfsRoot {
75 fn from_u32(idx: u32) -> VfsRoot {
76 VfsRoot(idx)
77 }
78 fn to_u32(self) -> u32 {
79 self.0
80 }
81}
82
83#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
84pub struct VfsFile(pub u32);
85 70
86impl ArenaId for VfsFile { 71#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
87 fn from_u32(idx: u32) -> VfsFile { 72pub struct VfsFile(pub RawId);
88 VfsFile(idx) 73impl_arena_id!(VfsFile);
89 }
90 fn to_u32(self) -> u32 {
91 self.0
92 }
93}
94 74
95struct VfsFileData { 75struct VfsFileData {
96 root: VfsRoot, 76 root: VfsRoot,
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 5e3d64eef..0bbd85b87 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -22,10 +22,10 @@
22 "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", 22 "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==",
23 "dev": true, 23 "dev": true,
24 "requires": { 24 "requires": {
25 "fast-deep-equal": "2.0.1", 25 "fast-deep-equal": "^2.0.1",
26 "fast-json-stable-stringify": "2.0.0", 26 "fast-json-stable-stringify": "^2.0.0",
27 "json-schema-traverse": "0.4.1", 27 "json-schema-traverse": "^0.4.1",
28 "uri-js": "4.2.2" 28 "uri-js": "^4.2.2"
29 } 29 }
30 }, 30 },
31 "ansi-cyan": { 31 "ansi-cyan": {
@@ -70,7 +70,7 @@
70 "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", 70 "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
71 "dev": true, 71 "dev": true,
72 "requires": { 72 "requires": {
73 "buffer-equal": "1.0.0" 73 "buffer-equal": "^1.0.0"
74 } 74 }
75 }, 75 },
76 "argparse": { 76 "argparse": {
@@ -79,7 +79,7 @@
79 "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 79 "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
80 "dev": true, 80 "dev": true,
81 "requires": { 81 "requires": {
82 "sprintf-js": "1.0.3" 82 "sprintf-js": "~1.0.2"
83 } 83 }
84 }, 84 },
85 "arr-diff": { 85 "arr-diff": {
@@ -88,8 +88,8 @@
88 "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", 88 "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
89 "dev": true, 89 "dev": true,
90 "requires": { 90 "requires": {
91 "arr-flatten": "1.1.0", 91 "arr-flatten": "^1.0.1",
92 "array-slice": "0.2.3" 92 "array-slice": "^0.2.3"
93 } 93 }
94 }, 94 },
95 "arr-flatten": { 95 "arr-flatten": {
@@ -122,7 +122,7 @@
122 "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", 122 "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
123 "dev": true, 123 "dev": true,
124 "requires": { 124 "requires": {
125 "array-uniq": "1.0.3" 125 "array-uniq": "^1.0.1"
126 } 126 }
127 }, 127 },
128 "array-uniq": { 128 "array-uniq": {
@@ -143,7 +143,7 @@
143 "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 143 "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
144 "dev": true, 144 "dev": true,
145 "requires": { 145 "requires": {
146 "safer-buffer": "2.1.2" 146 "safer-buffer": "~2.1.0"
147 } 147 }
148 }, 148 },
149 "assert-plus": { 149 "assert-plus": {
@@ -176,9 +176,9 @@
176 "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 176 "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
177 "dev": true, 177 "dev": true,
178 "requires": { 178 "requires": {
179 "chalk": "1.1.3", 179 "chalk": "^1.1.3",
180 "esutils": "2.0.2", 180 "esutils": "^2.0.2",
181 "js-tokens": "3.0.2" 181 "js-tokens": "^3.0.2"
182 }, 182 },
183 "dependencies": { 183 "dependencies": {
184 "chalk": { 184 "chalk": {
@@ -187,11 +187,11 @@
187 "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 187 "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
188 "dev": true, 188 "dev": true,
189 "requires": { 189 "requires": {
190 "ansi-styles": "2.2.1", 190 "ansi-styles": "^2.2.1",
191 "escape-string-regexp": "1.0.5", 191 "escape-string-regexp": "^1.0.2",
192 "has-ansi": "2.0.0", 192 "has-ansi": "^2.0.0",
193 "strip-ansi": "3.0.1", 193 "strip-ansi": "^3.0.0",
194 "supports-color": "2.0.0" 194 "supports-color": "^2.0.0"
195 } 195 }
196 } 196 }
197 } 197 }
@@ -208,7 +208,7 @@
208 "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 208 "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
209 "dev": true, 209 "dev": true,
210 "requires": { 210 "requires": {
211 "tweetnacl": "0.14.5" 211 "tweetnacl": "^0.14.3"
212 } 212 }
213 }, 213 },
214 "block-stream": { 214 "block-stream": {
@@ -217,7 +217,7 @@
217 "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", 217 "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
218 "dev": true, 218 "dev": true,
219 "requires": { 219 "requires": {
220 "inherits": "2.0.3" 220 "inherits": "~2.0.0"
221 } 221 }
222 }, 222 },
223 "boolbase": { 223 "boolbase": {
@@ -232,7 +232,7 @@
232 "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 232 "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
233 "dev": true, 233 "dev": true,
234 "requires": { 234 "requires": {
235 "balanced-match": "1.0.0", 235 "balanced-match": "^1.0.0",
236 "concat-map": "0.0.1" 236 "concat-map": "0.0.1"
237 } 237 }
238 }, 238 },
@@ -278,9 +278,9 @@
278 "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 278 "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
279 "dev": true, 279 "dev": true,
280 "requires": { 280 "requires": {
281 "ansi-styles": "3.2.1", 281 "ansi-styles": "^3.2.1",
282 "escape-string-regexp": "1.0.5", 282 "escape-string-regexp": "^1.0.5",
283 "supports-color": "5.5.0" 283 "supports-color": "^5.3.0"
284 }, 284 },
285 "dependencies": { 285 "dependencies": {
286 "ansi-styles": { 286 "ansi-styles": {
@@ -289,7 +289,7 @@
289 "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 289 "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
290 "dev": true, 290 "dev": true,
291 "requires": { 291 "requires": {
292 "color-convert": "1.9.3" 292 "color-convert": "^1.9.0"
293 } 293 }
294 }, 294 },
295 "supports-color": { 295 "supports-color": {
@@ -298,7 +298,7 @@
298 "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 298 "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
299 "dev": true, 299 "dev": true,
300 "requires": { 300 "requires": {
301 "has-flag": "3.0.0" 301 "has-flag": "^3.0.0"
302 } 302 }
303 } 303 }
304 } 304 }
@@ -309,12 +309,12 @@
309 "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", 309 "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=",
310 "dev": true, 310 "dev": true,
311 "requires": { 311 "requires": {
312 "css-select": "1.2.0", 312 "css-select": "~1.2.0",
313 "dom-serializer": "0.1.0", 313 "dom-serializer": "~0.1.0",
314 "entities": "1.1.2", 314 "entities": "~1.1.1",
315 "htmlparser2": "3.10.0", 315 "htmlparser2": "^3.9.1",
316 "lodash": "4.17.11", 316 "lodash": "^4.15.0",
317 "parse5": "3.0.3" 317 "parse5": "^3.0.1"
318 } 318 }
319 }, 319 },
320 "clone": { 320 "clone": {
@@ -341,9 +341,9 @@
341 "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", 341 "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
342 "dev": true, 342 "dev": true,
343 "requires": { 343 "requires": {
344 "inherits": "2.0.3", 344 "inherits": "^2.0.1",
345 "process-nextick-args": "2.0.0", 345 "process-nextick-args": "^2.0.0",
346 "readable-stream": "2.3.6" 346 "readable-stream": "^2.3.5"
347 }, 347 },
348 "dependencies": { 348 "dependencies": {
349 "readable-stream": { 349 "readable-stream": {
@@ -352,13 +352,13 @@
352 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 352 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
353 "dev": true, 353 "dev": true,
354 "requires": { 354 "requires": {
355 "core-util-is": "1.0.2", 355 "core-util-is": "~1.0.0",
356 "inherits": "2.0.3", 356 "inherits": "~2.0.3",
357 "isarray": "1.0.0", 357 "isarray": "~1.0.0",
358 "process-nextick-args": "2.0.0", 358 "process-nextick-args": "~2.0.0",
359 "safe-buffer": "5.1.2", 359 "safe-buffer": "~5.1.1",
360 "string_decoder": "1.1.1", 360 "string_decoder": "~1.1.1",
361 "util-deprecate": "1.0.2" 361 "util-deprecate": "~1.0.1"
362 } 362 }
363 }, 363 },
364 "string_decoder": { 364 "string_decoder": {
@@ -367,7 +367,7 @@
367 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 367 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
368 "dev": true, 368 "dev": true,
369 "requires": { 369 "requires": {
370 "safe-buffer": "5.1.2" 370 "safe-buffer": "~5.1.0"
371 } 371 }
372 } 372 }
373 } 373 }
@@ -393,7 +393,7 @@
393 "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", 393 "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
394 "dev": true, 394 "dev": true,
395 "requires": { 395 "requires": {
396 "delayed-stream": "1.0.0" 396 "delayed-stream": "~1.0.0"
397 } 397 }
398 }, 398 },
399 "commander": { 399 "commander": {
@@ -414,7 +414,7 @@
414 "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", 414 "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
415 "dev": true, 415 "dev": true,
416 "requires": { 416 "requires": {
417 "safe-buffer": "5.1.2" 417 "safe-buffer": "~5.1.1"
418 } 418 }
419 }, 419 },
420 "core-util-is": { 420 "core-util-is": {
@@ -429,10 +429,10 @@
429 "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", 429 "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
430 "dev": true, 430 "dev": true,
431 "requires": { 431 "requires": {
432 "boolbase": "1.0.0", 432 "boolbase": "~1.0.0",
433 "css-what": "2.1.2", 433 "css-what": "2.1",
434 "domutils": "1.5.1", 434 "domutils": "1.5.1",
435 "nth-check": "1.0.2" 435 "nth-check": "~1.0.1"
436 } 436 }
437 }, 437 },
438 "css-what": { 438 "css-what": {
@@ -447,7 +447,7 @@
447 "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 447 "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
448 "dev": true, 448 "dev": true,
449 "requires": { 449 "requires": {
450 "assert-plus": "1.0.0" 450 "assert-plus": "^1.0.0"
451 } 451 }
452 }, 452 },
453 "debug": { 453 "debug": {
@@ -465,7 +465,7 @@
465 "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", 465 "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=",
466 "dev": true, 466 "dev": true,
467 "requires": { 467 "requires": {
468 "is-obj": "1.0.1" 468 "is-obj": "^1.0.0"
469 } 469 }
470 }, 470 },
471 "define-properties": { 471 "define-properties": {
@@ -474,7 +474,7 @@
474 "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 474 "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
475 "dev": true, 475 "dev": true,
476 "requires": { 476 "requires": {
477 "object-keys": "1.0.12" 477 "object-keys": "^1.0.12"
478 } 478 }
479 }, 479 },
480 "delayed-stream": { 480 "delayed-stream": {
@@ -501,8 +501,8 @@
501 "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", 501 "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
502 "dev": true, 502 "dev": true,
503 "requires": { 503 "requires": {
504 "domelementtype": "1.1.3", 504 "domelementtype": "~1.1.1",
505 "entities": "1.1.2" 505 "entities": "~1.1.1"
506 }, 506 },
507 "dependencies": { 507 "dependencies": {
508 "domelementtype": { 508 "domelementtype": {
@@ -525,7 +525,7 @@
525 "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", 525 "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
526 "dev": true, 526 "dev": true,
527 "requires": { 527 "requires": {
528 "domelementtype": "1.3.1" 528 "domelementtype": "1"
529 } 529 }
530 }, 530 },
531 "domutils": { 531 "domutils": {
@@ -534,8 +534,8 @@
534 "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", 534 "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
535 "dev": true, 535 "dev": true,
536 "requires": { 536 "requires": {
537 "dom-serializer": "0.1.0", 537 "dom-serializer": "0",
538 "domelementtype": "1.3.1" 538 "domelementtype": "1"
539 } 539 }
540 }, 540 },
541 "duplexer": { 541 "duplexer": {
@@ -550,10 +550,10 @@
550 "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", 550 "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==",
551 "dev": true, 551 "dev": true,
552 "requires": { 552 "requires": {
553 "end-of-stream": "1.4.1", 553 "end-of-stream": "^1.0.0",
554 "inherits": "2.0.3", 554 "inherits": "^2.0.1",
555 "readable-stream": "2.3.6", 555 "readable-stream": "^2.0.0",
556 "stream-shift": "1.0.0" 556 "stream-shift": "^1.0.0"
557 }, 557 },
558 "dependencies": { 558 "dependencies": {
559 "readable-stream": { 559 "readable-stream": {
@@ -562,13 +562,13 @@
562 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 562 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
563 "dev": true, 563 "dev": true,
564 "requires": { 564 "requires": {
565 "core-util-is": "1.0.2", 565 "core-util-is": "~1.0.0",
566 "inherits": "2.0.3", 566 "inherits": "~2.0.3",
567 "isarray": "1.0.0", 567 "isarray": "~1.0.0",
568 "process-nextick-args": "2.0.0", 568 "process-nextick-args": "~2.0.0",
569 "safe-buffer": "5.1.2", 569 "safe-buffer": "~5.1.1",
570 "string_decoder": "1.1.1", 570 "string_decoder": "~1.1.1",
571 "util-deprecate": "1.0.2" 571 "util-deprecate": "~1.0.1"
572 } 572 }
573 }, 573 },
574 "string_decoder": { 574 "string_decoder": {
@@ -577,7 +577,7 @@
577 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 577 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
578 "dev": true, 578 "dev": true,
579 "requires": { 579 "requires": {
580 "safe-buffer": "5.1.2" 580 "safe-buffer": "~5.1.0"
581 } 581 }
582 } 582 }
583 } 583 }
@@ -588,8 +588,8 @@
588 "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 588 "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
589 "dev": true, 589 "dev": true,
590 "requires": { 590 "requires": {
591 "jsbn": "0.1.1", 591 "jsbn": "~0.1.0",
592 "safer-buffer": "2.1.2" 592 "safer-buffer": "^2.1.0"
593 } 593 }
594 }, 594 },
595 "end-of-stream": { 595 "end-of-stream": {
@@ -598,7 +598,7 @@
598 "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 598 "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
599 "dev": true, 599 "dev": true,
600 "requires": { 600 "requires": {
601 "once": "1.4.0" 601 "once": "^1.4.0"
602 } 602 }
603 }, 603 },
604 "entities": { 604 "entities": {
@@ -631,13 +631,13 @@
631 "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", 631 "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
632 "dev": true, 632 "dev": true,
633 "requires": { 633 "requires": {
634 "duplexer": "0.1.1", 634 "duplexer": "~0.1.1",
635 "from": "0.1.7", 635 "from": "~0",
636 "map-stream": "0.1.0", 636 "map-stream": "~0.1.0",
637 "pause-stream": "0.0.11", 637 "pause-stream": "0.0.11",
638 "split": "0.3.3", 638 "split": "0.3",
639 "stream-combiner": "0.0.4", 639 "stream-combiner": "~0.0.4",
640 "through": "2.3.8" 640 "through": "~2.3.1"
641 } 641 }
642 }, 642 },
643 "extend": { 643 "extend": {
@@ -652,7 +652,7 @@
652 "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", 652 "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
653 "dev": true, 653 "dev": true,
654 "requires": { 654 "requires": {
655 "kind-of": "1.1.0" 655 "kind-of": "^1.1.0"
656 } 656 }
657 }, 657 },
658 "extsprintf": { 658 "extsprintf": {
@@ -679,7 +679,7 @@
679 "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", 679 "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
680 "dev": true, 680 "dev": true,
681 "requires": { 681 "requires": {
682 "pend": "1.2.0" 682 "pend": "~1.2.0"
683 } 683 }
684 }, 684 },
685 "flush-write-stream": { 685 "flush-write-stream": {
@@ -688,8 +688,8 @@
688 "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", 688 "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
689 "dev": true, 689 "dev": true,
690 "requires": { 690 "requires": {
691 "inherits": "2.0.3", 691 "inherits": "^2.0.1",
692 "readable-stream": "2.3.6" 692 "readable-stream": "^2.0.4"
693 }, 693 },
694 "dependencies": { 694 "dependencies": {
695 "readable-stream": { 695 "readable-stream": {
@@ -698,13 +698,13 @@
698 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 698 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
699 "dev": true, 699 "dev": true,
700 "requires": { 700 "requires": {
701 "core-util-is": "1.0.2", 701 "core-util-is": "~1.0.0",
702 "inherits": "2.0.3", 702 "inherits": "~2.0.3",
703 "isarray": "1.0.0", 703 "isarray": "~1.0.0",
704 "process-nextick-args": "2.0.0", 704 "process-nextick-args": "~2.0.0",
705 "safe-buffer": "5.1.2", 705 "safe-buffer": "~5.1.1",
706 "string_decoder": "1.1.1", 706 "string_decoder": "~1.1.1",
707 "util-deprecate": "1.0.2" 707 "util-deprecate": "~1.0.1"
708 } 708 }
709 }, 709 },
710 "string_decoder": { 710 "string_decoder": {
@@ -713,7 +713,7 @@
713 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 713 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
714 "dev": true, 714 "dev": true,
715 "requires": { 715 "requires": {
716 "safe-buffer": "5.1.2" 716 "safe-buffer": "~5.1.0"
717 } 717 }
718 } 718 }
719 } 719 }
@@ -730,9 +730,9 @@
730 "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 730 "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
731 "dev": true, 731 "dev": true,
732 "requires": { 732 "requires": {
733 "asynckit": "0.4.0", 733 "asynckit": "^0.4.0",
734 "combined-stream": "1.0.7", 734 "combined-stream": "^1.0.6",
735 "mime-types": "2.1.21" 735 "mime-types": "^2.1.12"
736 } 736 }
737 }, 737 },
738 "from": { 738 "from": {
@@ -747,8 +747,8 @@
747 "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", 747 "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
748 "dev": true, 748 "dev": true,
749 "requires": { 749 "requires": {
750 "graceful-fs": "4.1.15", 750 "graceful-fs": "^4.1.11",
751 "through2": "2.0.5" 751 "through2": "^2.0.3"
752 } 752 }
753 }, 753 },
754 "fs.realpath": { 754 "fs.realpath": {
@@ -763,10 +763,10 @@
763 "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", 763 "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
764 "dev": true, 764 "dev": true,
765 "requires": { 765 "requires": {
766 "graceful-fs": "4.1.15", 766 "graceful-fs": "^4.1.2",
767 "inherits": "2.0.3", 767 "inherits": "~2.0.0",
768 "mkdirp": "0.5.1", 768 "mkdirp": ">=0.5 0",
769 "rimraf": "2.6.2" 769 "rimraf": "2"
770 } 770 }
771 }, 771 },
772 "function-bind": { 772 "function-bind": {
@@ -781,7 +781,7 @@
781 "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 781 "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
782 "dev": true, 782 "dev": true,
783 "requires": { 783 "requires": {
784 "assert-plus": "1.0.0" 784 "assert-plus": "^1.0.0"
785 } 785 }
786 }, 786 },
787 "glob": { 787 "glob": {
@@ -790,12 +790,12 @@
790 "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 790 "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
791 "dev": true, 791 "dev": true,
792 "requires": { 792 "requires": {
793 "fs.realpath": "1.0.0", 793 "fs.realpath": "^1.0.0",
794 "inflight": "1.0.6", 794 "inflight": "^1.0.4",
795 "inherits": "2.0.3", 795 "inherits": "2",
796 "minimatch": "3.0.4", 796 "minimatch": "^3.0.4",
797 "once": "1.4.0", 797 "once": "^1.3.0",
798 "path-is-absolute": "1.0.1" 798 "path-is-absolute": "^1.0.0"
799 } 799 }
800 }, 800 },
801 "glob-parent": { 801 "glob-parent": {
@@ -804,8 +804,8 @@
804 "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", 804 "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
805 "dev": true, 805 "dev": true,
806 "requires": { 806 "requires": {
807 "is-glob": "3.1.0", 807 "is-glob": "^3.1.0",
808 "path-dirname": "1.0.2" 808 "path-dirname": "^1.0.0"
809 } 809 }
810 }, 810 },
811 "glob-stream": { 811 "glob-stream": {
@@ -814,16 +814,16 @@
814 "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", 814 "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
815 "dev": true, 815 "dev": true,
816 "requires": { 816 "requires": {
817 "extend": "3.0.2", 817 "extend": "^3.0.0",
818 "glob": "7.1.3", 818 "glob": "^7.1.1",
819 "glob-parent": "3.1.0", 819 "glob-parent": "^3.1.0",
820 "is-negated-glob": "1.0.0", 820 "is-negated-glob": "^1.0.0",
821 "ordered-read-streams": "1.0.1", 821 "ordered-read-streams": "^1.0.0",
822 "pumpify": "1.5.1", 822 "pumpify": "^1.3.5",
823 "readable-stream": "2.3.6", 823 "readable-stream": "^2.1.5",
824 "remove-trailing-separator": "1.1.0", 824 "remove-trailing-separator": "^1.0.1",
825 "to-absolute-glob": "2.0.2", 825 "to-absolute-glob": "^2.0.0",
826 "unique-stream": "2.2.1" 826 "unique-stream": "^2.0.2"
827 }, 827 },
828 "dependencies": { 828 "dependencies": {
829 "readable-stream": { 829 "readable-stream": {
@@ -832,13 +832,13 @@
832 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 832 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
833 "dev": true, 833 "dev": true,
834 "requires": { 834 "requires": {
835 "core-util-is": "1.0.2", 835 "core-util-is": "~1.0.0",
836 "inherits": "2.0.3", 836 "inherits": "~2.0.3",
837 "isarray": "1.0.0", 837 "isarray": "~1.0.0",
838 "process-nextick-args": "2.0.0", 838 "process-nextick-args": "~2.0.0",
839 "safe-buffer": "5.1.2", 839 "safe-buffer": "~5.1.1",
840 "string_decoder": "1.1.1", 840 "string_decoder": "~1.1.1",
841 "util-deprecate": "1.0.2" 841 "util-deprecate": "~1.0.1"
842 } 842 }
843 }, 843 },
844 "string_decoder": { 844 "string_decoder": {
@@ -847,7 +847,7 @@
847 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 847 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
848 "dev": true, 848 "dev": true,
849 "requires": { 849 "requires": {
850 "safe-buffer": "5.1.2" 850 "safe-buffer": "~5.1.0"
851 } 851 }
852 } 852 }
853 } 853 }
@@ -870,9 +870,9 @@
870 "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=", 870 "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=",
871 "dev": true, 871 "dev": true,
872 "requires": { 872 "requires": {
873 "deep-assign": "1.0.0", 873 "deep-assign": "^1.0.0",
874 "stat-mode": "0.2.2", 874 "stat-mode": "^0.2.0",
875 "through2": "2.0.5" 875 "through2": "^2.0.0"
876 } 876 }
877 }, 877 },
878 "gulp-filter": { 878 "gulp-filter": {
@@ -881,9 +881,9 @@
881 "integrity": "sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM=", 881 "integrity": "sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM=",
882 "dev": true, 882 "dev": true,
883 "requires": { 883 "requires": {
884 "multimatch": "2.1.0", 884 "multimatch": "^2.0.0",
885 "plugin-error": "0.1.2", 885 "plugin-error": "^0.1.2",
886 "streamfilter": "1.0.7" 886 "streamfilter": "^1.0.5"
887 } 887 }
888 }, 888 },
889 "gulp-gunzip": { 889 "gulp-gunzip": {
@@ -892,8 +892,8 @@
892 "integrity": "sha1-FbdBFF6Dqcb1CIYkG1fMWHHxUak=", 892 "integrity": "sha1-FbdBFF6Dqcb1CIYkG1fMWHHxUak=",
893 "dev": true, 893 "dev": true,
894 "requires": { 894 "requires": {
895 "through2": "0.6.5", 895 "through2": "~0.6.5",
896 "vinyl": "0.4.6" 896 "vinyl": "~0.4.6"
897 }, 897 },
898 "dependencies": { 898 "dependencies": {
899 "isarray": { 899 "isarray": {
@@ -908,10 +908,10 @@
908 "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", 908 "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
909 "dev": true, 909 "dev": true,
910 "requires": { 910 "requires": {
911 "core-util-is": "1.0.2", 911 "core-util-is": "~1.0.0",
912 "inherits": "2.0.3", 912 "inherits": "~2.0.1",
913 "isarray": "0.0.1", 913 "isarray": "0.0.1",
914 "string_decoder": "0.10.31" 914 "string_decoder": "~0.10.x"
915 } 915 }
916 }, 916 },
917 "string_decoder": { 917 "string_decoder": {
@@ -926,8 +926,8 @@
926 "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", 926 "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
927 "dev": true, 927 "dev": true,
928 "requires": { 928 "requires": {
929 "readable-stream": "1.0.34", 929 "readable-stream": ">=1.0.33-1 <1.1.0-0",
930 "xtend": "4.0.1" 930 "xtend": ">=4.0.0 <4.1.0-0"
931 } 931 }
932 } 932 }
933 } 933 }
@@ -939,10 +939,10 @@
939 "dev": true, 939 "dev": true,
940 "requires": { 940 "requires": {
941 "event-stream": "3.3.4", 941 "event-stream": "3.3.4",
942 "node.extend": "1.1.8", 942 "node.extend": "^1.1.2",
943 "request": "2.88.0", 943 "request": "^2.79.0",
944 "through2": "2.0.5", 944 "through2": "^2.0.3",
945 "vinyl": "2.2.0" 945 "vinyl": "^2.0.1"
946 }, 946 },
947 "dependencies": { 947 "dependencies": {
948 "clone": { 948 "clone": {
@@ -963,12 +963,12 @@
963 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", 963 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
964 "dev": true, 964 "dev": true,
965 "requires": { 965 "requires": {
966 "clone": "2.1.2", 966 "clone": "^2.1.1",
967 "clone-buffer": "1.0.0", 967 "clone-buffer": "^1.0.0",
968 "clone-stats": "1.0.0", 968 "clone-stats": "^1.0.0",
969 "cloneable-readable": "1.1.2", 969 "cloneable-readable": "^1.0.0",
970 "remove-trailing-separator": "1.1.0", 970 "remove-trailing-separator": "^1.0.1",
971 "replace-ext": "1.0.0" 971 "replace-ext": "^1.0.0"
972 } 972 }
973 } 973 }
974 } 974 }
@@ -979,11 +979,11 @@
979 "integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==", 979 "integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==",
980 "dev": true, 980 "dev": true,
981 "requires": { 981 "requires": {
982 "event-stream": "3.3.4", 982 "event-stream": "~3.3.4",
983 "streamifier": "0.1.1", 983 "streamifier": "~0.1.1",
984 "tar": "2.2.1", 984 "tar": "^2.2.1",
985 "through2": "2.0.5", 985 "through2": "~2.0.3",
986 "vinyl": "1.2.0" 986 "vinyl": "^1.2.0"
987 }, 987 },
988 "dependencies": { 988 "dependencies": {
989 "clone": { 989 "clone": {
@@ -1004,8 +1004,8 @@
1004 "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", 1004 "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
1005 "dev": true, 1005 "dev": true,
1006 "requires": { 1006 "requires": {
1007 "clone": "1.0.4", 1007 "clone": "^1.0.0",
1008 "clone-stats": "0.0.1", 1008 "clone-stats": "^0.0.1",
1009 "replace-ext": "0.0.1" 1009 "replace-ext": "0.0.1"
1010 } 1010 }
1011 } 1011 }
@@ -1018,12 +1018,12 @@
1018 "dev": true, 1018 "dev": true,
1019 "requires": { 1019 "requires": {
1020 "event-stream": "3.3.4", 1020 "event-stream": "3.3.4",
1021 "queue": "4.5.1", 1021 "queue": "^4.2.1",
1022 "through2": "2.0.5", 1022 "through2": "^2.0.3",
1023 "vinyl": "2.2.0", 1023 "vinyl": "^2.0.2",
1024 "vinyl-fs": "3.0.3", 1024 "vinyl-fs": "^3.0.3",
1025 "yauzl": "2.10.0", 1025 "yauzl": "^2.2.1",
1026 "yazl": "2.5.1" 1026 "yazl": "^2.2.1"
1027 }, 1027 },
1028 "dependencies": { 1028 "dependencies": {
1029 "clone": { 1029 "clone": {
@@ -1044,12 +1044,12 @@
1044 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", 1044 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
1045 "dev": true, 1045 "dev": true,
1046 "requires": { 1046 "requires": {
1047 "clone": "2.1.2", 1047 "clone": "^2.1.1",
1048 "clone-buffer": "1.0.0", 1048 "clone-buffer": "^1.0.0",
1049 "clone-stats": "1.0.0", 1049 "clone-stats": "^1.0.0",
1050 "cloneable-readable": "1.1.2", 1050 "cloneable-readable": "^1.0.0",
1051 "remove-trailing-separator": "1.1.0", 1051 "remove-trailing-separator": "^1.0.1",
1052 "replace-ext": "1.0.0" 1052 "replace-ext": "^1.0.0"
1053 } 1053 }
1054 } 1054 }
1055 } 1055 }
@@ -1066,8 +1066,8 @@
1066 "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 1066 "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
1067 "dev": true, 1067 "dev": true,
1068 "requires": { 1068 "requires": {
1069 "ajv": "6.6.2", 1069 "ajv": "^6.5.5",
1070 "har-schema": "2.0.0" 1070 "har-schema": "^2.0.0"
1071 } 1071 }
1072 }, 1072 },
1073 "has": { 1073 "has": {
@@ -1076,7 +1076,7 @@
1076 "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1076 "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1077 "dev": true, 1077 "dev": true,
1078 "requires": { 1078 "requires": {
1079 "function-bind": "1.1.1" 1079 "function-bind": "^1.1.1"
1080 } 1080 }
1081 }, 1081 },
1082 "has-ansi": { 1082 "has-ansi": {
@@ -1085,7 +1085,7 @@
1085 "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 1085 "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
1086 "dev": true, 1086 "dev": true,
1087 "requires": { 1087 "requires": {
1088 "ansi-regex": "2.1.1" 1088 "ansi-regex": "^2.0.0"
1089 } 1089 }
1090 }, 1090 },
1091 "has-flag": { 1091 "has-flag": {
@@ -1112,12 +1112,12 @@
1112 "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==", 1112 "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
1113 "dev": true, 1113 "dev": true,
1114 "requires": { 1114 "requires": {
1115 "domelementtype": "1.3.1", 1115 "domelementtype": "^1.3.0",
1116 "domhandler": "2.4.2", 1116 "domhandler": "^2.3.0",
1117 "domutils": "1.5.1", 1117 "domutils": "^1.5.1",
1118 "entities": "1.1.2", 1118 "entities": "^1.1.1",
1119 "inherits": "2.0.3", 1119 "inherits": "^2.0.1",
1120 "readable-stream": "3.1.0" 1120 "readable-stream": "^3.0.6"
1121 } 1121 }
1122 }, 1122 },
1123 "http-signature": { 1123 "http-signature": {
@@ -1126,9 +1126,9 @@
1126 "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 1126 "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
1127 "dev": true, 1127 "dev": true,
1128 "requires": { 1128 "requires": {
1129 "assert-plus": "1.0.0", 1129 "assert-plus": "^1.0.0",
1130 "jsprim": "1.4.1", 1130 "jsprim": "^1.2.2",
1131 "sshpk": "1.15.2" 1131 "sshpk": "^1.7.0"
1132 } 1132 }
1133 }, 1133 },
1134 "inflight": { 1134 "inflight": {
@@ -1137,8 +1137,8 @@
1137 "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1137 "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1138 "dev": true, 1138 "dev": true,
1139 "requires": { 1139 "requires": {
1140 "once": "1.4.0", 1140 "once": "^1.3.0",
1141 "wrappy": "1.0.2" 1141 "wrappy": "1"
1142 } 1142 }
1143 }, 1143 },
1144 "inherits": { 1144 "inherits": {
@@ -1159,8 +1159,8 @@
1159 "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", 1159 "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
1160 "dev": true, 1160 "dev": true,
1161 "requires": { 1161 "requires": {
1162 "is-relative": "1.0.0", 1162 "is-relative": "^1.0.0",
1163 "is-windows": "1.0.2" 1163 "is-windows": "^1.0.1"
1164 } 1164 }
1165 }, 1165 },
1166 "is-buffer": { 1166 "is-buffer": {
@@ -1181,7 +1181,7 @@
1181 "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", 1181 "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
1182 "dev": true, 1182 "dev": true,
1183 "requires": { 1183 "requires": {
1184 "is-extglob": "2.1.1" 1184 "is-extglob": "^2.1.0"
1185 } 1185 }
1186 }, 1186 },
1187 "is-negated-glob": { 1187 "is-negated-glob": {
@@ -1202,7 +1202,7 @@
1202 "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", 1202 "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
1203 "dev": true, 1203 "dev": true,
1204 "requires": { 1204 "requires": {
1205 "is-unc-path": "1.0.0" 1205 "is-unc-path": "^1.0.0"
1206 } 1206 }
1207 }, 1207 },
1208 "is-typedarray": { 1208 "is-typedarray": {
@@ -1217,7 +1217,7 @@
1217 "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", 1217 "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
1218 "dev": true, 1218 "dev": true,
1219 "requires": { 1219 "requires": {
1220 "unc-path-regex": "0.1.2" 1220 "unc-path-regex": "^0.1.2"
1221 } 1221 }
1222 }, 1222 },
1223 "is-utf8": { 1223 "is-utf8": {
@@ -1262,8 +1262,8 @@
1262 "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", 1262 "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
1263 "dev": true, 1263 "dev": true,
1264 "requires": { 1264 "requires": {
1265 "argparse": "1.0.10", 1265 "argparse": "^1.0.7",
1266 "esprima": "4.0.1" 1266 "esprima": "^4.0.0"
1267 } 1267 }
1268 }, 1268 },
1269 "jsbn": { 1269 "jsbn": {
@@ -1290,7 +1290,7 @@
1290 "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", 1290 "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
1291 "dev": true, 1291 "dev": true,
1292 "requires": { 1292 "requires": {
1293 "jsonify": "0.0.0" 1293 "jsonify": "~0.0.0"
1294 } 1294 }
1295 }, 1295 },
1296 "json-stringify-safe": { 1296 "json-stringify-safe": {
@@ -1329,7 +1329,7 @@
1329 "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", 1329 "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
1330 "dev": true, 1330 "dev": true,
1331 "requires": { 1331 "requires": {
1332 "readable-stream": "2.3.6" 1332 "readable-stream": "^2.0.5"
1333 }, 1333 },
1334 "dependencies": { 1334 "dependencies": {
1335 "readable-stream": { 1335 "readable-stream": {
@@ -1338,13 +1338,13 @@
1338 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1338 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
1339 "dev": true, 1339 "dev": true,
1340 "requires": { 1340 "requires": {
1341 "core-util-is": "1.0.2", 1341 "core-util-is": "~1.0.0",
1342 "inherits": "2.0.3", 1342 "inherits": "~2.0.3",
1343 "isarray": "1.0.0", 1343 "isarray": "~1.0.0",
1344 "process-nextick-args": "2.0.0", 1344 "process-nextick-args": "~2.0.0",
1345 "safe-buffer": "5.1.2", 1345 "safe-buffer": "~5.1.1",
1346 "string_decoder": "1.1.1", 1346 "string_decoder": "~1.1.1",
1347 "util-deprecate": "1.0.2" 1347 "util-deprecate": "~1.0.1"
1348 } 1348 }
1349 }, 1349 },
1350 "string_decoder": { 1350 "string_decoder": {
@@ -1353,7 +1353,7 @@
1353 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1353 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1354 "dev": true, 1354 "dev": true,
1355 "requires": { 1355 "requires": {
1356 "safe-buffer": "5.1.2" 1356 "safe-buffer": "~5.1.0"
1357 } 1357 }
1358 } 1358 }
1359 } 1359 }
@@ -1364,7 +1364,7 @@
1364 "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", 1364 "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
1365 "dev": true, 1365 "dev": true,
1366 "requires": { 1366 "requires": {
1367 "flush-write-stream": "1.0.3" 1367 "flush-write-stream": "^1.0.2"
1368 } 1368 }
1369 }, 1369 },
1370 "linkify-it": { 1370 "linkify-it": {
@@ -1373,7 +1373,7 @@
1373 "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==", 1373 "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
1374 "dev": true, 1374 "dev": true,
1375 "requires": { 1375 "requires": {
1376 "uc.micro": "1.0.5" 1376 "uc.micro": "^1.0.1"
1377 } 1377 }
1378 }, 1378 },
1379 "lodash": { 1379 "lodash": {
@@ -1394,11 +1394,11 @@
1394 "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", 1394 "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
1395 "dev": true, 1395 "dev": true,
1396 "requires": { 1396 "requires": {
1397 "argparse": "1.0.10", 1397 "argparse": "^1.0.7",
1398 "entities": "1.1.2", 1398 "entities": "~1.1.1",
1399 "linkify-it": "2.1.0", 1399 "linkify-it": "^2.0.0",
1400 "mdurl": "1.0.1", 1400 "mdurl": "^1.0.1",
1401 "uc.micro": "1.0.5" 1401 "uc.micro": "^1.0.5"
1402 } 1402 }
1403 }, 1403 },
1404 "mdurl": { 1404 "mdurl": {
@@ -1425,7 +1425,7 @@
1425 "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 1425 "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
1426 "dev": true, 1426 "dev": true,
1427 "requires": { 1427 "requires": {
1428 "mime-db": "1.37.0" 1428 "mime-db": "~1.37.0"
1429 } 1429 }
1430 }, 1430 },
1431 "minimatch": { 1431 "minimatch": {
@@ -1434,7 +1434,7 @@
1434 "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1434 "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1435 "dev": true, 1435 "dev": true,
1436 "requires": { 1436 "requires": {
1437 "brace-expansion": "1.1.11" 1437 "brace-expansion": "^1.1.7"
1438 } 1438 }
1439 }, 1439 },
1440 "minimist": { 1440 "minimist": {
@@ -1488,12 +1488,12 @@
1488 "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 1488 "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
1489 "dev": true, 1489 "dev": true,
1490 "requires": { 1490 "requires": {
1491 "fs.realpath": "1.0.0", 1491 "fs.realpath": "^1.0.0",
1492 "inflight": "1.0.6", 1492 "inflight": "^1.0.4",
1493 "inherits": "2.0.3", 1493 "inherits": "2",
1494 "minimatch": "3.0.4", 1494 "minimatch": "^3.0.4",
1495 "once": "1.4.0", 1495 "once": "^1.3.0",
1496 "path-is-absolute": "1.0.1" 1496 "path-is-absolute": "^1.0.0"
1497 } 1497 }
1498 }, 1498 },
1499 "has-flag": { 1499 "has-flag": {
@@ -1508,7 +1508,7 @@
1508 "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", 1508 "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
1509 "dev": true, 1509 "dev": true,
1510 "requires": { 1510 "requires": {
1511 "has-flag": "2.0.0" 1511 "has-flag": "^2.0.0"
1512 } 1512 }
1513 } 1513 }
1514 } 1514 }
@@ -1525,10 +1525,10 @@
1525 "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", 1525 "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=",
1526 "dev": true, 1526 "dev": true,
1527 "requires": { 1527 "requires": {
1528 "array-differ": "1.0.0", 1528 "array-differ": "^1.0.0",
1529 "array-union": "1.0.2", 1529 "array-union": "^1.0.1",
1530 "arrify": "1.0.1", 1530 "arrify": "^1.0.0",
1531 "minimatch": "3.0.4" 1531 "minimatch": "^3.0.0"
1532 } 1532 }
1533 }, 1533 },
1534 "mute-stream": { 1534 "mute-stream": {
@@ -1543,8 +1543,8 @@
1543 "integrity": "sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA==", 1543 "integrity": "sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA==",
1544 "dev": true, 1544 "dev": true,
1545 "requires": { 1545 "requires": {
1546 "has": "1.0.3", 1546 "has": "^1.0.3",
1547 "is": "3.3.0" 1547 "is": "^3.2.1"
1548 } 1548 }
1549 }, 1549 },
1550 "normalize-path": { 1550 "normalize-path": {
@@ -1553,7 +1553,7 @@
1553 "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", 1553 "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
1554 "dev": true, 1554 "dev": true,
1555 "requires": { 1555 "requires": {
1556 "remove-trailing-separator": "1.1.0" 1556 "remove-trailing-separator": "^1.0.1"
1557 } 1557 }
1558 }, 1558 },
1559 "now-and-later": { 1559 "now-and-later": {
@@ -1562,7 +1562,7 @@
1562 "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", 1562 "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=",
1563 "dev": true, 1563 "dev": true,
1564 "requires": { 1564 "requires": {
1565 "once": "1.4.0" 1565 "once": "^1.3.2"
1566 } 1566 }
1567 }, 1567 },
1568 "nth-check": { 1568 "nth-check": {
@@ -1571,7 +1571,7 @@
1571 "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", 1571 "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
1572 "dev": true, 1572 "dev": true,
1573 "requires": { 1573 "requires": {
1574 "boolbase": "1.0.0" 1574 "boolbase": "~1.0.0"
1575 } 1575 }
1576 }, 1576 },
1577 "oauth-sign": { 1577 "oauth-sign": {
@@ -1592,10 +1592,10 @@
1592 "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 1592 "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
1593 "dev": true, 1593 "dev": true,
1594 "requires": { 1594 "requires": {
1595 "define-properties": "1.1.3", 1595 "define-properties": "^1.1.2",
1596 "function-bind": "1.1.1", 1596 "function-bind": "^1.1.1",
1597 "has-symbols": "1.0.0", 1597 "has-symbols": "^1.0.0",
1598 "object-keys": "1.0.12" 1598 "object-keys": "^1.0.11"
1599 } 1599 }
1600 }, 1600 },
1601 "once": { 1601 "once": {
@@ -1604,7 +1604,7 @@
1604 "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1604 "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1605 "dev": true, 1605 "dev": true,
1606 "requires": { 1606 "requires": {
1607 "wrappy": "1.0.2" 1607 "wrappy": "1"
1608 } 1608 }
1609 }, 1609 },
1610 "ordered-read-streams": { 1610 "ordered-read-streams": {
@@ -1613,7 +1613,7 @@
1613 "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", 1613 "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
1614 "dev": true, 1614 "dev": true,
1615 "requires": { 1615 "requires": {
1616 "readable-stream": "2.3.6" 1616 "readable-stream": "^2.0.1"
1617 }, 1617 },
1618 "dependencies": { 1618 "dependencies": {
1619 "readable-stream": { 1619 "readable-stream": {
@@ -1622,13 +1622,13 @@
1622 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1622 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
1623 "dev": true, 1623 "dev": true,
1624 "requires": { 1624 "requires": {
1625 "core-util-is": "1.0.2", 1625 "core-util-is": "~1.0.0",
1626 "inherits": "2.0.3", 1626 "inherits": "~2.0.3",
1627 "isarray": "1.0.0", 1627 "isarray": "~1.0.0",
1628 "process-nextick-args": "2.0.0", 1628 "process-nextick-args": "~2.0.0",
1629 "safe-buffer": "5.1.2", 1629 "safe-buffer": "~5.1.1",
1630 "string_decoder": "1.1.1", 1630 "string_decoder": "~1.1.1",
1631 "util-deprecate": "1.0.2" 1631 "util-deprecate": "~1.0.1"
1632 } 1632 }
1633 }, 1633 },
1634 "string_decoder": { 1634 "string_decoder": {
@@ -1637,7 +1637,7 @@
1637 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1637 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1638 "dev": true, 1638 "dev": true,
1639 "requires": { 1639 "requires": {
1640 "safe-buffer": "5.1.2" 1640 "safe-buffer": "~5.1.0"
1641 } 1641 }
1642 } 1642 }
1643 } 1643 }
@@ -1660,8 +1660,8 @@
1660 "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", 1660 "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
1661 "dev": true, 1661 "dev": true,
1662 "requires": { 1662 "requires": {
1663 "os-homedir": "1.0.2", 1663 "os-homedir": "^1.0.0",
1664 "os-tmpdir": "1.0.2" 1664 "os-tmpdir": "^1.0.0"
1665 } 1665 }
1666 }, 1666 },
1667 "parse-semver": { 1667 "parse-semver": {
@@ -1670,7 +1670,7 @@
1670 "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", 1670 "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=",
1671 "dev": true, 1671 "dev": true,
1672 "requires": { 1672 "requires": {
1673 "semver": "5.6.0" 1673 "semver": "^5.1.0"
1674 } 1674 }
1675 }, 1675 },
1676 "parse5": { 1676 "parse5": {
@@ -1679,7 +1679,7 @@
1679 "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", 1679 "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
1680 "dev": true, 1680 "dev": true,
1681 "requires": { 1681 "requires": {
1682 "@types/node": "8.10.38" 1682 "@types/node": "*"
1683 } 1683 }
1684 }, 1684 },
1685 "path-dirname": { 1685 "path-dirname": {
@@ -1706,7 +1706,7 @@
1706 "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", 1706 "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
1707 "dev": true, 1707 "dev": true,
1708 "requires": { 1708 "requires": {
1709 "through": "2.3.8" 1709 "through": "~2.3"
1710 } 1710 }
1711 }, 1711 },
1712 "pend": { 1712 "pend": {
@@ -1727,11 +1727,11 @@
1727 "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", 1727 "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=",
1728 "dev": true, 1728 "dev": true,
1729 "requires": { 1729 "requires": {
1730 "ansi-cyan": "0.1.1", 1730 "ansi-cyan": "^0.1.1",
1731 "ansi-red": "0.1.1", 1731 "ansi-red": "^0.1.1",
1732 "arr-diff": "1.1.0", 1732 "arr-diff": "^1.0.1",
1733 "arr-union": "2.1.0", 1733 "arr-union": "^2.0.1",
1734 "extend-shallow": "1.1.4" 1734 "extend-shallow": "^1.1.2"
1735 } 1735 }
1736 }, 1736 },
1737 "prettier": { 1737 "prettier": {
@@ -1758,8 +1758,8 @@
1758 "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", 1758 "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
1759 "dev": true, 1759 "dev": true,
1760 "requires": { 1760 "requires": {
1761 "end-of-stream": "1.4.1", 1761 "end-of-stream": "^1.1.0",
1762 "once": "1.4.0" 1762 "once": "^1.3.1"
1763 } 1763 }
1764 }, 1764 },
1765 "pumpify": { 1765 "pumpify": {
@@ -1768,9 +1768,9 @@
1768 "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", 1768 "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
1769 "dev": true, 1769 "dev": true,
1770 "requires": { 1770 "requires": {
1771 "duplexify": "3.6.1", 1771 "duplexify": "^3.6.0",
1772 "inherits": "2.0.3", 1772 "inherits": "^2.0.3",
1773 "pump": "2.0.1" 1773 "pump": "^2.0.0"
1774 } 1774 }
1775 }, 1775 },
1776 "punycode": { 1776 "punycode": {
@@ -1803,7 +1803,7 @@
1803 "integrity": "sha512-AMD7w5hRXcFSb8s9u38acBZ+309u6GsiibP4/0YacJeaurRshogB7v/ZcVPxP5gD5+zIw6ixRHdutiYUJfwKHw==", 1803 "integrity": "sha512-AMD7w5hRXcFSb8s9u38acBZ+309u6GsiibP4/0YacJeaurRshogB7v/ZcVPxP5gD5+zIw6ixRHdutiYUJfwKHw==",
1804 "dev": true, 1804 "dev": true,
1805 "requires": { 1805 "requires": {
1806 "inherits": "2.0.3" 1806 "inherits": "~2.0.0"
1807 } 1807 }
1808 }, 1808 },
1809 "read": { 1809 "read": {
@@ -1812,7 +1812,7 @@
1812 "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", 1812 "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
1813 "dev": true, 1813 "dev": true,
1814 "requires": { 1814 "requires": {
1815 "mute-stream": "0.0.7" 1815 "mute-stream": "~0.0.4"
1816 } 1816 }
1817 }, 1817 },
1818 "readable-stream": { 1818 "readable-stream": {
@@ -1821,9 +1821,9 @@
1821 "integrity": "sha512-vpydAvIJvPODZNagCPuHG87O9JNPtvFEtjHHRVwNVsVVRBqemvPJkc2SYbxJsiZXawJdtZNmkmnsPuE3IgsG0A==", 1821 "integrity": "sha512-vpydAvIJvPODZNagCPuHG87O9JNPtvFEtjHHRVwNVsVVRBqemvPJkc2SYbxJsiZXawJdtZNmkmnsPuE3IgsG0A==",
1822 "dev": true, 1822 "dev": true,
1823 "requires": { 1823 "requires": {
1824 "inherits": "2.0.3", 1824 "inherits": "^2.0.3",
1825 "string_decoder": "1.2.0", 1825 "string_decoder": "^1.1.1",
1826 "util-deprecate": "1.0.2" 1826 "util-deprecate": "^1.0.1"
1827 } 1827 }
1828 }, 1828 },
1829 "remove-bom-buffer": { 1829 "remove-bom-buffer": {
@@ -1832,8 +1832,8 @@
1832 "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", 1832 "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
1833 "dev": true, 1833 "dev": true,
1834 "requires": { 1834 "requires": {
1835 "is-buffer": "1.1.6", 1835 "is-buffer": "^1.1.5",
1836 "is-utf8": "0.2.1" 1836 "is-utf8": "^0.2.1"
1837 } 1837 }
1838 }, 1838 },
1839 "remove-bom-stream": { 1839 "remove-bom-stream": {
@@ -1842,9 +1842,9 @@
1842 "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", 1842 "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
1843 "dev": true, 1843 "dev": true,
1844 "requires": { 1844 "requires": {
1845 "remove-bom-buffer": "3.0.0", 1845 "remove-bom-buffer": "^3.0.0",
1846 "safe-buffer": "5.1.2", 1846 "safe-buffer": "^5.1.0",
1847 "through2": "2.0.5" 1847 "through2": "^2.0.3"
1848 } 1848 }
1849 }, 1849 },
1850 "remove-trailing-separator": { 1850 "remove-trailing-separator": {
@@ -1865,26 +1865,26 @@
1865 "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 1865 "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
1866 "dev": true, 1866 "dev": true,
1867 "requires": { 1867 "requires": {
1868 "aws-sign2": "0.7.0", 1868 "aws-sign2": "~0.7.0",
1869 "aws4": "1.8.0", 1869 "aws4": "^1.8.0",
1870 "caseless": "0.12.0", 1870 "caseless": "~0.12.0",
1871 "combined-stream": "1.0.7", 1871 "combined-stream": "~1.0.6",
1872 "extend": "3.0.2", 1872 "extend": "~3.0.2",
1873 "forever-agent": "0.6.1", 1873 "forever-agent": "~0.6.1",
1874 "form-data": "2.3.3", 1874 "form-data": "~2.3.2",
1875 "har-validator": "5.1.3", 1875 "har-validator": "~5.1.0",
1876 "http-signature": "1.2.0", 1876 "http-signature": "~1.2.0",
1877 "is-typedarray": "1.0.0", 1877 "is-typedarray": "~1.0.0",
1878 "isstream": "0.1.2", 1878 "isstream": "~0.1.2",
1879 "json-stringify-safe": "5.0.1", 1879 "json-stringify-safe": "~5.0.1",
1880 "mime-types": "2.1.21", 1880 "mime-types": "~2.1.19",
1881 "oauth-sign": "0.9.0", 1881 "oauth-sign": "~0.9.0",
1882 "performance-now": "2.1.0", 1882 "performance-now": "^2.1.0",
1883 "qs": "6.5.2", 1883 "qs": "~6.5.2",
1884 "safe-buffer": "5.1.2", 1884 "safe-buffer": "^5.1.2",
1885 "tough-cookie": "2.4.3", 1885 "tough-cookie": "~2.4.3",
1886 "tunnel-agent": "0.6.0", 1886 "tunnel-agent": "^0.6.0",
1887 "uuid": "3.3.2" 1887 "uuid": "^3.3.2"
1888 } 1888 }
1889 }, 1889 },
1890 "requires-port": { 1890 "requires-port": {
@@ -1899,7 +1899,7 @@
1899 "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", 1899 "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==",
1900 "dev": true, 1900 "dev": true,
1901 "requires": { 1901 "requires": {
1902 "path-parse": "1.0.6" 1902 "path-parse": "^1.0.6"
1903 } 1903 }
1904 }, 1904 },
1905 "resolve-options": { 1905 "resolve-options": {
@@ -1908,7 +1908,7 @@
1908 "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", 1908 "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
1909 "dev": true, 1909 "dev": true,
1910 "requires": { 1910 "requires": {
1911 "value-or-function": "3.0.0" 1911 "value-or-function": "^3.0.0"
1912 } 1912 }
1913 }, 1913 },
1914 "rimraf": { 1914 "rimraf": {
@@ -1917,7 +1917,7 @@
1917 "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 1917 "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
1918 "dev": true, 1918 "dev": true,
1919 "requires": { 1919 "requires": {
1920 "glob": "7.1.3" 1920 "glob": "^7.0.5"
1921 } 1921 }
1922 }, 1922 },
1923 "safe-buffer": { 1923 "safe-buffer": {
@@ -1949,8 +1949,8 @@
1949 "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", 1949 "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==",
1950 "dev": true, 1950 "dev": true,
1951 "requires": { 1951 "requires": {
1952 "buffer-from": "1.1.1", 1952 "buffer-from": "^1.0.0",
1953 "source-map": "0.6.1" 1953 "source-map": "^0.6.0"
1954 } 1954 }
1955 }, 1955 },
1956 "split": { 1956 "split": {
@@ -1959,7 +1959,7 @@
1959 "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", 1959 "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
1960 "dev": true, 1960 "dev": true,
1961 "requires": { 1961 "requires": {
1962 "through": "2.3.8" 1962 "through": "2"
1963 } 1963 }
1964 }, 1964 },
1965 "sprintf-js": { 1965 "sprintf-js": {
@@ -1974,15 +1974,15 @@
1974 "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", 1974 "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==",
1975 "dev": true, 1975 "dev": true,
1976 "requires": { 1976 "requires": {
1977 "asn1": "0.2.4", 1977 "asn1": "~0.2.3",
1978 "assert-plus": "1.0.0", 1978 "assert-plus": "^1.0.0",
1979 "bcrypt-pbkdf": "1.0.2", 1979 "bcrypt-pbkdf": "^1.0.0",
1980 "dashdash": "1.14.1", 1980 "dashdash": "^1.12.0",
1981 "ecc-jsbn": "0.1.2", 1981 "ecc-jsbn": "~0.1.1",
1982 "getpass": "0.1.7", 1982 "getpass": "^0.1.1",
1983 "jsbn": "0.1.1", 1983 "jsbn": "~0.1.0",
1984 "safer-buffer": "2.1.2", 1984 "safer-buffer": "^2.0.2",
1985 "tweetnacl": "0.14.5" 1985 "tweetnacl": "~0.14.0"
1986 } 1986 }
1987 }, 1987 },
1988 "stat-mode": { 1988 "stat-mode": {
@@ -1997,7 +1997,7 @@
1997 "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", 1997 "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
1998 "dev": true, 1998 "dev": true,
1999 "requires": { 1999 "requires": {
2000 "duplexer": "0.1.1" 2000 "duplexer": "~0.1.1"
2001 } 2001 }
2002 }, 2002 },
2003 "stream-shift": { 2003 "stream-shift": {
@@ -2012,7 +2012,7 @@
2012 "integrity": "sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ==", 2012 "integrity": "sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ==",
2013 "dev": true, 2013 "dev": true,
2014 "requires": { 2014 "requires": {
2015 "readable-stream": "2.3.6" 2015 "readable-stream": "^2.0.2"
2016 }, 2016 },
2017 "dependencies": { 2017 "dependencies": {
2018 "readable-stream": { 2018 "readable-stream": {
@@ -2021,13 +2021,13 @@
2021 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 2021 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
2022 "dev": true, 2022 "dev": true,
2023 "requires": { 2023 "requires": {
2024 "core-util-is": "1.0.2", 2024 "core-util-is": "~1.0.0",
2025 "inherits": "2.0.3", 2025 "inherits": "~2.0.3",
2026 "isarray": "1.0.0", 2026 "isarray": "~1.0.0",
2027 "process-nextick-args": "2.0.0", 2027 "process-nextick-args": "~2.0.0",
2028 "safe-buffer": "5.1.2", 2028 "safe-buffer": "~5.1.1",
2029 "string_decoder": "1.1.1", 2029 "string_decoder": "~1.1.1",
2030 "util-deprecate": "1.0.2" 2030 "util-deprecate": "~1.0.1"
2031 } 2031 }
2032 }, 2032 },
2033 "string_decoder": { 2033 "string_decoder": {
@@ -2036,7 +2036,7 @@
2036 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2036 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
2037 "dev": true, 2037 "dev": true,
2038 "requires": { 2038 "requires": {
2039 "safe-buffer": "5.1.2" 2039 "safe-buffer": "~5.1.0"
2040 } 2040 }
2041 } 2041 }
2042 } 2042 }
@@ -2053,7 +2053,7 @@
2053 "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", 2053 "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
2054 "dev": true, 2054 "dev": true,
2055 "requires": { 2055 "requires": {
2056 "safe-buffer": "5.1.2" 2056 "safe-buffer": "~5.1.0"
2057 } 2057 }
2058 }, 2058 },
2059 "strip-ansi": { 2059 "strip-ansi": {
@@ -2062,7 +2062,7 @@
2062 "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 2062 "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
2063 "dev": true, 2063 "dev": true,
2064 "requires": { 2064 "requires": {
2065 "ansi-regex": "2.1.1" 2065 "ansi-regex": "^2.0.0"
2066 } 2066 }
2067 }, 2067 },
2068 "supports-color": { 2068 "supports-color": {
@@ -2077,9 +2077,9 @@
2077 "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", 2077 "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
2078 "dev": true, 2078 "dev": true,
2079 "requires": { 2079 "requires": {
2080 "block-stream": "0.0.9", 2080 "block-stream": "*",
2081 "fstream": "1.0.11", 2081 "fstream": "^1.0.2",
2082 "inherits": "2.0.3" 2082 "inherits": "2"
2083 } 2083 }
2084 }, 2084 },
2085 "through": { 2085 "through": {
@@ -2094,8 +2094,8 @@
2094 "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", 2094 "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
2095 "dev": true, 2095 "dev": true,
2096 "requires": { 2096 "requires": {
2097 "readable-stream": "2.3.6", 2097 "readable-stream": "~2.3.6",
2098 "xtend": "4.0.1" 2098 "xtend": "~4.0.1"
2099 }, 2099 },
2100 "dependencies": { 2100 "dependencies": {
2101 "readable-stream": { 2101 "readable-stream": {
@@ -2104,13 +2104,13 @@
2104 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 2104 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
2105 "dev": true, 2105 "dev": true,
2106 "requires": { 2106 "requires": {
2107 "core-util-is": "1.0.2", 2107 "core-util-is": "~1.0.0",
2108 "inherits": "2.0.3", 2108 "inherits": "~2.0.3",
2109 "isarray": "1.0.0", 2109 "isarray": "~1.0.0",
2110 "process-nextick-args": "2.0.0", 2110 "process-nextick-args": "~2.0.0",
2111 "safe-buffer": "5.1.2", 2111 "safe-buffer": "~5.1.1",
2112 "string_decoder": "1.1.1", 2112 "string_decoder": "~1.1.1",
2113 "util-deprecate": "1.0.2" 2113 "util-deprecate": "~1.0.1"
2114 } 2114 }
2115 }, 2115 },
2116 "string_decoder": { 2116 "string_decoder": {
@@ -2119,7 +2119,7 @@
2119 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2119 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
2120 "dev": true, 2120 "dev": true,
2121 "requires": { 2121 "requires": {
2122 "safe-buffer": "5.1.2" 2122 "safe-buffer": "~5.1.0"
2123 } 2123 }
2124 } 2124 }
2125 } 2125 }
@@ -2130,8 +2130,8 @@
2130 "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", 2130 "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=",
2131 "dev": true, 2131 "dev": true,
2132 "requires": { 2132 "requires": {
2133 "through2": "2.0.5", 2133 "through2": "~2.0.0",
2134 "xtend": "4.0.1" 2134 "xtend": "~4.0.0"
2135 } 2135 }
2136 }, 2136 },
2137 "tmp": { 2137 "tmp": {
@@ -2140,7 +2140,7 @@
2140 "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", 2140 "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=",
2141 "dev": true, 2141 "dev": true,
2142 "requires": { 2142 "requires": {
2143 "os-tmpdir": "1.0.2" 2143 "os-tmpdir": "~1.0.1"
2144 } 2144 }
2145 }, 2145 },
2146 "to-absolute-glob": { 2146 "to-absolute-glob": {
@@ -2149,8 +2149,8 @@
2149 "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", 2149 "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
2150 "dev": true, 2150 "dev": true,
2151 "requires": { 2151 "requires": {
2152 "is-absolute": "1.0.0", 2152 "is-absolute": "^1.0.0",
2153 "is-negated-glob": "1.0.0" 2153 "is-negated-glob": "^1.0.0"
2154 } 2154 }
2155 }, 2155 },
2156 "to-through": { 2156 "to-through": {
@@ -2159,7 +2159,7 @@
2159 "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", 2159 "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
2160 "dev": true, 2160 "dev": true,
2161 "requires": { 2161 "requires": {
2162 "through2": "2.0.5" 2162 "through2": "^2.0.3"
2163 } 2163 }
2164 }, 2164 },
2165 "tough-cookie": { 2165 "tough-cookie": {
@@ -2168,8 +2168,8 @@
2168 "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 2168 "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
2169 "dev": true, 2169 "dev": true,
2170 "requires": { 2170 "requires": {
2171 "psl": "1.1.31", 2171 "psl": "^1.1.24",
2172 "punycode": "1.4.1" 2172 "punycode": "^1.4.1"
2173 }, 2173 },
2174 "dependencies": { 2174 "dependencies": {
2175 "punycode": { 2175 "punycode": {
@@ -2192,18 +2192,18 @@
2192 "integrity": "sha1-mPMMAurjzecAYgHkwzywi0hYHu0=", 2192 "integrity": "sha1-mPMMAurjzecAYgHkwzywi0hYHu0=",
2193 "dev": true, 2193 "dev": true,
2194 "requires": { 2194 "requires": {
2195 "babel-code-frame": "6.26.0", 2195 "babel-code-frame": "^6.22.0",
2196 "builtin-modules": "1.1.1", 2196 "builtin-modules": "^1.1.1",
2197 "chalk": "2.4.1", 2197 "chalk": "^2.3.0",
2198 "commander": "2.19.0", 2198 "commander": "^2.12.1",
2199 "diff": "3.5.0", 2199 "diff": "^3.2.0",
2200 "glob": "7.1.3", 2200 "glob": "^7.1.1",
2201 "js-yaml": "3.12.0", 2201 "js-yaml": "^3.7.0",
2202 "minimatch": "3.0.4", 2202 "minimatch": "^3.0.4",
2203 "resolve": "1.9.0", 2203 "resolve": "^1.3.2",
2204 "semver": "5.6.0", 2204 "semver": "^5.3.0",
2205 "tslib": "1.9.3", 2205 "tslib": "^1.8.0",
2206 "tsutils": "2.29.0" 2206 "tsutils": "^2.27.2"
2207 } 2207 }
2208 }, 2208 },
2209 "tslint-config-prettier": { 2209 "tslint-config-prettier": {
@@ -2218,7 +2218,7 @@
2218 "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", 2218 "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
2219 "dev": true, 2219 "dev": true,
2220 "requires": { 2220 "requires": {
2221 "tslib": "1.9.3" 2221 "tslib": "^1.8.1"
2222 } 2222 }
2223 }, 2223 },
2224 "tunnel": { 2224 "tunnel": {
@@ -2233,7 +2233,7 @@
2233 "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 2233 "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
2234 "dev": true, 2234 "dev": true,
2235 "requires": { 2235 "requires": {
2236 "safe-buffer": "5.1.2" 2236 "safe-buffer": "^5.0.1"
2237 } 2237 }
2238 }, 2238 },
2239 "tweetnacl": { 2239 "tweetnacl": {
@@ -2290,8 +2290,8 @@
2290 "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", 2290 "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=",
2291 "dev": true, 2291 "dev": true,
2292 "requires": { 2292 "requires": {
2293 "json-stable-stringify": "1.0.1", 2293 "json-stable-stringify": "^1.0.0",
2294 "through2-filter": "2.0.0" 2294 "through2-filter": "^2.0.0"
2295 } 2295 }
2296 }, 2296 },
2297 "uri-js": { 2297 "uri-js": {
@@ -2300,7 +2300,7 @@
2300 "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 2300 "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
2301 "dev": true, 2301 "dev": true,
2302 "requires": { 2302 "requires": {
2303 "punycode": "2.1.1" 2303 "punycode": "^2.1.0"
2304 } 2304 }
2305 }, 2305 },
2306 "url-join": { 2306 "url-join": {
@@ -2315,8 +2315,8 @@
2315 "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", 2315 "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==",
2316 "dev": true, 2316 "dev": true,
2317 "requires": { 2317 "requires": {
2318 "querystringify": "2.1.0", 2318 "querystringify": "^2.0.0",
2319 "requires-port": "1.0.0" 2319 "requires-port": "^1.0.0"
2320 } 2320 }
2321 }, 2321 },
2322 "util-deprecate": { 2322 "util-deprecate": {
@@ -2343,9 +2343,9 @@
2343 "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 2343 "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
2344 "dev": true, 2344 "dev": true,
2345 "requires": { 2345 "requires": {
2346 "assert-plus": "1.0.0", 2346 "assert-plus": "^1.0.0",
2347 "core-util-is": "1.0.2", 2347 "core-util-is": "1.0.2",
2348 "extsprintf": "1.3.0" 2348 "extsprintf": "^1.2.0"
2349 } 2349 }
2350 }, 2350 },
2351 "vinyl": { 2351 "vinyl": {
@@ -2354,8 +2354,8 @@
2354 "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", 2354 "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
2355 "dev": true, 2355 "dev": true,
2356 "requires": { 2356 "requires": {
2357 "clone": "0.2.0", 2357 "clone": "^0.2.0",
2358 "clone-stats": "0.0.1" 2358 "clone-stats": "^0.0.1"
2359 } 2359 }
2360 }, 2360 },
2361 "vinyl-fs": { 2361 "vinyl-fs": {
@@ -2364,23 +2364,23 @@
2364 "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", 2364 "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
2365 "dev": true, 2365 "dev": true,
2366 "requires": { 2366 "requires": {
2367 "fs-mkdirp-stream": "1.0.0", 2367 "fs-mkdirp-stream": "^1.0.0",
2368 "glob-stream": "6.1.0", 2368 "glob-stream": "^6.1.0",
2369 "graceful-fs": "4.1.15", 2369 "graceful-fs": "^4.0.0",
2370 "is-valid-glob": "1.0.0", 2370 "is-valid-glob": "^1.0.0",
2371 "lazystream": "1.0.0", 2371 "lazystream": "^1.0.0",
2372 "lead": "1.0.0", 2372 "lead": "^1.0.0",
2373 "object.assign": "4.1.0", 2373 "object.assign": "^4.0.4",
2374 "pumpify": "1.5.1", 2374 "pumpify": "^1.3.5",
2375 "readable-stream": "2.3.6", 2375 "readable-stream": "^2.3.3",
2376 "remove-bom-buffer": "3.0.0", 2376 "remove-bom-buffer": "^3.0.0",
2377 "remove-bom-stream": "1.2.0", 2377 "remove-bom-stream": "^1.2.0",
2378 "resolve-options": "1.1.0", 2378 "resolve-options": "^1.1.0",
2379 "through2": "2.0.5", 2379 "through2": "^2.0.0",
2380 "to-through": "2.0.0", 2380 "to-through": "^2.0.0",
2381 "value-or-function": "3.0.0", 2381 "value-or-function": "^3.0.0",
2382 "vinyl": "2.2.0", 2382 "vinyl": "^2.0.0",
2383 "vinyl-sourcemap": "1.1.0" 2383 "vinyl-sourcemap": "^1.1.0"
2384 }, 2384 },
2385 "dependencies": { 2385 "dependencies": {
2386 "clone": { 2386 "clone": {
@@ -2401,13 +2401,13 @@
2401 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 2401 "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
2402 "dev": true, 2402 "dev": true,
2403 "requires": { 2403 "requires": {
2404 "core-util-is": "1.0.2", 2404 "core-util-is": "~1.0.0",
2405 "inherits": "2.0.3", 2405 "inherits": "~2.0.3",
2406 "isarray": "1.0.0", 2406 "isarray": "~1.0.0",
2407 "process-nextick-args": "2.0.0", 2407 "process-nextick-args": "~2.0.0",
2408 "safe-buffer": "5.1.2", 2408 "safe-buffer": "~5.1.1",
2409 "string_decoder": "1.1.1", 2409 "string_decoder": "~1.1.1",
2410 "util-deprecate": "1.0.2" 2410 "util-deprecate": "~1.0.1"
2411 } 2411 }
2412 }, 2412 },
2413 "string_decoder": { 2413 "string_decoder": {
@@ -2416,7 +2416,7 @@
2416 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2416 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
2417 "dev": true, 2417 "dev": true,
2418 "requires": { 2418 "requires": {
2419 "safe-buffer": "5.1.2" 2419 "safe-buffer": "~5.1.0"
2420 } 2420 }
2421 }, 2421 },
2422 "vinyl": { 2422 "vinyl": {
@@ -2425,12 +2425,12 @@
2425 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", 2425 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
2426 "dev": true, 2426 "dev": true,
2427 "requires": { 2427 "requires": {
2428 "clone": "2.1.2", 2428 "clone": "^2.1.1",
2429 "clone-buffer": "1.0.0", 2429 "clone-buffer": "^1.0.0",
2430 "clone-stats": "1.0.0", 2430 "clone-stats": "^1.0.0",
2431 "cloneable-readable": "1.1.2", 2431 "cloneable-readable": "^1.0.0",
2432 "remove-trailing-separator": "1.1.0", 2432 "remove-trailing-separator": "^1.0.1",
2433 "replace-ext": "1.0.0" 2433 "replace-ext": "^1.0.0"
2434 } 2434 }
2435 } 2435 }
2436 } 2436 }
@@ -2441,8 +2441,8 @@
2441 "integrity": "sha1-YrU6E1YQqJbpjKlr7jqH8Aio54A=", 2441 "integrity": "sha1-YrU6E1YQqJbpjKlr7jqH8Aio54A=",
2442 "dev": true, 2442 "dev": true,
2443 "requires": { 2443 "requires": {
2444 "through2": "2.0.5", 2444 "through2": "^2.0.3",
2445 "vinyl": "0.4.6" 2445 "vinyl": "^0.4.3"
2446 } 2446 }
2447 }, 2447 },
2448 "vinyl-sourcemap": { 2448 "vinyl-sourcemap": {
@@ -2451,13 +2451,13 @@
2451 "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", 2451 "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
2452 "dev": true, 2452 "dev": true,
2453 "requires": { 2453 "requires": {
2454 "append-buffer": "1.0.2", 2454 "append-buffer": "^1.0.2",
2455 "convert-source-map": "1.6.0", 2455 "convert-source-map": "^1.5.0",
2456 "graceful-fs": "4.1.15", 2456 "graceful-fs": "^4.1.6",
2457 "normalize-path": "2.1.1", 2457 "normalize-path": "^2.1.1",
2458 "now-and-later": "2.0.0", 2458 "now-and-later": "^2.0.0",
2459 "remove-bom-buffer": "3.0.0", 2459 "remove-bom-buffer": "^3.0.0",
2460 "vinyl": "2.2.0" 2460 "vinyl": "^2.0.0"
2461 }, 2461 },
2462 "dependencies": { 2462 "dependencies": {
2463 "clone": { 2463 "clone": {
@@ -2478,12 +2478,12 @@
2478 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", 2478 "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
2479 "dev": true, 2479 "dev": true,
2480 "requires": { 2480 "requires": {
2481 "clone": "2.1.2", 2481 "clone": "^2.1.1",
2482 "clone-buffer": "1.0.0", 2482 "clone-buffer": "^1.0.0",
2483 "clone-stats": "1.0.0", 2483 "clone-stats": "^1.0.0",
2484 "cloneable-readable": "1.1.2", 2484 "cloneable-readable": "^1.0.0",
2485 "remove-trailing-separator": "1.1.0", 2485 "remove-trailing-separator": "^1.0.1",
2486 "replace-ext": "1.0.0" 2486 "replace-ext": "^1.0.0"
2487 } 2487 }
2488 } 2488 }
2489 } 2489 }
@@ -2494,23 +2494,23 @@
2494 "integrity": "sha512-yo7ctgQPK7hKnez/be3Tj7RG3eZzgkFhx/27y9guwzhMxHfjlU1pusAsFT8wBEZKZlYA5HNJAx8oClw4WDWi+A==", 2494 "integrity": "sha512-yo7ctgQPK7hKnez/be3Tj7RG3eZzgkFhx/27y9guwzhMxHfjlU1pusAsFT8wBEZKZlYA5HNJAx8oClw4WDWi+A==",
2495 "dev": true, 2495 "dev": true,
2496 "requires": { 2496 "requires": {
2497 "cheerio": "1.0.0-rc.2", 2497 "cheerio": "^1.0.0-rc.1",
2498 "commander": "2.19.0", 2498 "commander": "^2.8.1",
2499 "denodeify": "1.2.1", 2499 "denodeify": "^1.2.1",
2500 "glob": "7.1.3", 2500 "glob": "^7.0.6",
2501 "lodash": "4.17.11", 2501 "lodash": "^4.17.10",
2502 "markdown-it": "8.4.2", 2502 "markdown-it": "^8.3.1",
2503 "mime": "1.6.0", 2503 "mime": "^1.3.4",
2504 "minimatch": "3.0.4", 2504 "minimatch": "^3.0.3",
2505 "osenv": "0.1.5", 2505 "osenv": "^0.1.3",
2506 "parse-semver": "1.1.1", 2506 "parse-semver": "^1.1.1",
2507 "read": "1.0.7", 2507 "read": "^1.0.7",
2508 "semver": "5.6.0", 2508 "semver": "^5.1.0",
2509 "tmp": "0.0.29", 2509 "tmp": "0.0.29",
2510 "url-join": "1.1.0", 2510 "url-join": "^1.1.0",
2511 "vso-node-api": "6.1.2-preview", 2511 "vso-node-api": "6.1.2-preview",
2512 "yauzl": "2.10.0", 2512 "yauzl": "^2.3.1",
2513 "yazl": "2.5.1" 2513 "yazl": "^2.2.2"
2514 } 2514 }
2515 }, 2515 },
2516 "vscode": { 2516 "vscode": {
@@ -2519,20 +2519,20 @@
2519 "integrity": "sha512-z1Nf5J38gjUFbuDCbJHPN6OJ//5EG+e/yHlh6ERxj/U9B2Qc3aiHaFr38/fee/GGnxvRw/XegLMOG+UJwKi/Qg==", 2519 "integrity": "sha512-z1Nf5J38gjUFbuDCbJHPN6OJ//5EG+e/yHlh6ERxj/U9B2Qc3aiHaFr38/fee/GGnxvRw/XegLMOG+UJwKi/Qg==",
2520 "dev": true, 2520 "dev": true,
2521 "requires": { 2521 "requires": {
2522 "glob": "7.1.3", 2522 "glob": "^7.1.2",
2523 "gulp-chmod": "2.0.0", 2523 "gulp-chmod": "^2.0.0",
2524 "gulp-filter": "5.1.0", 2524 "gulp-filter": "^5.0.1",
2525 "gulp-gunzip": "1.0.0", 2525 "gulp-gunzip": "1.0.0",
2526 "gulp-remote-src-vscode": "0.5.1", 2526 "gulp-remote-src-vscode": "^0.5.1",
2527 "gulp-untar": "0.0.7", 2527 "gulp-untar": "^0.0.7",
2528 "gulp-vinyl-zip": "2.1.2", 2528 "gulp-vinyl-zip": "^2.1.2",
2529 "mocha": "4.1.0", 2529 "mocha": "^4.0.1",
2530 "request": "2.88.0", 2530 "request": "^2.88.0",
2531 "semver": "5.6.0", 2531 "semver": "^5.4.1",
2532 "source-map-support": "0.5.9", 2532 "source-map-support": "^0.5.0",
2533 "url-parse": "1.4.4", 2533 "url-parse": "^1.4.3",
2534 "vinyl-fs": "3.0.3", 2534 "vinyl-fs": "^3.0.3",
2535 "vinyl-source-stream": "1.1.2" 2535 "vinyl-source-stream": "^1.1.0"
2536 } 2536 }
2537 }, 2537 },
2538 "vscode-jsonrpc": { 2538 "vscode-jsonrpc": {
@@ -2545,7 +2545,7 @@
2545 "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", 2545 "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz",
2546 "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", 2546 "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==",
2547 "requires": { 2547 "requires": {
2548 "semver": "5.6.0", 2548 "semver": "^5.5.0",
2549 "vscode-languageserver-protocol": "3.14.1" 2549 "vscode-languageserver-protocol": "3.14.1"
2550 } 2550 }
2551 }, 2551 },
@@ -2554,7 +2554,7 @@
2554 "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", 2554 "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz",
2555 "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", 2555 "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==",
2556 "requires": { 2556 "requires": {
2557 "vscode-jsonrpc": "4.0.0", 2557 "vscode-jsonrpc": "^4.0.0",
2558 "vscode-languageserver-types": "3.14.0" 2558 "vscode-languageserver-types": "3.14.0"
2559 } 2559 }
2560 }, 2560 },
@@ -2569,10 +2569,10 @@
2569 "integrity": "sha1-qrNUbfJFHs2JTgcbuZtd8Zxfp48=", 2569 "integrity": "sha1-qrNUbfJFHs2JTgcbuZtd8Zxfp48=",
2570 "dev": true, 2570 "dev": true,
2571 "requires": { 2571 "requires": {
2572 "q": "1.5.1", 2572 "q": "^1.0.1",
2573 "tunnel": "0.0.4", 2573 "tunnel": "0.0.4",
2574 "typed-rest-client": "0.9.0", 2574 "typed-rest-client": "^0.9.0",
2575 "underscore": "1.9.1" 2575 "underscore": "^1.8.3"
2576 } 2576 }
2577 }, 2577 },
2578 "wrappy": { 2578 "wrappy": {
@@ -2593,8 +2593,8 @@
2593 "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", 2593 "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
2594 "dev": true, 2594 "dev": true,
2595 "requires": { 2595 "requires": {
2596 "buffer-crc32": "0.2.13", 2596 "buffer-crc32": "~0.2.3",
2597 "fd-slicer": "1.1.0" 2597 "fd-slicer": "~1.1.0"
2598 } 2598 }
2599 }, 2599 },
2600 "yazl": { 2600 "yazl": {
@@ -2603,7 +2603,7 @@
2603 "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", 2603 "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
2604 "dev": true, 2604 "dev": true,
2605 "requires": { 2605 "requires": {
2606 "buffer-crc32": "0.2.13" 2606 "buffer-crc32": "~0.2.3"
2607 } 2607 }
2608 } 2608 }
2609 } 2609 }
diff --git a/editors/code/package.json b/editors/code/package.json
index e0db3c337..9b8f6351b 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -214,4 +214,4 @@
214 } 214 }
215 ] 215 ]
216 } 216 }
217} \ No newline at end of file 217}
diff --git a/editors/code/src/commands/apply_source_change.ts b/editors/code/src/commands/apply_source_change.ts
index cf921e3ac..d96ace979 100644
--- a/editors/code/src/commands/apply_source_change.ts
+++ b/editors/code/src/commands/apply_source_change.ts
@@ -3,53 +3,31 @@ import * as lc from 'vscode-languageclient';
3 3
4import { Server } from '../server'; 4import { Server } from '../server';
5 5
6interface FileSystemEdit {
7 type: string;
8 uri?: string;
9 src?: string;
10 dst?: string;
11}
12
13export interface SourceChange { 6export interface SourceChange {
14 label: string; 7 label: string;
15 sourceFileEdits: lc.TextDocumentEdit[]; 8 workspaceEdit: lc.WorkspaceEdit;
16 fileSystemEdits: FileSystemEdit[];
17 cursorPosition?: lc.TextDocumentPositionParams; 9 cursorPosition?: lc.TextDocumentPositionParams;
18} 10}
19 11
20export async function handle(change: SourceChange) { 12export async function handle(change: SourceChange) {
21 const wsEdit = new vscode.WorkspaceEdit(); 13 const wsEdit = Server.client.protocol2CodeConverter.asWorkspaceEdit(change.workspaceEdit);
22 for (const sourceEdit of change.sourceFileEdits) {
23 const uri = Server.client.protocol2CodeConverter.asUri(
24 sourceEdit.textDocument.uri
25 );
26 const edits = Server.client.protocol2CodeConverter.asTextEdits(
27 sourceEdit.edits
28 );
29 wsEdit.set(uri, edits);
30 }
31 let created; 14 let created;
32 let moved; 15 let moved;
33 for (const fsEdit of change.fileSystemEdits) { 16 if (change.workspaceEdit.documentChanges) {
34 switch (fsEdit.type) { 17 for (const docChange of change.workspaceEdit.documentChanges) {
35 case 'createFile': 18 if (lc.CreateFile.is(docChange)) {
36 const uri = vscode.Uri.parse(fsEdit.uri!); 19 created = docChange.uri;
37 wsEdit.createFile(uri); 20 } else if (lc.RenameFile.is(docChange)) {
38 created = uri; 21 moved = docChange.newUri;
39 break; 22 }
40 case 'moveFile':
41 const src = vscode.Uri.parse(fsEdit.src!);
42 const dst = vscode.Uri.parse(fsEdit.dst!);
43 wsEdit.renameFile(src, dst);
44 moved = dst;
45 break;
46 } 23 }
47 } 24 }
48 const toOpen = created || moved; 25 const toOpen = created || moved;
49 const toReveal = change.cursorPosition; 26 const toReveal = change.cursorPosition;
50 await vscode.workspace.applyEdit(wsEdit); 27 await vscode.workspace.applyEdit(wsEdit);
51 if (toOpen) { 28 if (toOpen) {
52 const doc = await vscode.workspace.openTextDocument(toOpen); 29 const toOpenUri = vscode.Uri.parse(toOpen);
30 const doc = await vscode.workspace.openTextDocument(toOpenUri);
53 await vscode.window.showTextDocument(doc); 31 await vscode.window.showTextDocument(doc);
54 } else if (toReveal) { 32 } else if (toReveal) {
55 const uri = Server.client.protocol2CodeConverter.asUri( 33 const uri = Server.client.protocol2CodeConverter.asUri(
@@ -65,6 +43,6 @@ export async function handle(change: SourceChange) {
65 if (!editor.selection.isEmpty) { 43 if (!editor.selection.isEmpty) {
66 return; 44 return;
67 } 45 }
68 editor!.selection = new vscode.Selection(position, position); 46 editor.selection = new vscode.Selection(position, position);
69 } 47 }
70} 48}