From acc6458390eb7ed5947fe8b6a0628b4a9018fad1 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 16 Mar 2021 19:06:58 +0100 Subject: Replace trait object boxing with extra AttrsOwnerNode --- crates/ide/src/syntax_highlighting/inject.rs | 67 ++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 19 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index 5b065c09f..086db40e5 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs @@ -4,7 +4,7 @@ use either::Either; use hir::{HasAttrs, Semantics}; use ide_db::call_info::ActiveParameter; use syntax::{ - ast::{self, AstNode, AttrsOwner}, + ast::{self, AstNode, AttrsOwner, DocCommentsOwner}, match_ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize, }; @@ -85,28 +85,57 @@ const RUSTDOC_FENCE_TOKENS: &[&'static str] = &[ "edition2021", ]; +// Basically an owned dyn AttrsOwner without extra Boxing +struct AttrsOwnerNode { + node: SyntaxNode, +} + +impl AttrsOwnerNode { + fn new(node: N) -> Self { + AttrsOwnerNode { node: node.syntax().clone() } + } +} + +impl AttrsOwner for AttrsOwnerNode {} +impl AstNode for AttrsOwnerNode { + fn can_cast(_: syntax::SyntaxKind) -> bool + where + Self: Sized, + { + false + } + fn cast(_: SyntaxNode) -> Option + where + Self: Sized, + { + None + } + fn syntax(&self) -> &SyntaxNode { + &self.node + } +} + fn doc_attributes<'node>( sema: &Semantics, node: &'node SyntaxNode, -) -> Option<(Box, hir::Attrs)> { +) -> Option<(AttrsOwnerNode, hir::Attrs)> { match_ast! { match node { - ast::SourceFile(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Fn(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Struct(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Union(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::RecordField(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::TupleField(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Enum(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Variant(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Trait(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Module(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Static(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Const(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::TypeAlias(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::Impl(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::MacroRules(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), - ast::MacroRules(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), + ast::SourceFile(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Fn(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Struct(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Union(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::RecordField(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::TupleField(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Enum(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Variant(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Trait(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Module(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Static(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Const(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::TypeAlias(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::Impl(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), + ast::MacroRules(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))), // ast::MacroDef(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), // ast::Use(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))), _ => return None @@ -124,7 +153,7 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics, n if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) { return; } - let doc_comments = attributes.by_key("doc").attrs().map(|attr| attr.to_src(&*owner)); + let doc_comments = attributes.by_key("doc").attrs().map(|attr| attr.to_src(&owner)); let mut inj = Injector::default(); inj.add_unmapped("fn doctest() {\n"); -- cgit v1.2.3