mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
⬆️ rust-analyzer
This commit is contained in:
parent
31519bb394
commit
3e358a6827
74 changed files with 2091 additions and 951 deletions
|
@ -184,10 +184,10 @@ pub(crate) fn resolve_doc_path_for_def(
|
|||
Definition::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::Field(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::SelfType(it) => it.resolve_doc_path(db, link, ns),
|
||||
Definition::BuiltinAttr(_)
|
||||
| Definition::ToolModule(_)
|
||||
| Definition::BuiltinType(_)
|
||||
| Definition::SelfType(_)
|
||||
| Definition::Local(_)
|
||||
| Definition::GenericParam(_)
|
||||
| Definition::Label(_)
|
||||
|
|
|
@ -87,7 +87,7 @@ pub use crate::{
|
|||
},
|
||||
join_lines::JoinLinesConfig,
|
||||
markup::Markup,
|
||||
moniker::{MonikerKind, MonikerResult, PackageInformation},
|
||||
moniker::{MonikerDescriptorKind, MonikerKind, MonikerResult, PackageInformation},
|
||||
move_item::Direction,
|
||||
navigation_target::NavigationTarget,
|
||||
prime_caches::ParallelPrimeCachesProgress,
|
||||
|
@ -98,7 +98,7 @@ pub use crate::{
|
|||
static_index::{StaticIndex, StaticIndexedFile, TokenId, TokenStaticData},
|
||||
syntax_highlighting::{
|
||||
tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
|
||||
HlRange,
|
||||
HighlightConfig, HlRange,
|
||||
},
|
||||
};
|
||||
pub use hir::{Documentation, Semantics};
|
||||
|
@ -517,8 +517,12 @@ impl Analysis {
|
|||
}
|
||||
|
||||
/// Computes syntax highlighting for the given file
|
||||
pub fn highlight(&self, file_id: FileId) -> Cancellable<Vec<HlRange>> {
|
||||
self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false))
|
||||
pub fn highlight(
|
||||
&self,
|
||||
highlight_config: HighlightConfig,
|
||||
file_id: FileId,
|
||||
) -> Cancellable<Vec<HlRange>> {
|
||||
self.with_db(|db| syntax_highlighting::highlight(db, highlight_config, file_id, None))
|
||||
}
|
||||
|
||||
/// Computes all ranges to highlight for a given item in a file.
|
||||
|
@ -533,9 +537,13 @@ impl Analysis {
|
|||
}
|
||||
|
||||
/// Computes syntax highlighting for the given file range.
|
||||
pub fn highlight_range(&self, frange: FileRange) -> Cancellable<Vec<HlRange>> {
|
||||
pub fn highlight_range(
|
||||
&self,
|
||||
highlight_config: HighlightConfig,
|
||||
frange: FileRange,
|
||||
) -> Cancellable<Vec<HlRange>> {
|
||||
self.with_db(|db| {
|
||||
syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false)
|
||||
syntax_highlighting::highlight(db, highlight_config, frange.file_id, Some(frange.range))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -13,17 +13,39 @@ use syntax::{AstNode, SyntaxKind::*, T};
|
|||
|
||||
use crate::{doc_links::token_as_doc_comment, RangeInfo};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum MonikerDescriptorKind {
|
||||
Namespace,
|
||||
Type,
|
||||
Term,
|
||||
Method,
|
||||
TypeParameter,
|
||||
Parameter,
|
||||
Macro,
|
||||
Meta,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct MonikerDescriptor {
|
||||
pub name: Name,
|
||||
pub desc: MonikerDescriptorKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct MonikerIdentifier {
|
||||
crate_name: String,
|
||||
path: Vec<Name>,
|
||||
pub crate_name: String,
|
||||
pub description: Vec<MonikerDescriptor>,
|
||||
}
|
||||
|
||||
impl ToString for MonikerIdentifier {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
MonikerIdentifier { path, crate_name } => {
|
||||
format!("{}::{}", crate_name, path.iter().map(|x| x.to_string()).join("::"))
|
||||
MonikerIdentifier { description, crate_name } => {
|
||||
format!(
|
||||
"{}::{}",
|
||||
crate_name,
|
||||
description.iter().map(|x| x.name.to_string()).join("::")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +64,12 @@ pub struct MonikerResult {
|
|||
pub package_information: PackageInformation,
|
||||
}
|
||||
|
||||
impl MonikerResult {
|
||||
pub fn from_def(db: &RootDatabase, def: Definition, from_crate: Crate) -> Option<Self> {
|
||||
def_to_moniker(db, def, from_crate)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct PackageInformation {
|
||||
pub name: String,
|
||||
|
@ -105,13 +133,23 @@ pub(crate) fn def_to_moniker(
|
|||
def: Definition,
|
||||
from_crate: Crate,
|
||||
) -> Option<MonikerResult> {
|
||||
if matches!(def, Definition::GenericParam(_) | Definition::SelfType(_) | Definition::Local(_)) {
|
||||
if matches!(
|
||||
def,
|
||||
Definition::GenericParam(_)
|
||||
| Definition::Label(_)
|
||||
| Definition::DeriveHelper(_)
|
||||
| Definition::BuiltinAttr(_)
|
||||
| Definition::ToolModule(_)
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let module = def.module(db)?;
|
||||
let krate = module.krate();
|
||||
let mut path = vec![];
|
||||
path.extend(module.path_to_root(db).into_iter().filter_map(|x| x.name(db)));
|
||||
let mut description = vec![];
|
||||
description.extend(module.path_to_root(db).into_iter().filter_map(|x| {
|
||||
Some(MonikerDescriptor { name: x.name(db)?, desc: MonikerDescriptorKind::Namespace })
|
||||
}));
|
||||
|
||||
// Handle associated items within a trait
|
||||
if let Some(assoc) = def.as_assoc_item(db) {
|
||||
|
@ -120,31 +158,98 @@ pub(crate) fn def_to_moniker(
|
|||
AssocItemContainer::Trait(trait_) => {
|
||||
// Because different traits can have functions with the same name,
|
||||
// we have to include the trait name as part of the moniker for uniqueness.
|
||||
path.push(trait_.name(db));
|
||||
description.push(MonikerDescriptor {
|
||||
name: trait_.name(db),
|
||||
desc: MonikerDescriptorKind::Type,
|
||||
});
|
||||
}
|
||||
AssocItemContainer::Impl(impl_) => {
|
||||
// Because a struct can implement multiple traits, for implementations
|
||||
// we add both the struct name and the trait name to the path
|
||||
if let Some(adt) = impl_.self_ty(db).as_adt() {
|
||||
path.push(adt.name(db));
|
||||
description.push(MonikerDescriptor {
|
||||
name: adt.name(db),
|
||||
desc: MonikerDescriptorKind::Type,
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(trait_) = impl_.trait_(db) {
|
||||
path.push(trait_.name(db));
|
||||
description.push(MonikerDescriptor {
|
||||
name: trait_.name(db),
|
||||
desc: MonikerDescriptorKind::Type,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Definition::Field(it) = def {
|
||||
path.push(it.parent_def(db).name(db));
|
||||
description.push(MonikerDescriptor {
|
||||
name: it.parent_def(db).name(db),
|
||||
desc: MonikerDescriptorKind::Type,
|
||||
});
|
||||
}
|
||||
|
||||
path.push(def.name(db)?);
|
||||
let name_desc = match def {
|
||||
// These are handled by top-level guard (for performance).
|
||||
Definition::GenericParam(_)
|
||||
| Definition::Label(_)
|
||||
| Definition::DeriveHelper(_)
|
||||
| Definition::BuiltinAttr(_)
|
||||
| Definition::ToolModule(_) => return None,
|
||||
|
||||
Definition::Local(local) => {
|
||||
if !local.is_param(db) {
|
||||
return None;
|
||||
}
|
||||
|
||||
MonikerDescriptor { name: local.name(db), desc: MonikerDescriptorKind::Parameter }
|
||||
}
|
||||
Definition::Macro(m) => {
|
||||
MonikerDescriptor { name: m.name(db), desc: MonikerDescriptorKind::Macro }
|
||||
}
|
||||
Definition::Function(f) => {
|
||||
MonikerDescriptor { name: f.name(db), desc: MonikerDescriptorKind::Method }
|
||||
}
|
||||
Definition::Variant(v) => {
|
||||
MonikerDescriptor { name: v.name(db), desc: MonikerDescriptorKind::Type }
|
||||
}
|
||||
Definition::Const(c) => {
|
||||
MonikerDescriptor { name: c.name(db)?, desc: MonikerDescriptorKind::Term }
|
||||
}
|
||||
Definition::Trait(trait_) => {
|
||||
MonikerDescriptor { name: trait_.name(db), desc: MonikerDescriptorKind::Type }
|
||||
}
|
||||
Definition::TypeAlias(ta) => {
|
||||
MonikerDescriptor { name: ta.name(db), desc: MonikerDescriptorKind::TypeParameter }
|
||||
}
|
||||
Definition::Module(m) => {
|
||||
MonikerDescriptor { name: m.name(db)?, desc: MonikerDescriptorKind::Namespace }
|
||||
}
|
||||
Definition::BuiltinType(b) => {
|
||||
MonikerDescriptor { name: b.name(), desc: MonikerDescriptorKind::Type }
|
||||
}
|
||||
Definition::SelfType(imp) => MonikerDescriptor {
|
||||
name: imp.self_ty(db).as_adt()?.name(db),
|
||||
desc: MonikerDescriptorKind::Type,
|
||||
},
|
||||
Definition::Field(it) => {
|
||||
MonikerDescriptor { name: it.name(db), desc: MonikerDescriptorKind::Term }
|
||||
}
|
||||
Definition::Adt(adt) => {
|
||||
MonikerDescriptor { name: adt.name(db), desc: MonikerDescriptorKind::Type }
|
||||
}
|
||||
Definition::Static(s) => {
|
||||
MonikerDescriptor { name: s.name(db), desc: MonikerDescriptorKind::Meta }
|
||||
}
|
||||
};
|
||||
|
||||
description.push(name_desc);
|
||||
|
||||
Some(MonikerResult {
|
||||
identifier: MonikerIdentifier {
|
||||
crate_name: krate.display_name(db)?.crate_name().to_string(),
|
||||
path,
|
||||
description,
|
||||
},
|
||||
kind: if krate == from_crate { MonikerKind::Export } else { MonikerKind::Import },
|
||||
package_information: {
|
||||
|
|
|
@ -12,8 +12,9 @@ use ide_db::{
|
|||
salsa::{Database, ParallelDatabase, Snapshot},
|
||||
Cancelled, CrateGraph, CrateId, SourceDatabase, SourceDatabaseExt,
|
||||
},
|
||||
FxHashSet, FxIndexMap,
|
||||
FxIndexMap,
|
||||
};
|
||||
use stdx::hash::NoHashHashSet;
|
||||
|
||||
use crate::RootDatabase;
|
||||
|
||||
|
@ -141,7 +142,7 @@ pub(crate) fn parallel_prime_caches(
|
|||
}
|
||||
}
|
||||
|
||||
fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> FxHashSet<CrateId> {
|
||||
fn compute_crates_to_prime(db: &RootDatabase, graph: &CrateGraph) -> NoHashHashSet<CrateId> {
|
||||
// We're only interested in the workspace crates and the `ImportMap`s of their direct
|
||||
// dependencies, though in practice the latter also compute the `DefMap`s.
|
||||
// We don't prime transitive dependencies because they're generally not visible in
|
||||
|
|
|
@ -14,8 +14,9 @@ use ide_db::{
|
|||
base_db::FileId,
|
||||
defs::{Definition, NameClass, NameRefClass},
|
||||
search::{ReferenceCategory, SearchScope, UsageSearchResult},
|
||||
FxHashMap, RootDatabase,
|
||||
RootDatabase,
|
||||
};
|
||||
use stdx::hash::NoHashHashMap;
|
||||
use syntax::{
|
||||
algo::find_node_at_offset,
|
||||
ast::{self, HasName},
|
||||
|
@ -29,7 +30,7 @@ use crate::{FilePosition, NavigationTarget, TryToNav};
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct ReferenceSearchResult {
|
||||
pub declaration: Option<Declaration>,
|
||||
pub references: FxHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
|
||||
pub references: NoHashHashMap<FileId, Vec<(TextRange, Option<ReferenceCategory>)>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -14,7 +14,7 @@ mod html;
|
|||
mod tests;
|
||||
|
||||
use hir::{Name, Semantics};
|
||||
use ide_db::{FxHashMap, RootDatabase};
|
||||
use ide_db::{FxHashMap, RootDatabase, SymbolKind};
|
||||
use syntax::{
|
||||
ast, AstNode, AstToken, NodeOrToken, SyntaxKind::*, SyntaxNode, TextRange, WalkEvent, T,
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
|||
escape::highlight_escape_string, format::highlight_format_string, highlights::Highlights,
|
||||
macro_::MacroHighlighter, tags::Highlight,
|
||||
},
|
||||
FileId, HlMod, HlTag,
|
||||
FileId, HlMod, HlOperator, HlPunct, HlTag,
|
||||
};
|
||||
|
||||
pub(crate) use html::highlight_as_html;
|
||||
|
@ -36,6 +36,26 @@ pub struct HlRange {
|
|||
pub binding_hash: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct HighlightConfig {
|
||||
/// Whether to highlight strings
|
||||
pub strings: bool,
|
||||
/// Whether to highlight punctuation
|
||||
pub punctuation: bool,
|
||||
/// Whether to specialize punctuation highlights
|
||||
pub specialize_punctuation: bool,
|
||||
/// Whether to highlight operator
|
||||
pub operator: bool,
|
||||
/// Whether to specialize operator highlights
|
||||
pub specialize_operator: bool,
|
||||
/// Whether to inject highlights into doc comments
|
||||
pub inject_doc_comment: bool,
|
||||
/// Whether to highlight the macro call bang
|
||||
pub macro_bang: bool,
|
||||
/// Whether to highlight unresolved things be their syntax
|
||||
pub syntactic_name_ref_highlighting: bool,
|
||||
}
|
||||
|
||||
// Feature: Semantic Syntax Highlighting
|
||||
//
|
||||
// rust-analyzer highlights the code semantically.
|
||||
|
@ -155,9 +175,9 @@ pub struct HlRange {
|
|||
// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[]
|
||||
pub(crate) fn highlight(
|
||||
db: &RootDatabase,
|
||||
config: HighlightConfig,
|
||||
file_id: FileId,
|
||||
range_to_highlight: Option<TextRange>,
|
||||
syntactic_name_ref_highlighting: bool,
|
||||
) -> Vec<HlRange> {
|
||||
let _p = profile::span("highlight");
|
||||
let sema = Semantics::new(db);
|
||||
|
@ -183,26 +203,18 @@ pub(crate) fn highlight(
|
|||
Some(it) => it.krate(),
|
||||
None => return hl.to_vec(),
|
||||
};
|
||||
traverse(
|
||||
&mut hl,
|
||||
&sema,
|
||||
file_id,
|
||||
&root,
|
||||
krate,
|
||||
range_to_highlight,
|
||||
syntactic_name_ref_highlighting,
|
||||
);
|
||||
traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight);
|
||||
hl.to_vec()
|
||||
}
|
||||
|
||||
fn traverse(
|
||||
hl: &mut Highlights,
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
config: HighlightConfig,
|
||||
file_id: FileId,
|
||||
root: &SyntaxNode,
|
||||
krate: hir::Crate,
|
||||
range_to_highlight: TextRange,
|
||||
syntactic_name_ref_highlighting: bool,
|
||||
) {
|
||||
let is_unlinked = sema.to_module_def(file_id).is_none();
|
||||
let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default();
|
||||
|
@ -323,9 +335,11 @@ fn traverse(
|
|||
Enter(it) => it,
|
||||
Leave(NodeOrToken::Token(_)) => continue,
|
||||
Leave(NodeOrToken::Node(node)) => {
|
||||
// Doc comment highlighting injection, we do this when leaving the node
|
||||
// so that we overwrite the highlighting of the doc comment itself.
|
||||
inject::doc_comment(hl, sema, file_id, &node);
|
||||
if config.inject_doc_comment {
|
||||
// Doc comment highlighting injection, we do this when leaving the node
|
||||
// so that we overwrite the highlighting of the doc comment itself.
|
||||
inject::doc_comment(hl, sema, config, file_id, &node);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
@ -400,7 +414,8 @@ fn traverse(
|
|||
let string_to_highlight = ast::String::cast(descended_token.clone());
|
||||
if let Some((string, expanded_string)) = string.zip(string_to_highlight) {
|
||||
if string.is_raw() {
|
||||
if inject::ra_fixture(hl, sema, &string, &expanded_string).is_some() {
|
||||
if inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +436,7 @@ fn traverse(
|
|||
sema,
|
||||
krate,
|
||||
&mut bindings_shadow_count,
|
||||
syntactic_name_ref_highlighting,
|
||||
config.syntactic_name_ref_highlighting,
|
||||
name_like,
|
||||
),
|
||||
NodeOrToken::Token(token) => highlight::token(sema, token).zip(Some(None)),
|
||||
|
@ -439,6 +454,29 @@ fn traverse(
|
|||
// something unresolvable. FIXME: There should be a way to prevent that
|
||||
continue;
|
||||
}
|
||||
|
||||
// apply config filtering
|
||||
match &mut highlight.tag {
|
||||
HlTag::StringLiteral if !config.strings => continue,
|
||||
// If punctuation is disabled, make the macro bang part of the macro call again.
|
||||
tag @ HlTag::Punctuation(HlPunct::MacroBang) => {
|
||||
if !config.macro_bang {
|
||||
*tag = HlTag::Symbol(SymbolKind::Macro);
|
||||
} else if !config.specialize_punctuation {
|
||||
*tag = HlTag::Punctuation(HlPunct::Other);
|
||||
}
|
||||
}
|
||||
HlTag::Punctuation(_) if !config.punctuation => continue,
|
||||
tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => {
|
||||
*tag = HlTag::Punctuation(HlPunct::Other);
|
||||
}
|
||||
HlTag::Operator(_) if !config.operator && highlight.mods.is_empty() => continue,
|
||||
tag @ HlTag::Operator(_) if !config.specialize_operator => {
|
||||
*tag = HlTag::Operator(HlOperator::Other);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if inside_attribute {
|
||||
highlight |= HlMod::Attribute
|
||||
}
|
||||
|
|
|
@ -5,7 +5,10 @@ use oorandom::Rand32;
|
|||
use stdx::format_to;
|
||||
use syntax::AstNode;
|
||||
|
||||
use crate::{syntax_highlighting::highlight, FileId, RootDatabase};
|
||||
use crate::{
|
||||
syntax_highlighting::{highlight, HighlightConfig},
|
||||
FileId, RootDatabase,
|
||||
};
|
||||
|
||||
pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
|
||||
let parse = db.parse(file_id);
|
||||
|
@ -20,7 +23,21 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
|
|||
)
|
||||
}
|
||||
|
||||
let hl_ranges = highlight(db, file_id, None, false);
|
||||
let hl_ranges = highlight(
|
||||
db,
|
||||
HighlightConfig {
|
||||
strings: true,
|
||||
punctuation: true,
|
||||
specialize_punctuation: true,
|
||||
specialize_operator: true,
|
||||
operator: true,
|
||||
inject_doc_comment: true,
|
||||
macro_bang: true,
|
||||
syntactic_name_ref_highlighting: false,
|
||||
},
|
||||
file_id,
|
||||
None,
|
||||
);
|
||||
let text = parse.tree().syntax().to_string();
|
||||
let mut buf = String::new();
|
||||
buf.push_str(STYLE);
|
||||
|
|
|
@ -15,13 +15,14 @@ use syntax::{
|
|||
|
||||
use crate::{
|
||||
doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def},
|
||||
syntax_highlighting::{highlights::Highlights, injector::Injector},
|
||||
syntax_highlighting::{highlights::Highlights, injector::Injector, HighlightConfig},
|
||||
Analysis, HlMod, HlRange, HlTag, RootDatabase,
|
||||
};
|
||||
|
||||
pub(super) fn ra_fixture(
|
||||
hl: &mut Highlights,
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
config: HighlightConfig,
|
||||
literal: &ast::String,
|
||||
expanded: &ast::String,
|
||||
) -> Option<()> {
|
||||
|
@ -63,7 +64,13 @@ pub(super) fn ra_fixture(
|
|||
|
||||
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
|
||||
|
||||
for mut hl_range in analysis.highlight(tmp_file_id).unwrap() {
|
||||
for mut hl_range in analysis
|
||||
.highlight(
|
||||
HighlightConfig { syntactic_name_ref_highlighting: false, ..config },
|
||||
tmp_file_id,
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
for range in inj.map_range_up(hl_range.range) {
|
||||
if let Some(range) = literal.map_range_up(range) {
|
||||
hl_range.range = range;
|
||||
|
@ -86,6 +93,7 @@ const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
|
|||
pub(super) fn doc_comment(
|
||||
hl: &mut Highlights,
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
config: HighlightConfig,
|
||||
src_file_id: FileId,
|
||||
node: &SyntaxNode,
|
||||
) {
|
||||
|
@ -206,7 +214,14 @@ pub(super) fn doc_comment(
|
|||
|
||||
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
|
||||
|
||||
if let Ok(ranges) = analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)) {
|
||||
if let Ok(ranges) = analysis.with_db(|db| {
|
||||
super::highlight(
|
||||
db,
|
||||
HighlightConfig { syntactic_name_ref_highlighting: true, ..config },
|
||||
tmp_file_id,
|
||||
None,
|
||||
)
|
||||
}) {
|
||||
for HlRange { range, highlight, binding_hash } in ranges {
|
||||
for range in inj.map_range_up(range) {
|
||||
hl.add(HlRange { range, highlight: highlight | HlMod::Injected, binding_hash });
|
||||
|
|
|
@ -199,7 +199,7 @@ impl fmt::Display for HlTag {
|
|||
}
|
||||
|
||||
impl HlMod {
|
||||
const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[
|
||||
const ALL: &'static [HlMod; 19] = &[
|
||||
HlMod::Associated,
|
||||
HlMod::Async,
|
||||
HlMod::Attribute,
|
||||
|
@ -296,7 +296,7 @@ impl Highlight {
|
|||
Highlight { tag, mods: HlMods::default() }
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.tag == HlTag::None && self.mods == HlMods::default()
|
||||
self.tag == HlTag::None && self.mods.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,6 +330,10 @@ impl ops::BitOr<HlMod> for Highlight {
|
|||
}
|
||||
|
||||
impl HlMods {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0 == 0
|
||||
}
|
||||
|
||||
pub fn contains(self, m: HlMod) -> bool {
|
||||
self.0 & m.mask() == m.mask()
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="field declaration">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span><span class="comma">,</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="comment documentation">/// This is an impl with a code block.</span>
|
||||
<span class="comment documentation">/// This is an impl of </span><span class="struct documentation injected intra_doc_link">[`Foo`]</span><span class="comment documentation"> with a code block.</span>
|
||||
<span class="comment documentation">///</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function declaration injected">foo</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span>
|
||||
|
|
|
@ -4,7 +4,18 @@ use expect_test::{expect_file, ExpectFile};
|
|||
use ide_db::SymbolKind;
|
||||
use test_utils::{bench, bench_fixture, skip_slow_tests, AssertLinear};
|
||||
|
||||
use crate::{fixture, FileRange, HlTag, TextRange};
|
||||
use crate::{fixture, FileRange, HighlightConfig, HlTag, TextRange};
|
||||
|
||||
const HL_CONFIG: HighlightConfig = HighlightConfig {
|
||||
strings: true,
|
||||
punctuation: true,
|
||||
specialize_punctuation: true,
|
||||
specialize_operator: true,
|
||||
operator: true,
|
||||
inject_doc_comment: true,
|
||||
macro_bang: true,
|
||||
syntactic_name_ref_highlighting: false,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn attributes() {
|
||||
|
@ -613,7 +624,7 @@ struct Foo {
|
|||
bar: bool,
|
||||
}
|
||||
|
||||
/// This is an impl with a code block.
|
||||
/// This is an impl of [`Foo`] with a code block.
|
||||
///
|
||||
/// ```
|
||||
/// fn foo() {
|
||||
|
@ -996,7 +1007,10 @@ struct Foo {
|
|||
|
||||
// The "x"
|
||||
let highlights = &analysis
|
||||
.highlight_range(FileRange { file_id, range: TextRange::at(45.into(), 1.into()) })
|
||||
.highlight_range(
|
||||
HL_CONFIG,
|
||||
FileRange { file_id, range: TextRange::at(45.into(), 1.into()) },
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&highlights[0].highlight.to_string(), "field.declaration.public");
|
||||
|
@ -1011,7 +1025,7 @@ macro_rules! test {}
|
|||
}"#
|
||||
.trim(),
|
||||
);
|
||||
let _ = analysis.highlight(file_id).unwrap();
|
||||
let _ = analysis.highlight(HL_CONFIG, file_id).unwrap();
|
||||
}
|
||||
|
||||
/// Highlights the code given by the `ra_fixture` argument, renders the
|
||||
|
@ -1035,7 +1049,7 @@ fn benchmark_syntax_highlighting_long_struct() {
|
|||
let hash = {
|
||||
let _pt = bench("syntax highlighting long struct");
|
||||
analysis
|
||||
.highlight(file_id)
|
||||
.highlight(HL_CONFIG, file_id)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
|
||||
|
@ -1061,7 +1075,7 @@ fn syntax_highlighting_not_quadratic() {
|
|||
let time = Instant::now();
|
||||
|
||||
let hash = analysis
|
||||
.highlight(file_id)
|
||||
.highlight(HL_CONFIG, file_id)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
|
||||
|
@ -1086,7 +1100,7 @@ fn benchmark_syntax_highlighting_parser() {
|
|||
let hash = {
|
||||
let _pt = bench("syntax highlighting parser");
|
||||
analysis
|
||||
.highlight(file_id)
|
||||
.highlight(HL_CONFIG, file_id)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function))
|
||||
|
|
|
@ -3,8 +3,9 @@ use std::sync::Arc;
|
|||
use dot::{Id, LabelText};
|
||||
use ide_db::{
|
||||
base_db::{CrateGraph, CrateId, Dependency, SourceDatabase, SourceDatabaseExt},
|
||||
FxHashSet, RootDatabase,
|
||||
RootDatabase,
|
||||
};
|
||||
use stdx::hash::NoHashHashSet;
|
||||
|
||||
// Feature: View Crate Graph
|
||||
//
|
||||
|
@ -41,7 +42,7 @@ pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String,
|
|||
|
||||
struct DotCrateGraph {
|
||||
graph: Arc<CrateGraph>,
|
||||
crates_to_render: FxHashSet<CrateId>,
|
||||
crates_to_render: NoHashHashSet<CrateId>,
|
||||
}
|
||||
|
||||
type Edge<'a> = (CrateId, &'a Dependency);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue