From 55ba353b39db1e9d850f1df943ab6a16e7c15838 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 17 Dec 2020 14:29:05 +0300 Subject: Don't expose SyntaxKind from IDE API SyntaxKind is somewhat of an internal type, but IDE is using it to basically specify an icon. Let's have a dedicated entity for this instead. --- crates/ide/src/call_hierarchy.rs | 52 +++++------ crates/ide/src/display.rs | 3 +- crates/ide/src/display/navigation_target.rs | 132 ++++++++++++++++++++-------- crates/ide/src/file_structure.rs | 80 +++++++++-------- crates/ide/src/goto_definition.rs | 4 +- crates/ide/src/hover.rs | 74 ++++++++-------- crates/ide/src/lib.rs | 2 +- crates/ide/src/parent_module.rs | 6 +- crates/ide/src/references.rs | 72 +++++++-------- crates/ide/src/runnables.rs | 52 ++++++----- 10 files changed, 270 insertions(+), 207 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 8ad50a2ee..60e0cd4ad 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs @@ -181,8 +181,8 @@ fn caller() { call<|>ee(); } "#, - "callee FN FileId(0) 0..14 3..9", - &["caller FN FileId(0) 15..44 18..24 : [33..39]"], + "callee Function FileId(0) 0..14 3..9", + &["caller Function FileId(0) 15..44 18..24 : [33..39]"], &[], ); } @@ -197,8 +197,8 @@ fn caller() { callee(); } "#, - "callee FN FileId(0) 0..14 3..9", - &["caller FN FileId(0) 15..44 18..24 : [33..39]"], + "callee Function FileId(0) 0..14 3..9", + &["caller Function FileId(0) 15..44 18..24 : [33..39]"], &[], ); } @@ -214,8 +214,8 @@ fn caller() { callee(); } "#, - "callee FN FileId(0) 0..14 3..9", - &["caller FN FileId(0) 15..58 18..24 : [33..39, 47..53]"], + "callee Function FileId(0) 0..14 3..9", + &["caller Function FileId(0) 15..58 18..24 : [33..39, 47..53]"], &[], ); } @@ -234,10 +234,10 @@ fn caller2() { callee(); } "#, - "callee FN FileId(0) 0..14 3..9", + "callee Function FileId(0) 0..14 3..9", &[ - "caller1 FN FileId(0) 15..45 18..25 : [34..40]", - "caller2 FN FileId(0) 47..77 50..57 : [66..72]", + "caller1 Function FileId(0) 15..45 18..25 : [34..40]", + "caller2 Function FileId(0) 47..77 50..57 : [66..72]", ], &[], ); @@ -263,10 +263,10 @@ mod tests { } } "#, - "callee FN FileId(0) 0..14 3..9", + "callee Function FileId(0) 0..14 3..9", &[ - "caller1 FN FileId(0) 15..45 18..25 : [34..40]", - "test_caller FN FileId(0) 95..149 110..121 : [134..140]", + "caller1 Function FileId(0) 15..45 18..25 : [34..40]", + "test_caller Function FileId(0) 95..149 110..121 : [134..140]", ], &[], ); @@ -287,8 +287,8 @@ fn caller() { //- /foo/mod.rs pub fn callee() {} "#, - "callee FN FileId(1) 0..18 7..13", - &["caller FN FileId(0) 27..56 30..36 : [45..51]"], + "callee Function FileId(1) 0..18 7..13", + &["caller Function FileId(0) 27..56 30..36 : [45..51]"], &[], ); } @@ -304,9 +304,9 @@ fn call<|>er() { callee(); } "#, - "caller FN FileId(0) 15..58 18..24", + "caller Function FileId(0) 15..58 18..24", &[], - &["callee FN FileId(0) 0..14 3..9 : [33..39, 47..53]"], + &["callee Function FileId(0) 0..14 3..9 : [33..39, 47..53]"], ); } @@ -325,9 +325,9 @@ fn call<|>er() { //- /foo/mod.rs pub fn callee() {} "#, - "caller FN FileId(0) 27..56 30..36", + "caller Function FileId(0) 27..56 30..36", &[], - &["callee FN FileId(1) 0..18 7..13 : [45..51]"], + &["callee Function FileId(1) 0..18 7..13 : [45..51]"], ); } @@ -348,9 +348,9 @@ fn caller3() { } "#, - "caller2 FN FileId(0) 33..64 36..43", - &["caller1 FN FileId(0) 0..31 3..10 : [19..26]"], - &["caller3 FN FileId(0) 66..83 69..76 : [52..59]"], + "caller2 Function FileId(0) 33..64 36..43", + &["caller1 Function FileId(0) 0..31 3..10 : [19..26]"], + &["caller3 Function FileId(0) 66..83 69..76 : [52..59]"], ); } @@ -368,9 +368,9 @@ fn main() { a<|>() } "#, - "a FN FileId(0) 0..18 3..4", - &["main FN FileId(0) 31..52 34..38 : [47..48]"], - &["b FN FileId(0) 20..29 23..24 : [13..14]"], + "a Function FileId(0) 0..18 3..4", + &["main Function FileId(0) 31..52 34..38 : [47..48]"], + &["b Function FileId(0) 20..29 23..24 : [13..14]"], ); check_hierarchy( @@ -385,8 +385,8 @@ fn main() { a() } "#, - "b FN FileId(0) 20..29 23..24", - &["a FN FileId(0) 0..18 3..4 : [13..14]"], + "b Function FileId(0) 20..29 23..24", + &["a Function FileId(0) 0..18 3..4 : [13..14]"], &[], ); } diff --git a/crates/ide/src/display.rs b/crates/ide/src/display.rs index 0650915c5..bae9e40df 100644 --- a/crates/ide/src/display.rs +++ b/crates/ide/src/display.rs @@ -1,10 +1,9 @@ //! This module contains utilities for turning SyntaxNodes and HIR types //! into types that may be used to render in a UI. -mod navigation_target; +pub(crate) mod navigation_target; mod short_label; -pub use navigation_target::NavigationTarget; pub(crate) use navigation_target::{ToNav, TryToNav}; pub(crate) use short_label::ShortLabel; diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index 48acb8c93..ac6346b2b 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -2,19 +2,43 @@ use either::Either; use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource}; -use ide_db::base_db::{FileId, SourceDatabase}; +use ide_db::{ + base_db::{FileId, SourceDatabase}, + symbol_index::FileSymbolKind, +}; use ide_db::{defs::Definition, RootDatabase}; use syntax::{ ast::{self, NameOwner}, - match_ast, AstNode, SmolStr, - SyntaxKind::{self, IDENT_PAT, LIFETIME_PARAM, TYPE_PARAM}, - TextRange, + match_ast, AstNode, SmolStr, TextRange, }; use crate::FileSymbol; use super::short_label::ShortLabel; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum SymbolKind { + Module, + Impl, + Field, + TypeParam, + LifetimeParam, + SelfParam, + Local, + Function, + Const, + Static, + Struct, + Enum, + Variant, + Union, + TypeAlias, + Trait, + Macro, + // Do we actually need this? + DocTest, +} + /// `NavigationTarget` represents and element in the editor's UI which you can /// click on to navigate to a particular piece of code. /// @@ -40,7 +64,7 @@ pub struct NavigationTarget { /// Clients should place the cursor on this range when navigating to this target. pub focus_range: Option, pub name: SmolStr, - pub kind: SyntaxKind, + pub kind: SymbolKind, pub container_name: Option, pub description: Option, pub docs: Option, @@ -69,7 +93,7 @@ impl NavigationTarget { name, None, frange.range, - src.value.syntax().kind(), + SymbolKind::Module, ); res.docs = module.attrs(db).docs(); res.description = src.value.short_label(); @@ -101,6 +125,7 @@ impl NavigationTarget { pub(crate) fn from_named( db: &RootDatabase, node: InFile<&dyn ast::NameOwner>, + kind: SymbolKind, ) -> NavigationTarget { let name = node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_")); @@ -108,13 +133,7 @@ impl NavigationTarget { node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range); let frange = node.map(|it| it.syntax()).original_file_range(db); - NavigationTarget::from_syntax( - frange.file_id, - name, - focus_range, - frange.range, - node.value.syntax().kind(), - ) + NavigationTarget::from_syntax(frange.file_id, name, focus_range, frange.range, kind) } fn from_syntax( @@ -122,7 +141,7 @@ impl NavigationTarget { name: SmolStr, focus_range: Option, full_range: TextRange, - kind: SyntaxKind, + kind: SymbolKind, ) -> NavigationTarget { NavigationTarget { file_id, @@ -142,7 +161,17 @@ impl ToNav for FileSymbol { NavigationTarget { file_id: self.file_id, name: self.name.clone(), - kind: self.kind, + kind: match self.kind { + FileSymbolKind::Function => SymbolKind::Function, + FileSymbolKind::Struct => SymbolKind::Struct, + FileSymbolKind::Enum => SymbolKind::Enum, + FileSymbolKind::Trait => SymbolKind::Trait, + FileSymbolKind::Module => SymbolKind::Module, + FileSymbolKind::TypeAlias => SymbolKind::TypeAlias, + FileSymbolKind::Const => SymbolKind::Const, + FileSymbolKind::Static => SymbolKind::Static, + FileSymbolKind::Macro => SymbolKind::Macro, + }, full_range: self.range, focus_range: self.name_range, container_name: self.container_name.clone(), @@ -191,16 +220,36 @@ impl TryToNav for hir::ModuleDef { } } -pub(crate) trait ToNavFromAst {} -impl ToNavFromAst for hir::Function {} -impl ToNavFromAst for hir::Const {} -impl ToNavFromAst for hir::Static {} -impl ToNavFromAst for hir::Struct {} -impl ToNavFromAst for hir::Enum {} -impl ToNavFromAst for hir::EnumVariant {} -impl ToNavFromAst for hir::Union {} -impl ToNavFromAst for hir::TypeAlias {} -impl ToNavFromAst for hir::Trait {} +pub(crate) trait ToNavFromAst { + const KIND: SymbolKind; +} +impl ToNavFromAst for hir::Function { + const KIND: SymbolKind = SymbolKind::Function; +} +impl ToNavFromAst for hir::Const { + const KIND: SymbolKind = SymbolKind::Const; +} +impl ToNavFromAst for hir::Static { + const KIND: SymbolKind = SymbolKind::Static; +} +impl ToNavFromAst for hir::Struct { + const KIND: SymbolKind = SymbolKind::Struct; +} +impl ToNavFromAst for hir::Enum { + const KIND: SymbolKind = SymbolKind::Enum; +} +impl ToNavFromAst for hir::EnumVariant { + const KIND: SymbolKind = SymbolKind::Variant; +} +impl ToNavFromAst for hir::Union { + const KIND: SymbolKind = SymbolKind::Union; +} +impl ToNavFromAst for hir::TypeAlias { + const KIND: SymbolKind = SymbolKind::TypeAlias; +} +impl ToNavFromAst for hir::Trait { + const KIND: SymbolKind = SymbolKind::Trait; +} impl ToNav for D where @@ -209,8 +258,11 @@ where { fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { let src = self.source(db); - let mut res = - NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); + let mut res = NavigationTarget::from_named( + db, + src.as_ref().map(|it| it as &dyn ast::NameOwner), + D::KIND, + ); res.docs = self.docs(db); res.description = src.value.short_label(); res @@ -228,7 +280,7 @@ impl ToNav for hir::Module { } }; let frange = src.with_value(syntax).original_file_range(db); - NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind()) + NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, SymbolKind::Module) } } @@ -252,7 +304,7 @@ impl ToNav for hir::Impl { "impl".into(), focus_range, frange.range, - src.value.syntax().kind(), + SymbolKind::Impl, ) } } @@ -263,7 +315,8 @@ impl ToNav for hir::Field { match &src.value { FieldSource::Named(it) => { - let mut res = NavigationTarget::from_named(db, src.with_value(it)); + let mut res = + NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field); res.docs = self.docs(db); res.description = it.short_label(); res @@ -275,7 +328,7 @@ impl ToNav for hir::Field { "".into(), None, frange.range, - it.syntax().kind(), + SymbolKind::Field, ) } } @@ -286,8 +339,11 @@ impl ToNav for hir::MacroDef { fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { let src = self.source(db); log::debug!("nav target {:#?}", src.value.syntax()); - let mut res = - NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); + let mut res = NavigationTarget::from_named( + db, + src.as_ref().map(|it| it as &dyn ast::NameOwner), + SymbolKind::Macro, + ); res.docs = self.docs(db); res } @@ -330,7 +386,7 @@ impl ToNav for hir::Local { NavigationTarget { file_id: full_range.file_id, name, - kind: IDENT_PAT, + kind: SymbolKind::Local, full_range: full_range.range, focus_range: None, container_name: None, @@ -354,7 +410,7 @@ impl ToNav for hir::TypeParam { NavigationTarget { file_id: src.file_id.original_file(db), name: self.name(db).to_string().into(), - kind: TYPE_PARAM, + kind: SymbolKind::TypeParam, full_range, focus_range, container_name: None, @@ -371,7 +427,7 @@ impl ToNav for hir::LifetimeParam { NavigationTarget { file_id: src.file_id.original_file(db), name: self.name(db).to_string().into(), - kind: LIFETIME_PARAM, + kind: SymbolKind::LifetimeParam, full_range, focus_range: Some(full_range), container_name: None, @@ -432,7 +488,7 @@ fn foo() { enum FooInner { } } 5..13, ), name: "FooInner", - kind: ENUM, + kind: Enum, container_name: None, description: Some( "enum FooInner", @@ -448,7 +504,7 @@ fn foo() { enum FooInner { } } 34..42, ), name: "FooInner", - kind: ENUM, + kind: Enum, container_name: Some( "foo", ), diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs index c51531391..32556dad3 100644 --- a/crates/ide/src/file_structure.rs +++ b/crates/ide/src/file_structure.rs @@ -1,15 +1,17 @@ use syntax::{ ast::{self, AttrsOwner, GenericParamsOwner, NameOwner}, - match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, WalkEvent, + match_ast, AstNode, SourceFile, SyntaxNode, TextRange, WalkEvent, }; +use crate::SymbolKind; + #[derive(Debug, Clone)] pub struct StructureNode { pub parent: Option, pub label: String, pub navigation_range: TextRange, pub node_range: TextRange, - pub kind: SyntaxKind, + pub kind: SymbolKind, pub detail: Option, pub deprecated: bool, } @@ -51,25 +53,27 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec { } fn structure_node(node: &SyntaxNode) -> Option { - fn decl(node: N) -> Option { - decl_with_detail(&node, None) + fn decl(node: N, kind: SymbolKind) -> Option { + decl_with_detail(&node, None, kind) } fn decl_with_type_ref( node: &N, type_ref: Option, + kind: SymbolKind, ) -> Option { let detail = type_ref.map(|type_ref| { let mut detail = String::new(); collapse_ws(type_ref.syntax(), &mut detail); detail }); - decl_with_detail(node, detail) + decl_with_detail(node, detail, kind) } fn decl_with_detail( node: &N, detail: Option, + kind: SymbolKind, ) -> Option { let name = node.name()?; @@ -78,7 +82,7 @@ fn structure_node(node: &SyntaxNode) -> Option { label: name.text().to_string(), navigation_range: name.syntax().text_range(), node_range: node.syntax().text_range(), - kind: node.syntax().kind(), + kind, detail, deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"), }) @@ -117,18 +121,18 @@ fn structure_node(node: &SyntaxNode) -> Option { collapse_ws(ret_type.syntax(), &mut detail); } - decl_with_detail(&it, Some(detail)) + decl_with_detail(&it, Some(detail), SymbolKind::Function) }, - ast::Struct(it) => decl(it), - ast::Union(it) => decl(it), - ast::Enum(it) => decl(it), - ast::Variant(it) => decl(it), - ast::Trait(it) => decl(it), - ast::Module(it) => decl(it), - ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty()), - ast::RecordField(it) => decl_with_type_ref(&it, it.ty()), - ast::Const(it) => decl_with_type_ref(&it, it.ty()), - ast::Static(it) => decl_with_type_ref(&it, it.ty()), + ast::Struct(it) => decl(it, SymbolKind::Struct), + ast::Union(it) => decl(it, SymbolKind::Union), + ast::Enum(it) => decl(it, SymbolKind::Enum), + ast::Variant(it) => decl(it, SymbolKind::Variant), + ast::Trait(it) => decl(it, SymbolKind::Trait), + ast::Module(it) => decl(it, SymbolKind::Module), + ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::TypeAlias), + ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Field), + ast::Const(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Const), + ast::Static(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Static), ast::Impl(it) => { let target_type = it.self_ty()?; let target_trait = it.trait_(); @@ -144,13 +148,13 @@ fn structure_node(node: &SyntaxNode) -> Option { label, navigation_range: target_type.syntax().text_range(), node_range: it.syntax().text_range(), - kind: it.syntax().kind(), + kind: SymbolKind::Impl, detail: None, deprecated: false, }; Some(node) }, - ast::MacroRules(it) => decl(it), + ast::MacroRules(it) => decl(it, SymbolKind::Macro), _ => None, } } @@ -222,7 +226,7 @@ fn very_obsolete() {} label: "Foo", navigation_range: 8..11, node_range: 1..26, - kind: STRUCT, + kind: Struct, detail: None, deprecated: false, }, @@ -233,7 +237,7 @@ fn very_obsolete() {} label: "x", navigation_range: 18..19, node_range: 18..24, - kind: RECORD_FIELD, + kind: Field, detail: Some( "i32", ), @@ -244,7 +248,7 @@ fn very_obsolete() {} label: "m", navigation_range: 32..33, node_range: 28..158, - kind: MODULE, + kind: Module, detail: None, deprecated: false, }, @@ -255,7 +259,7 @@ fn very_obsolete() {} label: "bar1", navigation_range: 43..47, node_range: 40..52, - kind: FN, + kind: Function, detail: Some( "fn()", ), @@ -268,7 +272,7 @@ fn very_obsolete() {} label: "bar2", navigation_range: 60..64, node_range: 57..81, - kind: FN, + kind: Function, detail: Some( "fn(t: T) -> T", ), @@ -281,7 +285,7 @@ fn very_obsolete() {} label: "bar3", navigation_range: 89..93, node_range: 86..156, - kind: FN, + kind: Function, detail: Some( "fn(a: A, b: B) -> Vec< u32 >", ), @@ -292,7 +296,7 @@ fn very_obsolete() {} label: "E", navigation_range: 165..166, node_range: 160..180, - kind: ENUM, + kind: Enum, detail: None, deprecated: false, }, @@ -303,7 +307,7 @@ fn very_obsolete() {} label: "X", navigation_range: 169..170, node_range: 169..170, - kind: VARIANT, + kind: Variant, detail: None, deprecated: false, }, @@ -314,7 +318,7 @@ fn very_obsolete() {} label: "Y", navigation_range: 172..173, node_range: 172..178, - kind: VARIANT, + kind: Variant, detail: None, deprecated: false, }, @@ -323,7 +327,7 @@ fn very_obsolete() {} label: "T", navigation_range: 186..187, node_range: 181..193, - kind: TYPE_ALIAS, + kind: TypeAlias, detail: Some( "()", ), @@ -334,7 +338,7 @@ fn very_obsolete() {} label: "S", navigation_range: 201..202, node_range: 194..213, - kind: STATIC, + kind: Static, detail: Some( "i32", ), @@ -345,7 +349,7 @@ fn very_obsolete() {} label: "C", navigation_range: 220..221, node_range: 214..232, - kind: CONST, + kind: Const, detail: Some( "i32", ), @@ -356,7 +360,7 @@ fn very_obsolete() {} label: "impl E", navigation_range: 239..240, node_range: 234..243, - kind: IMPL, + kind: Impl, detail: None, deprecated: false, }, @@ -365,7 +369,7 @@ fn very_obsolete() {} label: "impl fmt::Debug for E", navigation_range: 265..266, node_range: 245..269, - kind: IMPL, + kind: Impl, detail: None, deprecated: false, }, @@ -374,7 +378,7 @@ fn very_obsolete() {} label: "mc", navigation_range: 284..286, node_range: 271..303, - kind: MACRO_RULES, + kind: Macro, detail: None, deprecated: false, }, @@ -383,7 +387,7 @@ fn very_obsolete() {} label: "mcexp", navigation_range: 334..339, node_range: 305..356, - kind: MACRO_RULES, + kind: Macro, detail: None, deprecated: false, }, @@ -392,7 +396,7 @@ fn very_obsolete() {} label: "mcexp", navigation_range: 387..392, node_range: 358..409, - kind: MACRO_RULES, + kind: Macro, detail: None, deprecated: false, }, @@ -401,7 +405,7 @@ fn very_obsolete() {} label: "obsolete", navigation_range: 428..436, node_range: 411..441, - kind: FN, + kind: Function, detail: Some( "fn()", ), @@ -412,7 +416,7 @@ fn very_obsolete() {} label: "very_obsolete", navigation_range: 481..494, node_range: 443..499, - kind: FN, + kind: Function, detail: Some( "fn()", ), diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 173509b08..5bee69f4b 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -9,7 +9,7 @@ use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, use crate::{ display::{ToNav, TryToNav}, - FilePosition, NavigationTarget, RangeInfo, + FilePosition, NavigationTarget, RangeInfo, SymbolKind, }; // Feature: Go to Definition @@ -86,7 +86,7 @@ fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option