aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/assist_ctx.rs30
-rw-r--r--crates/ra_assists/src/handlers/auto_import.rs42
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--crates/ra_assists/src/utils.rs2
-rw-r--r--crates/ra_assists/src/utils/insert_use.rs9
-rw-r--r--crates/ra_hir_def/src/adt.rs8
-rw-r--r--crates/ra_hir_ty/src/tests.rs27
-rw-r--r--crates/rust-analyzer/src/caps.rs7
-rw-r--r--docs/dev/debugging.md8
9 files changed, 110 insertions, 25 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index 2fe7c3de3..da2880037 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -105,7 +105,7 @@ impl<'a> AssistCtx<'a> {
105 let mut info = AssistInfo::new(label); 105 let mut info = AssistInfo::new(label);
106 if self.should_compute_edit { 106 if self.should_compute_edit {
107 let action = { 107 let action = {
108 let mut edit = ActionBuilder::default(); 108 let mut edit = ActionBuilder::new(&self);
109 f(&mut edit); 109 f(&mut edit);
110 edit.build() 110 edit.build()
111 }; 111 };
@@ -130,6 +130,12 @@ impl<'a> AssistCtx<'a> {
130 pub(crate) fn find_node_at_offset<N: AstNode>(&self) -> Option<N> { 130 pub(crate) fn find_node_at_offset<N: AstNode>(&self) -> Option<N> {
131 find_node_at_offset(self.source_file.syntax(), self.frange.range.start()) 131 find_node_at_offset(self.source_file.syntax(), self.frange.range.start())
132 } 132 }
133
134 pub(crate) fn find_node_at_offset_with_descend<N: AstNode>(&self) -> Option<N> {
135 self.sema
136 .find_node_at_offset_with_descend(self.source_file.syntax(), self.frange.range.start())
137 }
138
133 pub(crate) fn covering_element(&self) -> SyntaxElement { 139 pub(crate) fn covering_element(&self) -> SyntaxElement {
134 find_covering_element(self.source_file.syntax(), self.frange.range) 140 find_covering_element(self.source_file.syntax(), self.frange.range)
135 } 141 }
@@ -156,7 +162,7 @@ impl<'a> AssistGroup<'a> {
156 let mut info = AssistInfo::new(label).with_group(GroupLabel(self.group_name.clone())); 162 let mut info = AssistInfo::new(label).with_group(GroupLabel(self.group_name.clone()));
157 if self.ctx.should_compute_edit { 163 if self.ctx.should_compute_edit {
158 let action = { 164 let action = {
159 let mut edit = ActionBuilder::default(); 165 let mut edit = ActionBuilder::new(&self.ctx);
160 f(&mut edit); 166 f(&mut edit);
161 edit.build() 167 edit.build()
162 }; 168 };
@@ -175,15 +181,29 @@ impl<'a> AssistGroup<'a> {
175 } 181 }
176} 182}
177 183
178#[derive(Default)] 184pub(crate) struct ActionBuilder<'a, 'b> {
179pub(crate) struct ActionBuilder {
180 edit: TextEditBuilder, 185 edit: TextEditBuilder,
181 cursor_position: Option<TextSize>, 186 cursor_position: Option<TextSize>,
182 target: Option<TextRange>, 187 target: Option<TextRange>,
183 file: AssistFile, 188 file: AssistFile,
189 ctx: &'a AssistCtx<'b>,
184} 190}
185 191
186impl ActionBuilder { 192impl<'a, 'b> ActionBuilder<'a, 'b> {
193 fn new(ctx: &'a AssistCtx<'b>) -> Self {
194 Self {
195 edit: TextEditBuilder::default(),
196 cursor_position: None,
197 target: None,
198 file: AssistFile::default(),
199 ctx,
200 }
201 }
202
203 pub(crate) fn ctx(&self) -> &AssistCtx<'b> {
204 &self.ctx
205 }
206
187 /// Replaces specified `range` of text with a given string. 207 /// Replaces specified `range` of text with a given string.
188 pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) { 208 pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
189 self.edit.replace(range, replace_with.into()) 209 self.edit.replace(range, replace_with.into())
diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs
index 99682e023..db6c4d2fa 100644
--- a/crates/ra_assists/src/handlers/auto_import.rs
+++ b/crates/ra_assists/src/handlers/auto_import.rs
@@ -45,15 +45,12 @@ pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
45 return None; 45 return None;
46 } 46 }
47 47
48 let range = ctx.sema.original_range(&auto_import_assets.syntax_under_caret).range;
48 let mut group = ctx.add_assist_group(auto_import_assets.get_import_group_message()); 49 let mut group = ctx.add_assist_group(auto_import_assets.get_import_group_message());
49 for import in proposed_imports { 50 for import in proposed_imports {
50 group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| { 51 group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| {
51 edit.target(auto_import_assets.syntax_under_caret.text_range()); 52 edit.target(range);
52 insert_use_statement( 53 insert_use_statement(&auto_import_assets.syntax_under_caret, &import, edit);
53 &auto_import_assets.syntax_under_caret,
54 &import,
55 edit.text_edit_builder(),
56 );
57 }); 54 });
58 } 55 }
59 group.finish() 56 group.finish()
@@ -68,10 +65,10 @@ struct AutoImportAssets {
68 65
69impl AutoImportAssets { 66impl AutoImportAssets {
70 fn new(ctx: &AssistCtx) -> Option<Self> { 67 fn new(ctx: &AssistCtx) -> Option<Self> {
71 if let Some(path_under_caret) = ctx.find_node_at_offset::<ast::Path>() { 68 if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
72 Self::for_regular_path(path_under_caret, &ctx) 69 Self::for_regular_path(path_under_caret, &ctx)
73 } else { 70 } else {
74 Self::for_method_call(ctx.find_node_at_offset()?, &ctx) 71 Self::for_method_call(ctx.find_node_at_offset_with_descend()?, &ctx)
75 } 72 }
76 } 73 }
77 74
@@ -306,6 +303,35 @@ mod tests {
306 } 303 }
307 304
308 #[test] 305 #[test]
306 fn applicable_when_found_an_import_in_macros() {
307 check_assist(
308 auto_import,
309 r"
310 macro_rules! foo {
311 ($i:ident) => { fn foo(a: $i) {} }
312 }
313 foo!(Pub<|>Struct);
314
315 pub mod PubMod {
316 pub struct PubStruct;
317 }
318 ",
319 r"
320 use PubMod::PubStruct;
321
322 macro_rules! foo {
323 ($i:ident) => { fn foo(a: $i) {} }
324 }
325 foo!(Pub<|>Struct);
326
327 pub mod PubMod {
328 pub struct PubStruct;
329 }
330 ",
331 );
332 }
333
334 #[test]
309 fn auto_imports_are_merged() { 335 fn auto_imports_are_merged() {
310 check_assist( 336 check_assist(
311 auto_import, 337 auto_import,
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
index 918e8dd8d..ff2463c77 100644
--- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -38,7 +38,7 @@ pub(crate) fn replace_qualified_name_with_use(ctx: AssistCtx) -> Option<Assist>
38 "Replace qualified path with use", 38 "Replace qualified path with use",
39 |edit| { 39 |edit| {
40 let path_to_import = hir_path.mod_path().clone(); 40 let path_to_import = hir_path.mod_path().clone();
41 insert_use_statement(path.syntax(), &path_to_import, edit.text_edit_builder()); 41 insert_use_statement(path.syntax(), &path_to_import, edit);
42 42
43 if let Some(last) = path.segment() { 43 if let Some(last) = path.segment() {
44 // Here we are assuming the assist will provide a correct use statement 44 // Here we are assuming the assist will provide a correct use statement
diff --git a/crates/ra_assists/src/utils.rs b/crates/ra_assists/src/utils.rs
index efd988697..6be704ce3 100644
--- a/crates/ra_assists/src/utils.rs
+++ b/crates/ra_assists/src/utils.rs
@@ -11,7 +11,7 @@ use ra_syntax::{
11}; 11};
12use rustc_hash::FxHashSet; 12use rustc_hash::FxHashSet;
13 13
14pub use insert_use::insert_use_statement; 14pub(crate) use insert_use::insert_use_statement;
15 15
16pub fn get_missing_impl_items( 16pub fn get_missing_impl_items(
17 sema: &Semantics<RootDatabase>, 17 sema: &Semantics<RootDatabase>,
diff --git a/crates/ra_assists/src/utils/insert_use.rs b/crates/ra_assists/src/utils/insert_use.rs
index c507e71e0..c1f447efe 100644
--- a/crates/ra_assists/src/utils/insert_use.rs
+++ b/crates/ra_assists/src/utils/insert_use.rs
@@ -2,6 +2,7 @@
2// FIXME: rewrite according to the plan, outlined in 2// FIXME: rewrite according to the plan, outlined in
3// https://github.com/rust-analyzer/rust-analyzer/issues/3301#issuecomment-592931553 3// https://github.com/rust-analyzer/rust-analyzer/issues/3301#issuecomment-592931553
4 4
5use crate::assist_ctx::ActionBuilder;
5use hir::{self, ModPath}; 6use hir::{self, ModPath};
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, NameOwner}, 8 ast::{self, NameOwner},
@@ -14,14 +15,14 @@ use ra_text_edit::TextEditBuilder;
14/// Creates and inserts a use statement for the given path to import. 15/// Creates and inserts a use statement for the given path to import.
15/// The use statement is inserted in the scope most appropriate to the 16/// The use statement is inserted in the scope most appropriate to the
16/// the cursor position given, additionally merged with the existing use imports. 17/// the cursor position given, additionally merged with the existing use imports.
17pub fn insert_use_statement( 18pub(crate) fn insert_use_statement(
18 // Ideally the position of the cursor, used to 19 // Ideally the position of the cursor, used to
19 position: &SyntaxNode, 20 position: &SyntaxNode,
20 path_to_import: &ModPath, 21 path_to_import: &ModPath,
21 edit: &mut TextEditBuilder, 22 edit: &mut ActionBuilder,
22) { 23) {
23 let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>(); 24 let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>();
24 let container = position.ancestors().find_map(|n| { 25 let container = edit.ctx().sema.ancestors_with_macros(position.clone()).find_map(|n| {
25 if let Some(module) = ast::Module::cast(n.clone()) { 26 if let Some(module) = ast::Module::cast(n.clone()) {
26 return module.item_list().map(|it| it.syntax().clone()); 27 return module.item_list().map(|it| it.syntax().clone());
27 } 28 }
@@ -30,7 +31,7 @@ pub fn insert_use_statement(
30 31
31 if let Some(container) = container { 32 if let Some(container) = container {
32 let action = best_action_for_target(container, position.clone(), &target); 33 let action = best_action_for_target(container, position.clone(), &target);
33 make_assist(&action, &target, edit); 34 make_assist(&action, &target, edit.text_edit_builder());
34 } 35 }
35} 36}
36 37
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index 8eef51828..d0912ddaa 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -117,7 +117,13 @@ fn lower_enum(
117 ast: &InFile<ast::EnumDef>, 117 ast: &InFile<ast::EnumDef>,
118 module_id: ModuleId, 118 module_id: ModuleId,
119) { 119) {
120 for var in ast.value.variant_list().into_iter().flat_map(|it| it.variants()) { 120 let expander = CfgExpander::new(db, ast.file_id, module_id.krate);
121 let variants =
122 ast.value.variant_list().into_iter().flat_map(|it| it.variants()).filter(|var| {
123 let attrs = expander.parse_attrs(var);
124 expander.is_cfg_enabled(&attrs)
125 });
126 for var in variants {
121 trace.alloc( 127 trace.alloc(
122 || var.clone(), 128 || var.clone(),
123 || EnumVariantData { 129 || EnumVariantData {
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index 588d81282..d60732e19 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -361,6 +361,33 @@ fn no_such_field_with_feature_flag_diagnostics() {
361} 361}
362 362
363#[test] 363#[test]
364fn no_such_field_enum_with_feature_flag_diagnostics() {
365 let diagnostics = TestDB::with_files(
366 r#"
367 //- /lib.rs crate:foo cfg:feature=foo
368 enum Foo {
369 #[cfg(not(feature = "foo"))]
370 Buz,
371 #[cfg(feature = "foo")]
372 Bar,
373 Baz
374 }
375
376 fn test_fn(f: Foo) {
377 match f {
378 Foo::Bar => {},
379 Foo::Baz => {},
380 }
381 }
382 "#,
383 )
384 .diagnostics()
385 .0;
386
387 assert_snapshot!(diagnostics, @r###""###);
388}
389
390#[test]
364fn no_such_field_with_feature_flag_diagnostics_on_struct_lit() { 391fn no_such_field_with_feature_flag_diagnostics_on_struct_lit() {
365 let diagnostics = TestDB::with_files( 392 let diagnostics = TestDB::with_files(
366 r#" 393 r#"
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 44222d8bd..680415cac 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -1,4 +1,5 @@
1//! Advertizes the capabilities of the LSP Server. 1//! Advertizes the capabilities of the LSP Server.
2use std::env;
2 3
3use crate::semantic_tokens; 4use crate::semantic_tokens;
4 5
@@ -16,7 +17,11 @@ pub fn server_capabilities() -> ServerCapabilities {
16 ServerCapabilities { 17 ServerCapabilities {
17 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { 18 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
18 open_close: Some(true), 19 open_close: Some(true),
19 change: Some(TextDocumentSyncKind::Incremental), 20 change: Some(if env::var("RA_PROFILE").is_ok() {
21 TextDocumentSyncKind::Incremental
22 } else {
23 TextDocumentSyncKind::Full
24 }),
20 will_save: None, 25 will_save: None,
21 will_save_wait_until: None, 26 will_save_wait_until: None,
22 save: Some(SaveOptions::default()), 27 save: Some(SaveOptions::default()),
diff --git a/docs/dev/debugging.md b/docs/dev/debugging.md
index bece6a572..1aa392935 100644
--- a/docs/dev/debugging.md
+++ b/docs/dev/debugging.md
@@ -26,7 +26,7 @@ where **only** the `rust-analyzer` extension being debugged is enabled.
26- `Run Extension (Dev Server)` - runs extension with the locally built LSP server (`target/debug/rust-analyzer`). 26- `Run Extension (Dev Server)` - runs extension with the locally built LSP server (`target/debug/rust-analyzer`).
27 27
28TypeScript debugging is configured to watch your source edits and recompile. 28TypeScript debugging is configured to watch your source edits and recompile.
29To apply changes to an already running debug process press <kbd>Ctrl+Shift+P</kbd> and run the following command in your `[Extension Development Host]` 29To apply changes to an already running debug process, press <kbd>Ctrl+Shift+P</kbd> and run the following command in your `[Extension Development Host]`
30 30
31``` 31```
32> Developer: Reload Window 32> Developer: Reload Window
@@ -76,11 +76,11 @@ Make sure you open a rust file in the `[Extension Development Host]` and try aga
76 76
77Make sure you have run `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope`. 77Make sure you have run `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope`.
78 78
79By default this should reset back to 1 everytime you log in. 79By default this should reset back to 1 every time you log in.
80 80
81### Breakpoints are never being hit 81### Breakpoints are never being hit
82 82
83Check your version of `lldb` if it's version 6 and lower use the `classic` adapter type. 83Check your version of `lldb`. If it's version 6 and lower, use the `classic` adapter type.
84It's `lldb.adapterType` in settings file. 84It's `lldb.adapterType` in settings file.
85 85
86If you're running `lldb` version 7 change the lldb adapter type to `bundled` or `native`. 86If you're running `lldb` version 7, change the lldb adapter type to `bundled` or `native`.