From 1eed6b0e03eda02435c0260d2cc0e19a3bfdb257 Mon Sep 17 00:00:00 2001 From: Xavier Pinho Date: Wed, 22 Apr 2026 00:21:19 +0100 Subject: [PATCH 1/3] add scala smoke tests --- .github/workflows/pr.yml | 23 +- scala_tests/.gitignore | 7 + scala_tests/build.sbt | 12 + scala_tests/project/build.properties | 1 + .../rust2cpg/parser/RustNodeSyntax.scala | 2080 +++++++++++++++++ .../parser/RustAstGenPrettyPrintTests.scala | 115 + .../parser/RustAstGenTestFixture.scala | 80 + .../parser/RustAstGenTraversalTests.scala | 27 + src/bin/scala_bindings_gen.rs | 17 +- src/scala_gen/config.rs | 4 +- src/scala_gen/emitter.rs | 29 +- 11 files changed, 2384 insertions(+), 11 deletions(-) create mode 100644 scala_tests/.gitignore create mode 100644 scala_tests/build.sbt create mode 100644 scala_tests/project/build.properties create mode 100644 scala_tests/src/main/scala/io/joern/rust2cpg/parser/RustNodeSyntax.scala create mode 100644 scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenPrettyPrintTests.scala create mode 100644 scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala create mode 100644 scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTraversalTests.scala diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index dac1f9f..9be6eb4 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -26,11 +26,32 @@ jobs: - name: Run tests run: cargo test --locked + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + cache: sbt + cache-dependency-path: | + scala_tests/build.sbt + scala_tests/project/build.properties + + - name: Set up sbt + uses: sbt/setup-sbt@v1 + + - name: Regenerate Scala bindings + run: cargo run --locked --bin scala_bindings_gen -- --include-date=false --output scala_tests/src/main/scala/io/joern/rust2cpg/parser/RustNodeSyntax.scala + + - name: Run Scala tests + working-directory: scala_tests + shell: bash + run: sbt test + - name: Check if there are changes shell: bash run: | if [[ -n "$(git status --porcelain --untracked-files=no)" ]]; then - echo "::error title=Repository modified by CI::Did you forget to commit rust.ungram?" + echo "::error title=Repository modified by CI::Did you forget to commit regenerated files such as rust.ungram or RustNodeSyntax.scala?" echo "Changes:" git status --short exit 1 diff --git a/scala_tests/.gitignore b/scala_tests/.gitignore new file mode 100644 index 0000000..72cd136 --- /dev/null +++ b/scala_tests/.gitignore @@ -0,0 +1,7 @@ +.bsp/ +.idea/ +.coursier/ +.sbt-boot/ +.sbt-global/ +project/target/ +target/ \ No newline at end of file diff --git a/scala_tests/build.sbt b/scala_tests/build.sbt new file mode 100644 index 0000000..b91eefc --- /dev/null +++ b/scala_tests/build.sbt @@ -0,0 +1,12 @@ + +ThisBuild / scalaVersion := "3.7.4" + +lazy val root = (project in file(".")) + .settings( + name := "scala_tests", + // Versions chosen to match the versions used by joern. + libraryDependencies ++= Seq( + "com.lihaoyi" %% "upickle" % "4.0.2", + "org.scalatest" %% "scalatest" % "3.2.18" % Test + ) + ) diff --git a/scala_tests/project/build.properties b/scala_tests/project/build.properties new file mode 100644 index 0000000..45c26e8 --- /dev/null +++ b/scala_tests/project/build.properties @@ -0,0 +1 @@ +sbt.version = 1.12.9 diff --git a/scala_tests/src/main/scala/io/joern/rust2cpg/parser/RustNodeSyntax.scala b/scala_tests/src/main/scala/io/joern/rust2cpg/parser/RustNodeSyntax.scala new file mode 100644 index 0000000..4c1ee55 --- /dev/null +++ b/scala_tests/src/main/scala/io/joern/rust2cpg/parser/RustNodeSyntax.scala @@ -0,0 +1,2080 @@ +package io.joern.rust2cpg.parser + +// Automatically generated by rust_ast_gen v0.1.0 +// Do not edit directly! + +import ujson.Value +object RustNodeSyntax { + + def createRustNode(json: Value): RustNode = { + val kind = json("nodeKind").str + _kindMap.getOrElse( + kind, + throw new UnsupportedOperationException(s"Kind '$kind' is not a known Rust node or token kind") + )(json) + } + + private val _kindMap: Map[String, Value => RustNode] = Map( + "ABI" -> (json => Abi(json)), + "ADT" -> (json => Adt(json)), + "ARG_LIST" -> (json => ArgList(json)), + "ARRAY_EXPR" -> (json => ArrayExpr(json)), + "ARRAY_TYPE" -> (json => ArrayType(json)), + "ASM_CLOBBER_ABI" -> (json => AsmClobberAbi(json)), + "ASM_CONST" -> (json => AsmConst(json)), + "ASM_DIR_SPEC" -> (json => AsmDirSpec(json)), + "ASM_EXPR" -> (json => AsmExpr(json)), + "ASM_LABEL" -> (json => AsmLabel(json)), + "ASM_OPERAND" -> (json => AsmOperand(json)), + "ASM_OPERAND_EXPR" -> (json => AsmOperandExpr(json)), + "ASM_OPERAND_NAMED" -> (json => AsmOperandNamed(json)), + "ASM_OPTION" -> (json => AsmOption(json)), + "ASM_OPTIONS" -> (json => AsmOptions(json)), + "ASM_PIECE" -> (json => AsmPiece(json)), + "ASM_REG_OPERAND" -> (json => AsmRegOperand(json)), + "ASM_REG_SPEC" -> (json => AsmRegSpec(json)), + "ASM_SYM" -> (json => AsmSym(json)), + "ASSOC_ITEM" -> (json => AssocItem(json)), + "ASSOC_ITEM_LIST" -> (json => AssocItemList(json)), + "ASSOC_TYPE_ARG" -> (json => AssocTypeArg(json)), + "ATTR" -> (json => Attr(json)), + "AWAIT_EXPR" -> (json => AwaitExpr(json)), + "BECOME_EXPR" -> (json => BecomeExpr(json)), + "BIN_EXPR" -> (json => BinExpr(json)), + "BLOCK_EXPR" -> (json => BlockExpr(json)), + "BOX_PAT" -> (json => BoxPat(json)), + "BREAK_EXPR" -> (json => BreakExpr(json)), + "CALL_EXPR" -> (json => CallExpr(json)), + "CAST_EXPR" -> (json => CastExpr(json)), + "CFG_ATOM" -> (json => CfgAtom(json)), + "CFG_ATTR_META" -> (json => CfgAttrMeta(json)), + "CFG_COMPOSITE" -> (json => CfgComposite(json)), + "CFG_META" -> (json => CfgMeta(json)), + "CFG_PREDICATE" -> (json => CfgPredicate(json)), + "CLOSURE_EXPR" -> (json => ClosureExpr(json)), + "CONST" -> (json => Const(json)), + "CONST_ARG" -> (json => ConstArg(json)), + "CONST_BLOCK_PAT" -> (json => ConstBlockPat(json)), + "CONST_PARAM" -> (json => ConstParam(json)), + "CONTINUE_EXPR" -> (json => ContinueExpr(json)), + "DYN_TRAIT_TYPE" -> (json => DynTraitType(json)), + "ENUM" -> (json => Enum(json)), + "EXPR_STMT" -> (json => ExprStmt(json)), + "EXTERN_BLOCK" -> (json => ExternBlock(json)), + "EXTERN_CRATE" -> (json => ExternCrate(json)), + "EXTERN_ITEM" -> (json => ExternItem(json)), + "EXTERN_ITEM_LIST" -> (json => ExternItemList(json)), + "FIELD_EXPR" -> (json => FieldExpr(json)), + "FIELD_LIST" -> (json => FieldList(json)), + "FN" -> (json => Fn(json)), + "FN_PTR_TYPE" -> (json => FnPtrType(json)), + "FOR_BINDER" -> (json => ForBinder(json)), + "FOR_EXPR" -> (json => ForExpr(json)), + "FOR_TYPE" -> (json => ForType(json)), + "FORMAT_ARGS_ARG" -> (json => FormatArgsArg(json)), + "FORMAT_ARGS_ARG_NAME" -> (json => FormatArgsArgName(json)), + "FORMAT_ARGS_EXPR" -> (json => FormatArgsExpr(json)), + "GENERIC_ARG" -> (json => GenericArg(json)), + "GENERIC_ARG_LIST" -> (json => GenericArgList(json)), + "GENERIC_PARAM" -> (json => GenericParam(json)), + "GENERIC_PARAM_LIST" -> (json => GenericParamList(json)), + "IDENT_PAT" -> (json => IdentPat(json)), + "IF_EXPR" -> (json => IfExpr(json)), + "IMPL" -> (json => Impl(json)), + "IMPL_TRAIT_TYPE" -> (json => ImplTraitType(json)), + "INDEX_EXPR" -> (json => IndexExpr(json)), + "INFER_TYPE" -> (json => InferType(json)), + "ITEM_LIST" -> (json => ItemList(json)), + "KEY_VALUE_META" -> (json => KeyValueMeta(json)), + "LABEL" -> (json => Label(json)), + "LET_ELSE" -> (json => LetElse(json)), + "LET_EXPR" -> (json => LetExpr(json)), + "LET_STMT" -> (json => LetStmt(json)), + "LIFETIME" -> (json => Lifetime(json)), + "LIFETIME_ARG" -> (json => LifetimeArg(json)), + "LIFETIME_PARAM" -> (json => LifetimeParam(json)), + "LITERAL" -> (json => Literal(json)), + "LITERAL_PAT" -> (json => LiteralPat(json)), + "LOOP_EXPR" -> (json => LoopExpr(json)), + "MACRO_CALL" -> (json => MacroCall(json)), + "MACRO_DEF" -> (json => MacroDef(json)), + "MACRO_EXPR" -> (json => MacroExpr(json)), + "MACRO_ITEMS" -> (json => MacroItems(json)), + "MACRO_PAT" -> (json => MacroPat(json)), + "MACRO_RULES" -> (json => MacroRules(json)), + "MACRO_STMTS" -> (json => MacroStmts(json)), + "MACRO_TYPE" -> (json => MacroType(json)), + "MATCH_ARM" -> (json => MatchArm(json)), + "MATCH_ARM_LIST" -> (json => MatchArmList(json)), + "MATCH_EXPR" -> (json => MatchExpr(json)), + "MATCH_GUARD" -> (json => MatchGuard(json)), + "METHOD_CALL_EXPR" -> (json => MethodCallExpr(json)), + "MODULE" -> (json => Module(json)), + "NAME" -> (json => Name(json)), + "NAME_REF" -> (json => NameRef(json)), + "NEVER_TYPE" -> (json => NeverType(json)), + "OFFSET_OF_EXPR" -> (json => OffsetOfExpr(json)), + "OR_PAT" -> (json => OrPat(json)), + "PARAM" -> (json => Param(json)), + "PARAM_LIST" -> (json => ParamList(json)), + "PAREN_EXPR" -> (json => ParenExpr(json)), + "PAREN_PAT" -> (json => ParenPat(json)), + "PAREN_TYPE" -> (json => ParenType(json)), + "PARENTHESIZED_ARG_LIST" -> (json => ParenthesizedArgList(json)), + "PATH" -> (json => Path(json)), + "PATH_EXPR" -> (json => PathExpr(json)), + "PATH_META" -> (json => PathMeta(json)), + "PATH_PAT" -> (json => PathPat(json)), + "PATH_SEGMENT" -> (json => PathSegment(json)), + "PATH_TYPE" -> (json => PathType(json)), + "PREFIX_EXPR" -> (json => PrefixExpr(json)), + "PTR_TYPE" -> (json => PtrType(json)), + "RANGE_EXPR" -> (json => RangeExpr(json)), + "RANGE_PAT" -> (json => RangePat(json)), + "RECORD_EXPR" -> (json => RecordExpr(json)), + "RECORD_EXPR_FIELD" -> (json => RecordExprField(json)), + "RECORD_EXPR_FIELD_LIST" -> (json => RecordExprFieldList(json)), + "RECORD_FIELD" -> (json => RecordField(json)), + "RECORD_FIELD_LIST" -> (json => RecordFieldList(json)), + "RECORD_PAT" -> (json => RecordPat(json)), + "RECORD_PAT_FIELD" -> (json => RecordPatField(json)), + "RECORD_PAT_FIELD_LIST" -> (json => RecordPatFieldList(json)), + "REF_EXPR" -> (json => RefExpr(json)), + "REF_PAT" -> (json => RefPat(json)), + "REF_TYPE" -> (json => RefType(json)), + "RENAME" -> (json => Rename(json)), + "REST_PAT" -> (json => RestPat(json)), + "RET_TYPE" -> (json => RetType(json)), + "RETURN_EXPR" -> (json => ReturnExpr(json)), + "RETURN_TYPE_SYNTAX" -> (json => ReturnTypeSyntax(json)), + "SELF_PARAM" -> (json => SelfParam(json)), + "SLICE_PAT" -> (json => SlicePat(json)), + "SLICE_TYPE" -> (json => SliceType(json)), + "SOURCE_FILE" -> (json => SourceFile(json)), + "STATIC" -> (json => Static(json)), + "STMT_LIST" -> (json => StmtList(json)), + "STRUCT" -> (json => Struct(json)), + "TOKEN_TREE" -> (json => TokenTree(json)), + "TOKEN_TREE_META" -> (json => TokenTreeMeta(json)), + "TRAIT" -> (json => Trait(json)), + "TRY_BLOCK_MODIFIER" -> (json => TryBlockModifier(json)), + "TRY_EXPR" -> (json => TryExpr(json)), + "TUPLE_EXPR" -> (json => TupleExpr(json)), + "TUPLE_FIELD" -> (json => TupleField(json)), + "TUPLE_FIELD_LIST" -> (json => TupleFieldList(json)), + "TUPLE_PAT" -> (json => TuplePat(json)), + "TUPLE_STRUCT_PAT" -> (json => TupleStructPat(json)), + "TUPLE_TYPE" -> (json => TupleType(json)), + "TYPE_ALIAS" -> (json => TypeAlias(json)), + "TYPE_ANCHOR" -> (json => TypeAnchor(json)), + "TYPE_ARG" -> (json => TypeArg(json)), + "TYPE_BOUND" -> (json => TypeBound(json)), + "TYPE_BOUND_LIST" -> (json => TypeBoundList(json)), + "TYPE_PARAM" -> (json => TypeParam(json)), + "UNDERSCORE_EXPR" -> (json => UnderscoreExpr(json)), + "UNION" -> (json => Union(json)), + "UNSAFE_META" -> (json => UnsafeMeta(json)), + "USE" -> (json => Use(json)), + "USE_BOUND_GENERIC_ARG" -> (json => UseBoundGenericArg(json)), + "USE_BOUND_GENERIC_ARGS" -> (json => UseBoundGenericArgs(json)), + "USE_TREE" -> (json => UseTree(json)), + "USE_TREE_LIST" -> (json => UseTreeList(json)), + "VARIANT" -> (json => Variant(json)), + "VARIANT_DEF" -> (json => VariantDef(json)), + "VARIANT_LIST" -> (json => VariantList(json)), + "VISIBILITY" -> (json => Visibility(json)), + "WHERE_CLAUSE" -> (json => WhereClause(json)), + "WHERE_PRED" -> (json => WherePred(json)), + "WHILE_EXPR" -> (json => WhileExpr(json)), + "WILDCARD_PAT" -> (json => WildcardPat(json)), + "YEET_EXPR" -> (json => YeetExpr(json)), + "YIELD_EXPR" -> (json => YieldExpr(json)), + "BANG" -> (json => BangToken(json)), + "NEQ" -> (json => NeqToken(json)), + "POUND" -> (json => PoundToken(json)), + "FRONTMATTER" -> (json => FrontmatterToken(json)), + "IDENT" -> (json => IdentToken(json)), + "LIFETIME_IDENT" -> (json => LifetimeIdentToken(json)), + "SHEBANG" -> (json => ShebangToken(json)), + "PERCENT" -> (json => PercentToken(json)), + "PERCENTEQ" -> (json => PercenteqToken(json)), + "AMP" -> (json => AmpToken(json)), + "AMP2" -> (json => Amp2Token(json)), + "AMPEQ" -> (json => AmpeqToken(json)), + "L_PAREN" -> (json => LParenToken(json)), + "R_PAREN" -> (json => RParenToken(json)), + "STAR" -> (json => StarToken(json)), + "STAREQ" -> (json => StareqToken(json)), + "PLUS" -> (json => PlusToken(json)), + "PLUSEQ" -> (json => PluseqToken(json)), + "COMMA" -> (json => CommaToken(json)), + "MINUS" -> (json => MinusToken(json)), + "MINUSEQ" -> (json => MinuseqToken(json)), + "THIN_ARROW" -> (json => ThinArrowToken(json)), + "DOT" -> (json => DotToken(json)), + "DOT2" -> (json => Dot2Token(json)), + "DOT3" -> (json => Dot3Token(json)), + "DOT2EQ" -> (json => Dot2eqToken(json)), + "SLASH" -> (json => SlashToken(json)), + "SLASHEQ" -> (json => SlasheqToken(json)), + "COLON" -> (json => ColonToken(json)), + "COLON2" -> (json => Colon2Token(json)), + "SEMICOLON" -> (json => SemicolonToken(json)), + "L_ANGLE" -> (json => LAngleToken(json)), + "SHL" -> (json => ShlToken(json)), + "SHLEQ" -> (json => ShleqToken(json)), + "LTEQ" -> (json => LteqToken(json)), + "EQ" -> (json => EqToken(json)), + "EQ2" -> (json => Eq2Token(json)), + "FAT_ARROW" -> (json => FatArrowToken(json)), + "R_ANGLE" -> (json => RAngleToken(json)), + "GTEQ" -> (json => GteqToken(json)), + "SHR" -> (json => ShrToken(json)), + "SHREQ" -> (json => ShreqToken(json)), + "QUESTION" -> (json => QuestionToken(json)), + "AT" -> (json => AtToken(json)), + "BYTE" -> (json => ByteToken(json)), + "BYTE_STRING" -> (json => ByteStringToken(json)), + "C_STRING" -> (json => CStringToken(json)), + "CHAR" -> (json => CharToken(json)), + "FLOAT_NUMBER" -> (json => FloatNumberToken(json)), + "INT_NUMBER" -> (json => IntNumberToken(json)), + "STRING" -> (json => StringToken(json)), + "SELF_TYPE_KW" -> (json => SelfTypeKwToken(json)), + "L_BRACK" -> (json => LBrackToken(json)), + "R_BRACK" -> (json => RBrackToken(json)), + "CARET" -> (json => CaretToken(json)), + "CARETEQ" -> (json => CareteqToken(json)), + "UNDERSCORE" -> (json => UnderscoreToken(json)), + "AS_KW" -> (json => AsKwToken(json)), + "ASM_KW" -> (json => AsmKwToken(json)), + "ASYNC_KW" -> (json => AsyncKwToken(json)), + "ATT_SYNTAX_KW" -> (json => AttSyntaxKwToken(json)), + "AUTO_KW" -> (json => AutoKwToken(json)), + "AWAIT_KW" -> (json => AwaitKwToken(json)), + "BECOME_KW" -> (json => BecomeKwToken(json)), + "BIKESHED_KW" -> (json => BikeshedKwToken(json)), + "BOX_KW" -> (json => BoxKwToken(json)), + "BREAK_KW" -> (json => BreakKwToken(json)), + "BUILTIN_KW" -> (json => BuiltinKwToken(json)), + "CFG_KW" -> (json => CfgKwToken(json)), + "CFG_ATTR_KW" -> (json => CfgAttrKwToken(json)), + "CLOBBER_ABI_KW" -> (json => ClobberAbiKwToken(json)), + "CONST_KW" -> (json => ConstKwToken(json)), + "CONTINUE_KW" -> (json => ContinueKwToken(json)), + "CRATE_KW" -> (json => CrateKwToken(json)), + "DEFAULT_KW" -> (json => DefaultKwToken(json)), + "DO_KW" -> (json => DoKwToken(json)), + "DYN_KW" -> (json => DynKwToken(json)), + "ELSE_KW" -> (json => ElseKwToken(json)), + "ENUM_KW" -> (json => EnumKwToken(json)), + "EXTERN_KW" -> (json => ExternKwToken(json)), + "FALSE_KW" -> (json => FalseKwToken(json)), + "FN_KW" -> (json => FnKwToken(json)), + "FOR_KW" -> (json => ForKwToken(json)), + "FORMAT_ARGS_KW" -> (json => FormatArgsKwToken(json)), + "GEN_KW" -> (json => GenKwToken(json)), + "GLOBAL_ASM_KW" -> (json => GlobalAsmKwToken(json)), + "IF_KW" -> (json => IfKwToken(json)), + "IMPL_KW" -> (json => ImplKwToken(json)), + "IN_KW" -> (json => InKwToken(json)), + "INLATEOUT_KW" -> (json => InlateoutKwToken(json)), + "INOUT_KW" -> (json => InoutKwToken(json)), + "LABEL_KW" -> (json => LabelKwToken(json)), + "LATEOUT_KW" -> (json => LateoutKwToken(json)), + "LET_KW" -> (json => LetKwToken(json)), + "LOOP_KW" -> (json => LoopKwToken(json)), + "MACRO_KW" -> (json => MacroKwToken(json)), + "MACRO_RULES_KW" -> (json => MacroRulesKwToken(json)), + "MATCH_KW" -> (json => MatchKwToken(json)), + "MAY_UNWIND_KW" -> (json => MayUnwindKwToken(json)), + "MOD_KW" -> (json => ModKwToken(json)), + "MOVE_KW" -> (json => MoveKwToken(json)), + "MUT_KW" -> (json => MutKwToken(json)), + "NAKED_ASM_KW" -> (json => NakedAsmKwToken(json)), + "NOMEM_KW" -> (json => NomemKwToken(json)), + "NORETURN_KW" -> (json => NoreturnKwToken(json)), + "NOSTACK_KW" -> (json => NostackKwToken(json)), + "OFFSET_OF_KW" -> (json => OffsetOfKwToken(json)), + "OPTIONS_KW" -> (json => OptionsKwToken(json)), + "OUT_KW" -> (json => OutKwToken(json)), + "PRESERVES_FLAGS_KW" -> (json => PreservesFlagsKwToken(json)), + "PUB_KW" -> (json => PubKwToken(json)), + "PURE_KW" -> (json => PureKwToken(json)), + "RAW_KW" -> (json => RawKwToken(json)), + "READONLY_KW" -> (json => ReadonlyKwToken(json)), + "REF_KW" -> (json => RefKwToken(json)), + "RETURN_KW" -> (json => ReturnKwToken(json)), + "SAFE_KW" -> (json => SafeKwToken(json)), + "SELF_KW" -> (json => SelfKwToken(json)), + "STATIC_KW" -> (json => StaticKwToken(json)), + "STRUCT_KW" -> (json => StructKwToken(json)), + "SUPER_KW" -> (json => SuperKwToken(json)), + "SYM_KW" -> (json => SymKwToken(json)), + "TRAIT_KW" -> (json => TraitKwToken(json)), + "TRUE_KW" -> (json => TrueKwToken(json)), + "TRY_KW" -> (json => TryKwToken(json)), + "TYPE_KW" -> (json => TypeKwToken(json)), + "UNION_KW" -> (json => UnionKwToken(json)), + "UNSAFE_KW" -> (json => UnsafeKwToken(json)), + "USE_KW" -> (json => UseKwToken(json)), + "WHERE_KW" -> (json => WhereKwToken(json)), + "WHILE_KW" -> (json => WhileKwToken(json)), + "YEET_KW" -> (json => YeetKwToken(json)), + "YIELD_KW" -> (json => YieldKwToken(json)), + "L_CURLY" -> (json => LCurlyToken(json)), + "PIPE" -> (json => PipeToken(json)), + "PIPEEQ" -> (json => PipeeqToken(json)), + "PIPE2" -> (json => Pipe2Token(json)), + "R_CURLY" -> (json => RCurlyToken(json)), + "TILDE" -> (json => TildeToken(json)), + ) + + sealed trait RustNode { + def json: Value + protected lazy val _children: Seq[Value] = json.obj.get("children").map(_.arr.toSeq).getOrElse(Seq.empty) + protected lazy val _childrenByKind: Map[String, Seq[Value]] = _children.groupBy(_("nodeKind").str) + private lazy val rangeObj = json.obj.get("range").map(_.obj) + private def rangeField(name: String): Option[Int] = rangeObj.flatMap(_.get(name)).map(_.num.toInt) + def startOffset: Option[Int] = rangeField("startOffset") + def endOffset: Option[Int] = rangeField("endOffset") + def startLine: Option[Int] = rangeField("startLine") + def startColumn: Option[Int] = rangeField("startColumn") + } + + sealed trait RustToken extends RustNode + + private val _exprKinds: Set[String] = Set( + "ARRAY_EXPR", + "ASM_EXPR", + "AWAIT_EXPR", + "BECOME_EXPR", + "BIN_EXPR", + "BLOCK_EXPR", + "BREAK_EXPR", + "CALL_EXPR", + "CAST_EXPR", + "CLOSURE_EXPR", + "CONTINUE_EXPR", + "FIELD_EXPR", + "FOR_EXPR", + "FORMAT_ARGS_EXPR", + "IF_EXPR", + "INDEX_EXPR", + "LET_EXPR", + "LITERAL", + "LOOP_EXPR", + "MACRO_EXPR", + "MATCH_EXPR", + "METHOD_CALL_EXPR", + "OFFSET_OF_EXPR", + "PAREN_EXPR", + "PATH_EXPR", + "PREFIX_EXPR", + "RANGE_EXPR", + "RECORD_EXPR", + "REF_EXPR", + "RETURN_EXPR", + "TRY_EXPR", + "TUPLE_EXPR", + "UNDERSCORE_EXPR", + "WHILE_EXPR", + "YEET_EXPR", + "YIELD_EXPR", + ) + + private val _itemKinds: Set[String] = Set( + "ASM_EXPR", + "CONST", + "ENUM", + "EXTERN_BLOCK", + "EXTERN_CRATE", + "FN", + "IMPL", + "MACRO_CALL", + "MACRO_DEF", + "MACRO_RULES", + "MODULE", + "STATIC", + "STRUCT", + "TRAIT", + "TYPE_ALIAS", + "UNION", + "USE", + ) + + private val _metaKinds: Set[String] = Set( + "CFG_ATTR_META", + "CFG_META", + "KEY_VALUE_META", + "PATH_META", + "TOKEN_TREE_META", + "UNSAFE_META", + ) + + private val _patKinds: Set[String] = Set( + "BOX_PAT", + "CONST_BLOCK_PAT", + "IDENT_PAT", + "LITERAL_PAT", + "MACRO_PAT", + "OR_PAT", + "PAREN_PAT", + "PATH_PAT", + "RANGE_PAT", + "RECORD_PAT", + "REF_PAT", + "REST_PAT", + "SLICE_PAT", + "TUPLE_PAT", + "TUPLE_STRUCT_PAT", + "WILDCARD_PAT", + ) + + private val _stmtKinds: Set[String] = Set( + "ASM_EXPR", + "CONST", + "ENUM", + "EXPR_STMT", + "EXTERN_BLOCK", + "EXTERN_CRATE", + "FN", + "IMPL", + "LET_STMT", + "MACRO_CALL", + "MACRO_DEF", + "MACRO_RULES", + "MODULE", + "STATIC", + "STRUCT", + "TRAIT", + "TYPE_ALIAS", + "UNION", + "USE", + ) + + private val _typeKinds: Set[String] = Set( + "ARRAY_TYPE", + "DYN_TRAIT_TYPE", + "FN_PTR_TYPE", + "FOR_TYPE", + "IMPL_TRAIT_TYPE", + "INFER_TYPE", + "MACRO_TYPE", + "NEVER_TYPE", + "PAREN_TYPE", + "PATH_TYPE", + "PTR_TYPE", + "REF_TYPE", + "SLICE_TYPE", + "TUPLE_TYPE", + ) + + sealed trait Expr extends RustNode + + sealed trait Item extends RustNode + + sealed trait Meta extends RustNode + + sealed trait Pat extends RustNode + + sealed trait Stmt extends RustNode + + sealed trait Type extends RustNode + + final case class Abi(json: Value) extends RustNode { + def externKwToken: ExternKwToken = createRustNode(_childrenByKind("EXTERN_KW").head).asInstanceOf[ExternKwToken] + def stringToken: Option[StringToken] = _childrenByKind.get("STRING").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StringToken]) + } + + final case class Adt(json: Value) extends RustNode { + def `enum`: Option[Enum] = _childrenByKind.get("ENUM").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Enum]) + def struct: Option[Struct] = _childrenByKind.get("STRUCT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Struct]) + def union: Option[Union] = _childrenByKind.get("UNION").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Union]) + } + + final case class ArgList(json: Value) extends RustNode { + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def expr: Seq[Expr] = _children.filter(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class ArrayExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def lBrackToken: LBrackToken = createRustNode(_childrenByKind("L_BRACK").head).asInstanceOf[LBrackToken] + def expr: Seq[Expr] = _children.filter(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def semicolonToken: Option[SemicolonToken] = _childrenByKind.get("SEMICOLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SemicolonToken]) + def rBrackToken: RBrackToken = createRustNode(_childrenByKind("R_BRACK").head).asInstanceOf[RBrackToken] + } + + final case class ArrayType(json: Value) extends RustNode with Type { + def lBrackToken: LBrackToken = createRustNode(_childrenByKind("L_BRACK").head).asInstanceOf[LBrackToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def semicolonToken: SemicolonToken = createRustNode(_childrenByKind("SEMICOLON").head).asInstanceOf[SemicolonToken] + def constArg: ConstArg = createRustNode(_childrenByKind("CONST_ARG").head).asInstanceOf[ConstArg] + def rBrackToken: RBrackToken = createRustNode(_childrenByKind("R_BRACK").head).asInstanceOf[RBrackToken] + } + + final case class AsmClobberAbi(json: Value) extends RustNode { + def clobberAbiKwToken: ClobberAbiKwToken = createRustNode(_childrenByKind("CLOBBER_ABI_KW").head).asInstanceOf[ClobberAbiKwToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def stringToken: Seq[StringToken] = _childrenByKind.getOrElse("STRING", Seq.empty).map(createRustNode(_).asInstanceOf[StringToken]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class AsmConst(json: Value) extends RustNode { + def constKwToken: ConstKwToken = createRustNode(_childrenByKind("CONST_KW").head).asInstanceOf[ConstKwToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class AsmDirSpec(json: Value) extends RustNode { + def inKwToken: Option[InKwToken] = _childrenByKind.get("IN_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[InKwToken]) + def outKwToken: Option[OutKwToken] = _childrenByKind.get("OUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[OutKwToken]) + def lateoutKwToken: Option[LateoutKwToken] = _childrenByKind.get("LATEOUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LateoutKwToken]) + def inoutKwToken: Option[InoutKwToken] = _childrenByKind.get("INOUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[InoutKwToken]) + def inlateoutKwToken: Option[InlateoutKwToken] = _childrenByKind.get("INLATEOUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[InlateoutKwToken]) + } + + final case class AsmExpr(json: Value) extends RustNode with Expr with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def builtinKwToken: BuiltinKwToken = createRustNode(_childrenByKind("BUILTIN_KW").head).asInstanceOf[BuiltinKwToken] + def poundToken: PoundToken = createRustNode(_childrenByKind("POUND").head).asInstanceOf[PoundToken] + def asmKwToken: Option[AsmKwToken] = _childrenByKind.get("ASM_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmKwToken]) + def globalAsmKwToken: Option[GlobalAsmKwToken] = _childrenByKind.get("GLOBAL_ASM_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GlobalAsmKwToken]) + def nakedAsmKwToken: Option[NakedAsmKwToken] = _childrenByKind.get("NAKED_ASM_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NakedAsmKwToken]) + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def expr: Seq[Expr] = _children.filter(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def asmPiece: Seq[AsmPiece] = _childrenByKind.getOrElse("ASM_PIECE", Seq.empty).map(createRustNode(_).asInstanceOf[AsmPiece]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class AsmLabel(json: Value) extends RustNode { + def labelKwToken: LabelKwToken = createRustNode(_childrenByKind("LABEL_KW").head).asInstanceOf[LabelKwToken] + def blockExpr: BlockExpr = createRustNode(_childrenByKind("BLOCK_EXPR").head).asInstanceOf[BlockExpr] + } + + final case class AsmOperand(json: Value) extends RustNode { + def asmRegOperand: Option[AsmRegOperand] = _childrenByKind.get("ASM_REG_OPERAND").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmRegOperand]) + def asmLabel: Option[AsmLabel] = _childrenByKind.get("ASM_LABEL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmLabel]) + def asmSym: Option[AsmSym] = _childrenByKind.get("ASM_SYM").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmSym]) + def asmConst: Option[AsmConst] = _childrenByKind.get("ASM_CONST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmConst]) + } + + final case class AsmOperandExpr(json: Value) extends RustNode { + def expr: Seq[Expr] = _children.filter(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def fatArrowToken: Option[FatArrowToken] = _childrenByKind.get("FAT_ARROW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[FatArrowToken]) + } + + final case class AsmOperandNamed(json: Value) extends RustNode { + def name: Option[Name] = _childrenByKind.get("NAME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Name]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def asmOperand: AsmOperand = createRustNode(_childrenByKind("ASM_OPERAND").head).asInstanceOf[AsmOperand] + } + + final case class AsmOption(json: Value) extends RustNode { + def pureKwToken: Option[PureKwToken] = _childrenByKind.get("PURE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PureKwToken]) + def nomemKwToken: Option[NomemKwToken] = _childrenByKind.get("NOMEM_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NomemKwToken]) + def readonlyKwToken: Option[ReadonlyKwToken] = _childrenByKind.get("READONLY_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ReadonlyKwToken]) + def preservesFlagsKwToken: Option[PreservesFlagsKwToken] = _childrenByKind.get("PRESERVES_FLAGS_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PreservesFlagsKwToken]) + def noreturnKwToken: Option[NoreturnKwToken] = _childrenByKind.get("NORETURN_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NoreturnKwToken]) + def nostackKwToken: Option[NostackKwToken] = _childrenByKind.get("NOSTACK_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NostackKwToken]) + def attSyntaxKwToken: Option[AttSyntaxKwToken] = _childrenByKind.get("ATT_SYNTAX_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AttSyntaxKwToken]) + def rawKwToken: Option[RawKwToken] = _childrenByKind.get("RAW_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RawKwToken]) + def mayUnwindKwToken: Option[MayUnwindKwToken] = _childrenByKind.get("MAY_UNWIND_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MayUnwindKwToken]) + } + + final case class AsmOptions(json: Value) extends RustNode { + def optionsKwToken: OptionsKwToken = createRustNode(_childrenByKind("OPTIONS_KW").head).asInstanceOf[OptionsKwToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def asmOption: Seq[AsmOption] = _childrenByKind.getOrElse("ASM_OPTION", Seq.empty).map(createRustNode(_).asInstanceOf[AsmOption]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class AsmPiece(json: Value) extends RustNode { + def asmOperandNamed: Option[AsmOperandNamed] = _childrenByKind.get("ASM_OPERAND_NAMED").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmOperandNamed]) + def asmClobberAbi: Option[AsmClobberAbi] = _childrenByKind.get("ASM_CLOBBER_ABI").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmClobberAbi]) + def asmOptions: Option[AsmOptions] = _childrenByKind.get("ASM_OPTIONS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsmOptions]) + } + + final case class AsmRegOperand(json: Value) extends RustNode { + def asmDirSpec: AsmDirSpec = createRustNode(_childrenByKind("ASM_DIR_SPEC").head).asInstanceOf[AsmDirSpec] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def asmRegSpec: AsmRegSpec = createRustNode(_childrenByKind("ASM_REG_SPEC").head).asInstanceOf[AsmRegSpec] + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + def asmOperandExpr: AsmOperandExpr = createRustNode(_childrenByKind("ASM_OPERAND_EXPR").head).asInstanceOf[AsmOperandExpr] + } + + final case class AsmRegSpec(json: Value) extends RustNode { + def stringToken: Option[StringToken] = _childrenByKind.get("STRING").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StringToken]) + def nameRef: Option[NameRef] = _childrenByKind.get("NAME_REF").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NameRef]) + } + + final case class AsmSym(json: Value) extends RustNode { + def symKwToken: SymKwToken = createRustNode(_childrenByKind("SYM_KW").head).asInstanceOf[SymKwToken] + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + } + + final case class AssocItem(json: Value) extends RustNode { + def const: Option[Const] = _childrenByKind.get("CONST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Const]) + def fn: Option[Fn] = _childrenByKind.get("FN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Fn]) + def macroCall: Option[MacroCall] = _childrenByKind.get("MACRO_CALL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MacroCall]) + def typeAlias: Option[TypeAlias] = _childrenByKind.get("TYPE_ALIAS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeAlias]) + } + + final case class AssocItemList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def assocItem: Seq[AssocItem] = _childrenByKind.getOrElse("ASSOC_ITEM", Seq.empty).map(createRustNode(_).asInstanceOf[AssocItem]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class AssocTypeArg(json: Value) extends RustNode { + def nameRef: NameRef = createRustNode(_childrenByKind("NAME_REF").head).asInstanceOf[NameRef] + def genericArgList: Option[GenericArgList] = _childrenByKind.get("GENERIC_ARG_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericArgList]) + def paramList: Option[ParamList] = _childrenByKind.get("PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ParamList]) + def retType: Option[RetType] = _childrenByKind.get("RET_TYPE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RetType]) + def returnTypeSyntax: Option[ReturnTypeSyntax] = _childrenByKind.get("RETURN_TYPE_SYNTAX").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ReturnTypeSyntax]) + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def typeBoundList: Option[TypeBoundList] = _childrenByKind.get("TYPE_BOUND_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeBoundList]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def constArg: Option[ConstArg] = _childrenByKind.get("CONST_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstArg]) + } + + final case class Attr(json: Value) extends RustNode { + def poundToken: PoundToken = createRustNode(_childrenByKind("POUND").head).asInstanceOf[PoundToken] + def bangToken: Option[BangToken] = _childrenByKind.get("BANG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[BangToken]) + def lBrackToken: LBrackToken = createRustNode(_childrenByKind("L_BRACK").head).asInstanceOf[LBrackToken] + def meta: Meta = createRustNode(_children.find(child => _metaKinds.contains(child("nodeKind").str)).get).asInstanceOf[Meta] + def rBrackToken: RBrackToken = createRustNode(_childrenByKind("R_BRACK").head).asInstanceOf[RBrackToken] + } + + final case class AwaitExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def dotToken: DotToken = createRustNode(_childrenByKind("DOT").head).asInstanceOf[DotToken] + def awaitKwToken: AwaitKwToken = createRustNode(_childrenByKind("AWAIT_KW").head).asInstanceOf[AwaitKwToken] + } + + final case class BecomeExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def becomeKwToken: BecomeKwToken = createRustNode(_childrenByKind("BECOME_KW").head).asInstanceOf[BecomeKwToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class BinExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Seq[Expr] = _children.filter(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def pipe2Token: Option[Pipe2Token] = _childrenByKind.get("PIPE2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Pipe2Token]) + def amp2Token: Option[Amp2Token] = _childrenByKind.get("AMP2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Amp2Token]) + def eq2Token: Option[Eq2Token] = _childrenByKind.get("EQ2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Eq2Token]) + def neqToken: Option[NeqToken] = _childrenByKind.get("NEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NeqToken]) + def lteqToken: Option[LteqToken] = _childrenByKind.get("LTEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LteqToken]) + def gteqToken: Option[GteqToken] = _childrenByKind.get("GTEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GteqToken]) + def lAngleToken: Option[LAngleToken] = _childrenByKind.get("L_ANGLE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LAngleToken]) + def rAngleToken: Option[RAngleToken] = _childrenByKind.get("R_ANGLE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RAngleToken]) + def plusToken: Option[PlusToken] = _childrenByKind.get("PLUS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PlusToken]) + def starToken: Option[StarToken] = _childrenByKind.get("STAR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StarToken]) + def minusToken: Option[MinusToken] = _childrenByKind.get("MINUS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MinusToken]) + def slashToken: Option[SlashToken] = _childrenByKind.get("SLASH").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SlashToken]) + def percentToken: Option[PercentToken] = _childrenByKind.get("PERCENT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PercentToken]) + def shlToken: Option[ShlToken] = _childrenByKind.get("SHL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ShlToken]) + def shrToken: Option[ShrToken] = _childrenByKind.get("SHR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ShrToken]) + def caretToken: Option[CaretToken] = _childrenByKind.get("CARET").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CaretToken]) + def pipeToken: Option[PipeToken] = _childrenByKind.get("PIPE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PipeToken]) + def ampToken: Option[AmpToken] = _childrenByKind.get("AMP").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AmpToken]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def pluseqToken: Option[PluseqToken] = _childrenByKind.get("PLUSEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PluseqToken]) + def slasheqToken: Option[SlasheqToken] = _childrenByKind.get("SLASHEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SlasheqToken]) + def stareqToken: Option[StareqToken] = _childrenByKind.get("STAREQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StareqToken]) + def percenteqToken: Option[PercenteqToken] = _childrenByKind.get("PERCENTEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PercenteqToken]) + def shreqToken: Option[ShreqToken] = _childrenByKind.get("SHREQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ShreqToken]) + def shleqToken: Option[ShleqToken] = _childrenByKind.get("SHLEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ShleqToken]) + def minuseqToken: Option[MinuseqToken] = _childrenByKind.get("MINUSEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MinuseqToken]) + def pipeeqToken: Option[PipeeqToken] = _childrenByKind.get("PIPEEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PipeeqToken]) + def ampeqToken: Option[AmpeqToken] = _childrenByKind.get("AMPEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AmpeqToken]) + def careteqToken: Option[CareteqToken] = _childrenByKind.get("CARETEQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CareteqToken]) + } + + final case class BlockExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def label: Option[Label] = _childrenByKind.get("LABEL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Label]) + def tryBlockModifier: Option[TryBlockModifier] = _childrenByKind.get("TRY_BLOCK_MODIFIER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TryBlockModifier]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def asyncKwToken: Option[AsyncKwToken] = _childrenByKind.get("ASYNC_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsyncKwToken]) + def moveKwToken: Option[MoveKwToken] = _childrenByKind.get("MOVE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MoveKwToken]) + def genKwToken: Option[GenKwToken] = _childrenByKind.get("GEN_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenKwToken]) + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def stmtList: StmtList = createRustNode(_childrenByKind("STMT_LIST").head).asInstanceOf[StmtList] + } + + final case class BoxPat(json: Value) extends RustNode with Pat { + def boxKwToken: BoxKwToken = createRustNode(_childrenByKind("BOX_KW").head).asInstanceOf[BoxKwToken] + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + } + + final case class BreakExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def breakKwToken: BreakKwToken = createRustNode(_childrenByKind("BREAK_KW").head).asInstanceOf[BreakKwToken] + def lifetime: Option[Lifetime] = _childrenByKind.get("LIFETIME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Lifetime]) + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + } + + final case class CallExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def argList: ArgList = createRustNode(_childrenByKind("ARG_LIST").head).asInstanceOf[ArgList] + } + + final case class CastExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def asKwToken: AsKwToken = createRustNode(_childrenByKind("AS_KW").head).asInstanceOf[AsKwToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + } + + final case class CfgAtom(json: Value) extends RustNode { + def identToken: Option[IdentToken] = _childrenByKind.get("IDENT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[IdentToken]) + def trueKwToken: Option[TrueKwToken] = _childrenByKind.get("TRUE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TrueKwToken]) + def falseKwToken: Option[FalseKwToken] = _childrenByKind.get("FALSE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[FalseKwToken]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def stringToken: Option[StringToken] = _childrenByKind.get("STRING").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StringToken]) + } + + final case class CfgAttrMeta(json: Value) extends RustNode with Meta { + def cfgAttrKwToken: CfgAttrKwToken = createRustNode(_childrenByKind("CFG_ATTR_KW").head).asInstanceOf[CfgAttrKwToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def cfgPredicate: CfgPredicate = createRustNode(_childrenByKind("CFG_PREDICATE").head).asInstanceOf[CfgPredicate] + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def meta: Seq[Meta] = _children.filter(child => _metaKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Meta]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class CfgComposite(json: Value) extends RustNode { + def identToken: IdentToken = createRustNode(_childrenByKind("IDENT").head).asInstanceOf[IdentToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def cfgPredicate: Seq[CfgPredicate] = _childrenByKind.getOrElse("CFG_PREDICATE", Seq.empty).map(createRustNode(_).asInstanceOf[CfgPredicate]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class CfgMeta(json: Value) extends RustNode with Meta { + def cfgKwToken: CfgKwToken = createRustNode(_childrenByKind("CFG_KW").head).asInstanceOf[CfgKwToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def cfgPredicate: CfgPredicate = createRustNode(_childrenByKind("CFG_PREDICATE").head).asInstanceOf[CfgPredicate] + def commaToken: Option[CommaToken] = _childrenByKind.get("COMMA").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class CfgPredicate(json: Value) extends RustNode { + def cfgAtom: Option[CfgAtom] = _childrenByKind.get("CFG_ATOM").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CfgAtom]) + def cfgComposite: Option[CfgComposite] = _childrenByKind.get("CFG_COMPOSITE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CfgComposite]) + } + + final case class ClosureExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def forBinder: Option[ForBinder] = _childrenByKind.get("FOR_BINDER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ForBinder]) + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def staticKwToken: Option[StaticKwToken] = _childrenByKind.get("STATIC_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StaticKwToken]) + def asyncKwToken: Option[AsyncKwToken] = _childrenByKind.get("ASYNC_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsyncKwToken]) + def genKwToken: Option[GenKwToken] = _childrenByKind.get("GEN_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenKwToken]) + def moveKwToken: Option[MoveKwToken] = _childrenByKind.get("MOVE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MoveKwToken]) + def paramList: ParamList = createRustNode(_childrenByKind("PARAM_LIST").head).asInstanceOf[ParamList] + def retType: Option[RetType] = _childrenByKind.get("RET_TYPE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RetType]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class Const(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def defaultKwToken: Option[DefaultKwToken] = _childrenByKind.get("DEFAULT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[DefaultKwToken]) + def constKwToken: ConstKwToken = createRustNode(_childrenByKind("CONST_KW").head).asInstanceOf[ConstKwToken] + def name: Option[Name] = _childrenByKind.get("NAME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Name]) + def underscoreToken: Option[UnderscoreToken] = _childrenByKind.get("UNDERSCORE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnderscoreToken]) + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def colonToken: ColonToken = createRustNode(_childrenByKind("COLON").head).asInstanceOf[ColonToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def semicolonToken: SemicolonToken = createRustNode(_childrenByKind("SEMICOLON").head).asInstanceOf[SemicolonToken] + } + + final case class ConstArg(json: Value) extends RustNode { + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class ConstBlockPat(json: Value) extends RustNode with Pat { + def constKwToken: ConstKwToken = createRustNode(_childrenByKind("CONST_KW").head).asInstanceOf[ConstKwToken] + def blockExpr: BlockExpr = createRustNode(_childrenByKind("BLOCK_EXPR").head).asInstanceOf[BlockExpr] + } + + final case class ConstParam(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def constKwToken: ConstKwToken = createRustNode(_childrenByKind("CONST_KW").head).asInstanceOf[ConstKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def colonToken: ColonToken = createRustNode(_childrenByKind("COLON").head).asInstanceOf[ColonToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def constArg: Option[ConstArg] = _childrenByKind.get("CONST_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstArg]) + } + + final case class ContinueExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def continueKwToken: ContinueKwToken = createRustNode(_childrenByKind("CONTINUE_KW").head).asInstanceOf[ContinueKwToken] + def lifetime: Option[Lifetime] = _childrenByKind.get("LIFETIME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Lifetime]) + } + + final case class DynTraitType(json: Value) extends RustNode with Type { + def dynKwToken: Option[DynKwToken] = _childrenByKind.get("DYN_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[DynKwToken]) + def typeBoundList: TypeBoundList = createRustNode(_childrenByKind("TYPE_BOUND_LIST").head).asInstanceOf[TypeBoundList] + } + + final case class Enum(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def enumKwToken: EnumKwToken = createRustNode(_childrenByKind("ENUM_KW").head).asInstanceOf[EnumKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def variantList: VariantList = createRustNode(_childrenByKind("VARIANT_LIST").head).asInstanceOf[VariantList] + } + + final case class ExprStmt(json: Value) extends RustNode with Stmt { + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def semicolonToken: Option[SemicolonToken] = _childrenByKind.get("SEMICOLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SemicolonToken]) + } + + final case class ExternBlock(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def abi: Abi = createRustNode(_childrenByKind("ABI").head).asInstanceOf[Abi] + def externItemList: ExternItemList = createRustNode(_childrenByKind("EXTERN_ITEM_LIST").head).asInstanceOf[ExternItemList] + } + + final case class ExternCrate(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def externKwToken: ExternKwToken = createRustNode(_childrenByKind("EXTERN_KW").head).asInstanceOf[ExternKwToken] + def crateKwToken: CrateKwToken = createRustNode(_childrenByKind("CRATE_KW").head).asInstanceOf[CrateKwToken] + def nameRef: NameRef = createRustNode(_childrenByKind("NAME_REF").head).asInstanceOf[NameRef] + def rename: Option[Rename] = _childrenByKind.get("RENAME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Rename]) + def semicolonToken: SemicolonToken = createRustNode(_childrenByKind("SEMICOLON").head).asInstanceOf[SemicolonToken] + } + + final case class ExternItem(json: Value) extends RustNode { + def fn: Option[Fn] = _childrenByKind.get("FN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Fn]) + def macroCall: Option[MacroCall] = _childrenByKind.get("MACRO_CALL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MacroCall]) + def static: Option[Static] = _childrenByKind.get("STATIC").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Static]) + def typeAlias: Option[TypeAlias] = _childrenByKind.get("TYPE_ALIAS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeAlias]) + } + + final case class ExternItemList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def externItem: Seq[ExternItem] = _childrenByKind.getOrElse("EXTERN_ITEM", Seq.empty).map(createRustNode(_).asInstanceOf[ExternItem]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class FieldExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def dotToken: DotToken = createRustNode(_childrenByKind("DOT").head).asInstanceOf[DotToken] + def nameRef: NameRef = createRustNode(_childrenByKind("NAME_REF").head).asInstanceOf[NameRef] + } + + final case class FieldList(json: Value) extends RustNode { + def recordFieldList: Option[RecordFieldList] = _childrenByKind.get("RECORD_FIELD_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RecordFieldList]) + def tupleFieldList: Option[TupleFieldList] = _childrenByKind.get("TUPLE_FIELD_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TupleFieldList]) + } + + final case class Fn(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def defaultKwToken: Option[DefaultKwToken] = _childrenByKind.get("DEFAULT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[DefaultKwToken]) + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def asyncKwToken: Option[AsyncKwToken] = _childrenByKind.get("ASYNC_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsyncKwToken]) + def genKwToken: Option[GenKwToken] = _childrenByKind.get("GEN_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenKwToken]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def safeKwToken: Option[SafeKwToken] = _childrenByKind.get("SAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SafeKwToken]) + def abi: Option[Abi] = _childrenByKind.get("ABI").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Abi]) + def fnKwToken: FnKwToken = createRustNode(_childrenByKind("FN_KW").head).asInstanceOf[FnKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def paramList: ParamList = createRustNode(_childrenByKind("PARAM_LIST").head).asInstanceOf[ParamList] + def retType: Option[RetType] = _childrenByKind.get("RET_TYPE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RetType]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def blockExpr: Option[BlockExpr] = _childrenByKind.get("BLOCK_EXPR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[BlockExpr]) + def semicolonToken: Option[SemicolonToken] = _childrenByKind.get("SEMICOLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SemicolonToken]) + } + + final case class FnPtrType(json: Value) extends RustNode with Type { + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def asyncKwToken: Option[AsyncKwToken] = _childrenByKind.get("ASYNC_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsyncKwToken]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def abi: Option[Abi] = _childrenByKind.get("ABI").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Abi]) + def fnKwToken: FnKwToken = createRustNode(_childrenByKind("FN_KW").head).asInstanceOf[FnKwToken] + def paramList: ParamList = createRustNode(_childrenByKind("PARAM_LIST").head).asInstanceOf[ParamList] + def retType: Option[RetType] = _childrenByKind.get("RET_TYPE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RetType]) + } + + final case class ForBinder(json: Value) extends RustNode { + def forKwToken: ForKwToken = createRustNode(_childrenByKind("FOR_KW").head).asInstanceOf[ForKwToken] + def genericParamList: GenericParamList = createRustNode(_childrenByKind("GENERIC_PARAM_LIST").head).asInstanceOf[GenericParamList] + } + + final case class ForExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def label: Option[Label] = _childrenByKind.get("LABEL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Label]) + def forKwToken: ForKwToken = createRustNode(_childrenByKind("FOR_KW").head).asInstanceOf[ForKwToken] + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + def inKwToken: InKwToken = createRustNode(_childrenByKind("IN_KW").head).asInstanceOf[InKwToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def blockExpr: BlockExpr = createRustNode(_childrenByKind("BLOCK_EXPR").head).asInstanceOf[BlockExpr] + } + + final case class ForType(json: Value) extends RustNode with Type { + def forBinder: ForBinder = createRustNode(_childrenByKind("FOR_BINDER").head).asInstanceOf[ForBinder] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + } + + final case class FormatArgsArg(json: Value) extends RustNode { + def formatArgsArgName: Option[FormatArgsArgName] = _childrenByKind.get("FORMAT_ARGS_ARG_NAME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[FormatArgsArgName]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class FormatArgsArgName(json: Value) extends RustNode { + def eqToken: EqToken = createRustNode(_childrenByKind("EQ").head).asInstanceOf[EqToken] + } + + final case class FormatArgsExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def builtinKwToken: BuiltinKwToken = createRustNode(_childrenByKind("BUILTIN_KW").head).asInstanceOf[BuiltinKwToken] + def poundToken: PoundToken = createRustNode(_childrenByKind("POUND").head).asInstanceOf[PoundToken] + def formatArgsKwToken: FormatArgsKwToken = createRustNode(_childrenByKind("FORMAT_ARGS_KW").head).asInstanceOf[FormatArgsKwToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def formatArgsArg: Seq[FormatArgsArg] = _childrenByKind.getOrElse("FORMAT_ARGS_ARG", Seq.empty).map(createRustNode(_).asInstanceOf[FormatArgsArg]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class GenericArg(json: Value) extends RustNode { + def typeArg: Option[TypeArg] = _childrenByKind.get("TYPE_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeArg]) + def assocTypeArg: Option[AssocTypeArg] = _childrenByKind.get("ASSOC_TYPE_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AssocTypeArg]) + def lifetimeArg: Option[LifetimeArg] = _childrenByKind.get("LIFETIME_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LifetimeArg]) + def constArg: Option[ConstArg] = _childrenByKind.get("CONST_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstArg]) + } + + final case class GenericArgList(json: Value) extends RustNode { + def colon2Token: Option[Colon2Token] = _childrenByKind.get("COLON2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Colon2Token]) + def lAngleToken: LAngleToken = createRustNode(_childrenByKind("L_ANGLE").head).asInstanceOf[LAngleToken] + def genericArg: Seq[GenericArg] = _childrenByKind.getOrElse("GENERIC_ARG", Seq.empty).map(createRustNode(_).asInstanceOf[GenericArg]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rAngleToken: RAngleToken = createRustNode(_childrenByKind("R_ANGLE").head).asInstanceOf[RAngleToken] + } + + final case class GenericParam(json: Value) extends RustNode { + def constParam: Option[ConstParam] = _childrenByKind.get("CONST_PARAM").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstParam]) + def lifetimeParam: Option[LifetimeParam] = _childrenByKind.get("LIFETIME_PARAM").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LifetimeParam]) + def typeParam: Option[TypeParam] = _childrenByKind.get("TYPE_PARAM").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeParam]) + } + + final case class GenericParamList(json: Value) extends RustNode { + def lAngleToken: LAngleToken = createRustNode(_childrenByKind("L_ANGLE").head).asInstanceOf[LAngleToken] + def genericParam: Seq[GenericParam] = _childrenByKind.getOrElse("GENERIC_PARAM", Seq.empty).map(createRustNode(_).asInstanceOf[GenericParam]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rAngleToken: RAngleToken = createRustNode(_childrenByKind("R_ANGLE").head).asInstanceOf[RAngleToken] + } + + final case class IdentPat(json: Value) extends RustNode with Pat { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def refKwToken: Option[RefKwToken] = _childrenByKind.get("REF_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RefKwToken]) + def mutKwToken: Option[MutKwToken] = _childrenByKind.get("MUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MutKwToken]) + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def atToken: Option[AtToken] = _childrenByKind.get("AT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AtToken]) + def pat: Option[Pat] = _children.find(child => _patKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Pat]) + } + + final case class IfExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def ifKwToken: IfKwToken = createRustNode(_childrenByKind("IF_KW").head).asInstanceOf[IfKwToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def blockExpr: Seq[BlockExpr] = _childrenByKind.getOrElse("BLOCK_EXPR", Seq.empty).map(createRustNode(_).asInstanceOf[BlockExpr]) + def elseKwToken: Option[ElseKwToken] = _childrenByKind.get("ELSE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ElseKwToken]) + def ifExpr: Option[IfExpr] = _childrenByKind.get("IF_EXPR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[IfExpr]) + } + + final case class Impl(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def defaultKwToken: Option[DefaultKwToken] = _childrenByKind.get("DEFAULT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[DefaultKwToken]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def implKwToken: ImplKwToken = createRustNode(_childrenByKind("IMPL_KW").head).asInstanceOf[ImplKwToken] + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def bangToken: Option[BangToken] = _childrenByKind.get("BANG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[BangToken]) + def `type`: Seq[Type] = _children.filter(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def forKwToken: Option[ForKwToken] = _childrenByKind.get("FOR_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ForKwToken]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def assocItemList: AssocItemList = createRustNode(_childrenByKind("ASSOC_ITEM_LIST").head).asInstanceOf[AssocItemList] + } + + final case class ImplTraitType(json: Value) extends RustNode with Type { + def implKwToken: ImplKwToken = createRustNode(_childrenByKind("IMPL_KW").head).asInstanceOf[ImplKwToken] + def typeBoundList: TypeBoundList = createRustNode(_childrenByKind("TYPE_BOUND_LIST").head).asInstanceOf[TypeBoundList] + } + + final case class IndexExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Seq[Expr] = _children.filter(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def lBrackToken: LBrackToken = createRustNode(_childrenByKind("L_BRACK").head).asInstanceOf[LBrackToken] + def rBrackToken: RBrackToken = createRustNode(_childrenByKind("R_BRACK").head).asInstanceOf[RBrackToken] + } + + final case class InferType(json: Value) extends RustNode with Type { + def underscoreToken: UnderscoreToken = createRustNode(_childrenByKind("UNDERSCORE").head).asInstanceOf[UnderscoreToken] + } + + final case class ItemList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def item: Seq[Item] = _children.filter(child => _itemKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Item]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class KeyValueMeta(json: Value) extends RustNode with Meta { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + def eqToken: EqToken = createRustNode(_childrenByKind("EQ").head).asInstanceOf[EqToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class Label(json: Value) extends RustNode { + def lifetime: Lifetime = createRustNode(_childrenByKind("LIFETIME").head).asInstanceOf[Lifetime] + def colonToken: ColonToken = createRustNode(_childrenByKind("COLON").head).asInstanceOf[ColonToken] + } + + final case class LetElse(json: Value) extends RustNode { + def elseKwToken: ElseKwToken = createRustNode(_childrenByKind("ELSE_KW").head).asInstanceOf[ElseKwToken] + def blockExpr: BlockExpr = createRustNode(_childrenByKind("BLOCK_EXPR").head).asInstanceOf[BlockExpr] + } + + final case class LetExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def letKwToken: LetKwToken = createRustNode(_childrenByKind("LET_KW").head).asInstanceOf[LetKwToken] + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + def eqToken: EqToken = createRustNode(_childrenByKind("EQ").head).asInstanceOf[EqToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class LetStmt(json: Value) extends RustNode with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def superKwToken: Option[SuperKwToken] = _childrenByKind.get("SUPER_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SuperKwToken]) + def letKwToken: LetKwToken = createRustNode(_childrenByKind("LET_KW").head).asInstanceOf[LetKwToken] + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def eqToken: EqToken = createRustNode(_childrenByKind("EQ").head).asInstanceOf[EqToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def letElse: Option[LetElse] = _childrenByKind.get("LET_ELSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LetElse]) + def semicolonToken: SemicolonToken = createRustNode(_childrenByKind("SEMICOLON").head).asInstanceOf[SemicolonToken] + } + + final case class Lifetime(json: Value) extends RustNode { + def lifetimeIdentToken: LifetimeIdentToken = createRustNode(_childrenByKind("LIFETIME_IDENT").head).asInstanceOf[LifetimeIdentToken] + } + + final case class LifetimeArg(json: Value) extends RustNode { + def lifetime: Lifetime = createRustNode(_childrenByKind("LIFETIME").head).asInstanceOf[Lifetime] + } + + final case class LifetimeParam(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def lifetime: Lifetime = createRustNode(_childrenByKind("LIFETIME").head).asInstanceOf[Lifetime] + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def typeBoundList: Option[TypeBoundList] = _childrenByKind.get("TYPE_BOUND_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeBoundList]) + } + + final case class Literal(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def intNumberToken: Option[IntNumberToken] = _childrenByKind.get("INT_NUMBER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[IntNumberToken]) + def floatNumberToken: Option[FloatNumberToken] = _childrenByKind.get("FLOAT_NUMBER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[FloatNumberToken]) + def stringToken: Option[StringToken] = _childrenByKind.get("STRING").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StringToken]) + def byteStringToken: Option[ByteStringToken] = _childrenByKind.get("BYTE_STRING").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ByteStringToken]) + def cStringToken: Option[CStringToken] = _childrenByKind.get("C_STRING").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CStringToken]) + def charToken: Option[CharToken] = _childrenByKind.get("CHAR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CharToken]) + def byteToken: Option[ByteToken] = _childrenByKind.get("BYTE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ByteToken]) + def trueKwToken: Option[TrueKwToken] = _childrenByKind.get("TRUE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TrueKwToken]) + def falseKwToken: Option[FalseKwToken] = _childrenByKind.get("FALSE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[FalseKwToken]) + } + + final case class LiteralPat(json: Value) extends RustNode with Pat { + def minusToken: Option[MinusToken] = _childrenByKind.get("MINUS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MinusToken]) + def literal: Literal = createRustNode(_childrenByKind("LITERAL").head).asInstanceOf[Literal] + } + + final case class LoopExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def label: Option[Label] = _childrenByKind.get("LABEL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Label]) + def loopKwToken: LoopKwToken = createRustNode(_childrenByKind("LOOP_KW").head).asInstanceOf[LoopKwToken] + def blockExpr: BlockExpr = createRustNode(_childrenByKind("BLOCK_EXPR").head).asInstanceOf[BlockExpr] + } + + final case class MacroCall(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + def bangToken: BangToken = createRustNode(_childrenByKind("BANG").head).asInstanceOf[BangToken] + def tokenTree: TokenTree = createRustNode(_childrenByKind("TOKEN_TREE").head).asInstanceOf[TokenTree] + def semicolonToken: Option[SemicolonToken] = _childrenByKind.get("SEMICOLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SemicolonToken]) + } + + final case class MacroDef(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def macroKwToken: MacroKwToken = createRustNode(_childrenByKind("MACRO_KW").head).asInstanceOf[MacroKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def tokenTree: Seq[TokenTree] = _childrenByKind.getOrElse("TOKEN_TREE", Seq.empty).map(createRustNode(_).asInstanceOf[TokenTree]) + } + + final case class MacroExpr(json: Value) extends RustNode with Expr { + def macroCall: MacroCall = createRustNode(_childrenByKind("MACRO_CALL").head).asInstanceOf[MacroCall] + } + + final case class MacroItems(json: Value) extends RustNode { + def item: Seq[Item] = _children.filter(child => _itemKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Item]) + } + + final case class MacroPat(json: Value) extends RustNode with Pat { + def macroCall: MacroCall = createRustNode(_childrenByKind("MACRO_CALL").head).asInstanceOf[MacroCall] + } + + final case class MacroRules(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def macroRulesKwToken: MacroRulesKwToken = createRustNode(_childrenByKind("MACRO_RULES_KW").head).asInstanceOf[MacroRulesKwToken] + def bangToken: BangToken = createRustNode(_childrenByKind("BANG").head).asInstanceOf[BangToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def tokenTree: TokenTree = createRustNode(_childrenByKind("TOKEN_TREE").head).asInstanceOf[TokenTree] + } + + final case class MacroStmts(json: Value) extends RustNode { + def stmt: Seq[Stmt] = _children.filter(child => _stmtKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Stmt]) + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + } + + final case class MacroType(json: Value) extends RustNode with Type { + def macroCall: MacroCall = createRustNode(_childrenByKind("MACRO_CALL").head).asInstanceOf[MacroCall] + } + + final case class MatchArm(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + def matchGuard: Option[MatchGuard] = _childrenByKind.get("MATCH_GUARD").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MatchGuard]) + def fatArrowToken: FatArrowToken = createRustNode(_childrenByKind("FAT_ARROW").head).asInstanceOf[FatArrowToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def commaToken: Option[CommaToken] = _childrenByKind.get("COMMA").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CommaToken]) + } + + final case class MatchArmList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def matchArm: Seq[MatchArm] = _childrenByKind.getOrElse("MATCH_ARM", Seq.empty).map(createRustNode(_).asInstanceOf[MatchArm]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class MatchExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def matchKwToken: MatchKwToken = createRustNode(_childrenByKind("MATCH_KW").head).asInstanceOf[MatchKwToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def matchArmList: MatchArmList = createRustNode(_childrenByKind("MATCH_ARM_LIST").head).asInstanceOf[MatchArmList] + } + + final case class MatchGuard(json: Value) extends RustNode { + def ifKwToken: IfKwToken = createRustNode(_childrenByKind("IF_KW").head).asInstanceOf[IfKwToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class MethodCallExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def dotToken: DotToken = createRustNode(_childrenByKind("DOT").head).asInstanceOf[DotToken] + def nameRef: NameRef = createRustNode(_childrenByKind("NAME_REF").head).asInstanceOf[NameRef] + def genericArgList: Option[GenericArgList] = _childrenByKind.get("GENERIC_ARG_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericArgList]) + def argList: ArgList = createRustNode(_childrenByKind("ARG_LIST").head).asInstanceOf[ArgList] + } + + final case class Module(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def modKwToken: ModKwToken = createRustNode(_childrenByKind("MOD_KW").head).asInstanceOf[ModKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def itemList: Option[ItemList] = _childrenByKind.get("ITEM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ItemList]) + def semicolonToken: Option[SemicolonToken] = _childrenByKind.get("SEMICOLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SemicolonToken]) + } + + final case class Name(json: Value) extends RustNode { + def identToken: Option[IdentToken] = _childrenByKind.get("IDENT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[IdentToken]) + def selfKwToken: Option[SelfKwToken] = _childrenByKind.get("SELF_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SelfKwToken]) + } + + final case class NameRef(json: Value) extends RustNode { + def identToken: Option[IdentToken] = _childrenByKind.get("IDENT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[IdentToken]) + def intNumberToken: Option[IntNumberToken] = _childrenByKind.get("INT_NUMBER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[IntNumberToken]) + def selfKwToken: Option[SelfKwToken] = _childrenByKind.get("SELF_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SelfKwToken]) + def superKwToken: Option[SuperKwToken] = _childrenByKind.get("SUPER_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SuperKwToken]) + def crateKwToken: Option[CrateKwToken] = _childrenByKind.get("CRATE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[CrateKwToken]) + def selfTypeKwToken: Option[SelfTypeKwToken] = _childrenByKind.get("SELF_TYPE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SelfTypeKwToken]) + } + + final case class NeverType(json: Value) extends RustNode with Type { + def bangToken: BangToken = createRustNode(_childrenByKind("BANG").head).asInstanceOf[BangToken] + } + + final case class OffsetOfExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def builtinKwToken: BuiltinKwToken = createRustNode(_childrenByKind("BUILTIN_KW").head).asInstanceOf[BuiltinKwToken] + def poundToken: PoundToken = createRustNode(_childrenByKind("POUND").head).asInstanceOf[PoundToken] + def offsetOfKwToken: OffsetOfKwToken = createRustNode(_childrenByKind("OFFSET_OF_KW").head).asInstanceOf[OffsetOfKwToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def commaToken: CommaToken = createRustNode(_childrenByKind("COMMA").head).asInstanceOf[CommaToken] + def nameRef: Seq[NameRef] = _childrenByKind.getOrElse("NAME_REF", Seq.empty).map(createRustNode(_).asInstanceOf[NameRef]) + def dotToken: Seq[DotToken] = _childrenByKind.getOrElse("DOT", Seq.empty).map(createRustNode(_).asInstanceOf[DotToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class OrPat(json: Value) extends RustNode with Pat { + def pipeToken: Seq[PipeToken] = _childrenByKind.getOrElse("PIPE", Seq.empty).map(createRustNode(_).asInstanceOf[PipeToken]) + def pat: Seq[Pat] = _children.filter(child => _patKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Pat]) + } + + final case class Param(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def pat: Option[Pat] = _children.find(child => _patKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Pat]) + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def dot3Token: Option[Dot3Token] = _childrenByKind.get("DOT3").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Dot3Token]) + } + + final case class ParamList(json: Value) extends RustNode { + def lParenToken: Option[LParenToken] = _childrenByKind.get("L_PAREN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LParenToken]) + def selfParam: Option[SelfParam] = _childrenByKind.get("SELF_PARAM").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SelfParam]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def param: Seq[Param] = _childrenByKind.getOrElse("PARAM", Seq.empty).map(createRustNode(_).asInstanceOf[Param]) + def rParenToken: Option[RParenToken] = _childrenByKind.get("R_PAREN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RParenToken]) + def pipeToken: Seq[PipeToken] = _childrenByKind.getOrElse("PIPE", Seq.empty).map(createRustNode(_).asInstanceOf[PipeToken]) + } + + final case class ParenExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class ParenPat(json: Value) extends RustNode with Pat { + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class ParenType(json: Value) extends RustNode with Type { + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class ParenthesizedArgList(json: Value) extends RustNode { + def colon2Token: Option[Colon2Token] = _childrenByKind.get("COLON2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Colon2Token]) + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def typeArg: Seq[TypeArg] = _childrenByKind.getOrElse("TYPE_ARG", Seq.empty).map(createRustNode(_).asInstanceOf[TypeArg]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class Path(json: Value) extends RustNode { + def path: Option[Path] = _childrenByKind.get("PATH").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Path]) + def colon2Token: Option[Colon2Token] = _childrenByKind.get("COLON2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Colon2Token]) + def pathSegment: PathSegment = createRustNode(_childrenByKind("PATH_SEGMENT").head).asInstanceOf[PathSegment] + } + + final case class PathExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + } + + final case class PathMeta(json: Value) extends RustNode with Meta { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + } + + final case class PathPat(json: Value) extends RustNode with Pat { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + } + + final case class PathSegment(json: Value) extends RustNode { + def colon2Token: Option[Colon2Token] = _childrenByKind.get("COLON2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Colon2Token]) + def nameRef: Option[NameRef] = _childrenByKind.get("NAME_REF").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NameRef]) + def genericArgList: Option[GenericArgList] = _childrenByKind.get("GENERIC_ARG_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericArgList]) + def parenthesizedArgList: Option[ParenthesizedArgList] = _childrenByKind.get("PARENTHESIZED_ARG_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ParenthesizedArgList]) + def retType: Option[RetType] = _childrenByKind.get("RET_TYPE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RetType]) + def returnTypeSyntax: Option[ReturnTypeSyntax] = _childrenByKind.get("RETURN_TYPE_SYNTAX").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ReturnTypeSyntax]) + def typeAnchor: Option[TypeAnchor] = _childrenByKind.get("TYPE_ANCHOR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeAnchor]) + } + + final case class PathType(json: Value) extends RustNode with Type { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + } + + final case class PrefixExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def minusToken: Option[MinusToken] = _childrenByKind.get("MINUS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MinusToken]) + def bangToken: Option[BangToken] = _childrenByKind.get("BANG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[BangToken]) + def starToken: Option[StarToken] = _childrenByKind.get("STAR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StarToken]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class PtrType(json: Value) extends RustNode with Type { + def starToken: StarToken = createRustNode(_childrenByKind("STAR").head).asInstanceOf[StarToken] + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def mutKwToken: Option[MutKwToken] = _childrenByKind.get("MUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MutKwToken]) + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + } + + final case class RangeExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def dot2Token: Option[Dot2Token] = _childrenByKind.get("DOT2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Dot2Token]) + def dot2eqToken: Option[Dot2eqToken] = _childrenByKind.get("DOT2EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Dot2eqToken]) + } + + final case class RangePat(json: Value) extends RustNode with Pat { + def pat: Seq[Pat] = _children.filter(child => _patKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Pat]) + def dot2Token: Option[Dot2Token] = _childrenByKind.get("DOT2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Dot2Token]) + def dot2eqToken: Option[Dot2eqToken] = _childrenByKind.get("DOT2EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Dot2eqToken]) + } + + final case class RecordExpr(json: Value) extends RustNode with Expr { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + def recordExprFieldList: RecordExprFieldList = createRustNode(_childrenByKind("RECORD_EXPR_FIELD_LIST").head).asInstanceOf[RecordExprFieldList] + } + + final case class RecordExprField(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def nameRef: Option[NameRef] = _childrenByKind.get("NAME_REF").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NameRef]) + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class RecordExprFieldList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def recordExprField: Seq[RecordExprField] = _childrenByKind.getOrElse("RECORD_EXPR_FIELD", Seq.empty).map(createRustNode(_).asInstanceOf[RecordExprField]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def dot2Token: Option[Dot2Token] = _childrenByKind.get("DOT2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Dot2Token]) + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class RecordField(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def colonToken: ColonToken = createRustNode(_childrenByKind("COLON").head).asInstanceOf[ColonToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def constArg: Option[ConstArg] = _childrenByKind.get("CONST_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstArg]) + } + + final case class RecordFieldList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def recordField: Seq[RecordField] = _childrenByKind.getOrElse("RECORD_FIELD", Seq.empty).map(createRustNode(_).asInstanceOf[RecordField]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class RecordPat(json: Value) extends RustNode with Pat { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + def recordPatFieldList: RecordPatFieldList = createRustNode(_childrenByKind("RECORD_PAT_FIELD_LIST").head).asInstanceOf[RecordPatFieldList] + } + + final case class RecordPatField(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def nameRef: Option[NameRef] = _childrenByKind.get("NAME_REF").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NameRef]) + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + } + + final case class RecordPatFieldList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def recordPatField: Seq[RecordPatField] = _childrenByKind.getOrElse("RECORD_PAT_FIELD", Seq.empty).map(createRustNode(_).asInstanceOf[RecordPatField]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def restPat: Option[RestPat] = _childrenByKind.get("REST_PAT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RestPat]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class RefExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def ampToken: AmpToken = createRustNode(_childrenByKind("AMP").head).asInstanceOf[AmpToken] + def rawKwToken: Option[RawKwToken] = _childrenByKind.get("RAW_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RawKwToken]) + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def mutKwToken: Option[MutKwToken] = _childrenByKind.get("MUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MutKwToken]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + } + + final case class RefPat(json: Value) extends RustNode with Pat { + def ampToken: AmpToken = createRustNode(_childrenByKind("AMP").head).asInstanceOf[AmpToken] + def mutKwToken: Option[MutKwToken] = _childrenByKind.get("MUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MutKwToken]) + def pat: Pat = createRustNode(_children.find(child => _patKinds.contains(child("nodeKind").str)).get).asInstanceOf[Pat] + } + + final case class RefType(json: Value) extends RustNode with Type { + def ampToken: AmpToken = createRustNode(_childrenByKind("AMP").head).asInstanceOf[AmpToken] + def lifetime: Option[Lifetime] = _childrenByKind.get("LIFETIME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Lifetime]) + def mutKwToken: Option[MutKwToken] = _childrenByKind.get("MUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MutKwToken]) + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + } + + final case class Rename(json: Value) extends RustNode { + def asKwToken: AsKwToken = createRustNode(_childrenByKind("AS_KW").head).asInstanceOf[AsKwToken] + def name: Option[Name] = _childrenByKind.get("NAME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Name]) + def underscoreToken: Option[UnderscoreToken] = _childrenByKind.get("UNDERSCORE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnderscoreToken]) + } + + final case class RestPat(json: Value) extends RustNode with Pat { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def dot2Token: Dot2Token = createRustNode(_childrenByKind("DOT2").head).asInstanceOf[Dot2Token] + } + + final case class RetType(json: Value) extends RustNode { + def thinArrowToken: ThinArrowToken = createRustNode(_childrenByKind("THIN_ARROW").head).asInstanceOf[ThinArrowToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + } + + final case class ReturnExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def returnKwToken: ReturnKwToken = createRustNode(_childrenByKind("RETURN_KW").head).asInstanceOf[ReturnKwToken] + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + } + + final case class ReturnTypeSyntax(json: Value) extends RustNode { + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def dot2Token: Dot2Token = createRustNode(_childrenByKind("DOT2").head).asInstanceOf[Dot2Token] + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class SelfParam(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def ampToken: Option[AmpToken] = _childrenByKind.get("AMP").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AmpToken]) + def lifetime: Option[Lifetime] = _childrenByKind.get("LIFETIME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Lifetime]) + def mutKwToken: Option[MutKwToken] = _childrenByKind.get("MUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MutKwToken]) + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + } + + final case class SlicePat(json: Value) extends RustNode with Pat { + def lBrackToken: LBrackToken = createRustNode(_childrenByKind("L_BRACK").head).asInstanceOf[LBrackToken] + def pat: Seq[Pat] = _children.filter(child => _patKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Pat]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rBrackToken: RBrackToken = createRustNode(_childrenByKind("R_BRACK").head).asInstanceOf[RBrackToken] + } + + final case class SliceType(json: Value) extends RustNode with Type { + def lBrackToken: LBrackToken = createRustNode(_childrenByKind("L_BRACK").head).asInstanceOf[LBrackToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def rBrackToken: RBrackToken = createRustNode(_childrenByKind("R_BRACK").head).asInstanceOf[RBrackToken] + } + + final case class SourceFile(json: Value) extends RustNode { + def shebangToken: Option[ShebangToken] = _childrenByKind.get("SHEBANG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ShebangToken]) + def frontmatterToken: Option[FrontmatterToken] = _childrenByKind.get("FRONTMATTER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[FrontmatterToken]) + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def item: Seq[Item] = _children.filter(child => _itemKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Item]) + } + + final case class Static(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def safeKwToken: Option[SafeKwToken] = _childrenByKind.get("SAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SafeKwToken]) + def staticKwToken: StaticKwToken = createRustNode(_childrenByKind("STATIC_KW").head).asInstanceOf[StaticKwToken] + def mutKwToken: Option[MutKwToken] = _childrenByKind.get("MUT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[MutKwToken]) + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def colonToken: ColonToken = createRustNode(_childrenByKind("COLON").head).asInstanceOf[ColonToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def semicolonToken: SemicolonToken = createRustNode(_childrenByKind("SEMICOLON").head).asInstanceOf[SemicolonToken] + } + + final case class StmtList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def stmt: Seq[Stmt] = _children.filter(child => _stmtKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Stmt]) + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class Struct(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def structKwToken: StructKwToken = createRustNode(_childrenByKind("STRUCT_KW").head).asInstanceOf[StructKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def recordFieldList: Option[RecordFieldList] = _childrenByKind.get("RECORD_FIELD_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RecordFieldList]) + def semicolonToken: Option[SemicolonToken] = _childrenByKind.get("SEMICOLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SemicolonToken]) + def tupleFieldList: Option[TupleFieldList] = _childrenByKind.get("TUPLE_FIELD_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TupleFieldList]) + } + + final case class TokenTree(json: Value) extends RustNode { + def lParenToken: Option[LParenToken] = _childrenByKind.get("L_PAREN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LParenToken]) + def rParenToken: Option[RParenToken] = _childrenByKind.get("R_PAREN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RParenToken]) + def lCurlyToken: Option[LCurlyToken] = _childrenByKind.get("L_CURLY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LCurlyToken]) + def rCurlyToken: Option[RCurlyToken] = _childrenByKind.get("R_CURLY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RCurlyToken]) + def lBrackToken: Option[LBrackToken] = _childrenByKind.get("L_BRACK").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LBrackToken]) + def rBrackToken: Option[RBrackToken] = _childrenByKind.get("R_BRACK").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RBrackToken]) + } + + final case class TokenTreeMeta(json: Value) extends RustNode with Meta { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + def tokenTree: TokenTree = createRustNode(_childrenByKind("TOKEN_TREE").head).asInstanceOf[TokenTree] + } + + final case class Trait(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def unsafeKwToken: Option[UnsafeKwToken] = _childrenByKind.get("UNSAFE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UnsafeKwToken]) + def autoKwToken: Option[AutoKwToken] = _childrenByKind.get("AUTO_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AutoKwToken]) + def traitKwToken: TraitKwToken = createRustNode(_childrenByKind("TRAIT_KW").head).asInstanceOf[TraitKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def typeBoundList: Option[TypeBoundList] = _childrenByKind.get("TYPE_BOUND_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeBoundList]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def assocItemList: Option[AssocItemList] = _childrenByKind.get("ASSOC_ITEM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AssocItemList]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def semicolonToken: Option[SemicolonToken] = _childrenByKind.get("SEMICOLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[SemicolonToken]) + } + + final case class TryBlockModifier(json: Value) extends RustNode { + def tryKwToken: TryKwToken = createRustNode(_childrenByKind("TRY_KW").head).asInstanceOf[TryKwToken] + def bikeshedKwToken: Option[BikeshedKwToken] = _childrenByKind.get("BIKESHED_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[BikeshedKwToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + } + + final case class TryExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def questionToken: QuestionToken = createRustNode(_childrenByKind("QUESTION").head).asInstanceOf[QuestionToken] + } + + final case class TupleExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def expr: Seq[Expr] = _children.filter(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class TupleField(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + } + + final case class TupleFieldList(json: Value) extends RustNode { + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def tupleField: Seq[TupleField] = _childrenByKind.getOrElse("TUPLE_FIELD", Seq.empty).map(createRustNode(_).asInstanceOf[TupleField]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class TuplePat(json: Value) extends RustNode with Pat { + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def pat: Seq[Pat] = _children.filter(child => _patKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Pat]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class TupleStructPat(json: Value) extends RustNode with Pat { + def path: Path = createRustNode(_childrenByKind("PATH").head).asInstanceOf[Path] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def pat: Seq[Pat] = _children.filter(child => _patKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Pat]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class TupleType(json: Value) extends RustNode with Type { + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def `type`: Seq[Type] = _children.filter(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class TypeAlias(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def defaultKwToken: Option[DefaultKwToken] = _childrenByKind.get("DEFAULT_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[DefaultKwToken]) + def typeKwToken: TypeKwToken = createRustNode(_childrenByKind("TYPE_KW").head).asInstanceOf[TypeKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def typeBoundList: Option[TypeBoundList] = _childrenByKind.get("TYPE_BOUND_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeBoundList]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def semicolonToken: SemicolonToken = createRustNode(_childrenByKind("SEMICOLON").head).asInstanceOf[SemicolonToken] + } + + final case class TypeAnchor(json: Value) extends RustNode { + def lAngleToken: LAngleToken = createRustNode(_childrenByKind("L_ANGLE").head).asInstanceOf[LAngleToken] + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + def asKwToken: Option[AsKwToken] = _childrenByKind.get("AS_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsKwToken]) + def pathType: Option[PathType] = _childrenByKind.get("PATH_TYPE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[PathType]) + def rAngleToken: RAngleToken = createRustNode(_childrenByKind("R_ANGLE").head).asInstanceOf[RAngleToken] + } + + final case class TypeArg(json: Value) extends RustNode { + def `type`: Type = createRustNode(_children.find(child => _typeKinds.contains(child("nodeKind").str)).get).asInstanceOf[Type] + } + + final case class TypeBound(json: Value) extends RustNode { + def lifetime: Option[Lifetime] = _childrenByKind.get("LIFETIME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Lifetime]) + def forBinder: Option[ForBinder] = _childrenByKind.get("FOR_BINDER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ForBinder]) + def tildeToken: Option[TildeToken] = _childrenByKind.get("TILDE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TildeToken]) + def constKwToken: Option[ConstKwToken] = _childrenByKind.get("CONST_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstKwToken]) + def lBrackToken: Option[LBrackToken] = _childrenByKind.get("L_BRACK").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LBrackToken]) + def rBrackToken: Option[RBrackToken] = _childrenByKind.get("R_BRACK").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RBrackToken]) + def asyncKwToken: Option[AsyncKwToken] = _childrenByKind.get("ASYNC_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[AsyncKwToken]) + def questionToken: Option[QuestionToken] = _childrenByKind.get("QUESTION").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[QuestionToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def useKwToken: Option[UseKwToken] = _childrenByKind.get("USE_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UseKwToken]) + def useBoundGenericArgs: Option[UseBoundGenericArgs] = _childrenByKind.get("USE_BOUND_GENERIC_ARGS").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UseBoundGenericArgs]) + } + + final case class TypeBoundList(json: Value) extends RustNode { + def typeBound: Seq[TypeBound] = _childrenByKind.getOrElse("TYPE_BOUND", Seq.empty).map(createRustNode(_).asInstanceOf[TypeBound]) + def plusToken: Seq[PlusToken] = _childrenByKind.getOrElse("PLUS", Seq.empty).map(createRustNode(_).asInstanceOf[PlusToken]) + } + + final case class TypeParam(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def colonToken: Option[ColonToken] = _childrenByKind.get("COLON").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ColonToken]) + def typeBoundList: Option[TypeBoundList] = _childrenByKind.get("TYPE_BOUND_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeBoundList]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + } + + final case class UnderscoreExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def underscoreToken: UnderscoreToken = createRustNode(_childrenByKind("UNDERSCORE").head).asInstanceOf[UnderscoreToken] + } + + final case class Union(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def unionKwToken: UnionKwToken = createRustNode(_childrenByKind("UNION_KW").head).asInstanceOf[UnionKwToken] + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def genericParamList: Option[GenericParamList] = _childrenByKind.get("GENERIC_PARAM_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[GenericParamList]) + def whereClause: Option[WhereClause] = _childrenByKind.get("WHERE_CLAUSE").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[WhereClause]) + def recordFieldList: RecordFieldList = createRustNode(_childrenByKind("RECORD_FIELD_LIST").head).asInstanceOf[RecordFieldList] + } + + final case class UnsafeMeta(json: Value) extends RustNode with Meta { + def unsafeKwToken: UnsafeKwToken = createRustNode(_childrenByKind("UNSAFE_KW").head).asInstanceOf[UnsafeKwToken] + def lParenToken: LParenToken = createRustNode(_childrenByKind("L_PAREN").head).asInstanceOf[LParenToken] + def meta: Meta = createRustNode(_children.find(child => _metaKinds.contains(child("nodeKind").str)).get).asInstanceOf[Meta] + def rParenToken: RParenToken = createRustNode(_childrenByKind("R_PAREN").head).asInstanceOf[RParenToken] + } + + final case class Use(json: Value) extends RustNode with Item with Stmt { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def useKwToken: UseKwToken = createRustNode(_childrenByKind("USE_KW").head).asInstanceOf[UseKwToken] + def useTree: UseTree = createRustNode(_childrenByKind("USE_TREE").head).asInstanceOf[UseTree] + def semicolonToken: SemicolonToken = createRustNode(_childrenByKind("SEMICOLON").head).asInstanceOf[SemicolonToken] + } + + final case class UseBoundGenericArg(json: Value) extends RustNode { + def lifetime: Option[Lifetime] = _childrenByKind.get("LIFETIME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Lifetime]) + def nameRef: Option[NameRef] = _childrenByKind.get("NAME_REF").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[NameRef]) + } + + final case class UseBoundGenericArgs(json: Value) extends RustNode { + def lAngleToken: LAngleToken = createRustNode(_childrenByKind("L_ANGLE").head).asInstanceOf[LAngleToken] + def useBoundGenericArg: Seq[UseBoundGenericArg] = _childrenByKind.getOrElse("USE_BOUND_GENERIC_ARG", Seq.empty).map(createRustNode(_).asInstanceOf[UseBoundGenericArg]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rAngleToken: RAngleToken = createRustNode(_childrenByKind("R_ANGLE").head).asInstanceOf[RAngleToken] + } + + final case class UseTree(json: Value) extends RustNode { + def path: Option[Path] = _childrenByKind.get("PATH").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Path]) + def colon2Token: Option[Colon2Token] = _childrenByKind.get("COLON2").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Colon2Token]) + def starToken: Option[StarToken] = _childrenByKind.get("STAR").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[StarToken]) + def useTreeList: Option[UseTreeList] = _childrenByKind.get("USE_TREE_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[UseTreeList]) + def rename: Option[Rename] = _childrenByKind.get("RENAME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Rename]) + } + + final case class UseTreeList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def useTree: Seq[UseTree] = _childrenByKind.getOrElse("USE_TREE", Seq.empty).map(createRustNode(_).asInstanceOf[UseTree]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class Variant(json: Value) extends RustNode { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def visibility: Option[Visibility] = _childrenByKind.get("VISIBILITY").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Visibility]) + def name: Name = createRustNode(_childrenByKind("NAME").head).asInstanceOf[Name] + def fieldList: Option[FieldList] = _childrenByKind.get("FIELD_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[FieldList]) + def eqToken: Option[EqToken] = _childrenByKind.get("EQ").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[EqToken]) + def constArg: Option[ConstArg] = _childrenByKind.get("CONST_ARG").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ConstArg]) + } + + final case class VariantDef(json: Value) extends RustNode { + def struct: Option[Struct] = _childrenByKind.get("STRUCT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Struct]) + def union: Option[Union] = _childrenByKind.get("UNION").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Union]) + def variant: Option[Variant] = _childrenByKind.get("VARIANT").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Variant]) + } + + final case class VariantList(json: Value) extends RustNode { + def lCurlyToken: LCurlyToken = createRustNode(_childrenByKind("L_CURLY").head).asInstanceOf[LCurlyToken] + def variant: Seq[Variant] = _childrenByKind.getOrElse("VARIANT", Seq.empty).map(createRustNode(_).asInstanceOf[Variant]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + def rCurlyToken: RCurlyToken = createRustNode(_childrenByKind("R_CURLY").head).asInstanceOf[RCurlyToken] + } + + final case class Visibility(json: Value) extends RustNode { + def pubKwToken: PubKwToken = createRustNode(_childrenByKind("PUB_KW").head).asInstanceOf[PubKwToken] + def lParenToken: Option[LParenToken] = _childrenByKind.get("L_PAREN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[LParenToken]) + def inKwToken: Option[InKwToken] = _childrenByKind.get("IN_KW").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[InKwToken]) + def path: Option[Path] = _childrenByKind.get("PATH").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Path]) + def rParenToken: Option[RParenToken] = _childrenByKind.get("R_PAREN").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[RParenToken]) + } + + final case class WhereClause(json: Value) extends RustNode { + def whereKwToken: WhereKwToken = createRustNode(_childrenByKind("WHERE_KW").head).asInstanceOf[WhereKwToken] + def wherePred: Seq[WherePred] = _childrenByKind.getOrElse("WHERE_PRED", Seq.empty).map(createRustNode(_).asInstanceOf[WherePred]) + def commaToken: Seq[CommaToken] = _childrenByKind.getOrElse("COMMA", Seq.empty).map(createRustNode(_).asInstanceOf[CommaToken]) + } + + final case class WherePred(json: Value) extends RustNode { + def forBinder: Option[ForBinder] = _childrenByKind.get("FOR_BINDER").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[ForBinder]) + def lifetime: Option[Lifetime] = _childrenByKind.get("LIFETIME").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Lifetime]) + def `type`: Option[Type] = _children.find(child => _typeKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Type]) + def colonToken: ColonToken = createRustNode(_childrenByKind("COLON").head).asInstanceOf[ColonToken] + def typeBoundList: Option[TypeBoundList] = _childrenByKind.get("TYPE_BOUND_LIST").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[TypeBoundList]) + } + + final case class WhileExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def label: Option[Label] = _childrenByKind.get("LABEL").flatMap(_.headOption).map(createRustNode(_).asInstanceOf[Label]) + def whileKwToken: WhileKwToken = createRustNode(_childrenByKind("WHILE_KW").head).asInstanceOf[WhileKwToken] + def expr: Expr = createRustNode(_children.find(child => _exprKinds.contains(child("nodeKind").str)).get).asInstanceOf[Expr] + def blockExpr: BlockExpr = createRustNode(_childrenByKind("BLOCK_EXPR").head).asInstanceOf[BlockExpr] + } + + final case class WildcardPat(json: Value) extends RustNode with Pat { + def underscoreToken: UnderscoreToken = createRustNode(_childrenByKind("UNDERSCORE").head).asInstanceOf[UnderscoreToken] + } + + final case class YeetExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def doKwToken: DoKwToken = createRustNode(_childrenByKind("DO_KW").head).asInstanceOf[DoKwToken] + def yeetKwToken: YeetKwToken = createRustNode(_childrenByKind("YEET_KW").head).asInstanceOf[YeetKwToken] + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + } + + final case class YieldExpr(json: Value) extends RustNode with Expr { + def attr: Seq[Attr] = _childrenByKind.getOrElse("ATTR", Seq.empty).map(createRustNode(_).asInstanceOf[Attr]) + def yieldKwToken: YieldKwToken = createRustNode(_childrenByKind("YIELD_KW").head).asInstanceOf[YieldKwToken] + def expr: Option[Expr] = _children.find(child => _exprKinds.contains(child("nodeKind").str)).map(createRustNode(_).asInstanceOf[Expr]) + } + + final case class BangToken(json: Value) extends RustToken + + final case class NeqToken(json: Value) extends RustToken + + final case class PoundToken(json: Value) extends RustToken + + final case class FrontmatterToken(json: Value) extends RustToken + + final case class IdentToken(json: Value) extends RustToken + + final case class LifetimeIdentToken(json: Value) extends RustToken + + final case class ShebangToken(json: Value) extends RustToken + + final case class PercentToken(json: Value) extends RustToken + + final case class PercenteqToken(json: Value) extends RustToken + + final case class AmpToken(json: Value) extends RustToken + + final case class Amp2Token(json: Value) extends RustToken + + final case class AmpeqToken(json: Value) extends RustToken + + final case class LParenToken(json: Value) extends RustToken + + final case class RParenToken(json: Value) extends RustToken + + final case class StarToken(json: Value) extends RustToken + + final case class StareqToken(json: Value) extends RustToken + + final case class PlusToken(json: Value) extends RustToken + + final case class PluseqToken(json: Value) extends RustToken + + final case class CommaToken(json: Value) extends RustToken + + final case class MinusToken(json: Value) extends RustToken + + final case class MinuseqToken(json: Value) extends RustToken + + final case class ThinArrowToken(json: Value) extends RustToken + + final case class DotToken(json: Value) extends RustToken + + final case class Dot2Token(json: Value) extends RustToken + + final case class Dot3Token(json: Value) extends RustToken + + final case class Dot2eqToken(json: Value) extends RustToken + + final case class SlashToken(json: Value) extends RustToken + + final case class SlasheqToken(json: Value) extends RustToken + + final case class ColonToken(json: Value) extends RustToken + + final case class Colon2Token(json: Value) extends RustToken + + final case class SemicolonToken(json: Value) extends RustToken + + final case class LAngleToken(json: Value) extends RustToken + + final case class ShlToken(json: Value) extends RustToken + + final case class ShleqToken(json: Value) extends RustToken + + final case class LteqToken(json: Value) extends RustToken + + final case class EqToken(json: Value) extends RustToken + + final case class Eq2Token(json: Value) extends RustToken + + final case class FatArrowToken(json: Value) extends RustToken + + final case class RAngleToken(json: Value) extends RustToken + + final case class GteqToken(json: Value) extends RustToken + + final case class ShrToken(json: Value) extends RustToken + + final case class ShreqToken(json: Value) extends RustToken + + final case class QuestionToken(json: Value) extends RustToken + + final case class AtToken(json: Value) extends RustToken + + final case class ByteToken(json: Value) extends RustToken + + final case class ByteStringToken(json: Value) extends RustToken + + final case class CStringToken(json: Value) extends RustToken + + final case class CharToken(json: Value) extends RustToken + + final case class FloatNumberToken(json: Value) extends RustToken + + final case class IntNumberToken(json: Value) extends RustToken + + final case class StringToken(json: Value) extends RustToken + + final case class SelfTypeKwToken(json: Value) extends RustToken + + final case class LBrackToken(json: Value) extends RustToken + + final case class RBrackToken(json: Value) extends RustToken + + final case class CaretToken(json: Value) extends RustToken + + final case class CareteqToken(json: Value) extends RustToken + + final case class UnderscoreToken(json: Value) extends RustToken + + final case class AsKwToken(json: Value) extends RustToken + + final case class AsmKwToken(json: Value) extends RustToken + + final case class AsyncKwToken(json: Value) extends RustToken + + final case class AttSyntaxKwToken(json: Value) extends RustToken + + final case class AutoKwToken(json: Value) extends RustToken + + final case class AwaitKwToken(json: Value) extends RustToken + + final case class BecomeKwToken(json: Value) extends RustToken + + final case class BikeshedKwToken(json: Value) extends RustToken + + final case class BoxKwToken(json: Value) extends RustToken + + final case class BreakKwToken(json: Value) extends RustToken + + final case class BuiltinKwToken(json: Value) extends RustToken + + final case class CfgKwToken(json: Value) extends RustToken + + final case class CfgAttrKwToken(json: Value) extends RustToken + + final case class ClobberAbiKwToken(json: Value) extends RustToken + + final case class ConstKwToken(json: Value) extends RustToken + + final case class ContinueKwToken(json: Value) extends RustToken + + final case class CrateKwToken(json: Value) extends RustToken + + final case class DefaultKwToken(json: Value) extends RustToken + + final case class DoKwToken(json: Value) extends RustToken + + final case class DynKwToken(json: Value) extends RustToken + + final case class ElseKwToken(json: Value) extends RustToken + + final case class EnumKwToken(json: Value) extends RustToken + + final case class ExternKwToken(json: Value) extends RustToken + + final case class FalseKwToken(json: Value) extends RustToken + + final case class FnKwToken(json: Value) extends RustToken + + final case class ForKwToken(json: Value) extends RustToken + + final case class FormatArgsKwToken(json: Value) extends RustToken + + final case class GenKwToken(json: Value) extends RustToken + + final case class GlobalAsmKwToken(json: Value) extends RustToken + + final case class IfKwToken(json: Value) extends RustToken + + final case class ImplKwToken(json: Value) extends RustToken + + final case class InKwToken(json: Value) extends RustToken + + final case class InlateoutKwToken(json: Value) extends RustToken + + final case class InoutKwToken(json: Value) extends RustToken + + final case class LabelKwToken(json: Value) extends RustToken + + final case class LateoutKwToken(json: Value) extends RustToken + + final case class LetKwToken(json: Value) extends RustToken + + final case class LoopKwToken(json: Value) extends RustToken + + final case class MacroKwToken(json: Value) extends RustToken + + final case class MacroRulesKwToken(json: Value) extends RustToken + + final case class MatchKwToken(json: Value) extends RustToken + + final case class MayUnwindKwToken(json: Value) extends RustToken + + final case class ModKwToken(json: Value) extends RustToken + + final case class MoveKwToken(json: Value) extends RustToken + + final case class MutKwToken(json: Value) extends RustToken + + final case class NakedAsmKwToken(json: Value) extends RustToken + + final case class NomemKwToken(json: Value) extends RustToken + + final case class NoreturnKwToken(json: Value) extends RustToken + + final case class NostackKwToken(json: Value) extends RustToken + + final case class OffsetOfKwToken(json: Value) extends RustToken + + final case class OptionsKwToken(json: Value) extends RustToken + + final case class OutKwToken(json: Value) extends RustToken + + final case class PreservesFlagsKwToken(json: Value) extends RustToken + + final case class PubKwToken(json: Value) extends RustToken + + final case class PureKwToken(json: Value) extends RustToken + + final case class RawKwToken(json: Value) extends RustToken + + final case class ReadonlyKwToken(json: Value) extends RustToken + + final case class RefKwToken(json: Value) extends RustToken + + final case class ReturnKwToken(json: Value) extends RustToken + + final case class SafeKwToken(json: Value) extends RustToken + + final case class SelfKwToken(json: Value) extends RustToken + + final case class StaticKwToken(json: Value) extends RustToken + + final case class StructKwToken(json: Value) extends RustToken + + final case class SuperKwToken(json: Value) extends RustToken + + final case class SymKwToken(json: Value) extends RustToken + + final case class TraitKwToken(json: Value) extends RustToken + + final case class TrueKwToken(json: Value) extends RustToken + + final case class TryKwToken(json: Value) extends RustToken + + final case class TypeKwToken(json: Value) extends RustToken + + final case class UnionKwToken(json: Value) extends RustToken + + final case class UnsafeKwToken(json: Value) extends RustToken + + final case class UseKwToken(json: Value) extends RustToken + + final case class WhereKwToken(json: Value) extends RustToken + + final case class WhileKwToken(json: Value) extends RustToken + + final case class YeetKwToken(json: Value) extends RustToken + + final case class YieldKwToken(json: Value) extends RustToken + + final case class LCurlyToken(json: Value) extends RustToken + + final case class PipeToken(json: Value) extends RustToken + + final case class PipeeqToken(json: Value) extends RustToken + + final case class Pipe2Token(json: Value) extends RustToken + + final case class RCurlyToken(json: Value) extends RustToken + + final case class TildeToken(json: Value) extends RustToken + +} \ No newline at end of file diff --git a/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenPrettyPrintTests.scala b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenPrettyPrintTests.scala new file mode 100644 index 0000000..1d9dccd --- /dev/null +++ b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenPrettyPrintTests.scala @@ -0,0 +1,115 @@ +package io.joern.rust2cpg.parser + +import org.scalatest.funsuite.AnyFunSuite +import org.scalatest.matchers.should.Matchers.shouldBe + +class RustAstGenPrettyPrintTests extends AnyFunSuite with RustAstGenTestFixture { + + test("fn sum") { + val srcFile = code( + """fn sum(a: i32, b: i32) -> i32 { + | let total = a + b; + | total + |} + |""".stripMargin) + + srcFile.prettyPrint shouldBe + """SOURCE_FILE + | FN + | FN_KW + | NAME + | IDENT + | PARAM_LIST + | L_PAREN + | PARAM + | IDENT_PAT + | NAME + | IDENT + | COLON + | PATH_TYPE + | PATH + | PATH_SEGMENT + | NAME_REF + | IDENT + | COMMA + | PARAM + | IDENT_PAT + | NAME + | IDENT + | COLON + | PATH_TYPE + | PATH + | PATH_SEGMENT + | NAME_REF + | IDENT + | R_PAREN + | RET_TYPE + | THIN_ARROW + | PATH_TYPE + | PATH + | PATH_SEGMENT + | NAME_REF + | IDENT + | BLOCK_EXPR + | STMT_LIST + | L_CURLY + | LET_STMT + | LET_KW + | IDENT_PAT + | NAME + | IDENT + | EQ + | BIN_EXPR + | PATH_EXPR + | PATH + | PATH_SEGMENT + | NAME_REF + | IDENT + | PLUS + | PATH_EXPR + | PATH + | PATH_SEGMENT + | NAME_REF + | IDENT + | SEMICOLON + | PATH_EXPR + | PATH + | PATH_SEGMENT + | NAME_REF + | IDENT + | R_CURLY""".stripMargin + } + + test("pub struct with single private field") { + val srcFile = code( + """ + |pub struct Foo { + | my_field: i32, + |} + |""".stripMargin) + + srcFile.prettyPrint shouldBe + """SOURCE_FILE + | STRUCT + | VISIBILITY + | PUB_KW + | STRUCT_KW + | NAME + | IDENT + | RECORD_FIELD_LIST + | L_CURLY + | RECORD_FIELD + | NAME + | IDENT + | COLON + | PATH_TYPE + | PATH + | PATH_SEGMENT + | NAME_REF + | IDENT + | COMMA + | R_CURLY""".stripMargin + + } + +} diff --git a/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala new file mode 100644 index 0000000..af2c1f0 --- /dev/null +++ b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala @@ -0,0 +1,80 @@ +package io.joern.rust2cpg.parser + +import io.joern.rust2cpg.parser.RustNodeSyntax.{RustNode, SourceFile, createRustNode} + +import java.nio.file.{Files, Path, Paths} +import java.util.Comparator +import scala.sys.process.Process +import scala.util.Using +import ujson.Value + +trait RustAstGenTestFixture { + + def code(source: String): SourceFile = { + val projectDir = Files.createTempDirectory("rust-ast-gen-scala-tests") + + try { + val srcDir = Files.createDirectories(projectDir.resolve("src")) + val outputDir = projectDir.resolve("out") + + Files.writeString( + projectDir.resolve("Cargo.toml"), + """[package] + |name = "rust_ast_gen_scala_test" + |version = "0.1.0" + |edition = "2021" + |""".stripMargin + ) + Files.writeString(srcDir.resolve("main.rs"), source) + + val exitCode = Process( + Seq( + "cargo", + "run", + "--quiet", + "--release", + "--bin", + "rust_ast_gen", + "--", + "-i", + projectDir.toString, + "-o", + outputDir.toString + ), + repoRoot.toFile + ).! + + require(exitCode == 0, s"rust_ast_gen failed with exit code $exitCode") + + val json = ujson.read(Files.readString(outputDir.resolve("src").resolve("main.json"))) + RustNodeSyntax.createRustNode(sourceFileJson(json)).asInstanceOf[SourceFile] + } finally { + deleteRecursively(projectDir) + } + } + + private def sourceFileJson(json: Value): Value = + json("children")(0) + + private lazy val repoRoot: Path = Paths.get(".") + + private def deleteRecursively(path: Path): Unit = { + if (Files.exists(path)) { + Using.resource(Files.walk(path)) { paths => + paths.sorted(Comparator.reverseOrder()).forEach(path => Files.deleteIfExists(path)) + } + } + } + + private def childNodes(node: RustNode): Seq[RustNode] = { + node.json.obj.get("children").map(_.arr.toSeq).getOrElse(Seq.empty).map(createRustNode) + } + + private def prettyPrintNode(node: RustNode, indent: Int): String = { + val renderedChildren = childNodes(node).map(child => prettyPrintNode(child, indent + 1)) + (Seq((" " * indent) + node.json("nodeKind").str) ++ renderedChildren).mkString("\n") + } + + extension (node: RustNode) + def prettyPrint: String = prettyPrintNode(node, 0) +} diff --git a/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTraversalTests.scala b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTraversalTests.scala new file mode 100644 index 0000000..6c18ac1 --- /dev/null +++ b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTraversalTests.scala @@ -0,0 +1,27 @@ +package io.joern.rust2cpg.parser + +import io.joern.rust2cpg.parser.RustNodeSyntax.Fn +import org.scalatest.Inside.inside +import org.scalatest.funsuite.AnyFunSuite +import org.scalatest.matchers.should.Matchers.shouldBe + +class RustAstGenTraversalTests extends AnyFunSuite with RustAstGenTestFixture { + + test("fn main() {}") { + val srcFile = code( + """ + |fn main() {} + |""".stripMargin) + + inside(srcFile.item) { + case Seq(fn: Fn) => { + inside(fn.name.identToken) { + case Some(indentToken) => + // TODO: have an extension to fetch the corresponding code. + (indentToken.startLine, indentToken.startColumn) shouldBe(Some(1), Some(3)) + } + } + } + } + +} diff --git a/src/bin/scala_bindings_gen.rs b/src/bin/scala_bindings_gen.rs index ed106a8..7d8915d 100644 --- a/src/bin/scala_bindings_gen.rs +++ b/src/bin/scala_bindings_gen.rs @@ -15,9 +15,11 @@ fn main() -> Result<()> { let model = Model::from_ungrammar(&grammar)?; let codegen_version = env!("CARGO_PKG_VERSION").to_string(); - let codegen_date = chrono::Local::now() - .format("%d %B %Y, %H:%M:%S %Z") - .to_string(); + let codegen_date = args.include_date.then(|| { + chrono::Local::now() + .format("%d %B %Y, %H:%M:%S %Z") + .to_string() + }); let package_name = "io.joern.rust2cpg.parser".to_string(); let object_name = "RustNodeSyntax".to_string(); let base_node_trait = "RustNode".to_string(); @@ -27,6 +29,9 @@ fn main() -> Result<()> { "Expr".to_string(), "Type".to_string(), "Stmt".to_string(), + "Item".to_string(), + "Meta".to_string(), + "Pat".to_string(), ]; let config = ScalaAstGenConfig { package_name, @@ -61,6 +66,12 @@ struct ScalaBindingsGenArgs { #[arg(help = "Output file path for the generated Scala file")] #[arg(short = 'o', long = "output")] output_file_path: PathBuf, + + #[arg(help = "Include the current date in the generated file header")] + #[arg(default_value_t = true)] + #[arg(action = clap::ArgAction::Set)] + #[arg(long = "include-date")] + include_date: bool, } fn node_name_to_scala_name(node: &str) -> String { diff --git a/src/scala_gen/config.rs b/src/scala_gen/config.rs index 0a200db..4d4a387 100644 --- a/src/scala_gen/config.rs +++ b/src/scala_gen/config.rs @@ -31,8 +31,8 @@ pub struct ScalaAstGenConfig { pub token_name_to_json_kind: fn(&str) -> String, /// The time this code was generated. - /// Only included in the header - pub codegen_date: String, + /// Only included in the header when present. + pub codegen_date: Option, /// The version of the code generator. /// Only included in the header. diff --git a/src/scala_gen/emitter.rs b/src/scala_gen/emitter.rs index ed25a08..e4470d4 100644 --- a/src/scala_gen/emitter.rs +++ b/src/scala_gen/emitter.rs @@ -103,11 +103,16 @@ fn emit_header(out: &mut String, config: &ScalaAstGenConfig) -> Result<(), Error concat!( "package {}\n\n", "// Automatically generated by rust_ast_gen v{}\n", - "// Do not edit directly!\n", - "// Generated on {}\n\n" + "// Do not edit directly!\n" ), - config.package_name, config.codegen_version, config.codegen_date - ) + config.package_name, config.codegen_version + )?; + + if let Some(codegen_date) = &config.codegen_date { + writeln!(out, "// Generated on {codegen_date}")?; + } + + write!(out, "\n") } // TODO: Should come from the config @@ -474,7 +479,7 @@ mod tests { token_name_to_scala_name: |n| format!("{}Token", n), trait_nodes: vec![], codegen_version: "0.0.0".to_string(), - codegen_date: "2020-01-01".to_string(), + codegen_date: Some("2020-01-01".to_string()), } } @@ -670,6 +675,20 @@ object ExampleAst { ); } + #[test] + fn test_date_omitted_from_header() { + let grammar = Grammar::from_str("Expr = 'foo'").unwrap(); + + let model = Model::from_ungrammar(&grammar).unwrap(); + let mut config = example_config(); + config.codegen_date = None; + let scala = generate_scala(&model, &config).unwrap(); + + assert!(scala.contains("// Automatically generated by rust_ast_gen v0.0.0")); + assert!(scala.contains("// Do not edit directly!")); + assert!(!scala.contains("// Generated on ")); + } + #[test] fn test_reserved_scala_accessor_name() { let grammar = Grammar::from_str( From 40fed57bd7cbe062355d9936b70d324d51f73e9e Mon Sep 17 00:00:00 2001 From: Xavier Pinho Date: Wed, 22 Apr 2026 01:10:16 +0100 Subject: [PATCH 2/3] System.lineSeparator instead of newline --- .../scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala index af2c1f0..32a7d51 100644 --- a/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala +++ b/scala_tests/src/test/scala/io/joern/rust2cpg/parser/RustAstGenTestFixture.scala @@ -72,7 +72,7 @@ trait RustAstGenTestFixture { private def prettyPrintNode(node: RustNode, indent: Int): String = { val renderedChildren = childNodes(node).map(child => prettyPrintNode(child, indent + 1)) - (Seq((" " * indent) + node.json("nodeKind").str) ++ renderedChildren).mkString("\n") + (Seq((" " * indent) + node.json("nodeKind").str) ++ renderedChildren).mkString(System.lineSeparator()) } extension (node: RustNode) From 1180a550252ba6f18f10da0c02c5c8023463d119 Mon Sep 17 00:00:00 2001 From: Xavier Pinho Date: Wed, 22 Apr 2026 01:29:47 +0100 Subject: [PATCH 3/3] update .gitattributes once more --- .gitattributes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitattributes b/.gitattributes index 81378bb..a213678 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,5 @@ # Keep copied ungrammar file on LF so build.rs byte comparisons stay stable across OSes. rust.ungram text eol=lf + +# Also the auto-generated RustNodeSyntax.scala +scala_tests/src/main/scala/io/joern/rust2cpg/parser/RustNodeSyntax.scala text eol=lf \ No newline at end of file