From b6a854e161cc122e6d9ae12084b6a1d1f4d0f241 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 May 2019 16:10:07 +0300 Subject: update ra_ide_api to use builtins --- crates/ra_ide_api/src/completion/complete_path.rs | 20 +++++ .../ra_ide_api/src/completion/completion_item.rs | 2 + crates/ra_ide_api/src/completion/presentation.rs | 7 +- crates/ra_ide_api/src/display/navigation_target.rs | 13 +++- crates/ra_ide_api/src/goto_definition.rs | 5 +- crates/ra_ide_api/src/marks.rs | 1 + crates/ra_ide_api/src/syntax_highlighting.rs | 88 ++++++++++------------ crates/ra_lsp_server/src/conv.rs | 1 + 8 files changed, 82 insertions(+), 55 deletions(-) diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index c41752ae7..99da24142 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs @@ -17,6 +17,12 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { hir::ModuleDef::Module(module) => { let module_scope = module.scope(ctx.db); for (name, res) in module_scope.entries() { + if let Some(hir::ModuleDef::BuiltinType(..)) = res.def.as_ref().take_types() { + if ctx.use_item_syntax.is_some() { + tested_by!(dont_complete_primitive_in_use); + continue; + } + } if Some(module) == ctx.module { if let Some(import) = res.import { if let Either::A(use_tree) = module.import_source(ctx.db, import) { @@ -88,6 +94,20 @@ mod tests { assert_eq!(completions.len(), 2); } + #[test] + fn dont_complete_primitive_in_use() { + covers!(dont_complete_primitive_in_use); + let completions = do_completion(r"use self::<|>;", CompletionKind::BuiltinType); + assert!(completions.is_empty()); + } + + #[test] + fn completes_primitives() { + let completions = + do_completion(r"fn main() { let _: <|> = 92; }", CompletionKind::BuiltinType); + assert_eq!(completions.len(), 17); + } + #[test] fn completes_mod_with_docs() { check_reference_completion( diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index 6f1392231..6f2a60640 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs @@ -78,6 +78,7 @@ pub enum CompletionItemKind { Keyword, Module, Function, + BuiltinType, Struct, Enum, EnumVariant, @@ -102,6 +103,7 @@ pub(crate) enum CompletionKind { Magic, Snippet, Postfix, + BuiltinType, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 064d379a4..d405161d6 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -57,6 +57,7 @@ impl Completions { } Some(it) => it, }; + let mut completion_kind = CompletionKind::Reference; let (kind, docs) = match def { Resolution::Def(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)), Resolution::Def(Function(func)) => { @@ -70,6 +71,10 @@ impl Completions { Resolution::Def(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)), Resolution::Def(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)), Resolution::Def(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), + Resolution::Def(BuiltinType(..)) => { + completion_kind = CompletionKind::BuiltinType; + (CompletionItemKind::BuiltinType, None) + } Resolution::GenericParam(..) => (CompletionItemKind::TypeParam, None), Resolution::LocalBinding(..) => (CompletionItemKind::Binding, None), Resolution::SelfType(..) => ( @@ -77,7 +82,7 @@ impl Completions { None, ), }; - CompletionItem::new(CompletionKind::Reference, ctx.source_range(), local_name) + CompletionItem::new(completion_kind, ctx.source_range(), local_name) .kind(kind) .set_documentation(docs) .add_to(self) diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index ae729614f..e19c071b0 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -165,8 +165,11 @@ impl NavigationTarget { } } - pub(crate) fn from_def(db: &RootDatabase, module_def: hir::ModuleDef) -> NavigationTarget { - match module_def { + pub(crate) fn from_def( + db: &RootDatabase, + module_def: hir::ModuleDef, + ) -> Option { + let nav = match module_def { hir::ModuleDef::Module(module) => NavigationTarget::from_module(db, module), hir::ModuleDef::Function(func) => NavigationTarget::from_function(db, func), hir::ModuleDef::Struct(s) => { @@ -201,7 +204,11 @@ impl NavigationTarget { let (file_id, node) = e.source(db); NavigationTarget::from_named(file_id.original_file(db), &*node) } - } + hir::ModuleDef::BuiltinType(..) => { + return None; + } + }; + Some(nav) } pub(crate) fn from_impl_block( diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 4f8554625..97b367115 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -62,7 +62,10 @@ pub(crate) fn reference_definition( Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)), Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)), Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_impl_item(db, assoc)), - Some(Def(def)) => return Exact(NavigationTarget::from_def(db, def)), + Some(Def(def)) => match NavigationTarget::from_def(db, def) { + Some(nav) => return Exact(nav), + None => return Approximate(vec![]), + }, Some(SelfType(ty)) => { if let Some((def_id, _)) = ty.as_adt() { return Exact(NavigationTarget::from_adt_def(db, def_id)); diff --git a/crates/ra_ide_api/src/marks.rs b/crates/ra_ide_api/src/marks.rs index cc894a7df..9cb991de5 100644 --- a/crates/ra_ide_api/src/marks.rs +++ b/crates/ra_ide_api/src/marks.rs @@ -6,4 +6,5 @@ test_utils::marks!( goto_definition_works_for_named_fields call_info_bad_offset dont_complete_current_use + dont_complete_primitive_in_use ); diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 4b24754a8..3a04a51cd 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs @@ -30,14 +30,6 @@ fn is_control_keyword(kind: SyntaxKind) -> bool { } } -fn is_prim_type(node: &ast::NameRef) -> bool { - match node.text().as_str() { - "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "u64" | "i64" | "u128" | "i128" | "usize" - | "isize" | "f32" | "f64" | "bool" | "char" | "str" => true, - _ => false, - } -} - pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { let _p = profile("highlight"); let source_file = db.parse(file_id).tree; @@ -71,51 +63,47 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec { if let Some(name_ref) = node.as_node().and_then(ast::NameRef::cast) { // FIXME: revisit this after #1340 - if is_prim_type(name_ref) { - "type" - } else { - use crate::name_ref_kind::{classify_name_ref, NameRefKind::*}; - use hir::{ModuleDef, ImplItem}; + use crate::name_ref_kind::{classify_name_ref, NameRefKind::*}; + use hir::{ModuleDef, ImplItem}; - // FIXME: try to reuse the SourceAnalyzers - let analyzer = - hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); - match classify_name_ref(db, &analyzer, name_ref) { - Some(Method(_)) => "function", - Some(Macro(_)) => "macro", - Some(FieldAccess(_)) => "field", - Some(AssocItem(ImplItem::Method(_))) => "function", - Some(AssocItem(ImplItem::Const(_))) => "constant", - Some(AssocItem(ImplItem::TypeAlias(_))) => "type", - Some(Def(ModuleDef::Module(_))) => "module", - Some(Def(ModuleDef::Function(_))) => "function", - Some(Def(ModuleDef::Struct(_))) => "type", - Some(Def(ModuleDef::Union(_))) => "type", - Some(Def(ModuleDef::Enum(_))) => "type", - Some(Def(ModuleDef::EnumVariant(_))) => "constant", - Some(Def(ModuleDef::Const(_))) => "constant", - Some(Def(ModuleDef::Static(_))) => "constant", - Some(Def(ModuleDef::Trait(_))) => "type", - Some(Def(ModuleDef::TypeAlias(_))) => "type", - Some(SelfType(_)) => "type", - Some(Pat(ptr)) => { - binding_hash = Some({ - let text = ptr - .syntax_node_ptr() - .to_node(&source_file.syntax()) - .text() - .to_smol_string(); - let shadow_count = - bindings_shadow_count.entry(text.clone()).or_default(); - calc_binding_hash(file_id, &text, *shadow_count) - }); + // FIXME: try to reuse the SourceAnalyzers + let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None); + match classify_name_ref(db, &analyzer, name_ref) { + Some(Method(_)) => "function", + Some(Macro(_)) => "macro", + Some(FieldAccess(_)) => "field", + Some(AssocItem(ImplItem::Method(_))) => "function", + Some(AssocItem(ImplItem::Const(_))) => "constant", + Some(AssocItem(ImplItem::TypeAlias(_))) => "type", + Some(Def(ModuleDef::Module(_))) => "module", + Some(Def(ModuleDef::Function(_))) => "function", + Some(Def(ModuleDef::Struct(_))) => "type", + Some(Def(ModuleDef::Union(_))) => "type", + Some(Def(ModuleDef::Enum(_))) => "type", + Some(Def(ModuleDef::EnumVariant(_))) => "constant", + Some(Def(ModuleDef::Const(_))) => "constant", + Some(Def(ModuleDef::Static(_))) => "constant", + Some(Def(ModuleDef::Trait(_))) => "type", + Some(Def(ModuleDef::TypeAlias(_))) => "type", + Some(Def(ModuleDef::BuiltinType(_))) => "type", + Some(SelfType(_)) => "type", + Some(Pat(ptr)) => { + binding_hash = Some({ + let text = ptr + .syntax_node_ptr() + .to_node(&source_file.syntax()) + .text() + .to_smol_string(); + let shadow_count = + bindings_shadow_count.entry(text.clone()).or_default(); + calc_binding_hash(file_id, &text, *shadow_count) + }); - "variable" - } - Some(SelfParam(_)) => "type", - Some(GenericParam(_)) => "type", - None => "text", + "variable" } + Some(SelfParam(_)) => "type", + Some(GenericParam(_)) => "type", + None => "text", } } else { "text" diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 50a12ddbc..1b349d02a 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -65,6 +65,7 @@ impl Conv for CompletionItemKind { CompletionItemKind::Struct => Struct, CompletionItemKind::Enum => Enum, CompletionItemKind::EnumVariant => EnumMember, + CompletionItemKind::BuiltinType => Struct, CompletionItemKind::Binding => Variable, CompletionItemKind::Field => Field, CompletionItemKind::Trait => Interface, -- cgit v1.2.3