aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/assists/src/handlers/generate_enum_match_method.rs20
-rw-r--r--crates/assists/src/handlers/generate_new.rs21
-rw-r--r--crates/assists/src/utils.rs18
-rw-r--r--crates/hir_def/src/body/tests/block.rs16
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs10
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 @@
1use stdx::{format_to, to_lower_snake_case}; 1use stdx::{format_to, to_lower_snake_case};
2use syntax::ast::VisibilityOwner;
2use syntax::ast::{self, AstNode, NameOwner}; 3use syntax::ast::{self, AstNode, NameOwner};
3use syntax::{ast::VisibilityOwner, T};
4use test_utils::mark; 4use test_utils::mark;
5 5
6use crate::{utils::find_struct_impl, AssistContext, AssistId, AssistKind, Assists}; 6use 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;
2use stdx::format_to; 2use stdx::format_to;
3use syntax::{ 3use 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
8use crate::{utils::find_struct_impl, AssistContext, AssistId, AssistKind, Assists}; 8use 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`
281pub(crate) fn find_struct_impl( 282pub(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`
347pub(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() {
26fn use_from_crate() { 26fn use_from_crate() {
27 check_at( 27 check_at(
28 r#" 28 r#"
29struct Struct; 29struct Struct {}
30fn outer() { 30fn 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