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