diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-19 12:15:55 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-19 12:15:55 +0100 |
commit | f209843e31af7f0e0212aa28ffec2efad2a70c6f (patch) | |
tree | 548227da78a3bea644f57714d075410c0bdf7469 /crates/ra_ide_api/src/completion | |
parent | 58d4983ba5745975446d60f2886d96f8d2adf0f2 (diff) | |
parent | d4a66166c002f0a49e41d856a49cb5685ac93202 (diff) |
Merge #1545
1545: migrate ra_syntax to the new rowan API r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_ide_api/src/completion')
7 files changed, 36 insertions, 37 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index a5f071442..536ba36df 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs | |||
@@ -5,10 +5,11 @@ use rustc_hash::FxHashSet; | |||
5 | 5 | ||
6 | /// Complete dot accesses, i.e. fields or methods (currently only fields). | 6 | /// Complete dot accesses, i.e. fields or methods (currently only fields). |
7 | pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { | 7 | pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { |
8 | let receiver_ty = match ctx.dot_receiver.and_then(|it| ctx.analyzer.type_of(ctx.db, it)) { | 8 | let receiver_ty = |
9 | Some(it) => it, | 9 | match ctx.dot_receiver.as_ref().and_then(|it| ctx.analyzer.type_of(ctx.db, it)) { |
10 | None => return, | 10 | Some(it) => it, |
11 | }; | 11 | None => return, |
12 | }; | ||
12 | if !ctx.is_call { | 13 | if !ctx.is_call { |
13 | complete_fields(acc, ctx, receiver_ty.clone()); | 14 | complete_fields(acc, ctx, receiver_ty.clone()); |
14 | } | 15 | } |
diff --git a/crates/ra_ide_api/src/completion/complete_fn_param.rs b/crates/ra_ide_api/src/completion/complete_fn_param.rs index 5a117c485..0887ef1f6 100644 --- a/crates/ra_ide_api/src/completion/complete_fn_param.rs +++ b/crates/ra_ide_api/src/completion/complete_fn_param.rs | |||
@@ -20,7 +20,7 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) | |||
20 | let _ = visitor_ctx(&mut params) | 20 | let _ = visitor_ctx(&mut params) |
21 | .visit::<ast::SourceFile, _>(process) | 21 | .visit::<ast::SourceFile, _>(process) |
22 | .visit::<ast::ItemList, _>(process) | 22 | .visit::<ast::ItemList, _>(process) |
23 | .accept(node); | 23 | .accept(&node); |
24 | } | 24 | } |
25 | params | 25 | params |
26 | .into_iter() | 26 | .into_iter() |
@@ -38,10 +38,7 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) | |||
38 | .add_to(acc) | 38 | .add_to(acc) |
39 | }); | 39 | }); |
40 | 40 | ||
41 | fn process<'a, N: ast::FnDefOwner>( | 41 | fn process<N: ast::FnDefOwner>(node: N, params: &mut FxHashMap<String, (u32, ast::Param)>) { |
42 | node: &'a N, | ||
43 | params: &mut FxHashMap<String, (u32, &'a ast::Param)>, | ||
44 | ) { | ||
45 | node.functions().filter_map(|it| it.param_list()).flat_map(|it| it.params()).for_each( | 42 | node.functions().filter_map(|it| it.param_list()).flat_map(|it| it.params()).for_each( |
46 | |param| { | 43 | |param| { |
47 | let text = param.syntax().text().to_string(); | 44 | let text = param.syntax().text().to_string(); |
diff --git a/crates/ra_ide_api/src/completion/complete_keyword.rs b/crates/ra_ide_api/src/completion/complete_keyword.rs index 034ed934d..4cf34eff8 100644 --- a/crates/ra_ide_api/src/completion/complete_keyword.rs +++ b/crates/ra_ide_api/src/completion/complete_keyword.rs | |||
@@ -52,7 +52,7 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
52 | return; | 52 | return; |
53 | } | 53 | } |
54 | 54 | ||
55 | let fn_def = match ctx.function_syntax { | 55 | let fn_def = match &ctx.function_syntax { |
56 | Some(it) => it, | 56 | Some(it) => it, |
57 | None => return, | 57 | None => return, |
58 | }; | 58 | }; |
@@ -65,7 +65,7 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
65 | acc.add(keyword(ctx, "else", "else {$0}")); | 65 | acc.add(keyword(ctx, "else", "else {$0}")); |
66 | acc.add(keyword(ctx, "else if", "else if $0 {}")); | 66 | acc.add(keyword(ctx, "else if", "else if $0 {}")); |
67 | } | 67 | } |
68 | if is_in_loop_body(ctx.token) { | 68 | if is_in_loop_body(&ctx.token) { |
69 | if ctx.can_be_stmt { | 69 | if ctx.can_be_stmt { |
70 | acc.add(keyword(ctx, "continue", "continue;")); | 70 | acc.add(keyword(ctx, "continue", "continue;")); |
71 | acc.add(keyword(ctx, "break", "break;")); | 71 | acc.add(keyword(ctx, "break", "break;")); |
@@ -74,19 +74,19 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
74 | acc.add(keyword(ctx, "break", "break")); | 74 | acc.add(keyword(ctx, "break", "break")); |
75 | } | 75 | } |
76 | } | 76 | } |
77 | acc.add_all(complete_return(ctx, fn_def, ctx.can_be_stmt)); | 77 | acc.add_all(complete_return(ctx, &fn_def, ctx.can_be_stmt)); |
78 | } | 78 | } |
79 | 79 | ||
80 | fn is_in_loop_body(leaf: SyntaxToken) -> bool { | 80 | fn is_in_loop_body(leaf: &SyntaxToken) -> bool { |
81 | for node in leaf.parent().ancestors() { | 81 | for node in leaf.parent().ancestors() { |
82 | if node.kind() == FN_DEF || node.kind() == LAMBDA_EXPR { | 82 | if node.kind() == FN_DEF || node.kind() == LAMBDA_EXPR { |
83 | break; | 83 | break; |
84 | } | 84 | } |
85 | let loop_body = visitor() | 85 | let loop_body = visitor() |
86 | .visit::<ast::ForExpr, _>(LoopBodyOwner::loop_body) | 86 | .visit::<ast::ForExpr, _>(|it| it.loop_body()) |
87 | .visit::<ast::WhileExpr, _>(LoopBodyOwner::loop_body) | 87 | .visit::<ast::WhileExpr, _>(|it| it.loop_body()) |
88 | .visit::<ast::LoopExpr, _>(LoopBodyOwner::loop_body) | 88 | .visit::<ast::LoopExpr, _>(|it| it.loop_body()) |
89 | .accept(node); | 89 | .accept(&node); |
90 | if let Some(Some(body)) = loop_body { | 90 | if let Some(Some(body)) = loop_body { |
91 | if leaf.range().is_subrange(&body.syntax().range()) { | 91 | if leaf.range().is_subrange(&body.syntax().range()) { |
92 | return true; | 92 | return true; |
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs index 4f5062214..c75b1c159 100644 --- a/crates/ra_ide_api/src/completion/complete_postfix.rs +++ b/crates/ra_ide_api/src/completion/complete_postfix.rs | |||
@@ -11,7 +11,8 @@ use ra_text_edit::TextEditBuilder; | |||
11 | 11 | ||
12 | fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: &str) -> Builder { | 12 | fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: &str) -> Builder { |
13 | let edit = { | 13 | let edit = { |
14 | let receiver_range = ctx.dot_receiver.expect("no receiver available").syntax().range(); | 14 | let receiver_range = |
15 | ctx.dot_receiver.as_ref().expect("no receiver available").syntax().range(); | ||
15 | let delete_range = TextRange::from_to(receiver_range.start(), ctx.source_range().end()); | 16 | let delete_range = TextRange::from_to(receiver_range.start(), ctx.source_range().end()); |
16 | let mut builder = TextEditBuilder::default(); | 17 | let mut builder = TextEditBuilder::default(); |
17 | builder.replace(delete_range, snippet.to_string()); | 18 | builder.replace(delete_range, snippet.to_string()); |
@@ -38,9 +39,9 @@ fn is_bool_or_unknown(ty: Option<Ty>) -> bool { | |||
38 | } | 39 | } |
39 | 40 | ||
40 | pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | 41 | pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { |
41 | if let Some(dot_receiver) = ctx.dot_receiver { | 42 | if let Some(dot_receiver) = &ctx.dot_receiver { |
42 | let receiver_text = dot_receiver.syntax().text().to_string(); | 43 | let receiver_text = dot_receiver.syntax().text().to_string(); |
43 | let receiver_ty = ctx.analyzer.type_of(ctx.db, dot_receiver); | 44 | let receiver_ty = ctx.analyzer.type_of(ctx.db, &dot_receiver); |
44 | if is_bool_or_unknown(receiver_ty) { | 45 | if is_bool_or_unknown(receiver_ty) { |
45 | postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) | 46 | postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) |
46 | .add_to(acc); | 47 | .add_to(acc); |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 1ba871257..f92034055 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -20,8 +20,8 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
20 | let mut builder = TextEditBuilder::default(); | 20 | let mut builder = TextEditBuilder::default(); |
21 | builder.replace(ctx.source_range(), name.to_string()); | 21 | builder.replace(ctx.source_range(), name.to_string()); |
22 | auto_import::auto_import_text_edit( | 22 | auto_import::auto_import_text_edit( |
23 | ctx.token.parent(), | 23 | &ctx.token.parent(), |
24 | ctx.token.parent(), | 24 | &ctx.token.parent(), |
25 | &path, | 25 | &path, |
26 | &mut builder, | 26 | &mut builder, |
27 | ); | 27 | ); |
diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs index b6216f857..9410f740f 100644 --- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs | |||
@@ -4,8 +4,8 @@ use crate::completion::{CompletionContext, Completions}; | |||
4 | 4 | ||
5 | /// Complete fields in fields literals. | 5 | /// Complete fields in fields literals. |
6 | pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) { | 6 | pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) { |
7 | let (ty, variant) = match ctx.struct_lit_syntax.and_then(|it| { | 7 | let (ty, variant) = match ctx.struct_lit_syntax.as_ref().and_then(|it| { |
8 | Some((ctx.analyzer.type_of(ctx.db, it.into())?, ctx.analyzer.resolve_variant(it)?)) | 8 | Some((ctx.analyzer.type_of(ctx.db, &it.clone().into())?, ctx.analyzer.resolve_variant(it)?)) |
9 | }) { | 9 | }) { |
10 | Some(it) => it, | 10 | Some(it) => it, |
11 | _ => return, | 11 | _ => return, |
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index 4aa84751f..b803271ab 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs | |||
@@ -16,11 +16,11 @@ pub(crate) struct CompletionContext<'a> { | |||
16 | pub(super) db: &'a db::RootDatabase, | 16 | pub(super) db: &'a db::RootDatabase, |
17 | pub(super) analyzer: hir::SourceAnalyzer, | 17 | pub(super) analyzer: hir::SourceAnalyzer, |
18 | pub(super) offset: TextUnit, | 18 | pub(super) offset: TextUnit, |
19 | pub(super) token: SyntaxToken<'a>, | 19 | pub(super) token: SyntaxToken, |
20 | pub(super) module: Option<hir::Module>, | 20 | pub(super) module: Option<hir::Module>, |
21 | pub(super) function_syntax: Option<&'a ast::FnDef>, | 21 | pub(super) function_syntax: Option<ast::FnDef>, |
22 | pub(super) use_item_syntax: Option<&'a ast::UseItem>, | 22 | pub(super) use_item_syntax: Option<ast::UseItem>, |
23 | pub(super) struct_lit_syntax: Option<&'a ast::StructLit>, | 23 | pub(super) struct_lit_syntax: Option<ast::StructLit>, |
24 | pub(super) is_param: bool, | 24 | pub(super) is_param: bool, |
25 | /// If a name-binding or reference to a const in a pattern. | 25 | /// If a name-binding or reference to a const in a pattern. |
26 | /// Irrefutable patterns (like let) are excluded. | 26 | /// Irrefutable patterns (like let) are excluded. |
@@ -35,7 +35,7 @@ pub(crate) struct CompletionContext<'a> { | |||
35 | /// Something is typed at the "top" level, in module or impl/trait. | 35 | /// Something is typed at the "top" level, in module or impl/trait. |
36 | pub(super) is_new_item: bool, | 36 | pub(super) is_new_item: bool, |
37 | /// The receiver if this is a field or method access, i.e. writing something.<|> | 37 | /// The receiver if this is a field or method access, i.e. writing something.<|> |
38 | pub(super) dot_receiver: Option<&'a ast::Expr>, | 38 | pub(super) dot_receiver: Option<ast::Expr>, |
39 | /// If this is a call (method or function) in particular, i.e. the () are already there. | 39 | /// If this is a call (method or function) in particular, i.e. the () are already there. |
40 | pub(super) is_call: bool, | 40 | pub(super) is_call: bool, |
41 | } | 41 | } |
@@ -50,7 +50,7 @@ impl<'a> CompletionContext<'a> { | |||
50 | let token = | 50 | let token = |
51 | find_token_at_offset(original_parse.tree().syntax(), position.offset).left_biased()?; | 51 | find_token_at_offset(original_parse.tree().syntax(), position.offset).left_biased()?; |
52 | let analyzer = | 52 | let analyzer = |
53 | hir::SourceAnalyzer::new(db, position.file_id, token.parent(), Some(position.offset)); | 53 | hir::SourceAnalyzer::new(db, position.file_id, &token.parent(), Some(position.offset)); |
54 | let mut ctx = CompletionContext { | 54 | let mut ctx = CompletionContext { |
55 | db, | 55 | db, |
56 | analyzer, | 56 | analyzer, |
@@ -109,7 +109,7 @@ impl<'a> CompletionContext<'a> { | |||
109 | if is_node::<ast::BindPat>(name.syntax()) { | 109 | if is_node::<ast::BindPat>(name.syntax()) { |
110 | let bind_pat = name.syntax().ancestors().find_map(ast::BindPat::cast).unwrap(); | 110 | let bind_pat = name.syntax().ancestors().find_map(ast::BindPat::cast).unwrap(); |
111 | let parent = bind_pat.syntax().parent(); | 111 | let parent = bind_pat.syntax().parent(); |
112 | if parent.and_then(ast::MatchArm::cast).is_some() | 112 | if parent.clone().and_then(ast::MatchArm::cast).is_some() |
113 | || parent.and_then(ast::Condition::cast).is_some() | 113 | || parent.and_then(ast::Condition::cast).is_some() |
114 | { | 114 | { |
115 | self.is_pat_binding = true; | 115 | self.is_pat_binding = true; |
@@ -122,7 +122,7 @@ impl<'a> CompletionContext<'a> { | |||
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
125 | fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::NameRef) { | 125 | fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) { |
126 | let name_range = name_ref.syntax().range(); | 126 | let name_range = name_ref.syntax().range(); |
127 | if name_ref.syntax().parent().and_then(ast::NamedField::cast).is_some() { | 127 | if name_ref.syntax().parent().and_then(ast::NamedField::cast).is_some() { |
128 | self.struct_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset); | 128 | self.struct_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset); |
@@ -153,7 +153,7 @@ impl<'a> CompletionContext<'a> { | |||
153 | None => return, | 153 | None => return, |
154 | }; | 154 | }; |
155 | 155 | ||
156 | if let Some(segment) = ast::PathSegment::cast(parent) { | 156 | if let Some(segment) = ast::PathSegment::cast(parent.clone()) { |
157 | let path = segment.parent_path(); | 157 | let path = segment.parent_path(); |
158 | self.is_call = path | 158 | self.is_call = path |
159 | .syntax() | 159 | .syntax() |
@@ -162,7 +162,7 @@ impl<'a> CompletionContext<'a> { | |||
162 | .and_then(|it| it.syntax().parent().and_then(ast::CallExpr::cast)) | 162 | .and_then(|it| it.syntax().parent().and_then(ast::CallExpr::cast)) |
163 | .is_some(); | 163 | .is_some(); |
164 | 164 | ||
165 | if let Some(mut path) = hir::Path::from_ast(path) { | 165 | if let Some(mut path) = hir::Path::from_ast(path.clone()) { |
166 | if !path.is_ident() { | 166 | if !path.is_ident() { |
167 | path.segments.pop().unwrap(); | 167 | path.segments.pop().unwrap(); |
168 | self.path_prefix = Some(path); | 168 | self.path_prefix = Some(path); |
@@ -179,7 +179,7 @@ impl<'a> CompletionContext<'a> { | |||
179 | .syntax() | 179 | .syntax() |
180 | .ancestors() | 180 | .ancestors() |
181 | .find_map(|node| { | 181 | .find_map(|node| { |
182 | if let Some(stmt) = ast::ExprStmt::cast(node) { | 182 | if let Some(stmt) = ast::ExprStmt::cast(node.clone()) { |
183 | return Some(stmt.syntax().range() == name_ref.syntax().range()); | 183 | return Some(stmt.syntax().range() == name_ref.syntax().range()); |
184 | } | 184 | } |
185 | if let Some(block) = ast::Block::cast(node) { | 185 | if let Some(block) = ast::Block::cast(node) { |
@@ -203,7 +203,7 @@ impl<'a> CompletionContext<'a> { | |||
203 | } | 203 | } |
204 | } | 204 | } |
205 | } | 205 | } |
206 | if let Some(field_expr) = ast::FieldExpr::cast(parent) { | 206 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { |
207 | // The receiver comes before the point of insertion of the fake | 207 | // The receiver comes before the point of insertion of the fake |
208 | // ident, so it should have the same range in the non-modified file | 208 | // ident, so it should have the same range in the non-modified file |
209 | self.dot_receiver = field_expr | 209 | self.dot_receiver = field_expr |
@@ -222,7 +222,7 @@ impl<'a> CompletionContext<'a> { | |||
222 | } | 222 | } |
223 | } | 223 | } |
224 | 224 | ||
225 | fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<&N> { | 225 | fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { |
226 | find_covering_element(syntax, range).ancestors().find_map(N::cast) | 226 | find_covering_element(syntax, range).ancestors().find_map(N::cast) |
227 | } | 227 | } |
228 | 228 | ||