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
This commit is contained in:
Aleksey Kladov 2020-12-18 23:00:43 +03:00
parent 25185c1418
commit c45221907a
6 changed files with 129 additions and 125 deletions

View File

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

View File

@ -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
"#]],

View File

@ -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<RootDatabas
METHOD_CALL_EXPR => {
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<RootDatabas
_ => {
// 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<RootDatabas
};
match parent.kind() {
CALL_EXPR => 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(),
}

View File

@ -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<HighlightTag> {
| FormatSpecifier::Asterisk
| FormatSpecifier::QuestionMark => HighlightTag::FormatSpecifier,
FormatSpecifier::Integer | FormatSpecifier::Zero => HighlightTag::NumericLiteral,
FormatSpecifier::Identifier => HighlightTag::Local,
FormatSpecifier::Identifier => HighlightTag::Symbol(SymbolKind::Local),
})
}

View File

@ -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,
Comment,
Constant,
Enum,
EnumVariant,
EscapeSequence,
Field,
Function,
Generic,
Keyword,
Lifetime,
Macro,
Method,
Module,
NumericLiteral,
Punctuation,
SelfKeyword,
SelfType,
Static,
StringLiteral,
Struct,
Trait,
TypeAlias,
TypeParam,
Union,
ValueParam,
Local,
UnresolvedReference,
Attribute,
Comment,
EscapeSequence,
FormatSpecifier,
Keyword,
Punctuation,
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",
}
}

View File

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