/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
// The Cangjie API is in Beta. For details on its capabilities and limitations, please refer to the README file.
package std.ast
import std.collection.ArrayList
private func traverseNodes<N>(v: Visitor, nodes: ArrayList<N>) where N <: Node {
for (node in nodes) {
node.traverse(v)
}
}
public open class Decl <: Node {
init(annotations: ArrayList<Annotation>, modifiers: ArrayList<Modifier>, keyword: Token, identifier: Token,
genericParam: Option<GenericParam>, constraint: ArrayList<GenericConstraint>, constraintCommas: Tokens,
isGenericDecl: Bool) {
super()
this.annotations_ = annotations
this.modifiers_ = modifiers
this.identifier_ = identifier
this.keyword_ = keyword
this.genericParam_ = genericParam
this.constraint_ = constraint
this.constraintCommas_ = constraintCommas
this.isGenericDecl_ = isGenericDecl
}
init(keyword: Token, identifier: Token) {
super()
this.identifier_ = identifier
this.keyword_ = keyword
}
init(decl: Decl) {
super()
this.annotations_ = decl.annotations
this.modifiers_ = decl.modifiers
this.identifier_ = decl.identifier
this.keyword_ = decl.keyword
this.genericParam_ = decl.genericParam_
this.constraint_ = decl.genericConstraint
this.constraintCommas_ = decl.constraintCommas_
this.isGenericDecl_ = decl.isGenericDecl
}
init(input: Tokens) {
try {
var decl = parseDecl(input)
this.begin_ = decl.beginPos
this.end_ = decl.endPos
this.annotations_ = decl.annotations
this.modifiers_ = decl.modifiers
this.identifier_ = match (decl) {
case extDecl: ExtendDecl => Token()
case _ => decl.identifier
}
this.keyword_ = decl.keyword
this.genericParam_ = decl.genericParam_
this.constraint_ = decl.genericConstraint
this.constraintCommas_ = decl.constraintCommas
this.node = decl
this.isGenericDecl_ = decl.isGenericDecl
} catch (e: Exception) {
()
}
}
init() {
super()
}
protected var annotations_: ArrayList<Annotation> = ArrayList<Annotation>()
protected var modifiers_: ArrayList<Modifier> = ArrayList<Modifier>()
protected var keyword_: Token = Token()
protected var identifier_: Token = Token()
private var genericParam_: Option<GenericParam> = None<GenericParam>
private var constraint_: ArrayList<GenericConstraint> = ArrayList<GenericConstraint>()
private var constraintCommas_: Tokens = Tokens()
private var isGenericDecl_: Bool = false
protected var node: Node = Expr()
public mut open prop identifier: Token {
get() {
identifier_
}
set(v) {
identifier_ = v
}
}
public mut prop keyword: Token {
get() {
keyword_
}
set(v) {
keyword_ = v
}
}
public mut prop annotations: ArrayList<Annotation> {
get() {
annotations_
}
set(v) {
annotations_ = v
}
}
public mut prop modifiers: ArrayList<Modifier> {
get() {
modifiers_
}
set(v) {
modifiers_ = v
}
}
public mut prop genericParam: GenericParam {
get() {
match (genericParam_) {
case Some(v) => v
case None => throw ASTException("Get Generic parameters failed")
}
}
set(v) {
genericParam_ = Some(v)
}
}
public mut prop genericConstraint: ArrayList<GenericConstraint> {
get() {
constraint_
}
set(v) {
constraint_ = v
}
}
public mut prop constraintCommas: Tokens {
get() {
constraintCommas_
}
set(v) {
checkTokensType(v, COMMA)
constraintCommas_ = v
}
}
public func hasAttr(attr: String): Bool {
for (i in 0..annotations_.size) {
for (attribute in annotations_[i].attributes) {
if (attribute.value == attr) {
return true
}
}
}
return false
}
public func getAttrs(): Tokens {
var ret = Tokens()
for (i in 0..annotations_.size) {
for (attribute in annotations_[i].attributes) {
ret.append(attribute)
}
}
return ret
}
public mut prop isGenericDecl: Bool {
get() {
isGenericDecl_
}
set(v) {
isGenericDecl_ = v
}
}
public open func toTokens(): Tokens {
var ret = Tokens()
for (i in 0..annotations_.size) {
ret.append(annotations_[i].toTokens())
}
for (i in 0..modifiers_.size) {
ret.append(modifiers_[i].toTokens())
}
if (isValidToken(keyword_)) {
ret.append(keyword_)
}
if (isValidToken(identifier_) && !identifier_.value.isEmpty() && keyword_.value != identifier_.value) {
ret.append(identifier_)
}
match (genericParam_) {
case Some(v) => ret.append(v.toTokens())
case None => ()
}
return ret
}
public open func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
}
protected open func dump(indent: UInt16): String {
// Keep the same indentation as the caller:
var ret: String = ""
for (i in 0..annotations_.size) {
ret += getIndent(indent) + "-annotations: ${i}, "
ret += annotations_[i].dump(indent)
}
for (i in 0..modifiers_.size) {
ret += getIndent(indent) + "-modifiers: ${i}, "
ret += modifiers_[i].dump(indent)
}
if (!keyword_.value.isEmpty()) {
ret += getTokenIndent("-keyword", keyword_, indent)
}
if (!identifier_.value.isEmpty()) {
ret += getTokenIndent("-identifier", identifier_, indent)
}
match (this.genericParam_) {
case Some(node) =>
if (genericParam.parameters.size != 0) {
ret += getIndent(indent) + "-genericParam: "
ret += node.dump(indent)
}
case _ => ()
}
ret
}
// Traverse annotations, modifiers and generic parameters.
func traverseCommonChild(v: Visitor) {
traverseNodes(v, this.annotations_)
traverseNodes(v, modifiers_)
match (this.genericParam_) {
case Some(node) => node.traverse(v)
case _ => ()
}
}
}
public class ClassDecl <: Decl {
public init(inputs: Tokens) {
super(inputs)
match (super.node as ClassDecl) {
case Some(v) =>
this.upBound_ = checkValid(v.upBound_)
this.superTypes_ = v.superTypes_
this.superTypeBitAnds_ = v.superTypeBitAnds_
this.classbody_ = v.classbody_
case None => throw ASTException("Cannot construct the 'ClassDecl' node.")
}
}
init(decl: Decl, upBound: Token, superTypes: ArrayList<TypeNode>, superTypeBitAnds: Tokens, body: Body) {
super(decl)
this.upBound_ = upBound
this.classbody_ = body
this.superTypes_ = superTypes
this.superTypeBitAnds_ = superTypeBitAnds
}
public init() {
}
private var upBound_: Token = Token()
private var superTypes_: ArrayList<TypeNode> = ArrayList<TypeNode>()
private var superTypeBitAnds_: Tokens = Tokens()
private var classbody_: Body = Body()
public mut prop upperBound: Token {
get() {
upBound_
}
set(v) {
checkTokenType(v, UPPERBOUND)
upBound_ = v
}
}
public mut prop superTypes: ArrayList<TypeNode> {
get() {
superTypes_
}
set(v) {
superTypes_ = v
}
}
public mut prop superTypeBitAnds: Tokens {
get() {
superTypeBitAnds_
}
set(v) {
checkTokensType(v, BITAND)
superTypeBitAnds_ = v
}
}
public mut prop body: Body {
get() {
classbody_
}
set(v) {
classbody_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens()
return referenceType2Tokens(ret, RefTypeUpperBoundInfo(upBound_, superTypes_, superTypeBitAnds_),
genericConstraint, constraintCommas, classbody_)
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, superTypes_)
traverseNodes(v, genericConstraint)
classbody_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "ClassDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
ret += dumpCommonContent(currentIndent, upBound_, superTypes_, genericConstraint, classbody_)
ret += getIndent(indent) + "}\n"
ret
}
}
public class StructDecl <: Decl {
init(decl: Decl, upBound: Token, superTypes: ArrayList<TypeNode>, superTypeBitAnds: Tokens, body: Body) {
super(decl)
this.upBound_ = upBound
this.structbody_ = body
this.superTypes_ = superTypes
this.superTypeBitAnds_ = superTypeBitAnds
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as StructDecl) {
case Some(v) =>
this.upBound_ = checkValid(v.upBound_)
this.superTypes_ = v.superTypes_
this.structbody_ = v.structbody_
this.superTypeBitAnds_ = v.superTypeBitAnds_
case None => throw ASTException("Cannot construct the 'StructDecl' node.")
}
}
public init() {
}
private var upBound_: Token = Token()
private var superTypes_: ArrayList<TypeNode> = ArrayList<TypeNode>()
private var superTypeBitAnds_: Tokens = Tokens()
private var structbody_: Body = Body()
public mut prop upperBound: Token {
get() {
upBound_
}
set(v) {
checkTokenType(v, UPPERBOUND)
upBound_ = v
}
}
public mut prop superTypes: ArrayList<TypeNode> {
get() {
superTypes_
}
set(v) {
superTypes_ = v
}
}
public mut prop superTypeBitAnds: Tokens {
get() {
superTypeBitAnds_
}
set(v) {
checkTokensType(v, BITAND)
superTypeBitAnds_ = v
}
}
public mut prop body: Body {
get() {
structbody_
}
set(v) {
structbody_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens()
return referenceType2Tokens(ret, RefTypeUpperBoundInfo(upBound_, superTypes_, superTypeBitAnds_),
genericConstraint, constraintCommas, structbody_)
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, superTypes_)
traverseNodes(v, genericConstraint)
structbody_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "StructDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
ret += dumpCommonContent(currentIndent, upBound_, superTypes_, genericConstraint, structbody_)
ret += getIndent(indent) + "}\n"
ret
}
}
public class InterfaceDecl <: Decl {
init(decl: Decl, upBound: Token, superTypes: ArrayList<TypeNode>, superTypeBitAnds: Tokens, body: Body) {
super(decl)
this.upBound_ = upBound
this.interfacetbody_ = body
this.superTypes_ = superTypes
this.superTypeBitAnds_ = superTypeBitAnds
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as InterfaceDecl) {
case Some(v) =>
this.upBound_ = checkValid(v.upBound_)
this.superTypes_ = v.superTypes_
this.interfacetbody_ = v.interfacetbody_
this.superTypeBitAnds_ = v.superTypeBitAnds_
case None => throw ASTException("Cannot construct the 'InterfaceDecl' node.")
}
}
public init() {
}
private var upBound_: Token = Token()
private var superTypes_: ArrayList<TypeNode> = ArrayList<TypeNode>()
private var superTypeBitAnds_: Tokens = Tokens()
private var interfacetbody_: Body = Body()
public mut prop upperBound: Token {
get() {
upBound_
}
set(v) {
checkTokenType(v, UPPERBOUND)
upBound_ = v
}
}
public mut prop superTypes: ArrayList<TypeNode> {
get() {
superTypes_
}
set(v) {
superTypes_ = v
}
}
public mut prop superTypeBitAnds: Tokens {
get() {
superTypeBitAnds_
}
set(v) {
checkTokensType(v, BITAND)
superTypeBitAnds_ = v
}
}
public mut prop body: Body {
get() {
interfacetbody_
}
set(v) {
interfacetbody_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens()
return referenceType2Tokens(ret, RefTypeUpperBoundInfo(upBound_, superTypes_, superTypeBitAnds_),
genericConstraint, constraintCommas, interfacetbody_)
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, superTypes_)
traverseNodes(v, genericConstraint)
interfacetbody_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "InterfaceDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
ret += dumpCommonContent(currentIndent, upBound_, superTypes_, genericConstraint, interfacetbody_)
ret += getIndent(indent) + "}\n"
ret
}
}
public class EnumDecl <: Decl {
init(decl: Decl, upBound: Token, superTypes: ArrayList<TypeNode>, superTypeBitAnds: Tokens, lBrace: Token,
bitor: Tokens, constructors: ArrayList<Constructor>, decls: ArrayList<Decl>, rBrace: Token, ellipsis: Token) {
super(decl)
upBound_ = upBound
superTypes_ = superTypes
superTypeBitAnds_ = superTypeBitAnds
lBrace_ = lBrace
bitor_ = bitor
constructors_ = constructors
decls_ = decls
rBrace_ = rBrace
ellipsis_ = ellipsis
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as EnumDecl) {
case Some(v) =>
this.upBound_ = checkValid(v.upBound_)
this.superTypes_ = v.superTypes_
this.superTypeBitAnds_ = v.superTypeBitAnds_
this.lBrace_ = v.lBrace_
this.bitor_ = v.bitor_
this.constructors_ = v.constructors_
this.decls_ = v.decls_
this.rBrace_ = v.rBrace_
this.ellipsis_ = checkValid(v.ellipsis_)
case None => throw ASTException("Cannot construct the 'EnumDecl' node.")
}
}
public init() {
}
private var upBound_: Token = Token()
private var superTypes_: ArrayList<TypeNode> = ArrayList<TypeNode>()
private var superTypeBitAnds_: Tokens = Tokens()
private var lBrace_: Token = Token(TokenKind.LCURL)
private var bitor_: Tokens = Tokens()
private var constructors_ = ArrayList<Constructor>()
private var decls_ = ArrayList<Decl>()
private var rBrace_: Token = Token(TokenKind.RCURL)
private var ellipsis_: Token = Token()
public mut prop upperBound: Token {
get() {
upBound_
}
set(v) {
checkTokenType(v, UPPERBOUND)
upBound_ = v
}
}
public mut prop superTypes: ArrayList<TypeNode> {
get() {
superTypes_
}
set(v) {
superTypes_ = v
}
}
public mut prop superTypeBitAnds: Tokens {
get() {
superTypeBitAnds_
}
set(v) {
checkTokensType(v, BITAND)
superTypeBitAnds_ = v
}
}
public mut prop lBrace: Token {
get() {
lBrace_
}
set(v) {
checkTokenType(v, LCURL)
lBrace_ = v
}
}
public mut prop constructors: ArrayList<Constructor> {
get() {
constructors_
}
set(v) {
constructors_ = v
}
}
public mut prop decls: ArrayList<Decl> {
get() {
decls_
}
set(v) {
decls_ = v
}
}
public mut prop rBrace: Token {
get() {
rBrace_
}
set(v) {
checkTokenType(v, RCURL)
rBrace_ = v
}
}
public mut prop ellipsis: Token {
get() {
ellipsis_
}
set(v) {
checkTokenType(v, ELLIPSIS)
ellipsis_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens()
if (!superTypes_.isEmpty()) {
if (upBound_.kind != ILLEGAL) {
ret.append(upBound_)
} else {
ret.append(Token(TokenKind.UPPERBOUND))
}
for (i in 0..superTypes_.size - 1) {
let bitAnd = superTypeBitAnds_.tryGet(i) ?? Token(BITAND)
ret.append(superTypes_[i].toTokens()).append(bitAnd)
}
ret.append(superTypes_[superTypes_.size - 1].toTokens())
}
if (!super.genericConstraint.isEmpty()) {
var index = super.genericConstraint.size - 1
for (i in 0..index) {
let comma = super.constraintCommas.tryGet(i) ?? Token(TokenKind.COMMA)
ret.append(super.genericConstraint[i].toTokens()).append(comma)
}
ret.append(super.genericConstraint[index].toTokens())
}
ret.append(lBrace_).append(Token(NL))
let bitOrIterator = bitor_.iterator()
if (!constructors_.isEmpty()) {
if (bitor_.size != 0 && bitor_[0].pos.line <= constructors_[0].identifier.pos.line &&
bitor_[0].pos.column <= constructors_[0].identifier.pos.column) {
if (let Some(or) <- bitOrIterator.next()) {
ret.append(or)
}
}
ret.append(constructors_[0].toTokens()).append(Token(NL))
for (i in 1..constructors_.size) {
let bitOr = bitOrIterator.next() ?? Token(BITOR)
ret.append(bitOr).append(constructors_[i].toTokens()).append(Token(NL))
}
}
if (isValidToken(ellipsis_)) {
let bitOr = bitOrIterator.next() ?? Token(BITOR)
ret.append(bitOr).append(ellipsis_).append(Token(NL))
}
for (decl in decls_) {
ret.append(decl.toTokens())
}
ret.append(rBrace_).append(Token(NL))
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, superTypes_)
traverseNodes(v, genericConstraint)
traverseNodes(v, constructors_)
traverseNodes(v, decls_)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "EnumDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
if (isValidToken(upBound_)) {
ret += getTokenIndent("-upperBound", upBound_, currentIndent)
}
ret += dumpNodes("-superTypes", superTypes_, currentIndent)
ret += dumpNodes("-genericConstraint", genericConstraint, currentIndent)
for (i in 0..constructors_.size) {
ret += getIndent(currentIndent) + "-constructors: ${i}, "
ret += constructors_[i].dump(currentIndent)
}
if (isValidToken(ellipsis_)) {
ret += getTokenIndent("-ellipsis", ellipsis_, currentIndent)
}
for (i in 0..decls_.size) {
ret += getIndent(currentIndent) + "-decls: ${i}, "
ret += decls_[i].dump(currentIndent)
}
ret += getIndent(indent) + "}\n"
ret
}
}
public class ExtendDecl <: Decl {
init(decl: Decl, extendType: TypeNode, upBound: Token, superTypes: ArrayList<TypeNode>, superTypeBitAnds: Tokens,
body: Body) {
super(decl)
this.extendType_ = extendType
this.upBound_ = checkValid(upBound)
this.superTypes_ = superTypes
this.superTypeBitAnds_ = superTypeBitAnds
this.body_ = body
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as ExtendDecl) {
case Some(v) =>
this.extendType_ = v.extendType_
this.upBound_ = checkValid(v.upBound_)
this.superTypes_ = v.superTypes_
this.superTypeBitAnds_ = v.superTypeBitAnds_
this.body_ = v.body_
case None => throw ASTException("Cannot construct the 'ExtendDecl' node.")
}
}
public init() {
}
private var extendType_: TypeNode = TypeNode()
private var upBound_: Token = Token()
private var superTypes_: ArrayList<TypeNode> = ArrayList<TypeNode>()
private var superTypeBitAnds_: Tokens = Tokens()
private var body_ = Body()
public mut override prop identifier: Token {
get() {
throw ASTException("Current ExtendDecl don't have identifier")
}
set(_) {
throw ASTException("Current ExtendDecl don't have identifier")
}
}
public mut prop extendType: TypeNode {
get() {
extendType_
}
set(v) {
extendType_ = v
}
}
public mut prop upperBound: Token {
get() {
upBound_
}
set(v) {
checkTokenType(v, UPPERBOUND)
upBound_ = v
}
}
public mut prop superTypes: ArrayList<TypeNode> {
get() {
superTypes_
}
set(v) {
superTypes_ = v
}
}
public mut prop superTypeBitAnds: Tokens {
get() {
superTypeBitAnds_
}
set(v) {
checkTokensType(v, BITAND)
superTypeBitAnds_ = v
}
}
public mut prop body: Body {
get() {
body_
}
set(v) {
body_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens().append(extendType_)
return referenceType2Tokens(ret, RefTypeUpperBoundInfo(upBound_, superTypes_, superTypeBitAnds_),
genericConstraint, constraintCommas, body_)
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
extendType_.traverse(v)
traverseNodes(v, superTypes_)
traverseNodes(v, genericConstraint)
body_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "ExtendDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
ret += getIndent(currentIndent) + "-extendType: "
ret += extendType_.dump(currentIndent)
ret += dumpCommonContent(currentIndent, upBound_, superTypes_, genericConstraint, body_)
ret += getIndent(indent) + "}\n"
ret
}
}
public class FuncDecl <: Decl {
public init(inputs: Tokens) {
super(inputs)
match (super.node as FuncDecl) {
case Some(v) =>
this.lParen_ = v.lParen_
this.rParen_ = v.rParen_
this.params_ = v.params_
this.colon_ = checkValid(v.colon_)
this.retTy_ = v.retTy_
this.block_ = v.block_
this.overloadedOperators_ = v.overloadedOperators_
this.isEnumConstruct = v.isEnumConstruct
case None => throw ASTException("Cannot construct the 'FuncDecl' node.")
}
}
init(decl: Decl, lParen: Token, funcParams: ArrayList<FuncParam>, rParen: Token, colon: Token, ty: Option<TypeNode>,
block: Block) {
super(decl)
this.lParen_ = lParen
this.params_ = funcParams
this.rParen_ = rParen
this.colon_ = colon
this.retTy_ = ty
this.block_ = block
}
public init() {
}
private var overloadedOperators_: Tokens = Tokens()
private var lParen_: Token = Token(TokenKind.LPAREN)
private var params_: ArrayList<FuncParam> = ArrayList<FuncParam>()
private var rParen_: Token = Token(TokenKind.RPAREN)
private var colon_ = Token()
private var retTy_: Option<TypeNode> = None<TypeNode>
private var block_: Block = Block()
var isEnumConstruct: Bool = false
public mut prop overloadOp: Tokens {
get() {
overloadedOperators_
}
set(v) {
overloadedOperators_ = v
}
}
public mut prop lParen: Token {
get() {
lParen_
}
set(v) {
checkTokenType(v, LPAREN)
lParen_ = v
}
}
public mut prop funcParams: ArrayList<FuncParam> {
get() {
params_
}
set(v) {
params_ = v
}
}
public mut prop rParen: Token {
get() {
rParen_
}
set(v) {
checkTokenType(v, RPAREN)
rParen_ = v
}
}
public mut prop colon: Token {
get() {
colon_
}
set(v) {
checkTokenType(v, COLON)
colon_ = v
}
}
public mut prop declType: TypeNode {
get() {
match (retTy_) {
case Some(v) => v
case None => throw ASTException("Current FuncDecl has empty return type")
}
}
set(v) {
retTy_ = Some(v)
}
}
public mut prop block: Block {
get() {
block_
}
set(v) {
block_ = v
}
}
public func isConst(): Bool {
for (modifier in modifiers) {
if (modifier.keyword.value == "const") {
return true
}
}
return false
}
public func toTokens(): Tokens {
var ret: Tokens = Tokens()
for (i in 0..annotations.size) {
ret.append(annotations[i].toTokens())
}
for (i in 0..modifiers.size) {
ret.append(modifiers[i].toTokens())
}
if (isValidToken(keyword)) {
ret.append(keyword)
}
if (overloadOp.size != 0) {
ret.append(overloadOp)
} else if (isValidToken(identifier) && !identifier.value.isEmpty() && keyword.value != identifier.value) {
if (identifier.value == "~init") {
let identPos = identifier.pos
ret.append(Token(TokenKind.BITNOT).addPosition(identPos))
ret.append(Token(TokenKind.INIT).addPosition(identPos.fileID, identPos.line, identPos.column + 1))
} else {
ret.append(identifier)
}
}
var paramTokens = try {
genericParam.toTokens()
} catch (e: ASTException) {
Tokens()
}
ret.append(paramTokens).append(lParen_)
ret.append(funcParams.toTokens())
ret.append(rParen_)
match (retTy_) {
case Some(v) => ret.append(colon_).append(v.toTokens())
case None => ()
}
if (!super.genericConstraint.isEmpty()) {
var index = super.genericConstraint.size - 1
for (i in 0..index) {
let comma = super.constraintCommas.tryGet(i) ?? Token(TokenKind.COMMA)
ret.append(super.genericConstraint[i].toTokens()).append(comma)
}
ret.append(super.genericConstraint[index].toTokens())
}
ret.append(block.toTokens())
return ret
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, params_)
match (retTy_) {
case Some(node) => node.traverse(v)
case None => ()
}
traverseNodes(v, genericConstraint)
block_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "FuncDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
if (overloadedOperators_.size != 0) {
if (overloadedOperators_.size == 1) {
ret += getTokenIndent("overloadOp", overloadedOperators_[0], currentIndent, noNameIndent: true)
} else {
ret += getIndent(currentIndent) +
"overloadOp: ${overloadedOperators_[0].value + overloadedOperators_[1].value}"
}
}
ret += dumpNodes("-funcParams", funcParams, currentIndent)
match (retTy_) {
case Some(v) =>
ret += getIndent(currentIndent) + "-declType: "
ret += v.dump(currentIndent)
case None => ()
}
for (i in 0..genericConstraint.size) {
ret += getIndent(currentIndent) + "-genericConstraint: ${i}, "
ret += genericConstraint[i].dump(currentIndent)
}
ret += getIndent(currentIndent) + "-block: "
ret += block_.dump(currentIndent)
ret += getIndent(indent) + "}\n"
ret
}
}
public class MainDecl <: Decl {
init(decl: Decl, lParen: Token, funcParams: ArrayList<FuncParam>, rParen: Token, colon: Token, ty: Option<TypeNode>,
block: Block) {
super(decl)
this.lParen_ = lParen
this.params_ = funcParams
this.rParen_ = rParen
this.colon_ = colon
this.retTy_ = ty
this.block_ = block
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as MainDecl) {
case Some(v) =>
this.lParen_ = v.lParen_
this.rParen_ = v.rParen_
this.params_ = v.params_
this.colon_ = checkValid(v.colon_)
this.retTy_ = v.retTy_
this.block_ = v.block_
case None => throw ASTException("Cannot construct the 'MainDecl' node.")
}
}
public init() {
super()
}
private var lParen_: Token = Token(TokenKind.LPAREN)
private var rParen_: Token = Token(TokenKind.RPAREN)
private var colon_ = Token()
private var params_: ArrayList<FuncParam> = ArrayList<FuncParam>()
private var retTy_: Option<TypeNode> = None<TypeNode>
private var block_: Block = Block()
public mut prop lParen: Token {
get() {
lParen_
}
set(v) {
checkTokenType(v, LPAREN)
lParen_ = v
}
}
public mut prop funcParams: ArrayList<FuncParam> {
get() {
params_
}
set(v) {
params_ = v
}
}
public mut prop rParen: Token {
get() {
rParen_
}
set(v) {
checkTokenType(v, RPAREN)
rParen_ = v
}
}
public mut prop colon: Token {
get() {
colon_
}
set(v) {
checkTokenType(v, COLON)
colon_ = v
}
}
public mut prop declType: TypeNode {
get() {
match (retTy_) {
case Some(v) => v
case None => throw ASTException("Current MainDecl has empty return type")
}
}
set(v) {
retTy_ = Some(v)
}
}
public mut prop block: Block {
get() {
block_
}
set(v) {
block_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = Tokens().append(super.toTokens())
ret.append(lParen_)
ret.append(funcParams.toTokens())
ret.append(rParen_)
match (retTy_) {
case Some(v) => ret.append(colon_).append(v.toTokens())
case None => ()
}
ret.append(block.toTokens())
return ret
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, params_)
match (retTy_) {
case Some(node) => node.traverse(v)
case None => ()
}
block_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "MainDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
ret += dumpNodes("-funcParams", funcParams, currentIndent)
match (retTy_) {
case Some(v) =>
ret += getIndent(currentIndent) + "-declType: "
ret += v.dump(currentIndent)
case None => ()
}
ret += getIndent(currentIndent) + "-block: "
ret += block_.dump(currentIndent)
ret += getIndent(indent) + "}\n"
ret
}
}
public class MacroDecl <: Decl {
init(decl: Decl, lParen: Token, params: ArrayList<FuncParam>, rParen: Token, colon: Token, ty: Option<TypeNode>,
block: Block) {
super(decl)
lParen_ = lParen
this.params_ = params
rParen_ = rParen
this.colon_ = colon
this.retTy_ = ty
this.block_ = block
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as MacroDecl) {
case Some(v) =>
this.lParen_ = v.lParen_
this.rParen_ = v.rParen_
this.params_ = v.params_
this.colon_ = checkValid(v.colon_)
this.retTy_ = v.retTy_
this.block_ = v.block_
case None => throw ASTException("Cannot construct the 'MacroDecl' node.")
}
}
public init() {
super()
}
private var lParen_: Token = Token(TokenKind.LPAREN)
private var rParen_: Token = Token(TokenKind.RPAREN)
private var params_: ArrayList<FuncParam> = ArrayList<FuncParam>()
private var colon_ = Token()
private var retTy_: Option<TypeNode> = None<TypeNode>
private var block_: Block = Block()
public mut prop lParen: Token {
get() {
lParen_
}
set(v) {
checkTokenType(v, LPAREN)
lParen_ = v
}
}
public mut prop funcParams: ArrayList<FuncParam> {
get() {
params_
}
set(v) {
params_ = v
}
}
public mut prop rParen: Token {
get() {
rParen_
}
set(v) {
checkTokenType(v, RPAREN)
rParen_ = v
}
}
public mut prop colon: Token {
get() {
colon_
}
set(v) {
checkTokenType(v, COLON)
colon_ = v
}
}
public mut prop declType: TypeNode {
get() {
match (retTy_) {
case Some(v) => v
case None => throw ASTException("Current MacroDecl has empty return type")
}
}
set(v) {
retTy_ = Some(v)
}
}
public mut prop block: Block {
get() {
block_
}
set(v) {
block_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = Tokens().append(super.toTokens())
ret.append(lParen_)
ret.append(funcParams.toTokens())
ret.append(rParen_)
if (!isValidPosition(colon_)) {
return ret.append(block.toTokens())
}
match (retTy_) {
case Some(v) => ret.append(colon_).append(v)
case None => ()
}
return ret.append(block.toTokens())
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, params_)
declType.traverse(v)
traverseNodes(v, genericConstraint)
block_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "MacroDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
for (i in 0..funcParams.size) {
ret += getIndent(currentIndent) + "-funcParams: ${i}, "
ret += funcParams[i].dump(currentIndent)
}
if (isValidPosition(colon_)) {
match (retTy_) {
case Some(v) =>
ret += getIndent(currentIndent) + "-declType: "
ret += v.dump(currentIndent)
case None => ()
}
}
ret += getIndent(currentIndent) + "-block: "
ret += block_.dump(currentIndent)
ret += getIndent(indent) + "}\n"
ret
}
}
public class PrimaryCtorDecl <: Decl {
init(decl: Decl, lParen: Token, params: ArrayList<FuncParam>, rParen: Token, block: Block) {
super(decl)
this.lParen_ = lParen
this.params_ = params
this.rParen_ = rParen
this.block_ = block
}
public init(inputs: Tokens) {
try {
match (parseDecl(inputs, astKind: "PrimaryCtorDecl") as PrimaryCtorDecl) {
case Some(v) =>
this.begin_ = v.beginPos
this.end_ = v.endPos
this.annotations = v.annotations
this.modifiers = v.modifiers
this.identifier_ = v.identifier_
this.lParen_ = v.lParen_
this.rParen_ = v.rParen_
this.params_ = v.params_
this.block_ = v.block_
case None => throw ASTException("Cannot construct the 'PrimaryCtorDecl' node.")
}
} catch (e: ParseASTException) {
if (e.message == String.empty) {
throw ASTException("Cannot construct the 'PrimaryCtorDecl' node.")
} else {
throw ASTException(e.message)
}
}
}
public init() {
super()
}
private var lParen_: Token = Token(TokenKind.LPAREN)
private var rParen_: Token = Token(TokenKind.RPAREN)
private var params_: ArrayList<FuncParam> = ArrayList<FuncParam>()
private var block_: Block = Block()
public mut prop lParen: Token {
get() {
lParen_
}
set(v) {
checkTokenType(v, LPAREN)
lParen_ = v
}
}
public mut prop funcParams: ArrayList<FuncParam> {
get() {
params_
}
set(v) {
params_ = v
}
}
public mut prop rParen: Token {
get() {
rParen_
}
set(v) {
checkTokenType(v, RPAREN)
rParen_ = v
}
}
public mut prop block: Block {
get() {
block_
}
set(v) {
block_ = v
}
}
public func isConst(): Bool {
for (modifier in modifiers) {
if (modifier.keyword.value == "const") {
return true
}
}
return false
}
public func toTokens(): Tokens {
var ret: Tokens = Tokens().append(super.toTokens()).append(lParen_)
ret.append(funcParams.toTokens())
ret.append(rParen_).append(block.toTokens())
return ret
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
traverseNodes(v, params_)
traverseNodes(v, genericConstraint)
block_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "PrimaryCtorDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
for (i in 0..funcParams.size) {
ret += getIndent(currentIndent) + "-funcParams: ${i}, "
ret += funcParams[i].dump(currentIndent)
}
ret += getIndent(currentIndent) + "-block: "
ret += block_.dump(currentIndent)
ret += getIndent(indent) + "}\n"
ret
}
}
public class VarDecl <: Decl {
/**
* The following two constructors are used to parse token streams and are not exposed externally.
*/
init(decl: Decl, colon: Token, declType: Option<TypeNode>, assign: Token, expr: Option<Expr>) {
super(decl)
this.declType_ = declType
this.expr_ = expr
this.colon_ = colon
this.assign_ = assign
// const is a keyword, not a modifier
if (this.keyword.kind == TokenKind.CONST) {
modifiers.removeIf {mod => mod.keyword.kind == TokenKind.CONST}
}
}
init(decl: Decl, pattern: Option<Pattern>, colon: Token, declType: Option<TypeNode>, assign: Token,
expr: Option<Expr>) {
super(decl)
this.pattern_ = pattern
this.declType_ = declType
this.expr_ = expr
this.colon_ = colon
this.assign_ = assign
if (this.keyword.kind == TokenKind.CONST) {
modifiers.removeIf {mod => mod.keyword.kind == TokenKind.CONST}
}
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as VarDecl) {
case Some(v) =>
this.declType_ = v.declType_
this.expr_ = v.expr_
this.colon_ = checkValid(v.colon_)
this.assign_ = v.assign_
this.isEnumConstruct = v.isEnumConstruct
case None => throw ASTException("Cannot construct the 'VarDecl' node.")
}
if (this.keyword.kind == TokenKind.CONST) {
modifiers.removeIf {mod => mod.keyword.kind == TokenKind.CONST}
}
}
public init() {
super()
}
private var pattern_: Option<Pattern> = None<Pattern>
private var colon_ = Token()
private var declType_: Option<TypeNode> = None<TypeNode>
private var assign_: Token = Token()
private var expr_: Option<Expr> = None<Expr>
var isEnumConstruct: Bool = false
public mut prop pattern: Pattern {
get() {
match (pattern_) {
case Some(v) => v
case None => throw ASTException("Current VarDecl is with an empty pattern")
}
}
set(v) {
pattern_ = v
}
}
public mut prop colon: Token {
get() {
colon_
}
set(v) {
checkTokenType(v, COLON)
colon_ = v
}
}
public mut prop declType: TypeNode {
get() {
match (declType_) {
case Some(v) => v
case None => throw ASTException("Current VarDecl has an implicit type")
}
}
set(v) {
declType_ = Some(v)
}
}
public mut prop assign: Token {
get() {
assign_
}
set(v) {
checkTokenType(v, ASSIGN)
assign_ = v
}
}
public mut prop expr: Expr {
get() {
match (expr_) {
case Some(v) => v
case None => throw ASTException("Current VarDecl has not be initialized")
}
}
set(v) {
expr_ = Some(v)
}
}
public func isConst(): Bool {
if (keyword.kind == TokenKind.CONST) {
return true
}
return false
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens()
var endPos = Position(identifier.pos.fileID, identifier.pos.line,
identifier.pos.column + Int32(identifier.value.size))
match (pattern_) {
case Some(v) => ret.append(v.toTokens())
case None => ()
}
match (declType_) {
case Some(v) =>
ret.append(colon_).append(v.toTokens())
endPos = v.endPos
case None => ()
}
match (expr_) {
case Some(v) =>
ret.append(assign_).append(v.toTokens())
endPos = v.endPos
case None => ()
}
ret.append(Token(NL).addPosition(endPos))
return ret
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
match (pattern_) {
case Some(node) => node.traverse(v)
case None => ()
}
match (declType_) {
case Some(node) => node.traverse(v)
case None => ()
}
match (expr_) {
case Some(node) => node.traverse(v)
case None => ()
}
return
}
protected func dump(indent: UInt16): String {
var ret: String = "VarDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
match (pattern_) {
case Some(node) =>
ret += getIndent(currentIndent) + "-pattern: "
ret += node.dump(currentIndent)
case None => ()
}
match (declType_) {
case Some(node) =>
ret += getIndent(currentIndent) + "-declType: "
ret += node.dump(currentIndent)
case None => ()
}
ret += getTokenIndent("-assign", assign_, currentIndent)
match (expr_) {
case Some(node) =>
ret += getIndent(currentIndent) + "-expr: "
ret += node.dump(currentIndent)
case None => ()
}
ret += getIndent(indent) + "}\n"
ret
}
}
public open class FuncParam <: Decl {
init(decl: Decl, notMark: Token, colon: Token, paramType: TypeNode, assign: Token, expr: Option<Expr>, comma: Token,
isMemberParam: Bool) {
super(decl)
not_ = notMark
colon_ = colon
paramType_ = paramType
assign_ = assign
expr_ = expr
comma_ = comma
isMemberParam_ = isMemberParam
}
/**
* @throws ParseASTException if input tokens cannot be parsed to a FuncParam node.
*/
public init(inputs: Tokens) {
super()
var v = parseFuncParam(inputs)
var decl: Decl = v
// @ amd @! annotations are considered as macro expansion nodes
// extract the FuncParam node from Annotations with a loop
while (true) {
decl = match (decl as MacroExpandParam) {
case Some(val) =>
this.annotations_.add(createCustomAnnotation(val))
try {
parseFuncParam(val.macroInputs)
} catch (e: ParseASTException | ASTException) {
throw ParseASTException("Cannot construct the 'FuncParam' node.")
}
case None => break
}
}
v = match (decl as FuncParam) {
case Some(val) => val
case None => throw ParseASTException()
}
this.annotations_.add(all: v.annotations_)
this.not_ = checkValid(v.not_)
this.colon_ = v.colon_
this.paramType_ = v.paramType_
this.assign_ = checkValid(v.assign_)
this.expr_ = v.expr_
this.comma_ = v.comma_
this.identifier_ = v.identifier_
this.isMemberParam_ = v.isMemberParam_
this.modifiers_ = v.modifiers
this.keyword_ = v.keyword_
}
public init() {
}
init(key: Token, identifier: Token) {
super(key, identifier)
}
private var not_ = Token()
private var colon_ = Token()
private var paramType_: TypeNode = TypeNode()
private var assign_ = Token()
private var expr_: Option<Expr> = None<Expr>
private var comma_ = Token()
private var isMemberParam_ = false
public mut prop not: Token {
get() {
not_
}
set(v) {
checkTokenType(v, NOT)
not_ = v
}
}
public mut prop colon: Token {
get() {
colon_
}
set(v) {
checkTokenType(v, COLON)
colon_ = v
}
}
public mut prop paramType: TypeNode {
get() {
paramType_
}
set(v) {
paramType_ = v
}
}
public mut prop assign: Token {
get() {
assign_
}
set(v) {
checkTokenType(v, ASSIGN)
assign_ = v
}
}
public mut prop expr: Expr {
get() {
match (expr_) {
case Some(v) => v
case None => throw ASTException("The expression of FuncParam is None")
}
}
set(v) {
expr_ = Some(v)
}
}
public func isMemberParam(): Bool {
return isMemberParam_
}
public open func toTokens(): Tokens {
var ret = super.toTokens()
if (isValidToken(not_)) {
ret.append(not_)
}
if (paramType_.toTokens().size != 0) {
if (isValidToken(colon_)) {
ret.append(colon_)
} else {
ret.append(Token(TokenKind.COLON))
}
ret.append(paramType_.toTokens())
}
match (expr_) {
case Some(v) => ret.append(assign_).append(v.toTokens())
case None => ()
}
if (isValidToken(comma_)) {
ret.append(comma_)
}
ret
}
public open func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
v.breakTraverse()
return
}
this.traverseCommonChild(v)
paramType_.traverse(v)
match (expr_) {
case Some(node) => node.traverse(v)
case None => ()
}
return
}
protected open func dump(indent: UInt16): String {
var ret: String = "FuncParam {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
if (isValidToken(not_)) {
ret += getTokenIndent("-not", not_, currentIndent)
}
if (isValidToken(colon_)) {
ret += getTokenIndent("-colon", colon_, currentIndent)
}
ret += getIndent(currentIndent) + "-paramType: "
ret += paramType_.dump(currentIndent)
if (isValidToken(assign_)) {
ret += getTokenIndent("-assign", assign_, currentIndent)
}
match (expr_) {
case Some(v) =>
ret += getIndent(currentIndent) + "-expr: "
ret += v.dump(currentIndent)
case None => ()
}
ret += getIndent(indent) + "}\n"
ret
}
}
public class PropDecl <: Decl {
init(decl: Decl, colon: Token, declType: TypeNode, lCurl: Token, getter: Option<FuncDecl>, setter: Option<FuncDecl>,
rCurl: Token) {
super(decl)
this.colon_ = colon
this.declType_ = declType
this.lCurl_ = lCurl
this.getter_ = getter
this.setter_ = setter
this.rCurl_ = rCurl
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as PropDecl) {
case Some(v) =>
this.colon_ = checkValid(v.colon_)
this.declType_ = v.declType_
this.lCurl_ = v.lCurl_
this.getter_ = v.getter_
this.setter_ = v.setter_
this.rCurl_ = v.rCurl_
case None => throw ASTException("Cannot construct the 'PropDecl' node.")
}
}
public init() {
super()
}
private var colon_ = Token(TokenKind.COLON)
private var declType_: TypeNode = TypeNode()
private var lCurl_ = Token(TokenKind.LCURL)
private var getter_: Option<FuncDecl> = None<FuncDecl>
private var setter_: Option<FuncDecl> = None<FuncDecl>
private var rCurl_ = Token(TokenKind.RCURL)
public mut prop colon: Token {
get() {
colon_
}
set(v) {
checkTokenType(v, COLON)
colon_ = v
}
}
public mut prop declType: TypeNode {
get() {
declType_
}
set(v) {
declType_ = v
}
}
public mut prop lBrace: Token {
get() {
lCurl_
}
set(v) {
checkTokenType(v, LCURL)
lCurl_ = v
}
}
public mut prop getter: FuncDecl {
get() {
match (getter_) {
case Some(v) => v
case None => throw ASTException("The PropDecl have empty 'get()' function")
}
}
set(v) {
getter_ = Some(v)
}
}
public mut prop setter: FuncDecl {
get() {
match (setter_) {
case Some(v) => v
case None => throw ASTException("The PropDecl have empty 'set()' function")
}
}
set(v) {
setter_ = Some(v)
}
}
public mut prop rBrace: Token {
get() {
rCurl_
}
set(v) {
checkTokenType(v, RCURL)
rCurl_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens()
ret.append(colon_).append(declType_.toTokens())
if (!isValidPosition(lCurl_) || !isValidPosition(rCurl_)) {
return ret
}
ret.append(lCurl_).append(Token(NL))
match (getter_) {
case Some(v) => ret.append(v.toTokens())
case None => ()
}
match (setter_) {
case Some(v) => ret.append(v.toTokens())
case None => ()
}
ret.append(rCurl_).append(Token(NL))
return ret
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
declType_.traverse(v)
match (getter_) {
case Some(node) => node.traverse(v)
case None => ()
}
match (setter_) {
case Some(node) => node.traverse(v)
case None => ()
}
return
}
protected func dump(indent: UInt16): String {
var ret: String = "PropDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
ret += getIndent(currentIndent) + "-declType: "
ret += declType_.dump(currentIndent)
match (getter_) {
case Some(v) =>
ret += getIndent(currentIndent) + "-getter: "
ret += v.dump(currentIndent)
case None => ()
}
match (setter_) {
case Some(v) =>
ret += getIndent(currentIndent) + "-setter: "
ret += v.dump(currentIndent)
case None => ()
}
ret += getIndent(indent) + "}\n"
ret
}
}
public class TypeAliasDecl <: Decl {
init(decl: Decl, assign: Token, aliasType: TypeNode) {
super(decl)
assign_ = assign
aliasType_ = aliasType
}
public init(inputs: Tokens) {
super(inputs)
match (super.node as TypeAliasDecl) {
case Some(v) =>
this.assign_ = v.assign_
this.aliasType_ = v.aliasType_
case None => throw ASTException("Cannot construct the 'TypeAliasDecl' node.")
}
}
public init() {
super()
}
private var assign_: Token = Token()
private var aliasType_: TypeNode = TypeNode()
public mut prop assign: Token {
get() {
assign_
}
set(v) {
checkTokenType(v, ASSIGN)
assign_ = v
}
}
public mut prop aliasType: TypeNode {
get() {
aliasType_
}
set(v) {
aliasType_ = v
}
}
public func toTokens(): Tokens {
var ret: Tokens = super.toTokens()
ret.append(assign).append(aliasType_.toTokens()).append(Token(NL))
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
this.traverseCommonChild(v)
aliasType_.traverse(v)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "TypeAliasDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += super.dump(currentIndent)
ret += getTokenIndent("-assign", assign_, currentIndent)
ret += getIndent(currentIndent) + "-aliasType: "
ret += aliasType_.dump(currentIndent)
ret += getIndent(indent) + "}\n"
ret
}
}
// Appends a qualified macro name to ret as IDENTIFIER (DOT IDENTIFIER)* tokens.
// DOT positions are derived from the original pkgIdentifier token.
private func appendMacroQualifiedIdentifier(ret: Tokens, pkgIdentifier: Token): Tokens {
var out = ret
let identArray = pkgIdentifier.value.split(".")
let identPos = pkgIdentifier.pos
var identColumn = identPos.column
for (i in 0..identArray.size - 1) {
let identifier = identArray[i]
out = out.append(Token(TokenKind.IDENTIFIER, identifier).addPosition(identPos))
identColumn = identColumn + Int32(identifier.size)
out = out.append(Token(TokenKind.DOT).addPosition(identPos.fileID, identPos.line, identColumn))
identColumn++
}
if (identArray.size > 0) {
let identifier = identArray[identArray.size - 1]
out = out + Token(TokenKind.IDENTIFIER, identifier).addPosition(identPos.fileID, identPos.line, identColumn)
}
out
}
private func appendMacroAttrs(ret: Tokens, lSquare: Token, macroAttrs: Tokens, rSquare: Token): Tokens {
var out = ret
if (isValidToken(lSquare) && isValidToken(rSquare)) {
out.append(lSquare).append(macroAttrs).append(rSquare)
}
out
}
private func appendDeclMacroInputTokens(ret: Tokens, lParen: Token, macroInputs: Tokens, rParen: Token,
macroInputDecl: Option<Decl>): Tokens {
var out = ret
if (isValidToken(lParen) && isValidToken(rParen)) {
out.append(lParen).append(macroInputs).append(rParen).append(Token(NL))
} else {
match (macroInputDecl) {
case Some(v) => out.append(Token(NL)).append(v)
case None => ()
}
}
out
}
private func traverseDeclMacroExpandChildren(decl: Decl, v: Visitor, macroInputDecl: Option<Decl>) {
decl.traverseCommonChild(v)
match (macroInputDecl) {
case Some(node) => node.traverse(v)
case None => ()
}
}
public class MacroExpandDecl <: Decl {
init(at: Token, fullIdentifier: Token, identifier: Token, lSquare: Token, macroAttrs: Tokens, rSquare: Token,
lParen: Token, macroInputs: Tokens, rParen: Token, macroInputDecl: Option<Decl>, hasParenthesis: Bool,
isCompileTimeVisible: Bool) {
super(at, identifier)
pkgIdentifier_ = fullIdentifier
lSquare_ = lSquare
macroAttrs_ = macroAttrs
rSquare_ = rSquare
lParen_ = lParen
macroInputs_ = macroInputs
rParen_ = rParen
macroInputDecl_ = macroInputDecl
hasParenthesis_ = hasParenthesis
isCompileTimeVisible_ = isCompileTimeVisible
}
public init(inputs: Tokens) {
try {
match (parseDecl(inputs) as MacroExpandDecl) {
case Some(v) =>
this.begin_ = v.beginPos
this.end_ = v.endPos
super.keyword = v.keyword
this.pkgIdentifier_ = v.pkgIdentifier_
super.identifier = v.identifier
this.lSquare_ = checkValid(v.lSquare_)
this.macroAttrs_ = v.macroAttrs_
this.rSquare_ = checkValid(v.rSquare_)
this.lParen_ = checkValid(v.lParen_)
this.macroInputs_ = v.macroInputs_
this.rParen_ = checkValid(v.rParen_)
this.macroInputDecl_ = v.macroInputDecl_
this.hasParenthesis_ = v.hasParenthesis_
this.isCompileTimeVisible_ = v.isCompileTimeVisible_
this.annotations = v.annotations
case None => throw ASTException("Cannot construct the 'MacroExpandDecl' node.")
}
} catch (e: ParseASTException) {
if (e.message == String.empty) {
throw ASTException("Cannot construct the 'MacroExpandDecl' node.")
} else {
throw ASTException(e.message)
}
}
}
public init() {}
private var pkgIdentifier_: Token = Token()
private var lSquare_: Token = Token()
private var macroAttrs_: Tokens = Tokens()
private var rSquare_: Token = Token()
private var lParen_: Token = Token()
private var macroInputs_: Tokens = Tokens()
private var rParen_: Token = Token()
private var macroInputDecl_: Option<Decl> = None<Decl>
private var hasParenthesis_: Bool = false
var isCompileTimeVisible_ = false
public mut prop fullIdentifier: Token {
get() {
pkgIdentifier_
}
set(v) {
pkgIdentifier_ = v
if (let Some(index) <- v.value.lastIndexOf(".")) {
identifier_ = Token(TokenKind.IDENTIFIER, v.value.split(".", removeEmpty: true).last.getOrThrow())
.addPosition(v.pos.fileID, v.pos.line, v.pos.column + Int32(index) + 1)
} else {
identifier_ = v
}
}
}
public override mut prop identifier: Token {
get() {
identifier_
}
set(v) {
let prefix = pkgIdentifier_.value.removeSuffix(identifier_.value)
identifier_ = v
let pos = pkgIdentifier_.pos
pkgIdentifier_ = Token(TokenKind.IDENTIFIER, prefix + v.value).addPosition(pos)
}
}
public mut prop lSquare: Token {
get() {
lSquare_
}
set(v) {
checkTokenType(v, LSQUARE)
lSquare_ = v
}
}
public mut prop macroAttrs: Tokens {
get() {
macroAttrs_
}
set(v) {
macroAttrs_ = v
}
}
public mut prop rSquare: Token {
get() {
rSquare_
}
set(v) {
checkTokenType(v, RSQUARE)
rSquare_ = v
}
}
public mut prop lParen: Token {
get() {
lParen_
}
set(v) {
checkTokenType(v, LPAREN)
lParen_ = v
}
}
public mut prop macroInputs: Tokens {
get() {
macroInputs_
}
set(v) {
macroInputs_ = v
macroInputDecl_ = try {
Some(parseDecl(v))
} catch (e: ParseASTException | ASTException) {
None
}
}
}
public mut prop rParen: Token {
get() {
rParen_
}
set(v) {
checkTokenType(v, RPAREN)
rParen_ = v
}
}
public mut prop macroInputDecl: Decl {
get() {
match (macroInputDecl_) {
case Some(v) => v
case None => throw ASTException()
}
}
set(v) {
macroInputDecl_ = Some(v)
macroInputs_ = v.toTokens()
}
}
public func toTokens(): Tokens {
var ret = Tokens()
for (i in 0..annotations.size) {
ret.append(annotations[i].toTokens())
}
ret.append(keyword)
ret = appendMacroQualifiedIdentifier(ret, pkgIdentifier_)
ret = appendMacroAttrs(ret, lSquare_, macroAttrs_, rSquare_)
ret = appendDeclMacroInputTokens(ret, lParen_, macroInputs_, rParen_, macroInputDecl_)
ret
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
traverseDeclMacroExpandChildren(this, v, macroInputDecl_)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "MacroExpandDecl {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += getTokenIndent("-identifier", identifier, currentIndent)
for (i in 0..annotations.size) {
ret += getIndent(currentIndent) + "-annotations: ${i}, "
ret += annotations[i].dump(currentIndent)
}
for (i in 0..macroAttrs_.size) {
ret += getTokenIndent("-macroAttrs ${i}", macroAttrs[i], currentIndent)
}
for (i in 0..macroInputs_.size) {
ret += getTokenIndent("-macroInputs ${i}", macroInputs[i], currentIndent)
}
match (macroInputDecl_) {
case Some(node) =>
ret += getIndent(currentIndent) + "-macroInputDecl: "
ret += node.dump(currentIndent)
case None => ()
}
ret += getIndent(indent) + "}\n"
ret
}
}
public class MacroExpandParam <: FuncParam {
init(at: Token, fullIdentifier: Token, identifier: Token, lSquare: Token, macroAttrs: Tokens, rSquare: Token,
lParen: Token, macroInputs: Tokens, rParen: Token, macroInputDecl: Option<Decl>, hasParenthesis: Bool,
isCompileTimeVisible: Bool) {
super(at, identifier)
pkgIdentifier_ = fullIdentifier
lSquare_ = lSquare
macroAttrs_ = macroAttrs
rSquare_ = rSquare
lParen_ = lParen
macroInputs_ = macroInputs
rParen_ = rParen
macroInputDecl_ = macroInputDecl
hasParenthesis_ = hasParenthesis
isCompileTimeVisible_ = isCompileTimeVisible
}
public init() {}
private var pkgIdentifier_: Token = Token()
private var lSquare_: Token = Token()
private var macroAttrs_: Tokens = Tokens()
private var rSquare_: Token = Token()
private var lParen_: Token = Token()
private var macroInputs_: Tokens = Tokens()
private var rParen_: Token = Token()
private var macroInputDecl_: Option<Decl> = None<Decl>
private var hasParenthesis_: Bool = false
var isCompileTimeVisible_ = false
public mut prop fullIdentifier: Token {
get() {
pkgIdentifier_
}
set(v) {
pkgIdentifier_ = v
if (let Some(index) <- v.value.lastIndexOf(".")) {
identifier_ = Token(TokenKind.IDENTIFIER, v.value.split(".", removeEmpty: true).last.getOrThrow())
.addPosition(v.pos.fileID, v.pos.line, v.pos.column + Int32(index) + 1)
} else {
identifier_ = v
}
}
}
public override mut prop identifier: Token {
get() {
identifier_
}
set(v) {
let prefix = pkgIdentifier_.value.removeSuffix(identifier_.value)
identifier_ = v
let pos = pkgIdentifier_.pos
pkgIdentifier_ = Token(TokenKind.IDENTIFIER, prefix + v.value).addPosition(pos)
}
}
public mut prop lSquare: Token {
get() {
lSquare_
}
set(v) {
checkTokenType(v, LSQUARE)
lSquare_ = v
}
}
public mut prop macroAttrs: Tokens {
get() {
macroAttrs_
}
set(v) {
macroAttrs_ = v
}
}
public mut prop rSquare: Token {
get() {
rSquare_
}
set(v) {
checkTokenType(v, RSQUARE)
rSquare_ = v
}
}
public mut prop lParen: Token {
get() {
lParen_
}
set(v) {
checkTokenType(v, LPAREN)
lParen_ = v
}
}
public mut prop macroInputs: Tokens {
get() {
macroInputs_
}
set(v) {
macroInputs_ = v
macroInputDecl_ = try {
Some(FuncParam(v))
} catch (e: ParseASTException | ASTException) {
None
}
}
}
public mut prop rParen: Token {
get() {
rParen_
}
set(v) {
checkTokenType(v, RPAREN)
rParen_ = v
}
}
public mut prop macroInputDecl: Decl {
get() {
match (macroInputDecl_) {
case Some(v) => v
case None => throw ASTException()
}
}
set(v) {
macroInputDecl_ = Some(v)
macroInputs_ = v.toTokens()
}
}
public func toTokens(): Tokens {
var ret = Tokens()
for (i in 0..annotations.size) {
ret.append(annotations[i].toTokens())
}
ret.append(keyword)
ret = appendMacroQualifiedIdentifier(ret, pkgIdentifier_)
ret = appendMacroAttrs(ret, lSquare_, macroAttrs_, rSquare_)
ret = appendDeclMacroInputTokens(ret, lParen_, macroInputs_, rParen_, macroInputDecl_)
ret
}
public func traverse(v: Visitor): Unit {
v.visit(this)
super.traverse(v)
if (v.needBreakTraverse()) {
return
}
traverseDeclMacroExpandChildren(this, v, macroInputDecl_)
return
}
protected func dump(indent: UInt16): String {
var ret: String = "MacroExpandParam {\n"
currentIndent = indent
if (indent != 0 || beginNode) {
currentIndent++
}
ret += getTokenIndent("-identifier", identifier, currentIndent)
for (i in 0..annotations.size) {
ret += getIndent(currentIndent) + "-annotations: ${i}, "
ret += annotations[i].dump(currentIndent)
}
for (i in 0..macroAttrs_.size) {
ret += getTokenIndent("-macroAttrs ${i}", macroAttrs[i], currentIndent)
}
for (i in 0..macroInputs_.size) {
ret += getTokenIndent("-macroInputs ${i}", macroInputs[i], currentIndent)
}
match (macroInputDecl_) {
case Some(node) =>
ret += getIndent(currentIndent) + "-macroInputDecl: "
ret += node.dump(currentIndent)
case None => ()
}
ret += getIndent(indent) + "}\n"
ret
}
}