From 6d6e0b8f21385d008eb6161b56a98da2eac141a2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 21 Sep 2021 15:52:11 +0200 Subject: [PATCH 1/3] Generate ast nodes for each ast trait --- crates/hir/src/semantics.rs | 2 +- crates/hir_def/src/attr.rs | 36 +- crates/syntax/src/ast.rs | 4 +- crates/syntax/src/ast/generated/nodes.rs | 398 +++++++++++++++++++++++ crates/syntax/src/ast/node_ext.rs | 30 -- crates/syntax/src/tests/sourcegen_ast.rs | 61 ++++ 6 files changed, 480 insertions(+), 51 deletions(-) diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 9821d9d4fa..f5a8da2493 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -481,7 +481,7 @@ impl<'db> SemanticsImpl<'db> { ) } - // This might not be the correct way to due this, but it works for now + // This might not be the correct way to do this, but it works for now fn descend_node_into_attributes(&self, node: N) -> SmallVec<[N; 1]> { let mut res = smallvec![]; let tokens = (|| { diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index f8cc940486..0470b9510f 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs @@ -411,47 +411,47 @@ impl AttrsWithOwner { let file_id = id.parent.file_id(db); let root = db.parse_or_expand(file_id).unwrap(); let owner = match &map[id.local_id] { - Either::Left(it) => ast::AttrsOwnerNode::new(it.to_node(&root)), - Either::Right(it) => ast::AttrsOwnerNode::new(it.to_node(&root)), + Either::Left(it) => ast::DynAttrsOwner::new(it.to_node(&root)), + Either::Right(it) => ast::DynAttrsOwner::new(it.to_node(&root)), }; InFile::new(file_id, owner) } AttrDefId::AdtId(adt) => match adt { - AdtId::StructId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), - AdtId::UnionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), - AdtId::EnumId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), + AdtId::StructId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), + AdtId::UnionId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), + AdtId::EnumId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), }, - AttrDefId::FunctionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), + AttrDefId::FunctionId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), AttrDefId::EnumVariantId(id) => { let map = db.variants_attrs_source_map(id.parent); let file_id = id.parent.lookup(db).id.file_id(); let root = db.parse_or_expand(file_id).unwrap(); - InFile::new(file_id, ast::AttrsOwnerNode::new(map[id.local_id].to_node(&root))) + InFile::new(file_id, ast::DynAttrsOwner::new(map[id.local_id].to_node(&root))) } - AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), - AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), - AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), - AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), + AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), + AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), + AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), + AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), AttrDefId::MacroDefId(id) => id.ast_id().either( - |it| it.with_value(ast::AttrsOwnerNode::new(it.to_node(db.upcast()))), - |it| it.with_value(ast::AttrsOwnerNode::new(it.to_node(db.upcast()))), + |it| it.with_value(ast::DynAttrsOwner::new(it.to_node(db.upcast()))), + |it| it.with_value(ast::DynAttrsOwner::new(it.to_node(db.upcast()))), ), - AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), + AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::DynAttrsOwner::new), AttrDefId::GenericParamId(id) => match id { GenericParamId::TypeParamId(id) => { id.parent.child_source(db).map(|source| match &source[id.local_id] { - Either::Left(id) => ast::AttrsOwnerNode::new(id.clone()), - Either::Right(id) => ast::AttrsOwnerNode::new(id.clone()), + Either::Left(id) => ast::DynAttrsOwner::new(id.clone()), + Either::Right(id) => ast::DynAttrsOwner::new(id.clone()), }) } GenericParamId::LifetimeParamId(id) => id .parent .child_source(db) - .map(|source| ast::AttrsOwnerNode::new(source[id.local_id].clone())), + .map(|source| ast::DynAttrsOwner::new(source[id.local_id].clone())), GenericParamId::ConstParamId(id) => id .parent .child_source(db) - .map(|source| ast::AttrsOwnerNode::new(source[id.local_id].clone())), + .map(|source| ast::DynAttrsOwner::new(source[id.local_id].clone())), }, }; diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs index e26c5b7ad9..7c9200f568 100644 --- a/crates/syntax/src/ast.rs +++ b/crates/syntax/src/ast.rs @@ -21,8 +21,8 @@ pub use self::{ expr_ext::{ArrayExprKind, Effect, ElseBranch, LiteralKind}, generated::{nodes::*, tokens::*}, node_ext::{ - AttrKind, AttrsOwnerNode, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, - SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind, + AttrKind, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, SelfParamKind, + SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind, }, operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp}, token_ext::{ diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 205d01e974..5c80dc8346 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -1445,6 +1445,46 @@ pub enum GenericParam { TypeParam(TypeParam), } impl ast::AttrsOwner for GenericParam {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynArgListOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::ArgListOwner for DynArgListOwner {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynAttrsOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::AttrsOwner for DynAttrsOwner {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynGenericParamsOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::GenericParamsOwner for DynGenericParamsOwner {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynLoopBodyOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::LoopBodyOwner for DynLoopBodyOwner {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynModuleItemOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::ModuleItemOwner for DynModuleItemOwner {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynNameOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::NameOwner for DynNameOwner {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynTypeBoundsOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::TypeBoundsOwner for DynTypeBoundsOwner {} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DynVisibilityOwner { + pub(crate) syntax: SyntaxNode, +} +impl ast::VisibilityOwner for DynVisibilityOwner {} impl AstNode for Name { fn can_cast(kind: SyntaxKind) -> bool { kind == NAME } fn cast(syntax: SyntaxNode) -> Option { @@ -3564,6 +3604,364 @@ impl AstNode for GenericParam { } } } +impl DynArgListOwner { + #[inline] + pub fn new(node: T) -> DynArgListOwner { + DynArgListOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynArgListOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + CALL_EXPR | METHOD_CALL_EXPR => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + CALL_EXPR => DynArgListOwner { syntax }, + METHOD_CALL_EXPR => DynArgListOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl DynAttrsOwner { + #[inline] + pub fn new(node: T) -> DynAttrsOwner { + DynAttrsOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynAttrsOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + MACRO_CALL + | SOURCE_FILE + | CONST + | ENUM + | EXTERN_BLOCK + | EXTERN_CRATE + | FN + | IMPL + | MACRO_RULES + | MACRO_DEF + | MODULE + | STATIC + | STRUCT + | TRAIT + | TYPE_ALIAS + | UNION + | USE + | ITEM_LIST + | BLOCK_EXPR + | SELF_PARAM + | PARAM + | RECORD_FIELD + | TUPLE_FIELD + | VARIANT + | ASSOC_ITEM_LIST + | EXTERN_ITEM_LIST + | CONST_PARAM + | LIFETIME_PARAM + | TYPE_PARAM + | EXPR_STMT + | LET_STMT + | ARRAY_EXPR + | AWAIT_EXPR + | BIN_EXPR + | BOX_EXPR + | BREAK_EXPR + | CALL_EXPR + | CAST_EXPR + | CLOSURE_EXPR + | CONTINUE_EXPR + | EFFECT_EXPR + | FIELD_EXPR + | FOR_EXPR + | IF_EXPR + | INDEX_EXPR + | LITERAL + | LOOP_EXPR + | MATCH_EXPR + | METHOD_CALL_EXPR + | PAREN_EXPR + | PATH_EXPR + | PREFIX_EXPR + | RANGE_EXPR + | REF_EXPR + | RETURN_EXPR + | TRY_EXPR + | TUPLE_EXPR + | WHILE_EXPR + | YIELD_EXPR + | RECORD_EXPR_FIELD_LIST + | RECORD_EXPR_FIELD + | MATCH_ARM_LIST + | MATCH_ARM + | IDENT_PAT + | RECORD_PAT_FIELD => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + MACRO_CALL => DynAttrsOwner { syntax }, + SOURCE_FILE => DynAttrsOwner { syntax }, + CONST => DynAttrsOwner { syntax }, + ENUM => DynAttrsOwner { syntax }, + EXTERN_BLOCK => DynAttrsOwner { syntax }, + EXTERN_CRATE => DynAttrsOwner { syntax }, + FN => DynAttrsOwner { syntax }, + IMPL => DynAttrsOwner { syntax }, + MACRO_RULES => DynAttrsOwner { syntax }, + MACRO_DEF => DynAttrsOwner { syntax }, + MODULE => DynAttrsOwner { syntax }, + STATIC => DynAttrsOwner { syntax }, + STRUCT => DynAttrsOwner { syntax }, + TRAIT => DynAttrsOwner { syntax }, + TYPE_ALIAS => DynAttrsOwner { syntax }, + UNION => DynAttrsOwner { syntax }, + USE => DynAttrsOwner { syntax }, + ITEM_LIST => DynAttrsOwner { syntax }, + BLOCK_EXPR => DynAttrsOwner { syntax }, + SELF_PARAM => DynAttrsOwner { syntax }, + PARAM => DynAttrsOwner { syntax }, + RECORD_FIELD => DynAttrsOwner { syntax }, + TUPLE_FIELD => DynAttrsOwner { syntax }, + VARIANT => DynAttrsOwner { syntax }, + ASSOC_ITEM_LIST => DynAttrsOwner { syntax }, + EXTERN_ITEM_LIST => DynAttrsOwner { syntax }, + CONST_PARAM => DynAttrsOwner { syntax }, + LIFETIME_PARAM => DynAttrsOwner { syntax }, + TYPE_PARAM => DynAttrsOwner { syntax }, + EXPR_STMT => DynAttrsOwner { syntax }, + LET_STMT => DynAttrsOwner { syntax }, + ARRAY_EXPR => DynAttrsOwner { syntax }, + AWAIT_EXPR => DynAttrsOwner { syntax }, + BIN_EXPR => DynAttrsOwner { syntax }, + BOX_EXPR => DynAttrsOwner { syntax }, + BREAK_EXPR => DynAttrsOwner { syntax }, + CALL_EXPR => DynAttrsOwner { syntax }, + CAST_EXPR => DynAttrsOwner { syntax }, + CLOSURE_EXPR => DynAttrsOwner { syntax }, + CONTINUE_EXPR => DynAttrsOwner { syntax }, + EFFECT_EXPR => DynAttrsOwner { syntax }, + FIELD_EXPR => DynAttrsOwner { syntax }, + FOR_EXPR => DynAttrsOwner { syntax }, + IF_EXPR => DynAttrsOwner { syntax }, + INDEX_EXPR => DynAttrsOwner { syntax }, + LITERAL => DynAttrsOwner { syntax }, + LOOP_EXPR => DynAttrsOwner { syntax }, + MATCH_EXPR => DynAttrsOwner { syntax }, + METHOD_CALL_EXPR => DynAttrsOwner { syntax }, + PAREN_EXPR => DynAttrsOwner { syntax }, + PATH_EXPR => DynAttrsOwner { syntax }, + PREFIX_EXPR => DynAttrsOwner { syntax }, + RANGE_EXPR => DynAttrsOwner { syntax }, + REF_EXPR => DynAttrsOwner { syntax }, + RETURN_EXPR => DynAttrsOwner { syntax }, + TRY_EXPR => DynAttrsOwner { syntax }, + TUPLE_EXPR => DynAttrsOwner { syntax }, + WHILE_EXPR => DynAttrsOwner { syntax }, + YIELD_EXPR => DynAttrsOwner { syntax }, + RECORD_EXPR_FIELD_LIST => DynAttrsOwner { syntax }, + RECORD_EXPR_FIELD => DynAttrsOwner { syntax }, + MATCH_ARM_LIST => DynAttrsOwner { syntax }, + MATCH_ARM => DynAttrsOwner { syntax }, + IDENT_PAT => DynAttrsOwner { syntax }, + RECORD_PAT_FIELD => DynAttrsOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl DynGenericParamsOwner { + #[inline] + pub fn new(node: T) -> DynGenericParamsOwner { + DynGenericParamsOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynGenericParamsOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + ENUM => DynGenericParamsOwner { syntax }, + FN => DynGenericParamsOwner { syntax }, + IMPL => DynGenericParamsOwner { syntax }, + STRUCT => DynGenericParamsOwner { syntax }, + TRAIT => DynGenericParamsOwner { syntax }, + TYPE_ALIAS => DynGenericParamsOwner { syntax }, + UNION => DynGenericParamsOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl DynLoopBodyOwner { + #[inline] + pub fn new(node: T) -> DynLoopBodyOwner { + DynLoopBodyOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynLoopBodyOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + FOR_EXPR | LOOP_EXPR | WHILE_EXPR => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + FOR_EXPR => DynLoopBodyOwner { syntax }, + LOOP_EXPR => DynLoopBodyOwner { syntax }, + WHILE_EXPR => DynLoopBodyOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl DynModuleItemOwner { + #[inline] + pub fn new(node: T) -> DynModuleItemOwner { + DynModuleItemOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynModuleItemOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + MACRO_ITEMS | SOURCE_FILE | ITEM_LIST => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + MACRO_ITEMS => DynModuleItemOwner { syntax }, + SOURCE_FILE => DynModuleItemOwner { syntax }, + ITEM_LIST => DynModuleItemOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl DynNameOwner { + #[inline] + pub fn new(node: T) -> DynNameOwner { + DynNameOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynNameOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + CONST | ENUM | FN | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT + | TYPE_ALIAS | UNION | RENAME | SELF_PARAM | RECORD_FIELD | VARIANT | CONST_PARAM + | TYPE_PARAM | IDENT_PAT => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + CONST => DynNameOwner { syntax }, + ENUM => DynNameOwner { syntax }, + FN => DynNameOwner { syntax }, + MACRO_RULES => DynNameOwner { syntax }, + MACRO_DEF => DynNameOwner { syntax }, + MODULE => DynNameOwner { syntax }, + STATIC => DynNameOwner { syntax }, + STRUCT => DynNameOwner { syntax }, + TRAIT => DynNameOwner { syntax }, + TYPE_ALIAS => DynNameOwner { syntax }, + UNION => DynNameOwner { syntax }, + RENAME => DynNameOwner { syntax }, + SELF_PARAM => DynNameOwner { syntax }, + RECORD_FIELD => DynNameOwner { syntax }, + VARIANT => DynNameOwner { syntax }, + CONST_PARAM => DynNameOwner { syntax }, + TYPE_PARAM => DynNameOwner { syntax }, + IDENT_PAT => DynNameOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl DynTypeBoundsOwner { + #[inline] + pub fn new(node: T) -> DynTypeBoundsOwner { + DynTypeBoundsOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynTypeBoundsOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + ASSOC_TYPE_ARG => DynTypeBoundsOwner { syntax }, + TRAIT => DynTypeBoundsOwner { syntax }, + TYPE_ALIAS => DynTypeBoundsOwner { syntax }, + LIFETIME_PARAM => DynTypeBoundsOwner { syntax }, + TYPE_PARAM => DynTypeBoundsOwner { syntax }, + WHERE_PRED => DynTypeBoundsOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl DynVisibilityOwner { + #[inline] + pub fn new(node: T) -> DynVisibilityOwner { + DynVisibilityOwner { syntax: node.syntax().clone() } + } +} +impl AstNode for DynVisibilityOwner { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + CONST | ENUM | EXTERN_CRATE | FN | IMPL | MACRO_RULES | MACRO_DEF | MODULE | STATIC + | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => { + true + } + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + CONST => DynVisibilityOwner { syntax }, + ENUM => DynVisibilityOwner { syntax }, + EXTERN_CRATE => DynVisibilityOwner { syntax }, + FN => DynVisibilityOwner { syntax }, + IMPL => DynVisibilityOwner { syntax }, + MACRO_RULES => DynVisibilityOwner { syntax }, + MACRO_DEF => DynVisibilityOwner { syntax }, + MODULE => DynVisibilityOwner { syntax }, + STATIC => DynVisibilityOwner { syntax }, + STRUCT => DynVisibilityOwner { syntax }, + TRAIT => DynVisibilityOwner { syntax }, + TYPE_ALIAS => DynVisibilityOwner { syntax }, + UNION => DynVisibilityOwner { syntax }, + USE => DynVisibilityOwner { syntax }, + RECORD_FIELD => DynVisibilityOwner { syntax }, + TUPLE_FIELD => DynVisibilityOwner { syntax }, + VARIANT => DynVisibilityOwner { syntax }, + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl std::fmt::Display for GenericArg { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 99ef5c264f..1dce67da63 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -167,36 +167,6 @@ impl NameOwner for Macro { impl AttrsOwner for Macro {} -/// Basically an owned `dyn AttrsOwner` without extra boxing. -pub struct AttrsOwnerNode { - node: SyntaxNode, -} - -impl AttrsOwnerNode { - pub fn new(node: N) -> Self { - AttrsOwnerNode { node: node.syntax().clone() } - } -} - -impl AttrsOwner for AttrsOwnerNode {} -impl AstNode for AttrsOwnerNode { - fn can_cast(_: SyntaxKind) -> bool - where - Self: Sized, - { - false - } - fn cast(_: SyntaxNode) -> Option - where - Self: Sized, - { - None - } - fn syntax(&self) -> &SyntaxNode { - &self.node - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub enum AttrKind { Inner, diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs index a6624a8ab1..71171c859b 100644 --- a/crates/syntax/src/tests/sourcegen_ast.rs +++ b/crates/syntax/src/tests/sourcegen_ast.rs @@ -8,6 +8,7 @@ use std::{ fmt::Write, }; +use itertools::Itertools; use proc_macro2::{Punct, Spacing}; use quote::{format_ident, quote}; use ungrammar::{rust_grammar, Grammar, Rule}; @@ -208,6 +209,64 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { }) .unzip(); + let (dyn_node_defs, dyn_node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar + .nodes + .iter() + .flat_map(|node| node.traits.iter().map(move |t| (t, node))) + .into_group_map() + .into_iter() + .sorted_by_key(|(k, _)| k.clone()) + .map(|(trait_name, nodes)| { + let name = format_ident!("Dyn{}", trait_name); + let trait_name = format_ident!("{}", trait_name); + let kinds: Vec<_> = nodes + .iter() + .map(|name| format_ident!("{}", to_upper_snake_case(&name.name.to_string()))) + .collect(); + + ( + quote! { + #[pretty_doc_comment_placeholder_workaround] + #[derive(Debug, Clone, PartialEq, Eq, Hash)] + pub struct #name { + pub(crate) syntax: SyntaxNode, + } + impl ast::#trait_name for #name {} + }, + quote! { + impl #name { + #[inline] + pub fn new(node: T) -> #name { + #name { + syntax: node.syntax().clone() + } + } + } + impl AstNode for #name { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + #(#kinds)|* => true, + _ => false, + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + #( + #kinds => #name { syntax }, + )* + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } + } + }, + ) + }) + .unzip(); + let enum_names = grammar.enums.iter().map(|it| &it.name); let node_names = grammar.nodes.iter().map(|it| &it.name); @@ -244,8 +303,10 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { #(#node_defs)* #(#enum_defs)* + #(#dyn_node_defs)* #(#node_boilerplate_impls)* #(#enum_boilerplate_impls)* + #(#dyn_node_boilerplate_impls)* #(#display_impls)* }; From b36f12dba5413ca73bf351657fff2f52700e0c0e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 21 Sep 2021 15:56:06 +0200 Subject: [PATCH 2/3] Simplify --- crates/hir/src/semantics.rs | 15 +- crates/syntax/src/ast/generated/nodes.rs | 258 +++++++++-------------- crates/syntax/src/ast/node_ext.rs | 11 +- crates/syntax/src/tests/sourcegen_ast.rs | 12 +- 4 files changed, 112 insertions(+), 184 deletions(-) diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index f5a8da2493..51befc698c 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -682,20 +682,7 @@ impl<'db> SemanticsImpl<'db> { fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option { let text = lifetime.text(); let lifetime_param = lifetime.syntax().ancestors().find_map(|syn| { - let gpl = match_ast! { - match syn { - ast::Fn(it) => it.generic_param_list()?, - ast::TypeAlias(it) => it.generic_param_list()?, - ast::Struct(it) => it.generic_param_list()?, - ast::Enum(it) => it.generic_param_list()?, - ast::Union(it) => it.generic_param_list()?, - ast::Trait(it) => it.generic_param_list()?, - ast::Impl(it) => it.generic_param_list()?, - ast::WherePred(it) => it.generic_param_list()?, - ast::ForType(it) => it.generic_param_list()?, - _ => return None, - } - }; + let gpl = ast::DynGenericParamsOwner::cast(syn)?.generic_param_list()?; gpl.lifetime_params() .find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()).as_ref() == Some(&text)) })?; diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 5c80dc8346..047d97c90f 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -3618,12 +3618,10 @@ impl AstNode for DynArgListOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - CALL_EXPR => DynArgListOwner { syntax }, - METHOD_CALL_EXPR => DynArgListOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + CALL_EXPR | METHOD_CALL_EXPR => Some(DynArgListOwner { syntax }), + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3705,75 +3703,74 @@ impl AstNode for DynAttrsOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - MACRO_CALL => DynAttrsOwner { syntax }, - SOURCE_FILE => DynAttrsOwner { syntax }, - CONST => DynAttrsOwner { syntax }, - ENUM => DynAttrsOwner { syntax }, - EXTERN_BLOCK => DynAttrsOwner { syntax }, - EXTERN_CRATE => DynAttrsOwner { syntax }, - FN => DynAttrsOwner { syntax }, - IMPL => DynAttrsOwner { syntax }, - MACRO_RULES => DynAttrsOwner { syntax }, - MACRO_DEF => DynAttrsOwner { syntax }, - MODULE => DynAttrsOwner { syntax }, - STATIC => DynAttrsOwner { syntax }, - STRUCT => DynAttrsOwner { syntax }, - TRAIT => DynAttrsOwner { syntax }, - TYPE_ALIAS => DynAttrsOwner { syntax }, - UNION => DynAttrsOwner { syntax }, - USE => DynAttrsOwner { syntax }, - ITEM_LIST => DynAttrsOwner { syntax }, - BLOCK_EXPR => DynAttrsOwner { syntax }, - SELF_PARAM => DynAttrsOwner { syntax }, - PARAM => DynAttrsOwner { syntax }, - RECORD_FIELD => DynAttrsOwner { syntax }, - TUPLE_FIELD => DynAttrsOwner { syntax }, - VARIANT => DynAttrsOwner { syntax }, - ASSOC_ITEM_LIST => DynAttrsOwner { syntax }, - EXTERN_ITEM_LIST => DynAttrsOwner { syntax }, - CONST_PARAM => DynAttrsOwner { syntax }, - LIFETIME_PARAM => DynAttrsOwner { syntax }, - TYPE_PARAM => DynAttrsOwner { syntax }, - EXPR_STMT => DynAttrsOwner { syntax }, - LET_STMT => DynAttrsOwner { syntax }, - ARRAY_EXPR => DynAttrsOwner { syntax }, - AWAIT_EXPR => DynAttrsOwner { syntax }, - BIN_EXPR => DynAttrsOwner { syntax }, - BOX_EXPR => DynAttrsOwner { syntax }, - BREAK_EXPR => DynAttrsOwner { syntax }, - CALL_EXPR => DynAttrsOwner { syntax }, - CAST_EXPR => DynAttrsOwner { syntax }, - CLOSURE_EXPR => DynAttrsOwner { syntax }, - CONTINUE_EXPR => DynAttrsOwner { syntax }, - EFFECT_EXPR => DynAttrsOwner { syntax }, - FIELD_EXPR => DynAttrsOwner { syntax }, - FOR_EXPR => DynAttrsOwner { syntax }, - IF_EXPR => DynAttrsOwner { syntax }, - INDEX_EXPR => DynAttrsOwner { syntax }, - LITERAL => DynAttrsOwner { syntax }, - LOOP_EXPR => DynAttrsOwner { syntax }, - MATCH_EXPR => DynAttrsOwner { syntax }, - METHOD_CALL_EXPR => DynAttrsOwner { syntax }, - PAREN_EXPR => DynAttrsOwner { syntax }, - PATH_EXPR => DynAttrsOwner { syntax }, - PREFIX_EXPR => DynAttrsOwner { syntax }, - RANGE_EXPR => DynAttrsOwner { syntax }, - REF_EXPR => DynAttrsOwner { syntax }, - RETURN_EXPR => DynAttrsOwner { syntax }, - TRY_EXPR => DynAttrsOwner { syntax }, - TUPLE_EXPR => DynAttrsOwner { syntax }, - WHILE_EXPR => DynAttrsOwner { syntax }, - YIELD_EXPR => DynAttrsOwner { syntax }, - RECORD_EXPR_FIELD_LIST => DynAttrsOwner { syntax }, - RECORD_EXPR_FIELD => DynAttrsOwner { syntax }, - MATCH_ARM_LIST => DynAttrsOwner { syntax }, - MATCH_ARM => DynAttrsOwner { syntax }, - IDENT_PAT => DynAttrsOwner { syntax }, - RECORD_PAT_FIELD => DynAttrsOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + MACRO_CALL + | SOURCE_FILE + | CONST + | ENUM + | EXTERN_BLOCK + | EXTERN_CRATE + | FN + | IMPL + | MACRO_RULES + | MACRO_DEF + | MODULE + | STATIC + | STRUCT + | TRAIT + | TYPE_ALIAS + | UNION + | USE + | ITEM_LIST + | BLOCK_EXPR + | SELF_PARAM + | PARAM + | RECORD_FIELD + | TUPLE_FIELD + | VARIANT + | ASSOC_ITEM_LIST + | EXTERN_ITEM_LIST + | CONST_PARAM + | LIFETIME_PARAM + | TYPE_PARAM + | EXPR_STMT + | LET_STMT + | ARRAY_EXPR + | AWAIT_EXPR + | BIN_EXPR + | BOX_EXPR + | BREAK_EXPR + | CALL_EXPR + | CAST_EXPR + | CLOSURE_EXPR + | CONTINUE_EXPR + | EFFECT_EXPR + | FIELD_EXPR + | FOR_EXPR + | IF_EXPR + | INDEX_EXPR + | LITERAL + | LOOP_EXPR + | MATCH_EXPR + | METHOD_CALL_EXPR + | PAREN_EXPR + | PATH_EXPR + | PREFIX_EXPR + | RANGE_EXPR + | REF_EXPR + | RETURN_EXPR + | TRY_EXPR + | TUPLE_EXPR + | WHILE_EXPR + | YIELD_EXPR + | RECORD_EXPR_FIELD_LIST + | RECORD_EXPR_FIELD + | MATCH_ARM_LIST + | MATCH_ARM + | IDENT_PAT + | RECORD_PAT_FIELD => Some(DynAttrsOwner { syntax }), + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3791,17 +3788,12 @@ impl AstNode for DynGenericParamsOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - ENUM => DynGenericParamsOwner { syntax }, - FN => DynGenericParamsOwner { syntax }, - IMPL => DynGenericParamsOwner { syntax }, - STRUCT => DynGenericParamsOwner { syntax }, - TRAIT => DynGenericParamsOwner { syntax }, - TYPE_ALIAS => DynGenericParamsOwner { syntax }, - UNION => DynGenericParamsOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION => { + Some(DynGenericParamsOwner { syntax }) + } + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3819,13 +3811,10 @@ impl AstNode for DynLoopBodyOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - FOR_EXPR => DynLoopBodyOwner { syntax }, - LOOP_EXPR => DynLoopBodyOwner { syntax }, - WHILE_EXPR => DynLoopBodyOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + FOR_EXPR | LOOP_EXPR | WHILE_EXPR => Some(DynLoopBodyOwner { syntax }), + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3843,13 +3832,10 @@ impl AstNode for DynModuleItemOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - MACRO_ITEMS => DynModuleItemOwner { syntax }, - SOURCE_FILE => DynModuleItemOwner { syntax }, - ITEM_LIST => DynModuleItemOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + MACRO_ITEMS | SOURCE_FILE | ITEM_LIST => Some(DynModuleItemOwner { syntax }), + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3869,28 +3855,12 @@ impl AstNode for DynNameOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - CONST => DynNameOwner { syntax }, - ENUM => DynNameOwner { syntax }, - FN => DynNameOwner { syntax }, - MACRO_RULES => DynNameOwner { syntax }, - MACRO_DEF => DynNameOwner { syntax }, - MODULE => DynNameOwner { syntax }, - STATIC => DynNameOwner { syntax }, - STRUCT => DynNameOwner { syntax }, - TRAIT => DynNameOwner { syntax }, - TYPE_ALIAS => DynNameOwner { syntax }, - UNION => DynNameOwner { syntax }, - RENAME => DynNameOwner { syntax }, - SELF_PARAM => DynNameOwner { syntax }, - RECORD_FIELD => DynNameOwner { syntax }, - VARIANT => DynNameOwner { syntax }, - CONST_PARAM => DynNameOwner { syntax }, - TYPE_PARAM => DynNameOwner { syntax }, - IDENT_PAT => DynNameOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + CONST | ENUM | FN | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT + | TYPE_ALIAS | UNION | RENAME | SELF_PARAM | RECORD_FIELD | VARIANT | CONST_PARAM + | TYPE_PARAM | IDENT_PAT => Some(DynNameOwner { syntax }), + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3908,16 +3878,12 @@ impl AstNode for DynTypeBoundsOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - ASSOC_TYPE_ARG => DynTypeBoundsOwner { syntax }, - TRAIT => DynTypeBoundsOwner { syntax }, - TYPE_ALIAS => DynTypeBoundsOwner { syntax }, - LIFETIME_PARAM => DynTypeBoundsOwner { syntax }, - TYPE_PARAM => DynTypeBoundsOwner { syntax }, - WHERE_PRED => DynTypeBoundsOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED => { + Some(DynTypeBoundsOwner { syntax }) + } + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3938,27 +3904,13 @@ impl AstNode for DynVisibilityOwner { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - CONST => DynVisibilityOwner { syntax }, - ENUM => DynVisibilityOwner { syntax }, - EXTERN_CRATE => DynVisibilityOwner { syntax }, - FN => DynVisibilityOwner { syntax }, - IMPL => DynVisibilityOwner { syntax }, - MACRO_RULES => DynVisibilityOwner { syntax }, - MACRO_DEF => DynVisibilityOwner { syntax }, - MODULE => DynVisibilityOwner { syntax }, - STATIC => DynVisibilityOwner { syntax }, - STRUCT => DynVisibilityOwner { syntax }, - TRAIT => DynVisibilityOwner { syntax }, - TYPE_ALIAS => DynVisibilityOwner { syntax }, - UNION => DynVisibilityOwner { syntax }, - USE => DynVisibilityOwner { syntax }, - RECORD_FIELD => DynVisibilityOwner { syntax }, - TUPLE_FIELD => DynVisibilityOwner { syntax }, - VARIANT => DynVisibilityOwner { syntax }, - _ => return None, - }; - Some(res) + match syntax.kind() { + CONST | ENUM | EXTERN_CRATE | FN | IMPL | MACRO_RULES | MACRO_DEF | MODULE | STATIC + | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => { + Some(DynVisibilityOwner { syntax }) + } + _ => None, + } } fn syntax(&self) -> &SyntaxNode { &self.syntax } } diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 1dce67da63..930e5ce74f 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -572,16 +572,7 @@ impl ast::Variant { impl ast::Item { pub fn generic_param_list(&self) -> Option { - match self { - ast::Item::Enum(it) => it.generic_param_list(), - ast::Item::Fn(it) => it.generic_param_list(), - ast::Item::Impl(it) => it.generic_param_list(), - ast::Item::Struct(it) => it.generic_param_list(), - ast::Item::Trait(it) => it.generic_param_list(), - ast::Item::TypeAlias(it) => it.generic_param_list(), - ast::Item::Union(it) => it.generic_param_list(), - _ => None, - } + ast::DynGenericParamsOwner::cast(self.syntax().clone())?.generic_param_list() } } diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs index 71171c859b..08700cd5a8 100644 --- a/crates/syntax/src/tests/sourcegen_ast.rs +++ b/crates/syntax/src/tests/sourcegen_ast.rs @@ -250,13 +250,11 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { } } fn cast(syntax: SyntaxNode) -> Option { - let res = match syntax.kind() { - #( - #kinds => #name { syntax }, - )* - _ => return None, - }; - Some(res) + match syntax.kind() { + #(#kinds)|* => Some(#name { syntax }), + _ => None, + } + } fn syntax(&self) -> &SyntaxNode { &self.syntax From 83e97adfff998e67c036ca17934d014c237afe45 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 21 Sep 2021 16:15:30 +0200 Subject: [PATCH 3/3] Simplify --- crates/syntax/src/ast/generated/nodes.rs | 113 ++--------------------- crates/syntax/src/tests/sourcegen_ast.rs | 6 +- 2 files changed, 9 insertions(+), 110 deletions(-) diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 047d97c90f..547e754636 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -3618,10 +3618,7 @@ impl AstNode for DynArgListOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - CALL_EXPR | METHOD_CALL_EXPR => Some(DynArgListOwner { syntax }), - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynArgListOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3703,74 +3700,7 @@ impl AstNode for DynAttrsOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - MACRO_CALL - | SOURCE_FILE - | CONST - | ENUM - | EXTERN_BLOCK - | EXTERN_CRATE - | FN - | IMPL - | MACRO_RULES - | MACRO_DEF - | MODULE - | STATIC - | STRUCT - | TRAIT - | TYPE_ALIAS - | UNION - | USE - | ITEM_LIST - | BLOCK_EXPR - | SELF_PARAM - | PARAM - | RECORD_FIELD - | TUPLE_FIELD - | VARIANT - | ASSOC_ITEM_LIST - | EXTERN_ITEM_LIST - | CONST_PARAM - | LIFETIME_PARAM - | TYPE_PARAM - | EXPR_STMT - | LET_STMT - | ARRAY_EXPR - | AWAIT_EXPR - | BIN_EXPR - | BOX_EXPR - | BREAK_EXPR - | CALL_EXPR - | CAST_EXPR - | CLOSURE_EXPR - | CONTINUE_EXPR - | EFFECT_EXPR - | FIELD_EXPR - | FOR_EXPR - | IF_EXPR - | INDEX_EXPR - | LITERAL - | LOOP_EXPR - | MATCH_EXPR - | METHOD_CALL_EXPR - | PAREN_EXPR - | PATH_EXPR - | PREFIX_EXPR - | RANGE_EXPR - | REF_EXPR - | RETURN_EXPR - | TRY_EXPR - | TUPLE_EXPR - | WHILE_EXPR - | YIELD_EXPR - | RECORD_EXPR_FIELD_LIST - | RECORD_EXPR_FIELD - | MATCH_ARM_LIST - | MATCH_ARM - | IDENT_PAT - | RECORD_PAT_FIELD => Some(DynAttrsOwner { syntax }), - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynAttrsOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3788,12 +3718,7 @@ impl AstNode for DynGenericParamsOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION => { - Some(DynGenericParamsOwner { syntax }) - } - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynGenericParamsOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3811,10 +3736,7 @@ impl AstNode for DynLoopBodyOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - FOR_EXPR | LOOP_EXPR | WHILE_EXPR => Some(DynLoopBodyOwner { syntax }), - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynLoopBodyOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3832,10 +3754,7 @@ impl AstNode for DynModuleItemOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - MACRO_ITEMS | SOURCE_FILE | ITEM_LIST => Some(DynModuleItemOwner { syntax }), - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynModuleItemOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3855,12 +3774,7 @@ impl AstNode for DynNameOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - CONST | ENUM | FN | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT - | TYPE_ALIAS | UNION | RENAME | SELF_PARAM | RECORD_FIELD | VARIANT | CONST_PARAM - | TYPE_PARAM | IDENT_PAT => Some(DynNameOwner { syntax }), - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynNameOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3878,12 +3792,7 @@ impl AstNode for DynTypeBoundsOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED => { - Some(DynTypeBoundsOwner { syntax }) - } - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynTypeBoundsOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } @@ -3904,13 +3813,7 @@ impl AstNode for DynVisibilityOwner { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - CONST | ENUM | EXTERN_CRATE | FN | IMPL | MACRO_RULES | MACRO_DEF | MODULE | STATIC - | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => { - Some(DynVisibilityOwner { syntax }) - } - _ => None, - } + Self::can_cast(syntax.kind()).then(|| DynVisibilityOwner { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax } } diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs index 08700cd5a8..1a0377830b 100644 --- a/crates/syntax/src/tests/sourcegen_ast.rs +++ b/crates/syntax/src/tests/sourcegen_ast.rs @@ -250,11 +250,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { } } fn cast(syntax: SyntaxNode) -> Option { - match syntax.kind() { - #(#kinds)|* => Some(#name { syntax }), - _ => None, - } - + Self::can_cast(syntax.kind()).then(|| #name { syntax }) } fn syntax(&self) -> &SyntaxNode { &self.syntax