Give defaultLibrary semantic token modifier to items from standard library

This commit is contained in:
lhvy 2021-09-30 23:40:17 +10:00
parent 161a5e8724
commit 2b3baa8503
No known key found for this signature in database
GPG key ID: E6CAEAA74B3C53AC
11 changed files with 167 additions and 49 deletions

View file

@ -3,7 +3,7 @@
use hir::{AsAssocItem, HasVisibility, Semantics};
use ide_db::{
defs::{Definition, NameClass, NameRefClass},
helpers::try_resolve_derive_input_at,
helpers::{try_resolve_derive_input_at, FamousDefs},
RootDatabase, SymbolKind,
};
use rustc_hash::FxHashMap;
@ -25,7 +25,6 @@ pub(super) fn element(
syntactic_name_ref_highlighting: bool,
element: SyntaxElement,
) -> Option<(Highlight, Option<u64>)> {
let db = sema.db;
let mut binding_hash = None;
let highlight: Highlight = match element.kind() {
FN => {
@ -79,10 +78,10 @@ pub(super) fn element(
match NameClass::classify_lifetime(sema, &lifetime) {
Some(NameClass::Definition(def)) => {
highlight_def(db, krate, def) | HlMod::Definition
highlight_def(sema, krate, def) | HlMod::Definition
}
None => match NameRefClass::classify_lifetime(sema, &lifetime) {
Some(NameRefClass::Definition(def)) => highlight_def(db, krate, def),
Some(NameRefClass::Definition(def)) => highlight_def(sema, krate, def),
_ => SymbolKind::LifetimeParam.into(),
},
_ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition,
@ -93,7 +92,7 @@ pub(super) fn element(
element.ancestors().nth(2).and_then(ast::Attr::cast).zip(element.as_token())
{
match try_resolve_derive_input_at(sema, &attr, token) {
Some(makro) => highlight_def(sema.db, krate, Definition::Macro(makro)),
Some(makro) => highlight_def(sema, krate, Definition::Macro(makro)),
None => HlTag::None.into(),
}
} else {
@ -275,7 +274,7 @@ fn highlight_name_ref(
}
};
let mut h = highlight_def(db, krate, def);
let mut h = highlight_def(sema, krate, def);
match def {
Definition::Local(local)
@ -334,7 +333,7 @@ fn highlight_name(
};
match name_kind {
Some(NameClass::Definition(def)) => {
let mut h = highlight_def(db, krate, def) | HlMod::Definition;
let mut h = highlight_def(sema, krate, def) | HlMod::Definition;
if let Definition::ModuleDef(hir::ModuleDef::Trait(trait_)) = &def {
if trait_.is_unsafe(db) {
h |= HlMod::Unsafe;
@ -342,7 +341,7 @@ fn highlight_name(
}
h
}
Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def),
Some(NameClass::ConstReference(def)) => highlight_def(sema, krate, def),
Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
let mut h = HlTag::Symbol(SymbolKind::Field).into();
if let hir::VariantDef::Union(_) = field_ref.parent_def(db) {
@ -366,7 +365,12 @@ fn calc_binding_hash(name: &hir::Name, shadow_count: u32) -> u64 {
hash((name, shadow_count))
}
fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition) -> Highlight {
fn highlight_def(
sema: &Semantics<RootDatabase>,
krate: Option<hir::Crate>,
def: Definition,
) -> Highlight {
let db = sema.db;
let mut h = match def {
Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)),
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
@ -504,7 +508,14 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition)
Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)),
};
let is_from_other_crate = def.module(db).map(hir::Module::krate) != krate;
let famous_defs = FamousDefs(&sema, krate);
let def_crate = def.module(db).map(hir::Module::krate).or_else(|| match def {
Definition::ModuleDef(hir::ModuleDef::Module(module)) => Some(module.krate()),
_ => None,
});
let is_from_other_crate = def_crate != krate;
let is_from_builtin_crate =
def_crate.map_or(false, |it| famous_defs.builtin_crates().contains(&it));
let is_builtin_type = matches!(def, Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)));
let is_public = def.visibility(db) == Some(hir::Visibility::Public);
@ -514,6 +525,10 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition)
_ => {}
}
if is_from_builtin_crate {
h |= HlMod::DefaultLibrary;
}
h
}
@ -546,7 +561,10 @@ fn highlight_method_call(
h |= HlMod::Trait;
}
let is_from_other_crate = Some(func.module(sema.db).krate()) != krate;
let famous_defs = FamousDefs(&sema, krate);
let def_crate = func.module(sema.db).krate();
let is_from_other_crate = Some(def_crate) != krate;
let is_from_builtin_crate = famous_defs.builtin_crates().contains(&def_crate);
let is_public = func.visibility(sema.db) == hir::Visibility::Public;
if is_from_other_crate {
@ -555,6 +573,10 @@ fn highlight_method_call(
h |= HlMod::Public;
}
if is_from_builtin_crate {
h |= HlMod::DefaultLibrary;
}
if let Some(self_param) = func.self_param(sema.db) {
match self_param.access(sema.db) {
hir::Access::Shared => h |= HlMod::Reference,

View file

@ -55,6 +55,8 @@ pub enum HlMod {
Consuming,
/// Used with keywords like `if` and `break`.
ControlFlow,
/// Used for items from built-in crates (std, core, alloc, test and proc_macro).
DefaultLibrary,
/// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is
/// not.
Definition,
@ -187,42 +189,44 @@ impl fmt::Display for HlTag {
impl HlMod {
const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[
HlMod::Associated,
HlMod::Async,
HlMod::Attribute,
HlMod::Callable,
HlMod::Consuming,
HlMod::ControlFlow,
HlMod::DefaultLibrary,
HlMod::Definition,
HlMod::Documentation,
HlMod::Injected,
HlMod::IntraDocLink,
HlMod::Library,
HlMod::Mutable,
HlMod::Public,
HlMod::Reference,
HlMod::Static,
HlMod::Trait,
HlMod::Async,
HlMod::Library,
HlMod::Public,
HlMod::Unsafe,
];
fn as_str(self) -> &'static str {
match self {
HlMod::Associated => "associated",
HlMod::Async => "async",
HlMod::Attribute => "attribute",
HlMod::Callable => "callable",
HlMod::Consuming => "consuming",
HlMod::ControlFlow => "control",
HlMod::DefaultLibrary => "default_library",
HlMod::Definition => "declaration",
HlMod::Documentation => "documentation",
HlMod::Injected => "injected",
HlMod::IntraDocLink => "intra_doc_link",
HlMod::Library => "library",
HlMod::Mutable => "mutable",
HlMod::Public => "public",
HlMod::Reference => "reference",
HlMod::Static => "static",
HlMod::Trait => "trait",
HlMod::Async => "async",
HlMod::Library => "library",
HlMod::Public => "public",
HlMod::Unsafe => "unsafe",
}
}

View file

@ -45,8 +45,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration static public">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration reference public">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="brace">}</span>
<span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span>
@ -55,7 +55,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="brace">}</span>
<span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration static trait public">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration reference trait public">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static trait">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference trait">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="brace">}</span>
</code></pre>

View file

@ -0,0 +1,49 @@
<style>
body { margin: 0; }
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
.lifetime { color: #DFAF8F; font-style: italic; }
.label { color: #DFAF8F; font-style: italic; }
.comment { color: #7F9F7F; }
.documentation { color: #629755; }
.intra_doc_link { font-style: italic; }
.injected { opacity: 0.65 ; }
.struct, .enum { color: #7CB8BB; }
.enum_variant { color: #BDE0F3; }
.string_literal { color: #CC9393; }
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.mutable.unsafe { color: #BC8383; text-decoration: underline; }
.keyword.unsafe { color: #BC8383; font-weight: bold; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }
.type { color: #7CB8BB; }
.builtin_type { color: #8CD0D3; }
.type_param { color: #DFAF8F; }
.attribute { color: #94BFF3; }
.numeric_literal { color: #BFEBBF; }
.bool_literal { color: #BFE6EB; }
.macro { color: #94BFF3; }
.module { color: #AFD8AF; }
.value_param { color: #DCDCCC; }
.variable { color: #DCDCCC; }
.format_specifier { color: #CC696B; }
.mutable { text-decoration: underline; }
.escape_sequence { color: #94BFF3; }
.keyword { color: #F0DFAF; font-weight: bold; }
.control { font-style: italic; }
.reference { font-style: italic; font-weight: bold; }
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code><span class="keyword">use</span> <span class="module default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword">let</span> <span class="variable declaration">foo</span> <span class="operator">=</span> <span class="enum_variant default_library library">Some</span><span class="parenthesis">(</span><span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration">nums</span> <span class="operator">=</span> <span class="module default_library library">iter</span><span class="operator">::</span><span class="function default_library library">repeat</span><span class="parenthesis">(</span><span class="variable">foo</span><span class="operator">.</span><span class="function associated consuming default_library library">unwrap</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span>
</code></pre>

View file

@ -75,7 +75,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="comment documentation">/// #</span><span class="none injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="builtin_attr attribute injected">allow</span><span class="parenthesis attribute injected">(</span><span class="none attribute injected">unused_mut</span><span class="parenthesis attribute injected">)</span><span class="attribute attribute injected">]</span>
<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="keyword injected">mut</span><span class="none injected"> </span><span class="variable declaration injected mutable">foo</span><span class="colon injected">:</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
<span class="comment documentation">/// ```</span>
<span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function associated declaration static public">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="brace">{</span>
<span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function associated declaration public static">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="brace">{</span>
<span class="struct">Foo</span> <span class="brace">{</span> <span class="field">bar</span><span class="colon">:</span> <span class="bool_literal">true</span> <span class="brace">}</span>
<span class="brace">}</span>
@ -109,7 +109,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="comment documentation">/// ```sh</span>
<span class="comment documentation">/// echo 1</span>
<span class="comment documentation">/// ```</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration reference public">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
<span class="bool_literal">true</span>
<span class="brace">}</span>
<span class="brace">}</span>

View file

@ -40,6 +40,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module library">std</span><span class="semicolon">;</span>
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module library">alloc</span> <span class="keyword">as</span> <span class="module declaration library">abc</span><span class="semicolon">;</span>
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module default_library library">std</span><span class="semicolon">;</span>
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module default_library library">alloc</span> <span class="keyword">as</span> <span class="module default_library declaration library">abc</span><span class="semicolon">;</span>
</code></pre>

View file

@ -241,12 +241,12 @@ proc_macros::<span class="macro">mirror!</span> <span class="brace">{</span>
<span class="brace">}</span>
<span class="brace">}</span>
<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function declaration async">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword">let</span> <span class="variable declaration">song</span> <span class="operator">=</span> <span class="unresolved_reference">learn_song</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword control async">await</span><span class="semicolon">;</span>
<span class="unresolved_reference">sing_song</span><span class="parenthesis">(</span><span class="variable consuming">song</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword control async">await</span><span class="semicolon">;</span>
<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function async declaration">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword">let</span> <span class="variable declaration">song</span> <span class="operator">=</span> <span class="unresolved_reference">learn_song</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span>
<span class="unresolved_reference">sing_song</span><span class="parenthesis">(</span><span class="variable consuming">song</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function declaration async">async_main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function async declaration">async_main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword">let</span> <span class="variable declaration">f1</span> <span class="operator">=</span> <span class="function async">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration">f2</span> <span class="operator">=</span> <span class="unresolved_reference">dance</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
futures::<span class="macro">join!</span><span class="parenthesis">(</span>f1<span class="comma">,</span> f2<span class="parenthesis">)</span><span class="semicolon">;</span>

View file

@ -734,6 +734,23 @@ fn test_extern_crate() {
);
}
#[test]
fn test_default_library() {
check_highlighting(
r#"
//- minicore: option, iterators
use core::iter;
fn main() {
let foo = Some(92);
let nums = iter::repeat(foo.unwrap());
}
"#,
expect_file!["./test_data/highlight_default_library.html"],
false,
);
}
#[test]
fn test_associated_function() {
check_highlighting(

View file

@ -68,6 +68,30 @@ impl FamousDefs<'_, '_> {
self.find_trait("core:ops:Deref")
}
pub fn alloc(&self) -> Option<Crate> {
self.find_crate("alloc")
}
pub fn test(&self) -> Option<Crate> {
self.find_crate("test")
}
pub fn proc_macro(&self) -> Option<Crate> {
self.find_crate("proc_macro")
}
pub fn builtin_crates(&self) -> Vec<Crate> {
IntoIterator::into_iter([
self.std(),
self.core(),
self.alloc(),
self.test(),
self.proc_macro(),
])
.filter_map(|it| it)
.collect()
}
fn find_trait(&self, path: &str) -> Option<Trait> {
match self.find_def(path)? {
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),

View file

@ -87,20 +87,21 @@ macro_rules! define_semantic_token_modifiers {
}
define_semantic_token_modifiers![
(CONSTANT, "constant"),
(CONTROL_FLOW, "controlFlow"),
(INJECTED, "injected"),
(MUTABLE, "mutable"),
(CONSUMING, "consuming"),
(ASYNC, "async"),
(LIBRARY, "library"),
(PUBLIC, "public"),
(UNSAFE, "unsafe"),
(ATTRIBUTE_MODIFIER, "attribute"),
(TRAIT_MODIFIER, "trait"),
(CALLABLE, "callable"),
(CONSTANT, "constant"),
(CONSUMING, "consuming"),
(CONTROL_FLOW, "controlFlow"),
(DEFAULT_LIBRARY, "defaultLibrary"),
(INJECTED, "injected"),
(INTRA_DOC_LINK, "intraDocLink"),
(LIBRARY, "library"),
(MUTABLE, "mutable"),
(PUBLIC, "public"),
(REFERENCE, "reference"),
(TRAIT_MODIFIER, "trait"),
(UNSAFE, "unsafe"),
];
#[derive(Default)]

View file

@ -529,23 +529,24 @@ fn semantic_token_type_and_modifiers(
for modifier in highlight.mods.iter() {
let modifier = match modifier {
HlMod::Associated => continue,
HlMod::Async => semantic_tokens::ASYNC,
HlMod::Attribute => semantic_tokens::ATTRIBUTE_MODIFIER,
HlMod::Callable => semantic_tokens::CALLABLE,
HlMod::Consuming => semantic_tokens::CONSUMING,
HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW,
HlMod::DefaultLibrary => semantic_tokens::DEFAULT_LIBRARY,
HlMod::Definition => lsp_types::SemanticTokenModifier::DECLARATION,
HlMod::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION,
HlMod::Injected => semantic_tokens::INJECTED,
HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW,
HlMod::Mutable => semantic_tokens::MUTABLE,
HlMod::Reference => semantic_tokens::REFERENCE,
HlMod::Consuming => semantic_tokens::CONSUMING,
HlMod::Async => semantic_tokens::ASYNC,
HlMod::Library => semantic_tokens::LIBRARY,
HlMod::Public => semantic_tokens::PUBLIC,
HlMod::Unsafe => semantic_tokens::UNSAFE,
HlMod::Callable => semantic_tokens::CALLABLE,
HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,
HlMod::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
HlMod::Library => semantic_tokens::LIBRARY,
HlMod::Mutable => semantic_tokens::MUTABLE,
HlMod::Public => semantic_tokens::PUBLIC,
HlMod::Reference => semantic_tokens::REFERENCE,
HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,
HlMod::Trait => semantic_tokens::TRAIT_MODIFIER,
HlMod::Associated => continue,
HlMod::Unsafe => semantic_tokens::UNSAFE,
};
mods |= modifier;
}