use compactp_syntax::{SyntaxKind, SyntaxNode, SyntaxToken};
use crate::expr::Expr;
use crate::{AstNode, support};
macro_rules! ast_node {
(
$(#[$meta:meta])*
$name:ident => $kind:ident
) => {
$(#[$meta])*
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct $name(SyntaxNode);
impl AstNode for $name {
fn can_cast(kind: SyntaxKind) -> bool {
kind == SyntaxKind::$kind
}
fn cast(node: SyntaxNode) -> Option<Self> {
if Self::can_cast(node.kind()) {
Some(Self(node))
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode {
&self.0
}
}
};
}
ast_node! {
SourceFile => SOURCE_FILE
}
impl SourceFile {
pub fn pragmas(&self) -> impl Iterator<Item = Pragma> {
support::children_nodes(&self.0)
}
pub fn includes(&self) -> impl Iterator<Item = Include> {
support::children_nodes(&self.0)
}
pub fn imports(&self) -> impl Iterator<Item = Import> {
support::children_nodes(&self.0)
}
pub fn circuit_defs(&self) -> impl Iterator<Item = CircuitDef> {
support::children_nodes(&self.0)
}
pub fn struct_defs(&self) -> impl Iterator<Item = StructDef> {
support::children_nodes(&self.0)
}
pub fn enum_defs(&self) -> impl Iterator<Item = EnumDef> {
support::children_nodes(&self.0)
}
pub fn items(&self) -> impl Iterator<Item = Item> + '_ {
self.0.children().filter_map(Item::cast)
}
}
ast_node! {
Pragma => PRAGMA
}
impl Pragma {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
}
ast_node! {
Include => INCLUDE
}
impl Include {
pub fn path(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::STRING_LIT)
}
}
ast_node! {
Import => IMPORT
}
impl Import {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn path(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::STRING_LIT)
}
pub fn generic_args(&self) -> Option<GenericArgList> {
support::child_node(&self.0)
}
pub fn prefix(&self) -> Option<PrefixDecl> {
support::child_node(&self.0)
}
}
ast_node! {
ImportSpecifier => IMPORT_SPECIFIER
}
impl ImportSpecifier {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
}
ast_node! {
ExportList => EXPORT_LIST
}
impl ExportList {
pub fn names(&self) -> impl Iterator<Item = SyntaxToken> + '_ {
self.0
.children_with_tokens()
.filter_map(rowan::NodeOrToken::into_token)
.filter(|t| t.kind() == SyntaxKind::IDENT)
}
}
ast_node! {
ModuleDef => MODULE_DEF
}
impl ModuleDef {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn generic_params(&self) -> Option<GenericParamList> {
support::child_node(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
}
ast_node! {
LedgerDecl => LEDGER_DECL
}
impl LedgerDecl {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn sealed_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::SEALED_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn ty(&self) -> Option<Type> {
support::child_node(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
pub fn is_sealed(&self) -> bool {
self.sealed_kw().is_some()
}
}
ast_node! {
ConstructorDef => CONSTRUCTOR_DEF
}
impl ConstructorDef {
pub fn params(&self) -> impl Iterator<Item = Param> {
support::children_nodes(&self.0)
}
pub fn body(&self) -> Option<Block> {
support::child_node(&self.0)
}
}
ast_node! {
CircuitDef => CIRCUIT_DEF
}
impl CircuitDef {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn pure_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::PURE_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn generic_params(&self) -> Option<GenericParamList> {
support::child_node(&self.0)
}
pub fn params(&self) -> impl Iterator<Item = Param> {
support::children_nodes(&self.0)
}
pub fn return_type(&self) -> Option<Type> {
support::child_node(&self.0)
}
pub fn body(&self) -> Option<Block> {
support::child_node(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
pub fn is_pure(&self) -> bool {
self.pure_kw().is_some()
}
}
ast_node! {
CircuitDecl => CIRCUIT_DECL
}
impl CircuitDecl {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn generic_params(&self) -> Option<GenericParamList> {
support::child_node(&self.0)
}
pub fn params(&self) -> impl Iterator<Item = Param> {
support::children_nodes(&self.0)
}
pub fn return_type(&self) -> Option<Type> {
support::child_node(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
}
ast_node! {
WitnessDecl => WITNESS_DECL
}
impl WitnessDecl {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn generic_params(&self) -> Option<GenericParamList> {
support::child_node(&self.0)
}
pub fn return_type(&self) -> Option<Type> {
support::child_node(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
}
ast_node! {
ContractDecl => CONTRACT_DECL
}
impl ContractDecl {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn circuits(&self) -> impl Iterator<Item = ContractCircuit> {
support::children_nodes(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
}
ast_node! {
ContractCircuit => CONTRACT_CIRCUIT
}
impl ContractCircuit {
pub fn pure_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::PURE_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn return_type(&self) -> Option<Type> {
support::child_node(&self.0)
}
pub fn is_pure(&self) -> bool {
self.pure_kw().is_some()
}
}
ast_node! {
StructDef => STRUCT_DEF
}
impl StructDef {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn generic_params(&self) -> Option<GenericParamList> {
support::child_node(&self.0)
}
pub fn fields(&self) -> impl Iterator<Item = StructField> {
support::children_nodes(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
}
ast_node! {
StructField => STRUCT_FIELD
}
impl StructField {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn ty(&self) -> Option<Type> {
support::child_node(&self.0)
}
}
ast_node! {
EnumDef => ENUM_DEF
}
impl EnumDef {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn variants(&self) -> impl Iterator<Item = EnumVariant> {
support::children_nodes(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
}
ast_node! {
EnumVariant => ENUM_VARIANT
}
impl EnumVariant {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
}
ast_node! {
PrefixDecl => PREFIX_DECL
}
impl PrefixDecl {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
}
ast_node! {
TypeDecl => TYPE_DECL
}
impl TypeDecl {
pub fn export_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::EXPORT_KW)
}
pub fn new_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::NEW_KW)
}
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn generic_params(&self) -> Option<GenericParamList> {
support::child_node(&self.0)
}
pub fn aliased_type(&self) -> Option<Type> {
support::child_node(&self.0)
}
pub fn is_exported(&self) -> bool {
self.export_kw().is_some()
}
pub fn is_newtype(&self) -> bool {
self.new_kw().is_some()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Item {
Pragma(Pragma),
Include(Include),
Import(Import),
ExportList(ExportList),
LedgerDecl(LedgerDecl),
ConstructorDef(ConstructorDef),
CircuitDef(CircuitDef),
CircuitDecl(CircuitDecl),
WitnessDecl(WitnessDecl),
ContractDecl(ContractDecl),
StructDef(StructDef),
EnumDef(EnumDef),
ModuleDef(ModuleDef),
TypeDecl(TypeDecl),
}
impl AstNode for Item {
fn can_cast(kind: SyntaxKind) -> bool {
Pragma::can_cast(kind)
|| Include::can_cast(kind)
|| Import::can_cast(kind)
|| ExportList::can_cast(kind)
|| LedgerDecl::can_cast(kind)
|| ConstructorDef::can_cast(kind)
|| CircuitDef::can_cast(kind)
|| CircuitDecl::can_cast(kind)
|| WitnessDecl::can_cast(kind)
|| ContractDecl::can_cast(kind)
|| StructDef::can_cast(kind)
|| EnumDef::can_cast(kind)
|| ModuleDef::can_cast(kind)
|| TypeDecl::can_cast(kind)
}
fn cast(node: SyntaxNode) -> Option<Self> {
if let Some(n) = Pragma::cast(node.clone()) {
return Some(Item::Pragma(n));
}
if let Some(n) = Include::cast(node.clone()) {
return Some(Item::Include(n));
}
if let Some(n) = Import::cast(node.clone()) {
return Some(Item::Import(n));
}
if let Some(n) = ExportList::cast(node.clone()) {
return Some(Item::ExportList(n));
}
if let Some(n) = LedgerDecl::cast(node.clone()) {
return Some(Item::LedgerDecl(n));
}
if let Some(n) = ConstructorDef::cast(node.clone()) {
return Some(Item::ConstructorDef(n));
}
if let Some(n) = CircuitDef::cast(node.clone()) {
return Some(Item::CircuitDef(n));
}
if let Some(n) = CircuitDecl::cast(node.clone()) {
return Some(Item::CircuitDecl(n));
}
if let Some(n) = WitnessDecl::cast(node.clone()) {
return Some(Item::WitnessDecl(n));
}
if let Some(n) = ContractDecl::cast(node.clone()) {
return Some(Item::ContractDecl(n));
}
if let Some(n) = StructDef::cast(node.clone()) {
return Some(Item::StructDef(n));
}
if let Some(n) = EnumDef::cast(node.clone()) {
return Some(Item::EnumDef(n));
}
if let Some(n) = ModuleDef::cast(node.clone()) {
return Some(Item::ModuleDef(n));
}
if let Some(n) = TypeDecl::cast(node) {
return Some(Item::TypeDecl(n));
}
None
}
fn syntax(&self) -> &SyntaxNode {
match self {
Item::Pragma(n) => n.syntax(),
Item::Include(n) => n.syntax(),
Item::Import(n) => n.syntax(),
Item::ExportList(n) => n.syntax(),
Item::LedgerDecl(n) => n.syntax(),
Item::ConstructorDef(n) => n.syntax(),
Item::CircuitDef(n) => n.syntax(),
Item::CircuitDecl(n) => n.syntax(),
Item::WitnessDecl(n) => n.syntax(),
Item::ContractDecl(n) => n.syntax(),
Item::StructDef(n) => n.syntax(),
Item::EnumDef(n) => n.syntax(),
Item::ModuleDef(n) => n.syntax(),
Item::TypeDecl(n) => n.syntax(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Type {
Ref(TypeRef),
Boolean(BooleanType),
Field(FieldType),
Uint(UintType),
Bytes(BytesType),
Opaque(OpaqueType),
Vector(VectorType),
Tuple(TupleType),
UnsignedInteger(UnsignedIntegerType),
Record(RecordType),
}
impl AstNode for Type {
fn can_cast(kind: SyntaxKind) -> bool {
matches!(
kind,
SyntaxKind::TYPE_REF
| SyntaxKind::BOOLEAN_TYPE
| SyntaxKind::FIELD_TYPE
| SyntaxKind::UINT_TYPE
| SyntaxKind::BYTES_TYPE
| SyntaxKind::OPAQUE_TYPE
| SyntaxKind::VECTOR_TYPE
| SyntaxKind::TUPLE_TYPE
| SyntaxKind::UNSIGNED_INTEGER_TYPE
| SyntaxKind::RECORD_TYPE
)
}
fn cast(node: SyntaxNode) -> Option<Self> {
match node.kind() {
SyntaxKind::TYPE_REF => Some(Self::Ref(TypeRef(node))),
SyntaxKind::BOOLEAN_TYPE => Some(Self::Boolean(BooleanType(node))),
SyntaxKind::FIELD_TYPE => Some(Self::Field(FieldType(node))),
SyntaxKind::UINT_TYPE => Some(Self::Uint(UintType(node))),
SyntaxKind::BYTES_TYPE => Some(Self::Bytes(BytesType(node))),
SyntaxKind::OPAQUE_TYPE => Some(Self::Opaque(OpaqueType(node))),
SyntaxKind::VECTOR_TYPE => Some(Self::Vector(VectorType(node))),
SyntaxKind::TUPLE_TYPE => Some(Self::Tuple(TupleType(node))),
SyntaxKind::UNSIGNED_INTEGER_TYPE => {
Some(Self::UnsignedInteger(UnsignedIntegerType(node)))
}
SyntaxKind::RECORD_TYPE => Some(Self::Record(RecordType(node))),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode {
match self {
Self::Ref(n) => &n.0,
Self::Boolean(n) => &n.0,
Self::Field(n) => &n.0,
Self::Uint(n) => &n.0,
Self::Bytes(n) => &n.0,
Self::Opaque(n) => &n.0,
Self::Vector(n) => &n.0,
Self::Tuple(n) => &n.0,
Self::UnsignedInteger(n) => &n.0,
Self::Record(n) => &n.0,
}
}
}
ast_node! {
TypeRef => TYPE_REF
}
impl TypeRef {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn generic_args(&self) -> Option<GenericArgList> {
support::child_node(&self.0)
}
}
ast_node! {
BooleanType => BOOLEAN_TYPE
}
ast_node! {
FieldType => FIELD_TYPE
}
ast_node! {
UintType => UINT_TYPE
}
impl UintType {
pub fn sizes(&self) -> impl Iterator<Item = TypeSize> {
support::children_nodes(&self.0)
}
}
ast_node! {
BytesType => BYTES_TYPE
}
impl BytesType {
pub fn size(&self) -> Option<TypeSize> {
support::child_node(&self.0)
}
}
ast_node! {
OpaqueType => OPAQUE_TYPE
}
impl OpaqueType {
pub fn tag(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::STRING_LIT)
}
}
ast_node! {
VectorType => VECTOR_TYPE
}
impl VectorType {
pub fn size(&self) -> Option<TypeSize> {
support::child_node(&self.0)
}
pub fn element_type(&self) -> Option<Type> {
support::child_node(&self.0)
}
}
ast_node! {
TupleType => TUPLE_TYPE
}
impl TupleType {
pub fn element_types(&self) -> impl Iterator<Item = Type> {
support::children_nodes(&self.0)
}
}
ast_node! {
UnsignedIntegerType => UNSIGNED_INTEGER_TYPE
}
ast_node! {
RecordType => RECORD_TYPE
}
ast_node! {
GenericArgList => GENERIC_ARG_LIST
}
impl GenericArgList {
pub fn args(&self) -> impl Iterator<Item = GenericArg> {
support::children_nodes(&self.0)
}
}
ast_node! {
GenericArg => GENERIC_ARG
}
ast_node! {
GenericParamList => GENERIC_PARAM_LIST
}
impl GenericParamList {
pub fn params(&self) -> impl Iterator<Item = GenericParam> {
support::children_nodes(&self.0)
}
}
ast_node! {
GenericParam => GENERIC_PARAM
}
impl GenericParam {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn is_numeric(&self) -> bool {
support::child_token(&self.0, SyntaxKind::HASH).is_some()
}
}
ast_node! {
TypeSize => TYPE_SIZE
}
ast_node! {
Param => PARAM
}
impl Param {
pub fn pattern(&self) -> Option<Pat> {
support::child_node(&self.0)
}
pub fn ty(&self) -> Option<Type> {
support::child_node(&self.0)
}
}
ast_node! {
ParamList => PARAM_LIST
}
impl ParamList {
pub fn params(&self) -> impl Iterator<Item = Param> {
support::children_nodes(&self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Stmt {
Block(Block),
Assign(AssignStmt),
Const(ConstStmt),
MultiConst(MultiConstStmt),
Expr(ExprStmt),
Return(ReturnStmt),
If(IfStmt),
For(ForStmt),
Assert(AssertStmt),
}
impl AstNode for Stmt {
fn can_cast(kind: SyntaxKind) -> bool {
matches!(
kind,
SyntaxKind::BLOCK
| SyntaxKind::ASSIGN_STMT
| SyntaxKind::CONST_STMT
| SyntaxKind::MULTI_CONST_STMT
| SyntaxKind::EXPR_STMT
| SyntaxKind::RETURN_STMT
| SyntaxKind::IF_STMT
| SyntaxKind::FOR_STMT
| SyntaxKind::ASSERT_STMT
)
}
fn cast(node: SyntaxNode) -> Option<Self> {
match node.kind() {
SyntaxKind::BLOCK => Some(Self::Block(Block(node))),
SyntaxKind::ASSIGN_STMT => Some(Self::Assign(AssignStmt(node))),
SyntaxKind::CONST_STMT => Some(Self::Const(ConstStmt(node))),
SyntaxKind::MULTI_CONST_STMT => Some(Self::MultiConst(MultiConstStmt(node))),
SyntaxKind::EXPR_STMT => Some(Self::Expr(ExprStmt(node))),
SyntaxKind::RETURN_STMT => Some(Self::Return(ReturnStmt(node))),
SyntaxKind::IF_STMT => Some(Self::If(IfStmt(node))),
SyntaxKind::FOR_STMT => Some(Self::For(ForStmt(node))),
SyntaxKind::ASSERT_STMT => Some(Self::Assert(AssertStmt(node))),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode {
match self {
Self::Block(n) => &n.0,
Self::Assign(n) => &n.0,
Self::Const(n) => &n.0,
Self::MultiConst(n) => &n.0,
Self::Expr(n) => &n.0,
Self::Return(n) => &n.0,
Self::If(n) => &n.0,
Self::For(n) => &n.0,
Self::Assert(n) => &n.0,
}
}
}
ast_node! {
Block => BLOCK
}
impl Block {
pub fn stmts(&self) -> impl Iterator<Item = Stmt> {
support::children_nodes(&self.0)
}
}
ast_node! {
AssignStmt => ASSIGN_STMT
}
impl AssignStmt {
pub fn op(&self) -> Option<SyntaxToken> {
self.0
.children_with_tokens()
.filter_map(rowan::NodeOrToken::into_token)
.find(|t| {
matches!(
t.kind(),
SyntaxKind::EQ | SyntaxKind::PLUS_EQ | SyntaxKind::MINUS_EQ
)
})
}
}
ast_node! {
ConstStmt => CONST_STMT
}
impl ConstStmt {
pub fn pattern(&self) -> Option<Pat> {
support::child_node(&self.0)
}
pub fn ty(&self) -> Option<Type> {
support::child_node(&self.0)
}
pub fn value(&self) -> Option<Expr> {
support::child_node(&self.0)
}
}
ast_node! {
MultiConstStmt => MULTI_CONST_STMT
}
ast_node! {
ExprStmt => EXPR_STMT
}
ast_node! {
ReturnStmt => RETURN_STMT
}
impl ReturnStmt {
pub fn value(&self) -> Option<Expr> {
support::child_node(&self.0)
}
}
ast_node! {
IfStmt => IF_STMT
}
impl IfStmt {
pub fn then_branch(&self) -> Option<Block> {
support::child_node(&self.0)
}
pub fn else_kw(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::ELSE_KW)
}
}
ast_node! {
ForStmt => FOR_STMT
}
impl ForStmt {
pub fn var_name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn body(&self) -> Option<Block> {
support::child_node(&self.0)
}
}
ast_node! {
AssertStmt => ASSERT_STMT
}
impl AssertStmt {
pub fn message(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::STRING_LIT)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Pat {
Ident(IdentPat),
Tuple(TuplePat),
Struct(StructPat),
}
impl AstNode for Pat {
fn can_cast(kind: SyntaxKind) -> bool {
matches!(
kind,
SyntaxKind::IDENT_PAT | SyntaxKind::TUPLE_PAT | SyntaxKind::STRUCT_PAT
)
}
fn cast(node: SyntaxNode) -> Option<Self> {
match node.kind() {
SyntaxKind::IDENT_PAT => Some(Self::Ident(IdentPat(node))),
SyntaxKind::TUPLE_PAT => Some(Self::Tuple(TuplePat(node))),
SyntaxKind::STRUCT_PAT => Some(Self::Struct(StructPat(node))),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode {
match self {
Self::Ident(n) => &n.0,
Self::Tuple(n) => &n.0,
Self::Struct(n) => &n.0,
}
}
}
ast_node! {
IdentPat => IDENT_PAT
}
impl IdentPat {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
}
ast_node! {
TuplePat => TUPLE_PAT
}
impl TuplePat {
pub fn elements(&self) -> impl Iterator<Item = TuplePatElt> {
support::children_nodes(&self.0)
}
}
ast_node! {
TuplePatElt => TUPLE_PAT_ELT
}
impl TuplePatElt {
pub fn pattern(&self) -> Option<Pat> {
support::child_node(&self.0)
}
}
ast_node! {
StructPat => STRUCT_PAT
}
impl StructPat {
pub fn fields(&self) -> impl Iterator<Item = StructPatField> {
support::children_nodes(&self.0)
}
}
ast_node! {
StructPatField => STRUCT_PAT_FIELD
}
impl StructPatField {
pub fn name(&self) -> Option<SyntaxToken> {
support::child_token(&self.0, SyntaxKind::IDENT)
}
pub fn pattern(&self) -> Option<Pat> {
support::child_node(&self.0)
}
}