aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock41
-rw-r--r--crates/ra_hir/src/source_binder.rs40
-rw-r--r--crates/ra_hir_expand/src/db.rs1
-rw-r--r--crates/ra_hir_expand/src/lib.rs1
-rw-r--r--crates/ra_ide_api/src/expand_macro.rs64
-rw-r--r--crates/ra_ide_api/src/typing.rs34
-rw-r--r--crates/ra_lsp_server/src/lib.rs24
-rw-r--r--crates/ra_lsp_server/src/main.rs3
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs68
9 files changed, 226 insertions, 50 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ef3735197..8f7783deb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,7 +10,7 @@ dependencies = [
10 10
11[[package]] 11[[package]]
12name = "anyhow" 12name = "anyhow"
13version = "1.0.19" 13version = "1.0.22"
14source = "registry+https://github.com/rust-lang/crates.io-index" 14source = "registry+https://github.com/rust-lang/crates.io-index"
15 15
16[[package]] 16[[package]]
@@ -276,14 +276,6 @@ dependencies = [
276 276
277[[package]] 277[[package]]
278name = "crossbeam-queue" 278name = "crossbeam-queue"
279version = "0.1.2"
280source = "registry+https://github.com/rust-lang/crates.io-index"
281dependencies = [
282 "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
283]
284
285[[package]]
286name = "crossbeam-queue"
287version = "0.2.0" 279version = "0.2.0"
288source = "registry+https://github.com/rust-lang/crates.io-index" 280source = "registry+https://github.com/rust-lang/crates.io-index"
289dependencies = [ 281dependencies = [
@@ -292,15 +284,6 @@ dependencies = [
292 284
293[[package]] 285[[package]]
294name = "crossbeam-utils" 286name = "crossbeam-utils"
295version = "0.6.6"
296source = "registry+https://github.com/rust-lang/crates.io-index"
297dependencies = [
298 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
299 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
300]
301
302[[package]]
303name = "crossbeam-utils"
304version = "0.7.0" 287version = "0.7.0"
305source = "registry+https://github.com/rust-lang/crates.io-index" 288source = "registry+https://github.com/rust-lang/crates.io-index"
306dependencies = [ 289dependencies = [
@@ -1092,7 +1075,7 @@ dependencies = [
1092 "ra_syntax 0.1.0", 1075 "ra_syntax 0.1.0",
1093 "ra_text_edit 0.1.0", 1076 "ra_text_edit 0.1.0",
1094 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1077 "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1095 "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1078 "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1096 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1079 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
1097 "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1080 "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1098 "test_utils 0.1.0", 1081 "test_utils 0.1.0",
@@ -1371,22 +1354,22 @@ dependencies = [
1371 1354
1372[[package]] 1355[[package]]
1373name = "rayon" 1356name = "rayon"
1374version = "1.2.0" 1357version = "1.2.1"
1375source = "registry+https://github.com/rust-lang/crates.io-index" 1358source = "registry+https://github.com/rust-lang/crates.io-index"
1376dependencies = [ 1359dependencies = [
1377 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1360 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1378 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 1361 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
1379 "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 1362 "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
1380] 1363]
1381 1364
1382[[package]] 1365[[package]]
1383name = "rayon-core" 1366name = "rayon-core"
1384version = "1.6.0" 1367version = "1.6.1"
1385source = "registry+https://github.com/rust-lang/crates.io-index" 1368source = "registry+https://github.com/rust-lang/crates.io-index"
1386dependencies = [ 1369dependencies = [
1387 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1370 "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
1388 "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1371 "crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1389 "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 1372 "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
1390 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1373 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1391 "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", 1374 "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
1392] 1375]
@@ -1833,7 +1816,7 @@ dependencies = [
1833name = "xtask" 1816name = "xtask"
1834version = "0.1.0" 1817version = "0.1.0"
1835dependencies = [ 1818dependencies = [
1836 "anyhow 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", 1819 "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
1837 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1820 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1838 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1821 "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
1839 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1822 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1857,7 +1840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1857 1840
1858[metadata] 1841[metadata]
1859"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" 1842"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
1860"checksum anyhow 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "57114fc2a6cc374bce195d3482057c846e706d252ff3604363449695684d7a0d" 1843"checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968"
1861"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 1844"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
1862"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" 1845"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
1863"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 1846"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
@@ -1887,9 +1870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1887"checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" 1870"checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
1888"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" 1871"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
1889"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" 1872"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
1890"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
1891"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" 1873"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700"
1892"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
1893"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" 1874"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
1894"checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" 1875"checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9"
1895"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" 1876"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
@@ -1984,8 +1965,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1984"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1965"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
1985"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" 1966"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
1986"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1967"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
1987"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" 1968"checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd"
1988"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" 1969"checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791"
1989"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1970"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
1990"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 1971"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
1991"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" 1972"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index c42ceabdf..797f90d50 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -131,6 +131,7 @@ pub struct ReferenceDescriptor {
131} 131}
132 132
133pub struct Expansion { 133pub struct Expansion {
134 macro_file_kind: MacroFileKind,
134 macro_call_id: MacroCallId, 135 macro_call_id: MacroCallId,
135} 136}
136 137
@@ -145,7 +146,7 @@ impl Expansion {
145 } 146 }
146 147
147 pub fn file_id(&self) -> HirFileId { 148 pub fn file_id(&self) -> HirFileId {
148 self.macro_call_id.as_file(MacroFileKind::Items) 149 self.macro_call_id.as_file(self.macro_file_kind)
149 } 150 }
150} 151}
151 152
@@ -439,7 +440,10 @@ impl SourceAnalyzer {
439 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), 440 db.ast_id_map(macro_call.file_id).ast_id(macro_call.value),
440 ); 441 );
441 let macro_call_loc = MacroCallLoc { def, ast_id }; 442 let macro_call_loc = MacroCallLoc { def, ast_id };
442 Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) 443 Some(Expansion {
444 macro_call_id: db.intern_macro(macro_call_loc),
445 macro_file_kind: to_macro_file_kind(macro_call.value),
446 })
443 } 447 }
444 448
445 #[cfg(test)] 449 #[cfg(test)]
@@ -538,3 +542,35 @@ fn adjust(
538 }) 542 })
539 .map(|(_ptr, scope)| *scope) 543 .map(|(_ptr, scope)| *scope)
540} 544}
545
546/// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to.
547/// FIXME: Not completed
548fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind {
549 let syn = macro_call.syntax();
550 let parent = match syn.parent() {
551 Some(it) => it,
552 None => {
553 // FIXME:
554 // If it is root, which means the parent HirFile
555 // MacroKindFile must be non-items
556 // return expr now.
557 return MacroFileKind::Expr;
558 }
559 };
560
561 match parent.kind() {
562 MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items,
563 LET_STMT => {
564 // FIXME: Handle Pattern
565 MacroFileKind::Expr
566 }
567 EXPR_STMT => MacroFileKind::Statements,
568 BLOCK => MacroFileKind::Statements,
569 ARG_LIST => MacroFileKind::Expr,
570 TRY_EXPR => MacroFileKind::Expr,
571 _ => {
572 // Unknown , Just guess it is `Items`
573 MacroFileKind::Items
574 }
575 }
576}
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index 3c11c8a22..e1d93a8ef 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -151,6 +151,7 @@ pub(crate) fn parse_macro(
151 let fragment_kind = match macro_file.macro_file_kind { 151 let fragment_kind = match macro_file.macro_file_kind {
152 MacroFileKind::Items => FragmentKind::Items, 152 MacroFileKind::Items => FragmentKind::Items,
153 MacroFileKind::Expr => FragmentKind::Expr, 153 MacroFileKind::Expr => FragmentKind::Expr,
154 MacroFileKind::Statements => FragmentKind::Statements,
154 }; 155 };
155 let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; 156 let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?;
156 Some((parse, Arc::new(rev_token_map))) 157 Some((parse, Arc::new(rev_token_map)))
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 1389f64ce..126d12fbb 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -109,6 +109,7 @@ pub struct MacroFile {
109pub enum MacroFileKind { 109pub enum MacroFileKind {
110 Items, 110 Items,
111 Expr, 111 Expr,
112 Statements,
112} 113}
113 114
114/// `MacroCallId` identifies a particular macro invocation, like 115/// `MacroCallId` identifies a particular macro invocation, like
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs
index 7f39262dc..7dbf33a16 100644
--- a/crates/ra_ide_api/src/expand_macro.rs
+++ b/crates/ra_ide_api/src/expand_macro.rs
@@ -84,24 +84,19 @@ fn insert_whitespaces(syn: SyntaxNode) -> String {
84 }; 84 };
85 85
86 res += &match token.kind() { 86 res += &match token.kind() {
87 k @ _ 87 k @ _ if is_text(k) && is_next(|it| !it.is_punct(), true) => {
88 if (k.is_keyword() || k.is_literal() || k == IDENT)
89 && is_next(|it| !it.is_punct(), true) =>
90 {
91 token.text().to_string() + " " 88 token.text().to_string() + " "
92 } 89 }
93 L_CURLY if is_next(|it| it != R_CURLY, true) => { 90 L_CURLY if is_next(|it| it != R_CURLY, true) => {
94 indent += 1; 91 indent += 1;
95 format!(" {{\n{}", " ".repeat(indent)) 92 let leading_space = if is_last(|it| is_text(it), false) { " " } else { "" };
93 format!("{}{{\n{}", leading_space, " ".repeat(indent))
96 } 94 }
97 R_CURLY if is_last(|it| it != L_CURLY, true) => { 95 R_CURLY if is_last(|it| it != L_CURLY, true) => {
98 indent = indent.checked_sub(1).unwrap_or(0); 96 indent = indent.checked_sub(1).unwrap_or(0);
99 format!("\n}}{}", " ".repeat(indent)) 97 format!("\n{}}}", " ".repeat(indent))
100 }
101 R_CURLY => {
102 indent = indent.checked_sub(1).unwrap_or(0);
103 format!("}}\n{}", " ".repeat(indent))
104 } 98 }
99 R_CURLY => format!("}}\n{}", " ".repeat(indent)),
105 T![;] => format!(";\n{}", " ".repeat(indent)), 100 T![;] => format!(";\n{}", " ".repeat(indent)),
106 T![->] => " -> ".to_string(), 101 T![->] => " -> ".to_string(),
107 T![=] => " = ".to_string(), 102 T![=] => " = ".to_string(),
@@ -112,7 +107,11 @@ fn insert_whitespaces(syn: SyntaxNode) -> String {
112 last = Some(token.kind()); 107 last = Some(token.kind());
113 } 108 }
114 109
115 res 110 return res;
111
112 fn is_text(k: SyntaxKind) -> bool {
113 k.is_keyword() || k.is_literal() || k == IDENT
114 }
116} 115}
117 116
118#[cfg(test)] 117#[cfg(test)]
@@ -175,4 +174,47 @@ fn some_thing() -> u32 {
175} 174}
176"###); 175"###);
177 } 176 }
177
178 #[test]
179 fn macro_expand_match_ast() {
180 let res = check_expand_macro(
181 r#"
182 //- /lib.rs
183 macro_rules! match_ast {
184 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };
185
186 (match ($node:expr) {
187 $( ast::$ast:ident($it:ident) => $res:block, )*
188 _ => $catch_all:expr $(,)?
189 }) => {{
190 $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
191 { $catch_all }
192 }};
193 }
194
195 fn main() {
196 mat<|>ch_ast! {
197 match container {
198 ast::TraitDef(it) => {},
199 ast::ImplBlock(it) => {},
200 _ => { continue },
201 }
202 }
203 }
204 "#,
205 );
206
207 assert_eq!(res.name, "match_ast");
208 assert_snapshot!(res.expansion, @r###"
209{
210 if let Some(it) = ast::TraitDef::cast(container.clone()){}
211 else if let Some(it) = ast::ImplBlock::cast(container.clone()){}
212 else {
213 {
214 continue
215 }
216 }
217}
218"###);
219 }
178} 220}
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index d51132f73..21e5be9b3 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -40,9 +40,13 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour
40 } 40 }
41 41
42 let prefix = comment.prefix(); 42 let prefix = comment.prefix();
43 if position.offset 43 let comment_range = comment.syntax().text_range();
44 < comment.syntax().text_range().start() + TextUnit::of_str(prefix) + TextUnit::from(1) 44 if position.offset < comment_range.start() + TextUnit::of_str(prefix) + TextUnit::from(1) {
45 { 45 return None;
46 }
47
48 // Continuing non-doc line comments (like this one :) ) is annoying
49 if prefix == "//" && comment_range.end() == position.offset {
46 return None; 50 return None;
47 } 51 }
48 52
@@ -247,6 +251,30 @@ impl S {
247} 251}
248", 252",
249 ); 253 );
254 do_check(
255 r"
256fn main() {
257 // Fix<|> me
258 let x = 1 + 1;
259}
260",
261 r"
262fn main() {
263 // Fix
264 // <|> me
265 let x = 1 + 1;
266}
267",
268 );
269 do_check_noop(
270 r"
271fn main() {
272 // Fix me<|>
273 let x = 1 + 1;
274}
275",
276 );
277
250 do_check_noop(r"<|>//! docz"); 278 do_check_noop(r"<|>//! docz");
251 } 279 }
252 280
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs
index 0e5dbbbd5..9c36402b0 100644
--- a/crates/ra_lsp_server/src/lib.rs
+++ b/crates/ra_lsp_server/src/lib.rs
@@ -1,6 +1,26 @@
1//! FIXME: write short doc here 1//! Implementation of the LSP for rust-analyzer.
2 2//!
3//! This crate takes Rust-specific analysis results from ra_ide_api and
4//! translates into LSP types.
5//!
6//! It also is the root of all state. `world` module defines the bulk of the
7//! state, and `main_loop` module defines the rules for modifying it.
3#![recursion_limit = "512"] 8#![recursion_limit = "512"]
9
10#[allow(unused)]
11macro_rules! println {
12 ($($tt:tt)*) => {
13 compile_error!("stdout is locked, use eprintln")
14 };
15}
16
17#[allow(unused)]
18macro_rules! print {
19 ($($tt:tt)*) => {
20 compile_error!("stdout is locked, use eprint")
21 };
22}
23
4mod caps; 24mod caps;
5mod cargo_target_spec; 25mod cargo_target_spec;
6mod conv; 26mod conv;
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index 7d9a1d054..e13c8ca14 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -1,8 +1,7 @@
1//! FIXME: write short doc here 1//! `ra_lsp_server` binary
2 2
3use flexi_logger::{Duplicate, Logger}; 3use flexi_logger::{Duplicate, Logger};
4use lsp_server::Connection; 4use lsp_server::Connection;
5
6use ra_lsp_server::{show_message, Result, ServerConfig}; 5use ra_lsp_server::{show_message, Result, ServerConfig};
7use ra_prof; 6use ra_prof;
8 7
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index d1c49c0b3..1de399fee 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -5,6 +5,7 @@ use ra_syntax::{
5 ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode, 5 ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode,
6 SyntaxTreeBuilder, TextRange, TextUnit, T, 6 SyntaxTreeBuilder, TextRange, TextUnit, T,
7}; 7};
8use std::iter::successors;
8use tt::buffer::{Cursor, TokenBuffer}; 9use tt::buffer::{Cursor, TokenBuffer};
9 10
10use crate::subtree_source::SubtreeTokenSource; 11use crate::subtree_source::SubtreeTokenSource;
@@ -160,6 +161,31 @@ impl Convertor {
160 161
161 let first_child = tt.first_child_or_token()?; 162 let first_child = tt.first_child_or_token()?;
162 let last_child = tt.last_child_or_token()?; 163 let last_child = tt.last_child_or_token()?;
164
165 // ignore trivial first_child and last_child
166 let first_child = successors(Some(first_child), |it| {
167 if it.kind().is_trivia() {
168 it.next_sibling_or_token()
169 } else {
170 None
171 }
172 })
173 .last()
174 .unwrap();
175 if first_child.kind().is_trivia() {
176 return Some(tt::Subtree { token_trees: vec![], delimiter: tt::Delimiter::None });
177 }
178
179 let last_child = successors(Some(last_child), |it| {
180 if it.kind().is_trivia() {
181 it.prev_sibling_or_token()
182 } else {
183 None
184 }
185 })
186 .last()
187 .unwrap();
188
163 let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) { 189 let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) {
164 (T!['('], T![')']) => (tt::Delimiter::Parenthesis, true), 190 (T!['('], T![')']) => (tt::Delimiter::Parenthesis, true),
165 (T!['{'], T!['}']) => (tt::Delimiter::Brace, true), 191 (T!['{'], T!['}']) => (tt::Delimiter::Brace, true),
@@ -363,6 +389,7 @@ mod tests {
363 use super::*; 389 use super::*;
364 use crate::tests::{create_rules, expand}; 390 use crate::tests::{create_rules, expand};
365 use ra_parser::TokenSource; 391 use ra_parser::TokenSource;
392 use ra_syntax::algo::{insert_children, InsertPosition};
366 393
367 #[test] 394 #[test]
368 fn convert_tt_token_source() { 395 fn convert_tt_token_source() {
@@ -423,4 +450,45 @@ mod tests {
423 let expansion = expand(&rules, "stmts!();"); 450 let expansion = expand(&rules, "stmts!();");
424 assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err()); 451 assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err());
425 } 452 }
453
454 #[test]
455 fn test_token_tree_last_child_is_white_space() {
456 let source_file = ast::SourceFile::parse("f!({} );").ok().unwrap();
457 let macro_call = source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
458 let token_tree = macro_call.token_tree().unwrap();
459
460 // Token Tree now is :
461 // TokenTree
462 // - T!['(']
463 // - TokenTree
464 // - T!['{']
465 // - T!['}']
466 // - WHITE_SPACE
467 // - T![')']
468
469 let rbrace =
470 token_tree.syntax().descendants_with_tokens().find(|it| it.kind() == T!['}']).unwrap();
471 let space = token_tree
472 .syntax()
473 .descendants_with_tokens()
474 .find(|it| it.kind() == SyntaxKind::WHITESPACE)
475 .unwrap();
476
477 // reorder th white space, such that the white is inside the inner token-tree.
478 let token_tree = insert_children(
479 &rbrace.parent().unwrap(),
480 InsertPosition::Last,
481 &mut std::iter::once(space),
482 );
483
484 // Token Tree now is :
485 // TokenTree
486 // - T!['{']
487 // - T!['}']
488 // - WHITE_SPACE
489 let token_tree = ast::TokenTree::cast(token_tree).unwrap();
490 let tt = ast_to_token_tree(&token_tree).unwrap().0;
491
492 assert_eq!(tt.delimiter, tt::Delimiter::Brace);
493 }
426} 494}