8279: Added initial implementation for

Operator semantic highlighting.
This commit is contained in:
Chetan Khilosiya 2021-04-06 00:09:17 +05:30
parent 5f279d57f0
commit 1735b3ef6a
5 changed files with 92 additions and 19 deletions

View File

@ -82,7 +82,7 @@ pub use crate::{
references::{rename::RenameError, ReferenceSearchResult},
runnables::{Runnable, RunnableKind, TestId},
syntax_highlighting::{
tags::{Highlight, HlMod, HlMods, HlPunct, HlTag},
tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
HlRange,
},
};

View File

@ -12,7 +12,10 @@ use syntax::{
SyntaxNode, SyntaxToken, T,
};
use crate::{syntax_highlighting::tags::HlPunct, Highlight, HlMod, HlTag};
use crate::{
syntax_highlighting::tags::{HlOperator, HlPunct},
Highlight, HlMod, HlTag,
};
pub(super) fn element(
sema: &Semantics<RootDatabase>,
@ -132,7 +135,7 @@ pub(super) fn element(
INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(),
BYTE => HlTag::ByteLiteral.into(),
CHAR => HlTag::CharLiteral.into(),
QUESTION => Highlight::new(HlTag::Operator) | HlMod::ControlFlow,
QUESTION => Highlight::new(HlTag::Operator(HlOperator::Other)) | HlMod::ControlFlow,
LIFETIME => {
let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap();
@ -146,8 +149,11 @@ pub(super) fn element(
}
}
p if p.is_punct() => match p {
T![&] if element.parent().and_then(ast::BinExpr::cast).is_some() => {
HlTag::Operator(HlOperator::Bitwise).into()
}
T![&] => {
let h = HlTag::Operator.into();
let h = HlTag::Operator(HlOperator::Other).into();
let is_unsafe = element
.parent()
.and_then(ast::RefExpr::cast)
@ -159,13 +165,21 @@ pub(super) fn element(
h
}
}
T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => HlTag::Operator.into(),
T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => {
HlTag::Operator(HlOperator::Other).into()
}
T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
eprintln!("in macro call: {}", element);
HlTag::Symbol(SymbolKind::Macro).into()
}
T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => {
eprintln!("in never type : {}", element);
HlTag::BuiltinType.into()
}
T![!] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => {
eprintln!("pre expr for : {}", element);
HlTag::Operator(HlOperator::Bitwise).into()
}
T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => {
HlTag::Keyword.into()
}
@ -175,32 +189,60 @@ pub(super) fn element(
let expr = prefix_expr.expr()?;
let ty = sema.type_of_expr(&expr)?;
if ty.is_raw_ptr() {
HlTag::Operator | HlMod::Unsafe
HlTag::Operator(HlOperator::Other) | HlMod::Unsafe
} else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() {
HlTag::Operator.into()
HlTag::Operator(HlOperator::Other).into()
} else {
HlTag::Punctuation(HlPunct::Other).into()
}
}
T![-] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => {
eprintln!("the - operator: {}", element);
let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?;
let expr = prefix_expr.expr()?;
match expr {
ast::Expr::Literal(_) => HlTag::NumericLiteral,
_ => HlTag::Operator,
_ => HlTag::Operator(HlOperator::Other),
}
.into()
}
_ if element.parent().and_then(ast::PrefixExpr::cast).is_some() => {
HlTag::Operator.into()
eprintln!("the prefix expr block: {}", element);
HlTag::Operator(HlOperator::Other).into()
}
T![+] | T![-] | T![*] | T![/] | T![+=] | T![-=] | T![*=] | T![/=]
if element.parent().and_then(ast::BinExpr::cast).is_some() =>
{
HlTag::Operator(HlOperator::Arithmetic).into()
}
T![|] | T![&] | T![!] | T![^] | T![|=] | T![&=] | T![^=]
if element.parent().and_then(ast::BinExpr::cast).is_some() =>
{
HlTag::Operator(HlOperator::Bitwise).into()
}
T![&&] | T![||] if element.parent().and_then(ast::BinExpr::cast).is_some() => {
HlTag::Operator(HlOperator::Logical).into()
}
T![>] | T![<] | T![==] | T![>=] | T![<=] | T![!=]
if element.parent().and_then(ast::BinExpr::cast).is_some() =>
{
HlTag::Operator(HlOperator::Comparision).into()
}
_ if element.parent().and_then(ast::BinExpr::cast).is_some() => {
eprintln!("the bin expr : {}", element);
HlTag::Operator(HlOperator::Other).into()
}
_ if element.parent().and_then(ast::BinExpr::cast).is_some() => HlTag::Operator.into(),
_ if element.parent().and_then(ast::RangeExpr::cast).is_some() => {
HlTag::Operator.into()
eprintln!("the range expr block: {}", element);
HlTag::Operator(HlOperator::Other).into()
}
_ if element.parent().and_then(ast::RangePat::cast).is_some() => {
HlTag::Operator(HlOperator::Other).into()
}
_ if element.parent().and_then(ast::RestPat::cast).is_some() => {
HlTag::Operator(HlOperator::Other).into()
}
_ if element.parent().and_then(ast::RangePat::cast).is_some() => HlTag::Operator.into(),
_ if element.parent().and_then(ast::RestPat::cast).is_some() => HlTag::Operator.into(),
_ if element.parent().and_then(ast::Attr::cast).is_some() => HlTag::Attribute.into(),
kind => HlTag::Punctuation(match kind {
T!['['] | T![']'] => HlPunct::Bracket,

View File

@ -28,7 +28,7 @@ pub enum HlTag {
FormatSpecifier,
Keyword,
NumericLiteral,
Operator,
Operator(HlOperator),
Punctuation(HlPunct),
StringLiteral,
UnresolvedReference,
@ -87,6 +87,20 @@ pub enum HlPunct {
Other,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum HlOperator {
/// |, &, !, ^, |=, &=, ^=
Bitwise,
/// +, -, *, /, +=, -=, *=, /=
Arithmetic,
/// &&, ||, !
Logical,
/// >, <, ==, >=, <=, !=
Comparision,
///
Other,
}
impl HlTag {
fn as_str(self) -> &'static str {
match self {
@ -133,7 +147,13 @@ impl HlTag {
HlPunct::Other => "punctuation",
},
HlTag::NumericLiteral => "numeric_literal",
HlTag::Operator => "operator",
HlTag::Operator(op) => match op {
HlOperator::Bitwise => "bitwise",
HlOperator::Arithmetic => "arithmetic",
HlOperator::Logical => "logical",
HlOperator::Comparision => "comparision",
HlOperator::Other => "operator",
},
HlTag::StringLiteral => "string_literal",
HlTag::UnresolvedReference => "unresolved_reference",
HlTag::None => "none",

View File

@ -39,7 +39,9 @@ macro_rules! define_semantic_token_types {
define_semantic_token_types![
(ANGLE, "angle"),
(ARITHMETIC, "arithmetic"),
(ATTRIBUTE, "attribute"),
(BITWISE, "bitwise"),
(BOOLEAN, "boolean"),
(BRACE, "brace"),
(BRACKET, "bracket"),
@ -47,6 +49,7 @@ define_semantic_token_types![
(CHAR_LITERAL, "characterLiteral"),
(COLON, "colon"),
(COMMA, "comma"),
(COMPARISION, "comparision"),
(CONST_PARAMETER, "constParameter"),
(DOT, "dot"),
(ESCAPE_SEQUENCE, "escapeSequence"),
@ -54,6 +57,8 @@ define_semantic_token_types![
(GENERIC, "generic"),
(LABEL, "label"),
(LIFETIME, "lifetime"),
(LOGICAL, "logical"),
(OPERATOR, "operator"),
(PARENTHESIS, "parenthesis"),
(PUNCTUATION, "punctuation"),
(SELF_KEYWORD, "selfKeyword"),

View File

@ -7,9 +7,9 @@ use std::{
use ide::{
Annotation, AnnotationKind, Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind,
CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit, Fold, FoldKind,
Highlight, HlMod, HlPunct, HlRange, HlTag, Indel, InlayHint, InlayKind, InsertTextFormat,
Markup, NavigationTarget, ReferenceAccess, RenameError, Runnable, Severity, SourceChange,
StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint, InlayKind,
InsertTextFormat, Markup, NavigationTarget, ReferenceAccess, RenameError, Runnable, Severity,
SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
};
use itertools::Itertools;
use serde_json::to_value;
@ -445,7 +445,13 @@ fn semantic_token_type_and_modifiers(
HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD,
HlTag::None => semantic_tokens::GENERIC,
HlTag::Operator => lsp_types::SemanticTokenType::OPERATOR,
HlTag::Operator(op) => match op {
HlOperator::Bitwise => semantic_tokens::BITWISE,
HlOperator::Arithmetic => semantic_tokens::ARITHMETIC,
HlOperator::Logical => semantic_tokens::LOGICAL,
HlOperator::Comparision => semantic_tokens::COMPARISION,
HlOperator::Other => semantic_tokens::OPERATOR,
},
HlTag::StringLiteral => lsp_types::SemanticTokenType::STRING,
HlTag::UnresolvedReference => semantic_tokens::UNRESOLVED_REFERENCE,
HlTag::Punctuation(punct) => match punct {