[IR generator] Simplify configuration of visitor parents
Don't specify a visitor parent manually for each IR node, use an algorithm instead.
This commit is contained in:
committed by
Space Team
parent
62d32471e1
commit
a5b5492b2d
-5
@@ -79,11 +79,6 @@ class Element(name: String, override val propertyName: String, kind: Kind) : Abs
|
||||
override val visitorParameterName: String
|
||||
get() = safeDecapitalizedName
|
||||
|
||||
var customParentInVisitor: Element? = null
|
||||
|
||||
override val parentInVisitor: Element?
|
||||
get() = customParentInVisitor ?: elementParents.singleOrNull()?.element?.takeIf { !it.isRootElement }
|
||||
|
||||
var doesNotNeedImplementation: Boolean = false
|
||||
|
||||
val needTransformOtherChildren: Boolean get() = _needTransformOtherChildren || elementParents.any { it.element.needTransformOtherChildren }
|
||||
|
||||
+2
-2
@@ -461,7 +461,7 @@ class ExpressionCodegen(
|
||||
}
|
||||
}
|
||||
|
||||
private fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock, data: BlockInfo): PromisedValue {
|
||||
private fun generateInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock, data: BlockInfo): PromisedValue {
|
||||
val inlineCall = inlinedBlock.inlineCall
|
||||
val callee = inlinedBlock.inlineDeclaration as? IrFunction
|
||||
|
||||
@@ -559,7 +559,7 @@ class ExpressionCodegen(
|
||||
|
||||
private fun visitStatementContainer(container: IrStatementContainer, data: BlockInfo): PromisedValue {
|
||||
if (container is IrInlinedFunctionBlock) {
|
||||
return visitInlinedFunctionBlock(container, data)
|
||||
return generateInlinedFunctionBlock(container, data)
|
||||
}
|
||||
return container.statements.fold(unitValue) { prev, exp ->
|
||||
prev.discard()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
/**
|
||||
* A leaf IR tree element.
|
||||
@@ -19,4 +20,7 @@ abstract class IrInlinedFunctionBlock : IrBlock() {
|
||||
abstract var inlineCall: IrFunctionAccessExpression
|
||||
|
||||
abstract var inlinedElement: IrElement
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitInlinedFunctionBlock(this, data)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ package org.jetbrains.kotlin.ir.expressions
|
||||
import org.jetbrains.kotlin.ir.declarations.IrReturnTarget
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
/**
|
||||
* A leaf IR tree element.
|
||||
@@ -19,4 +20,7 @@ import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
*/
|
||||
abstract class IrReturnableBlock : IrBlock(), IrSymbolOwner, IrReturnTarget {
|
||||
abstract override val symbol: IrReturnableBlockSymbol
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitReturnableBlock(this, data)
|
||||
}
|
||||
|
||||
@@ -140,6 +140,12 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
|
||||
override fun visitComposite(expression: IrComposite, data: D): IrExpression =
|
||||
visitContainerExpression(expression, data)
|
||||
|
||||
override fun visitReturnableBlock(expression: IrReturnableBlock, data: D): IrExpression =
|
||||
visitBlock(expression, data)
|
||||
|
||||
override fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock, data: D): IrExpression =
|
||||
visitBlock(inlinedBlock, data)
|
||||
|
||||
override fun visitSyntheticBody(body: IrSyntheticBody, data: D): IrBody =
|
||||
visitBody(body, data)
|
||||
|
||||
|
||||
@@ -256,6 +256,18 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
|
||||
final override fun visitComposite(expression: IrComposite, data: Nothing?): IrExpression =
|
||||
visitComposite(expression)
|
||||
|
||||
open fun visitReturnableBlock(expression: IrReturnableBlock): IrExpression =
|
||||
visitBlock(expression)
|
||||
|
||||
final override fun visitReturnableBlock(expression: IrReturnableBlock, data: Nothing?): IrExpression =
|
||||
visitReturnableBlock(expression)
|
||||
|
||||
open fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock): IrExpression =
|
||||
visitBlock(inlinedBlock)
|
||||
|
||||
final override fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock, data: Nothing?): IrExpression =
|
||||
visitInlinedFunctionBlock(inlinedBlock)
|
||||
|
||||
open fun visitSyntheticBody(body: IrSyntheticBody): IrBody =
|
||||
visitBody(body)
|
||||
|
||||
|
||||
@@ -124,6 +124,12 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitComposite(expression: IrComposite, data: D): R =
|
||||
visitContainerExpression(expression, data)
|
||||
|
||||
fun visitReturnableBlock(expression: IrReturnableBlock, data: D): R =
|
||||
visitBlock(expression, data)
|
||||
|
||||
fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock, data: D): R =
|
||||
visitBlock(inlinedBlock, data)
|
||||
|
||||
fun visitSyntheticBody(body: IrSyntheticBody, data: D): R =
|
||||
visitBody(body, data)
|
||||
|
||||
|
||||
@@ -304,6 +304,22 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
|
||||
visitContainerExpression(expression)
|
||||
}
|
||||
|
||||
override fun visitReturnableBlock(expression: IrReturnableBlock, data: Nothing?) {
|
||||
visitReturnableBlock(expression)
|
||||
}
|
||||
|
||||
fun visitReturnableBlock(expression: IrReturnableBlock) {
|
||||
visitBlock(expression)
|
||||
}
|
||||
|
||||
override fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock, data: Nothing?) {
|
||||
visitInlinedFunctionBlock(inlinedBlock)
|
||||
}
|
||||
|
||||
fun visitInlinedFunctionBlock(inlinedBlock: IrInlinedFunctionBlock) {
|
||||
visitBlock(inlinedBlock)
|
||||
}
|
||||
|
||||
override fun visitSyntheticBody(body: IrSyntheticBody, data: Nothing?) {
|
||||
visitSyntheticBody(body)
|
||||
}
|
||||
|
||||
+21
-137
@@ -48,6 +48,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
private fun declarationWithLateBinding(symbol: ClassRef<*>, initializer: Element.() -> Unit) = element(Declaration) {
|
||||
initializer()
|
||||
|
||||
noAcceptMethod()
|
||||
noMethodInVisitor()
|
||||
|
||||
fieldsToSkipInIrFactoryMethod.add("symbol")
|
||||
fieldsToSkipInIrFactoryMethod.add("containerSource")
|
||||
|
||||
@@ -72,8 +75,8 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
|
||||
override val rootElement: Element by element(Other, name = "Element") {
|
||||
hasAcceptMethod = true
|
||||
hasTransformMethod = true
|
||||
needAcceptMethod()
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
|
||||
fun offsetField(prefix: String) = field(prefix + "Offset", int, mutable = false) {
|
||||
@@ -110,7 +113,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
typeKind = TypeKind.Class
|
||||
transformByChildren = true
|
||||
transformerReturnType = statement
|
||||
parentInVisitor = rootElement
|
||||
nameInVisitorMethod = "Declaration"
|
||||
|
||||
parent(declaration)
|
||||
@@ -194,8 +196,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("isAssignable", boolean, mutable = false)
|
||||
}
|
||||
val valueParameter: Element by element(Declaration) {
|
||||
hasTransformMethod = true
|
||||
parentInVisitor = declarationBase
|
||||
needTransformMethod()
|
||||
|
||||
parent(declarationBase)
|
||||
parent(valueDeclaration)
|
||||
@@ -239,8 +240,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("defaultValue", expressionBody, nullable = true, isChild = true)
|
||||
}
|
||||
val `class`: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
parent(possiblyExternalDeclaration)
|
||||
parent(declarationWithVisibility)
|
||||
@@ -325,8 +324,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val anonymousInitializer: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
|
||||
+descriptor("ClassDescriptor") // TODO special descriptor for anonymous initializer blocks
|
||||
@@ -360,8 +357,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+listField("typeParameters", typeParameter, mutability = Var, isChild = true)
|
||||
}
|
||||
val typeParameter: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
hasTransformMethod = true
|
||||
needTransformMethod()
|
||||
|
||||
parent(declarationBase)
|
||||
parent(declarationWithName)
|
||||
@@ -382,8 +378,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+symbol(returnTargetSymbolType)
|
||||
}
|
||||
val function: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
parent(possiblyExternalDeclaration)
|
||||
parent(declarationWithVisibility)
|
||||
@@ -410,8 +404,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("body", body, nullable = true, isChild = true)
|
||||
}
|
||||
val constructor: Element by element(Declaration) {
|
||||
parentInVisitor = function
|
||||
|
||||
parent(function)
|
||||
|
||||
+descriptor("ClassConstructorDescriptor")
|
||||
@@ -419,8 +411,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("isPrimary", boolean)
|
||||
}
|
||||
val enumEntry: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
parent(declarationWithName)
|
||||
|
||||
@@ -430,8 +420,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("correspondingClass", `class`, nullable = true, isChild = true)
|
||||
}
|
||||
val errorDeclaration: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
|
||||
additionalIrFactoryMethodParameters.add(
|
||||
@@ -454,8 +442,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
parent(property)
|
||||
}
|
||||
val field: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
parent(possiblyExternalDeclaration)
|
||||
parent(declarationWithVisibility)
|
||||
@@ -473,8 +459,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val localDelegatedProperty: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
parent(declarationWithName)
|
||||
parent(symbolOwner)
|
||||
@@ -489,8 +473,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("setter", simpleFunction, nullable = true, isChild = true)
|
||||
}
|
||||
val moduleFragment: Element by element(Declaration) {
|
||||
parentInVisitor = rootElement
|
||||
hasTransformMethod = true
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
@@ -509,7 +492,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val property: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
isLeaf = true
|
||||
|
||||
parent(declarationBase)
|
||||
@@ -541,7 +523,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
//TODO: make IrScript as IrPackageFragment, because script is used as a file, not as a class
|
||||
//NOTE: declarations and statements stored separately
|
||||
val script: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
parent(declarationBase)
|
||||
@@ -567,7 +548,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("constructor", constructor, nullable = true) // K1
|
||||
}
|
||||
val simpleFunction: Element by element(Declaration) {
|
||||
parentInVisitor = function
|
||||
isLeaf = true
|
||||
|
||||
parent(function)
|
||||
@@ -585,8 +565,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val typeAlias: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
parent(declarationBase)
|
||||
parent(declarationWithName)
|
||||
parent(declarationWithVisibility)
|
||||
@@ -598,8 +576,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("expandedType", irTypeType)
|
||||
}
|
||||
val variable: Element by element(Declaration) {
|
||||
parentInVisitor = declarationBase
|
||||
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
parent(declarationBase)
|
||||
@@ -613,7 +589,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("initializer", expression, nullable = true, isChild = true)
|
||||
}
|
||||
val packageFragment: Element by element(Declaration) {
|
||||
parentInVisitor = rootElement
|
||||
ownsChildren = false
|
||||
|
||||
parent(declarationContainer)
|
||||
@@ -643,7 +618,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val externalPackageFragment: Element by element(Declaration) {
|
||||
parentInVisitor = packageFragment
|
||||
transformByChildren = true
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
@@ -653,9 +627,8 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("containerSource", type<DeserializedContainerSource>(), nullable = true, mutable = false)
|
||||
}
|
||||
val file: Element by element(Declaration) {
|
||||
hasTransformMethod = true
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
parentInVisitor = packageFragment
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
parent(packageFragment)
|
||||
@@ -668,8 +641,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
|
||||
val expression: Element by element(Expression) {
|
||||
parentInVisitor = rootElement
|
||||
hasTransformMethod = true
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
|
||||
parent(statement)
|
||||
@@ -692,15 +664,13 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+listField("statements", statement, mutability = List, isChild = true)
|
||||
}
|
||||
val body: Element by element(Expression) {
|
||||
hasTransformMethod = true
|
||||
parentInVisitor = rootElement
|
||||
needTransformMethod()
|
||||
visitorParameterName = "body"
|
||||
transformByChildren = true
|
||||
typeKind = TypeKind.Class
|
||||
}
|
||||
val expressionBody: Element by element(Expression) {
|
||||
hasTransformMethod = true
|
||||
parentInVisitor = body
|
||||
needTransformMethod()
|
||||
visitorParameterName = "body"
|
||||
generateIrFactoryMethod = true
|
||||
|
||||
@@ -712,7 +682,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val blockBody: Element by element(Expression) {
|
||||
parentInVisitor = body
|
||||
visitorParameterName = "body"
|
||||
generateIrFactoryMethod = true
|
||||
|
||||
@@ -722,15 +691,12 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+factory
|
||||
}
|
||||
val declarationReference: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+symbol(symbolType)
|
||||
//diff: no accept
|
||||
}
|
||||
val memberAccessExpression: Element by element(Expression) {
|
||||
parentInVisitor = declarationReference
|
||||
nameInVisitorMethod = "MemberAccess"
|
||||
transformerReturnType = rootElement
|
||||
val s = +param("S", symbolType)
|
||||
@@ -812,7 +778,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val functionAccessExpression: Element by element(Expression) {
|
||||
parentInVisitor = memberAccessExpression
|
||||
nameInVisitorMethod = "FunctionAccess"
|
||||
transformerReturnType = rootElement
|
||||
|
||||
@@ -821,7 +786,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("contextReceiversCount", int)
|
||||
}
|
||||
val constructorCall: Element by element(Expression) {
|
||||
parentInVisitor = functionAccessExpression
|
||||
transformerReturnType = rootElement
|
||||
|
||||
parent(functionAccessExpression)
|
||||
@@ -833,20 +797,17 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("constructorTypeArgumentsCount", int)
|
||||
}
|
||||
val getSingletonValue: Element by element(Expression) {
|
||||
parentInVisitor = declarationReference
|
||||
nameInVisitorMethod = "SingletonReference"
|
||||
|
||||
parent(declarationReference)
|
||||
}
|
||||
val getObjectValue: Element by element(Expression) {
|
||||
parentInVisitor = getSingletonValue
|
||||
|
||||
parent(getSingletonValue)
|
||||
|
||||
+symbol(classSymbolType, mutable = true)
|
||||
}
|
||||
val getEnumValue: Element by element(Expression) {
|
||||
parentInVisitor = getSingletonValue
|
||||
|
||||
parent(getSingletonValue)
|
||||
|
||||
@@ -860,15 +821,12 @@ object IrTree : AbstractTreeBuilder() {
|
||||
* On JVM platform it represents a MethodHandle constant.
|
||||
*/
|
||||
val rawFunctionReference: Element by element(Expression) {
|
||||
parentInVisitor = declarationReference
|
||||
|
||||
parent(declarationReference)
|
||||
|
||||
+symbol(functionSymbolType, mutable = true)
|
||||
}
|
||||
val containerExpression: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
parent(statementContainer)
|
||||
|
||||
@@ -878,14 +836,11 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val block: Element by element(Expression) {
|
||||
parentInVisitor = containerExpression
|
||||
hasAcceptMethod = true
|
||||
needAcceptMethod()
|
||||
|
||||
parent(containerExpression)
|
||||
}
|
||||
val composite: Element by element(Expression) {
|
||||
parentInVisitor = containerExpression
|
||||
|
||||
parent(containerExpression)
|
||||
}
|
||||
val returnableBlock: Element by element(Expression) {
|
||||
@@ -898,11 +853,12 @@ object IrTree : AbstractTreeBuilder() {
|
||||
val inlinedFunctionBlock: Element by element(Expression) {
|
||||
parent(block)
|
||||
|
||||
visitorParameterName = "inlinedBlock"
|
||||
|
||||
+field("inlineCall", functionAccessExpression)
|
||||
+field("inlinedElement", rootElement)
|
||||
}
|
||||
val syntheticBody: Element by element(Expression) {
|
||||
parentInVisitor = body
|
||||
visitorParameterName = "body"
|
||||
|
||||
parent(body)
|
||||
@@ -910,7 +866,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("kind", type(Packages.exprs, "IrSyntheticBodyKind"))
|
||||
}
|
||||
val breakContinue: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
visitorParameterName = "jump"
|
||||
|
||||
parent(expression)
|
||||
@@ -921,27 +876,22 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val `break` by element(Expression) {
|
||||
parentInVisitor = breakContinue
|
||||
visitorParameterName = "jump"
|
||||
|
||||
parent(breakContinue)
|
||||
}
|
||||
val `continue` by element(Expression) {
|
||||
parentInVisitor = breakContinue
|
||||
visitorParameterName = "jump"
|
||||
|
||||
parent(breakContinue)
|
||||
}
|
||||
val call: Element by element(Expression) {
|
||||
parentInVisitor = functionAccessExpression
|
||||
|
||||
parent(functionAccessExpression)
|
||||
|
||||
+symbol(simpleFunctionSymbolType, mutable = true)
|
||||
+field("superQualifierSymbol", classSymbolType, nullable = true)
|
||||
}
|
||||
val callableReference: Element by element(Expression) {
|
||||
parentInVisitor = memberAccessExpression
|
||||
val s = +param("S", symbolType)
|
||||
|
||||
parent(memberAccessExpression.withArgs("S" to s))
|
||||
@@ -949,15 +899,12 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+symbol(s, mutable = true)
|
||||
}
|
||||
val functionReference: Element by element(Expression) {
|
||||
parentInVisitor = callableReference
|
||||
|
||||
parent(callableReference.withArgs("S" to functionSymbolType))
|
||||
|
||||
+field("reflectionTarget", functionSymbolType, nullable = true)
|
||||
}
|
||||
val propertyReference: Element by element(Expression) {
|
||||
parentInVisitor = callableReference
|
||||
|
||||
parent(callableReference.withArgs("S" to propertySymbolType))
|
||||
|
||||
+field("field", fieldSymbolType, nullable = true)
|
||||
@@ -965,8 +912,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("setter", simpleFunctionSymbolType, nullable = true)
|
||||
}
|
||||
val localDelegatedPropertyReference: Element by element(Expression) {
|
||||
parentInVisitor = callableReference
|
||||
|
||||
parent(callableReference.withArgs("S" to localDelegatedPropertySymbolType))
|
||||
|
||||
+field("delegate", variableSymbolType)
|
||||
@@ -974,15 +919,12 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("setter", simpleFunctionSymbolType, nullable = true)
|
||||
}
|
||||
val classReference: Element by element(Expression) {
|
||||
parentInVisitor = declarationReference
|
||||
|
||||
parent(declarationReference)
|
||||
|
||||
+symbol(classifierSymbolType, mutable = true)
|
||||
+field("classType", irTypeType)
|
||||
}
|
||||
val const: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
val t = +param("T")
|
||||
|
||||
parent(expression)
|
||||
@@ -991,7 +933,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("value", t)
|
||||
}
|
||||
val constantValue: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
transformByChildren = true
|
||||
|
||||
parent(expression)
|
||||
@@ -1016,15 +957,11 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val constantPrimitive: Element by element(Expression) {
|
||||
parentInVisitor = constantValue
|
||||
|
||||
parent(constantValue)
|
||||
|
||||
+field("value", const.withArgs("T" to TypeRef.Star), isChild = true)
|
||||
}
|
||||
val constantObject: Element by element(Expression) {
|
||||
parentInVisitor = constantValue
|
||||
|
||||
parent(constantValue)
|
||||
|
||||
+field("constructor", constructorSymbolType)
|
||||
@@ -1032,27 +969,19 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+listField("typeArguments", irTypeType, mutability = List)
|
||||
}
|
||||
val constantArray: Element by element(Expression) {
|
||||
parentInVisitor = constantValue
|
||||
|
||||
parent(constantValue)
|
||||
|
||||
+listField("elements", constantValue, mutability = List, isChild = true)
|
||||
}
|
||||
val delegatingConstructorCall: Element by element(Expression) {
|
||||
parentInVisitor = functionAccessExpression
|
||||
|
||||
parent(functionAccessExpression)
|
||||
|
||||
+symbol(constructorSymbolType, mutable = true)
|
||||
}
|
||||
val dynamicExpression: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
}
|
||||
val dynamicOperatorExpression: Element by element(Expression) {
|
||||
parentInVisitor = dynamicExpression
|
||||
|
||||
parent(dynamicExpression)
|
||||
|
||||
+field("operator", type(Packages.exprs, "IrDynamicOperator"))
|
||||
@@ -1060,38 +989,30 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+listField("arguments", expression, mutability = List, isChild = true)
|
||||
}
|
||||
val dynamicMemberExpression: Element by element(Expression) {
|
||||
parentInVisitor = dynamicExpression
|
||||
|
||||
parent(dynamicExpression)
|
||||
|
||||
+field("memberName", string)
|
||||
+field("receiver", expression, isChild = true)
|
||||
}
|
||||
val enumConstructorCall: Element by element(Expression) {
|
||||
parentInVisitor = functionAccessExpression
|
||||
|
||||
parent(functionAccessExpression)
|
||||
|
||||
+symbol(constructorSymbolType, mutable = true)
|
||||
}
|
||||
val errorExpression: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
hasAcceptMethod = true
|
||||
needAcceptMethod()
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("description", string)
|
||||
}
|
||||
val errorCallExpression: Element by element(Expression) {
|
||||
parentInVisitor = errorExpression
|
||||
|
||||
parent(errorExpression)
|
||||
|
||||
+field("explicitReceiver", expression, nullable = true, isChild = true)
|
||||
+listField("arguments", expression, mutability = List, isChild = true)
|
||||
}
|
||||
val fieldAccessExpression: Element by element(Expression) {
|
||||
parentInVisitor = declarationReference
|
||||
nameInVisitorMethod = "FieldAccess"
|
||||
ownsChildren = false
|
||||
|
||||
@@ -1105,19 +1026,14 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("origin", statementOriginType, nullable = true)
|
||||
}
|
||||
val getField: Element by element(Expression) {
|
||||
parentInVisitor = fieldAccessExpression
|
||||
|
||||
parent(fieldAccessExpression)
|
||||
}
|
||||
val setField: Element by element(Expression) {
|
||||
parentInVisitor = fieldAccessExpression
|
||||
|
||||
parent(fieldAccessExpression)
|
||||
|
||||
+field("value", expression, isChild = true)
|
||||
}
|
||||
val functionExpression: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
transformerReturnType = rootElement
|
||||
|
||||
parent(expression)
|
||||
@@ -1126,21 +1042,16 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("function", simpleFunction, isChild = true)
|
||||
}
|
||||
val getClass: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("argument", expression, isChild = true)
|
||||
}
|
||||
val instanceInitializerCall: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("classSymbol", classSymbolType)
|
||||
}
|
||||
val loop: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
visitorParameterName = "loop"
|
||||
ownsChildren = false
|
||||
|
||||
@@ -1156,36 +1067,28 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
val whileLoop: Element by element(Expression) {
|
||||
parentInVisitor = loop
|
||||
visitorParameterName = "loop"
|
||||
childrenOrderOverride = listOf("condition", "body")
|
||||
|
||||
parent(loop)
|
||||
}
|
||||
val doWhileLoop: Element by element(Expression) {
|
||||
parentInVisitor = loop
|
||||
visitorParameterName = "loop"
|
||||
|
||||
parent(loop)
|
||||
}
|
||||
val `return`: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("value", expression, isChild = true)
|
||||
+field("returnTargetSymbol", returnTargetSymbolType)
|
||||
}
|
||||
val stringConcatenation: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+listField("arguments", expression, mutability = List, isChild = true)
|
||||
}
|
||||
val suspensionPoint: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("suspensionPointIdParameter", variable, isChild = true)
|
||||
@@ -1193,22 +1096,17 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("resumeResult", expression, isChild = true)
|
||||
}
|
||||
val suspendableExpression: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("suspensionPointId", expression, isChild = true)
|
||||
+field("result", expression, isChild = true)
|
||||
}
|
||||
val `throw`: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("value", expression, isChild = true)
|
||||
}
|
||||
val `try`: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
visitorParameterName = "aTry"
|
||||
|
||||
parent(expression)
|
||||
@@ -1218,16 +1116,14 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("finallyExpression", expression, nullable = true, isChild = true)
|
||||
}
|
||||
val catch: Element by element(Expression) {
|
||||
parentInVisitor = rootElement
|
||||
visitorParameterName = "aCatch"
|
||||
hasTransformMethod = true
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
|
||||
+field("catchParameter", variable, isChild = true)
|
||||
+field("result", expression, isChild = true)
|
||||
}
|
||||
val typeOperatorCall: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
nameInVisitorMethod = "TypeOperator"
|
||||
|
||||
parent(expression)
|
||||
@@ -1237,7 +1133,6 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("typeOperand", irTypeType)
|
||||
}
|
||||
val valueAccessExpression: Element by element(Expression) {
|
||||
parentInVisitor = declarationReference
|
||||
nameInVisitorMethod = "ValueAccess"
|
||||
|
||||
parent(declarationReference)
|
||||
@@ -1246,30 +1141,23 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("origin", statementOriginType, nullable = true)
|
||||
}
|
||||
val getValue: Element by element(Expression) {
|
||||
parentInVisitor = valueAccessExpression
|
||||
|
||||
parent(valueAccessExpression)
|
||||
}
|
||||
val setValue: Element by element(Expression) {
|
||||
parentInVisitor = valueAccessExpression
|
||||
|
||||
parent(valueAccessExpression)
|
||||
|
||||
+field("value", expression, isChild = true)
|
||||
}
|
||||
val varargElement: Element by element(Expression)
|
||||
val vararg: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("varargElementType", irTypeType)
|
||||
+listField("elements", varargElement, mutability = List, isChild = true)
|
||||
}
|
||||
val spreadElement: Element by element(Expression) {
|
||||
parentInVisitor = rootElement
|
||||
visitorParameterName = "spread"
|
||||
hasTransformMethod = true
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
|
||||
parent(varargElement)
|
||||
@@ -1277,27 +1165,23 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("expression", expression, isChild = true)
|
||||
}
|
||||
val `when`: Element by element(Expression) {
|
||||
parentInVisitor = expression
|
||||
|
||||
parent(expression)
|
||||
|
||||
+field("origin", statementOriginType, nullable = true)
|
||||
+listField("branches", branch, mutability = List, isChild = true)
|
||||
}
|
||||
val branch: Element by element(Expression) {
|
||||
parentInVisitor = rootElement
|
||||
visitorParameterName = "branch"
|
||||
hasAcceptMethod = true
|
||||
hasTransformMethod = true
|
||||
needAcceptMethod()
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
|
||||
+field("condition", expression, isChild = true)
|
||||
+field("result", expression, isChild = true)
|
||||
}
|
||||
val elseBranch: Element by element(Expression) {
|
||||
parentInVisitor = branch
|
||||
visitorParameterName = "branch"
|
||||
hasTransformMethod = true
|
||||
needTransformMethod()
|
||||
transformByChildren = true
|
||||
|
||||
parent(branch)
|
||||
|
||||
+16
@@ -50,6 +50,22 @@ abstract class AbstractTreeBuilder {
|
||||
elementParents.add(ElementRef(type.element, type.args, type.nullable))
|
||||
}
|
||||
|
||||
protected fun Element.needAcceptMethod() {
|
||||
customHasAcceptMethod = true
|
||||
}
|
||||
|
||||
protected fun Element.noAcceptMethod() {
|
||||
customHasAcceptMethod = false
|
||||
}
|
||||
|
||||
protected fun Element.needTransformMethod() {
|
||||
hasTransformMethod = true
|
||||
}
|
||||
|
||||
protected fun Element.noMethodInVisitor() {
|
||||
generateVisitorMethod = false
|
||||
}
|
||||
|
||||
protected fun param(name: String, vararg bounds: TypeRef, variance: Variance = Variance.INVARIANT): TypeVariable {
|
||||
return TypeVariable(name, bounds.toList(), variance)
|
||||
}
|
||||
|
||||
+20
-2
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.ir.generator.model
|
||||
import org.jetbrains.kotlin.generators.tree.*
|
||||
import org.jetbrains.kotlin.generators.tree.ListField as AbstractListField
|
||||
import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE
|
||||
import org.jetbrains.kotlin.ir.generator.IrTree
|
||||
import org.jetbrains.kotlin.ir.generator.elementBaseType
|
||||
import org.jetbrains.kotlin.utils.SmartPrinter
|
||||
import org.jetbrains.kotlin.utils.topologicalSort
|
||||
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
|
||||
@@ -53,7 +55,19 @@ class Element(
|
||||
override val args: Map<NamedTypeParameterRef, TypeRef>
|
||||
get() = emptyMap()
|
||||
|
||||
override var parentInVisitor: Element? = null
|
||||
/**
|
||||
* Allows to forcibly skip generation of the method for this element in visitors.
|
||||
*/
|
||||
var generateVisitorMethod = true
|
||||
|
||||
override val parentInVisitor: Element?
|
||||
get() {
|
||||
if (!generateVisitorMethod) return null
|
||||
return customParentInVisitor
|
||||
?: elementParents.singleOrNull { it.typeKind == TypeKind.Class }?.element
|
||||
?: IrTree.rootElement.takeIf { elementBaseType in otherParents }
|
||||
}
|
||||
|
||||
|
||||
var typeKind: TypeKind? = null
|
||||
set(value) {
|
||||
@@ -86,7 +100,11 @@ class Element(
|
||||
|
||||
override var visitorParameterName = category.defaultVisitorParam
|
||||
|
||||
override var hasAcceptMethod = false // By default, accept is generated only for leaves.
|
||||
var customHasAcceptMethod: Boolean? = null
|
||||
|
||||
override val hasAcceptMethod: Boolean
|
||||
get() = customHasAcceptMethod ?: (isLeaf && parentInVisitor != null)
|
||||
|
||||
|
||||
override var hasTransformMethod = false
|
||||
|
||||
|
||||
-3
@@ -37,9 +37,6 @@ internal fun markLeaves(elements: List<Element>) {
|
||||
|
||||
for (el in leaves) {
|
||||
el.isLeaf = true
|
||||
if (el.parentInVisitor != null) {
|
||||
el.hasAcceptMethod = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -56,10 +56,16 @@ abstract class AbstractElement<Element, Field>(
|
||||
*/
|
||||
abstract val visitorParameterName: String
|
||||
|
||||
/**
|
||||
* @see parentInVisitor
|
||||
*/
|
||||
var customParentInVisitor: Element? = null
|
||||
|
||||
/**
|
||||
* The default element to visit if the method for visiting this element is not overridden.
|
||||
*/
|
||||
abstract val parentInVisitor: Element?
|
||||
open val parentInVisitor: Element?
|
||||
get() = customParentInVisitor ?: elementParents.singleOrNull()?.element?.takeIf { !it.isRootElement }
|
||||
|
||||
override val allParents: List<Element>
|
||||
get() = elementParents.map { it.element }
|
||||
@@ -92,7 +98,7 @@ abstract class AbstractElement<Element, Field>(
|
||||
/**
|
||||
* The return type of the corresponding transformer method for this element.
|
||||
*
|
||||
* By default, computed using [org.jetbrains.kotlin.generators.tree.detectBaseTransformerTypes], but can be customizaed via
|
||||
* By default, computed using [org.jetbrains.kotlin.generators.tree.detectBaseTransformerTypes], but can be customized via
|
||||
* [transformerReturnType]
|
||||
*/
|
||||
val transformerClass: Element
|
||||
|
||||
@@ -11,7 +11,7 @@ fun <Element : AbstractElement<Element, *>> Element.traverseParents(block: (Elem
|
||||
}
|
||||
|
||||
/**
|
||||
* For each tree element, sets its [AbstractElement.baseTransformerType] to one of it parents if that parent type is used at least once as
|
||||
* For each tree element, sets its [AbstractElement.baseTransformerType] to one of its parents if that parent type is used at least once as
|
||||
* a type of a field, except when that field is explicitly opted out of it via
|
||||
* [AbstractField.useInBaseTransformerDetection].
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user