update ra_ide_api to use builtins

This commit is contained in:
Aleksey Kladov 2019-05-30 16:10:07 +03:00
parent c6ee9d681c
commit b6a854e161
8 changed files with 82 additions and 55 deletions

View file

@ -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(

View file

@ -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)]

View file

@ -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)

View file

@ -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<NavigationTarget> {
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(

View file

@ -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));

View file

@ -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
);

View file

@ -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<HighlightedRange> {
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<HighlightedRa
NAME_REF => {
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"

View file

@ -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,