[IR generator] Don't use kotlinpoet for auto-generating IR tree classes
KT-61970 Fixed KT-61703 Fixed
This commit is contained in:
committed by
Space Team
parent
63e9dd588c
commit
ed28923282
-1
@@ -24,7 +24,6 @@ fun Builder.generateCode(generationPath: File): GeneratedFile =
|
||||
typeName,
|
||||
fileSuppressions = listOf("DuplicatedCode", "unused"),
|
||||
) {
|
||||
println()
|
||||
addAllImports(usedTypes)
|
||||
printBuilder(this@generateCode)
|
||||
}
|
||||
|
||||
-1
@@ -88,6 +88,5 @@ private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Ele
|
||||
|
||||
fun Element.generateCode(generationPath: File): GeneratedFile =
|
||||
printGeneratedType(generationPath, TREE_GENERATOR_README, packageName, typeName) {
|
||||
println()
|
||||
ElementPrinter(this).printElement(element)
|
||||
}
|
||||
|
||||
-1
@@ -24,7 +24,6 @@ fun Implementation.generateCode(generationPath: File): GeneratedFile =
|
||||
this.typeName,
|
||||
fileSuppressions = listOf("DuplicatedCode", "unused"),
|
||||
) {
|
||||
println()
|
||||
addAllImports(usedTypes)
|
||||
printImplementation(this@generateCode)
|
||||
}
|
||||
|
||||
-1
@@ -106,6 +106,5 @@ fun printTransformer(elements: List<Element>, generationPath: File): GeneratedFi
|
||||
firTransformerType.packageName,
|
||||
firTransformerType.simpleName,
|
||||
) {
|
||||
println()
|
||||
TransformerPrinter(this).printVisitor(elements)
|
||||
}
|
||||
|
||||
-1
@@ -120,6 +120,5 @@ private fun printVisitorCommon(
|
||||
makePrinter: (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter<Element, Field>,
|
||||
): GeneratedFile =
|
||||
printGeneratedType(generationPath, TREE_GENERATOR_README, visitorType.packageName, visitorType.simpleName) {
|
||||
println()
|
||||
makePrinter(this, visitorType).printVisitor(elements)
|
||||
}
|
||||
@@ -19,10 +19,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
interface IrElement {
|
||||
/**
|
||||
* The start offset of the syntax node from which this IR node was generated,
|
||||
* in number of characters from the start of the source file. If there is no source information
|
||||
* for this IR node,
|
||||
* the [UNDEFINED_OFFSET] constant is used. In order to get the line number and the column
|
||||
* number from this offset,
|
||||
* in number of characters from the start of the source file. If there is no source information for this IR node,
|
||||
* the [UNDEFINED_OFFSET] constant is used. In order to get the line number and the column number from this offset,
|
||||
* [IrFileEntry.getLineNumber] and [IrFileEntry.getColumnNumber] can be used.
|
||||
*
|
||||
* @see IrFileEntry.getSourceRangeInfo
|
||||
@@ -31,10 +29,8 @@ interface IrElement {
|
||||
|
||||
/**
|
||||
* The end offset of the syntax node from which this IR node was generated,
|
||||
* in number of characters from the start of the source file. If there is no source information
|
||||
* for this IR node,
|
||||
* the [UNDEFINED_OFFSET] constant is used. In order to get the line number and the column
|
||||
* number from this offset,
|
||||
* in number of characters from the start of the source file. If there is no source information for this IR node,
|
||||
* the [UNDEFINED_OFFSET] constant is used. In order to get the line number and the column number from this offset,
|
||||
* [IrFileEntry.getLineNumber] and [IrFileEntry.getColumnNumber] can be used.
|
||||
*
|
||||
* @see IrFileEntry.getSourceRangeInfo
|
||||
@@ -74,8 +70,7 @@ interface IrElement {
|
||||
/**
|
||||
* Recursively transforms this node's children *in place* using [transformer].
|
||||
*
|
||||
* Basically, executes `this.child = this.child.transform(transformer, data)` for each child
|
||||
* of this node.
|
||||
* Basically, executes `this.child = this.child.transform(transformer, data)` for each child of this node.
|
||||
*
|
||||
* Does **not** run [transformer] on this node itself.
|
||||
*
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.ValueClassRepresentation
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
@@ -27,9 +23,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.class]
|
||||
*/
|
||||
abstract class IrClass : IrDeclarationBase(), IrPossiblyExternalDeclaration,
|
||||
IrDeclarationWithVisibility, IrTypeParametersContainer, IrDeclarationContainer,
|
||||
IrAttributeContainer, IrMetadataSourceOwner {
|
||||
abstract class IrClass : IrDeclarationBase(), IrPossiblyExternalDeclaration, IrDeclarationWithVisibility, IrTypeParametersContainer, IrDeclarationContainer, IrAttributeContainer, IrMetadataSourceOwner {
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
abstract override val descriptor: ClassDescriptor
|
||||
|
||||
@@ -52,12 +46,9 @@ abstract class IrClass : IrDeclarationBase(), IrPossiblyExternalDeclaration,
|
||||
abstract var isFun: Boolean
|
||||
|
||||
/**
|
||||
* Returns true iff this is a class loaded from dependencies which has the `HAS_ENUM_ENTRIES`
|
||||
* metadata flag set.
|
||||
* This flag is useful for Kotlin/JVM to determine whether an enum class from dependency
|
||||
* actually has the `entries` property
|
||||
* in its bytecode, as opposed to whether it has it in its member scope, which is true even for
|
||||
* enum classes compiled by
|
||||
* Returns true iff this is a class loaded from dependencies which has the `HAS_ENUM_ENTRIES` metadata flag set.
|
||||
* This flag is useful for Kotlin/JVM to determine whether an enum class from dependency actually has the `entries` property
|
||||
* in its bytecode, as opposed to whether it has it in its member scope, which is true even for enum classes compiled by
|
||||
* old versions of Kotlin which did not support the EnumEntries language feature.
|
||||
*/
|
||||
abstract var hasEnumEntries: Boolean
|
||||
@@ -71,8 +62,7 @@ abstract class IrClass : IrDeclarationBase(), IrPossiblyExternalDeclaration,
|
||||
abstract var valueClassRepresentation: ValueClassRepresentation<IrSimpleType>?
|
||||
|
||||
/**
|
||||
* If this is a sealed class or interface, this list contains symbols of all its immediate
|
||||
* subclasses.
|
||||
* If this is a sealed class or interface, this list contains symbols of all its immediate subclasses.
|
||||
* Otherwise, this is an empty list.
|
||||
*
|
||||
* NOTE: If this [IrClass] was deserialized from a klib, this list will always be empty!
|
||||
|
||||
@@ -22,8 +22,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.field]
|
||||
*/
|
||||
abstract class IrField : IrDeclarationBase(), IrPossiblyExternalDeclaration,
|
||||
IrDeclarationWithVisibility, IrDeclarationParent, IrMetadataSourceOwner {
|
||||
abstract class IrField : IrDeclarationBase(), IrPossiblyExternalDeclaration, IrDeclarationWithVisibility, IrDeclarationParent, IrMetadataSourceOwner {
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
abstract override val descriptor: PropertyDescriptor
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.file]
|
||||
*/
|
||||
abstract class IrFile : IrPackageFragment(), IrMetadataSourceOwner,
|
||||
IrMutableAnnotationContainer {
|
||||
abstract class IrFile : IrPackageFragment(), IrMetadataSourceOwner, IrMutableAnnotationContainer {
|
||||
abstract override val symbol: IrFileSymbol
|
||||
|
||||
abstract var module: IrModuleFragment
|
||||
|
||||
@@ -22,9 +22,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.function]
|
||||
*/
|
||||
abstract class IrFunction : IrDeclarationBase(), IrPossiblyExternalDeclaration,
|
||||
IrDeclarationWithVisibility, IrTypeParametersContainer, IrSymbolOwner, IrDeclarationParent,
|
||||
IrReturnTarget, IrMemberWithContainerSource, IrMetadataSourceOwner {
|
||||
abstract class IrFunction : IrDeclarationBase(), IrPossiblyExternalDeclaration, IrDeclarationWithVisibility, IrTypeParametersContainer, IrSymbolOwner, IrDeclarationParent, IrReturnTarget, IrMemberWithContainerSource, IrMetadataSourceOwner {
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
abstract override val descriptor: FunctionDescriptor
|
||||
|
||||
|
||||
+1
-2
@@ -20,8 +20,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.localDelegatedProperty]
|
||||
*/
|
||||
abstract class IrLocalDelegatedProperty : IrDeclarationBase(), IrDeclarationWithName,
|
||||
IrSymbolOwner, IrMetadataSourceOwner {
|
||||
abstract class IrLocalDelegatedProperty : IrDeclarationBase(), IrDeclarationWithName, IrSymbolOwner, IrMetadataSourceOwner {
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
abstract override val descriptor: VariableDescriptorWithAccessors
|
||||
|
||||
|
||||
+2
-4
@@ -14,11 +14,9 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
* An [IrElement] capable of holding something which backends can use to write
|
||||
* as the metadata for the declaration.
|
||||
*
|
||||
* Technically, it can even be ± an array of bytes, but right now it's usually the frontend
|
||||
* representation of the declaration,
|
||||
* Technically, it can even be ± an array of bytes, but right now it's usually the frontend representation of the declaration,
|
||||
* so a descriptor in case of K1, and [org.jetbrains.kotlin.fir.FirElement] in case of K2,
|
||||
* and the backend invokes a metadata serializer on it to obtain metadata and write it, for example,
|
||||
* to `@kotlin.Metadata`
|
||||
* and the backend invokes a metadata serializer on it to obtain metadata and write it, for example, to `@kotlin.Metadata`
|
||||
* on JVM.
|
||||
*
|
||||
* In Kotlin/Native, [metadata] is used to store some LLVM-related stuff in an IR declaration,
|
||||
|
||||
@@ -41,8 +41,8 @@ abstract class IrModuleFragment : IrElementBase(), IrElement {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitModuleFragment(this, data)
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D):
|
||||
IrModuleFragment = accept(transformer, data) as IrModuleFragment
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrModuleFragment =
|
||||
accept(transformer, data) as IrModuleFragment
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
files.forEach { it.accept(visitor, data) }
|
||||
|
||||
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.overridableMember]
|
||||
*/
|
||||
interface IrOverridableMember : IrDeclaration, IrDeclarationWithVisibility,
|
||||
IrDeclarationWithName, IrSymbolOwner {
|
||||
interface IrOverridableMember : IrDeclaration, IrDeclarationWithVisibility, IrDeclarationWithName, IrSymbolOwner {
|
||||
var modality: Modality
|
||||
}
|
||||
|
||||
@@ -28,9 +28,8 @@ abstract class IrPackageFragment : IrElementBase(), IrDeclarationContainer, IrSy
|
||||
|
||||
/**
|
||||
* This should be a link to [IrModuleFragment] instead.
|
||||
*
|
||||
* Unfortunately, some package fragments (e.g. some synthetic ones and
|
||||
* [IrExternalPackageFragment])
|
||||
*
|
||||
* Unfortunately, some package fragments (e.g. some synthetic ones and [IrExternalPackageFragment])
|
||||
* are not located in any IR module, but still have a module descriptor.
|
||||
*/
|
||||
abstract val moduleDescriptor: ModuleDescriptor
|
||||
|
||||
-1
@@ -8,7 +8,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
|
||||
/**
|
||||
* A non-leaf IR tree element.
|
||||
*
|
||||
|
||||
@@ -19,9 +19,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.property]
|
||||
*/
|
||||
abstract class IrProperty : IrDeclarationBase(), IrPossiblyExternalDeclaration,
|
||||
IrOverridableDeclaration<IrPropertySymbol>, IrMetadataSourceOwner, IrAttributeContainer,
|
||||
IrMemberWithContainerSource {
|
||||
abstract class IrProperty : IrDeclarationBase(), IrPossiblyExternalDeclaration, IrOverridableDeclaration<IrPropertySymbol>, IrMetadataSourceOwner, IrAttributeContainer, IrMemberWithContainerSource {
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
abstract override val descriptor: PropertyDescriptor
|
||||
|
||||
|
||||
@@ -23,8 +23,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.script]
|
||||
*/
|
||||
abstract class IrScript : IrDeclarationBase(), IrDeclarationWithName, IrDeclarationParent,
|
||||
IrStatementContainer, IrMetadataSourceOwner {
|
||||
abstract class IrScript : IrDeclarationBase(), IrDeclarationWithName, IrDeclarationParent, IrStatementContainer, IrMetadataSourceOwner {
|
||||
abstract override val symbol: IrScriptSymbol
|
||||
|
||||
abstract var thisReceiver: IrValueParameter?
|
||||
@@ -67,10 +66,8 @@ abstract class IrScript : IrDeclarationBase(), IrDeclarationWithName, IrDeclarat
|
||||
statements.transformInPlace(transformer, data)
|
||||
thisReceiver = thisReceiver?.transform(transformer, data)
|
||||
explicitCallParameters = explicitCallParameters.transformIfNeeded(transformer, data)
|
||||
implicitReceiversParameters = implicitReceiversParameters.transformIfNeeded(transformer,
|
||||
data)
|
||||
providedPropertiesParameters = providedPropertiesParameters.transformIfNeeded(transformer,
|
||||
data)
|
||||
implicitReceiversParameters = implicitReceiversParameters.transformIfNeeded(transformer, data)
|
||||
providedPropertiesParameters = providedPropertiesParameters.transformIfNeeded(transformer, data)
|
||||
earlierScriptsParameter = earlierScriptsParameter?.transform(transformer, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.simpleFunction]
|
||||
*/
|
||||
abstract class IrSimpleFunction : IrFunction(),
|
||||
IrOverridableDeclaration<IrSimpleFunctionSymbol>, IrAttributeContainer {
|
||||
abstract class IrSimpleFunction : IrFunction(), IrOverridableDeclaration<IrSimpleFunctionSymbol>, IrAttributeContainer {
|
||||
abstract override val symbol: IrSimpleFunctionSymbol
|
||||
|
||||
abstract var isTailrec: Boolean
|
||||
|
||||
@@ -21,8 +21,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.typeAlias]
|
||||
*/
|
||||
abstract class IrTypeAlias : IrDeclarationBase(), IrDeclarationWithName,
|
||||
IrDeclarationWithVisibility, IrTypeParametersContainer {
|
||||
abstract class IrTypeAlias : IrDeclarationBase(), IrDeclarationWithName, IrDeclarationWithVisibility, IrTypeParametersContainer {
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
abstract override val descriptor: TypeAliasDescriptor
|
||||
|
||||
|
||||
@@ -38,6 +38,6 @@ abstract class IrTypeParameter : IrDeclarationBase(), IrDeclarationWithName {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitTypeParameter(this, data)
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D):
|
||||
IrTypeParameter = accept(transformer, data) as IrTypeParameter
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter =
|
||||
accept(transformer, data) as IrTypeParameter
|
||||
}
|
||||
|
||||
-1
@@ -8,7 +8,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
|
||||
/**
|
||||
* A non-leaf IR tree element.
|
||||
*
|
||||
|
||||
@@ -40,8 +40,7 @@ abstract class IrValueParameter : IrDeclarationBase(), IrValueDeclaration {
|
||||
* If `true`, the value parameter does not participate in [IdSignature] computation.
|
||||
*
|
||||
* This is a workaround that is needed for better support of compiler plugins.
|
||||
* Suppose you have the following code and some IR plugin that adds a value parameter to
|
||||
* functions
|
||||
* Suppose you have the following code and some IR plugin that adds a value parameter to functions
|
||||
* marked with the `@PluginMarker` annotation.
|
||||
* ```kotlin
|
||||
* @PluginMarker
|
||||
@@ -55,11 +54,9 @@ abstract class IrValueParameter : IrDeclarationBase(), IrValueDeclaration {
|
||||
* ```
|
||||
*
|
||||
* If a compiler plugin adds parameters to an [IrFunction],
|
||||
* the representations of the function in the frontend and in the backend may diverge,
|
||||
* potentially causing signature mismatch and
|
||||
* the representations of the function in the frontend and in the backend may diverge, potentially causing signature mismatch and
|
||||
* linkage errors (see [KT-40980](https://youtrack.jetbrains.com/issue/KT-40980)).
|
||||
* We wouldn't want IR plugins to affect the frontend representation, since in an IDE you'd want
|
||||
* to be able to see those
|
||||
* We wouldn't want IR plugins to affect the frontend representation, since in an IDE you'd want to be able to see those
|
||||
* declarations in their original form (without the `$extra` parameter).
|
||||
*
|
||||
* To fix this problem, [isHidden] was introduced.
|
||||
@@ -73,8 +70,8 @@ abstract class IrValueParameter : IrDeclarationBase(), IrValueDeclaration {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitValueParameter(this, data)
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D):
|
||||
IrValueParameter = accept(transformer, data) as IrValueParameter
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrValueParameter =
|
||||
accept(transformer, data) as IrValueParameter
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
defaultValue?.accept(visitor, data)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
|
||||
/**
|
||||
* A non-leaf IR tree element.
|
||||
*
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
|
||||
/**
|
||||
* A non-leaf IR tree element.
|
||||
*
|
||||
|
||||
@@ -20,6 +20,6 @@ abstract class IrElseBranch : IrBranch() {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitElseBranch(this, data)
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElseBranch
|
||||
= accept(transformer, data) as IrElseBranch
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElseBranch =
|
||||
accept(transformer, data) as IrElseBranch
|
||||
}
|
||||
|
||||
@@ -19,14 +19,13 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.expression]
|
||||
*/
|
||||
abstract class IrExpression : IrElementBase(), IrStatement, IrVarargElement,
|
||||
IrAttributeContainer {
|
||||
abstract class IrExpression : IrElementBase(), IrStatement, IrVarargElement, IrAttributeContainer {
|
||||
override var attributeOwnerId: IrAttributeContainer = this
|
||||
|
||||
override var originalBeforeInline: IrAttributeContainer? = null
|
||||
|
||||
abstract var type: IrType
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpression
|
||||
= accept(transformer, data) as IrExpression
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpression =
|
||||
accept(transformer, data) as IrExpression
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ abstract class IrExpressionBody : IrBody() {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitExpressionBody(this, data)
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D):
|
||||
IrExpressionBody = accept(transformer, data) as IrExpressionBody
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrExpressionBody =
|
||||
accept(transformer, data) as IrExpressionBody
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
expression.accept(visitor, data)
|
||||
|
||||
+1
-2
@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
*
|
||||
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.localDelegatedPropertyReference]
|
||||
*/
|
||||
abstract class IrLocalDelegatedPropertyReference :
|
||||
IrCallableReference<IrLocalDelegatedPropertySymbol>() {
|
||||
abstract class IrLocalDelegatedPropertyReference : IrCallableReference<IrLocalDelegatedPropertySymbol>() {
|
||||
abstract var delegate: IrVariableSymbol
|
||||
|
||||
abstract var getter: IrSimpleFunctionSymbol
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
|
||||
/**
|
||||
* A non-leaf IR tree element.
|
||||
*
|
||||
|
||||
+12
-12
@@ -38,18 +38,6 @@ abstract class IrMemberAccessExpression<S : IrSymbol> : IrDeclarationReference()
|
||||
val typeArgumentsCount: Int
|
||||
get() = typeArguments.size
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
dispatchReceiver?.accept(visitor, data)
|
||||
extensionReceiver?.accept(visitor, data)
|
||||
valueArguments.forEach { it?.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
dispatchReceiver = dispatchReceiver?.transform(transformer, data)
|
||||
extensionReceiver = extensionReceiver?.transform(transformer, data)
|
||||
valueArguments.transformInPlace(transformer, data)
|
||||
}
|
||||
|
||||
fun getValueArgument(index: Int): IrExpression? {
|
||||
checkArgumentSlotAccess("value", index, valueArguments.size)
|
||||
return valueArguments[index]
|
||||
@@ -69,4 +57,16 @@ abstract class IrMemberAccessExpression<S : IrSymbol> : IrDeclarationReference()
|
||||
checkArgumentSlotAccess("type", index, typeArguments.size)
|
||||
typeArguments[index] = type
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
dispatchReceiver?.accept(visitor, data)
|
||||
extensionReceiver?.accept(visitor, data)
|
||||
valueArguments.forEach { it?.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
dispatchReceiver = dispatchReceiver?.transform(transformer, data)
|
||||
extensionReceiver = extensionReceiver?.transform(transformer, data)
|
||||
valueArguments.transformInPlace(transformer, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ abstract class IrSpreadElement : IrElementBase(), IrVarargElement {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitSpreadElement(this, data)
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D):
|
||||
IrSpreadElement = accept(transformer, data) as IrSpreadElement
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrSpreadElement =
|
||||
accept(transformer, data) as IrSpreadElement
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
expression.accept(visitor, data)
|
||||
|
||||
@@ -34,8 +34,7 @@ abstract class IrSuspensionPoint : IrExpression() {
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
suspensionPointIdParameter = suspensionPointIdParameter.transform(transformer, data) as
|
||||
IrVariable
|
||||
suspensionPointIdParameter = suspensionPointIdParameter.transform(transformer, data) as IrVariable
|
||||
result = result.transform(transformer, data)
|
||||
resumeResult = resumeResult.transform(transformer, data)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ dependencies {
|
||||
implementation(project(":generators"))
|
||||
implementation(project(":generators:tree-generator-common"))
|
||||
implementation(project(":compiler:util"))
|
||||
implementation("com.squareup:kotlinpoet:1.11.0")
|
||||
|
||||
compileOnly(intellijCore())
|
||||
compileOnly(commonDependency("org.jetbrains.intellij.deps:trove4j"))
|
||||
|
||||
+7
-1
@@ -6,13 +6,14 @@
|
||||
package org.jetbrains.kotlin.ir.generator
|
||||
|
||||
import org.jetbrains.kotlin.generators.tree.TypeKind
|
||||
import org.jetbrains.kotlin.generators.tree.type
|
||||
import org.jetbrains.kotlin.ir.generator.Packages.declarations
|
||||
import org.jetbrains.kotlin.ir.generator.Packages.exprs
|
||||
import org.jetbrains.kotlin.ir.generator.Packages.symbols
|
||||
import org.jetbrains.kotlin.ir.generator.Packages.tree
|
||||
import org.jetbrains.kotlin.ir.generator.Packages.types
|
||||
import org.jetbrains.kotlin.ir.generator.Packages.util
|
||||
import org.jetbrains.kotlin.ir.generator.Packages.visitors
|
||||
import org.jetbrains.kotlin.generators.tree.type
|
||||
|
||||
object Packages {
|
||||
const val tree = "org.jetbrains.kotlin.ir"
|
||||
@@ -22,6 +23,7 @@ object Packages {
|
||||
const val types = "org.jetbrains.kotlin.ir.types"
|
||||
const val visitors = "org.jetbrains.kotlin.ir.visitors"
|
||||
const val descriptors = "org.jetbrains.kotlin.descriptors"
|
||||
const val util = "org.jetbrains.kotlin.ir.util"
|
||||
}
|
||||
|
||||
val elementBaseType = type(tree, "IrElementBase", TypeKind.Class)
|
||||
@@ -34,6 +36,7 @@ val mutableAnnotationContainerType = type(declarations, "IrMutableAnnotationCont
|
||||
val irTypeType = type(types, "IrType")
|
||||
val irFactoryType = type(declarations, "IrFactory")
|
||||
val stageControllerType = type(declarations, "StageController", TypeKind.Class)
|
||||
val idSignatureType = type(util, "IdSignature", TypeKind.Class)
|
||||
|
||||
val symbolType = type(symbols, "IrSymbol")
|
||||
val packageFragmentSymbolType = type(symbols, "IrPackageFragmentSymbol")
|
||||
@@ -57,3 +60,6 @@ val returnableBlockSymbolType = type(symbols, "IrReturnableBlockSymbol")
|
||||
val propertySymbolType = type(symbols, "IrPropertySymbol")
|
||||
val localDelegatedPropertySymbolType = type(symbols, "IrLocalDelegatedPropertySymbol")
|
||||
val typeAliasSymbolType = type(symbols, "IrTypeAliasSymbol")
|
||||
|
||||
val obsoleteDescriptorBasedApiAnnotation = type(BASE_PACKAGE, "ObsoleteDescriptorBasedAPI", TypeKind.Class)
|
||||
val unsafeDuringIrConstructionApiAnnotation = type(symbols, "UnsafeDuringIrConstructionAPI", TypeKind.Class)
|
||||
|
||||
+112
-102
@@ -5,27 +5,26 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.generator
|
||||
|
||||
import com.squareup.kotlinpoet.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.ValueClassRepresentation
|
||||
import org.jetbrains.kotlin.generators.tree.*
|
||||
import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter
|
||||
import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration
|
||||
import org.jetbrains.kotlin.ir.generator.config.AbstractTreeBuilder
|
||||
import org.jetbrains.kotlin.ir.generator.config.ElementConfig
|
||||
import org.jetbrains.kotlin.ir.generator.config.ElementConfig.Category.*
|
||||
import org.jetbrains.kotlin.ir.generator.config.ListFieldConfig.Mutability.*
|
||||
import org.jetbrains.kotlin.ir.generator.config.ListFieldConfig.Mutability.Array
|
||||
import org.jetbrains.kotlin.ir.generator.config.ListFieldConfig.Mutability.List
|
||||
import org.jetbrains.kotlin.ir.generator.config.ListFieldConfig.Mutability.Var
|
||||
import org.jetbrains.kotlin.ir.generator.config.SimpleFieldConfig
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element.Companion.elementName2typeName
|
||||
import org.jetbrains.kotlin.ir.generator.print.toPoet
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.ir.generator.util.Import
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.withIndent
|
||||
|
||||
// Note the style of the DSL to describe IR elements, which is these things in the following order:
|
||||
// 1) config (see properties of ElementConfig)
|
||||
@@ -38,10 +37,11 @@ object IrTree : AbstractTreeBuilder() {
|
||||
private fun descriptor(typeName: String, nullable: Boolean = false): SimpleFieldConfig =
|
||||
field(
|
||||
name = "descriptor",
|
||||
type = ClassRef<TypeParameterRef>(TypeKind.Interface, Packages.descriptors, typeName),
|
||||
type = type(Packages.descriptors, typeName),
|
||||
mutable = false,
|
||||
nullable = nullable,
|
||||
) {
|
||||
optInAnnotation = obsoleteDescriptorBasedApiAnnotation
|
||||
skipInIrFactory()
|
||||
}
|
||||
|
||||
@@ -55,16 +55,15 @@ object IrTree : AbstractTreeBuilder() {
|
||||
skipInIrFactory()
|
||||
}
|
||||
|
||||
val oldCallback = generationCallback
|
||||
generationCallback = {
|
||||
oldCallback?.invoke(this)
|
||||
addFunction(
|
||||
FunSpec.builder("acquireSymbol")
|
||||
.addModifiers(KModifier.ABSTRACT)
|
||||
.addParameter("symbol", symbol.toPoet())
|
||||
.returns(this@element.toPoet())
|
||||
.build(),
|
||||
println()
|
||||
printFunctionDeclaration(
|
||||
name = "acquireSymbol",
|
||||
parameters = listOf(FunctionParameter("symbol", symbol)),
|
||||
returnType = this@element,
|
||||
modality = Modality.ABSTRACT,
|
||||
)
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +207,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("isCrossinline", boolean)
|
||||
+field("isNoinline", boolean)
|
||||
+field("isHidden", boolean) {
|
||||
additionalImports.add(Import("org.jetbrains.kotlin.ir.util", "IdSignature"))
|
||||
usedTypes.add(idSignatureType)
|
||||
kDoc = """
|
||||
If `true`, the value parameter does not participate in [IdSignature] computation.
|
||||
|
||||
@@ -349,9 +348,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
before IR for all sources is built (because fake-overrides of lazy classes may depend on
|
||||
declaration of source classes, e.g. for java source classes)
|
||||
""".trimIndent()
|
||||
generationCallback = {
|
||||
addAnnotation(ClassName("org.jetbrains.kotlin.ir.symbols", "UnsafeDuringIrConstructionAPI"))
|
||||
}
|
||||
optInAnnotation = unsafeDuringIrConstructionApiAnnotation
|
||||
}
|
||||
}
|
||||
val typeParametersContainer: ElementConfig by element(Declaration) {
|
||||
@@ -446,7 +443,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
fieldsToSkipInIrFactoryMethod.add("origin")
|
||||
|
||||
+field("symbol", symbolType, mutable = false) {
|
||||
baseGetter = code("error(\"Should never be called\")")
|
||||
baseGetter = "error(\"Should never be called\")"
|
||||
skipInIrFactory()
|
||||
}
|
||||
}
|
||||
@@ -497,16 +494,18 @@ object IrTree : AbstractTreeBuilder() {
|
||||
transformByChildren = true
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
+descriptor("ModuleDescriptor")
|
||||
+descriptor("ModuleDescriptor").apply {
|
||||
optInAnnotation = null
|
||||
}
|
||||
+field("name", type<Name>(), mutable = false)
|
||||
+field("irBuiltins", type(Packages.tree, "IrBuiltIns"), mutable = false)
|
||||
+listField("files", file, mutability = List, isChild = true)
|
||||
val undefinedOffset = MemberName(Packages.tree, "UNDEFINED_OFFSET")
|
||||
usedTypes += ArbitraryImportable(Packages.tree, "UNDEFINED_OFFSET")
|
||||
+field("startOffset", int, mutable = false) {
|
||||
baseGetter = code("%M", undefinedOffset)
|
||||
baseGetter = "UNDEFINED_OFFSET"
|
||||
}
|
||||
+field("endOffset", int, mutable = false) {
|
||||
baseGetter = code("%M", undefinedOffset)
|
||||
baseGetter = "UNDEFINED_OFFSET"
|
||||
}
|
||||
}
|
||||
val property: ElementConfig by element(Declaration) {
|
||||
@@ -621,7 +620,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
parent(symbolOwner)
|
||||
|
||||
+symbol(packageFragmentSymbolType)
|
||||
+field("packageFragmentDescriptor", type(Packages.descriptors, "PackageFragmentDescriptor"), mutable = false)
|
||||
+field("packageFragmentDescriptor", type(Packages.descriptors, "PackageFragmentDescriptor"), mutable = false) {
|
||||
optInAnnotation = obsoleteDescriptorBasedApiAnnotation
|
||||
}
|
||||
+field("moduleDescriptor", type(Packages.descriptors, "ModuleDescriptor"), mutable = false) {
|
||||
kDoc = """
|
||||
This should be a link to [IrModuleFragment] instead.
|
||||
@@ -632,16 +633,13 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
+field("packageFqName", type<FqName>())
|
||||
+field("fqName", type<FqName>()) {
|
||||
baseGetter = code("packageFqName")
|
||||
generationCallback = {
|
||||
val deprecatedAnnotation = AnnotationSpec.builder(Deprecated::class)
|
||||
.addMember(code("message = \"Please use `packageFqName` instead\""))
|
||||
.addMember(code("replaceWith = ReplaceWith(\"packageFqName\")"))
|
||||
.addMember(code("level = DeprecationLevel.ERROR"))
|
||||
.build()
|
||||
addAnnotation(deprecatedAnnotation)
|
||||
setter(FunSpec.setterBuilder().addParameter("value", FqName::class).addCode(code("packageFqName = value")).build())
|
||||
}
|
||||
baseGetter = "packageFqName"
|
||||
customSetter = "packageFqName = value"
|
||||
deprecation = Deprecated(
|
||||
"Please use `packageFqName` instead",
|
||||
ReplaceWith("packageFqName"),
|
||||
DeprecationLevel.ERROR,
|
||||
)
|
||||
}
|
||||
}
|
||||
val externalPackageFragment: ElementConfig by element(Declaration) {
|
||||
@@ -679,11 +677,11 @@ object IrTree : AbstractTreeBuilder() {
|
||||
parent(attributeContainer)
|
||||
|
||||
+field("attributeOwnerId", attributeContainer) {
|
||||
baseDefaultValue = code("this")
|
||||
baseDefaultValue = "this"
|
||||
skipInIrFactory()
|
||||
}
|
||||
+field("originalBeforeInline", attributeContainer, nullable = true) {
|
||||
baseDefaultValue = code("null")
|
||||
baseDefaultValue = "null"
|
||||
skipInIrFactory()
|
||||
}
|
||||
+field("type", irTypeType)
|
||||
@@ -740,67 +738,79 @@ object IrTree : AbstractTreeBuilder() {
|
||||
parent(declarationReference)
|
||||
|
||||
+field("dispatchReceiver", expression, nullable = true, isChild = true) {
|
||||
baseDefaultValue = code("null")
|
||||
baseDefaultValue = "null"
|
||||
}
|
||||
+field("extensionReceiver", expression, nullable = true, isChild = true) {
|
||||
baseDefaultValue = code("null")
|
||||
baseDefaultValue = "null"
|
||||
}
|
||||
+symbol(s)
|
||||
+field("origin", statementOriginType, nullable = true)
|
||||
+listField("valueArguments", expression.copy(nullable = true), mutability = Array, isChild = true) {
|
||||
generationCallback = {
|
||||
addModifiers(KModifier.PROTECTED)
|
||||
}
|
||||
visibility = Visibility.PROTECTED
|
||||
}
|
||||
+listField("typeArguments", irTypeType.copy(nullable = true), mutability = Array) {
|
||||
generationCallback = {
|
||||
addModifiers(KModifier.PROTECTED)
|
||||
}
|
||||
visibility = Visibility.PROTECTED
|
||||
}
|
||||
|
||||
val checkArgumentSlotAccess = MemberName("org.jetbrains.kotlin.ir.expressions", "checkArgumentSlotAccess", true)
|
||||
usedTypes += ArbitraryImportable(Packages.exprs, "checkArgumentSlotAccess")
|
||||
generationCallback = {
|
||||
addFunction(
|
||||
FunSpec.builder("getValueArgument")
|
||||
.addParameter("index", int.toPoet())
|
||||
.returns(expression.toPoet().copy(nullable = true))
|
||||
.addCode("%M(\"value\", index, valueArguments.size)\n", checkArgumentSlotAccess)
|
||||
.addCode("return valueArguments[index]")
|
||||
.build()
|
||||
val indexParam = FunctionParameter("index", StandardTypes.int)
|
||||
val valueArgumentParam = FunctionParameter("valueArgument", expression.copy(nullable = true))
|
||||
val typeArgumentParam = FunctionParameter("type", irTypeType.copy(nullable = true))
|
||||
|
||||
fun printSizeProperty(listName: String) {
|
||||
println()
|
||||
println("val ", listName, "Count: Int")
|
||||
withIndent {
|
||||
println("get() = ", listName, ".size")
|
||||
}
|
||||
}
|
||||
|
||||
printSizeProperty("valueArguments")
|
||||
printSizeProperty("typeArguments")
|
||||
|
||||
fun printFunction(
|
||||
name: String,
|
||||
additionalParameter: FunctionParameter?,
|
||||
returnType: TypeRefWithNullability,
|
||||
vararg statements: String,
|
||||
) {
|
||||
println()
|
||||
printFunctionDeclaration(name, listOf(indexParam) + listOfNotNull(additionalParameter), returnType)
|
||||
println(" {")
|
||||
withIndent {
|
||||
statements.forEach { println(it) }
|
||||
}
|
||||
println("}")
|
||||
}
|
||||
|
||||
printFunction(
|
||||
"getValueArgument",
|
||||
null,
|
||||
expression.copy(nullable = true),
|
||||
"checkArgumentSlotAccess(\"value\", index, valueArguments.size)",
|
||||
"return valueArguments[index]",
|
||||
)
|
||||
addFunction(
|
||||
FunSpec.builder("getTypeArgument")
|
||||
.addParameter("index", int.toPoet())
|
||||
.returns(irTypeType.toPoet().copy(nullable = true))
|
||||
.addCode("%M(\"type\", index, typeArguments.size)\n", checkArgumentSlotAccess)
|
||||
.addCode("return typeArguments[index]")
|
||||
.build()
|
||||
printFunction(
|
||||
"getTypeArgument",
|
||||
null,
|
||||
irTypeType.copy(nullable = true),
|
||||
"checkArgumentSlotAccess(\"type\", index, typeArguments.size)",
|
||||
"return typeArguments[index]",
|
||||
)
|
||||
addFunction(
|
||||
FunSpec.builder("putValueArgument")
|
||||
.addParameter("index", int.toPoet())
|
||||
.addParameter("valueArgument", expression.toPoet().copy(nullable = true))
|
||||
.addCode("%M(\"value\", index, valueArguments.size)\n", checkArgumentSlotAccess)
|
||||
.addCode("valueArguments[index] = valueArgument")
|
||||
.build()
|
||||
printFunction(
|
||||
"putValueArgument",
|
||||
valueArgumentParam,
|
||||
StandardTypes.unit,
|
||||
"checkArgumentSlotAccess(\"value\", index, valueArguments.size)",
|
||||
"valueArguments[index] = valueArgument",
|
||||
)
|
||||
addFunction(
|
||||
FunSpec.builder("putTypeArgument")
|
||||
.addParameter("index", int.toPoet())
|
||||
.addParameter("type", irTypeType.toPoet().copy(nullable = true))
|
||||
.addCode("%M(\"type\", index, typeArguments.size)\n", checkArgumentSlotAccess)
|
||||
.addCode("typeArguments[index] = type")
|
||||
.build()
|
||||
)
|
||||
addProperty(
|
||||
PropertySpec.builder("valueArgumentsCount", int.toPoet())
|
||||
.getter(FunSpec.getterBuilder().addCode("return valueArguments.size").build())
|
||||
.build()
|
||||
)
|
||||
addProperty(
|
||||
PropertySpec.builder("typeArgumentsCount", int.toPoet())
|
||||
.getter(FunSpec.getterBuilder().addCode("return typeArguments.size").build())
|
||||
.build()
|
||||
printFunction(
|
||||
"putTypeArgument",
|
||||
typeArgumentParam,
|
||||
StandardTypes.unit,
|
||||
"checkArgumentSlotAccess(\"type\", index, typeArguments.size)",
|
||||
"typeArguments[index] = type",
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -867,10 +877,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
|
||||
+field("origin", statementOriginType, nullable = true)
|
||||
+listField("statements", statement, mutability = List, isChild = true) {
|
||||
generationCallback = {
|
||||
addModifiers(KModifier.OVERRIDE)
|
||||
}
|
||||
baseDefaultValue = code("ArrayList(2)")
|
||||
baseDefaultValue = "ArrayList(2)"
|
||||
}
|
||||
}
|
||||
val block: ElementConfig by element(Expression) {
|
||||
@@ -913,7 +920,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
|
||||
+field("loop", loop)
|
||||
+field("label", string, nullable = true) {
|
||||
baseDefaultValue = code("null")
|
||||
baseDefaultValue = "null"
|
||||
}
|
||||
}
|
||||
val `break` by element(Expression) {
|
||||
@@ -993,19 +1000,22 @@ object IrTree : AbstractTreeBuilder() {
|
||||
parent(expression)
|
||||
|
||||
generationCallback = {
|
||||
addFunction(
|
||||
FunSpec.builder("contentEquals")
|
||||
.addModifiers(KModifier.ABSTRACT)
|
||||
.addParameter("other", constantValue.toPoet())
|
||||
.returns(boolean.toPoet())
|
||||
.build()
|
||||
println()
|
||||
printFunctionDeclaration(
|
||||
name = "contentEquals",
|
||||
parameters = listOf(FunctionParameter("other", constantValue)),
|
||||
returnType = StandardTypes.boolean,
|
||||
modality = Modality.ABSTRACT,
|
||||
)
|
||||
addFunction(
|
||||
FunSpec.builder("contentHashCode")
|
||||
.addModifiers(KModifier.ABSTRACT)
|
||||
.returns(int.toPoet())
|
||||
.build()
|
||||
println()
|
||||
println()
|
||||
printFunctionDeclaration(
|
||||
name = "contentHashCode",
|
||||
parameters = emptyList(),
|
||||
returnType = StandardTypes.int,
|
||||
modality = Modality.ABSTRACT,
|
||||
)
|
||||
println()
|
||||
}
|
||||
}
|
||||
val constantPrimitive: ElementConfig by element(Expression) {
|
||||
@@ -1093,7 +1103,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+symbol(fieldSymbolType, mutable = true)
|
||||
+field("superQualifierSymbol", classSymbolType, nullable = true)
|
||||
+field("receiver", expression, nullable = true, isChild = true) {
|
||||
baseDefaultValue = code("null")
|
||||
baseDefaultValue = "null"
|
||||
}
|
||||
+field("origin", statementOriginType, nullable = true)
|
||||
}
|
||||
@@ -1141,11 +1151,11 @@ object IrTree : AbstractTreeBuilder() {
|
||||
|
||||
+field("origin", statementOriginType, nullable = true)
|
||||
+field("body", expression, nullable = true, isChild = true) {
|
||||
baseDefaultValue = code("null")
|
||||
baseDefaultValue = "null"
|
||||
}
|
||||
+field("condition", expression, isChild = true)
|
||||
+field("label", string, nullable = true) {
|
||||
baseDefaultValue = code("null")
|
||||
baseDefaultValue = "null"
|
||||
}
|
||||
}
|
||||
val whileLoop: ElementConfig by element(Expression) {
|
||||
|
||||
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.ir.generator.print.*
|
||||
import java.io.File
|
||||
|
||||
const val BASE_PACKAGE = "org.jetbrains.kotlin.ir"
|
||||
const val VISITOR_PACKAGE = "$BASE_PACKAGE.visitors"
|
||||
|
||||
internal const val TREE_GENERATOR_README = "compiler/ir/ir.tree/tree-generator/ReadMe.md"
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val generationPath = args.firstOrNull()?.let { File(it) }
|
||||
|
||||
+11
-12
@@ -5,13 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.generator.config
|
||||
|
||||
import com.squareup.kotlinpoet.CodeBlock
|
||||
import com.squareup.kotlinpoet.PropertySpec
|
||||
import com.squareup.kotlinpoet.TypeSpec
|
||||
import org.jetbrains.kotlin.generators.tree.*
|
||||
import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.utils.SmartPrinter
|
||||
|
||||
class Config(
|
||||
val elements: List<ElementConfig>,
|
||||
@@ -26,7 +23,7 @@ class ElementConfig(
|
||||
val params = mutableListOf<TypeVariable>()
|
||||
val parents = mutableListOf<TypeRef>()
|
||||
val fields = mutableListOf<FieldConfig>()
|
||||
val additionalImports = mutableListOf<Import>()
|
||||
val usedTypes = mutableListOf<Importable>()
|
||||
|
||||
var visitorName: String? = null
|
||||
var visitorParent: ElementConfig? = null
|
||||
@@ -53,7 +50,7 @@ class ElementConfig(
|
||||
|
||||
var typeKind: TypeKind? = null
|
||||
|
||||
var generationCallback: (TypeSpec.Builder.() -> Unit)? = null
|
||||
var generationCallback: (context(ImportCollector) SmartPrinter.() -> Unit)? = null
|
||||
var kDoc: String? = null
|
||||
|
||||
override val element get() = this
|
||||
@@ -139,10 +136,14 @@ sealed class FieldConfig(
|
||||
val name: String,
|
||||
val isChild: Boolean,
|
||||
) {
|
||||
var baseDefaultValue: CodeBlock? = null
|
||||
var baseGetter: CodeBlock? = null
|
||||
var printProperty = true
|
||||
var strictCastInTransformChildren = false
|
||||
var baseDefaultValue: String? = null
|
||||
var baseGetter: String? = null
|
||||
var customSetter: String? = null
|
||||
var optInAnnotation: ClassRef<*>? = null
|
||||
|
||||
var deprecation: Deprecated? = null
|
||||
|
||||
var visibility = Visibility.PUBLIC
|
||||
|
||||
internal var useFieldInIrFactoryStrategy: UseFieldAsParameterInIrFactoryStrategy =
|
||||
if (isChild) UseFieldAsParameterInIrFactoryStrategy.No else UseFieldAsParameterInIrFactoryStrategy.Yes(null)
|
||||
@@ -157,8 +158,6 @@ sealed class FieldConfig(
|
||||
|
||||
var kDoc: String? = null
|
||||
|
||||
var generationCallback: (PropertySpec.Builder.() -> Unit)? = null
|
||||
|
||||
override fun toString() = name
|
||||
}
|
||||
|
||||
|
||||
+20
-14
@@ -5,11 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.generator.model
|
||||
|
||||
import com.squareup.kotlinpoet.CodeBlock
|
||||
import org.jetbrains.kotlin.generators.tree.*
|
||||
import org.jetbrains.kotlin.ir.generator.config.ElementConfig
|
||||
import org.jetbrains.kotlin.ir.generator.config.FieldConfig
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.utils.topologicalSort
|
||||
import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
@@ -77,7 +75,7 @@ class Element(
|
||||
|
||||
override val kDoc = config.kDoc
|
||||
|
||||
val additionalImports: List<Import> = config.additionalImports
|
||||
val usedTypes: List<Importable> = config.usedTypes
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
@@ -112,25 +110,33 @@ class Element(
|
||||
typealias ElementRef = GenericElementRef<Element, Field>
|
||||
typealias ElementOrRef = GenericElementOrRef<Element, Field>
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
sealed class Field(
|
||||
config: FieldConfig,
|
||||
override val name: String,
|
||||
override var isMutable: Boolean,
|
||||
val isChild: Boolean,
|
||||
) : AbstractField() {
|
||||
abstract val baseDefaultValue: CodeBlock?
|
||||
abstract val baseGetter: CodeBlock?
|
||||
var isOverride = false
|
||||
var needsDescriptorApiAnnotation = false
|
||||
abstract val baseDefaultValue: String?
|
||||
abstract val baseGetter: String?
|
||||
abstract val transformable: Boolean
|
||||
|
||||
val useInIrFactoryStrategy = config.useFieldInIrFactoryStrategy
|
||||
|
||||
init {
|
||||
kDoc = config.kDoc
|
||||
optInAnnotation = config.optInAnnotation
|
||||
deprecation = config.deprecation
|
||||
visibility = config.visibility
|
||||
}
|
||||
|
||||
val printProperty = config.printProperty
|
||||
val generationCallback = config.generationCallback
|
||||
override val withGetter: Boolean
|
||||
get() = baseGetter != null
|
||||
|
||||
override val defaultValueInImplementation: String?
|
||||
get() = baseGetter ?: baseDefaultValue
|
||||
|
||||
override val customSetter: String? = config.customSetter
|
||||
|
||||
override fun toString() = "$name: $typeRef"
|
||||
|
||||
@@ -138,7 +144,7 @@ sealed class Field(
|
||||
get() = false
|
||||
|
||||
override val isFinal: Boolean
|
||||
get() = false
|
||||
get() = defaultValueInImplementation != null
|
||||
|
||||
override val isLateinit: Boolean
|
||||
get() = false
|
||||
@@ -153,8 +159,8 @@ class SingleField(
|
||||
override var typeRef: TypeRefWithNullability,
|
||||
mutable: Boolean,
|
||||
isChild: Boolean,
|
||||
override val baseDefaultValue: CodeBlock?,
|
||||
override val baseGetter: CodeBlock?,
|
||||
override val baseDefaultValue: String?,
|
||||
override val baseGetter: String?,
|
||||
) : Field(config, name, mutable, isChild) {
|
||||
override val transformable: Boolean
|
||||
get() = isMutable
|
||||
@@ -168,8 +174,8 @@ class ListField(
|
||||
mutable: Boolean,
|
||||
isChild: Boolean,
|
||||
override val transformable: Boolean,
|
||||
override val baseDefaultValue: CodeBlock?,
|
||||
override val baseGetter: CodeBlock?,
|
||||
override val baseDefaultValue: String?,
|
||||
override val baseGetter: String?,
|
||||
) : Field(config, name, mutable, isChild) {
|
||||
override val typeRef: TypeRefWithNullability
|
||||
get() = listType.withArgs(elementType)
|
||||
|
||||
+2
-17
@@ -50,7 +50,6 @@ fun config2model(config: Config): Model {
|
||||
configureInterfacesAndAbstractClasses(elements)
|
||||
addPureAbstractElement(elements, elementBaseType)
|
||||
markLeaves(elements)
|
||||
configureDescriptorApiAnnotation(elements)
|
||||
processFieldOverrides(elements)
|
||||
addWalkableChildren(elements)
|
||||
|
||||
@@ -160,19 +159,6 @@ private fun markLeaves(elements: List<Element>) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureDescriptorApiAnnotation(elements: List<Element>) {
|
||||
for (el in elements) {
|
||||
for (field in el.fields) {
|
||||
val type = field.typeRef
|
||||
if (type is ClassRef<*> && type.packageName.startsWith("org.jetbrains.kotlin.descriptors") &&
|
||||
type.simpleName.endsWith("Descriptor") && type.simpleName != "ModuleDescriptor"
|
||||
) {
|
||||
field.needsDescriptorApiAnnotation = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processFieldOverrides(elements: List<Element>) {
|
||||
for (element in iterateElementsParentFirst(elements)) {
|
||||
for (field in element.fields) {
|
||||
@@ -180,9 +166,8 @@ private fun processFieldOverrides(elements: List<Element>) {
|
||||
for (parent in visited.elementParents) {
|
||||
val overriddenField = parent.element.fields.singleOrNull { it.name == field.name }
|
||||
if (overriddenField != null) {
|
||||
field.isOverride = true
|
||||
field.needsDescriptorApiAnnotation =
|
||||
field.needsDescriptorApiAnnotation || overriddenField.needsDescriptorApiAnnotation
|
||||
field.fromParent = true
|
||||
field.optInAnnotation = field.optInAnnotation ?: overriddenField.optInAnnotation
|
||||
|
||||
fun transformInferredType(type: TypeRef, overriddenType: TypeRef) =
|
||||
type.takeUnless { it is InferredOverriddenType } ?: overriddenType
|
||||
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.generator.print
|
||||
|
||||
import com.squareup.kotlinpoet.FileSpec
|
||||
import com.squareup.kotlinpoet.TypeSpec
|
||||
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
|
||||
import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType
|
||||
import org.jetbrains.kotlin.ir.generator.util.Import
|
||||
import java.io.File
|
||||
|
||||
internal const val TREE_GENERATOR_README = "compiler/ir/ir.tree/tree-generator/ReadMe.md"
|
||||
|
||||
fun printTypeCommon(
|
||||
generationPath: File,
|
||||
packageName: String,
|
||||
type: TypeSpec,
|
||||
additionalImports: List<Import> = emptyList(),
|
||||
): GeneratedFile = printGeneratedType(generationPath, TREE_GENERATOR_README, packageName, type.name!!) {
|
||||
val code = FileSpec.builder(packageName, type.name!!)
|
||||
.apply {
|
||||
additionalImports.forEach { addImport(it.packageName, it.className) }
|
||||
}
|
||||
.indent(" ")
|
||||
.addType(type)
|
||||
.build()
|
||||
.toString()
|
||||
.replace("package $packageName\n\n", "")
|
||||
.unbacktickIdentifiers("data", "value", "operator", "constructor", "delegate", "receiver", "field")
|
||||
.replace("public ", "")
|
||||
.replace(":\\s*Unit".toRegex(), "")
|
||||
.replace("import kotlin\\..*\\n".toRegex(), "")
|
||||
// Half-baked attempt to remove double indent generated by KotlinPoet, which is not idiomatic according to the Kotlin style guide
|
||||
.replace(" visitor.visit", " visitor.visit")
|
||||
.replace(" accept(transformer, data)", " accept(transformer, data)")
|
||||
print(code)
|
||||
}
|
||||
|
||||
private fun String.unbacktickIdentifiers(vararg identifiers: String): String {
|
||||
var result = this
|
||||
for (identifier in identifiers) {
|
||||
result = result.replace("`$identifier`", identifier)
|
||||
}
|
||||
return result
|
||||
}
|
||||
+137
-243
@@ -5,278 +5,172 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.generator.print
|
||||
|
||||
import com.squareup.kotlinpoet.*
|
||||
import org.jetbrains.kotlin.generators.tree.ImplementationKind
|
||||
import org.jetbrains.kotlin.generators.tree.TypeKind
|
||||
import org.jetbrains.kotlin.generators.tree.*
|
||||
import org.jetbrains.kotlin.generators.tree.printer.*
|
||||
import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE
|
||||
import org.jetbrains.kotlin.ir.generator.TREE_GENERATOR_README
|
||||
import org.jetbrains.kotlin.ir.generator.elementTransformerType
|
||||
import org.jetbrains.kotlin.ir.generator.elementVisitorType
|
||||
import org.jetbrains.kotlin.ir.generator.model.*
|
||||
import org.jetbrains.kotlin.generators.tree.TypeRefWithNullability
|
||||
import org.jetbrains.kotlin.generators.tree.typeKind
|
||||
import org.jetbrains.kotlin.generators.tree.printer.extendedKDoc
|
||||
import org.jetbrains.kotlin.ir.generator.util.tryParameterizedBy
|
||||
import org.jetbrains.kotlin.utils.SmartPrinter
|
||||
import org.jetbrains.kotlin.utils.withIndent
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
|
||||
fun printElements(generationPath: File, model: Model) = sequence {
|
||||
for (element in model.elements) {
|
||||
private val transformIfNeeded = ArbitraryImportable("$BASE_PACKAGE.util", "transformIfNeeded")
|
||||
private val transformInPlace = ArbitraryImportable("$BASE_PACKAGE.util", "transformInPlace")
|
||||
|
||||
val elementName = element.toPoet()
|
||||
val selfParametrizedElementName = element.toPoetSelfParameterized()
|
||||
private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Element, Field>(printer) {
|
||||
|
||||
val elementType = when (element.kind?.typeKind) {
|
||||
null -> error("Element's category not configured")
|
||||
TypeKind.Class -> TypeSpec.classBuilder(elementName)
|
||||
TypeKind.Interface -> TypeSpec.interfaceBuilder(elementName)
|
||||
}.apply {
|
||||
addModifiers(
|
||||
when (element.kind) {
|
||||
ImplementationKind.SealedClass -> listOf(KModifier.SEALED)
|
||||
ImplementationKind.SealedInterface -> listOf(KModifier.SEALED)
|
||||
ImplementationKind.AbstractClass -> listOf(KModifier.ABSTRACT)
|
||||
ImplementationKind.FinalClass -> listOf(KModifier.FINAL)
|
||||
ImplementationKind.OpenClass -> listOf(KModifier.OPEN)
|
||||
else -> emptyList()
|
||||
}
|
||||
override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter<Field>(printer) {
|
||||
override fun forceMutable(field: Field) = field.isMutable
|
||||
}
|
||||
|
||||
override fun defaultElementKDoc(element: Element) =
|
||||
"A ${if (element.isLeaf) "leaf" else "non-leaf"} IR tree element."
|
||||
|
||||
override val separateFieldsWithBlankLine: Boolean
|
||||
get() = true
|
||||
|
||||
context(ImportCollector)
|
||||
override fun SmartPrinter.printAdditionalMethods(element: Element) {
|
||||
element.generationCallback?.invoke(this@ImportCollector, this)
|
||||
|
||||
if (element.hasAcceptMethod) {
|
||||
printAcceptMethod(
|
||||
element = element,
|
||||
visitorClass = elementVisitorType,
|
||||
hasImplementation = !element.isRootElement,
|
||||
kDoc = """
|
||||
Runs the provided [visitor] on the IR subtree with the root at this node.
|
||||
|
||||
@param visitor The visitor to accept.
|
||||
@param data An arbitrary context to pass to each invocation of [visitor]'s methods.
|
||||
@return The value returned by the topmost `visit*` invocation.
|
||||
""".trimIndent().takeIf { element.isRootElement }
|
||||
)
|
||||
addTypeVariables(element.params.map { it.toPoet() })
|
||||
}
|
||||
|
||||
val (classes, interfaces) = element.parentRefs.partition { it.typeKind == TypeKind.Class }
|
||||
classes.singleOrNull()?.let {
|
||||
superclass(it.toPoet())
|
||||
}
|
||||
addSuperinterfaces(interfaces.map { it.toPoet() })
|
||||
if (element.hasTransformMethod) {
|
||||
printTransformMethod(
|
||||
element = element,
|
||||
transformerClass = elementTransformerType,
|
||||
implementation = "accept(transformer, data)".takeIf { !element.isRootElement },
|
||||
returnType = element,
|
||||
kDoc = """
|
||||
Runs the provided [transformer] on the IR subtree with the root at this node.
|
||||
|
||||
@param transformer The transformer to use.
|
||||
@param data An arbitrary context to pass to each invocation of [transformer]'s methods.
|
||||
@return The transformed node.
|
||||
""".trimIndent().takeIf { element.isRootElement }
|
||||
)
|
||||
}
|
||||
|
||||
for (field in element.fields) {
|
||||
if (!field.printProperty) continue
|
||||
val poetType = field.typeRef.toPoet().copy(nullable = field.nullable)
|
||||
addProperty(PropertySpec.builder(field.name, poetType).apply {
|
||||
mutable(field.isMutable)
|
||||
if (field.isOverride) {
|
||||
addModifiers(KModifier.OVERRIDE)
|
||||
}
|
||||
if (field.baseDefaultValue == null && field.baseGetter == null) {
|
||||
addModifiers(KModifier.ABSTRACT)
|
||||
}
|
||||
|
||||
field.baseDefaultValue?.let {
|
||||
initializer(it)
|
||||
}
|
||||
field.baseGetter?.let {
|
||||
getter(FunSpec.getterBuilder().addCode("return ").addCode(it).build())
|
||||
}
|
||||
|
||||
if (field.needsDescriptorApiAnnotation) {
|
||||
addAnnotation(descriptorApiAnnotation)
|
||||
}
|
||||
|
||||
field.kDoc?.let {
|
||||
addKdoc(it)
|
||||
}
|
||||
|
||||
field.generationCallback?.invoke(this)
|
||||
}.build())
|
||||
}
|
||||
|
||||
val isRootElement = element.isRootElement
|
||||
val acceptMethodName = "accept"
|
||||
val transformMethodName = "transform"
|
||||
if (element.hasAcceptMethod) {
|
||||
addFunction(FunSpec.builder(acceptMethodName).apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val r = TypeVariableName("R")
|
||||
val d = TypeVariableName("D")
|
||||
addTypeVariable(r)
|
||||
addTypeVariable(d)
|
||||
val visitorParam = ParameterSpec.builder("visitor", elementVisitorType.toPoet().tryParameterizedBy(r, d))
|
||||
.build()
|
||||
.also(::addParameter)
|
||||
val dataParam = ParameterSpec.builder("data", d)
|
||||
.build()
|
||||
.also(::addParameter)
|
||||
returns(r)
|
||||
if (!isRootElement) {
|
||||
addStatement("return %N.%N(this, %N)", visitorParam, element.visitFunctionName, dataParam)
|
||||
}
|
||||
if (isRootElement) {
|
||||
addKdoc(
|
||||
"""
|
||||
Runs the provided [%1N] on the IR subtree with the root at this node.
|
||||
|
||||
@param %1N The visitor to accept.
|
||||
@param %2N An arbitrary context to pass to each invocation of [%1N]'s methods.
|
||||
@return The value returned by the topmost `visit*` invocation.
|
||||
""".trimIndent(),
|
||||
visitorParam,
|
||||
dataParam,
|
||||
)
|
||||
}
|
||||
}.build())
|
||||
}
|
||||
|
||||
if (element.hasTransformMethod) {
|
||||
addFunction(FunSpec.builder(transformMethodName).apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val d = TypeVariableName("D")
|
||||
addTypeVariable(d)
|
||||
val transformerParam = ParameterSpec.builder("transformer", elementTransformerType.toPoet().tryParameterizedBy(d))
|
||||
.build()
|
||||
.also(::addParameter)
|
||||
val dataParam = ParameterSpec.builder("data", d)
|
||||
.build()
|
||||
.also(::addParameter)
|
||||
returns(selfParametrizedElementName)
|
||||
if (!isRootElement) {
|
||||
addStatement("return %N(%N, %N) as %T", acceptMethodName, transformerParam, dataParam, selfParametrizedElementName)
|
||||
}
|
||||
if (isRootElement) {
|
||||
addKdoc(
|
||||
"""
|
||||
Runs the provided [%1N] on the IR subtree with the root at this node.
|
||||
|
||||
@param %1N The transformer to use.
|
||||
@param %2N An arbitrary context to pass to each invocation of [%1N]'s methods.
|
||||
@return The transformed node.
|
||||
""".trimIndent(),
|
||||
transformerParam,
|
||||
dataParam,
|
||||
)
|
||||
}
|
||||
}.build())
|
||||
}
|
||||
|
||||
if (element.hasAcceptChildrenMethod) {
|
||||
addFunction(FunSpec.builder("acceptChildren").apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val d = TypeVariableName("D")
|
||||
addTypeVariable(d)
|
||||
|
||||
val visitorParam = ParameterSpec
|
||||
.builder("visitor", elementVisitorType.toPoet().tryParameterizedBy(UNIT, d)).build()
|
||||
.also(::addParameter)
|
||||
val dataParam = ParameterSpec
|
||||
.builder("data", d).build()
|
||||
.also(::addParameter)
|
||||
if (element.hasAcceptChildrenMethod) {
|
||||
printAcceptChildrenMethod(
|
||||
element = element,
|
||||
visitorClass = elementVisitorType,
|
||||
visitorResultType = StandardTypes.unit,
|
||||
override = !element.isRootElement,
|
||||
kDoc = """
|
||||
Runs the provided [visitor] on subtrees with roots in this node's children.
|
||||
|
||||
Basically, calls `accept(visitor, data)` on each child of this node.
|
||||
|
||||
Does **not** run [visitor] on this node itself.
|
||||
|
||||
@param visitor The visitor for children to accept.
|
||||
@param data An arbitrary context to pass to each invocation of [visitor]'s methods.
|
||||
""".trimIndent().takeIf { element.isRootElement }
|
||||
)
|
||||
|
||||
if (!element.isRootElement) {
|
||||
println(" {")
|
||||
withIndent {
|
||||
for (child in element.walkableChildren) {
|
||||
addStatement(buildString {
|
||||
append("%N")
|
||||
if (child.nullable) append("?")
|
||||
when (child) {
|
||||
is SingleField -> append(".%N(%N, %N)")
|
||||
is ListField -> {
|
||||
append(".forEach { it")
|
||||
if ((child.elementType as? TypeRefWithNullability)?.nullable == true) append("?")
|
||||
append(".%N(%N, %N) }")
|
||||
print(child.name)
|
||||
if (child.nullable) {
|
||||
print("?")
|
||||
}
|
||||
when (child) {
|
||||
is SingleField -> println(".accept(visitor, data)")
|
||||
is ListField -> {
|
||||
print(".forEach { it")
|
||||
if (child.elementType.nullable) {
|
||||
print("?")
|
||||
}
|
||||
println(".accept(visitor, data) }")
|
||||
}
|
||||
}, child.name, acceptMethodName, visitorParam, dataParam)
|
||||
}
|
||||
}
|
||||
|
||||
if (isRootElement) {
|
||||
addKdoc(
|
||||
"""
|
||||
Runs the provided [%1N] on subtrees with roots in this node's children.
|
||||
|
||||
Basically, calls `%3N(%1N, %2N)` on each child of this node.
|
||||
|
||||
Does **not** run [%1N] on this node itself.
|
||||
|
||||
@param %1N The visitor for children to accept.
|
||||
@param %2N An arbitrary context to pass to each invocation of [%1N]'s methods.
|
||||
""".trimIndent(),
|
||||
visitorParam,
|
||||
dataParam,
|
||||
acceptMethodName,
|
||||
)
|
||||
}
|
||||
}.build())
|
||||
}
|
||||
print("}")
|
||||
}
|
||||
println()
|
||||
}
|
||||
|
||||
if (element.hasTransformChildrenMethod) {
|
||||
addFunction(FunSpec.builder("transformChildren").apply {
|
||||
addModifiers(if (isRootElement) KModifier.ABSTRACT else KModifier.OVERRIDE)
|
||||
val d = TypeVariableName("D")
|
||||
addTypeVariable(d)
|
||||
val transformerParam =
|
||||
ParameterSpec.builder("transformer", elementTransformerType.toPoet().tryParameterizedBy(d)).build()
|
||||
.also(::addParameter)
|
||||
val dataParam = ParameterSpec.builder("data", d).build().also(::addParameter)
|
||||
|
||||
if (element.hasTransformChildrenMethod) {
|
||||
printTransformChildrenMethod(
|
||||
element = element,
|
||||
transformerClass = elementTransformerType,
|
||||
returnType = StandardTypes.unit,
|
||||
override = !element.isRootElement,
|
||||
kDoc = """
|
||||
Recursively transforms this node's children *in place* using [transformer].
|
||||
|
||||
Basically, executes `this.child = this.child.transform(transformer, data)` for each child of this node.
|
||||
|
||||
Does **not** run [transformer] on this node itself.
|
||||
|
||||
@param transformer The transformer to use for transforming the children.
|
||||
@param data An arbitrary context to pass to each invocation of [transformer]'s methods.
|
||||
""".trimIndent().takeIf { element.isRootElement }
|
||||
)
|
||||
if (!element.isRootElement) {
|
||||
println(" {")
|
||||
withIndent {
|
||||
for (child in element.transformableChildren) {
|
||||
val args = mutableListOf<Any>()
|
||||
val code = buildString {
|
||||
append("%N")
|
||||
args.add(child.name)
|
||||
when (child) {
|
||||
is SingleField -> {
|
||||
append(" = %N")
|
||||
args.add(child.name)
|
||||
if (child.nullable) append("?")
|
||||
append(".%N(%N, %N)")
|
||||
args.add(transformMethodName)
|
||||
print(child.name)
|
||||
when (child) {
|
||||
is SingleField -> {
|
||||
print(" = ", child.name)
|
||||
if (child.nullable) {
|
||||
print("?")
|
||||
}
|
||||
is ListField -> {
|
||||
if (child.isMutable) {
|
||||
append(" = ")
|
||||
append(child.name)
|
||||
if (child.nullable) append("?")
|
||||
}
|
||||
append(".%M(%N, %N)")
|
||||
args.add(if (child.isMutable) transformIfNeeded else transformInPlace)
|
||||
print(".transform(transformer, data)")
|
||||
val elementRef = child.typeRef as GenericElementRef<*, *>
|
||||
if (!elementRef.element.hasTransformMethod) {
|
||||
print(" as ", elementRef.render())
|
||||
}
|
||||
println()
|
||||
}
|
||||
|
||||
args.add(transformerParam)
|
||||
args.add(dataParam)
|
||||
|
||||
if (child is SingleField) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val elRef = child.typeRef as GenericElementRef<Element, Field>
|
||||
if (!elRef.element.hasTransformMethod) {
|
||||
append(" as %T")
|
||||
args.add(elRef.toPoet())
|
||||
is ListField -> {
|
||||
if (child.isMutable) {
|
||||
print(" = ", child.name)
|
||||
if (child.nullable) {
|
||||
print("?")
|
||||
}
|
||||
addImport(transformIfNeeded)
|
||||
println(".transformIfNeeded(transformer, data)")
|
||||
} else {
|
||||
addImport(transformInPlace)
|
||||
println(".transformInPlace(transformer, data)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addStatement(code, *args.toTypedArray())
|
||||
}
|
||||
|
||||
if (isRootElement) {
|
||||
addKdoc(
|
||||
"""
|
||||
Recursively transforms this node's children *in place* using [%1N].
|
||||
|
||||
Basically, executes `this.child = this.child.%3N(%1N, %2N)` for each child of this node.
|
||||
|
||||
Does **not** run [%1N] on this node itself.
|
||||
|
||||
@param %1N The transformer to use for transforming the children.
|
||||
@param %2N An arbitrary context to pass to each invocation of [%1N]'s methods.
|
||||
""".trimIndent(),
|
||||
transformerParam,
|
||||
dataParam,
|
||||
transformMethodName,
|
||||
)
|
||||
}
|
||||
}.build())
|
||||
}
|
||||
print("}")
|
||||
}
|
||||
|
||||
generateElementKDoc(element)
|
||||
|
||||
element.generationCallback?.invoke(this)
|
||||
}.build()
|
||||
|
||||
yield(printTypeCommon(generationPath, elementName.packageName, elementType, element.additionalImports))
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TypeSpec.Builder.generateElementKDoc(element: Element) {
|
||||
addKdoc(element.extendedKDoc("A ${if (element.isLeaf) "leaf" else "non-leaf"} IR tree element."))
|
||||
fun printElements(generationPath: File, model: Model) = model.elements.map { element ->
|
||||
printGeneratedType(generationPath, TREE_GENERATOR_README, element.packageName, element.typeName) {
|
||||
addAllImports(element.usedTypes)
|
||||
ElementPrinter(this).printElement(element)
|
||||
}
|
||||
}
|
||||
|
||||
private val descriptorApiAnnotation = ClassName("org.jetbrains.kotlin.ir", "ObsoleteDescriptorBasedAPI")
|
||||
private val transformIfNeeded = MemberName("$BASE_PACKAGE.util", "transformIfNeeded", true)
|
||||
private val transformInPlace = MemberName("$BASE_PACKAGE.util", "transformInPlace", true)
|
||||
|
||||
+1
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
|
||||
import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration
|
||||
import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType
|
||||
import org.jetbrains.kotlin.ir.generator.IrTree
|
||||
import org.jetbrains.kotlin.ir.generator.TREE_GENERATOR_README
|
||||
import org.jetbrains.kotlin.ir.generator.config.UseFieldAsParameterInIrFactoryStrategy
|
||||
import org.jetbrains.kotlin.ir.generator.irFactoryType
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element
|
||||
@@ -28,7 +29,6 @@ internal fun printFactory(generationPath: File, model: Model): GeneratedFile = p
|
||||
irFactoryType.packageName,
|
||||
irFactoryType.simpleName,
|
||||
) {
|
||||
println()
|
||||
println("interface ", irFactoryType.simpleName, " {")
|
||||
withIndent {
|
||||
println("val stageController: ", stageControllerType.render())
|
||||
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.generator.print
|
||||
|
||||
import com.squareup.kotlinpoet.*
|
||||
import org.jetbrains.kotlin.generators.tree.*
|
||||
import org.jetbrains.kotlin.ir.generator.config.ElementConfigOrRef
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element.Companion.elementName2typeName
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef
|
||||
|
||||
fun Element.toPoet() = ClassName(packageName, this.typeName)
|
||||
fun Element.toPoetSelfParameterized() = toPoet().parameterizedByIfAny(poetTypeVariables)
|
||||
fun Element.toPoetStarParameterized() = toPoet().parameterizedByIfAny(List(params.size) { STAR })
|
||||
val Element.poetTypeVariables get() = params.map { TypeVariableName(it.name) }
|
||||
|
||||
fun TypeRef.toPoet(): TypeName {
|
||||
return when (this) {
|
||||
is GenericElementRef<*, *> -> ClassName(element.packageName, element.typeName).parameterizedByIfAny(typeArgsToPoet())
|
||||
is ClassRef<*> -> ClassName(packageName, simpleNames).parameterizedByIfAny(typeArgsToPoet())
|
||||
is NamedTypeParameterRef -> TypeVariableName(name)
|
||||
is ElementConfigOrRef -> ClassName(this.element.category.packageName, elementName2typeName(element.name)).parameterizedByIfAny(
|
||||
typeArgsToPoet()
|
||||
) // ad-hoc solution
|
||||
is TypeRef.Star -> STAR
|
||||
else -> error("Unexpected type reference: $this")
|
||||
}.let {
|
||||
if (this is TypeRefWithNullability) it.copy(nullable = nullable) else it
|
||||
}
|
||||
}
|
||||
|
||||
private fun ParametrizedTypeRef<*, *>.typeArgsToPoet(): List<TypeName> {
|
||||
if (args.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
fun fromPositional(args: Map<PositionTypeParameterRef, TypeRef>): List<TypeName> {
|
||||
val num = args.keys.maxOfOrNull { it.index }!!
|
||||
return (0..num).map { i -> args[PositionTypeParameterRef(i)]?.toPoet() ?: STAR }
|
||||
}
|
||||
|
||||
val positional = args.keys.filterIsInstance<PositionTypeParameterRef>()
|
||||
if (positional.size == args.size) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return fromPositional(args as Map<PositionTypeParameterRef, TypeRef>)
|
||||
} else {
|
||||
check(positional.isEmpty()) { "Can't yet handle mixed index-name args" }
|
||||
this as GenericElementRef<*, *> // Named args must only be used with generated elements (for now)
|
||||
|
||||
val args = args.entries
|
||||
.associate { p -> PositionTypeParameterRef(element.params.withIndex().single { it.value.name == p.key.name }.index) to p.value }
|
||||
return fromPositional(args)
|
||||
}
|
||||
}
|
||||
|
||||
fun TypeVariable.toPoet() = TypeVariableName(
|
||||
name, bounds.map { it.toPoet() }, when (variance) {
|
||||
Variance.INVARIANT -> null
|
||||
Variance.IN_VARIANCE -> KModifier.IN
|
||||
Variance.OUT_VARIANCE -> KModifier.OUT
|
||||
}
|
||||
)
|
||||
|
||||
-1
@@ -22,7 +22,6 @@ private fun printVisitorCommon(
|
||||
makePrinter: (SmartPrinter, ClassRef<*>) -> AbstractVisitorPrinter<Element, Field>,
|
||||
): GeneratedFile =
|
||||
printGeneratedType(generationPath, TREE_GENERATOR_README, visitorType.packageName, visitorType.simpleName) {
|
||||
println()
|
||||
makePrinter(this, visitorType).printVisitor(model.elements)
|
||||
}
|
||||
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.generator.util
|
||||
|
||||
import com.squareup.kotlinpoet.ClassName
|
||||
import com.squareup.kotlinpoet.CodeBlock
|
||||
import com.squareup.kotlinpoet.ParameterizedTypeName
|
||||
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
|
||||
import com.squareup.kotlinpoet.TypeName
|
||||
|
||||
class Import(val packageName: String, val className: String)
|
||||
|
||||
fun ClassName.parameterizedByIfAny(typeArguments: List<TypeName>) =
|
||||
if (typeArguments.isNotEmpty()) parameterizedBy(typeArguments) else this
|
||||
|
||||
fun TypeName.tryParameterizedBy(vararg typeArguments: TypeName) = when (this) {
|
||||
is ClassName -> parameterizedBy(*typeArguments)
|
||||
is ParameterizedTypeName -> this.rawType.parameterizedBy(*typeArguments)
|
||||
else -> {
|
||||
if (typeArguments.isNotEmpty())
|
||||
error("Type $this cannot be parameterized")
|
||||
else this
|
||||
}
|
||||
}
|
||||
|
||||
fun code(code: String, vararg args: Any?) = CodeBlock.of(code, *args)
|
||||
+1
-1
@@ -69,7 +69,7 @@ abstract class AbstractElementPrinter<Element : AbstractElement<Element, Field>,
|
||||
|
||||
if (body.isNotEmpty()) {
|
||||
println(" {")
|
||||
print(body)
|
||||
print(body.trimStart('\n'))
|
||||
print("}")
|
||||
}
|
||||
println()
|
||||
|
||||
+4
@@ -32,6 +32,10 @@ abstract class AbstractField {
|
||||
open val withGetter: Boolean get() = false
|
||||
open val customSetter: String? get() = null
|
||||
|
||||
var deprecation: Deprecated? = null
|
||||
|
||||
var visibility: Visibility = Visibility.PUBLIC
|
||||
|
||||
var fromParent: Boolean = false
|
||||
|
||||
open val defaultValueInImplementation: String? get() = null
|
||||
|
||||
+15
@@ -35,6 +35,17 @@ abstract class AbstractFieldPrinter<Field : AbstractField>(
|
||||
) {
|
||||
printer.run {
|
||||
printKDoc(field.kDoc)
|
||||
|
||||
field.deprecation?.let {
|
||||
println("@Deprecated(")
|
||||
withIndent {
|
||||
println("message = \"", it.message, "\",")
|
||||
println("replaceWith = ReplaceWith(\"", it.replaceWith.expression, "\"),")
|
||||
println("level = DeprecationLevel.", it.level.name, ",")
|
||||
}
|
||||
println(")")
|
||||
}
|
||||
|
||||
if (field.isVolatile) {
|
||||
println("@", type<Volatile>().render())
|
||||
}
|
||||
@@ -50,6 +61,10 @@ abstract class AbstractFieldPrinter<Field : AbstractField>(
|
||||
}
|
||||
}
|
||||
|
||||
if (field.visibility != Visibility.PUBLIC) {
|
||||
print(field.visibility.name.toLowerCaseAsciiOnly(), " ")
|
||||
}
|
||||
|
||||
modality?.let {
|
||||
print(it.name.toLowerCaseAsciiOnly(), " ")
|
||||
}
|
||||
|
||||
+9
-1
@@ -68,12 +68,20 @@ class ImportCollector(currentPackage: String) {
|
||||
addImport(packageName, "*")
|
||||
}
|
||||
|
||||
fun printAllImports(printer: Appendable) {
|
||||
/**
|
||||
* Prints all the collected imports in alphabetical order.
|
||||
*
|
||||
* @return `true` if at least one import was printed, `false` if no imports were printed.
|
||||
*/
|
||||
fun printAllImports(printer: Appendable): Boolean {
|
||||
var atLeastOneImport = false
|
||||
for ((packageName, entities) in imports) {
|
||||
for (entity in entities) {
|
||||
atLeastOneImport = true
|
||||
printer.append("import ", packageName, ".", entity, "\n")
|
||||
}
|
||||
}
|
||||
return atLeastOneImport
|
||||
}
|
||||
|
||||
fun addAllImports(importables: Collection<Importable>) {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.generators.tree
|
||||
|
||||
enum class Visibility {
|
||||
PUBLIC, PROTECTED, INTERNAL, PRIVATE
|
||||
}
|
||||
+3
-1
@@ -45,7 +45,9 @@ fun printGeneratedType(
|
||||
}
|
||||
appendLine("package $packageName")
|
||||
appendLine()
|
||||
importCollector.printAllImports(this)
|
||||
if (importCollector.printAllImports(this)) {
|
||||
appendLine()
|
||||
}
|
||||
append(stringBuilder)
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user