mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
Generate ast nodes for each ast trait
This commit is contained in:
parent
ba84b91e78
commit
6d6e0b8f21
6 changed files with 480 additions and 51 deletions
|
@ -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<N: AstNode>(&self, node: N) -> SmallVec<[N; 1]> {
|
||||
let mut res = smallvec![];
|
||||
let tokens = (|| {
|
||||
|
|
|
@ -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())),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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::{
|
||||
|
|
|
@ -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<Self> {
|
||||
|
@ -3564,6 +3604,364 @@ impl AstNode for GenericParam {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl DynArgListOwner {
|
||||
#[inline]
|
||||
pub fn new<T: ast::ArgListOwner>(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<Self> {
|
||||
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<T: ast::AttrsOwner>(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<Self> {
|
||||
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<T: ast::GenericParamsOwner>(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<Self> {
|
||||
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<T: ast::LoopBodyOwner>(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<Self> {
|
||||
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<T: ast::ModuleItemOwner>(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<Self> {
|
||||
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<T: ast::NameOwner>(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<Self> {
|
||||
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<T: ast::TypeBoundsOwner>(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<Self> {
|
||||
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<T: ast::VisibilityOwner>(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<Self> {
|
||||
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)
|
||||
|
|
|
@ -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<N: AttrsOwner>(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<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
None
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode {
|
||||
&self.node
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum AttrKind {
|
||||
Inner,
|
||||
|
|
|
@ -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<T: ast::#trait_name>(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<Self> {
|
||||
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)*
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue