[IR generator] Simplify computation of walkable children
Don't require to specify them explicitly via `isChild` in IR generator, instead test the field type whether it is an element.
This commit is contained in:
committed by
Space Team
parent
ad4e97154f
commit
5f04bc8a27
+79
-68
@@ -105,6 +105,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+descriptor("DeclarationDescriptor")
|
+descriptor("DeclarationDescriptor")
|
||||||
+field("origin", type(Packages.declarations, "IrDeclarationOrigin"))
|
+field("origin", type(Packages.declarations, "IrDeclarationOrigin"))
|
||||||
+field("parent", declarationParent) {
|
+field("parent", declarationParent) {
|
||||||
|
needAcceptAndTransform = false
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
+factory
|
+factory
|
||||||
@@ -237,7 +238,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
TODO: consider dropping [$name] if it isn't used by any known plugin.
|
TODO: consider dropping [$name] if it isn't used by any known plugin.
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
+field("defaultValue", expressionBody, nullable = true, isChild = true)
|
+field("defaultValue", expressionBody, nullable = true)
|
||||||
}
|
}
|
||||||
val `class`: Element by element(Declaration) {
|
val `class`: Element by element(Declaration) {
|
||||||
parent(declarationBase)
|
parent(declarationBase)
|
||||||
@@ -285,7 +286,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+listField("superTypes", irTypeType, mutability = Var) {
|
+listField("superTypes", irTypeType, mutability = Var) {
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
+field("thisReceiver", valueParameter, nullable = true, isChild = true)
|
+field("thisReceiver", valueParameter, nullable = true)
|
||||||
+field(
|
+field(
|
||||||
"valueClassRepresentation",
|
"valueClassRepresentation",
|
||||||
type<ValueClassRepresentation<*>>().withArgs(type(Packages.types, "IrSimpleType")),
|
type<ValueClassRepresentation<*>>().withArgs(type(Packages.types, "IrSimpleType")),
|
||||||
@@ -316,10 +317,12 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
+field("attributeOwnerId", attributeContainer) {
|
+field("attributeOwnerId", attributeContainer) {
|
||||||
|
needAcceptAndTransform = false
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
// null <=> this element wasn't inlined
|
// null <=> this element wasn't inlined
|
||||||
+field("originalBeforeInline", attributeContainer, nullable = true) {
|
+field("originalBeforeInline", attributeContainer, nullable = true) {
|
||||||
|
needAcceptAndTransform = false
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,14 +334,14 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+field("isStatic", boolean) {
|
+field("isStatic", boolean) {
|
||||||
useFieldInIrFactory(defaultValue = "false")
|
useFieldInIrFactory(defaultValue = "false")
|
||||||
}
|
}
|
||||||
+field("body", blockBody, isChild = true)
|
+field("body", blockBody)
|
||||||
}
|
}
|
||||||
val declarationContainer: Element by element(Declaration) {
|
val declarationContainer: Element by element(Declaration) {
|
||||||
ownsChildren = false
|
ownsChildren = false
|
||||||
|
|
||||||
parent(declarationParent)
|
parent(declarationParent)
|
||||||
|
|
||||||
+listField("declarations", declaration, mutability = MutableList, isChild = true) {
|
+listField("declarations", declaration, mutability = MutableList) {
|
||||||
kDoc = """
|
kDoc = """
|
||||||
Accessing list of declaration may trigger lazy declaration list computation for lazy class,
|
Accessing list of declaration may trigger lazy declaration list computation for lazy class,
|
||||||
which requires computation of fake-overrides for this class. So it's unsafe to access it
|
which requires computation of fake-overrides for this class. So it's unsafe to access it
|
||||||
@@ -354,7 +357,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(declaration)
|
parent(declaration)
|
||||||
parent(declarationParent)
|
parent(declarationParent)
|
||||||
|
|
||||||
+listField("typeParameters", typeParameter, mutability = Var, isChild = true)
|
+listField("typeParameters", typeParameter, mutability = Var)
|
||||||
}
|
}
|
||||||
val typeParameter: Element by element(Declaration) {
|
val typeParameter: Element by element(Declaration) {
|
||||||
needTransformMethod()
|
needTransformMethod()
|
||||||
@@ -394,14 +397,14 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+field("isInline", boolean)
|
+field("isInline", boolean)
|
||||||
+field("isExpect", boolean)
|
+field("isExpect", boolean)
|
||||||
+field("returnType", irTypeType)
|
+field("returnType", irTypeType)
|
||||||
+field("dispatchReceiverParameter", valueParameter, nullable = true, isChild = true)
|
+field("dispatchReceiverParameter", valueParameter, nullable = true)
|
||||||
+field("extensionReceiverParameter", valueParameter, nullable = true, isChild = true)
|
+field("extensionReceiverParameter", valueParameter, nullable = true)
|
||||||
+listField("valueParameters", valueParameter, mutability = Var, isChild = true)
|
+listField("valueParameters", valueParameter, mutability = Var)
|
||||||
// The first `contextReceiverParametersCount` value parameters are context receivers.
|
// The first `contextReceiverParametersCount` value parameters are context receivers.
|
||||||
+field("contextReceiverParametersCount", int) {
|
+field("contextReceiverParametersCount", int) {
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
+field("body", body, nullable = true, isChild = true)
|
+field("body", body, nullable = true)
|
||||||
}
|
}
|
||||||
val constructor: Element by element(Declaration) {
|
val constructor: Element by element(Declaration) {
|
||||||
parent(function)
|
parent(function)
|
||||||
@@ -416,8 +419,8 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
|
|
||||||
+descriptor("ClassDescriptor")
|
+descriptor("ClassDescriptor")
|
||||||
+symbol(enumEntrySymbolType)
|
+symbol(enumEntrySymbolType)
|
||||||
+field("initializerExpression", expressionBody, nullable = true, isChild = true)
|
+field("initializerExpression", expressionBody, nullable = true)
|
||||||
+field("correspondingClass", `class`, nullable = true, isChild = true)
|
+field("correspondingClass", `class`, nullable = true)
|
||||||
}
|
}
|
||||||
val errorDeclaration: Element by element(Declaration) {
|
val errorDeclaration: Element by element(Declaration) {
|
||||||
parent(declarationBase)
|
parent(declarationBase)
|
||||||
@@ -453,7 +456,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+field("type", irTypeType)
|
+field("type", irTypeType)
|
||||||
+field("isFinal", boolean)
|
+field("isFinal", boolean)
|
||||||
+field("isStatic", boolean)
|
+field("isStatic", boolean)
|
||||||
+field("initializer", expressionBody, nullable = true, isChild = true)
|
+field("initializer", expressionBody, nullable = true)
|
||||||
+field("correspondingPropertySymbol", propertySymbolType, nullable = true) {
|
+field("correspondingPropertySymbol", propertySymbolType, nullable = true) {
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
@@ -468,9 +471,9 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+symbol(localDelegatedPropertySymbolType)
|
+symbol(localDelegatedPropertySymbolType)
|
||||||
+field("type", irTypeType)
|
+field("type", irTypeType)
|
||||||
+field("isVar", boolean)
|
+field("isVar", boolean)
|
||||||
+field("delegate", variable, isChild = true)
|
+field("delegate", variable)
|
||||||
+field("getter", simpleFunction, isChild = true)
|
+field("getter", simpleFunction)
|
||||||
+field("setter", simpleFunction, nullable = true, isChild = true)
|
+field("setter", simpleFunction, nullable = true)
|
||||||
}
|
}
|
||||||
val moduleFragment: Element by element(Declaration) {
|
val moduleFragment: Element by element(Declaration) {
|
||||||
needTransformMethod()
|
needTransformMethod()
|
||||||
@@ -482,7 +485,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
}
|
}
|
||||||
+field("name", type<Name>(), mutable = false)
|
+field("name", type<Name>(), mutable = false)
|
||||||
+field("irBuiltins", type(Packages.tree, "IrBuiltIns"), mutable = false)
|
+field("irBuiltins", type(Packages.tree, "IrBuiltIns"), mutable = false)
|
||||||
+listField("files", file, mutability = MutableList, isChild = true)
|
+listField("files", file, mutability = MutableList)
|
||||||
usedTypes += ArbitraryImportable(Packages.tree, "UNDEFINED_OFFSET")
|
usedTypes += ArbitraryImportable(Packages.tree, "UNDEFINED_OFFSET")
|
||||||
+field("startOffset", int, mutable = false) {
|
+field("startOffset", int, mutable = false) {
|
||||||
baseGetter = "UNDEFINED_OFFSET"
|
baseGetter = "UNDEFINED_OFFSET"
|
||||||
@@ -511,9 +514,9 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
useFieldInIrFactory(defaultValue = "false")
|
useFieldInIrFactory(defaultValue = "false")
|
||||||
}
|
}
|
||||||
+isFakeOverrideField()
|
+isFakeOverrideField()
|
||||||
+field("backingField", field, nullable = true, isChild = true)
|
+field("backingField", field, nullable = true)
|
||||||
+field("getter", simpleFunction, nullable = true, isChild = true)
|
+field("getter", simpleFunction, nullable = true)
|
||||||
+field("setter", simpleFunction, nullable = true, isChild = true)
|
+field("setter", simpleFunction, nullable = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isFakeOverrideField() = field("isFakeOverride", boolean) {
|
private fun isFakeOverrideField() = field("isFakeOverride", boolean) {
|
||||||
@@ -534,18 +537,20 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+symbol(scriptSymbolType)
|
+symbol(scriptSymbolType)
|
||||||
// NOTE: is the result of the FE conversion, because there script interpreted as a class and has receiver
|
// NOTE: is the result of the FE conversion, because there script interpreted as a class and has receiver
|
||||||
// TODO: consider removing from here and handle appropriately in the lowering
|
// TODO: consider removing from here and handle appropriately in the lowering
|
||||||
+field("thisReceiver", valueParameter, isChild = true, nullable = true) // K1
|
+field("thisReceiver", valueParameter, nullable = true) // K1
|
||||||
+field("baseClass", irTypeType, nullable = true) // K1
|
+field("baseClass", irTypeType, nullable = true) // K1
|
||||||
+listField("explicitCallParameters", variable, mutability = Var, isChild = true)
|
+listField("explicitCallParameters", variable, mutability = Var)
|
||||||
+listField("implicitReceiversParameters", valueParameter, mutability = Var, isChild = true)
|
+listField("implicitReceiversParameters", valueParameter, mutability = Var)
|
||||||
+listField("providedProperties", propertySymbolType, mutability = Var)
|
+listField("providedProperties", propertySymbolType, mutability = Var)
|
||||||
+listField("providedPropertiesParameters", valueParameter, mutability = Var, isChild = true)
|
+listField("providedPropertiesParameters", valueParameter, mutability = Var)
|
||||||
+field("resultProperty", propertySymbolType, nullable = true)
|
+field("resultProperty", propertySymbolType, nullable = true)
|
||||||
+field("earlierScriptsParameter", valueParameter, nullable = true, isChild = true)
|
+field("earlierScriptsParameter", valueParameter, nullable = true)
|
||||||
+listField("importedScripts", scriptSymbolType, mutability = Var, nullable = true)
|
+listField("importedScripts", scriptSymbolType, mutability = Var, nullable = true)
|
||||||
+listField("earlierScripts", scriptSymbolType, mutability = Var, nullable = true)
|
+listField("earlierScripts", scriptSymbolType, mutability = Var, nullable = true)
|
||||||
+field("targetClass", classSymbolType, nullable = true)
|
+field("targetClass", classSymbolType, nullable = true)
|
||||||
+field("constructor", constructor, nullable = true) // K1
|
+field("constructor", constructor, nullable = true) { // K1
|
||||||
|
needAcceptAndTransform = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val simpleFunction: Element by element(Declaration) {
|
val simpleFunction: Element by element(Declaration) {
|
||||||
isLeaf = true
|
isLeaf = true
|
||||||
@@ -586,7 +591,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
+field("isVar", boolean)
|
+field("isVar", boolean)
|
||||||
+field("isConst", boolean)
|
+field("isConst", boolean)
|
||||||
+field("isLateinit", boolean)
|
+field("isLateinit", boolean)
|
||||||
+field("initializer", expression, nullable = true, isChild = true)
|
+field("initializer", expression, nullable = true)
|
||||||
}
|
}
|
||||||
val packageFragment: Element by element(Declaration) {
|
val packageFragment: Element by element(Declaration) {
|
||||||
ownsChildren = false
|
ownsChildren = false
|
||||||
@@ -636,7 +641,9 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(metadataSourceOwner)
|
parent(metadataSourceOwner)
|
||||||
|
|
||||||
+symbol(fileSymbolType)
|
+symbol(fileSymbolType)
|
||||||
+field("module", moduleFragment)
|
+field("module", moduleFragment) {
|
||||||
|
needAcceptAndTransform = false
|
||||||
|
}
|
||||||
+field("fileEntry", type(Packages.tree, "IrFileEntry"))
|
+field("fileEntry", type(Packages.tree, "IrFileEntry"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,10 +656,12 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(attributeContainer)
|
parent(attributeContainer)
|
||||||
|
|
||||||
+field("attributeOwnerId", attributeContainer) {
|
+field("attributeOwnerId", attributeContainer) {
|
||||||
|
needAcceptAndTransform = false
|
||||||
baseDefaultValue = "this"
|
baseDefaultValue = "this"
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
+field("originalBeforeInline", attributeContainer, nullable = true) {
|
+field("originalBeforeInline", attributeContainer, nullable = true) {
|
||||||
|
needAcceptAndTransform = false
|
||||||
baseDefaultValue = "null"
|
baseDefaultValue = "null"
|
||||||
skipInIrFactory()
|
skipInIrFactory()
|
||||||
}
|
}
|
||||||
@@ -661,7 +670,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
val statementContainer: Element by element(Expression) {
|
val statementContainer: Element by element(Expression) {
|
||||||
ownsChildren = false
|
ownsChildren = false
|
||||||
|
|
||||||
+listField("statements", statement, mutability = MutableList, isChild = true)
|
+listField("statements", statement, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val body: Element by element(Expression) {
|
val body: Element by element(Expression) {
|
||||||
needTransformMethod()
|
needTransformMethod()
|
||||||
@@ -677,7 +686,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(body)
|
parent(body)
|
||||||
|
|
||||||
+factory
|
+factory
|
||||||
+field("expression", expression, isChild = true) {
|
+field("expression", expression) {
|
||||||
useFieldInIrFactory()
|
useFieldInIrFactory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,15 +712,15 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
|
|
||||||
parent(declarationReference)
|
parent(declarationReference)
|
||||||
|
|
||||||
+field("dispatchReceiver", expression, nullable = true, isChild = true) {
|
+field("dispatchReceiver", expression, nullable = true) {
|
||||||
baseDefaultValue = "null"
|
baseDefaultValue = "null"
|
||||||
}
|
}
|
||||||
+field("extensionReceiver", expression, nullable = true, isChild = true) {
|
+field("extensionReceiver", expression, nullable = true) {
|
||||||
baseDefaultValue = "null"
|
baseDefaultValue = "null"
|
||||||
}
|
}
|
||||||
+symbol(s)
|
+symbol(s)
|
||||||
+field("origin", statementOriginType, nullable = true)
|
+field("origin", statementOriginType, nullable = true)
|
||||||
+listField("valueArguments", expression.copy(nullable = true), mutability = Array, isChild = true) {
|
+listField("valueArguments", expression.copy(nullable = true), mutability = Array) {
|
||||||
visibility = Visibility.PROTECTED
|
visibility = Visibility.PROTECTED
|
||||||
}
|
}
|
||||||
+listField("typeArguments", irTypeType.copy(nullable = true), mutability = Array) {
|
+listField("typeArguments", irTypeType.copy(nullable = true), mutability = Array) {
|
||||||
@@ -831,7 +840,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(statementContainer)
|
parent(statementContainer)
|
||||||
|
|
||||||
+field("origin", statementOriginType, nullable = true)
|
+field("origin", statementOriginType, nullable = true)
|
||||||
+listField("statements", statement, mutability = MutableList, isChild = true) {
|
+listField("statements", statement, mutability = MutableList) {
|
||||||
baseDefaultValue = "ArrayList(2)"
|
baseDefaultValue = "ArrayList(2)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -870,7 +879,9 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
|
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("loop", loop)
|
+field("loop", loop) {
|
||||||
|
needAcceptAndTransform = false
|
||||||
|
}
|
||||||
+field("label", string, nullable = true) {
|
+field("label", string, nullable = true) {
|
||||||
baseDefaultValue = "null"
|
baseDefaultValue = "null"
|
||||||
}
|
}
|
||||||
@@ -959,19 +970,19 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
val constantPrimitive: Element by element(Expression) {
|
val constantPrimitive: Element by element(Expression) {
|
||||||
parent(constantValue)
|
parent(constantValue)
|
||||||
|
|
||||||
+field("value", const.withArgs("T" to TypeRef.Star), isChild = true)
|
+field("value", const.withArgs("T" to TypeRef.Star))
|
||||||
}
|
}
|
||||||
val constantObject: Element by element(Expression) {
|
val constantObject: Element by element(Expression) {
|
||||||
parent(constantValue)
|
parent(constantValue)
|
||||||
|
|
||||||
+field("constructor", constructorSymbolType)
|
+field("constructor", constructorSymbolType)
|
||||||
+listField("valueArguments", constantValue, mutability = MutableList, isChild = true)
|
+listField("valueArguments", constantValue, mutability = MutableList)
|
||||||
+listField("typeArguments", irTypeType, mutability = MutableList)
|
+listField("typeArguments", irTypeType, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val constantArray: Element by element(Expression) {
|
val constantArray: Element by element(Expression) {
|
||||||
parent(constantValue)
|
parent(constantValue)
|
||||||
|
|
||||||
+listField("elements", constantValue, mutability = MutableList, isChild = true)
|
+listField("elements", constantValue, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val delegatingConstructorCall: Element by element(Expression) {
|
val delegatingConstructorCall: Element by element(Expression) {
|
||||||
parent(functionAccessExpression)
|
parent(functionAccessExpression)
|
||||||
@@ -985,14 +996,14 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(dynamicExpression)
|
parent(dynamicExpression)
|
||||||
|
|
||||||
+field("operator", type(Packages.exprs, "IrDynamicOperator"))
|
+field("operator", type(Packages.exprs, "IrDynamicOperator"))
|
||||||
+field("receiver", expression, isChild = true)
|
+field("receiver", expression)
|
||||||
+listField("arguments", expression, mutability = MutableList, isChild = true)
|
+listField("arguments", expression, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val dynamicMemberExpression: Element by element(Expression) {
|
val dynamicMemberExpression: Element by element(Expression) {
|
||||||
parent(dynamicExpression)
|
parent(dynamicExpression)
|
||||||
|
|
||||||
+field("memberName", string)
|
+field("memberName", string)
|
||||||
+field("receiver", expression, isChild = true)
|
+field("receiver", expression)
|
||||||
}
|
}
|
||||||
val enumConstructorCall: Element by element(Expression) {
|
val enumConstructorCall: Element by element(Expression) {
|
||||||
parent(functionAccessExpression)
|
parent(functionAccessExpression)
|
||||||
@@ -1009,8 +1020,8 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
val errorCallExpression: Element by element(Expression) {
|
val errorCallExpression: Element by element(Expression) {
|
||||||
parent(errorExpression)
|
parent(errorExpression)
|
||||||
|
|
||||||
+field("explicitReceiver", expression, nullable = true, isChild = true)
|
+field("explicitReceiver", expression, nullable = true)
|
||||||
+listField("arguments", expression, mutability = MutableList, isChild = true)
|
+listField("arguments", expression, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val fieldAccessExpression: Element by element(Expression) {
|
val fieldAccessExpression: Element by element(Expression) {
|
||||||
nameInVisitorMethod = "FieldAccess"
|
nameInVisitorMethod = "FieldAccess"
|
||||||
@@ -1020,7 +1031,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
|
|
||||||
+symbol(fieldSymbolType, mutable = true)
|
+symbol(fieldSymbolType, mutable = true)
|
||||||
+field("superQualifierSymbol", classSymbolType, nullable = true)
|
+field("superQualifierSymbol", classSymbolType, nullable = true)
|
||||||
+field("receiver", expression, nullable = true, isChild = true) {
|
+field("receiver", expression, nullable = true) {
|
||||||
baseDefaultValue = "null"
|
baseDefaultValue = "null"
|
||||||
}
|
}
|
||||||
+field("origin", statementOriginType, nullable = true)
|
+field("origin", statementOriginType, nullable = true)
|
||||||
@@ -1031,7 +1042,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
val setField: Element by element(Expression) {
|
val setField: Element by element(Expression) {
|
||||||
parent(fieldAccessExpression)
|
parent(fieldAccessExpression)
|
||||||
|
|
||||||
+field("value", expression, isChild = true)
|
+field("value", expression)
|
||||||
}
|
}
|
||||||
val functionExpression: Element by element(Expression) {
|
val functionExpression: Element by element(Expression) {
|
||||||
transformerReturnType = rootElement
|
transformerReturnType = rootElement
|
||||||
@@ -1039,12 +1050,12 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("origin", statementOriginType)
|
+field("origin", statementOriginType)
|
||||||
+field("function", simpleFunction, isChild = true)
|
+field("function", simpleFunction)
|
||||||
}
|
}
|
||||||
val getClass: Element by element(Expression) {
|
val getClass: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("argument", expression, isChild = true)
|
+field("argument", expression)
|
||||||
}
|
}
|
||||||
val instanceInitializerCall: Element by element(Expression) {
|
val instanceInitializerCall: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
@@ -1058,10 +1069,10 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("origin", statementOriginType, nullable = true)
|
+field("origin", statementOriginType, nullable = true)
|
||||||
+field("body", expression, nullable = true, isChild = true) {
|
+field("body", expression, nullable = true) {
|
||||||
baseDefaultValue = "null"
|
baseDefaultValue = "null"
|
||||||
}
|
}
|
||||||
+field("condition", expression, isChild = true)
|
+field("condition", expression)
|
||||||
+field("label", string, nullable = true) {
|
+field("label", string, nullable = true) {
|
||||||
baseDefaultValue = "null"
|
baseDefaultValue = "null"
|
||||||
}
|
}
|
||||||
@@ -1080,48 +1091,48 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
val `return`: Element by element(Expression) {
|
val `return`: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("value", expression, isChild = true)
|
+field("value", expression)
|
||||||
+field("returnTargetSymbol", returnTargetSymbolType)
|
+field("returnTargetSymbol", returnTargetSymbolType)
|
||||||
}
|
}
|
||||||
val stringConcatenation: Element by element(Expression) {
|
val stringConcatenation: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+listField("arguments", expression, mutability = MutableList, isChild = true)
|
+listField("arguments", expression, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val suspensionPoint: Element by element(Expression) {
|
val suspensionPoint: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("suspensionPointIdParameter", variable, isChild = true)
|
+field("suspensionPointIdParameter", variable)
|
||||||
+field("result", expression, isChild = true)
|
+field("result", expression)
|
||||||
+field("resumeResult", expression, isChild = true)
|
+field("resumeResult", expression)
|
||||||
}
|
}
|
||||||
val suspendableExpression: Element by element(Expression) {
|
val suspendableExpression: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("suspensionPointId", expression, isChild = true)
|
+field("suspensionPointId", expression)
|
||||||
+field("result", expression, isChild = true)
|
+field("result", expression)
|
||||||
}
|
}
|
||||||
val `throw`: Element by element(Expression) {
|
val `throw`: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("value", expression, isChild = true)
|
+field("value", expression)
|
||||||
}
|
}
|
||||||
val `try`: Element by element(Expression) {
|
val `try`: Element by element(Expression) {
|
||||||
visitorParameterName = "aTry"
|
visitorParameterName = "aTry"
|
||||||
|
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("tryResult", expression, isChild = true)
|
+field("tryResult", expression)
|
||||||
+listField("catches", catch, mutability = MutableList, isChild = true)
|
+listField("catches", catch, mutability = MutableList)
|
||||||
+field("finallyExpression", expression, nullable = true, isChild = true)
|
+field("finallyExpression", expression, nullable = true)
|
||||||
}
|
}
|
||||||
val catch: Element by element(Expression) {
|
val catch: Element by element(Expression) {
|
||||||
visitorParameterName = "aCatch"
|
visitorParameterName = "aCatch"
|
||||||
needTransformMethod()
|
needTransformMethod()
|
||||||
transformByChildren = true
|
transformByChildren = true
|
||||||
|
|
||||||
+field("catchParameter", variable, isChild = true)
|
+field("catchParameter", variable)
|
||||||
+field("result", expression, isChild = true)
|
+field("result", expression)
|
||||||
}
|
}
|
||||||
val typeOperatorCall: Element by element(Expression) {
|
val typeOperatorCall: Element by element(Expression) {
|
||||||
nameInVisitorMethod = "TypeOperator"
|
nameInVisitorMethod = "TypeOperator"
|
||||||
@@ -1129,7 +1140,7 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("operator", type(Packages.exprs, "IrTypeOperator"))
|
+field("operator", type(Packages.exprs, "IrTypeOperator"))
|
||||||
+field("argument", expression, isChild = true)
|
+field("argument", expression)
|
||||||
+field("typeOperand", irTypeType)
|
+field("typeOperand", irTypeType)
|
||||||
}
|
}
|
||||||
val valueAccessExpression: Element by element(Expression) {
|
val valueAccessExpression: Element by element(Expression) {
|
||||||
@@ -1146,14 +1157,14 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
val setValue: Element by element(Expression) {
|
val setValue: Element by element(Expression) {
|
||||||
parent(valueAccessExpression)
|
parent(valueAccessExpression)
|
||||||
|
|
||||||
+field("value", expression, isChild = true)
|
+field("value", expression)
|
||||||
}
|
}
|
||||||
val varargElement: Element by element(Expression)
|
val varargElement: Element by element(Expression)
|
||||||
val vararg: Element by element(Expression) {
|
val vararg: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("varargElementType", irTypeType)
|
+field("varargElementType", irTypeType)
|
||||||
+listField("elements", varargElement, mutability = MutableList, isChild = true)
|
+listField("elements", varargElement, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val spreadElement: Element by element(Expression) {
|
val spreadElement: Element by element(Expression) {
|
||||||
visitorParameterName = "spread"
|
visitorParameterName = "spread"
|
||||||
@@ -1162,13 +1173,13 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
|
|
||||||
parent(varargElement)
|
parent(varargElement)
|
||||||
|
|
||||||
+field("expression", expression, isChild = true)
|
+field("expression", expression)
|
||||||
}
|
}
|
||||||
val `when`: Element by element(Expression) {
|
val `when`: Element by element(Expression) {
|
||||||
parent(expression)
|
parent(expression)
|
||||||
|
|
||||||
+field("origin", statementOriginType, nullable = true)
|
+field("origin", statementOriginType, nullable = true)
|
||||||
+listField("branches", branch, mutability = MutableList, isChild = true)
|
+listField("branches", branch, mutability = MutableList)
|
||||||
}
|
}
|
||||||
val branch: Element by element(Expression) {
|
val branch: Element by element(Expression) {
|
||||||
visitorParameterName = "branch"
|
visitorParameterName = "branch"
|
||||||
@@ -1176,8 +1187,8 @@ object IrTree : AbstractTreeBuilder() {
|
|||||||
needTransformMethod()
|
needTransformMethod()
|
||||||
transformByChildren = true
|
transformByChildren = true
|
||||||
|
|
||||||
+field("condition", expression, isChild = true)
|
+field("condition", expression)
|
||||||
+field("result", expression, isChild = true)
|
+field("result", expression)
|
||||||
}
|
}
|
||||||
val elseBranch: Element by element(Expression) {
|
val elseBranch: Element by element(Expression) {
|
||||||
visitorParameterName = "branch"
|
visitorParameterName = "branch"
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.generators.tree.addPureAbstractElement
|
|||||||
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
|
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil
|
||||||
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.collectPreviouslyGeneratedFiles
|
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.collectPreviouslyGeneratedFiles
|
||||||
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.removeExtraFilesFromPreviousGeneration
|
import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil.removeExtraFilesFromPreviousGeneration
|
||||||
import org.jetbrains.kotlin.ir.generator.model.addWalkableChildren
|
|
||||||
import org.jetbrains.kotlin.ir.generator.model.markLeaves
|
import org.jetbrains.kotlin.ir.generator.model.markLeaves
|
||||||
import org.jetbrains.kotlin.ir.generator.print.*
|
import org.jetbrains.kotlin.ir.generator.print.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -28,7 +27,6 @@ fun main(args: Array<String>) {
|
|||||||
InterfaceAndAbstractClassConfigurator(model.elements).configureInterfacesAndAbstractClasses()
|
InterfaceAndAbstractClassConfigurator(model.elements).configureInterfacesAndAbstractClasses()
|
||||||
addPureAbstractElement(model.elements, elementBaseType)
|
addPureAbstractElement(model.elements, elementBaseType)
|
||||||
markLeaves(model.elements)
|
markLeaves(model.elements)
|
||||||
addWalkableChildren(model.elements)
|
|
||||||
|
|
||||||
val previouslyGeneratedFiles = collectPreviouslyGeneratedFiles(generationPath)
|
val previouslyGeneratedFiles = collectPreviouslyGeneratedFiles(generationPath)
|
||||||
val generatedFiles = sequence {
|
val generatedFiles = sequence {
|
||||||
|
|||||||
+6
-19
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.generator.config
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.generators.tree.*
|
import org.jetbrains.kotlin.generators.tree.*
|
||||||
import org.jetbrains.kotlin.ir.generator.model.*
|
import org.jetbrains.kotlin.ir.generator.model.*
|
||||||
|
import org.jetbrains.kotlin.ir.generator.model.ElementOrRef
|
||||||
import org.jetbrains.kotlin.ir.generator.model.ElementRef
|
import org.jetbrains.kotlin.ir.generator.model.ElementRef
|
||||||
import org.jetbrains.kotlin.ir.generator.model.ListField
|
import org.jetbrains.kotlin.ir.generator.model.ListField
|
||||||
import org.jetbrains.kotlin.ir.generator.model.Model
|
import org.jetbrains.kotlin.ir.generator.model.Model
|
||||||
@@ -14,7 +15,6 @@ import org.jetbrains.kotlin.types.Variance
|
|||||||
import kotlin.properties.PropertyDelegateProvider
|
import kotlin.properties.PropertyDelegateProvider
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
|
|
||||||
|
|
||||||
abstract class AbstractTreeBuilder {
|
abstract class AbstractTreeBuilder {
|
||||||
private val configurationCallbacks = mutableListOf<() -> Element>()
|
private val configurationCallbacks = mutableListOf<() -> Element>()
|
||||||
@@ -22,11 +22,11 @@ abstract class AbstractTreeBuilder {
|
|||||||
abstract val rootElement: Element
|
abstract val rootElement: Element
|
||||||
|
|
||||||
protected fun Field.skipInIrFactory() {
|
protected fun Field.skipInIrFactory() {
|
||||||
useInIrFactoryStrategy = Field.UseFieldAsParameterInIrFactoryStrategy.No
|
customUseInIrFactoryStrategy = Field.UseFieldAsParameterInIrFactoryStrategy.No
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun Field.useFieldInIrFactory(defaultValue: String? = null) {
|
protected fun Field.useFieldInIrFactory(defaultValue: String? = null) {
|
||||||
useInIrFactoryStrategy = Field.UseFieldAsParameterInIrFactoryStrategy.Yes(defaultValue)
|
customUseInIrFactoryStrategy = Field.UseFieldAsParameterInIrFactoryStrategy.Yes(defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun element(category: Element.Category, name: String? = null, initializer: Element.() -> Unit = {}): ElementDelegate {
|
fun element(category: Element.Category, name: String? = null, initializer: Element.() -> Unit = {}): ElementDelegate {
|
||||||
@@ -75,22 +75,18 @@ abstract class AbstractTreeBuilder {
|
|||||||
type: TypeRefWithNullability,
|
type: TypeRefWithNullability,
|
||||||
nullable: Boolean = false,
|
nullable: Boolean = false,
|
||||||
mutable: Boolean = true,
|
mutable: Boolean = true,
|
||||||
isChild: Boolean = false,
|
|
||||||
initializer: SingleField.() -> Unit = {}
|
initializer: SingleField.() -> Unit = {}
|
||||||
): SingleField {
|
): SingleField {
|
||||||
checkChildType(isChild, type, name)
|
return SingleField(name, type.copy(nullable), mutable).apply(initializer)
|
||||||
return SingleField(name, type.copy(nullable), mutable, isChild).apply(initializer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun listField(
|
protected fun listField(
|
||||||
name: String,
|
name: String,
|
||||||
elementType: TypeRef,
|
baseType: TypeRef,
|
||||||
nullable: Boolean = false,
|
nullable: Boolean = false,
|
||||||
mutability: ListField.Mutability,
|
mutability: ListField.Mutability,
|
||||||
isChild: Boolean = false,
|
|
||||||
initializer: ListField.() -> Unit = {}
|
initializer: ListField.() -> Unit = {}
|
||||||
): ListField {
|
): ListField {
|
||||||
checkChildType(isChild, elementType, name)
|
|
||||||
val listType = when (mutability) {
|
val listType = when (mutability) {
|
||||||
ListField.Mutability.MutableList -> StandardTypes.mutableList
|
ListField.Mutability.MutableList -> StandardTypes.mutableList
|
||||||
ListField.Mutability.Array -> StandardTypes.array
|
ListField.Mutability.Array -> StandardTypes.array
|
||||||
@@ -98,22 +94,13 @@ abstract class AbstractTreeBuilder {
|
|||||||
}
|
}
|
||||||
return ListField(
|
return ListField(
|
||||||
name = name,
|
name = name,
|
||||||
baseType = elementType,
|
baseType = baseType,
|
||||||
listType = listType,
|
listType = listType,
|
||||||
isNullable = nullable,
|
isNullable = nullable,
|
||||||
mutable = mutability == ListField.Mutability.Var,
|
mutable = mutability == ListField.Mutability.Var,
|
||||||
isChild = isChild,
|
|
||||||
).apply(initializer)
|
).apply(initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkChildType(isChild: Boolean, type: TypeRef?, name: String) {
|
|
||||||
if (isChild) {
|
|
||||||
require(type == null || type is GenericElementOrRef<*, *>) {
|
|
||||||
"Field $name is a child field but has non-element type $type"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun build(): Model {
|
fun build(): Model {
|
||||||
val elements = configurationCallbacks.map { it() }
|
val elements = configurationCallbacks.map { it() }
|
||||||
return Model(elements, rootElement)
|
return Model(elements, rootElement)
|
||||||
|
|||||||
+28
-16
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE
|
|||||||
import org.jetbrains.kotlin.ir.generator.IrTree
|
import org.jetbrains.kotlin.ir.generator.IrTree
|
||||||
import org.jetbrains.kotlin.ir.generator.elementBaseType
|
import org.jetbrains.kotlin.ir.generator.elementBaseType
|
||||||
import org.jetbrains.kotlin.utils.SmartPrinter
|
import org.jetbrains.kotlin.utils.SmartPrinter
|
||||||
import org.jetbrains.kotlin.utils.topologicalSort
|
|
||||||
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
|
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
|
||||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||||
|
|
||||||
@@ -90,8 +89,7 @@ class Element(
|
|||||||
*/
|
*/
|
||||||
var isLeaf = false
|
var isLeaf = false
|
||||||
|
|
||||||
var childrenOrderOverride: List<String>? = null
|
override var childrenOrderOverride: List<String>? = null
|
||||||
override var walkableChildren: List<Field> = emptyList()
|
|
||||||
|
|
||||||
override var visitorParameterName = category.defaultVisitorParam
|
override var visitorParameterName = category.defaultVisitorParam
|
||||||
|
|
||||||
@@ -104,10 +102,19 @@ class Element(
|
|||||||
override var hasTransformMethod = false
|
override var hasTransformMethod = false
|
||||||
|
|
||||||
override val hasAcceptChildrenMethod: Boolean
|
override val hasAcceptChildrenMethod: Boolean
|
||||||
get() = ownsChildren && (isRootElement || walkableChildren.isNotEmpty())
|
get() = hasAcceptOrTransformChildrenMethod(Element::walkableChildren)
|
||||||
|
|
||||||
override val hasTransformChildrenMethod: Boolean
|
override val hasTransformChildrenMethod: Boolean
|
||||||
get() = ownsChildren && (isRootElement || transformableChildren.isNotEmpty())
|
get() = hasAcceptOrTransformChildrenMethod(Element::transformableChildren)
|
||||||
|
|
||||||
|
private fun hasAcceptOrTransformChildrenMethod(walkableOrTransformableChildren: Element.() -> List<Field>): Boolean {
|
||||||
|
if (!ownsChildren) return false
|
||||||
|
if (!isRootElement && walkableOrTransformableChildren().isEmpty()) return false
|
||||||
|
val atLeastOneParentHasAcceptOrTransformChildrenMethod = traverseParentsUntil { parent ->
|
||||||
|
parent != this && parent.hasAcceptOrTransformChildrenMethod(walkableOrTransformableChildren) && !parent.isRootElement
|
||||||
|
}
|
||||||
|
return !atLeastOneParentHasAcceptOrTransformChildrenMethod
|
||||||
|
}
|
||||||
|
|
||||||
var transformByChildren = false
|
var transformByChildren = false
|
||||||
var ownsChildren = true // If false, acceptChildren/transformChildren will NOT be generated.
|
var ownsChildren = true // If false, acceptChildren/transformChildren will NOT be generated.
|
||||||
@@ -135,7 +142,6 @@ typealias ElementOrRef = GenericElementOrRef<Element, Field>
|
|||||||
sealed class Field(
|
sealed class Field(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override var isMutable: Boolean,
|
override var isMutable: Boolean,
|
||||||
val isChild: Boolean,
|
|
||||||
) : AbstractField<Field>() {
|
) : AbstractField<Field>() {
|
||||||
var baseDefaultValue: String? = null
|
var baseDefaultValue: String? = null
|
||||||
var baseGetter: String? = null
|
var baseGetter: String? = null
|
||||||
@@ -147,8 +153,15 @@ sealed class Field(
|
|||||||
data class Yes(val defaultValue: String?) : UseFieldAsParameterInIrFactoryStrategy()
|
data class Yes(val defaultValue: String?) : UseFieldAsParameterInIrFactoryStrategy()
|
||||||
}
|
}
|
||||||
|
|
||||||
var useInIrFactoryStrategy =
|
var customUseInIrFactoryStrategy: UseFieldAsParameterInIrFactoryStrategy? = null
|
||||||
if (isChild) UseFieldAsParameterInIrFactoryStrategy.No else UseFieldAsParameterInIrFactoryStrategy.Yes(null)
|
|
||||||
|
val useInIrFactoryStrategy: UseFieldAsParameterInIrFactoryStrategy
|
||||||
|
get() = customUseInIrFactoryStrategy
|
||||||
|
?: if (needAcceptAndTransform && containsElement) {
|
||||||
|
UseFieldAsParameterInIrFactoryStrategy.No
|
||||||
|
} else {
|
||||||
|
UseFieldAsParameterInIrFactoryStrategy.Yes(null)
|
||||||
|
}
|
||||||
|
|
||||||
override val withGetter: Boolean
|
override val withGetter: Boolean
|
||||||
get() = baseGetter != null
|
get() = baseGetter != null
|
||||||
@@ -175,12 +188,13 @@ sealed class Field(
|
|||||||
override fun copy() = internalCopy().also(::updateFieldsInCopy)
|
override fun copy() = internalCopy().also(::updateFieldsInCopy)
|
||||||
|
|
||||||
protected fun updateFieldsInCopy(copy: Field) {
|
protected fun updateFieldsInCopy(copy: Field) {
|
||||||
|
copy.needAcceptAndTransform = needAcceptAndTransform
|
||||||
copy.useInBaseTransformerDetection = useInBaseTransformerDetection
|
copy.useInBaseTransformerDetection = useInBaseTransformerDetection
|
||||||
copy.isMutable = isMutable
|
copy.isMutable = isMutable
|
||||||
copy.optInAnnotation = optInAnnotation
|
copy.optInAnnotation = optInAnnotation
|
||||||
copy.baseDefaultValue = baseDefaultValue
|
copy.baseDefaultValue = baseDefaultValue
|
||||||
copy.baseGetter = baseGetter
|
copy.baseGetter = baseGetter
|
||||||
copy.useInIrFactoryStrategy = useInIrFactoryStrategy
|
copy.customUseInIrFactoryStrategy = customUseInIrFactoryStrategy
|
||||||
copy.fromParent = fromParent
|
copy.fromParent = fromParent
|
||||||
copy.customSetter = customSetter
|
copy.customSetter = customSetter
|
||||||
copy.visibility = visibility
|
copy.visibility = visibility
|
||||||
@@ -195,13 +209,12 @@ class SingleField(
|
|||||||
name: String,
|
name: String,
|
||||||
override var typeRef: TypeRefWithNullability,
|
override var typeRef: TypeRefWithNullability,
|
||||||
mutable: Boolean,
|
mutable: Boolean,
|
||||||
isChild: Boolean,
|
) : Field(name, mutable) {
|
||||||
) : Field(name, mutable, isChild) {
|
|
||||||
|
|
||||||
override fun replaceType(newType: TypeRefWithNullability) =
|
override fun replaceType(newType: TypeRefWithNullability) =
|
||||||
SingleField(name, newType, isMutable, isChild).also(::updateFieldsInCopy)
|
SingleField(name, newType, isMutable).also(::updateFieldsInCopy)
|
||||||
|
|
||||||
override fun internalCopy() = SingleField(name, typeRef, isMutable, isChild)
|
override fun internalCopy() = SingleField(name, typeRef, isMutable)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ListField(
|
class ListField(
|
||||||
@@ -210,15 +223,14 @@ class ListField(
|
|||||||
private val isNullable: Boolean,
|
private val isNullable: Boolean,
|
||||||
override val listType: ClassRef<PositionTypeParameterRef>,
|
override val listType: ClassRef<PositionTypeParameterRef>,
|
||||||
mutable: Boolean,
|
mutable: Boolean,
|
||||||
isChild: Boolean,
|
) : Field(name, mutable), AbstractListField {
|
||||||
) : Field(name, mutable, isChild), AbstractListField {
|
|
||||||
|
|
||||||
override val typeRef: ClassRef<PositionTypeParameterRef>
|
override val typeRef: ClassRef<PositionTypeParameterRef>
|
||||||
get() = listType.withArgs(baseType).copy(isNullable)
|
get() = listType.withArgs(baseType).copy(isNullable)
|
||||||
|
|
||||||
override fun replaceType(newType: TypeRefWithNullability) = copy()
|
override fun replaceType(newType: TypeRefWithNullability) = copy()
|
||||||
|
|
||||||
override fun internalCopy() = ListField(name, baseType, isNullable, listType, isMutable, isChild)
|
override fun internalCopy() = ListField(name, baseType, isNullable, listType, isMutable)
|
||||||
|
|
||||||
enum class Mutability {
|
enum class Mutability {
|
||||||
Var,
|
Var,
|
||||||
|
|||||||
-52
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.generator.model
|
package org.jetbrains.kotlin.ir.generator.model
|
||||||
|
|
||||||
import org.jetbrains.kotlin.generators.tree.*
|
|
||||||
|
|
||||||
typealias Model = org.jetbrains.kotlin.generators.tree.Model<Element>
|
typealias Model = org.jetbrains.kotlin.generators.tree.Model<Element>
|
||||||
|
|
||||||
internal fun markLeaves(elements: List<Element>) {
|
internal fun markLeaves(elements: List<Element>) {
|
||||||
@@ -24,53 +22,3 @@ internal fun markLeaves(elements: List<Element>) {
|
|||||||
el.isLeaf = true
|
el.isLeaf = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal fun addWalkableChildren(elements: List<Element>) {
|
|
||||||
for (element in elements) {
|
|
||||||
val walkableChildren = mutableMapOf<String, Field>()
|
|
||||||
|
|
||||||
fun visitParents(visited: Element) {
|
|
||||||
for (parent in visited.elementParents) {
|
|
||||||
if (!parent.element.ownsChildren) {
|
|
||||||
for (field in parent.element.fields) {
|
|
||||||
if (field.isChild) {
|
|
||||||
walkableChildren[field.name] = field
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visitParents(parent.element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visitParents(element)
|
|
||||||
|
|
||||||
element.fields.filter { it.isChild }.associateByTo(walkableChildren) { it.name }
|
|
||||||
|
|
||||||
element.walkableChildren = reorderIfNecessary(walkableChildren.values.toList(), element.childrenOrderOverride)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun reorderIfNecessary(fields: List<Field>, order: List<String>?): List<Field> =
|
|
||||||
if (order == null) fields else fields.sortedBy {
|
|
||||||
val position = order.indexOf(it.name)
|
|
||||||
if (position < 0) order.size else position
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun iterateElementsParentFirst(elements: List<Element>) = sequence {
|
|
||||||
val pending = elements.sortedBy { it.elementParents.size }.toMutableSet()
|
|
||||||
pendingLoop@ while (pending.isNotEmpty()) {
|
|
||||||
val iter = pending.iterator()
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
val element = iter.next()
|
|
||||||
if (element.elementParents.none { it.element in pending }) {
|
|
||||||
yield(element)
|
|
||||||
iter.remove()
|
|
||||||
continue@pendingLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
error("Cannot find next element to process")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+9
-1
@@ -26,11 +26,19 @@ interface FieldContainer<out Field : AbstractField<*>> {
|
|||||||
val hasTransformChildrenMethod: Boolean
|
val hasTransformChildrenMethod: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to override the order in which the specified children will be visited in `acceptChildren`/`transformChildren` methods.
|
||||||
|
*/
|
||||||
|
val childrenOrderOverride: List<String>?
|
||||||
|
get() = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The fields on which to run the visitor in generated `acceptChildren` methods.
|
* The fields on which to run the visitor in generated `acceptChildren` methods.
|
||||||
*/
|
*/
|
||||||
val walkableChildren: List<Field>
|
val walkableChildren: List<Field>
|
||||||
get() = allFields.filter { it.containsElement && !it.withGetter && it.needAcceptAndTransform }
|
get() = allFields
|
||||||
|
.filter { it.containsElement && !it.withGetter && it.needAcceptAndTransform }
|
||||||
|
.reorderFieldsIfNecessary(childrenOrderOverride)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The fields on which to run the transformer in generated `transformChildren` methods.
|
* The fields on which to run the transformer in generated `transformChildren` methods.
|
||||||
|
|||||||
@@ -5,9 +5,26 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.generators.tree
|
package org.jetbrains.kotlin.generators.tree
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs [block] on this element and all its parents recursively.
|
||||||
|
*/
|
||||||
fun <Element : AbstractElement<Element, *>> Element.traverseParents(block: (Element) -> Unit) {
|
fun <Element : AbstractElement<Element, *>> Element.traverseParents(block: (Element) -> Unit) {
|
||||||
block(this)
|
traverseParentsUntil { block(it); false }
|
||||||
elementParents.forEach { it.element.traverseParents(block) }
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs [block] on this element and all its parents recursively.
|
||||||
|
*
|
||||||
|
* If [block] returns `true` at any point, aborts iteration and returns `true`.
|
||||||
|
*
|
||||||
|
* If [block] always returns `false`, visits all the parents and returns `false`.
|
||||||
|
*/
|
||||||
|
fun <Element : AbstractElement<Element, *>> Element.traverseParentsUntil(block: (Element) -> Boolean): Boolean {
|
||||||
|
if (block(this)) return true
|
||||||
|
for (parent in elementParents) {
|
||||||
|
if (parent.element.traverseParentsUntil(block)) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,3 +64,13 @@ operator fun <K, V, U> MutableMap<K, MutableMap<V, U>>.set(k1: K, k2: V, value:
|
|||||||
operator fun <K, V, U> Map<K, Map<V, U>>.get(k1: K, k2: V): U {
|
operator fun <K, V, U> Map<K, Map<V, U>>.get(k1: K, k2: V): U {
|
||||||
return getValue(k1).getValue(k2)
|
return getValue(k1).getValue(k2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <Field : AbstractField<*>> List<Field>.reorderFieldsIfNecessary(order: List<String>?): List<Field> =
|
||||||
|
if (order == null) {
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
sortedBy {
|
||||||
|
val position = order.indexOf(it.name)
|
||||||
|
if (position < 0) order.size else position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user