aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock58
-rw-r--r--Cargo.toml1
-rw-r--r--crates/ra_editor/src/code_actions.rs18
-rw-r--r--crates/ra_editor/src/completion.rs13
-rw-r--r--crates/ra_editor/src/extend_selection.rs18
-rw-r--r--crates/ra_editor/src/folding_ranges.rs10
-rw-r--r--crates/ra_editor/src/lib.rs10
-rw-r--r--crates/ra_editor/src/scope/fn_scope.rs6
-rw-r--r--crates/ra_editor/src/symbols.rs4
-rw-r--r--crates/ra_editor/src/typing.rs3
-rw-r--r--crates/ra_syntax/Cargo.toml3
-rw-r--r--crates/ra_syntax/src/algo/mod.rs24
-rw-r--r--crates/ra_syntax/src/algo/walk.rs6
-rw-r--r--crates/ra_syntax/src/ast/mod.rs13
-rw-r--r--crates/ra_syntax/src/lib.rs15
-rw-r--r--crates/ra_syntax/src/reparsing.rs10
-rw-r--r--crates/ra_syntax/src/utils.rs8
-rw-r--r--crates/ra_syntax/src/yellow/builder.rs32
-rw-r--r--crates/ra_syntax/src/yellow/green.rs90
-rw-r--r--crates/ra_syntax/src/yellow/mod.rs194
-rw-r--r--crates/ra_syntax/src/yellow/red.rs113
-rw-r--r--crates/ra_syntax/src/yellow/syntax.rs215
-rw-r--r--crates/ra_syntax/src/yellow/syntax_text.rs6
24 files changed, 240 insertions, 631 deletions
diff --git a/.gitignore b/.gitignore
index 531323cf0..6f43069b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
1/target/ 1/target/
2**/*.rs.bk 2**/*.rs.bk
3.idea/*
3.vscode/* 4.vscode/*
4*.log 5*.log
diff --git a/Cargo.lock b/Cargo.lock
index 815c97483..256821a2e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -81,7 +81,7 @@ dependencies = [
81 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 81 "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
82 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 82 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
83 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 83 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
84 "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 84 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
85] 85]
86 86
87[[package]] 87[[package]]
@@ -279,7 +279,7 @@ dependencies = [
279 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 279 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
280 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 280 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
281 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 281 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
282 "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 282 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
283] 283]
284 284
285[[package]] 285[[package]]
@@ -312,7 +312,7 @@ dependencies = [
312 312
313[[package]] 313[[package]]
314name = "im" 314name = "im"
315version = "12.0.0" 315version = "12.1.0"
316source = "registry+https://github.com/rust-lang/crates.io-index" 316source = "registry+https://github.com/rust-lang/crates.io-index"
317dependencies = [ 317dependencies = [
318 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 318 "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -347,7 +347,7 @@ dependencies = [
347 "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 347 "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
348 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 348 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
349 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 349 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
350 "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 350 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
351 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 351 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
352 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 352 "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
353] 353]
@@ -357,7 +357,7 @@ name = "lazy_static"
357version = "1.1.0" 357version = "1.1.0"
358source = "registry+https://github.com/rust-lang/crates.io-index" 358source = "registry+https://github.com/rust-lang/crates.io-index"
359dependencies = [ 359dependencies = [
360 "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 360 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
361] 361]
362 362
363[[package]] 363[[package]]
@@ -367,7 +367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
367 367
368[[package]] 368[[package]]
369name = "lock_api" 369name = "lock_api"
370version = "0.1.3" 370version = "0.1.4"
371source = "registry+https://github.com/rust-lang/crates.io-index" 371source = "registry+https://github.com/rust-lang/crates.io-index"
372dependencies = [ 372dependencies = [
373 "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 373 "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -394,7 +394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
394dependencies = [ 394dependencies = [
395 "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 395 "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
396 "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 396 "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
397 "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 397 "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
398] 398]
399 399
400[[package]] 400[[package]]
@@ -469,7 +469,7 @@ name = "parking_lot"
469version = "0.6.4" 469version = "0.6.4"
470source = "registry+https://github.com/rust-lang/crates.io-index" 470source = "registry+https://github.com/rust-lang/crates.io-index"
471dependencies = [ 471dependencies = [
472 "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 472 "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
473 "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 473 "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
474] 474]
475 475
@@ -532,7 +532,7 @@ version = "0.1.0"
532dependencies = [ 532dependencies = [
533 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 533 "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
534 "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 534 "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
535 "im 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 535 "im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
536 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 536 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
537 "once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 537 "once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
538 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 538 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -577,7 +577,7 @@ dependencies = [
577 "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 577 "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
578 "flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", 578 "flexi_logger 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
579 "gen_lsp_server 0.1.0", 579 "gen_lsp_server 0.1.0",
580 "im 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 580 "im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
581 "languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)", 581 "languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
582 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 582 "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
583 "ra_analysis 0.1.0", 583 "ra_analysis 0.1.0",
@@ -587,7 +587,7 @@ dependencies = [
587 "relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 587 "relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
588 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 588 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
589 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 589 "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
590 "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 590 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
591 "smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 591 "smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
592 "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 592 "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
593 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 593 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -602,9 +602,8 @@ dependencies = [
602 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 602 "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
603 "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", 603 "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
604 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 604 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
605 "smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 605 "rowan 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
606 "test_utils 0.1.0", 606 "test_utils 0.1.0",
607 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
608 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 607 "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
609 "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 608 "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
610] 609]
@@ -714,6 +713,16 @@ dependencies = [
714] 713]
715 714
716[[package]] 715[[package]]
716name = "rowan"
717version = "0.1.0"
718source = "registry+https://github.com/rust-lang/crates.io-index"
719dependencies = [
720 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
721 "smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
722 "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
723]
724
725[[package]]
717name = "rustc-demangle" 726name = "rustc-demangle"
718version = "0.1.9" 727version = "0.1.9"
719source = "registry+https://github.com/rust-lang/crates.io-index" 728source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -740,7 +749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
740name = "salsa" 749name = "salsa"
741version = "0.1.0" 750version = "0.1.0"
742dependencies = [ 751dependencies = [
743 "im 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 752 "im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
744 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 753 "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
745] 754]
746 755
@@ -786,12 +795,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
786dependencies = [ 795dependencies = [
787 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 796 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
788 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 797 "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
789 "syn 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)", 798 "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
790] 799]
791 800
792[[package]] 801[[package]]
793name = "serde_json" 802name = "serde_json"
794version = "1.0.28" 803version = "1.0.31"
795source = "registry+https://github.com/rust-lang/crates.io-index" 804source = "registry+https://github.com/rust-lang/crates.io-index"
796dependencies = [ 805dependencies = [
797 "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 806 "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -860,7 +869,7 @@ dependencies = [
860 869
861[[package]] 870[[package]]
862name = "syn" 871name = "syn"
863version = "0.15.5" 872version = "0.15.7"
864source = "registry+https://github.com/rust-lang/crates.io-index" 873source = "registry+https://github.com/rust-lang/crates.io-index"
865dependencies = [ 874dependencies = [
866 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 875 "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -910,7 +919,7 @@ dependencies = [
910 "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", 919 "pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
911 "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 920 "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
912 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", 921 "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
913 "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", 922 "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
914 "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 923 "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
915 "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 924 "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
916 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 925 "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1108,7 +1117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1108 1117
1109[[package]] 1118[[package]]
1110name = "version_check" 1119name = "version_check"
1111version = "0.1.4" 1120version = "0.1.5"
1112source = "registry+https://github.com/rust-lang/crates.io-index" 1121source = "registry+https://github.com/rust-lang/crates.io-index"
1113 1122
1114[[package]] 1123[[package]]
@@ -1190,14 +1199,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1190"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" 1199"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
1191"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" 1200"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
1192"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1201"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
1193"checksum im 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ca4b379f0383e3a502dfdd6a9424fd9707633160d5215bb42d7e00db8a056ab" 1202"checksum im 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90742b94a13db9b161eeab35f89bc9723634eb72bfd124f3ebb025734fdfef18"
1194"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" 1203"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
1195"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" 1204"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
1196"checksum join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7bddc885f3fd69dd4b5d747c2efe6dd2c36d795ea9938281ed50910e32c95e31" 1205"checksum join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7bddc885f3fd69dd4b5d747c2efe6dd2c36d795ea9938281ed50910e32c95e31"
1197"checksum languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)" = "caecadd973c43c93f5ce96fa457da310113d867af28808a8ed74023e9887a39e" 1206"checksum languageserver-types 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)" = "caecadd973c43c93f5ce96fa457da310113d867af28808a8ed74023e9887a39e"
1198"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" 1207"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
1199"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" 1208"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
1200"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" 1209"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a"
1201"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" 1210"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
1202"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1211"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
1203"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" 1212"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
@@ -1230,6 +1239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1230"checksum relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e614f96449605730b4f7ad2c019e88c1652d730634b4eba07b810801856635e3" 1239"checksum relative-path 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e614f96449605730b4f7ad2c019e88c1652d730634b4eba07b810801856635e3"
1231"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" 1240"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
1232"checksum ron 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9fa11b7a38511d46ff1959ae46ebb60bd8a746f17bdd0206b4c8de7559ac47b" 1241"checksum ron 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9fa11b7a38511d46ff1959ae46ebb60bd8a746f17bdd0206b4c8de7559ac47b"
1242"checksum rowan 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4a1a7366ece9deee5e7df8316a136d585d5c5042854c2297f7f1aee3014c9130"
1233"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" 1243"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
1234"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1244"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
1235"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" 1245"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
@@ -1240,7 +1250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1240"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1250"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
1241"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" 1251"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
1242"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe" 1252"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
1243"checksum serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "d30ec34ac923489285d24688c7a9c0898d16edff27fc1f1bd854edeff6ca3b7f" 1253"checksum serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "bb47a3d5c84320222f66d7db21157c4a7407755de41798f9b4c1c40593397b1a"
1244"checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" 1254"checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
1245"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" 1255"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
1246"checksum smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "248055d41f4c53f8ee7048e8a578a5190d0cca306630718091e4d481735e44b9" 1256"checksum smol_str 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "248055d41f4c53f8ee7048e8a578a5190d0cca306630718091e4d481735e44b9"
@@ -1249,7 +1259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1249"checksum superslice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50b13d42370e0f5fc62eafdd5c2d20065eaf5458dab215ff3e20e63eea96b30" 1259"checksum superslice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50b13d42370e0f5fc62eafdd5c2d20065eaf5458dab215ff3e20e63eea96b30"
1250"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 1260"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
1251"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" 1261"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
1252"checksum syn 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5522da8e493dbd7703e88ec5518546ed45c30efa2699f291a7bd0a08fb0a6ab6" 1262"checksum syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)" = "455a6ec9b368f8c479b0ae5494d13b22dc00990d2f00d68c9dc6a2dc4f17f210"
1253"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 1263"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
1254"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" 1264"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
1255"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" 1265"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
@@ -1278,7 +1288,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1278"checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" 1288"checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
1279"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" 1289"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
1280"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" 1290"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
1281"checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" 1291"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
1282"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1292"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
1283"checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35" 1293"checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35"
1284"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" 1294"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
diff --git a/Cargo.toml b/Cargo.toml
index 5cfc064b5..8e4e84729 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,6 @@
1[workspace] 1[workspace]
2members = [ "crates/*" ] 2members = [ "crates/*" ]
3exclude = [ "crates/rowan"]
3 4
4[profile.release] 5[profile.release]
5debug = true 6debug = true
diff --git a/crates/ra_editor/src/code_actions.rs b/crates/ra_editor/src/code_actions.rs
index 83f7956d2..216d592ff 100644
--- a/crates/ra_editor/src/code_actions.rs
+++ b/crates/ra_editor/src/code_actions.rs
@@ -1,15 +1,13 @@
1use join_to_string::join; 1use join_to_string::join;
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 File, TextUnit, TextRange, 4 File, TextUnit, TextRange, Direction,
5 ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner}, 5 ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner},
6 SyntaxKind::{COMMA, WHITESPACE}, 6 SyntaxKind::{COMMA, WHITESPACE},
7 SyntaxNodeRef, 7 SyntaxNodeRef,
8 algo::{ 8 algo::{
9 Direction, siblings,
10 find_leaf_at_offset, 9 find_leaf_at_offset,
11 find_covering_node, 10 find_covering_node,
12 ancestors,
13 }, 11 },
14}; 12};
15 13
@@ -25,12 +23,12 @@ pub fn flip_comma<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce()
25 let syntax = file.syntax(); 23 let syntax = file.syntax();
26 24
27 let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?; 25 let comma = find_leaf_at_offset(syntax, offset).find(|leaf| leaf.kind() == COMMA)?;
28 let left = non_trivia_sibling(comma, Direction::Backward)?; 26 let prev = non_trivia_sibling(comma, Direction::Prev)?;
29 let right = non_trivia_sibling(comma, Direction::Forward)?; 27 let next = non_trivia_sibling(comma, Direction::Next)?;
30 Some(move || { 28 Some(move || {
31 let mut edit = EditBuilder::new(); 29 let mut edit = EditBuilder::new();
32 edit.replace(left.range(), right.text().to_string()); 30 edit.replace(prev.range(), next.text().to_string());
33 edit.replace(right.range(), left.text().to_string()); 31 edit.replace(next.range(), prev.text().to_string());
34 LocalEdit { 32 LocalEdit {
35 edit: edit.finish(), 33 edit: edit.finish(),
36 cursor_position: None, 34 cursor_position: None,
@@ -101,8 +99,8 @@ pub fn add_impl<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() ->
101 99
102pub fn introduce_variable<'a>(file: &'a File, range: TextRange) -> Option<impl FnOnce() -> LocalEdit + 'a> { 100pub fn introduce_variable<'a>(file: &'a File, range: TextRange) -> Option<impl FnOnce() -> LocalEdit + 'a> {
103 let node = find_covering_node(file.syntax(), range); 101 let node = find_covering_node(file.syntax(), range);
104 let expr = ancestors(node).filter_map(ast::Expr::cast).next()?; 102 let expr = node.ancestors().filter_map(ast::Expr::cast).next()?;
105 let anchor_stmt = ancestors(expr.syntax()).filter_map(ast::Stmt::cast).next()?; 103 let anchor_stmt = expr.syntax().ancestors().filter_map(ast::Stmt::cast).next()?;
106 let indent = anchor_stmt.syntax().prev_sibling()?; 104 let indent = anchor_stmt.syntax().prev_sibling()?;
107 if indent.kind() != WHITESPACE { 105 if indent.kind() != WHITESPACE {
108 return None; 106 return None;
@@ -130,7 +128,7 @@ pub fn introduce_variable<'a>(file: &'a File, range: TextRange) -> Option<impl F
130} 128}
131 129
132fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { 130fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> {
133 siblings(node, direction) 131 node.siblings(direction)
134 .skip(1) 132 .skip(1)
135 .find(|node| !node.kind().is_trivia()) 133 .find(|node| !node.kind().is_trivia())
136} 134}
diff --git a/crates/ra_editor/src/completion.rs b/crates/ra_editor/src/completion.rs
index ff9de20d3..62a63fb04 100644
--- a/crates/ra_editor/src/completion.rs
+++ b/crates/ra_editor/src/completion.rs
@@ -4,7 +4,6 @@ use ra_syntax::{
4 File, TextUnit, AstNode, SyntaxNodeRef, SyntaxKind::*, 4 File, TextUnit, AstNode, SyntaxNodeRef, SyntaxKind::*,
5 ast::{self, LoopBodyOwner, ModuleItemOwner}, 5 ast::{self, LoopBodyOwner, ModuleItemOwner},
6 algo::{ 6 algo::{
7 ancestors,
8 visit::{visitor, Visitor, visitor_ctx, VisitorCtx}, 7 visit::{visitor, Visitor, visitor_ctx, VisitorCtx},
9 }, 8 },
10 text_utils::is_subrange, 9 text_utils::is_subrange,
@@ -59,7 +58,7 @@ fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<Completi
59 return; 58 return;
60 } 59 }
61 let mut visited_fn = false; 60 let mut visited_fn = false;
62 for node in ancestors(name_ref.syntax()) { 61 for node in name_ref.syntax().ancestors() {
63 if let Some(items) = visitor() 62 if let Some(items) = visitor()
64 .visit::<ast::Root, _>(|it| Some(it.items())) 63 .visit::<ast::Root, _>(|it| Some(it.items()))
65 .visit::<ast::Module, _>(|it| Some(it.item_list()?.items())) 64 .visit::<ast::Module, _>(|it| Some(it.item_list()?.items()))
@@ -92,7 +91,7 @@ fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<Completi
92 91
93fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) { 92fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) {
94 let mut params = HashMap::new(); 93 let mut params = HashMap::new();
95 for node in ancestors(ctx) { 94 for node in ctx.ancestors() {
96 let _ = visitor_ctx(&mut params) 95 let _ = visitor_ctx(&mut params)
97 .visit::<ast::Root, _>(process) 96 .visit::<ast::Root, _>(process)
98 .visit::<ast::ItemList, _>(process) 97 .visit::<ast::ItemList, _>(process)
@@ -123,7 +122,7 @@ fn param_completions(ctx: SyntaxNodeRef, acc: &mut Vec<CompletionItem>) {
123} 122}
124 123
125fn is_node<'a, N: AstNode<'a>>(node: SyntaxNodeRef<'a>) -> bool { 124fn is_node<'a, N: AstNode<'a>>(node: SyntaxNodeRef<'a>) -> bool {
126 match ancestors(node).filter_map(N::cast).next() { 125 match node.ancestors().filter_map(N::cast).next() {
127 None => false, 126 None => false,
128 Some(n) => n.syntax().range() == node.range(), 127 Some(n) => n.syntax().range() == node.range(),
129 } 128 }
@@ -152,7 +151,7 @@ fn complete_expr_keywords(file: &File, fn_def: ast::FnDef, name_ref: ast::NameRe
152} 151}
153 152
154fn is_in_loop_body(name_ref: ast::NameRef) -> bool { 153fn is_in_loop_body(name_ref: ast::NameRef) -> bool {
155 for node in ancestors(name_ref.syntax()) { 154 for node in name_ref.syntax().ancestors() {
156 if node.kind() == FN_DEF || node.kind() == LAMBDA_EXPR { 155 if node.kind() == FN_DEF || node.kind() == LAMBDA_EXPR {
157 break; 156 break;
158 } 157 }
@@ -171,7 +170,7 @@ fn is_in_loop_body(name_ref: ast::NameRef) -> bool {
171} 170}
172 171
173fn complete_return(fn_def: ast::FnDef, name_ref: ast::NameRef) -> Option<CompletionItem> { 172fn complete_return(fn_def: ast::FnDef, name_ref: ast::NameRef) -> Option<CompletionItem> {
174 // let is_last_in_block = ancestors(name_ref.syntax()).filter_map(ast::Expr::cast) 173 // let is_last_in_block = name_ref.syntax().ancestors().filter_map(ast::Expr::cast)
175 // .next() 174 // .next()
176 // .and_then(|it| it.syntax().parent()) 175 // .and_then(|it| it.syntax().parent())
177 // .and_then(ast::Block::cast) 176 // .and_then(ast::Block::cast)
@@ -181,7 +180,7 @@ fn complete_return(fn_def: ast::FnDef, name_ref: ast::NameRef) -> Option<Complet
181 // return None; 180 // return None;
182 // } 181 // }
183 182
184 let is_stmt = match ancestors(name_ref.syntax()).filter_map(ast::ExprStmt::cast).next() { 183 let is_stmt = match name_ref.syntax().ancestors().filter_map(ast::ExprStmt::cast).next() {
185 None => false, 184 None => false,
186 Some(expr_stmt) => expr_stmt.syntax().range() == name_ref.syntax().range() 185 Some(expr_stmt) => expr_stmt.syntax().range() == name_ref.syntax().range()
187 }; 186 };
diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs
index dc914a26a..b00a457b9 100644
--- a/crates/ra_editor/src/extend_selection.rs
+++ b/crates/ra_editor/src/extend_selection.rs
@@ -1,7 +1,7 @@
1use ra_syntax::{ 1use ra_syntax::{
2 File, TextRange, SyntaxNodeRef, TextUnit, 2 File, TextRange, SyntaxNodeRef, TextUnit, Direction,
3 SyntaxKind::*, 3 SyntaxKind::*,
4 algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node, ancestors, Direction, siblings}, 4 algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node},
5}; 5};
6 6
7pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { 7pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> {
@@ -30,7 +30,7 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange>
30 } 30 }
31 } 31 }
32 32
33 match ancestors(node).skip_while(|n| n.range() == range).next() { 33 match node.ancestors().skip_while(|n| n.range() == range).next() {
34 None => None, 34 None => None,
35 Some(parent) => Some(parent.range()), 35 Some(parent) => Some(parent.range()),
36 } 36 }
@@ -71,12 +71,12 @@ fn pick_best<'a>(l: SyntaxNodeRef<'a>, r: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a
71} 71}
72 72
73fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> { 73fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
74 let left = adj_comments(node, Direction::Backward); 74 let prev = adj_comments(node, Direction::Prev);
75 let right = adj_comments(node, Direction::Forward); 75 let next = adj_comments(node, Direction::Next);
76 if left != right { 76 if prev != next {
77 Some(TextRange::from_to( 77 Some(TextRange::from_to(
78 left.range().start(), 78 prev.range().start(),
79 right.range().end(), 79 next.range().end(),
80 )) 80 ))
81 } else { 81 } else {
82 None 82 None
@@ -85,7 +85,7 @@ fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
85 85
86fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef { 86fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef {
87 let mut res = node; 87 let mut res = node;
88 for node in siblings(node, dir) { 88 for node in node.siblings(dir) {
89 match node.kind() { 89 match node.kind() {
90 COMMENT => res = node, 90 COMMENT => res = node,
91 WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), 91 WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
diff --git a/crates/ra_editor/src/folding_ranges.rs b/crates/ra_editor/src/folding_ranges.rs
index 817da28d1..733512368 100644
--- a/crates/ra_editor/src/folding_ranges.rs
+++ b/crates/ra_editor/src/folding_ranges.rs
@@ -3,7 +3,7 @@ use std::collections::HashSet;
3use ra_syntax::{ 3use ra_syntax::{
4 File, TextRange, SyntaxNodeRef, 4 File, TextRange, SyntaxNodeRef,
5 SyntaxKind, 5 SyntaxKind,
6 algo::{walk, Direction, siblings}, 6 Direction,
7}; 7};
8 8
9#[derive(Debug, PartialEq, Eq)] 9#[derive(Debug, PartialEq, Eq)]
@@ -19,12 +19,10 @@ pub struct Fold {
19} 19}
20 20
21pub fn folding_ranges(file: &File) -> Vec<Fold> { 21pub fn folding_ranges(file: &File) -> Vec<Fold> {
22 let syntax = file.syntax();
23
24 let mut res = vec![]; 22 let mut res = vec![];
25 let mut visited = HashSet::new(); 23 let mut visited = HashSet::new();
26 24
27 for node in walk::preorder(syntax) { 25 for node in file.syntax().descendants() {
28 if visited.contains(&node) { 26 if visited.contains(&node) {
29 continue; 27 continue;
30 } 28 }
@@ -64,7 +62,7 @@ fn contiguous_range_for<'a>(
64 62
65 let left = node; 63 let left = node;
66 let mut right = node; 64 let mut right = node;
67 for node in siblings(node, Direction::Forward) { 65 for node in node.siblings(Direction::Next) {
68 visited.insert(node); 66 visited.insert(node);
69 match node.kind() { 67 match node.kind() {
70 SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), 68 SyntaxKind::WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
@@ -139,4 +137,4 @@ fn main() {
139 } 137 }
140 138
141 139
142} \ No newline at end of file 140}
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs
index de929d73a..a93924e00 100644
--- a/crates/ra_editor/src/lib.rs
+++ b/crates/ra_editor/src/lib.rs
@@ -21,7 +21,7 @@ mod test_utils;
21use ra_syntax::{ 21use ra_syntax::{
22 File, TextUnit, TextRange, SyntaxNodeRef, 22 File, TextUnit, TextRange, SyntaxNodeRef,
23 ast::{self, AstNode, NameOwner}, 23 ast::{self, AstNode, NameOwner},
24 algo::{walk, find_leaf_at_offset, ancestors}, 24 algo::find_leaf_at_offset,
25 SyntaxKind::{self, *}, 25 SyntaxKind::{self, *},
26}; 26};
27pub use ra_syntax::AtomEdit; 27pub use ra_syntax::AtomEdit;
@@ -86,7 +86,7 @@ pub fn matching_brace(file: &File, offset: TextUnit) -> Option<TextUnit> {
86 86
87pub fn highlight(file: &File) -> Vec<HighlightedRange> { 87pub fn highlight(file: &File) -> Vec<HighlightedRange> {
88 let mut res = Vec::new(); 88 let mut res = Vec::new();
89 for node in walk::preorder(file.syntax()) { 89 for node in file.syntax().descendants() {
90 let tag = match node.kind() { 90 let tag = match node.kind() {
91 ERROR => "error", 91 ERROR => "error",
92 COMMENT | DOC_COMMENT => "comment", 92 COMMENT | DOC_COMMENT => "comment",
@@ -110,7 +110,7 @@ pub fn highlight(file: &File) -> Vec<HighlightedRange> {
110pub fn diagnostics(file: &File) -> Vec<Diagnostic> { 110pub fn diagnostics(file: &File) -> Vec<Diagnostic> {
111 let mut res = Vec::new(); 111 let mut res = Vec::new();
112 112
113 for node in walk::preorder(file.syntax()) { 113 for node in file.syntax().descendants() {
114 if node.kind() == ERROR { 114 if node.kind() == ERROR {
115 res.push(Diagnostic { 115 res.push(Diagnostic {
116 range: node.range(), 116 range: node.range(),
@@ -130,7 +130,7 @@ pub fn syntax_tree(file: &File) -> String {
130} 130}
131 131
132pub fn runnables(file: &File) -> Vec<Runnable> { 132pub fn runnables(file: &File) -> Vec<Runnable> {
133 walk::preorder(file.syntax()) 133 file.syntax().descendants()
134 .filter_map(ast::FnDef::cast) 134 .filter_map(ast::FnDef::cast)
135 .filter_map(|f| { 135 .filter_map(|f| {
136 let name = f.name()?.text(); 136 let name = f.name()?.text();
@@ -159,7 +159,7 @@ pub fn find_node_at_offset<'a, N: AstNode<'a>>(
159 let leaf = leaves.clone() 159 let leaf = leaves.clone()
160 .find(|leaf| !leaf.kind().is_trivia()) 160 .find(|leaf| !leaf.kind().is_trivia())
161 .or_else(|| leaves.right_biased())?; 161 .or_else(|| leaves.right_biased())?;
162 ancestors(leaf) 162 leaf.ancestors()
163 .filter_map(N::cast) 163 .filter_map(N::cast)
164 .next() 164 .next()
165} 165}
diff --git a/crates/ra_editor/src/scope/fn_scope.rs b/crates/ra_editor/src/scope/fn_scope.rs
index 3ae5276a2..eddd87495 100644
--- a/crates/ra_editor/src/scope/fn_scope.rs
+++ b/crates/ra_editor/src/scope/fn_scope.rs
@@ -6,7 +6,7 @@ use std::{
6use ra_syntax::{ 6use ra_syntax::{
7 SyntaxNodeRef, SyntaxNode, SmolStr, AstNode, 7 SyntaxNodeRef, SyntaxNode, SmolStr, AstNode,
8 ast::{self, NameOwner, LoopBodyOwner, ArgListOwner}, 8 ast::{self, NameOwner, LoopBodyOwner, ArgListOwner},
9 algo::{ancestors, generate, walk::preorder} 9 algo::{generate}
10}; 10};
11 11
12type ScopeId = usize; 12type ScopeId = usize;
@@ -51,7 +51,7 @@ impl FnScopes {
51 res 51 res
52 } 52 }
53 fn add_bindings(&mut self, scope: ScopeId, pat: ast::Pat) { 53 fn add_bindings(&mut self, scope: ScopeId, pat: ast::Pat) {
54 let entries = preorder(pat.syntax()) 54 let entries = pat.syntax().descendants()
55 .filter_map(ast::BindPat::cast) 55 .filter_map(ast::BindPat::cast)
56 .filter_map(ScopeEntry::new); 56 .filter_map(ScopeEntry::new);
57 self.scopes[scope].entries.extend(entries); 57 self.scopes[scope].entries.extend(entries);
@@ -66,7 +66,7 @@ impl FnScopes {
66 self.scope_for.insert(node.owned(), scope); 66 self.scope_for.insert(node.owned(), scope);
67 } 67 }
68 fn scope_for(&self, node: SyntaxNodeRef) -> Option<ScopeId> { 68 fn scope_for(&self, node: SyntaxNodeRef) -> Option<ScopeId> {
69 ancestors(node) 69 node.ancestors()
70 .filter_map(|it| self.scope_for.get(&it.owned()).map(|&scope| scope)) 70 .filter_map(|it| self.scope_for.get(&it.owned()).map(|&scope| scope))
71 .next() 71 .next()
72 } 72 }
diff --git a/crates/ra_editor/src/symbols.rs b/crates/ra_editor/src/symbols.rs
index 917984177..e5cc5ca28 100644
--- a/crates/ra_editor/src/symbols.rs
+++ b/crates/ra_editor/src/symbols.rs
@@ -3,7 +3,7 @@ use ra_syntax::{
3 ast::{self, NameOwner}, 3 ast::{self, NameOwner},
4 algo::{ 4 algo::{
5 visit::{visitor, Visitor}, 5 visit::{visitor, Visitor},
6 walk::{walk, WalkEvent, preorder}, 6 walk::{walk, WalkEvent},
7 }, 7 },
8}; 8};
9use TextRange; 9use TextRange;
@@ -25,7 +25,7 @@ pub struct FileSymbol {
25} 25}
26 26
27pub fn file_symbols(file: &File) -> Vec<FileSymbol> { 27pub fn file_symbols(file: &File) -> Vec<FileSymbol> {
28 preorder(file.syntax()) 28 file.syntax().descendants()
29 .filter_map(to_symbol) 29 .filter_map(to_symbol)
30 .collect() 30 .collect()
31} 31}
diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs
index 0f4e7e0d0..512076941 100644
--- a/crates/ra_editor/src/typing.rs
+++ b/crates/ra_editor/src/typing.rs
@@ -4,7 +4,6 @@ use ra_syntax::{
4 TextUnit, TextRange, SyntaxNodeRef, File, AstNode, SyntaxKind, 4 TextUnit, TextRange, SyntaxNodeRef, File, AstNode, SyntaxKind,
5 ast, 5 ast,
6 algo::{ 6 algo::{
7 walk::preorder,
8 find_covering_node, 7 find_covering_node,
9 }, 8 },
10 text_utils::{intersect, contains_offset_nonstrict}, 9 text_utils::{intersect, contains_offset_nonstrict},
@@ -33,7 +32,7 @@ pub fn join_lines(file: &File, range: TextRange) -> LocalEdit {
33 }; 32 };
34 let node = find_covering_node(file.syntax(), range); 33 let node = find_covering_node(file.syntax(), range);
35 let mut edit = EditBuilder::new(); 34 let mut edit = EditBuilder::new();
36 for node in preorder(node) { 35 for node in node.descendants() {
37 let text = match node.leaf_text() { 36 let text = match node.leaf_text() {
38 Some(text) => text, 37 Some(text) => text,
39 None => continue, 38 None => continue,
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index a0fd633e0..6345e4725 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -6,11 +6,10 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8unicode-xid = "0.1.0" 8unicode-xid = "0.1.0"
9text_unit = "0.1.4"
10itertools = "0.7.8" 9itertools = "0.7.8"
11drop_bomb = "0.1.4" 10drop_bomb = "0.1.4"
12parking_lot = "0.6.0" 11parking_lot = "0.6.0"
13smol_str = "0.1.6" 12rowan = "0.1.0"
14 13
15[dev-dependencies] 14[dev-dependencies]
16test_utils = { path = "../test_utils" } 15test_utils = { path = "../test_utils" }
diff --git a/crates/ra_syntax/src/algo/mod.rs b/crates/ra_syntax/src/algo/mod.rs
index 8de44c586..a6678093d 100644
--- a/crates/ra_syntax/src/algo/mod.rs
+++ b/crates/ra_syntax/src/algo/mod.rs
@@ -94,29 +94,9 @@ pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRe
94 common_ancestor(left, right) 94 common_ancestor(left, right)
95} 95}
96 96
97pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
98 generate(Some(node), |&node| node.parent())
99}
100
101#[derive(Debug)]
102pub enum Direction {
103 Forward,
104 Backward,
105}
106
107pub fn siblings<'a>(
108 node: SyntaxNodeRef<'a>,
109 direction: Direction
110) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
111 generate(Some(node), move |&node| match direction {
112 Direction::Forward => node.next_sibling(),
113 Direction::Backward => node.prev_sibling(),
114 })
115}
116
117fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { 97fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> {
118 for p in ancestors(n1) { 98 for p in n1.ancestors() {
119 if ancestors(n2).any(|a| a == p) { 99 if n2.ancestors().any(|a| a == p) {
120 return p; 100 return p;
121 } 101 }
122 } 102 }
diff --git a/crates/ra_syntax/src/algo/walk.rs b/crates/ra_syntax/src/algo/walk.rs
index 536ee705f..8e294d965 100644
--- a/crates/ra_syntax/src/algo/walk.rs
+++ b/crates/ra_syntax/src/algo/walk.rs
@@ -3,12 +3,6 @@ use {
3 algo::generate, 3 algo::generate,
4}; 4};
5 5
6pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
7 walk(root).filter_map(|event| match event {
8 WalkEvent::Enter(node) => Some(node),
9 WalkEvent::Exit(_) => None,
10 })
11}
12 6
13#[derive(Debug, Copy, Clone)] 7#[derive(Debug, Copy, Clone)]
14pub enum WalkEvent<'a> { 8pub enum WalkEvent<'a> {
diff --git a/crates/ra_syntax/src/ast/mod.rs b/crates/ra_syntax/src/ast/mod.rs
index a6da82957..c1570b868 100644
--- a/crates/ra_syntax/src/ast/mod.rs
+++ b/crates/ra_syntax/src/ast/mod.rs
@@ -3,10 +3,9 @@ mod generated;
3use std::marker::PhantomData; 3use std::marker::PhantomData;
4 4
5use itertools::Itertools; 5use itertools::Itertools;
6use smol_str::SmolStr;
7 6
8use { 7use {
9 SyntaxNodeRef, SyntaxKind::*, 8 SmolStr, SyntaxNodeRef, SyntaxKind::*,
10 yellow::{RefRoot, SyntaxNodeChildren}, 9 yellow::{RefRoot, SyntaxNodeChildren},
11}; 10};
12pub use self::generated::*; 11pub use self::generated::*;
@@ -76,7 +75,7 @@ impl<'a> Attr<'a> {
76 let tt = self.value()?; 75 let tt = self.value()?;
77 let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; 76 let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?;
78 if attr.kind() == IDENT { 77 if attr.kind() == IDENT {
79 Some(attr.leaf_text().unwrap()) 78 Some(attr.leaf_text().unwrap().clone())
80 } else { 79 } else {
81 None 80 None
82 } 81 }
@@ -87,7 +86,7 @@ impl<'a> Attr<'a> {
87 let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; 86 let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?;
88 let args = TokenTree::cast(args)?; 87 let args = TokenTree::cast(args)?;
89 if attr.kind() == IDENT { 88 if attr.kind() == IDENT {
90 Some((attr.leaf_text().unwrap(), args)) 89 Some((attr.leaf_text().unwrap().clone(), args))
91 } else { 90 } else {
92 None 91 None
93 } 92 }
@@ -96,7 +95,7 @@ impl<'a> Attr<'a> {
96 95
97impl<'a> Lifetime<'a> { 96impl<'a> Lifetime<'a> {
98 pub fn text(&self) -> SmolStr { 97 pub fn text(&self) -> SmolStr {
99 self.syntax().leaf_text().unwrap() 98 self.syntax().leaf_text().unwrap().clone()
100 } 99 }
101} 100}
102 101
@@ -104,7 +103,7 @@ impl<'a> Name<'a> {
104 pub fn text(&self) -> SmolStr { 103 pub fn text(&self) -> SmolStr {
105 let ident = self.syntax().first_child() 104 let ident = self.syntax().first_child()
106 .unwrap(); 105 .unwrap();
107 ident.leaf_text().unwrap() 106 ident.leaf_text().unwrap().clone()
108 } 107 }
109} 108}
110 109
@@ -112,7 +111,7 @@ impl<'a> NameRef<'a> {
112 pub fn text(&self) -> SmolStr { 111 pub fn text(&self) -> SmolStr {
113 let ident = self.syntax().first_child() 112 let ident = self.syntax().first_child()
114 .unwrap(); 113 .unwrap();
115 ident.leaf_text().unwrap() 114 ident.leaf_text().unwrap().clone()
116 } 115 }
117} 116}
118 117
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index eb271762e..738664afd 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -24,8 +24,7 @@ extern crate itertools;
24extern crate unicode_xid; 24extern crate unicode_xid;
25extern crate drop_bomb; 25extern crate drop_bomb;
26extern crate parking_lot; 26extern crate parking_lot;
27extern crate smol_str; 27extern crate rowan;
28extern crate text_unit;
29 28
30#[cfg(test)] 29#[cfg(test)]
31#[macro_use] 30#[macro_use]
@@ -48,17 +47,16 @@ pub mod utils;
48pub mod text_utils; 47pub mod text_utils;
49 48
50pub use { 49pub use {
51 text_unit::{TextRange, TextUnit}, 50 rowan::{SmolStr, TextRange, TextUnit},
52 smol_str::SmolStr,
53 ast::AstNode, 51 ast::AstNode,
54 lexer::{tokenize, Token}, 52 lexer::{tokenize, Token},
55 syntax_kinds::SyntaxKind, 53 syntax_kinds::SyntaxKind,
56 yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError}, 54 yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError, Direction},
57 reparsing::AtomEdit, 55 reparsing::AtomEdit,
58}; 56};
59 57
60use { 58use {
61 yellow::{GreenNode, SyntaxRoot}, 59 yellow::{GreenNode},
62}; 60};
63 61
64#[derive(Clone, Debug, Hash)] 62#[derive(Clone, Debug, Hash)]
@@ -68,8 +66,7 @@ pub struct File {
68 66
69impl File { 67impl File {
70 fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File { 68 fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File {
71 let root = SyntaxRoot::new(green, errors); 69 let root = SyntaxNode::new(green, errors);
72 let root = SyntaxNode::new_owned(root);
73 if cfg!(debug_assertions) { 70 if cfg!(debug_assertions) {
74 utils::validate_block_structure(root.borrowed()); 71 utils::validate_block_structure(root.borrowed());
75 } 72 }
@@ -100,6 +97,6 @@ impl File {
100 self.root.borrowed() 97 self.root.borrowed()
101 } 98 }
102 pub fn errors(&self) -> Vec<SyntaxError> { 99 pub fn errors(&self) -> Vec<SyntaxError> {
103 self.syntax().root.syntax_root().errors.clone() 100 self.root.root_data().clone()
104 } 101 }
105} 102}
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs
index da44913c5..dcafd2c40 100644
--- a/crates/ra_syntax/src/reparsing.rs
+++ b/crates/ra_syntax/src/reparsing.rs
@@ -1,11 +1,11 @@
1use algo; 1use algo;
2use grammar; 2use grammar;
3use lexer::{tokenize, Token}; 3use lexer::{tokenize, Token};
4use text_unit::{TextRange, TextUnit}; 4use yellow::{self, GreenNode, SyntaxNodeRef, SyntaxError};
5use yellow::{self, SyntaxNodeRef, GreenNode, SyntaxError};
6use parser_impl; 5use parser_impl;
7use parser_api::Parser; 6use parser_api::Parser;
8use { 7use {
8 TextUnit, TextRange,
9 SyntaxKind::*, 9 SyntaxKind::*,
10}; 10};
11use text_utils::replace_range; 11use text_utils::replace_range;
@@ -65,7 +65,7 @@ fn reparse_leaf<'node>(
65 return None; 65 return None;
66 } 66 }
67 67
68 let green = GreenNode::new_leaf(node.kind(), &text); 68 let green = GreenNode::new_leaf(node.kind(), text.into());
69 let new_errors = vec![]; 69 let new_errors = vec![];
70 Some((node, green, new_errors)) 70 Some((node, green, new_errors))
71 } 71 }
@@ -112,7 +112,7 @@ fn find_reparsable_node<'node>(
112 range: TextRange, 112 range: TextRange,
113) -> Option<(SyntaxNodeRef<'node>, fn(&mut Parser))> { 113) -> Option<(SyntaxNodeRef<'node>, fn(&mut Parser))> {
114 let node = algo::find_covering_node(node, range); 114 let node = algo::find_covering_node(node, range);
115 return algo::ancestors(node) 115 return node.ancestors()
116 .filter_map(|node| reparser(node).map(|r| (node, r))) 116 .filter_map(|node| reparser(node).map(|r| (node, r)))
117 .next(); 117 .next();
118 118
@@ -340,4 +340,4 @@ enum Foo {
340} 340}
341", "Clone"); 341", "Clone");
342 } 342 }
343} \ No newline at end of file 343}
diff --git a/crates/ra_syntax/src/utils.rs b/crates/ra_syntax/src/utils.rs
index 671dd7afa..e274f7471 100644
--- a/crates/ra_syntax/src/utils.rs
+++ b/crates/ra_syntax/src/utils.rs
@@ -1,12 +1,12 @@
1use std::fmt::Write; 1use std::fmt::Write;
2use { 2use {
3 algo::walk::{preorder, walk, WalkEvent}, 3 algo::walk::{walk, WalkEvent},
4 SyntaxKind, File, SyntaxNodeRef, TreeRoot, 4 SyntaxKind, File, SyntaxNodeRef
5}; 5};
6 6
7/// Parse a file and create a string representation of the resulting parse tree. 7/// Parse a file and create a string representation of the resulting parse tree.
8pub fn dump_tree(syntax: SyntaxNodeRef) -> String { 8pub fn dump_tree(syntax: SyntaxNodeRef) -> String {
9 let mut errors: Vec<_> = syntax.root.syntax_root().errors.iter().cloned().collect(); 9 let mut errors: Vec<_> = syntax.root_data().iter().cloned().collect();
10 errors.sort_by_key(|e| e.offset); 10 errors.sort_by_key(|e| e.offset);
11 let mut err_pos = 0; 11 let mut err_pos = 0;
12 let mut level = 0; 12 let mut level = 0;
@@ -56,7 +56,7 @@ pub fn check_fuzz_invariants(text: &str) {
56 56
57pub(crate) fn validate_block_structure(root: SyntaxNodeRef) { 57pub(crate) fn validate_block_structure(root: SyntaxNodeRef) {
58 let mut stack = Vec::new(); 58 let mut stack = Vec::new();
59 for node in preorder(root) { 59 for node in root.descendants() {
60 match node.kind() { 60 match node.kind() {
61 SyntaxKind::L_CURLY => { 61 SyntaxKind::L_CURLY => {
62 stack.push(node) 62 stack.push(node)
diff --git a/crates/ra_syntax/src/yellow/builder.rs b/crates/ra_syntax/src/yellow/builder.rs
index e4ab37899..35dbaec05 100644
--- a/crates/ra_syntax/src/yellow/builder.rs
+++ b/crates/ra_syntax/src/yellow/builder.rs
@@ -1,15 +1,15 @@
1use rowan::GreenNodeBuilder;
1use { 2use {
2 parser_impl::Sink, 3 parser_impl::Sink,
3 yellow::{GreenNode, SyntaxError}, 4 yellow::{GreenNode, SyntaxError, RaTypes},
4 SyntaxKind, TextRange, TextUnit, 5 SyntaxKind, TextRange, TextUnit,
5}; 6};
6 7
7pub(crate) struct GreenBuilder<'a> { 8pub(crate) struct GreenBuilder<'a> {
8 text: &'a str, 9 text: &'a str,
9 parents: Vec<(SyntaxKind, usize)>,
10 children: Vec<GreenNode>,
11 pos: TextUnit, 10 pos: TextUnit,
12 errors: Vec<SyntaxError>, 11 errors: Vec<SyntaxError>,
12 inner: GreenNodeBuilder<RaTypes>,
13} 13}
14 14
15impl<'a> Sink<'a> for GreenBuilder<'a> { 15impl<'a> Sink<'a> for GreenBuilder<'a> {
@@ -18,35 +18,25 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
18 fn new(text: &'a str) -> Self { 18 fn new(text: &'a str) -> Self {
19 GreenBuilder { 19 GreenBuilder {
20 text, 20 text,
21 parents: Vec::new(),
22 children: Vec::new(),
23 pos: 0.into(), 21 pos: 0.into(),
24 errors: Vec::new(), 22 errors: Vec::new(),
23 inner: GreenNodeBuilder::new(),
25 } 24 }
26 } 25 }
27 26
28 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) { 27 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
29 let range = TextRange::offset_len(self.pos, len); 28 let range = TextRange::offset_len(self.pos, len);
30 self.pos += len; 29 self.pos += len;
31 let text = &self.text[range]; 30 let text = self.text[range].into();
32 self.children.push( 31 self.inner.leaf(kind, text);
33 GreenNode::new_leaf(kind, text)
34 );
35 } 32 }
36 33
37 fn start_internal(&mut self, kind: SyntaxKind) { 34 fn start_internal(&mut self, kind: SyntaxKind) {
38 let len = self.children.len(); 35 self.inner.start_internal(kind)
39 self.parents.push((kind, len));
40 } 36 }
41 37
42 fn finish_internal(&mut self) { 38 fn finish_internal(&mut self) {
43 let (kind, first_child) = self.parents.pop().unwrap(); 39 self.inner.finish_internal();
44 let children: Vec<_> = self.children
45 .drain(first_child..)
46 .collect();
47 self.children.push(
48 GreenNode::new_branch(kind, children.into_boxed_slice())
49 );
50 } 40 }
51 41
52 fn error(&mut self, message: String) { 42 fn error(&mut self, message: String) {
@@ -56,9 +46,7 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
56 }) 46 })
57 } 47 }
58 48
59 fn finish(mut self) -> (GreenNode, Vec<SyntaxError>) { 49 fn finish(self) -> (GreenNode, Vec<SyntaxError>) {
60 assert_eq!(self.children.len(), 1); 50 (self.inner.finish(), self.errors)
61 let root = self.children.pop().unwrap();
62 (root, self.errors)
63 } 51 }
64} 52}
diff --git a/crates/ra_syntax/src/yellow/green.rs b/crates/ra_syntax/src/yellow/green.rs
deleted file mode 100644
index 8fb691643..000000000
--- a/crates/ra_syntax/src/yellow/green.rs
+++ /dev/null
@@ -1,90 +0,0 @@
1use std::sync::Arc;
2
3use smol_str::SmolStr;
4
5use {SyntaxKind, TextUnit};
6
7#[derive(Clone, Debug)]
8pub(crate) enum GreenNode {
9 Leaf {
10 kind: SyntaxKind,
11 text: SmolStr,
12 },
13 Branch(Arc<GreenBranch>),
14}
15
16impl GreenNode {
17 pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode {
18 GreenNode::Leaf { kind, text: SmolStr::new(text) }
19 }
20
21 pub(crate) fn new_branch(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenNode {
22 GreenNode::Branch(Arc::new(GreenBranch::new(kind, children)))
23 }
24
25 pub fn kind(&self) -> SyntaxKind {
26 match self {
27 GreenNode::Leaf { kind, .. } => *kind,
28 GreenNode::Branch(b) => b.kind(),
29 }
30 }
31
32 pub fn text_len(&self) -> TextUnit {
33 match self {
34 GreenNode::Leaf { text, .. } => TextUnit::from(text.len() as u32),
35 GreenNode::Branch(b) => b.text_len(),
36 }
37 }
38
39 pub fn children(&self) -> &[GreenNode] {
40 match self {
41 GreenNode::Leaf { .. } => &[],
42 GreenNode::Branch(b) => b.children(),
43 }
44 }
45
46 pub fn leaf_text_ref(&self) -> Option<&SmolStr> {
47 match self {
48 GreenNode::Leaf { text, .. } => Some(text),
49 GreenNode::Branch(_) => None,
50 }
51 }
52}
53
54#[derive(Clone, Debug)]
55pub(crate) struct GreenBranch {
56 text_len: TextUnit,
57 kind: SyntaxKind,
58 children: Box<[GreenNode]>,
59}
60
61impl GreenBranch {
62 fn new(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenBranch {
63 let text_len = children.iter().map(|x| x.text_len()).sum::<TextUnit>();
64 GreenBranch {
65 text_len,
66 kind,
67 children,
68 }
69 }
70
71 pub fn kind(&self) -> SyntaxKind {
72 self.kind
73 }
74
75 pub fn text_len(&self) -> TextUnit {
76 self.text_len
77 }
78
79 pub fn children(&self) -> &[GreenNode] {
80 &*self.children
81 }
82}
83
84#[test]
85fn test_sizes() {
86 use std::mem::size_of;
87 println!("GreenBranch = {}", size_of::<GreenBranch>());
88 println!("GreenNode = {}", size_of::<GreenNode>());
89 println!("SmolStr = {}", size_of::<SmolStr>());
90}
diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs
index 0596e702f..710320f47 100644
--- a/crates/ra_syntax/src/yellow/mod.rs
+++ b/crates/ra_syntax/src/yellow/mod.rs
@@ -1,100 +1,164 @@
1mod builder; 1mod builder;
2mod green;
3mod red;
4mod syntax;
5mod syntax_text; 2mod syntax_text;
6 3
7use std::{ 4use std::{
8 sync::Arc, 5 fmt,
9 ptr, 6 hash::{Hash, Hasher},
10};
11pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren};
12pub(crate) use self::{
13 builder::GreenBuilder,
14 green::GreenNode,
15 red::RedNode,
16 syntax_text::SyntaxText,
17}; 7};
8use rowan::Types;
9use {SyntaxKind, TextUnit, TextRange, SmolStr};
10use self::syntax_text::SyntaxText;
18 11
19#[derive(Debug)] 12pub use rowan::{TreeRoot};
20pub struct SyntaxRoot { 13pub(crate) use self::builder::GreenBuilder;
21 red: RedNode, 14
22 pub(crate) errors: Vec<SyntaxError>, 15#[derive(Debug, Clone, Copy)]
16pub enum RaTypes {}
17impl Types for RaTypes {
18 type Kind = SyntaxKind;
19 type RootData = Vec<SyntaxError>;
23} 20}
24 21
25pub trait TreeRoot: Clone + Send + Sync { 22pub type OwnedRoot = ::rowan::OwnedRoot<RaTypes>;
26 fn borrowed(&self) -> RefRoot; 23pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>;
27 fn owned(&self) -> OwnedRoot; 24
25pub type GreenNode = ::rowan::GreenNode<RaTypes>;
28 26
29 #[doc(hidden)] 27#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
30 fn syntax_root(&self) -> &SyntaxRoot; 28pub struct SyntaxError {
29 pub msg: String,
30 pub offset: TextUnit,
31} 31}
32#[derive(Clone, Debug)]
33pub struct OwnedRoot(Arc<SyntaxRoot>);
34#[derive(Clone, Copy, Debug)]
35pub struct RefRoot<'a>(&'a OwnedRoot); // TODO: shared_from_this instead of double indirection
36 32
37impl<'a> RefRoot<'a> { 33#[derive(Clone, Copy)]
38 fn syntax_root(&self) -> &'a SyntaxRoot { 34pub struct SyntaxNode<R: TreeRoot<RaTypes> = OwnedRoot>(
39 self.0.syntax_root() 35 ::rowan::SyntaxNode<RaTypes, R>,
36);
37pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
38
39impl<R1, R2> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2>
40where
41 R1: TreeRoot<RaTypes>,
42 R2: TreeRoot<RaTypes>,
43{
44 fn eq(&self, other: &SyntaxNode<R1>) -> bool {
45 self.0 == other.0
40 } 46 }
41} 47}
42 48
43impl TreeRoot for OwnedRoot { 49impl<R: TreeRoot<RaTypes>> Eq for SyntaxNode<R> {}
44 fn borrowed(&self) -> RefRoot { 50impl<R: TreeRoot<RaTypes>> Hash for SyntaxNode<R> {
45 RefRoot(&self) 51 fn hash<H: Hasher>(&self, state: &mut H) {
52 self.0.hash(state)
46 } 53 }
47 fn owned(&self) -> OwnedRoot { 54}
48 self.clone() 55
56impl SyntaxNode {
57 pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
58 SyntaxNode(::rowan::SyntaxNode::new(green, errors))
49 } 59 }
60}
50 61
51 fn syntax_root(&self) -> &SyntaxRoot { 62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52 &*self.0 63pub enum Direction {
64 Next,
65 Prev,
66}
67
68impl<'a> SyntaxNodeRef<'a> {
69 pub fn leaf_text(self) -> Option<&'a SmolStr> {
70 self.0.leaf_text()
71 }
72 pub fn ancestors(self) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
73 ::algo::generate(Some(self), |&node| node.parent())
74 }
75 pub fn descendants(self) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
76 ::algo::walk::walk(self).filter_map(|event| match event {
77 ::algo::walk::WalkEvent::Enter(node) => Some(node),
78 ::algo::walk::WalkEvent::Exit(_) => None,
79 })
80 }
81 pub fn siblings(self, direction: Direction) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
82 ::algo::generate(Some(self), move |&node| match direction {
83 Direction::Next => node.next_sibling(),
84 Direction::Prev => node.prev_sibling(),
85 })
53 } 86 }
54} 87}
55 88
56impl<'a> TreeRoot for RefRoot<'a> { 89impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
57 fn borrowed(&self) -> RefRoot { 90 pub(crate) fn root_data(&self) -> &Vec<SyntaxError> {
58 *self 91 self.0.root_data()
92 }
93 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
94 self.0.replace_with(replacement)
95 }
96 pub fn borrowed<'a>(&'a self) -> SyntaxNode<RefRoot<'a>> {
97 SyntaxNode(self.0.borrowed())
59 } 98 }
60 fn owned(&self) -> OwnedRoot { 99 pub fn owned(&self) -> SyntaxNode<OwnedRoot> {
61 self.0.clone() 100 SyntaxNode(self.0.owned())
62 } 101 }
63 fn syntax_root(&self) -> &SyntaxRoot { 102 pub fn kind(&self) -> SyntaxKind {
64 self.0.syntax_root() 103 self.0.kind()
104 }
105 pub fn range(&self) -> TextRange {
106 self.0.range()
107 }
108 pub fn text(&self) -> SyntaxText {
109 SyntaxText::new(self.borrowed())
110 }
111 pub fn is_leaf(&self) -> bool {
112 self.0.is_leaf()
113 }
114 pub fn parent(&self) -> Option<SyntaxNode<R>> {
115 self.0.parent().map(SyntaxNode)
116 }
117 pub fn first_child(&self) -> Option<SyntaxNode<R>> {
118 self.0.first_child().map(SyntaxNode)
119 }
120 pub fn last_child(&self) -> Option<SyntaxNode<R>> {
121 self.0.last_child().map(SyntaxNode)
122 }
123 pub fn next_sibling(&self) -> Option<SyntaxNode<R>> {
124 self.0.next_sibling().map(SyntaxNode)
125 }
126 pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
127 self.0.prev_sibling().map(SyntaxNode)
128 }
129 pub fn children(&self) -> SyntaxNodeChildren<R> {
130 SyntaxNodeChildren(self.0.children())
65 } 131 }
66} 132}
67 133
68impl SyntaxRoot { 134impl<R: TreeRoot<RaTypes>> fmt::Debug for SyntaxNode<R> {
69 pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot { 135 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
70 SyntaxRoot { 136 write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
71 red: RedNode::new_root(green), 137 if has_short_text(self.kind()) {
72 errors, 138 write!(fmt, " \"{}\"", self.text())?;
73 } 139 }
140 Ok(())
74 } 141 }
75} 142}
76 143
77#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 144#[derive(Debug)]
78pub(crate) struct RedPtr(ptr::NonNull<RedNode>); 145pub struct SyntaxNodeChildren<R: TreeRoot<RaTypes>>(
79 146 ::rowan::SyntaxNodeChildren<RaTypes, R>
80unsafe impl Send for RedPtr {} 147);
81 148
82unsafe impl Sync for RedPtr {} 149impl<R: TreeRoot<RaTypes>> Iterator for SyntaxNodeChildren<R> {
150 type Item = SyntaxNode<R>;
83 151
84impl RedPtr { 152 fn next(&mut self) -> Option<SyntaxNode<R>> {
85 fn new(red: &RedNode) -> RedPtr { 153 self.0.next().map(SyntaxNode)
86 RedPtr(red.into())
87 }
88
89 unsafe fn get<'a>(self, _root: &'a SyntaxRoot) -> &'a RedNode {
90 &*self.0.as_ptr()
91 } 154 }
92} 155}
93 156
94#[test] 157
95fn assert_send_sync() { 158fn has_short_text(kind: SyntaxKind) -> bool {
96 fn f<T: Send + Sync>() {} 159 use SyntaxKind::*;
97 f::<GreenNode>(); 160 match kind {
98 f::<RedNode>(); 161 IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true,
99 f::<SyntaxNode>(); 162 _ => false,
163 }
100} 164}
diff --git a/crates/ra_syntax/src/yellow/red.rs b/crates/ra_syntax/src/yellow/red.rs
deleted file mode 100644
index 84cfe4fba..000000000
--- a/crates/ra_syntax/src/yellow/red.rs
+++ /dev/null
@@ -1,113 +0,0 @@
1use parking_lot::RwLock;
2use {yellow::{GreenNode, RedPtr}, TextUnit};
3
4#[derive(Debug)]
5pub(crate) struct RedNode {
6 green: GreenNode,
7 parent: Option<ParentData>,
8 children: RwLock<Box<[RedChild]>>,
9}
10
11#[derive(Debug)]
12enum RedChild {
13 Zigot(TextUnit),
14 Child(RedNode)
15}
16
17impl RedChild {
18 fn set(&mut self, node: RedNode) -> &RedNode {
19 match self {
20 RedChild::Child(node) => return node,
21 RedChild::Zigot(_) => {
22 *self = RedChild::Child(node);
23 match self {
24 RedChild::Child(node) => return node,
25 RedChild::Zigot(_) => unreachable!()
26 }
27 }
28 }
29 }
30}
31
32#[derive(Debug)]
33struct ParentData {
34 parent: RedPtr,
35 start_offset: TextUnit,
36 index_in_parent: usize,
37}
38
39impl RedNode {
40 pub fn new_root(green: GreenNode) -> RedNode {
41 RedNode::new(green, None)
42 }
43
44 fn new_child(
45 green: GreenNode,
46 parent: RedPtr,
47 start_offset: TextUnit,
48 index_in_parent: usize,
49 ) -> RedNode {
50 let parent_data = ParentData {
51 parent,
52 start_offset,
53 index_in_parent,
54 };
55 RedNode::new(green, Some(parent_data))
56 }
57
58 fn new(green: GreenNode, parent: Option<ParentData>) -> RedNode {
59 let mut start_offset = parent.as_ref().map(|it| it.start_offset).unwrap_or(0.into());
60 let children = green.children()
61 .iter()
62 .map(|child| {
63 let off = start_offset;
64 start_offset += child.text_len();
65 RedChild::Zigot(off)
66 })
67 .collect::<Vec<_>>()
68 .into_boxed_slice();
69 RedNode {
70 green,
71 parent,
72 children: RwLock::new(children),
73 }
74 }
75
76 pub(crate) fn green(&self) -> &GreenNode {
77 &self.green
78 }
79
80 pub(crate) fn start_offset(&self) -> TextUnit {
81 match &self.parent {
82 None => 0.into(),
83 Some(p) => p.start_offset,
84 }
85 }
86
87 pub(crate) fn n_children(&self) -> usize {
88 self.green.children().len()
89 }
90
91 pub(crate) fn get_child(&self, idx: usize) -> Option<RedPtr> {
92 if idx >= self.n_children() {
93 return None;
94 }
95 let start_offset = match &self.children.read()[idx] {
96 RedChild::Child(child) => return Some(RedPtr::new(child)),
97 RedChild::Zigot(start_offset) => *start_offset,
98 };
99 let green_children = self.green.children();
100 let child =
101 RedNode::new_child(green_children[idx].clone(), RedPtr::new(self), start_offset, idx);
102 let mut children = self.children.write();
103 let child = children[idx].set(child);
104 Some(RedPtr::new(child))
105 }
106
107 pub(crate) fn parent(&self) -> Option<RedPtr> {
108 Some(self.parent.as_ref()?.parent)
109 }
110 pub(crate) fn index_in_parent(&self) -> Option<usize> {
111 Some(self.parent.as_ref()?.index_in_parent)
112 }
113}
diff --git a/crates/ra_syntax/src/yellow/syntax.rs b/crates/ra_syntax/src/yellow/syntax.rs
deleted file mode 100644
index 1d99cab4a..000000000
--- a/crates/ra_syntax/src/yellow/syntax.rs
+++ /dev/null
@@ -1,215 +0,0 @@
1use std::{
2 fmt, sync::Arc,
3 hash::{Hasher, Hash},
4 ops::Range,
5};
6
7use smol_str::SmolStr;
8
9use {
10 yellow::{GreenNode, RedNode, TreeRoot, SyntaxRoot, RedPtr, RefRoot, OwnedRoot, SyntaxText},
11 SyntaxKind::{self, *},
12 TextRange, TextUnit,
13};
14
15
16#[derive(Clone, Copy)]
17pub struct SyntaxNode<R: TreeRoot = OwnedRoot> {
18 pub(crate) root: R,
19 // Guaranteed to not dangle, because `root` holds a
20 // strong reference to red's ancestor
21 red: RedPtr,
22}
23
24unsafe impl<R: TreeRoot> Send for SyntaxNode<R> {}
25unsafe impl<R: TreeRoot> Sync for SyntaxNode<R> {}
26
27impl<R1: TreeRoot, R2: TreeRoot> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2> {
28 fn eq(&self, other: &SyntaxNode<R1>) -> bool {
29 self.red == other.red
30 }
31}
32
33impl<R: TreeRoot> Eq for SyntaxNode<R> {}
34impl<R: TreeRoot> Hash for SyntaxNode<R> {
35 fn hash<H: Hasher>(&self, state: &mut H) {
36 self.red.hash(state)
37 }
38}
39
40pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
41
42#[test]
43fn syntax_node_ref_is_copy() {
44 fn assert_copy<T: Copy>(){}
45 assert_copy::<SyntaxNodeRef>()
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
49pub struct SyntaxError {
50 pub msg: String,
51 pub offset: TextUnit,
52}
53
54impl SyntaxNode<OwnedRoot> {
55 pub(crate) fn new_owned(root: SyntaxRoot) -> Self {
56 let root = OwnedRoot(Arc::new(root));
57 let red = RedPtr::new(&root.syntax_root().red);
58 SyntaxNode { root, red }
59 }
60}
61
62impl<'a> SyntaxNode<RefRoot<'a>> {
63 pub(crate) fn leaf_text_ref(self) -> Option<&'a SmolStr> {
64 let red = unsafe { self.red.get(self.root.syntax_root()) };
65 red.green().leaf_text_ref()
66 }
67}
68
69impl<R: TreeRoot> SyntaxNode<R> {
70 pub fn borrowed<'a>(&'a self) -> SyntaxNodeRef<'a> {
71 SyntaxNode {
72 root: self.root.borrowed(),
73 red: self.red,
74 }
75 }
76
77 pub fn owned(&self) -> SyntaxNode {
78 SyntaxNode {
79 root: self.root.owned(),
80 red: self.red,
81 }
82 }
83
84 pub fn kind(&self) -> SyntaxKind {
85 self.red().green().kind()
86 }
87
88 pub fn range(&self) -> TextRange {
89 let red = self.red();
90 TextRange::offset_len(red.start_offset(), red.green().text_len())
91 }
92
93 pub fn text(&self) -> SyntaxText {
94 SyntaxText::new(self.borrowed())
95 }
96
97 pub fn children(&self) -> SyntaxNodeChildren<R> {
98 SyntaxNodeChildren {
99 parent: self.clone(),
100 iter: (0..self.red().n_children())
101 }
102 }
103
104 pub fn parent(&self) -> Option<SyntaxNode<R>> {
105 let parent = self.red().parent()?;
106 Some(SyntaxNode {
107 root: self.root.clone(),
108 red: parent,
109 })
110 }
111
112 pub fn first_child(&self) -> Option<SyntaxNode<R>> {
113 let red = self.red().get_child(0)?;
114 Some(SyntaxNode { root: self.root.clone(), red })
115 }
116
117 pub fn last_child(&self) -> Option<SyntaxNode<R>> {
118 let n = self.red().n_children();
119 let n = n.checked_sub(1)?;
120 let red = self.red().get_child(n)?;
121 Some(SyntaxNode { root: self.root.clone(), red })
122 }
123
124 pub fn next_sibling(&self) -> Option<SyntaxNode<R>> {
125 let red = self.red();
126 let parent = self.parent()?;
127 let next_sibling_idx = red.index_in_parent()? + 1;
128 let sibling_red = parent.red().get_child(next_sibling_idx)?;
129 Some(SyntaxNode {
130 root: self.root.clone(),
131 red: sibling_red,
132 })
133 }
134
135 pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
136 let red = self.red();
137 let parent = self.parent()?;
138 let prev_sibling_idx = red.index_in_parent()?.checked_sub(1)?;
139 let sibling_red = parent.red().get_child(prev_sibling_idx)?;
140 Some(SyntaxNode {
141 root: self.root.clone(),
142 red: sibling_red,
143 })
144 }
145
146 pub fn is_leaf(&self) -> bool {
147 self.first_child().is_none()
148 }
149
150 pub fn leaf_text(&self) -> Option<SmolStr> {
151 self.borrowed().leaf_text_ref().map(|it| it.clone())
152 }
153
154 pub(crate) fn replace_with(&self, green: GreenNode) -> GreenNode {
155 assert_eq!(self.kind(), green.kind());
156 match self.parent() {
157 None => green,
158 Some(parent) => {
159 let children: Vec<_> = parent.children().map(|child| {
160 if child == *self {
161 green.clone()
162 } else {
163 child.red().green().clone()
164 }
165 }).collect();
166 let new_parent = GreenNode::new_branch(
167 parent.kind(),
168 children.into_boxed_slice(),
169 );
170 parent.replace_with(new_parent)
171 },
172 }
173 }
174
175 fn red(&self) -> &RedNode {
176 unsafe { self.red.get(self.root.syntax_root()) }
177 }
178}
179
180impl<R: TreeRoot> fmt::Debug for SyntaxNode<R> {
181 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
182 write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
183 if has_short_text(self.kind()) {
184 write!(fmt, " \"{}\"", self.text())?;
185 }
186 Ok(())
187 }
188}
189
190#[derive(Debug)]
191pub struct SyntaxNodeChildren<R: TreeRoot> {
192 parent: SyntaxNode<R>,
193 iter: Range<usize>,
194}
195
196impl<R: TreeRoot> Iterator for SyntaxNodeChildren<R> {
197 type Item = SyntaxNode<R>;
198
199 fn next(&mut self) -> Option<SyntaxNode<R>> {
200 self.iter.next().map(|i| {
201 let red = self.parent.red();
202 SyntaxNode {
203 root: self.parent.root.clone(),
204 red: red.get_child(i).unwrap(),
205 }
206 })
207 }
208}
209
210fn has_short_text(kind: SyntaxKind) -> bool {
211 match kind {
212 IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true,
213 _ => false,
214 }
215}
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs
index 280bedd78..0db1049de 100644
--- a/crates/ra_syntax/src/yellow/syntax_text.rs
+++ b/crates/ra_syntax/src/yellow/syntax_text.rs
@@ -4,7 +4,6 @@ use std::{
4 4
5use { 5use {
6 SyntaxNodeRef, TextRange, TextUnit, 6 SyntaxNodeRef, TextRange, TextUnit,
7 algo::walk::preorder,
8 text_utils::{intersect, contains_offset_nonstrict}, 7 text_utils::{intersect, contains_offset_nonstrict},
9}; 8};
10 9
@@ -23,9 +22,10 @@ impl<'a> SyntaxText<'a> {
23 } 22 }
24 pub fn chunks(&self) -> impl Iterator<Item=&'a str> { 23 pub fn chunks(&self) -> impl Iterator<Item=&'a str> {
25 let range = self.range; 24 let range = self.range;
26 preorder(self.node) 25 self.node
26 .descendants()
27 .filter_map(move |node| { 27 .filter_map(move |node| {
28 let text = node.leaf_text_ref()?; 28 let text = node.leaf_text()?;
29 let range = intersect(range, node.range())?; 29 let range = intersect(range, node.range())?;
30 let range = range - node.range().start(); 30 let range = range - node.range().start();
31 Some(&text[range]) 31 Some(&text[range])