aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-30 18:03:18 +0100
committerAleksey Kladov <[email protected]>2018-08-30 18:03:18 +0100
commit49e14a99ed4d0baf849bbd5766f6c16e7d37930c (patch)
tree080b101c51c4f2c5921ee14000950abd65917994
parent9fcebbc51284408203c05219a0ee92519f51ea74 (diff)
Complete types
-rw-r--r--crates/libeditor/src/completion.rs22
-rw-r--r--crates/libsyntax2/src/ast/generated.rs18
-rw-r--r--crates/libsyntax2/src/grammar.ron3
3 files changed, 35 insertions, 8 deletions
diff --git a/crates/libeditor/src/completion.rs b/crates/libeditor/src/completion.rs
index d95c40773..f733cd2b2 100644
--- a/crates/libeditor/src/completion.rs
+++ b/crates/libeditor/src/completion.rs
@@ -21,11 +21,10 @@ pub fn scope_completion(file: &File, offset: TextUnit) -> Option<Vec<CompletionI
21 // Insert a fake ident to get a valid parse tree 21 // Insert a fake ident to get a valid parse tree
22 let file = { 22 let file = {
23 let edit = AtomEdit::insert(offset, "intellijRulezz".to_string()); 23 let edit = AtomEdit::insert(offset, "intellijRulezz".to_string());
24 // Don't bother with completion if incremental reparse fails 24 file.reparse(&edit)
25 file.incremental_reparse(&edit)?
26 }; 25 };
27 let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), offset)?; 26 let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), offset)?;
28 if !is_ident_expr(name_ref) { 27 if !is_single_segment(name_ref) {
29 return None; 28 return None;
30 } 29 }
31 30
@@ -50,11 +49,11 @@ pub fn scope_completion(file: &File, offset: TextUnit) -> Option<Vec<CompletionI
50 Some(res) 49 Some(res)
51} 50}
52 51
53fn is_ident_expr(name_ref: ast::NameRef) -> bool { 52fn is_single_segment(name_ref: ast::NameRef) -> bool {
54 match ancestors(name_ref.syntax()).filter_map(ast::Expr::cast).next() { 53 match ancestors(name_ref.syntax()).filter_map(ast::Path::cast).next() {
55 None => false, 54 None => false,
56 Some(expr) => { 55 Some(path) => {
57 expr.syntax().range() == name_ref.syntax().range() 56 path.syntax().range() == name_ref.syntax().range()
58 } 57 }
59 } 58 }
60} 59}
@@ -204,6 +203,15 @@ mod tests {
204 } 203 }
205 204
206 #[test] 205 #[test]
206 fn test_complete_type() {
207 check_scope_completion(r"
208 struct Foo;
209 fn x() -> <|>
210 ", r#"[CompletionItem { name: "Foo", snippet: None },
211 CompletionItem { name: "x", snippet: None }]"#)
212 }
213
214 #[test]
207 fn test_completion_kewords() { 215 fn test_completion_kewords() {
208 check_snippet_completion(r" 216 check_snippet_completion(r"
209 fn quux() { 217 fn quux() {
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs
index d72e2091a..c2a22c8fc 100644
--- a/crates/libsyntax2/src/ast/generated.rs
+++ b/crates/libsyntax2/src/ast/generated.rs
@@ -1278,6 +1278,24 @@ impl<'a> AstNode<'a> for Pat<'a> {
1278 1278
1279impl<'a> Pat<'a> {} 1279impl<'a> Pat<'a> {}
1280 1280
1281// Path
1282#[derive(Debug, Clone, Copy)]
1283pub struct Path<'a> {
1284 syntax: SyntaxNodeRef<'a>,
1285}
1286
1287impl<'a> AstNode<'a> for Path<'a> {
1288 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
1289 match syntax.kind() {
1290 PATH => Some(Path { syntax }),
1291 _ => None,
1292 }
1293 }
1294 fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
1295}
1296
1297impl<'a> Path<'a> {}
1298
1281// PathExpr 1299// PathExpr
1282#[derive(Debug, Clone, Copy)] 1300#[derive(Debug, Clone, Copy)]
1283pub struct PathExpr<'a> { 1301pub struct PathExpr<'a> {
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron
index 3c293d3e4..0bb40f5ab 100644
--- a/crates/libsyntax2/src/grammar.ron
+++ b/crates/libsyntax2/src/grammar.ron
@@ -513,6 +513,7 @@ Grammar(
513 collections: [ 513 collections: [
514 ["args", "Expr"] 514 ["args", "Expr"]
515 ] 515 ]
516 ) 516 ),
517 "Path": (),
517 }, 518 },
518) 519)