diff options
-rw-r--r-- | crates/assists/src/handlers/generate_enum_match_method.rs | 20 | ||||
-rw-r--r-- | crates/assists/src/handlers/generate_new.rs | 21 | ||||
-rw-r--r-- | crates/assists/src/utils.rs | 18 | ||||
-rw-r--r-- | crates/hir_def/src/body/tests/block.rs | 16 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 10 |
5 files changed, 49 insertions, 36 deletions
diff --git a/crates/assists/src/handlers/generate_enum_match_method.rs b/crates/assists/src/handlers/generate_enum_match_method.rs index ee89d4208..4cf66b5d5 100644 --- a/crates/assists/src/handlers/generate_enum_match_method.rs +++ b/crates/assists/src/handlers/generate_enum_match_method.rs | |||
@@ -1,9 +1,12 @@ | |||
1 | use stdx::{format_to, to_lower_snake_case}; | 1 | use stdx::{format_to, to_lower_snake_case}; |
2 | use syntax::ast::VisibilityOwner; | ||
2 | use syntax::ast::{self, AstNode, NameOwner}; | 3 | use syntax::ast::{self, AstNode, NameOwner}; |
3 | use syntax::{ast::VisibilityOwner, T}; | ||
4 | use test_utils::mark; | 4 | use test_utils::mark; |
5 | 5 | ||
6 | use crate::{utils::find_struct_impl, AssistContext, AssistId, AssistKind, Assists}; | 6 | use crate::{ |
7 | utils::{find_impl_block, find_struct_impl}, | ||
8 | AssistContext, AssistId, AssistKind, Assists, | ||
9 | }; | ||
7 | 10 | ||
8 | // Assist: generate_enum_match_method | 11 | // Assist: generate_enum_match_method |
9 | // | 12 | // |
@@ -63,7 +66,6 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext) | |||
63 | } | 66 | } |
64 | 67 | ||
65 | let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v)); | 68 | let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v)); |
66 | |||
67 | format_to!( | 69 | format_to!( |
68 | buf, | 70 | buf, |
69 | " /// Returns `true` if the {} is [`{}`]. | 71 | " /// Returns `true` if the {} is [`{}`]. |
@@ -78,17 +80,7 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext) | |||
78 | ); | 80 | ); |
79 | 81 | ||
80 | let start_offset = impl_def | 82 | let start_offset = impl_def |
81 | .and_then(|impl_def| { | 83 | .and_then(|impl_def| find_impl_block(impl_def, &mut buf)) |
82 | buf.push('\n'); | ||
83 | let start = impl_def | ||
84 | .syntax() | ||
85 | .descendants_with_tokens() | ||
86 | .find(|t| t.kind() == T!['{'])? | ||
87 | .text_range() | ||
88 | .end(); | ||
89 | |||
90 | Some(start) | ||
91 | }) | ||
92 | .unwrap_or_else(|| { | 84 | .unwrap_or_else(|| { |
93 | buf = generate_impl_text(&parent_enum, &buf); | 85 | buf = generate_impl_text(&parent_enum, &buf); |
94 | parent_enum.syntax().text_range().end() | 86 | parent_enum.syntax().text_range().end() |
diff --git a/crates/assists/src/handlers/generate_new.rs b/crates/assists/src/handlers/generate_new.rs index 84832273f..307f2e228 100644 --- a/crates/assists/src/handlers/generate_new.rs +++ b/crates/assists/src/handlers/generate_new.rs | |||
@@ -2,10 +2,13 @@ use itertools::Itertools; | |||
2 | use stdx::format_to; | 2 | use stdx::format_to; |
3 | use syntax::{ | 3 | use syntax::{ |
4 | ast::{self, AstNode, GenericParamsOwner, NameOwner, StructKind, VisibilityOwner}, | 4 | ast::{self, AstNode, GenericParamsOwner, NameOwner, StructKind, VisibilityOwner}, |
5 | SmolStr, T, | 5 | SmolStr, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{utils::find_struct_impl, AssistContext, AssistId, AssistKind, Assists}; | 8 | use crate::{ |
9 | utils::{find_impl_block, find_struct_impl}, | ||
10 | AssistContext, AssistId, AssistKind, Assists, | ||
11 | }; | ||
9 | 12 | ||
10 | // Assist: generate_new | 13 | // Assist: generate_new |
11 | // | 14 | // |
@@ -58,17 +61,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
58 | format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); | 61 | format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); |
59 | 62 | ||
60 | let start_offset = impl_def | 63 | let start_offset = impl_def |
61 | .and_then(|impl_def| { | 64 | .and_then(|impl_def| find_impl_block(impl_def, &mut buf)) |
62 | buf.push('\n'); | ||
63 | let start = impl_def | ||
64 | .syntax() | ||
65 | .descendants_with_tokens() | ||
66 | .find(|t| t.kind() == T!['{'])? | ||
67 | .text_range() | ||
68 | .end(); | ||
69 | |||
70 | Some(start) | ||
71 | }) | ||
72 | .unwrap_or_else(|| { | 65 | .unwrap_or_else(|| { |
73 | buf = generate_impl_text(&strukt, &buf); | 66 | buf = generate_impl_text(&strukt, &buf); |
74 | strukt.syntax().text_range().end() | 67 | strukt.syntax().text_range().end() |
@@ -93,7 +86,7 @@ fn generate_impl_text(strukt: &ast::Struct, code: &str) -> String { | |||
93 | if let Some(type_params) = &type_params { | 86 | if let Some(type_params) = &type_params { |
94 | format_to!(buf, "{}", type_params.syntax()); | 87 | format_to!(buf, "{}", type_params.syntax()); |
95 | } | 88 | } |
96 | buf.push_str(" "); | 89 | buf.push(' '); |
97 | buf.push_str(strukt.name().unwrap().text()); | 90 | buf.push_str(strukt.name().unwrap().text()); |
98 | if let Some(type_params) = type_params { | 91 | if let Some(type_params) = type_params { |
99 | let lifetime_params = type_params | 92 | let lifetime_params = type_params |
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 3842558d8..8045aac40 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
@@ -274,10 +274,11 @@ pub(crate) fn does_pat_match_variant(pat: &ast::Pat, var: &ast::Pat) -> bool { | |||
274 | // Uses a syntax-driven approach to find any impl blocks for the struct that | 274 | // Uses a syntax-driven approach to find any impl blocks for the struct that |
275 | // exist within the module/file | 275 | // exist within the module/file |
276 | // | 276 | // |
277 | // Returns `None` if we've found an existing `new` fn | 277 | // Returns `None` if we've found an existing fn |
278 | // | 278 | // |
279 | // FIXME: change the new fn checking to a more semantic approach when that's more | 279 | // FIXME: change the new fn checking to a more semantic approach when that's more |
280 | // viable (e.g. we process proc macros, etc) | 280 | // viable (e.g. we process proc macros, etc) |
281 | // FIXME: this partially overlaps with `find_impl_block` | ||
281 | pub(crate) fn find_struct_impl( | 282 | pub(crate) fn find_struct_impl( |
282 | ctx: &AssistContext, | 283 | ctx: &AssistContext, |
283 | strukt: &ast::AdtDef, | 284 | strukt: &ast::AdtDef, |
@@ -338,3 +339,18 @@ fn has_fn(imp: &ast::Impl, rhs_name: &str) -> bool { | |||
338 | 339 | ||
339 | false | 340 | false |
340 | } | 341 | } |
342 | |||
343 | /// Find the start of the `impl` block for the given `ast::Impl`. | ||
344 | // | ||
345 | // FIXME: add a way to find the end of the `impl` block. | ||
346 | // FIXME: this partially overlaps with `find_struct_impl` | ||
347 | pub(crate) fn find_impl_block(impl_def: ast::Impl, buf: &mut String) -> Option<TextSize> { | ||
348 | buf.push('\n'); | ||
349 | let start = impl_def | ||
350 | .syntax() | ||
351 | .descendants_with_tokens() | ||
352 | .find(|t| t.kind() == T!['{'])? | ||
353 | .text_range() | ||
354 | .end(); | ||
355 | Some(start) | ||
356 | } | ||
diff --git a/crates/hir_def/src/body/tests/block.rs b/crates/hir_def/src/body/tests/block.rs index 062560a70..b599c6269 100644 --- a/crates/hir_def/src/body/tests/block.rs +++ b/crates/hir_def/src/body/tests/block.rs | |||
@@ -26,22 +26,26 @@ fn outer() { | |||
26 | fn use_from_crate() { | 26 | fn use_from_crate() { |
27 | check_at( | 27 | check_at( |
28 | r#" | 28 | r#" |
29 | struct Struct; | 29 | struct Struct {} |
30 | fn outer() { | 30 | fn outer() { |
31 | use Struct; | 31 | fn Struct() {} |
32 | use Struct as PlainStruct; | ||
32 | use crate::Struct as CrateStruct; | 33 | use crate::Struct as CrateStruct; |
33 | use self::Struct as SelfStruct; | 34 | use self::Struct as SelfStruct; |
35 | use super::Struct as SuperStruct; | ||
34 | $0 | 36 | $0 |
35 | } | 37 | } |
36 | "#, | 38 | "#, |
37 | expect![[r#" | 39 | expect![[r#" |
38 | block scope | 40 | block scope |
39 | CrateStruct: t v | 41 | CrateStruct: t |
40 | SelfStruct: t v | 42 | PlainStruct: t v |
41 | Struct: t v | 43 | SelfStruct: t |
44 | Struct: v | ||
45 | SuperStruct: _ | ||
42 | 46 | ||
43 | crate | 47 | crate |
44 | Struct: t v | 48 | Struct: t |
45 | outer: v | 49 | outer: v |
46 | "#]], | 50 | "#]], |
47 | ); | 51 | ); |
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index 036e389b0..fdcdc23ae 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs | |||
@@ -227,7 +227,15 @@ impl DefMap { | |||
227 | } | 227 | } |
228 | } | 228 | } |
229 | 229 | ||
230 | PerNs::types(self.module_id(module).into(), Visibility::Public) | 230 | // Resolve `self` to the containing crate-rooted module if we're a block |
231 | self.with_ancestor_maps(db, module, &mut |def_map, module| { | ||
232 | if def_map.block.is_some() { | ||
233 | None // keep ascending | ||
234 | } else { | ||
235 | Some(PerNs::types(def_map.module_id(module).into(), Visibility::Public)) | ||
236 | } | ||
237 | }) | ||
238 | .expect("block DefMap not rooted in crate DefMap") | ||
231 | } | 239 | } |
232 | PathKind::Abs => { | 240 | PathKind::Abs => { |
233 | // 2018-style absolute path -- only extern prelude | 241 | // 2018-style absolute path -- only extern prelude |