diff options
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 165 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/add_missing_impl_members.rs | 6 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/convert_comment_block.rs | 46 | ||||
-rw-r--r-- | crates/syntax/src/ast/token_ext.rs | 5 |
4 files changed, 97 insertions, 125 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 28b73c3a1..d8fabe49b 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -91,7 +91,6 @@ pub(super) fn collect_defs( | |||
91 | resolved_imports: Vec::new(), | 91 | resolved_imports: Vec::new(), |
92 | 92 | ||
93 | unexpanded_macros: Vec::new(), | 93 | unexpanded_macros: Vec::new(), |
94 | unexpanded_attribute_macros: Vec::new(), | ||
95 | mod_dirs: FxHashMap::default(), | 94 | mod_dirs: FxHashMap::default(), |
96 | cfg_options, | 95 | cfg_options, |
97 | proc_macros, | 96 | proc_macros, |
@@ -202,15 +201,14 @@ struct ImportDirective { | |||
202 | #[derive(Clone, Debug, Eq, PartialEq)] | 201 | #[derive(Clone, Debug, Eq, PartialEq)] |
203 | struct MacroDirective { | 202 | struct MacroDirective { |
204 | module_id: LocalModuleId, | 203 | module_id: LocalModuleId, |
205 | ast_id: AstIdWithPath<ast::MacroCall>, | ||
206 | legacy: Option<MacroCallId>, | ||
207 | depth: usize, | 204 | depth: usize, |
205 | kind: MacroDirectiveKind, | ||
208 | } | 206 | } |
209 | 207 | ||
210 | #[derive(Clone, Debug, Eq, PartialEq)] | 208 | #[derive(Clone, Debug, Eq, PartialEq)] |
211 | struct DeriveDirective { | 209 | enum MacroDirectiveKind { |
212 | module_id: LocalModuleId, | 210 | FnLike { ast_id: AstIdWithPath<ast::MacroCall>, legacy: Option<MacroCallId> }, |
213 | ast_id: AstIdWithPath<ast::Item>, | 211 | Derive { ast_id: AstIdWithPath<ast::Item> }, |
214 | } | 212 | } |
215 | 213 | ||
216 | struct DefData<'a> { | 214 | struct DefData<'a> { |
@@ -228,7 +226,6 @@ struct DefCollector<'a> { | |||
228 | unresolved_imports: Vec<ImportDirective>, | 226 | unresolved_imports: Vec<ImportDirective>, |
229 | resolved_imports: Vec<ImportDirective>, | 227 | resolved_imports: Vec<ImportDirective>, |
230 | unexpanded_macros: Vec<MacroDirective>, | 228 | unexpanded_macros: Vec<MacroDirective>, |
231 | unexpanded_attribute_macros: Vec<DeriveDirective>, | ||
232 | mod_dirs: FxHashMap<LocalModuleId, ModDir>, | 229 | mod_dirs: FxHashMap<LocalModuleId, ModDir>, |
233 | cfg_options: &'a CfgOptions, | 230 | cfg_options: &'a CfgOptions, |
234 | /// List of procedural macros defined by this crate. This is read from the dynamic library | 231 | /// List of procedural macros defined by this crate. This is read from the dynamic library |
@@ -782,60 +779,58 @@ impl DefCollector<'_> { | |||
782 | 779 | ||
783 | fn resolve_macros(&mut self) -> ReachedFixedPoint { | 780 | fn resolve_macros(&mut self) -> ReachedFixedPoint { |
784 | let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); | 781 | let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); |
785 | let mut attribute_macros = | ||
786 | std::mem::replace(&mut self.unexpanded_attribute_macros, Vec::new()); | ||
787 | let mut resolved = Vec::new(); | 782 | let mut resolved = Vec::new(); |
788 | let mut res = ReachedFixedPoint::Yes; | 783 | let mut res = ReachedFixedPoint::Yes; |
789 | macros.retain(|directive| { | 784 | macros.retain(|directive| { |
790 | if let Some(call_id) = directive.legacy { | 785 | match &directive.kind { |
791 | res = ReachedFixedPoint::No; | 786 | MacroDirectiveKind::FnLike { ast_id, legacy } => { |
792 | resolved.push((directive.module_id, call_id, directive.depth)); | 787 | if let Some(call_id) = legacy { |
793 | return false; | 788 | res = ReachedFixedPoint::No; |
794 | } | 789 | resolved.push((directive.module_id, *call_id, directive.depth)); |
790 | return false; | ||
791 | } | ||
795 | 792 | ||
796 | match macro_call_as_call_id( | 793 | match macro_call_as_call_id( |
797 | &directive.ast_id, | 794 | ast_id, |
798 | self.db, | ||
799 | self.def_map.krate, | ||
800 | |path| { | ||
801 | let resolved_res = self.def_map.resolve_path_fp_with_macro( | ||
802 | self.db, | 795 | self.db, |
803 | ResolveMode::Other, | 796 | self.def_map.krate, |
804 | directive.module_id, | 797 | |path| { |
805 | &path, | 798 | let resolved_res = self.def_map.resolve_path_fp_with_macro( |
806 | BuiltinShadowMode::Module, | 799 | self.db, |
807 | ); | 800 | ResolveMode::Other, |
808 | resolved_res.resolved_def.take_macros() | 801 | directive.module_id, |
809 | }, | 802 | &path, |
810 | &mut |_err| (), | 803 | BuiltinShadowMode::Module, |
811 | ) { | 804 | ); |
812 | Ok(Ok(call_id)) => { | 805 | resolved_res.resolved_def.take_macros() |
813 | resolved.push((directive.module_id, call_id, directive.depth)); | 806 | }, |
814 | res = ReachedFixedPoint::No; | 807 | &mut |_err| (), |
815 | return false; | 808 | ) { |
809 | Ok(Ok(call_id)) => { | ||
810 | resolved.push((directive.module_id, call_id, directive.depth)); | ||
811 | res = ReachedFixedPoint::No; | ||
812 | return false; | ||
813 | } | ||
814 | Err(UnresolvedMacro) | Ok(Err(_)) => {} | ||
815 | } | ||
816 | } | 816 | } |
817 | Err(UnresolvedMacro) | Ok(Err(_)) => {} | 817 | MacroDirectiveKind::Derive { ast_id } => { |
818 | } | 818 | match derive_macro_as_call_id(ast_id, self.db, self.def_map.krate, |path| { |
819 | 819 | self.resolve_derive_macro(directive.module_id, &path) | |
820 | true | 820 | }) { |
821 | }); | 821 | Ok(call_id) => { |
822 | attribute_macros.retain(|directive| { | 822 | resolved.push((directive.module_id, call_id, 0)); |
823 | match derive_macro_as_call_id(&directive.ast_id, self.db, self.def_map.krate, |path| { | 823 | res = ReachedFixedPoint::No; |
824 | self.resolve_derive_macro(&directive, &path) | 824 | return false; |
825 | }) { | 825 | } |
826 | Ok(call_id) => { | 826 | Err(UnresolvedMacro) => (), |
827 | resolved.push((directive.module_id, call_id, 0)); | 827 | } |
828 | res = ReachedFixedPoint::No; | ||
829 | return false; | ||
830 | } | 828 | } |
831 | Err(UnresolvedMacro) => (), | ||
832 | } | 829 | } |
833 | 830 | ||
834 | true | 831 | true |
835 | }); | 832 | }); |
836 | |||
837 | self.unexpanded_macros = macros; | 833 | self.unexpanded_macros = macros; |
838 | self.unexpanded_attribute_macros = attribute_macros; | ||
839 | 834 | ||
840 | for (module_id, macro_call_id, depth) in resolved { | 835 | for (module_id, macro_call_id, depth) in resolved { |
841 | self.collect_macro_expansion(module_id, macro_call_id, depth); | 836 | self.collect_macro_expansion(module_id, macro_call_id, depth); |
@@ -844,15 +839,11 @@ impl DefCollector<'_> { | |||
844 | res | 839 | res |
845 | } | 840 | } |
846 | 841 | ||
847 | fn resolve_derive_macro( | 842 | fn resolve_derive_macro(&self, module: LocalModuleId, path: &ModPath) -> Option<MacroDefId> { |
848 | &self, | ||
849 | directive: &DeriveDirective, | ||
850 | path: &ModPath, | ||
851 | ) -> Option<MacroDefId> { | ||
852 | let resolved_res = self.def_map.resolve_path_fp_with_macro( | 843 | let resolved_res = self.def_map.resolve_path_fp_with_macro( |
853 | self.db, | 844 | self.db, |
854 | ResolveMode::Other, | 845 | ResolveMode::Other, |
855 | directive.module_id, | 846 | module, |
856 | &path, | 847 | &path, |
857 | BuiltinShadowMode::Module, | 848 | BuiltinShadowMode::Module, |
858 | ); | 849 | ); |
@@ -912,33 +903,35 @@ impl DefCollector<'_> { | |||
912 | // Emit diagnostics for all remaining unexpanded macros. | 903 | // Emit diagnostics for all remaining unexpanded macros. |
913 | 904 | ||
914 | for directive in &self.unexpanded_macros { | 905 | for directive in &self.unexpanded_macros { |
915 | let mut error = None; | 906 | match &directive.kind { |
916 | match macro_call_as_call_id( | 907 | MacroDirectiveKind::FnLike { ast_id, .. } => match macro_call_as_call_id( |
917 | &directive.ast_id, | 908 | ast_id, |
918 | self.db, | 909 | self.db, |
919 | self.def_map.krate, | 910 | self.def_map.krate, |
920 | |path| { | 911 | |path| { |
921 | let resolved_res = self.def_map.resolve_path_fp_with_macro( | 912 | let resolved_res = self.def_map.resolve_path_fp_with_macro( |
922 | self.db, | 913 | self.db, |
923 | ResolveMode::Other, | 914 | ResolveMode::Other, |
924 | directive.module_id, | 915 | directive.module_id, |
925 | &path, | 916 | &path, |
926 | BuiltinShadowMode::Module, | 917 | BuiltinShadowMode::Module, |
927 | ); | 918 | ); |
928 | resolved_res.resolved_def.take_macros() | 919 | resolved_res.resolved_def.take_macros() |
929 | }, | 920 | }, |
930 | &mut |e| { | 921 | &mut |_| (), |
931 | error.get_or_insert(e); | 922 | ) { |
923 | Ok(_) => (), | ||
924 | Err(UnresolvedMacro) => { | ||
925 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( | ||
926 | directive.module_id, | ||
927 | ast_id.ast_id, | ||
928 | )); | ||
929 | } | ||
932 | }, | 930 | }, |
933 | ) { | 931 | MacroDirectiveKind::Derive { .. } => { |
934 | Ok(_) => (), | 932 | // FIXME: we might want to diagnose this too |
935 | Err(UnresolvedMacro) => { | ||
936 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( | ||
937 | directive.module_id, | ||
938 | directive.ast_id.ast_id, | ||
939 | )); | ||
940 | } | 933 | } |
941 | }; | 934 | } |
942 | } | 935 | } |
943 | 936 | ||
944 | // Emit diagnostics for all remaining unresolved imports. | 937 | // Emit diagnostics for all remaining unresolved imports. |
@@ -1380,9 +1373,11 @@ impl ModCollector<'_, '_> { | |||
1380 | Some(derive_macros) => { | 1373 | Some(derive_macros) => { |
1381 | for path in derive_macros { | 1374 | for path in derive_macros { |
1382 | let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); | 1375 | let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); |
1383 | self.def_collector | 1376 | self.def_collector.unexpanded_macros.push(MacroDirective { |
1384 | .unexpanded_attribute_macros | 1377 | module_id: self.module_id, |
1385 | .push(DeriveDirective { module_id: self.module_id, ast_id }); | 1378 | depth: self.macro_depth + 1, |
1379 | kind: MacroDirectiveKind::Derive { ast_id }, | ||
1380 | }); | ||
1386 | } | 1381 | } |
1387 | } | 1382 | } |
1388 | None => { | 1383 | None => { |
@@ -1497,9 +1492,8 @@ impl ModCollector<'_, '_> { | |||
1497 | 1492 | ||
1498 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1493 | self.def_collector.unexpanded_macros.push(MacroDirective { |
1499 | module_id: self.module_id, | 1494 | module_id: self.module_id, |
1500 | ast_id, | ||
1501 | legacy: None, | ||
1502 | depth: self.macro_depth + 1, | 1495 | depth: self.macro_depth + 1, |
1496 | kind: MacroDirectiveKind::FnLike { ast_id, legacy: None }, | ||
1503 | }); | 1497 | }); |
1504 | } | 1498 | } |
1505 | 1499 | ||
@@ -1542,7 +1536,6 @@ mod tests { | |||
1542 | unresolved_imports: Vec::new(), | 1536 | unresolved_imports: Vec::new(), |
1543 | resolved_imports: Vec::new(), | 1537 | resolved_imports: Vec::new(), |
1544 | unexpanded_macros: Vec::new(), | 1538 | unexpanded_macros: Vec::new(), |
1545 | unexpanded_attribute_macros: Vec::new(), | ||
1546 | mod_dirs: FxHashMap::default(), | 1539 | mod_dirs: FxHashMap::default(), |
1547 | cfg_options: &CfgOptions::default(), | 1540 | cfg_options: &CfgOptions::default(), |
1548 | proc_macros: Default::default(), | 1541 | proc_macros: Default::default(), |
diff --git a/crates/ide_assists/src/handlers/add_missing_impl_members.rs b/crates/ide_assists/src/handlers/add_missing_impl_members.rs index 63cea754d..0148635f9 100644 --- a/crates/ide_assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide_assists/src/handlers/add_missing_impl_members.rs | |||
@@ -3,9 +3,9 @@ use syntax::ast::{self, AstNode}; | |||
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | assist_context::{AssistContext, Assists}, | 5 | assist_context::{AssistContext, Assists}, |
6 | utils::add_trait_assoc_items_to_impl, | 6 | utils::{ |
7 | utils::DefaultMethods, | 7 | add_trait_assoc_items_to_impl, filter_assoc_items, render_snippet, Cursor, DefaultMethods, |
8 | utils::{filter_assoc_items, render_snippet, Cursor}, | 8 | }, |
9 | AssistId, AssistKind, | 9 | AssistId, AssistKind, |
10 | }; | 10 | }; |
11 | 11 | ||
diff --git a/crates/ide_assists/src/handlers/convert_comment_block.rs b/crates/ide_assists/src/handlers/convert_comment_block.rs index 9dc3ee28f..d202a85f9 100644 --- a/crates/ide_assists/src/handlers/convert_comment_block.rs +++ b/crates/ide_assists/src/handlers/convert_comment_block.rs | |||
@@ -1,13 +1,6 @@ | |||
1 | use itertools::Itertools; | 1 | use itertools::Itertools; |
2 | use syntax::{ | 2 | use syntax::{ |
3 | ast::{ | 3 | ast::{self, edit::IndentLevel, Comment, CommentKind, CommentShape, Whitespace}, |
4 | self, | ||
5 | edit::IndentLevel, | ||
6 | Comment, CommentKind, | ||
7 | CommentPlacement::{Inner, Outer}, | ||
8 | CommentShape::{self, Block, Line}, | ||
9 | Whitespace, | ||
10 | }, | ||
11 | AstToken, Direction, SyntaxElement, TextRange, | 4 | AstToken, Direction, SyntaxElement, TextRange, |
12 | }; | 5 | }; |
13 | 6 | ||
@@ -29,21 +22,18 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
29 | /// */ | 22 | /// */ |
30 | /// ``` | 23 | /// ``` |
31 | pub(crate) fn convert_comment_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 24 | pub(crate) fn convert_comment_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
32 | if let Some(comment) = ctx.find_token_at_offset::<ast::Comment>() { | 25 | let comment = ctx.find_token_at_offset::<ast::Comment>()?; |
33 | // Only allow comments which are alone on their line | 26 | // Only allow comments which are alone on their line |
34 | if let Some(prev) = comment.syntax().prev_token() { | 27 | if let Some(prev) = comment.syntax().prev_token() { |
35 | if Whitespace::cast(prev).filter(|w| w.text().contains('\n')).is_none() { | 28 | if Whitespace::cast(prev).filter(|w| w.text().contains('\n')).is_none() { |
36 | return None; | 29 | return None; |
37 | } | ||
38 | } | 30 | } |
39 | |||
40 | return match comment.kind().shape { | ||
41 | ast::CommentShape::Block => block_to_line(acc, comment), | ||
42 | ast::CommentShape::Line => line_to_block(acc, comment), | ||
43 | }; | ||
44 | } | 31 | } |
45 | 32 | ||
46 | return None; | 33 | match comment.kind().shape { |
34 | ast::CommentShape::Block => block_to_line(acc, comment), | ||
35 | ast::CommentShape::Line => line_to_block(acc, comment), | ||
36 | } | ||
47 | } | 37 | } |
48 | 38 | ||
49 | fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> { | 39 | fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> { |
@@ -55,8 +45,7 @@ fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> { | |||
55 | target, | 45 | target, |
56 | |edit| { | 46 | |edit| { |
57 | let indentation = IndentLevel::from_token(comment.syntax()); | 47 | let indentation = IndentLevel::from_token(comment.syntax()); |
58 | let line_prefix = | 48 | let line_prefix = CommentKind { shape: CommentShape::Line, ..comment.kind() }.prefix(); |
59 | comment_kind_prefix(CommentKind { shape: CommentShape::Line, ..comment.kind() }); | ||
60 | 49 | ||
61 | let text = comment.text(); | 50 | let text = comment.text(); |
62 | let text = &text[comment.prefix().len()..(text.len() - "*/".len())].trim(); | 51 | let text = &text[comment.prefix().len()..(text.len() - "*/".len())].trim(); |
@@ -105,7 +94,7 @@ fn line_to_block(acc: &mut Assists, comment: ast::Comment) -> Option<()> { | |||
105 | comments.into_iter().map(|c| line_comment_text(indentation, c)).join("\n"); | 94 | comments.into_iter().map(|c| line_comment_text(indentation, c)).join("\n"); |
106 | 95 | ||
107 | let block_prefix = | 96 | let block_prefix = |
108 | comment_kind_prefix(CommentKind { shape: CommentShape::Block, ..comment.kind() }); | 97 | CommentKind { shape: CommentShape::Block, ..comment.kind() }.prefix(); |
109 | 98 | ||
110 | let output = | 99 | let output = |
111 | format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation.to_string()); | 100 | format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation.to_string()); |
@@ -182,17 +171,6 @@ fn line_comment_text(indentation: IndentLevel, comm: ast::Comment) -> String { | |||
182 | } | 171 | } |
183 | } | 172 | } |
184 | 173 | ||
185 | fn comment_kind_prefix(ck: ast::CommentKind) -> &'static str { | ||
186 | match (ck.shape, ck.doc) { | ||
187 | (Line, Some(Inner)) => "//!", | ||
188 | (Line, Some(Outer)) => "///", | ||
189 | (Line, None) => "//", | ||
190 | (Block, Some(Inner)) => "/*!", | ||
191 | (Block, Some(Outer)) => "/**", | ||
192 | (Block, None) => "/*", | ||
193 | } | ||
194 | } | ||
195 | |||
196 | #[cfg(test)] | 174 | #[cfg(test)] |
197 | mod tests { | 175 | mod tests { |
198 | use crate::tests::{check_assist, check_assist_not_applicable}; | 176 | use crate::tests::{check_assist, check_assist_not_applicable}; |
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs index 090282d28..29d25a58a 100644 --- a/crates/syntax/src/ast/token_ext.rs +++ b/crates/syntax/src/ast/token_ext.rs | |||
@@ -102,8 +102,9 @@ impl CommentKind { | |||
102 | kind | 102 | kind |
103 | } | 103 | } |
104 | 104 | ||
105 | fn prefix(&self) -> &'static str { | 105 | pub fn prefix(&self) -> &'static str { |
106 | let &(prefix, _) = CommentKind::BY_PREFIX.iter().find(|(_, kind)| kind == self).unwrap(); | 106 | let &(prefix, _) = |
107 | CommentKind::BY_PREFIX.iter().rev().find(|(_, kind)| kind == self).unwrap(); | ||
107 | prefix | 108 | prefix |
108 | } | 109 | } |
109 | } | 110 | } |