From c45221907adde640208a9e52636f4845d4654994 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 18 Dec 2020 23:00:43 +0300 Subject: Deduplicate highlight tags and symbol kinds Curiously, LSP uses different enums for those, and unsurprising and annoyingly, there are things which exist in one but not in the other. Let's not repeat the mistake and unify the two things --- crates/ide/src/display/navigation_target.rs | 6 +- crates/ide/src/references.rs | 4 +- crates/ide/src/syntax_highlighting.rs | 101 ++++++++++++++------------- crates/ide/src/syntax_highlighting/format.rs | 6 +- crates/ide/src/syntax_highlighting/tags.rs | 76 +++++++++----------- crates/rust-analyzer/src/to_proto.rs | 59 ++++++++-------- 6 files changed, 128 insertions(+), 124 deletions(-) (limited to 'crates') diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index cbdd4ecc2..7d0514105 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs @@ -18,13 +18,14 @@ use crate::FileSymbol; use super::short_label::ShortLabel; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum SymbolKind { Module, Impl, Field, TypeParam, LifetimeParam, + ValueParam, SelfParam, Local, Function, @@ -406,10 +407,11 @@ impl ToNav for hir::Local { Some(it) => it.to_string().into(), None => "".into(), }; + let kind = if self.is_param(db) { SymbolKind::ValueParam } else { SymbolKind::Local }; NavigationTarget { file_id: full_range.file_id, name, - kind: Some(SymbolKind::Local), + kind: Some(kind), full_range: full_range.range, focus_range: None, container_name: None, diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 8c00a7105..18ea19305 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -546,7 +546,7 @@ fn bar() { fn foo(i : u32) -> u32 { i<|> } "#, expect![[r#" - i Local FileId(0) 7..8 Other + i ValueParam FileId(0) 7..8 Other FileId(0) 25..26 Other Read "#]], @@ -560,7 +560,7 @@ fn foo(i : u32) -> u32 { i<|> } fn foo(i<|> : u32) -> u32 { i } "#, expect![[r#" - i Local FileId(0) 7..8 Other + i ValueParam FileId(0) 7..8 Other FileId(0) 25..26 Other Read "#]], diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 488969f1a..7f98aa316 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -23,7 +23,7 @@ use crate::{ syntax_highlighting::{ format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight, }, - FileId, HighlightModifier, HighlightTag, + FileId, HighlightModifier, HighlightTag, SymbolKind, }; pub(crate) use html::highlight_as_html; @@ -103,7 +103,7 @@ pub(crate) fn highlight( if let Some(range) = macro_call_range(&mc) { stack.add(HighlightedRange { range, - highlight: HighlightTag::Macro.into(), + highlight: HighlightTag::Symbol(SymbolKind::Macro).into(), binding_hash: None, }); } @@ -470,13 +470,13 @@ fn highlight_element( }; match name_kind { - Some(NameClass::ExternCrate(_)) => HighlightTag::Module.into(), + Some(NameClass::ExternCrate(_)) => HighlightTag::Symbol(SymbolKind::Module).into(), Some(NameClass::Definition(def)) => { highlight_def(db, def) | HighlightModifier::Definition } Some(NameClass::ConstReference(def)) => highlight_def(db, def), Some(NameClass::PatFieldShorthand { field_ref, .. }) => { - let mut h = HighlightTag::Field.into(); + let mut h = HighlightTag::Symbol(SymbolKind::Field).into(); if let Definition::Field(field) = field_ref { if let VariantDef::Union(_) = field.parent_def(db) { h |= HighlightModifier::Unsafe; @@ -493,14 +493,16 @@ fn highlight_element( NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { // even though we track whether we are in an attribute or not we still need this special case // as otherwise we would emit unresolved references for name refs inside attributes - Highlight::from(HighlightTag::Function) + Highlight::from(HighlightTag::Symbol(SymbolKind::Function)) } NAME_REF => { let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { match NameRefClass::classify(sema, &name_ref) { Some(name_kind) => match name_kind { - NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), + NameRefClass::ExternCrate(_) => { + HighlightTag::Symbol(SymbolKind::Module).into() + } NameRefClass::Definition(def) => { if let Definition::Local(local) = &def { if let Some(name) = local.name(db) { @@ -530,7 +532,9 @@ fn highlight_element( h } - NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), + NameRefClass::FieldShorthand { .. } => { + HighlightTag::Symbol(SymbolKind::Field).into() + } }, None if syntactic_name_ref_highlighting => { highlight_name_ref_by_syntax(name_ref, sema) @@ -556,7 +560,7 @@ fn highlight_element( CHAR => HighlightTag::CharLiteral.into(), QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow, LIFETIME => { - let h = Highlight::new(HighlightTag::Lifetime); + let h = Highlight::new(HighlightTag::Symbol(SymbolKind::LifetimeParam)); match element.parent().map(|it| it.kind()) { Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition, _ => h, @@ -580,7 +584,7 @@ fn highlight_element( HighlightTag::Operator.into() } T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { - HighlightTag::Macro.into() + HighlightTag::Symbol(SymbolKind::Macro).into() } T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { HighlightTag::BuiltinType.into() @@ -659,7 +663,7 @@ fn highlight_element( .and_then(SyntaxNode::parent) .and_then(ast::Path::cast) .and_then(|p| sema.resolve_path(&p)); - let mut h = HighlightTag::SelfKeyword.into(); + let mut h = HighlightTag::Symbol(SymbolKind::SelfParam).into(); if self_param_is_mut || matches!(self_path, Some(hir::PathResolution::Local(local)) @@ -756,10 +760,10 @@ fn highlight_method_call( fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { match def { - Definition::Macro(_) => HighlightTag::Macro, - Definition::Field(_) => HighlightTag::Field, + Definition::Macro(_) => HighlightTag::Symbol(SymbolKind::Macro), + Definition::Field(_) => HighlightTag::Symbol(SymbolKind::Field), Definition::ModuleDef(def) => match def { - hir::ModuleDef::Module(_) => HighlightTag::Module, + hir::ModuleDef::Module(_) => HighlightTag::Symbol(SymbolKind::Module), hir::ModuleDef::Function(func) => { let mut h = if func.as_assoc_item(db).is_some() { if func.self_param(db).is_none() { @@ -768,23 +772,23 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { HighlightTag::Method.into() } } else { - HighlightTag::Function.into() + HighlightTag::Symbol(SymbolKind::Function).into() }; if func.is_unsafe(db) { h |= HighlightModifier::Unsafe; } return h; } - hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, - hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, - hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, - hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant, - hir::ModuleDef::Const(_) => HighlightTag::Constant, - hir::ModuleDef::Trait(_) => HighlightTag::Trait, - hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias, + hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Symbol(SymbolKind::Struct), + hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Symbol(SymbolKind::Enum), + hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Symbol(SymbolKind::Union), + hir::ModuleDef::EnumVariant(_) => HighlightTag::Symbol(SymbolKind::Variant), + hir::ModuleDef::Const(_) => HighlightTag::Symbol(SymbolKind::Const), + hir::ModuleDef::Trait(_) => HighlightTag::Symbol(SymbolKind::Trait), + hir::ModuleDef::TypeAlias(_) => HighlightTag::Symbol(SymbolKind::TypeAlias), hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType, hir::ModuleDef::Static(s) => { - let mut h = Highlight::new(HighlightTag::Static); + let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Static)); if s.is_mut(db) { h |= HighlightModifier::Mutable; h |= HighlightModifier::Unsafe; @@ -792,11 +796,14 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { return h; } }, - Definition::SelfType(_) => HighlightTag::SelfType, - Definition::TypeParam(_) => HighlightTag::TypeParam, + Definition::SelfType(_) => HighlightTag::Symbol(SymbolKind::Impl), + Definition::TypeParam(_) => HighlightTag::Symbol(SymbolKind::TypeParam), Definition::Local(local) => { - let tag = - if local.is_param(db) { HighlightTag::ValueParam } else { HighlightTag::Local }; + let tag = if local.is_param(db) { + HighlightTag::Symbol(SymbolKind::ValueParam) + } else { + HighlightTag::Symbol(SymbolKind::Local) + }; let mut h = Highlight::new(tag); if local.is_mut(db) || local.ty(db).is_mutable_reference() { h |= HighlightModifier::Mutable; @@ -806,7 +813,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { } return h; } - Definition::LifetimeParam(_) => HighlightTag::Lifetime, + Definition::LifetimeParam(_) => HighlightTag::Symbol(SymbolKind::LifetimeParam), } .into() } @@ -820,19 +827,19 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { }; let tag = match parent.kind() { - STRUCT => HighlightTag::Struct, - ENUM => HighlightTag::Enum, - UNION => HighlightTag::Union, - TRAIT => HighlightTag::Trait, - TYPE_ALIAS => HighlightTag::TypeAlias, - TYPE_PARAM => HighlightTag::TypeParam, - RECORD_FIELD => HighlightTag::Field, - MODULE => HighlightTag::Module, - FN => HighlightTag::Function, - CONST => HighlightTag::Constant, - STATIC => HighlightTag::Static, - VARIANT => HighlightTag::EnumVariant, - IDENT_PAT => HighlightTag::Local, + STRUCT => HighlightTag::Symbol(SymbolKind::Struct), + ENUM => HighlightTag::Symbol(SymbolKind::Enum), + VARIANT => HighlightTag::Symbol(SymbolKind::Variant), + UNION => HighlightTag::Symbol(SymbolKind::Union), + TRAIT => HighlightTag::Symbol(SymbolKind::Trait), + TYPE_ALIAS => HighlightTag::Symbol(SymbolKind::TypeAlias), + TYPE_PARAM => HighlightTag::Symbol(SymbolKind::TypeParam), + RECORD_FIELD => HighlightTag::Symbol(SymbolKind::Field), + MODULE => HighlightTag::Symbol(SymbolKind::Module), + FN => HighlightTag::Symbol(SymbolKind::Function), + CONST => HighlightTag::Symbol(SymbolKind::Const), + STATIC => HighlightTag::Symbol(SymbolKind::Static), + IDENT_PAT => HighlightTag::Symbol(SymbolKind::Local), _ => default, }; @@ -851,10 +858,10 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics { return ast::MethodCallExpr::cast(parent) .and_then(|method_call| highlight_method_call(sema, &method_call)) - .unwrap_or_else(|| HighlightTag::Function.into()); + .unwrap_or_else(|| HighlightTag::Symbol(SymbolKind::Function).into()); } FIELD_EXPR => { - let h = HighlightTag::Field; + let h = HighlightTag::Symbol(SymbolKind::Field); let is_union = ast::FieldExpr::cast(parent) .and_then(|field_expr| { let field = sema.resolve_field(&field_expr)?; @@ -881,9 +888,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics { // within path, decide whether it is module or adt by checking for uppercase name return if name.text().chars().next().unwrap_or_default().is_uppercase() { - HighlightTag::Struct + HighlightTag::Symbol(SymbolKind::Struct) } else { - HighlightTag::Module + HighlightTag::Symbol(SymbolKind::Module) } .into(); } @@ -894,11 +901,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics HighlightTag::Function.into(), + CALL_EXPR => HighlightTag::Symbol(SymbolKind::Function).into(), _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { - HighlightTag::Struct.into() + HighlightTag::Symbol(SymbolKind::Struct) } else { - HighlightTag::Constant + HighlightTag::Symbol(SymbolKind::Const) } .into(), } diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs index 42f27df5d..26416022b 100644 --- a/crates/ide/src/syntax_highlighting/format.rs +++ b/crates/ide/src/syntax_highlighting/format.rs @@ -4,7 +4,9 @@ use syntax::{ AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, }; -use crate::{syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange}; +use crate::{ + syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange, SymbolKind, +}; #[derive(Default)] pub(super) struct FormatStringHighlighter { @@ -71,6 +73,6 @@ fn highlight_format_specifier(kind: FormatSpecifier) -> Option { | FormatSpecifier::Asterisk | FormatSpecifier::QuestionMark => HighlightTag::FormatSpecifier, FormatSpecifier::Integer | FormatSpecifier::Zero => HighlightTag::NumericLiteral, - FormatSpecifier::Identifier => HighlightTag::Local, + FormatSpecifier::Identifier => HighlightTag::Symbol(SymbolKind::Local), }) } diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index ffd9588b8..e0117a6b2 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs @@ -3,6 +3,8 @@ use std::{fmt, ops}; +use crate::SymbolKind; + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Highlight { pub tag: HighlightTag, @@ -14,40 +16,26 @@ pub struct HighlightModifiers(u32); #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum HighlightTag { - Attribute, + Symbol(SymbolKind), + BoolLiteral, BuiltinType, ByteLiteral, CharLiteral, + NumericLiteral, + StringLiteral, + Attribute, Comment, - Constant, - Enum, - EnumVariant, EscapeSequence, - Field, - Function, - Generic, + FormatSpecifier, Keyword, - Lifetime, - Macro, - Method, - Module, - NumericLiteral, Punctuation, - SelfKeyword, - SelfType, - Static, - StringLiteral, - Struct, - Trait, - TypeAlias, - TypeParam, - Union, - ValueParam, - Local, - UnresolvedReference, - FormatSpecifier, Operator, + UnresolvedReference, + + // FIXME: this two are random and don't fit with the others + Method, + Generic, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -73,39 +61,41 @@ pub enum HighlightModifier { impl HighlightTag { fn as_str(self) -> &'static str { match self { + HighlightTag::Symbol(symbol) => match symbol { + SymbolKind::Const => "constant", + SymbolKind::Static => "static", + SymbolKind::Enum => "enum", + SymbolKind::Variant => "enum_variant", + SymbolKind::Struct => "struct", + SymbolKind::Union => "union", + SymbolKind::Field => "field", + SymbolKind::Module => "module", + SymbolKind::Trait => "trait", + SymbolKind::Function => "function", + SymbolKind::TypeAlias => "type_alias", + SymbolKind::TypeParam => "type_param", + SymbolKind::LifetimeParam => "lifetime", + SymbolKind::Macro => "macro", + SymbolKind::Local => "variable", + SymbolKind::ValueParam => "value_param", + SymbolKind::SelfParam => "self_keyword", + SymbolKind::Impl => "self_type", + }, HighlightTag::Attribute => "attribute", HighlightTag::BoolLiteral => "bool_literal", HighlightTag::BuiltinType => "builtin_type", HighlightTag::ByteLiteral => "byte_literal", HighlightTag::CharLiteral => "char_literal", HighlightTag::Comment => "comment", - HighlightTag::Constant => "constant", - HighlightTag::Enum => "enum", - HighlightTag::EnumVariant => "enum_variant", HighlightTag::EscapeSequence => "escape_sequence", - HighlightTag::Field => "field", HighlightTag::FormatSpecifier => "format_specifier", - HighlightTag::Function => "function", HighlightTag::Generic => "generic", HighlightTag::Keyword => "keyword", - HighlightTag::Lifetime => "lifetime", HighlightTag::Punctuation => "punctuation", - HighlightTag::Macro => "macro", HighlightTag::Method => "method", - HighlightTag::Module => "module", HighlightTag::NumericLiteral => "numeric_literal", HighlightTag::Operator => "operator", - HighlightTag::SelfKeyword => "self_keyword", - HighlightTag::SelfType => "self_type", - HighlightTag::Static => "static", HighlightTag::StringLiteral => "string_literal", - HighlightTag::Struct => "struct", - HighlightTag::Trait => "trait", - HighlightTag::TypeAlias => "type_alias", - HighlightTag::TypeParam => "type_param", - HighlightTag::Union => "union", - HighlightTag::ValueParam => "value_param", - HighlightTag::Local => "variable", HighlightTag::UnresolvedReference => "unresolved_reference", } } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 6b2302803..229df47dc 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -43,9 +43,10 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { SymbolKind::Static => lsp_types::SymbolKind::Constant, SymbolKind::Const => lsp_types::SymbolKind::Constant, SymbolKind::Impl => lsp_types::SymbolKind::Object, - SymbolKind::Local | SymbolKind::SelfParam | SymbolKind::LifetimeParam => { - lsp_types::SymbolKind::Variable - } + SymbolKind::Local + | SymbolKind::SelfParam + | SymbolKind::LifetimeParam + | SymbolKind::ValueParam => lsp_types::SymbolKind::Variable, SymbolKind::Union => lsp_types::SymbolKind::Struct, } } @@ -371,34 +372,36 @@ fn semantic_token_type_and_modifiers( ) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) { let mut mods = semantic_tokens::ModifierSet::default(); let type_ = match highlight.tag { - HighlightTag::Struct => lsp_types::SemanticTokenType::STRUCT, - HighlightTag::Enum => lsp_types::SemanticTokenType::ENUM, - HighlightTag::Union => semantic_tokens::UNION, - HighlightTag::TypeAlias => semantic_tokens::TYPE_ALIAS, - HighlightTag::Trait => lsp_types::SemanticTokenType::INTERFACE, + HighlightTag::Symbol(symbol) => match symbol { + SymbolKind::Module => lsp_types::SemanticTokenType::NAMESPACE, + SymbolKind::Impl => lsp_types::SemanticTokenType::TYPE, + SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY, + SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER, + SymbolKind::LifetimeParam => semantic_tokens::LIFETIME, + SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER, + SymbolKind::SelfParam => semantic_tokens::SELF_KEYWORD, + SymbolKind::Local => lsp_types::SemanticTokenType::VARIABLE, + SymbolKind::Function => lsp_types::SemanticTokenType::FUNCTION, + SymbolKind::Const => { + mods |= semantic_tokens::CONSTANT; + mods |= lsp_types::SemanticTokenModifier::STATIC; + lsp_types::SemanticTokenType::VARIABLE + } + SymbolKind::Static => { + mods |= lsp_types::SemanticTokenModifier::STATIC; + lsp_types::SemanticTokenType::VARIABLE + } + SymbolKind::Struct => lsp_types::SemanticTokenType::STRUCT, + SymbolKind::Enum => lsp_types::SemanticTokenType::ENUM, + SymbolKind::Variant => lsp_types::SemanticTokenType::ENUM_MEMBER, + SymbolKind::Union => semantic_tokens::UNION, + SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS, + SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE, + SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO, + }, HighlightTag::BuiltinType => semantic_tokens::BUILTIN_TYPE, - HighlightTag::SelfKeyword => semantic_tokens::SELF_KEYWORD, - HighlightTag::SelfType => lsp_types::SemanticTokenType::TYPE, - HighlightTag::Field => lsp_types::SemanticTokenType::PROPERTY, - HighlightTag::Function => lsp_types::SemanticTokenType::FUNCTION, HighlightTag::Generic => semantic_tokens::GENERIC, - HighlightTag::Module => lsp_types::SemanticTokenType::NAMESPACE, HighlightTag::Method => lsp_types::SemanticTokenType::METHOD, - HighlightTag::Constant => { - mods |= semantic_tokens::CONSTANT; - mods |= lsp_types::SemanticTokenModifier::STATIC; - lsp_types::SemanticTokenType::VARIABLE - } - HighlightTag::Static => { - mods |= lsp_types::SemanticTokenModifier::STATIC; - lsp_types::SemanticTokenType::VARIABLE - } - HighlightTag::EnumVariant => lsp_types::SemanticTokenType::ENUM_MEMBER, - HighlightTag::Macro => lsp_types::SemanticTokenType::MACRO, - HighlightTag::ValueParam => lsp_types::SemanticTokenType::PARAMETER, - HighlightTag::Local => lsp_types::SemanticTokenType::VARIABLE, - HighlightTag::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER, - HighlightTag::Lifetime => semantic_tokens::LIFETIME, HighlightTag::ByteLiteral | HighlightTag::NumericLiteral => { lsp_types::SemanticTokenType::NUMBER } -- cgit v1.2.3