Persistent IR generator
Goal: - avoid hand-writing the boilerplate - easier PIR evolution Output is reasonably close the hand-writtern version
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(kotlinStdlib())
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
|
||||
val generatePir by generator("org.jetbrains.kotlin.ir.persistentIrGenerator.MainKt", mainSourceSet)
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateAnonymousInitializer() {
|
||||
val body = Field("body", IrBlockBody, lateinit = true)
|
||||
|
||||
writeFile("PersistentIrAnonymousInitializer.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrAnonymousInitializer(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + IrAnonymousInitializerSymbol,
|
||||
isStatic + " = false",
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("AnonymousInitializer") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
descriptor(ClassDescriptor),
|
||||
body.toBody(),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/AnonymousInitializerCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers("AnonymousInitializer", body)()
|
||||
})
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateClass() {
|
||||
val visibilityField = Field("visibility", descriptorType("DescriptorVisibility"))
|
||||
val thisReceiverField = Field("thisReceiver", irDeclaration("IrValueParameter") + "?")
|
||||
val typeParametersField = Field("typeParameters", +"List<" + irDeclaration("IrTypeParameter") + ">")
|
||||
val superTypesField = Field("superTypes", +"List<" + import("IrType", "org.jetbrains.kotlin.ir.types") + ">")
|
||||
val metadataField = Field("metadata", irDeclaration("MetadataSource") + "?")
|
||||
val modalityField = Field("modality", descriptorType("Modality"))
|
||||
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer)
|
||||
val isExternalField = Field("isExternal", +"Boolean", notEq = "!=")
|
||||
|
||||
writeFile("PersistentIrClass.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrClass(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + IrClassSymbol,
|
||||
name,
|
||||
kind,
|
||||
visibility,
|
||||
modality,
|
||||
isCompanion,
|
||||
isInner,
|
||||
isData,
|
||||
isExternal + " = false",
|
||||
isInline + " = false",
|
||||
isExpect + " = false",
|
||||
isFun,
|
||||
source,
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("Class") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
descriptor(ClassDescriptor),
|
||||
visibilityField.toPersistentField(+"visibility"),
|
||||
thisReceiverField.toPersistentField(+"null"),
|
||||
lines(
|
||||
+"private var initialDeclarations: MutableList<" + IrDeclaration + ">? = null",
|
||||
id,
|
||||
+"override val declarations: MutableList<IrDeclaration> = " + import("ArrayList", "java.util") + "()",
|
||||
lines(
|
||||
+"get() " + block(
|
||||
+"if (createdOn < stageController.currentStage && initialDeclarations == null) " + block(
|
||||
+"initialDeclarations = " + import("Collections", "java.util") + ".unmodifiableList(ArrayList(field))"
|
||||
),
|
||||
id,
|
||||
+"""
|
||||
return if (stageController.canAccessDeclarationsOf(this)) {
|
||||
ensureLowered()
|
||||
field
|
||||
} else {
|
||||
initialDeclarations ?: field
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
).indent()
|
||||
),
|
||||
typeParametersField.toPersistentField(+"emptyList()"),
|
||||
superTypesField.toPersistentField(+"emptyList()"),
|
||||
metadataField.toPersistentField(+"null"),
|
||||
modalityField.toPersistentField(+"modality"),
|
||||
isExternalField.toPersistentField(+"isExternal"),
|
||||
attributeOwnerIdField.toPersistentField(+"this"),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/ClassCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"Class",
|
||||
thisReceiverField,
|
||||
metadataField,
|
||||
visibilityField,
|
||||
modalityField,
|
||||
attributeOwnerIdField,
|
||||
typeParametersField,
|
||||
superTypesField,
|
||||
isExternalField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateConstructor() {
|
||||
val returnTypeFieldField = Field("returnTypeField", IrType)
|
||||
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">")
|
||||
val dispatchReceiverParameterField = Field("dispatchReceiverParameter", IrValueParameter + "?")
|
||||
val extensionReceiverParameterField = Field("extensionReceiverParameter", IrValueParameter + "?")
|
||||
val valueParametersField = Field("valueParameters", +"List<" + IrValueParameter + ">")
|
||||
val bodyField = Field("body", IrBody + "?")
|
||||
val metadataField = Field("metadata", MetadataSource + "?")
|
||||
val visibilityField = Field("visibility", DescriptorVisibility)
|
||||
val isExternalField = Field("isExternal", +"Boolean", notEq = "!=")
|
||||
|
||||
writeFile("PersistentIrConstructor.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrConstructor(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + irSymbol("IrConstructorSymbol"),
|
||||
name,
|
||||
visibility,
|
||||
returnType,
|
||||
isInline,
|
||||
isExternal,
|
||||
isPrimary,
|
||||
isExpect,
|
||||
containerSource,
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("Constructor") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
returnTypeFieldField.toPersistentField(+"returnType", modifier = "private"),
|
||||
lines(
|
||||
+"override var returnType: IrType",
|
||||
lines(
|
||||
+"get() = returnTypeField.let " + block(
|
||||
+"if (it !== " + import("IrUninitializedType", "org.jetbrains.kotlin.ir.types.impl") + ") it else throw " + import("ReturnTypeIsNotInitializedException", "org.jetbrains.kotlin.ir.types.impl") + "(this)"
|
||||
),
|
||||
+"set(c) " + block(
|
||||
+"returnTypeField = c"
|
||||
)
|
||||
).indent()
|
||||
),
|
||||
typeParametersField.toPersistentField(+"emptyList()"),
|
||||
dispatchReceiverParameterField.toPersistentField(+"null"),
|
||||
extensionReceiverParameterField.toPersistentField(+"null"),
|
||||
valueParametersField.toPersistentField(+"emptyList()"),
|
||||
bodyField.toBody(),
|
||||
metadataField.toPersistentField(+"null"),
|
||||
visibilityField.toPersistentField(+"visibility"),
|
||||
isExternalField.toPersistentField(+"isExternal"),
|
||||
descriptor(ClassConstructorDescriptor)
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/ConstructorCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"Constructor",
|
||||
returnTypeFieldField,
|
||||
dispatchReceiverParameterField,
|
||||
extensionReceiverParameterField,
|
||||
bodyField,
|
||||
metadataField,
|
||||
visibilityField,
|
||||
typeParametersField,
|
||||
valueParametersField,
|
||||
isExternalField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateEnumEntry() {
|
||||
val correspondingClassField = Field("correspondingClass", IrClass + "?")
|
||||
val initializerExpressionField = Field("initializerExpression", IrExpressionBody + "?")
|
||||
|
||||
writeFile("PersistentIrEnumEntry.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrEnumEntry(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + irSymbol("IrEnumEntrySymbol"),
|
||||
name,
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("EnumEntry") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
descriptor(ClassDescriptor),
|
||||
|
||||
correspondingClassField.toPersistentField(+"null"),
|
||||
initializerExpressionField.toBody()
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/EnumEntryCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"EnumEntry",
|
||||
correspondingClassField,
|
||||
initializerExpressionField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
|
||||
internal fun PersistentIrGenerator.generateErrorDeclaration() {
|
||||
writeFile("PersistentIrErrorDeclaration.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"@OptIn(" + ObsoleteDescriptorBasedAPI + "::class)",
|
||||
+"internal class PersistentIrErrorDeclaration(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
+"private val _descriptor: " + DeclarationDescriptor + "?"
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("ErrorDeclaration") + " " + block(
|
||||
lines(
|
||||
+"override val descriptor: " + DeclarationDescriptor,
|
||||
+" get() = _descriptor ?: this." + import("toIrBasedDescriptor", "org.jetbrains.kotlin.ir.descriptors") + "()"
|
||||
),
|
||||
id,
|
||||
lastModified,
|
||||
loweredUpTo,
|
||||
values,
|
||||
createdOn,
|
||||
id,
|
||||
parentField,
|
||||
+"override var originField: " + IrDeclarationOrigin + " = IrDeclarationOrigin.DEFINED",
|
||||
removedOn,
|
||||
annotationsField,
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/ErrorDeclarationCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"ErrorDeclaration",
|
||||
)()
|
||||
})
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateField() {
|
||||
val initializerField = Field("initializer", IrExpressionBody + "?")
|
||||
val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?")
|
||||
val metadataField = Field("metadata", MetadataSource + "?")
|
||||
val typeField = Field("type", IrType)
|
||||
val isExternalField = Field("isExternal", +"Boolean", notEq = "!=")
|
||||
|
||||
writeFile("PersistentIrField.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrField(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + irSymbol("IrFieldSymbol"),
|
||||
name,
|
||||
+"type: " + IrType,
|
||||
+"override var " + visibility,
|
||||
isFinal,
|
||||
isExternal,
|
||||
isStatic,
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("Field") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
descriptor(descriptorType("PropertyDescriptor")),
|
||||
initializerField.toBody(),
|
||||
correspondingPropertySymbolField.toPersistentField(+"null"),
|
||||
metadataField.toPersistentField(+"null"),
|
||||
typeField.toPersistentField(+"type"),
|
||||
isExternalField.toPersistentField(+"isExternal"),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/FieldCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"Field",
|
||||
typeField,
|
||||
initializerField,
|
||||
correspondingPropertySymbolField,
|
||||
metadataField,
|
||||
isExternalField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateFunction() {
|
||||
|
||||
val returnTypeFieldField = Field("returnTypeField", IrType)
|
||||
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">")
|
||||
val dispatchReceiverParameterField = Field("dispatchReceiverParameter", IrValueParameter + "?")
|
||||
val extensionReceiverParameterField = Field("extensionReceiverParameter", IrValueParameter + "?")
|
||||
val valueParametersField = Field("valueParameters", +"List<" + IrValueParameter + ">")
|
||||
val bodyField = Field("body", IrBody + "?")
|
||||
val metadataField = Field("metadata", MetadataSource + "?")
|
||||
val visibilityField = Field("visibility", DescriptorVisibility)
|
||||
val overriddenSymbolsField = Field("overriddenSymbols", +"List<" + irSymbol("IrSimpleFunctionSymbol") + ">")
|
||||
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer)
|
||||
val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?")
|
||||
val isExternalField = Field("isExternal", +"Boolean", notEq = "!=")
|
||||
|
||||
writeFile("PersistentIrFunctionCommon.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal abstract class PersistentIrFunctionCommon(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
name,
|
||||
visibility,
|
||||
returnType,
|
||||
isInline,
|
||||
isExternal,
|
||||
+"override val isTailrec: Boolean",
|
||||
+"override val isSuspend: Boolean",
|
||||
+"override val isOperator: Boolean",
|
||||
+"override val isInfix: Boolean",
|
||||
isExpect,
|
||||
containerSource + " = null",
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("Function", baseClass = "IrSimpleFunction") + " " + blockSpaced(
|
||||
commonFields,
|
||||
returnTypeFieldField.toPersistentField(+"returnType", modifier = "private"),
|
||||
lines(
|
||||
+"final override var returnType: IrType",
|
||||
lines(
|
||||
+"get() = returnTypeField.let " + block(
|
||||
+"if (it !== " + import(
|
||||
"IrUninitializedType",
|
||||
"org.jetbrains.kotlin.ir.types.impl"
|
||||
) + ") it else throw " + import(
|
||||
"ReturnTypeIsNotInitializedException",
|
||||
"org.jetbrains.kotlin.ir.types.impl"
|
||||
) + "(this)"
|
||||
),
|
||||
+"set(c) " + block(
|
||||
+"returnTypeField = c"
|
||||
)
|
||||
).indent()
|
||||
),
|
||||
typeParametersField.toPersistentField(+"emptyList()"),
|
||||
dispatchReceiverParameterField.toPersistentField(+"null"),
|
||||
extensionReceiverParameterField.toPersistentField(+"null"),
|
||||
valueParametersField.toPersistentField(+"emptyList()"),
|
||||
bodyField.toBody(),
|
||||
metadataField.toPersistentField(+"null"),
|
||||
visibilityField.toPersistentField(+"visibility"),
|
||||
overriddenSymbolsField.toPersistentField(+"emptyList()"),
|
||||
lines(
|
||||
+"@Suppress(\"LeakingThis\")",
|
||||
attributeOwnerIdField.toPersistentField(+"this"),
|
||||
),
|
||||
correspondingPropertySymbolField.toPersistentField(+"null"),
|
||||
isExternalField.toPersistentField(+"isExternal")
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/FunctionCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"Function",
|
||||
returnTypeFieldField,
|
||||
dispatchReceiverParameterField,
|
||||
extensionReceiverParameterField,
|
||||
bodyField,
|
||||
metadataField,
|
||||
visibilityField,
|
||||
typeParametersField,
|
||||
valueParametersField,
|
||||
correspondingPropertySymbolField,
|
||||
overriddenSymbolsField,
|
||||
attributeOwnerIdField,
|
||||
isExternalField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateLocalDelegatedProperty() {
|
||||
val typeField = Field("type", IrType)
|
||||
val delegateField = Field("delegate", irDeclaration("IrVariable"), lateinit = true)
|
||||
val getterField = Field("getter", irDeclaration("IrSimpleFunction"), lateinit = true)
|
||||
val setterField = Field("setter", irDeclaration("IrSimpleFunction") + "?")
|
||||
val metadataField = Field("metadata", MetadataSource + "?")
|
||||
|
||||
writeFile("PersistentIrLocalDelegatedProperty.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"// TODO make not persistent",
|
||||
+"internal class PersistentIrLocalDelegatedProperty(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + irSymbol("IrLocalDelegatedPropertySymbol"),
|
||||
name,
|
||||
+"type: " + IrType,
|
||||
+"override val isVar: Boolean",
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("LocalDelegatedProperty") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
descriptor(descriptorType("VariableDescriptorWithAccessors")),
|
||||
typeField.toPersistentField(+"type"),
|
||||
delegateField.toPersistentField(+"null"),
|
||||
getterField.toPersistentField(+"null"),
|
||||
setterField.toPersistentField(+"null"),
|
||||
metadataField.toPersistentField(+"null"),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/LocalDelegatedPropertyCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"LocalDelegatedProperty",
|
||||
typeField,
|
||||
delegateField,
|
||||
getterField,
|
||||
setterField,
|
||||
metadataField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
fun main() {
|
||||
PersistentIrGenerator.run {
|
||||
generateAnonymousInitializer()
|
||||
generateClass()
|
||||
generateConstructor()
|
||||
generateEnumEntry()
|
||||
generateErrorDeclaration()
|
||||
generateField()
|
||||
generateFunction()
|
||||
generateLocalDelegatedProperty()
|
||||
generateProperty()
|
||||
generateTypeAlias()
|
||||
generateTypeParameter()
|
||||
generateValueParameter()
|
||||
}
|
||||
}
|
||||
+315
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
import java.io.File
|
||||
import java.lang.StringBuilder
|
||||
import java.time.Year
|
||||
|
||||
internal interface R {
|
||||
fun text(t: String): R
|
||||
|
||||
fun indent(fn: R.() -> Unit): R
|
||||
|
||||
fun import(fqn: String): R
|
||||
}
|
||||
|
||||
internal typealias E = R.() -> R
|
||||
|
||||
internal class Field(val name: String, val type: E, val lateinit: Boolean = false, val notEq: String = "!==")
|
||||
|
||||
internal object PersistentIrGenerator {
|
||||
|
||||
// Imports
|
||||
|
||||
val ClassDescriptor: E = descriptorType("ClassDescriptor")
|
||||
val DeclarationDescriptor: E = descriptorType("DeclarationDescriptor")
|
||||
val ClassConstructorDescriptor: E = descriptorType("ClassConstructorDescriptor")
|
||||
val DescriptorVisibility = descriptorType("DescriptorVisibility")
|
||||
|
||||
val IrDeclaration = irDeclaration("IrDeclaration")
|
||||
val IrDeclarationOrigin = irDeclaration("IrDeclarationOrigin")
|
||||
val IrDeclarationParent = irDeclaration("IrDeclarationParent")
|
||||
val IrAnonymousInitializer = irDeclaration("IrAnonymousInitializer")
|
||||
val IrClass = irDeclaration("IrClass")
|
||||
val IrTypeParameter = irDeclaration("IrTypeParameter")
|
||||
val IrValueParameter = irDeclaration("IrValueParameter")
|
||||
val MetadataSource = irDeclaration("MetadataSource")
|
||||
val IrAttributeContainer = irDeclaration("IrAttributeContainer")
|
||||
|
||||
val IrConstructorCall = irExpression("IrConstructorCall")
|
||||
val IrBody = irExpression("IrBody")
|
||||
val IrBlockBody = irExpression("IrBlockBody")
|
||||
val IrExpressionBody = irExpression("IrExpressionBody")
|
||||
|
||||
val IrAnonymousInitializerSymbol = irSymbol("IrAnonymousInitializerSymbol")
|
||||
val IrClassSymbol = irSymbol("IrClassSymbol")
|
||||
|
||||
val AnonymousInitializerCarrier = irCarrier("AnonymousInitializerCarrier")
|
||||
val Carrier = irCarrier("Carrier")
|
||||
|
||||
val ObsoleteDescriptorBasedAPI = import("ObsoleteDescriptorBasedAPI", "org.jetbrains.kotlin.ir")
|
||||
|
||||
val stageController = import("stageController", "org.jetbrains.kotlin.ir.declarations")
|
||||
|
||||
val IrType = import("IrType", "org.jetbrains.kotlin.ir.types")
|
||||
|
||||
val IrPropertySymbol = irSymbol("IrPropertySymbol")
|
||||
|
||||
// Constructor parameters
|
||||
|
||||
val startOffset = +"override val startOffset: Int"
|
||||
val endOffset = +"override val endOffset: Int"
|
||||
val origin = +"origin: " + IrDeclarationOrigin
|
||||
val isStatic = +"override val isStatic: Boolean"
|
||||
val name = +"override val name: " + import("Name", "org.jetbrains.kotlin.name")
|
||||
val kind = +"override val kind: " + descriptorType("ClassKind")
|
||||
val visibility = +"visibility: " + DescriptorVisibility
|
||||
val modality = +"modality: " + descriptorType("Modality")
|
||||
val isCompanion = +"override val isCompanion: Boolean = false"
|
||||
val isInner = +"override val isInner: Boolean = false"
|
||||
val isData = +"override val isData: Boolean = false"
|
||||
val isExternal = +"isExternal: Boolean"
|
||||
val isFinal = +"override val isFinal: Boolean"
|
||||
val isInline = +"override val isInline: Boolean"
|
||||
val isExpect = +"override val isExpect: Boolean"
|
||||
val isFun = +"override val isFun: Boolean = false"
|
||||
val source = +"override val source: " + descriptorType("SourceElement") + " = SourceElement.NO_SOURCE"
|
||||
val returnType = +"returnType: " + IrType
|
||||
val isPrimary = +"override val isPrimary: Boolean"
|
||||
val containerSource = +"override val containerSource: " + import("DeserializedContainerSource", "org.jetbrains.kotlin.serialization.deserialization.descriptors") + "?"
|
||||
|
||||
val initBlock = +"init " + block(
|
||||
+"symbol.bind(this)"
|
||||
)
|
||||
|
||||
// Fields
|
||||
val lastModified = +"override var lastModified: Int = " + stageController + ".currentStage"
|
||||
val loweredUpTo = +"override var loweredUpTo: Int = " + stageController + ".currentStage"
|
||||
val values = +"override var values: Array<" + Carrier + ">? = null"
|
||||
val createdOn = +"override val createdOn: Int = " + stageController + ".currentStage"
|
||||
|
||||
val parentField = +"override var parentField: " + IrDeclarationParent + "? = null"
|
||||
val originField = +"override var originField: " + IrDeclarationOrigin + " = origin"
|
||||
val removedOn = +"override var removedOn: Int = Int.MAX_VALUE"
|
||||
val annotationsField = +"override var annotationsField: List<" + IrConstructorCall + "> = emptyList()"
|
||||
|
||||
val commonFields = lines(
|
||||
lastModified,
|
||||
loweredUpTo,
|
||||
values,
|
||||
createdOn,
|
||||
id,
|
||||
parentField,
|
||||
originField,
|
||||
removedOn,
|
||||
annotationsField,
|
||||
)
|
||||
|
||||
fun Field.toPersistentField(initializer: E, modifier: String = "override") =
|
||||
persistentField(name, type, initializer, lateinit, modifier, notEq = notEq)
|
||||
|
||||
fun Field.toBody() = body(type, lateinit, name)
|
||||
|
||||
// Helpers
|
||||
|
||||
fun baseClasses(name: String, baseClass: String = "Ir$name"): E = lines(
|
||||
irDeclaration(baseClass) + "(),",
|
||||
+" PersistentIrDeclarationBase<" + irCarrier("${name}Carrier") + ">,",
|
||||
+" ${name}Carrier",
|
||||
)
|
||||
|
||||
fun persistentField(
|
||||
name: String,
|
||||
type: E,
|
||||
initializer: E,
|
||||
lateinit: Boolean = false,
|
||||
modifier: String = "override",
|
||||
isBody: Boolean = false,
|
||||
notEq: String = "!==",
|
||||
): E = lines(
|
||||
+"override var ${name}Field: " + type + "${if (lateinit) "?" else ""} = " + initializer,
|
||||
id,
|
||||
+"$modifier var $name: " + type,
|
||||
lines(
|
||||
+"get() = getCarrier().${name}Field${if (lateinit) "!!" else ""}",
|
||||
+"set(v) " + block(
|
||||
+"if (${if (lateinit) "getCarrier().${name}Field" else name} $notEq v) " + block(
|
||||
(if (isBody) lines(
|
||||
+"if (v is PersistentIrBodyBase<*>) " + block(
|
||||
+"v.container = this"
|
||||
),
|
||||
id
|
||||
) else id) + "setCarrier().${name}Field = v"
|
||||
)
|
||||
)
|
||||
).indent()
|
||||
)
|
||||
|
||||
fun body(bodyType: E, lateinit: Boolean = false, fieldName: String = "body"): E =
|
||||
persistentField(fieldName, bodyType, initializer = +"null", lateinit, isBody = true)
|
||||
|
||||
fun descriptor(type: E) = lines(
|
||||
+"@" + ObsoleteDescriptorBasedAPI,
|
||||
+"override val descriptor: " + type,
|
||||
+" get() = symbol.descriptor"
|
||||
)
|
||||
|
||||
fun carriers(name: String, vararg fields: Field): E = lines(
|
||||
id,
|
||||
+"internal interface ${name}Carrier : DeclarationCarrier" + block(
|
||||
*(fields.map { +"var ${it.name}Field: " + it.type + if (it.lateinit) "?" else "" }.toTypedArray()),
|
||||
id,
|
||||
+"override fun clone(): ${name}Carrier " + block(
|
||||
+"return ${name}CarrierImpl(",
|
||||
arrayOf(
|
||||
+"lastModified",
|
||||
+"parentField",
|
||||
+"originField",
|
||||
+"annotationsField",
|
||||
*(fields.map { +"${it.name}Field" }.toTypedArray())
|
||||
).join(separator = ",\n").indent(),
|
||||
+")",
|
||||
)
|
||||
),
|
||||
id,
|
||||
+"internal class ${name}CarrierImpl(",
|
||||
arrayOf(
|
||||
+"override val lastModified: Int",
|
||||
+"override var parentField: " + IrDeclarationParent + "?",
|
||||
+"override var originField: " + IrDeclarationOrigin,
|
||||
+"override var annotationsField: List<" + IrConstructorCall + ">",
|
||||
*(fields.map { +"override var ${it.name}Field: " + it.type + if (it.lateinit) "?" else "" }.toTypedArray()),
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : ${name}Carrier",
|
||||
id,
|
||||
)
|
||||
|
||||
fun lines(vararg fn: E): E = fn.join(separator = "\n")
|
||||
|
||||
fun block(vararg fn: E): E = lines(+"{", { indent { lines(*fn)() } }, +"}")
|
||||
|
||||
fun blockSpaced(vararg fn: E): E {
|
||||
return block(*(fn.flatMap { listOf(id, it) }.toTypedArray()))
|
||||
}
|
||||
|
||||
fun import(name: String, pkg: String): E = { import("$pkg.$name").text(name) }
|
||||
|
||||
fun descriptorType(name: String): E = import(name, "org.jetbrains.kotlin.descriptors")
|
||||
|
||||
fun irDeclaration(name: String): E = import(name, "org.jetbrains.kotlin.ir.declarations")
|
||||
|
||||
fun irExpression(name: String): E = import(name, "org.jetbrains.kotlin.ir.expressions")
|
||||
|
||||
fun irCarrier(name: String): E = import(name, "org.jetbrains.kotlin.ir.declarations.persistent.carriers")
|
||||
|
||||
fun irSymbol(name: String): E = import(name, "org.jetbrains.kotlin.ir.symbols")
|
||||
|
||||
infix operator fun E.plus(e: E?): E = { this@plus(); e.safe()() }
|
||||
|
||||
infix operator fun E.plus(e: String): E = this + (+e)
|
||||
|
||||
operator fun String.unaryPlus(): E = { text(this@unaryPlus) }
|
||||
|
||||
val id: E get() = { this }
|
||||
|
||||
fun E?.safe(): E = this ?: id
|
||||
|
||||
fun Array<out E>.join(prefix: String = "", separator: String = "", suffix: String = ""): E =
|
||||
join(+prefix, +separator, +suffix)
|
||||
|
||||
fun Array<out E>.join(prefix: E = id, separator: E = id, suffix: E = id): E {
|
||||
if (this.isEmpty()) return id
|
||||
return prefix + interleaveWith(separator) + suffix
|
||||
}
|
||||
|
||||
fun Array<out E>.interleaveWith(b: E): E {
|
||||
return {
|
||||
this@interleaveWith.forEachIndexed { i, e ->
|
||||
if (i != 0) b()
|
||||
e()
|
||||
}
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
fun Boolean.ifTrue(s: String): E = if (this) +s else id
|
||||
|
||||
fun type(name: E, vararg parameters: E, isNullable: Boolean = false): E =
|
||||
name + parameters.join("<", ", ", ">") + isNullable.ifTrue("?")
|
||||
|
||||
fun E.indent(): E = {
|
||||
val self = this@indent
|
||||
indent {
|
||||
self()
|
||||
}
|
||||
}
|
||||
|
||||
fun renderFile(pkg: String, fn: R.() -> R): String {
|
||||
val sb = StringBuilder()
|
||||
val imports: MutableSet<String> = mutableSetOf()
|
||||
|
||||
val renderer = object : R {
|
||||
var currentIndent = ""
|
||||
|
||||
var atLineStart = true
|
||||
|
||||
override fun text(t: String): R {
|
||||
if (t.isEmpty()) return this
|
||||
|
||||
if (atLineStart) {
|
||||
sb.append(currentIndent)
|
||||
atLineStart = false
|
||||
}
|
||||
|
||||
val cr = t.indexOf('\n')
|
||||
if (cr >= 0) {
|
||||
sb.append(t.substring(0, cr + 1))
|
||||
atLineStart = true
|
||||
text(t.substring(cr + 1))
|
||||
} else {
|
||||
sb.append(t)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun indent(fn: R.() -> Unit): R {
|
||||
val oldIndent = currentIndent
|
||||
currentIndent = "$oldIndent "
|
||||
fn()
|
||||
currentIndent = oldIndent
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun import(fqn: String): R {
|
||||
imports += fqn
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
renderer.fn()
|
||||
|
||||
var result = File("license/COPYRIGHT_HEADER.txt").readText() + "\n\n" + "package $pkg\n\n"
|
||||
|
||||
result += imports.map { "import $it" }.sorted().joinToString(separator = "\n")
|
||||
result += "\n\n"
|
||||
result += "// Auto-generated by compiler/ir/ir.tree.persistent/generator/src/org/jetbrains/kotlin/ir/persistentIrGenerator/Main.kt. DO NOT EDIT!\n"
|
||||
result += sb.toString()
|
||||
|
||||
result = result.lines().map { if (it.isBlank()) "" else it }.joinToString(separator = "\n")
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private val prefix = "compiler/ir/ir.tree.persistent/gen/org/jetbrains/kotlin/ir/declarations/persistent/"
|
||||
|
||||
fun writeFile(path: String, content: String) {
|
||||
File(prefix + path).writeText(content)
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateProperty() {
|
||||
val backingFieldField = Field("backingField", irDeclaration("IrField") + "?")
|
||||
val getterField = Field("getter", irDeclaration("IrSimpleFunction") + "?")
|
||||
val setterField = Field("setter", irDeclaration("IrSimpleFunction") + "?")
|
||||
val metadataField = Field("metadata", MetadataSource + "?")
|
||||
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer)
|
||||
val isExternalField = Field("isExternal", +"Boolean", notEq = "!=")
|
||||
|
||||
writeFile("PersistentIrPropertyCommon.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal abstract class PersistentIrPropertyCommon(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
name,
|
||||
+"override var " + visibility, // TODO non-persisted state
|
||||
+"override val isVar: Boolean",
|
||||
+"override val isConst: Boolean",
|
||||
+"override val isLateinit: Boolean",
|
||||
+"override val isDelegated: Boolean",
|
||||
isExternal,
|
||||
isExpect,
|
||||
containerSource
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("Property") + " " + blockSpaced(
|
||||
commonFields,
|
||||
backingFieldField.toPersistentField(+"null"),
|
||||
getterField.toPersistentField(+"null"),
|
||||
setterField.toPersistentField(+"null"),
|
||||
metadataField.toPersistentField(+"null"),
|
||||
lines(
|
||||
+"@Suppress(\"LeakingThis\")",
|
||||
attributeOwnerIdField.toPersistentField(+"this"),
|
||||
),
|
||||
isExternalField.toPersistentField(+"isExternal"),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/PropertyCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"Property",
|
||||
backingFieldField,
|
||||
getterField,
|
||||
setterField,
|
||||
metadataField,
|
||||
attributeOwnerIdField,
|
||||
isExternalField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateTypeAlias() {
|
||||
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">")
|
||||
val expandedTypeField = Field("expandedType", IrType)
|
||||
|
||||
writeFile("PersistentIrTypeAlias.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrTypeAlias(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
+"override val symbol: " + irSymbol("IrTypeAliasSymbol"),
|
||||
name,
|
||||
+"override var " + visibility,
|
||||
+"expandedType: " + IrType,
|
||||
+"override val isActual: Boolean",
|
||||
origin,
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("TypeAlias") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
descriptor(descriptorType("TypeAliasDescriptor")),
|
||||
|
||||
typeParametersField.toPersistentField(+"emptyList()"),
|
||||
expandedTypeField.toPersistentField(+"expandedType"),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/TypeAliasCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"TypeAlias",
|
||||
typeParametersField,
|
||||
expandedTypeField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateTypeParameter() {
|
||||
val superTypesField = Field("superTypes", +"List<" + IrType + ">")
|
||||
|
||||
writeFile("PersistentIrTypeParameter.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrTypeParameter(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + irSymbol("IrTypeParameterSymbol"),
|
||||
name,
|
||||
+"override val index: Int",
|
||||
+"override val isReified: Boolean",
|
||||
+"override val variance: " + import("Variance", "org.jetbrains.kotlin.types")
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("TypeParameter") + " " + blockSpaced(
|
||||
initBlock,
|
||||
commonFields,
|
||||
descriptor(descriptorType("TypeParameterDescriptor")),
|
||||
superTypesField.toPersistentField(+"emptyList()"),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
|
||||
writeFile("carriers/TypeParameterCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"TypeParameter",
|
||||
superTypesField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.persistentIrGenerator
|
||||
|
||||
internal fun PersistentIrGenerator.generateValueParameter() {
|
||||
|
||||
val defaultValueField = Field("defaultValue", IrExpressionBody + "?")
|
||||
val typeField = Field("type", IrType)
|
||||
val varargElementTypeField = Field("varargElementType", IrType + "?")
|
||||
|
||||
writeFile("PersistentIrValueParameter.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
|
||||
lines(
|
||||
id,
|
||||
+"internal class PersistentIrValueParameter(",
|
||||
arrayOf(
|
||||
startOffset,
|
||||
endOffset,
|
||||
origin,
|
||||
+"override val symbol: " + irSymbol("IrValueParameterSymbol"),
|
||||
name,
|
||||
+"override val index: Int",
|
||||
+"type: " + IrType,
|
||||
+"varargElementType: " + IrType + "?",
|
||||
+"override val isCrossinline: Boolean",
|
||||
+"override val isNoinline: Boolean",
|
||||
+"override val isHidden: Boolean",
|
||||
+"override val isAssignable: Boolean"
|
||||
).join(separator = ",\n").indent(),
|
||||
+") : " + baseClasses("ValueParameter") + " " + blockSpaced(
|
||||
descriptor(descriptorType("ParameterDescriptor")),
|
||||
initBlock,
|
||||
commonFields,
|
||||
defaultValueField.toBody(),
|
||||
typeField.toPersistentField(+"type"),
|
||||
varargElementTypeField.toPersistentField(+"varargElementType"),
|
||||
),
|
||||
id,
|
||||
)()
|
||||
})
|
||||
writeFile("carriers/ValueParameterCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
|
||||
carriers(
|
||||
"ValueParameter",
|
||||
defaultValueField,
|
||||
typeField,
|
||||
varargElementTypeField,
|
||||
)()
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user