[IR] Automatically generate IrFactory interface
^KT-59308 Fixed
This commit is contained in:
committed by
Space Team
parent
c2a8d46867
commit
8aa0b6a562
+50
-39
@@ -1,16 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// This file was generated automatically. See compiler/ir/ir.tree/tree-generator/ReadMe.md.
|
||||
// DO NOT MODIFY IT MANUALLY.
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrAnonymousInitializerSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrLocalDelegatedPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
@@ -57,8 +74,8 @@ interface IrFactory {
|
||||
returnType: IrType,
|
||||
symbol: IrConstructorSymbol,
|
||||
isPrimary: Boolean,
|
||||
isExternal: Boolean,
|
||||
containerSource: DeserializedContainerSource? = null
|
||||
isExternal: Boolean = false,
|
||||
containerSource: DeserializedContainerSource? = null,
|
||||
): IrConstructor
|
||||
|
||||
fun createEnumEntry(
|
||||
@@ -85,29 +102,9 @@ interface IrFactory {
|
||||
type: IrType,
|
||||
isFinal: Boolean,
|
||||
isStatic: Boolean,
|
||||
isExternal: Boolean,
|
||||
isExternal: Boolean = false,
|
||||
): IrField
|
||||
|
||||
fun createSimpleFunction(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
name: Name,
|
||||
visibility: DescriptorVisibility,
|
||||
isInline: Boolean,
|
||||
isExpect: Boolean,
|
||||
returnType: IrType,
|
||||
modality: Modality,
|
||||
symbol: IrSimpleFunctionSymbol,
|
||||
isTailrec: Boolean,
|
||||
isSuspend: Boolean,
|
||||
isOperator: Boolean,
|
||||
isInfix: Boolean,
|
||||
isExternal: Boolean,
|
||||
containerSource: DeserializedContainerSource? = null,
|
||||
isFakeOverride: Boolean = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
): IrSimpleFunction
|
||||
|
||||
fun createFunctionWithLateBinding(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
@@ -148,10 +145,10 @@ interface IrFactory {
|
||||
isConst: Boolean,
|
||||
isLateinit: Boolean,
|
||||
isDelegated: Boolean,
|
||||
isExternal: Boolean,
|
||||
isExternal: Boolean = false,
|
||||
containerSource: DeserializedContainerSource? = null,
|
||||
isExpect: Boolean = false,
|
||||
isFakeOverride: Boolean = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
||||
isFakeOverride: Boolean = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
): IrProperty
|
||||
|
||||
fun createPropertyWithLateBinding(
|
||||
@@ -170,6 +167,26 @@ interface IrFactory {
|
||||
isFakeOverride: Boolean = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
): IrPropertyWithLateBinding
|
||||
|
||||
fun createSimpleFunction(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
name: Name,
|
||||
visibility: DescriptorVisibility,
|
||||
isInline: Boolean,
|
||||
isExpect: Boolean,
|
||||
returnType: IrType,
|
||||
modality: Modality,
|
||||
symbol: IrSimpleFunctionSymbol,
|
||||
isTailrec: Boolean,
|
||||
isSuspend: Boolean,
|
||||
isOperator: Boolean,
|
||||
isInfix: Boolean,
|
||||
isExternal: Boolean = false,
|
||||
containerSource: DeserializedContainerSource? = null,
|
||||
isFakeOverride: Boolean = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
): IrSimpleFunction
|
||||
|
||||
fun createTypeAlias(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
@@ -204,10 +221,10 @@ interface IrFactory {
|
||||
varargElementType: IrType?,
|
||||
isCrossinline: Boolean,
|
||||
isNoinline: Boolean,
|
||||
isHidden: Boolean
|
||||
isHidden: Boolean,
|
||||
): IrValueParameter
|
||||
|
||||
// Bodies
|
||||
fun createBlockBody(startOffset: Int, endOffset: Int): IrBlockBody
|
||||
|
||||
fun createExpressionBody(
|
||||
startOffset: Int,
|
||||
@@ -215,12 +232,6 @@ interface IrFactory {
|
||||
expression: IrExpression,
|
||||
): IrExpressionBody
|
||||
|
||||
fun createBlockBody(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
): IrBlockBody
|
||||
|
||||
|
||||
@Deprecated(
|
||||
message = "This method was moved to an extension." +
|
||||
" This variant of the method will be removed when the 2024.2 IntelliJ platform is shipped (see KTIJ-26314).",
|
||||
@@ -417,9 +428,9 @@ interface IrFactory {
|
||||
level = DeprecationLevel.HIDDEN,
|
||||
)
|
||||
fun createExpressionBody(expression: IrExpression): IrExpressionBody =
|
||||
createExpressionBody(
|
||||
expression,
|
||||
)
|
||||
createExpressionBody(
|
||||
expression,
|
||||
)
|
||||
|
||||
@Deprecated(
|
||||
message = "The method's parameters were reordered." +
|
||||
@@ -11,6 +11,7 @@ runtimeOnly.extendsFrom(compileOnly)
|
||||
dependencies {
|
||||
implementation(project(":generators"))
|
||||
implementation(project(":core:compiler.common"))
|
||||
implementation(project(":compiler:util"))
|
||||
implementation("com.squareup:kotlinpoet:1.11.0")
|
||||
|
||||
compileOnly(intellijCore())
|
||||
|
||||
+123
-30
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.generator.config.ListFieldConfig.Mutability.List
|
||||
import org.jetbrains.kotlin.ir.generator.config.ListFieldConfig.Mutability.Var
|
||||
import org.jetbrains.kotlin.ir.generator.config.SimpleFieldConfig
|
||||
import org.jetbrains.kotlin.ir.generator.model.Element.Companion.elementName2typeName
|
||||
import org.jetbrains.kotlin.ir.generator.print.IR_FACTORY_TYPE
|
||||
import org.jetbrains.kotlin.ir.generator.print.toPoet
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.ir.generator.util.Import
|
||||
@@ -33,13 +34,26 @@ import org.jetbrains.kotlin.types.Variance
|
||||
object IrTree : AbstractTreeBuilder() {
|
||||
private fun symbol(type: TypeRef, mutable: Boolean = false): SimpleFieldConfig =
|
||||
field("symbol", type, mutable = mutable)
|
||||
private fun descriptor(typeName: String): SimpleFieldConfig =
|
||||
field("descriptor", ClassRef<TypeParameterRef>(TypeKind.Interface, "org.jetbrains.kotlin.descriptors", typeName), mutable = false)
|
||||
|
||||
private fun descriptor(typeName: String, nullable: Boolean = false): SimpleFieldConfig =
|
||||
field(
|
||||
name = "descriptor",
|
||||
type = ClassRef<TypeParameterRef>(TypeKind.Interface, Packages.descriptors, typeName),
|
||||
mutable = false,
|
||||
nullable = nullable,
|
||||
) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
|
||||
private fun declarationWithLateBinding(symbol: ClassRef<*>, initializer: ElementConfig.() -> Unit) = element(Declaration) {
|
||||
initializer()
|
||||
|
||||
+field("isBound", boolean, mutable = false)
|
||||
fieldsToSkipInIrFactoryMethod.add("symbol")
|
||||
fieldsToSkipInIrFactoryMethod.add("containerSource")
|
||||
|
||||
+field("isBound", boolean, mutable = false) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
|
||||
val oldCallback = generationCallback
|
||||
generationCallback = {
|
||||
@@ -54,7 +68,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
}
|
||||
}
|
||||
|
||||
private val factory: SimpleFieldConfig = field("factory", type(Packages.declarations, "IrFactory"), mutable = false)
|
||||
private val factory: SimpleFieldConfig = field("factory", IR_FACTORY_TYPE, mutable = false) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
|
||||
override val rootElement: ElementConfig by element(Other, name = "element") {
|
||||
accept = true
|
||||
@@ -86,7 +102,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
|
||||
+descriptor("DeclarationDescriptor")
|
||||
+field("origin", type(Packages.declarations, "IrDeclarationOrigin"))
|
||||
+field("parent", declarationParent)
|
||||
+field("parent", declarationParent) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
+factory
|
||||
}
|
||||
val declarationBase: ElementConfig by element(Declaration) {
|
||||
@@ -112,13 +130,16 @@ object IrTree : AbstractTreeBuilder() {
|
||||
val possiblyExternalDeclaration: ElementConfig by element(Declaration) {
|
||||
parent(declarationWithName)
|
||||
|
||||
+field("isExternal", boolean)
|
||||
+field("isExternal", boolean) {
|
||||
useFieldInIrFactory(false)
|
||||
}
|
||||
}
|
||||
val symbolOwner: ElementConfig by element(Declaration) {
|
||||
+symbol(symbolType)
|
||||
}
|
||||
val metadataSourceOwner: ElementConfig by element(Declaration) {
|
||||
val metadataField = +field("metadata", type(Packages.declarations, "MetadataSource"), nullable = true) {
|
||||
skipInIrFactory()
|
||||
kdoc = """
|
||||
The arbitrary metadata associated with this IR node.
|
||||
|
||||
@@ -152,13 +173,17 @@ object IrTree : AbstractTreeBuilder() {
|
||||
parent(overridableMember)
|
||||
|
||||
+field("symbol", s, mutable = false)
|
||||
+field("isFakeOverride", boolean)
|
||||
+listField("overriddenSymbols", s, mutability = Var)
|
||||
+isFakeOverrideField()
|
||||
+listField("overriddenSymbols", s, mutability = Var) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
}
|
||||
val memberWithContainerSource: ElementConfig by element(Declaration) {
|
||||
parent(declarationWithName)
|
||||
|
||||
+field("containerSource", type<DeserializedContainerSource>(), nullable = true, mutable = false)
|
||||
+field("containerSource", type<DeserializedContainerSource>(), nullable = true, mutable = false) {
|
||||
useFieldInIrFactory(defaultValue = code("null"))
|
||||
}
|
||||
}
|
||||
val valueDeclaration: ElementConfig by element(Declaration) {
|
||||
parent(declarationWithName)
|
||||
@@ -229,21 +254,40 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+symbol(classSymbolType)
|
||||
+field("kind", type<ClassKind>())
|
||||
+field("modality", type<Modality>())
|
||||
+field("isCompanion", boolean)
|
||||
+field("isInner", boolean)
|
||||
+field("isData", boolean)
|
||||
+field("isValue", boolean)
|
||||
+field("isExpect", boolean)
|
||||
+field("isFun", boolean)
|
||||
+field("source", type<SourceElement>(), mutable = false)
|
||||
+listField("superTypes", irTypeType, mutability = Var)
|
||||
+field("isCompanion", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+field("isInner", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+field("isData", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+field("isValue", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+field("isExpect", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+field("isFun", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+field("source", type<SourceElement>(), mutable = false) {
|
||||
useFieldInIrFactory(defaultValue = code("%T.NO_SOURCE", SourceElement::class))
|
||||
}
|
||||
+listField("superTypes", irTypeType, mutability = Var) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
+field("thisReceiver", valueParameter, nullable = true, isChild = true)
|
||||
+field(
|
||||
"valueClassRepresentation",
|
||||
type<ValueClassRepresentation<*>>().withArgs(type(Packages.types, "IrSimpleType")),
|
||||
nullable = true,
|
||||
)
|
||||
) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
+listField("sealedSubclasses", classSymbolType, mutability = Var) {
|
||||
skipInIrFactory()
|
||||
kdoc = """
|
||||
If this is a sealed class or interface, this list contains symbols of all its immediate subclasses.
|
||||
Otherwise, this is an empty list.
|
||||
@@ -264,8 +308,13 @@ object IrTree : AbstractTreeBuilder() {
|
||||
idempotence invariant and can contain a chain of declarations.
|
||||
""".trimIndent()
|
||||
|
||||
+field("attributeOwnerId", attributeContainer)
|
||||
+field("originalBeforeInline", attributeContainer, nullable = true) // null <=> this element wasn't inlined
|
||||
+field("attributeOwnerId", attributeContainer) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
// null <=> this element wasn't inlined
|
||||
+field("originalBeforeInline", attributeContainer, nullable = true) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
}
|
||||
val anonymousInitializer: ElementConfig by element(Declaration) {
|
||||
visitorParent = declarationBase
|
||||
@@ -274,7 +323,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
|
||||
+descriptor("ClassDescriptor") // TODO special descriptor for anonymous initializer blocks
|
||||
+symbol(anonymousInitializerSymbolType)
|
||||
+field("isStatic", boolean)
|
||||
+field("isStatic", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+field("body", blockBody, isChild = true)
|
||||
}
|
||||
val declarationContainer: ElementConfig by element(Declaration) {
|
||||
@@ -304,7 +355,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("variance", type<Variance>())
|
||||
+field("index", int)
|
||||
+field("isReified", boolean)
|
||||
+listField("superTypes", irTypeType, mutability = Var)
|
||||
+listField("superTypes", irTypeType, mutability = Var) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
}
|
||||
val returnTarget: ElementConfig by element(Declaration) {
|
||||
parent(symbolOwner)
|
||||
@@ -335,7 +388,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("extensionReceiverParameter", valueParameter, nullable = true, isChild = true)
|
||||
+listField("valueParameters", valueParameter, mutability = Var, isChild = true)
|
||||
// The first `contextReceiverParametersCount` value parameters are context receivers.
|
||||
+field("contextReceiverParametersCount", int)
|
||||
+field("contextReceiverParametersCount", int) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
+field("body", body, nullable = true, isChild = true)
|
||||
}
|
||||
val constructor: ElementConfig by element(Declaration) {
|
||||
@@ -363,8 +418,17 @@ object IrTree : AbstractTreeBuilder() {
|
||||
|
||||
parent(declarationBase)
|
||||
|
||||
additionalIrFactoryMethodParameters.add(
|
||||
descriptor("DeclarationDescriptor", nullable = true).apply {
|
||||
useFieldInIrFactory(defaultValue = code("null"))
|
||||
}
|
||||
)
|
||||
|
||||
fieldsToSkipInIrFactoryMethod.add("origin")
|
||||
|
||||
+field("symbol", symbolType, mutable = false) {
|
||||
baseGetter = code("error(\"Should never be called\")")
|
||||
skipInIrFactory()
|
||||
}
|
||||
}
|
||||
val functionWithLateBinding: ElementConfig by declarationWithLateBinding(simpleFunctionSymbolType) {
|
||||
@@ -388,7 +452,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("isFinal", boolean)
|
||||
+field("isStatic", boolean)
|
||||
+field("initializer", expressionBody, nullable = true, isChild = true)
|
||||
+field("correspondingPropertySymbol", propertySymbolType, nullable = true)
|
||||
+field("correspondingPropertySymbol", propertySymbolType, nullable = true) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
}
|
||||
val localDelegatedProperty: ElementConfig by element(Declaration) {
|
||||
visitorParent = declarationBase
|
||||
@@ -410,6 +476,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
visitorParent = rootElement
|
||||
transform = true
|
||||
transformByChildren = true
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
+descriptor("ModuleDescriptor")
|
||||
+field("name", type<Name>(), mutable = false)
|
||||
@@ -440,17 +507,29 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+field("isConst", boolean)
|
||||
+field("isLateinit", boolean)
|
||||
+field("isDelegated", boolean)
|
||||
+field("isExpect", boolean)
|
||||
+field("isFakeOverride", boolean)
|
||||
+field("isExpect", boolean) {
|
||||
useFieldInIrFactory(defaultValue = false)
|
||||
}
|
||||
+isFakeOverrideField()
|
||||
+field("backingField", field, nullable = true, isChild = true)
|
||||
+field("getter", simpleFunction, nullable = true, isChild = true)
|
||||
+field("setter", simpleFunction, nullable = true, isChild = true)
|
||||
}
|
||||
|
||||
private fun isFakeOverrideField() = field("isFakeOverride", boolean) {
|
||||
useFieldInIrFactory(
|
||||
defaultValue = code(
|
||||
"origin == %T.FAKE_OVERRIDE",
|
||||
type(Packages.declarations, "IrDeclarationOrigin").toPoet(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
//TODO: make IrScript as IrPackageFragment, because script is used as a file, not as a class
|
||||
//NOTE: declarations and statements stored separately
|
||||
val script: ElementConfig by element(Declaration) {
|
||||
visitorParent = declarationBase
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
parent(declarationBase)
|
||||
parent(declarationWithName)
|
||||
@@ -484,10 +563,12 @@ object IrTree : AbstractTreeBuilder() {
|
||||
+symbol(simpleFunctionSymbolType)
|
||||
+field("isTailrec", boolean)
|
||||
+field("isSuspend", boolean)
|
||||
+field("isFakeOverride", boolean)
|
||||
+isFakeOverrideField()
|
||||
+field("isOperator", boolean)
|
||||
+field("isInfix", boolean)
|
||||
+field("correspondingPropertySymbol", propertySymbolType, nullable = true)
|
||||
+field("correspondingPropertySymbol", propertySymbolType, nullable = true) {
|
||||
skipInIrFactory()
|
||||
}
|
||||
}
|
||||
val typeAlias: ElementConfig by element(Declaration) {
|
||||
visitorParent = declarationBase
|
||||
@@ -505,6 +586,8 @@ object IrTree : AbstractTreeBuilder() {
|
||||
val variable: ElementConfig by element(Declaration) {
|
||||
visitorParent = declarationBase
|
||||
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
parent(declarationBase)
|
||||
parent(valueDeclaration)
|
||||
|
||||
@@ -541,6 +624,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
val externalPackageFragment: ElementConfig by element(Declaration) {
|
||||
visitorParent = packageFragment
|
||||
transformByChildren = true
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
parent(packageFragment)
|
||||
|
||||
@@ -551,6 +635,7 @@ object IrTree : AbstractTreeBuilder() {
|
||||
transform = true
|
||||
transformByChildren = true
|
||||
visitorParent = packageFragment
|
||||
generateIrFactoryMethod = false
|
||||
|
||||
parent(packageFragment)
|
||||
parent(mutableAnnotationContainerType)
|
||||
@@ -572,9 +657,11 @@ object IrTree : AbstractTreeBuilder() {
|
||||
|
||||
+field("attributeOwnerId", attributeContainer) {
|
||||
baseDefaultValue = code("this")
|
||||
skipInIrFactory()
|
||||
}
|
||||
+field("originalBeforeInline", attributeContainer, nullable = true) {
|
||||
baseDefaultValue = code("null")
|
||||
skipInIrFactory()
|
||||
}
|
||||
+field("type", irTypeType)
|
||||
}
|
||||
@@ -594,15 +681,19 @@ object IrTree : AbstractTreeBuilder() {
|
||||
transform = true
|
||||
visitorParent = body
|
||||
visitorParam = "body"
|
||||
generateIrFactoryMethod = true
|
||||
|
||||
parent(body)
|
||||
|
||||
+factory
|
||||
+field("expression", expression, isChild = true)
|
||||
+field("expression", expression, isChild = true) {
|
||||
useFieldInIrFactory()
|
||||
}
|
||||
}
|
||||
val blockBody: ElementConfig by element(Expression) {
|
||||
visitorParent = body
|
||||
visitorParam = "body"
|
||||
generateIrFactoryMethod = true
|
||||
|
||||
parent(body)
|
||||
parent(statementContainer)
|
||||
@@ -706,7 +797,9 @@ object IrTree : AbstractTreeBuilder() {
|
||||
parent(functionAccessExpression)
|
||||
|
||||
+symbol(constructorSymbolType, mutable = true)
|
||||
+field("source", type<SourceElement>())
|
||||
+field("source", type<SourceElement>()) {
|
||||
useFieldInIrFactory(defaultValue = code("%T.NO_SOURCE", SourceElement::class))
|
||||
}
|
||||
+field("constructorTypeArgumentsCount", int)
|
||||
}
|
||||
val getSingletonValue: ElementConfig by element(Expression) {
|
||||
|
||||
@@ -30,6 +30,7 @@ fun main(args: Array<String>) {
|
||||
yield(printTransformer(generationPath, model))
|
||||
yield(printTypeVisitor(generationPath, model))
|
||||
// IrElementTransformerVoid is too random to autogenerate
|
||||
yield(printFactory(generationPath, model))
|
||||
}.map {
|
||||
GeneratorsFileUtil.writeFileIfContentChanged(it.file, it.newText, logNotChanged = false)
|
||||
it.file
|
||||
|
||||
+26
@@ -37,6 +37,10 @@ class ElementConfig(
|
||||
|
||||
var ownsChildren = true // If false, acceptChildren/transformChildren will NOT be generated.
|
||||
|
||||
var generateIrFactoryMethod = category == Category.Declaration
|
||||
val additionalIrFactoryMethodParameters = mutableListOf<FieldConfig>()
|
||||
val fieldsToSkipInIrFactoryMethod = hashSetOf<String>()
|
||||
|
||||
/**
|
||||
* Set this to `true` if the element should be a leaf semantically, but technically it's not.
|
||||
*
|
||||
@@ -91,6 +95,13 @@ class ElementConfigRef(
|
||||
override fun toString() = element.name
|
||||
}
|
||||
|
||||
sealed class UseFieldAsParameterInIrFactoryStrategy {
|
||||
|
||||
data object No : UseFieldAsParameterInIrFactoryStrategy()
|
||||
|
||||
data class Yes(val defaultValue: CodeBlock?) : UseFieldAsParameterInIrFactoryStrategy()
|
||||
}
|
||||
|
||||
sealed class FieldConfig(
|
||||
val name: String,
|
||||
val isChild: Boolean,
|
||||
@@ -100,6 +111,21 @@ sealed class FieldConfig(
|
||||
var printProperty = true
|
||||
var strictCastInTransformChildren = false
|
||||
|
||||
internal var useFieldInIrFactoryStrategy: UseFieldAsParameterInIrFactoryStrategy =
|
||||
if (isChild) UseFieldAsParameterInIrFactoryStrategy.No else UseFieldAsParameterInIrFactoryStrategy.Yes(null)
|
||||
|
||||
fun useFieldInIrFactory(defaultValue: CodeBlock? = null) {
|
||||
useFieldInIrFactoryStrategy = UseFieldAsParameterInIrFactoryStrategy.Yes(defaultValue)
|
||||
}
|
||||
|
||||
fun useFieldInIrFactory(defaultValue: Boolean) {
|
||||
useFieldInIrFactoryStrategy = UseFieldAsParameterInIrFactoryStrategy.Yes(code("%L", defaultValue))
|
||||
}
|
||||
|
||||
fun skipInIrFactory() {
|
||||
useFieldInIrFactoryStrategy = UseFieldAsParameterInIrFactoryStrategy.No
|
||||
}
|
||||
|
||||
var kdoc: String? = null
|
||||
|
||||
var generationCallback: (PropertySpec.Builder.() -> Unit)? = null
|
||||
|
||||
+34
-6
@@ -9,6 +9,7 @@ import com.squareup.kotlinpoet.CodeBlock
|
||||
import org.jetbrains.kotlin.ir.generator.config.ElementConfig
|
||||
import org.jetbrains.kotlin.ir.generator.config.FieldConfig
|
||||
import org.jetbrains.kotlin.ir.generator.util.*
|
||||
import org.jetbrains.kotlin.utils.topologicalSort
|
||||
|
||||
class Element(
|
||||
config: ElementConfig,
|
||||
@@ -16,6 +17,7 @@ class Element(
|
||||
val packageName: String,
|
||||
val params: List<TypeVariable>,
|
||||
val fields: MutableList<Field>,
|
||||
val additionalFactoryMethodParameters: MutableList<Field>,
|
||||
) {
|
||||
var elementParents: List<ElementRef> = emptyList()
|
||||
var otherParents: List<ClassRef<*>> = emptyList()
|
||||
@@ -38,6 +40,8 @@ class Element(
|
||||
val transform = config.transform
|
||||
val transformByChildren = config.transformByChildren
|
||||
val ownsChildren = config.ownsChildren
|
||||
val generateIrFactoryMethod = config.generateIrFactoryMethod
|
||||
val fieldsToSkipInIrFactoryMethod = config.fieldsToSkipInIrFactoryMethod
|
||||
|
||||
val generationCallback = config.generationCallback
|
||||
val suppressPrint = config.suppressPrint
|
||||
@@ -59,6 +63,29 @@ class Element(
|
||||
companion object {
|
||||
fun elementName2typeName(name: String) = "Ir" + name.replaceFirstChar(Char::uppercaseChar)
|
||||
}
|
||||
|
||||
fun elementParentsRecursively(): List<ElementRef> {
|
||||
val linkedSet = buildSet {
|
||||
fun recurse(element: Element) {
|
||||
addAll(element.elementParents)
|
||||
element.elementParents.forEach { recurse(it.element) }
|
||||
}
|
||||
recurse(this@Element)
|
||||
}
|
||||
return topologicalSort(linkedSet) {
|
||||
element.elementParents
|
||||
}
|
||||
}
|
||||
|
||||
fun allFieldsRecursively(): List<Field> {
|
||||
val parentFields = elementParentsRecursively()
|
||||
.reversed()
|
||||
.flatMap { it.element.fields }
|
||||
return (parentFields + fields)
|
||||
.asReversed()
|
||||
.distinctBy { it.name }
|
||||
.asReversed()
|
||||
}
|
||||
}
|
||||
|
||||
data class ElementRef(
|
||||
@@ -72,7 +99,7 @@ data class ElementRef(
|
||||
}
|
||||
|
||||
sealed class Field(
|
||||
config: FieldConfig?,
|
||||
config: FieldConfig,
|
||||
val name: String,
|
||||
val nullable: Boolean,
|
||||
val mutable: Boolean,
|
||||
@@ -85,16 +112,17 @@ sealed class Field(
|
||||
var needsDescriptorApiAnnotation = false
|
||||
abstract val transformable: Boolean
|
||||
|
||||
val kdoc = config?.kdoc
|
||||
val useInIrFactoryStrategy = config.useFieldInIrFactoryStrategy
|
||||
val kdoc = config.kdoc
|
||||
|
||||
val printProperty = config?.printProperty ?: true
|
||||
val generationCallback = config?.generationCallback
|
||||
val printProperty = config.printProperty
|
||||
val generationCallback = config.generationCallback
|
||||
|
||||
override fun toString() = "$name: $type"
|
||||
}
|
||||
|
||||
class SingleField(
|
||||
config: FieldConfig?,
|
||||
config: FieldConfig,
|
||||
name: String,
|
||||
override var type: TypeRef,
|
||||
nullable: Boolean,
|
||||
@@ -108,7 +136,7 @@ class SingleField(
|
||||
}
|
||||
|
||||
class ListField(
|
||||
config: FieldConfig?,
|
||||
config: FieldConfig,
|
||||
name: String,
|
||||
var elementType: TypeRef,
|
||||
private val listType: ClassRef<PositionTypeParameterRef>,
|
||||
|
||||
+47
-49
@@ -20,56 +20,16 @@ fun config2model(config: Config): Model {
|
||||
val ec2el = mutableMapOf<ElementConfig, Element>()
|
||||
|
||||
val elements = config.elements.map { ec ->
|
||||
val fields = ec.fields.mapTo(mutableListOf()) { fc ->
|
||||
val field = when (fc) {
|
||||
is SimpleFieldConfig -> SingleField(
|
||||
fc,
|
||||
fc.name,
|
||||
fc.type ?: InferredOverriddenType,
|
||||
fc.nullable,
|
||||
fc.mutable,
|
||||
fc.isChild,
|
||||
fc.baseDefaultValue,
|
||||
fc.baseGetter
|
||||
)
|
||||
is ListFieldConfig -> {
|
||||
val listType = when (fc.mutability) {
|
||||
ListFieldConfig.Mutability.List -> type(
|
||||
"kotlin.collections",
|
||||
"MutableList"
|
||||
)
|
||||
ListFieldConfig.Mutability.Array -> type(
|
||||
"kotlin.",
|
||||
"Array"
|
||||
)
|
||||
else -> type("kotlin.collections", "List")
|
||||
}
|
||||
ListField(
|
||||
fc,
|
||||
fc.name,
|
||||
fc.elementType ?: InferredOverriddenType,
|
||||
listType,
|
||||
fc.nullable,
|
||||
fc.mutability == ListFieldConfig.Mutability.Var,
|
||||
fc.isChild,
|
||||
fc.mutability != ListFieldConfig.Mutability.Immutable,
|
||||
fc.baseDefaultValue,
|
||||
fc.baseGetter
|
||||
)
|
||||
}
|
||||
}
|
||||
field
|
||||
Element(
|
||||
config = ec,
|
||||
name = ec.name,
|
||||
packageName = ec.category.packageName,
|
||||
params = ec.params,
|
||||
fields = ec.fields.mapTo(mutableListOf(), ::transformFieldConfig),
|
||||
additionalFactoryMethodParameters = ec.additionalIrFactoryMethodParameters.mapTo(mutableListOf(), ::transformFieldConfig)
|
||||
).also {
|
||||
ec2el[ec.element] = it
|
||||
}
|
||||
|
||||
val element = Element(
|
||||
ec,
|
||||
ec.name,
|
||||
ec.category.packageName,
|
||||
ec.params,
|
||||
fields
|
||||
)
|
||||
ec2el[ec.element] = element
|
||||
element
|
||||
}
|
||||
|
||||
val rootElement = replaceElementRefs(config, ec2el)
|
||||
@@ -83,6 +43,44 @@ fun config2model(config: Config): Model {
|
||||
return Model(elements, rootElement)
|
||||
}
|
||||
|
||||
private fun transformFieldConfig(fc: FieldConfig): Field = when (fc) {
|
||||
is SimpleFieldConfig -> SingleField(
|
||||
fc,
|
||||
fc.name,
|
||||
fc.type ?: InferredOverriddenType,
|
||||
fc.nullable,
|
||||
fc.mutable,
|
||||
fc.isChild,
|
||||
fc.baseDefaultValue,
|
||||
fc.baseGetter,
|
||||
)
|
||||
is ListFieldConfig -> {
|
||||
val listType = when (fc.mutability) {
|
||||
ListFieldConfig.Mutability.List -> type(
|
||||
"kotlin.collections",
|
||||
"MutableList",
|
||||
)
|
||||
ListFieldConfig.Mutability.Array -> type(
|
||||
"kotlin.",
|
||||
"Array",
|
||||
)
|
||||
else -> type("kotlin.collections", "List")
|
||||
}
|
||||
ListField(
|
||||
fc,
|
||||
fc.name,
|
||||
fc.elementType ?: InferredOverriddenType,
|
||||
listType,
|
||||
fc.nullable,
|
||||
fc.mutability == ListFieldConfig.Mutability.Var,
|
||||
fc.isChild,
|
||||
fc.mutability != ListFieldConfig.Mutability.Immutable,
|
||||
fc.baseDefaultValue,
|
||||
fc.baseGetter,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(UnsafeCastFunction::class)
|
||||
private fun replaceElementRefs(config: Config, mapping: Map<ElementConfig, Element>): Element {
|
||||
val visited = mutableMapOf<TypeRef, TypeRef>()
|
||||
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* 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.ir.generator.print
|
||||
|
||||
import com.squareup.kotlinpoet.*
|
||||
import org.jetbrains.kotlin.ir.generator.IrTree
|
||||
import org.jetbrains.kotlin.ir.generator.Packages
|
||||
import org.jetbrains.kotlin.ir.generator.config.UseFieldAsParameterInIrFactoryStrategy
|
||||
import org.jetbrains.kotlin.ir.generator.model.Model
|
||||
import org.jetbrains.kotlin.ir.generator.util.GeneratedFile
|
||||
import org.jetbrains.kotlin.ir.generator.util.parameterizedByIfAny
|
||||
import org.jetbrains.kotlin.ir.generator.util.tryParameterizedBy
|
||||
import org.jetbrains.kotlin.ir.generator.util.type
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
||||
import java.io.File
|
||||
|
||||
internal val IR_FACTORY_TYPE = type(Packages.declarations, "IrFactory")
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
internal fun printFactory(generationPath: File, model: Model): GeneratedFile {
|
||||
val visitorType = TypeSpec.interfaceBuilder(IR_FACTORY_TYPE.toPoet() as ClassName).apply {
|
||||
addProperty("stageController", ClassName(Packages.declarations, "StageController"))
|
||||
model.elements
|
||||
.filter { it.isLeaf && it.generateIrFactoryMethod }
|
||||
.sortedWith(compareBy({ it.packageName }, { it.name }))
|
||||
.forEach { element ->
|
||||
val typeParams = element.params.map { it.toPoet() }
|
||||
addFunction(
|
||||
FunSpec.builder("create${element.name.capitalizeAsciiOnly()}")
|
||||
.addTypeVariables(typeParams)
|
||||
.apply {
|
||||
val fields = (element.allFieldsRecursively() + element.additionalFactoryMethodParameters)
|
||||
.filterNot { it.name in element.fieldsToSkipInIrFactoryMethod }
|
||||
.mapNotNull { field ->
|
||||
(field.useInIrFactoryStrategy as? UseFieldAsParameterInIrFactoryStrategy.Yes)?.let {
|
||||
field to it.defaultValue
|
||||
}
|
||||
}
|
||||
.sortedBy { (_, defaultValue) -> defaultValue != null } // All parameters with default values must go last
|
||||
fields.forEach { (field, defaultValue) ->
|
||||
addParameter(
|
||||
ParameterSpec.builder(field.name, field.type.toPoet().copy(nullable = field.nullable))
|
||||
.defaultValue(defaultValue)
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
}
|
||||
.returns(element.toPoet().parameterizedByIfAny(typeParams))
|
||||
.addModifiers(KModifier.ABSTRACT)
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
|
||||
fun replacement(name: String) = funSpecs.find { it.name == name } ?: error("Method '$name' not found")
|
||||
|
||||
addDeprecatedFunction(
|
||||
replacement("createBlockBody")
|
||||
.toBuilder()
|
||||
.addParameter(
|
||||
"initializer",
|
||||
LambdaTypeName.get(receiver = IrTree.blockBody.toPoet(), returnType = UNIT)
|
||||
)
|
||||
.build()
|
||||
) {
|
||||
deprecationMessage = "This method was moved to an extension."
|
||||
additionalImports.add("${Packages.declarations}.$oldName")
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("initializer")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(
|
||||
replacement("createBlockBody")
|
||||
.toBuilder()
|
||||
.addParameter(
|
||||
"statements",
|
||||
LIST.tryParameterizedBy(IrTree.statement.toPoet())
|
||||
)
|
||||
.build()
|
||||
) {
|
||||
deprecationMessage = "This method was moved to an extension."
|
||||
additionalImports.add("${Packages.declarations}.$oldName")
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("statements")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createClass")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("kind")
|
||||
parameter("visibility")
|
||||
parameter("modality")
|
||||
parameter("isCompanion")
|
||||
parameter("isInner")
|
||||
parameter("isData")
|
||||
parameter("isExternal")
|
||||
parameter("isValue")
|
||||
parameter("isExpect")
|
||||
parameter("isFun")
|
||||
parameter("source")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createConstructor")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("visibility")
|
||||
parameter("returnType")
|
||||
parameter("isInline")
|
||||
parameter("isExternal", removeDefaultValue = true)
|
||||
parameter("isPrimary")
|
||||
parameter("isExpect")
|
||||
parameter("containerSource")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createEnumEntry")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createExpressionBody")) {
|
||||
deprecationMessage = "This method was moved to an extension."
|
||||
additionalImports.add("${Packages.declarations}.$oldName")
|
||||
parameter("expression")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createField")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("type")
|
||||
parameter("visibility")
|
||||
parameter("isFinal")
|
||||
parameter("isExternal", removeDefaultValue = true)
|
||||
parameter("isStatic")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createFunctionWithLateBinding")) {
|
||||
returnType = IrTree.simpleFunction.toPoet()
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("name")
|
||||
parameter("visibility")
|
||||
parameter("modality")
|
||||
parameter("returnType")
|
||||
parameter("isInline")
|
||||
parameter("isExternal", removeDefaultValue = true)
|
||||
parameter("isTailrec")
|
||||
parameter("isSuspend")
|
||||
parameter("isOperator")
|
||||
parameter("isInfix")
|
||||
parameter("isExpect")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createLocalDelegatedProperty")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("type")
|
||||
parameter("isVar")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createProperty")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("visibility")
|
||||
parameter("modality")
|
||||
parameter("isVar")
|
||||
parameter("isConst")
|
||||
parameter("isLateinit")
|
||||
parameter("isDelegated")
|
||||
parameter("isExternal", removeDefaultValue = true)
|
||||
parameter("isExpect")
|
||||
parameter("isFakeOverride")
|
||||
parameter("containerSource")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createPropertyWithLateBinding")) {
|
||||
returnType = IrTree.property.toPoet()
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("name")
|
||||
parameter("visibility")
|
||||
parameter("modality")
|
||||
parameter("isVar")
|
||||
parameter("isConst")
|
||||
parameter("isLateinit")
|
||||
parameter("isDelegated")
|
||||
parameter("isExternal", removeDefaultValue = true)
|
||||
parameter("isExpect", removeDefaultValue = true)
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createSimpleFunction"),) {
|
||||
oldName = "createFunction"
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("visibility")
|
||||
parameter("modality")
|
||||
parameter("returnType")
|
||||
parameter("isInline")
|
||||
parameter("isExternal", removeDefaultValue = true)
|
||||
parameter("isTailrec")
|
||||
parameter("isSuspend")
|
||||
parameter("isOperator")
|
||||
parameter("isInfix")
|
||||
parameter("isExpect")
|
||||
parameter("isFakeOverride")
|
||||
parameter("containerSource")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createTypeAlias")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("visibility")
|
||||
parameter("expandedType")
|
||||
parameter("isActual")
|
||||
parameter("origin")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createTypeParameter")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("index")
|
||||
parameter("isReified")
|
||||
parameter("variance")
|
||||
}
|
||||
|
||||
addDeprecatedFunction(replacement("createValueParameter")) {
|
||||
parameter("startOffset")
|
||||
parameter("endOffset")
|
||||
parameter("origin")
|
||||
parameter("symbol")
|
||||
parameter("name")
|
||||
parameter("index")
|
||||
parameter("type")
|
||||
parameter("varargElementType")
|
||||
parameter("isCrossinline")
|
||||
parameter("isNoinline")
|
||||
parameter("isHidden")
|
||||
parameter("isAssignable")
|
||||
}
|
||||
}.build()
|
||||
|
||||
return printTypeCommon(generationPath, IR_FACTORY_TYPE.packageName, visitorType)
|
||||
}
|
||||
|
||||
private class DeprecatedFunctionBuilder(private val replacement: FunSpec) {
|
||||
|
||||
val deprecatedFunctionParameterSpecs = mutableListOf<ParameterSpec>()
|
||||
|
||||
var oldName = replacement.name
|
||||
|
||||
var returnType = replacement.returnType
|
||||
|
||||
var deprecationMessage: String? = null
|
||||
|
||||
val additionalImports = mutableListOf<String>()
|
||||
|
||||
fun parameter(name: String, removeDefaultValue: Boolean = false) {
|
||||
val replacementParameter =
|
||||
replacement.parameters.find { it.name == name } ?: error("Parameter '$name' not found in $replacement")
|
||||
deprecatedFunctionParameterSpecs.add(
|
||||
replacementParameter
|
||||
.toBuilder()
|
||||
.applyIf(removeDefaultValue) {
|
||||
defaultValue(null)
|
||||
}
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun TypeSpec.Builder.addDeprecatedFunction(
|
||||
replacement: FunSpec,
|
||||
build: DeprecatedFunctionBuilder.() -> Unit
|
||||
): TypeSpec.Builder {
|
||||
|
||||
val builder = DeprecatedFunctionBuilder(replacement)
|
||||
builder.build()
|
||||
|
||||
val message = builder.deprecationMessage ?: if (builder.oldName != replacement.name) {
|
||||
"The method has been renamed, and its parameters were reordered."
|
||||
} else {
|
||||
"The method's parameters were reordered."
|
||||
}
|
||||
|
||||
fun CodeBlock.Builder.addCallToNewFunction(explicitParameterName: Boolean) =
|
||||
add("%N(\n", replacement)
|
||||
.apply {
|
||||
for (parameter in replacement.parameters) {
|
||||
if (builder.deprecatedFunctionParameterSpecs.any { it.name == parameter.name }) {
|
||||
indent()
|
||||
add(if (explicitParameterName) "%1N = %1N,\n" else "%N,\n", parameter)
|
||||
unindent()
|
||||
}
|
||||
}
|
||||
}
|
||||
.add(")")
|
||||
|
||||
return addFunction(
|
||||
FunSpec.builder(builder.oldName)
|
||||
.addTypeVariables(replacement.typeVariables)
|
||||
.addCode(CodeBlock.builder().add("return ").addCallToNewFunction(explicitParameterName = false).build())
|
||||
.addAnnotation(
|
||||
AnnotationSpec.builder(Deprecated::class)
|
||||
.addMember(
|
||||
"message = %S + %S",
|
||||
message,
|
||||
" This variant of the method will be removed when the 2024.2 IntelliJ platform is shipped (see KTIJ-26314).",
|
||||
)
|
||||
.addMember(
|
||||
CodeBlock.builder()
|
||||
.add("replaceWith = ReplaceWith(\n")
|
||||
.indent()
|
||||
.add("\"\"\"")
|
||||
.addCallToNewFunction(explicitParameterName = true)
|
||||
.unindent()
|
||||
.add("\"\"\",\n")
|
||||
.apply {
|
||||
for (additionalImport in builder.additionalImports) {
|
||||
indent()
|
||||
add("%S,\n", additionalImport)
|
||||
unindent()
|
||||
}
|
||||
}
|
||||
.add(")")
|
||||
.build()
|
||||
)
|
||||
.addMember("level = %T.%N", DeprecationLevel::class, DeprecationLevel.HIDDEN.name)
|
||||
.build(),
|
||||
)
|
||||
.addParameters(builder.deprecatedFunctionParameterSpecs)
|
||||
.apply {
|
||||
builder.returnType?.let { returns(it) }
|
||||
}
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user