From a84277782ae3359ad3b2e1049a17888e0de64bc3 Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Mon, 16 Oct 2023 12:34:08 +0300 Subject: [PATCH] [IR generator] Don't use kotlinpoet for auto-generating IrFactory KT-61970 --- .../kotlin/ir/declarations/IrFactory.kt | 23 +- .../kotlin/ir/generator/CommonTypes.kt | 2 + .../jetbrains/kotlin/ir/generator/IrTree.kt | 38 ++- .../kotlin/ir/generator/config/ConfigModel.kt | 35 ++- .../kotlin/ir/generator/print/Factory.kt | 224 +++++++++--------- .../kotlin/generators/tree/TypeRef.kt | 33 ++- 6 files changed, 190 insertions(+), 165 deletions(-) diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFactory.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFactory.kt index 720e1d6bdea..1ba5086b719 100644 --- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFactory.kt +++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrFactory.kt @@ -8,26 +8,12 @@ package org.jetbrains.kotlin.ir.declarations -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.descriptors.* 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.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.symbols.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource @@ -362,10 +348,7 @@ interface IrFactory { " This variant of the method will be removed when the 2024.2 IntelliJ platform is shipped (see KTIJ-26314).", level = DeprecationLevel.HIDDEN, ) - fun createExpressionBody(expression: IrExpression): IrExpressionBody = - createExpressionBody( - expression, - ) + fun createExpressionBody(expression: IrExpression): IrExpressionBody = createExpressionBody(expression) @Deprecated( message = "The method's parameters were reordered." + diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/CommonTypes.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/CommonTypes.kt index b569d2b7335..312d216319d 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/CommonTypes.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/CommonTypes.kt @@ -32,6 +32,8 @@ val elementTransformerType = type(visitors, "IrElementTransformer") val typeTransformerType = type(visitors, "IrTypeTransformer") val mutableAnnotationContainerType = type(declarations, "IrMutableAnnotationContainer") val irTypeType = type(types, "IrType") +val irFactoryType = type(declarations, "IrFactory") +val stageControllerType = type(declarations, "StageController", TypeKind.Class) val symbolType = type(symbols, "IrSymbol") val packageFragmentSymbolType = type(symbols, "IrPackageFragmentSymbol") diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt index 6f9d7d73490..d8642d03f3a 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt @@ -19,7 +19,6 @@ 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 @@ -69,7 +68,7 @@ object IrTree : AbstractTreeBuilder() { } } - private val factory: SimpleFieldConfig = field("factory", IR_FACTORY_TYPE, mutable = false) { + private val factory: SimpleFieldConfig = field("factory", irFactoryType, mutable = false) { skipInIrFactory() } @@ -132,7 +131,7 @@ object IrTree : AbstractTreeBuilder() { parent(declarationWithName) +field("isExternal", boolean) { - useFieldInIrFactory(false) + useFieldInIrFactory(defaultValue = "false") } } val symbolOwner: ElementConfig by element(Declaration) { @@ -183,7 +182,7 @@ object IrTree : AbstractTreeBuilder() { parent(declarationWithName) +field("containerSource", type(), nullable = true, mutable = false) { - useFieldInIrFactory(defaultValue = code("null")) + useFieldInIrFactory(defaultValue = "null") } } val valueDeclaration: ElementConfig by element(Declaration) { @@ -256,25 +255,25 @@ object IrTree : AbstractTreeBuilder() { +field("kind", type()) +field("modality", type()) +field("isCompanion", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +field("isInner", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +field("isData", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +field("isValue", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +field("isExpect", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +field("isFun", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +field("hasEnumEntries", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") kDoc = """ Returns true iff this is a class loaded from dependencies which has the `HAS_ENUM_ENTRIES` metadata flag set. This flag is useful for Kotlin/JVM to determine whether an enum class from dependency actually has the `entries` property @@ -283,7 +282,7 @@ object IrTree : AbstractTreeBuilder() { """.trimIndent() } +field("source", type(), mutable = false) { - useFieldInIrFactory(defaultValue = code("%T.NO_SOURCE", SourceElement::class)) + useFieldInIrFactory(defaultValue = "SourceElement.NO_SOURCE") } +listField("superTypes", irTypeType, mutability = Var) { skipInIrFactory() @@ -334,7 +333,7 @@ object IrTree : AbstractTreeBuilder() { +descriptor("ClassDescriptor") // TODO special descriptor for anonymous initializer blocks +symbol(anonymousInitializerSymbolType) +field("isStatic", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +field("body", blockBody, isChild = true) } @@ -440,7 +439,7 @@ object IrTree : AbstractTreeBuilder() { additionalIrFactoryMethodParameters.add( descriptor("DeclarationDescriptor", nullable = true).apply { - useFieldInIrFactory(defaultValue = code("null")) + useFieldInIrFactory(defaultValue = "null") } ) @@ -528,7 +527,7 @@ object IrTree : AbstractTreeBuilder() { +field("isLateinit", boolean) +field("isDelegated", boolean) +field("isExpect", boolean) { - useFieldInIrFactory(defaultValue = false) + useFieldInIrFactory(defaultValue = "false") } +isFakeOverrideField() +field("backingField", field, nullable = true, isChild = true) @@ -537,12 +536,7 @@ object IrTree : AbstractTreeBuilder() { } private fun isFakeOverrideField() = field("isFakeOverride", boolean) { - useFieldInIrFactory( - defaultValue = code( - "origin == %T.FAKE_OVERRIDE", - type(Packages.declarations, "IrDeclarationOrigin").toPoet(), - ), - ) + useFieldInIrFactory(defaultValue = "origin == IrDeclarationOrigin.FAKE_OVERRIDE") } //TODO: make IrScript as IrPackageFragment, because script is used as a file, not as a class @@ -827,7 +821,7 @@ object IrTree : AbstractTreeBuilder() { +symbol(constructorSymbolType, mutable = true) +field("source", type()) { - useFieldInIrFactory(defaultValue = code("%T.NO_SOURCE", SourceElement::class)) + useFieldInIrFactory(defaultValue = "SourceElement.NO_SOURCE") } +field("constructorTypeArgumentsCount", int) } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt index 8a5a05509cf..f09193b00c8 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/ConfigModel.kt @@ -10,6 +10,7 @@ import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.TypeSpec import org.jetbrains.kotlin.generators.tree.* import org.jetbrains.kotlin.ir.generator.BASE_PACKAGE +import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.util.* class Config( @@ -73,9 +74,19 @@ class ElementConfig( override fun toString() = element.name + override val packageName: String + get() = category.packageName + + override val typeName: String + get() = Element.elementName2typeName(name) + context(ImportCollector) override fun renderTo(appendable: Appendable) { - renderingIsNotSupported() + addImport(this) + appendable.append(typeName) + if (params.isNotEmpty()) { + params.joinTo(appendable, prefix = "<", postfix = ">") { it.name } + } } enum class Category(private val packageDir: String, val defaultVisitorParam: String) { @@ -87,7 +98,7 @@ class ElementConfig( } } -sealed interface ElementConfigOrRef : ParametrizedTypeRef, TypeRefWithNullability { +sealed interface ElementConfigOrRef : ParametrizedTypeRef, TypeRefWithNullability, Importable { val element: ElementConfig } @@ -96,6 +107,13 @@ class ElementConfigRef( override val args: Map, override val nullable: Boolean ) : ElementConfigOrRef { + + override val packageName: String + get() = element.packageName + + override val typeName: String + get() = element.typeName + override fun copy(args: Map) = ElementConfigRef(element, args, nullable) override fun copy(nullable: Boolean) = ElementConfigRef(element, args, nullable) @@ -103,7 +121,10 @@ class ElementConfigRef( context(ImportCollector) override fun renderTo(appendable: Appendable) { - renderingIsNotSupported() + addImport(element) + appendable.append(element.typeName) + renderArgsTo(appendable) + renderNullabilityTo(appendable) } } @@ -111,7 +132,7 @@ sealed class UseFieldAsParameterInIrFactoryStrategy { data object No : UseFieldAsParameterInIrFactoryStrategy() - data class Yes(val defaultValue: CodeBlock?) : UseFieldAsParameterInIrFactoryStrategy() + data class Yes(val defaultValue: String?) : UseFieldAsParameterInIrFactoryStrategy() } sealed class FieldConfig( @@ -126,14 +147,10 @@ sealed class FieldConfig( internal var useFieldInIrFactoryStrategy: UseFieldAsParameterInIrFactoryStrategy = if (isChild) UseFieldAsParameterInIrFactoryStrategy.No else UseFieldAsParameterInIrFactoryStrategy.Yes(null) - fun useFieldInIrFactory(defaultValue: CodeBlock? = null) { + fun useFieldInIrFactory(defaultValue: String? = null) { useFieldInIrFactoryStrategy = UseFieldAsParameterInIrFactoryStrategy.Yes(defaultValue) } - fun useFieldInIrFactory(defaultValue: Boolean) { - useFieldInIrFactoryStrategy = UseFieldAsParameterInIrFactoryStrategy.Yes(code("%L", defaultValue)) - } - fun skipInIrFactory() { useFieldInIrFactoryStrategy = UseFieldAsParameterInIrFactoryStrategy.No } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Factory.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Factory.kt index 81fa1808739..2e951c6cd91 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Factory.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Factory.kt @@ -5,66 +5,48 @@ package org.jetbrains.kotlin.ir.generator.print -import com.squareup.kotlinpoet.* +import org.jetbrains.kotlin.generators.tree.* +import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile -import org.jetbrains.kotlin.generators.tree.type +import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration +import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType import org.jetbrains.kotlin.ir.generator.IrTree -import org.jetbrains.kotlin.ir.generator.Packages import org.jetbrains.kotlin.ir.generator.config.UseFieldAsParameterInIrFactoryStrategy +import org.jetbrains.kotlin.ir.generator.irFactoryType +import org.jetbrains.kotlin.ir.generator.model.Element import org.jetbrains.kotlin.ir.generator.model.Model -import org.jetbrains.kotlin.ir.generator.util.parameterizedByIfAny -import org.jetbrains.kotlin.ir.generator.util.tryParameterizedBy +import org.jetbrains.kotlin.ir.generator.stageControllerType import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly -import org.jetbrains.kotlin.utils.addToStdlib.applyIf +import org.jetbrains.kotlin.utils.SmartPrinter +import org.jetbrains.kotlin.utils.withIndent 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 +internal fun printFactory(generationPath: File, model: Model): GeneratedFile = printGeneratedType( + generationPath, + TREE_GENERATOR_README, + irFactoryType.packageName, + irFactoryType.simpleName, +) { + println() + println("interface ", irFactoryType.simpleName, " {") + withIndent { + println("val stageController: ", stageControllerType.render()) + val factoryMethods = 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.typeRef.toPoet().copy(nullable = field.nullable)) - .defaultValue(defaultValue) - .build(), - ) - } - } - .returns(element.toPoet().parameterizedByIfAny(typeParams)) - .addModifiers(KModifier.ABSTRACT) - .build(), - ) - } + .map(::FactoryMethod) - fun replacement(name: String) = funSpecs.find { it.name == name } ?: error("Method '$name' not found") + factoryMethods.forEach { printFactoryMethod(it) } + + fun replacement(name: String) = factoryMethods.find { it.name == name } ?: error("Method '$name' not found") addDeprecatedFunction( replacement("createBlockBody") - .toBuilder() .addParameter( "initializer", - LambdaTypeName.get(receiver = IrTree.blockBody.toPoet(), returnType = UNIT) - ) - .build() + Lambda(receiver = IrTree.blockBody, returnType = StandardTypes.unit), + ), ) { deprecationMessage = "This method was moved to an extension." parameter("startOffset") @@ -74,12 +56,10 @@ internal fun printFactory(generationPath: File, model: Model): GeneratedFile { addDeprecatedFunction( replacement("createBlockBody") - .toBuilder() .addParameter( "statements", - LIST.tryParameterizedBy(IrTree.statement.toPoet()) - ) - .build() + StandardTypes.list.withArgs(IrTree.statement), + ), ) { deprecationMessage = "This method was moved to an extension." parameter("startOffset") @@ -104,7 +84,7 @@ internal fun printFactory(generationPath: File, model: Model): GeneratedFile { parameter("isExpect") parameter("isFun") parameter("source") - defaultValue["hasEnumEntries"] = false + defaultValue["hasEnumEntries"] = "false" } addDeprecatedFunction(replacement("createConstructor")) { @@ -149,7 +129,7 @@ internal fun printFactory(generationPath: File, model: Model): GeneratedFile { } addDeprecatedFunction(replacement("createFunctionWithLateBinding")) { - returnType = IrTree.simpleFunction.toPoet() + returnType = IrTree.simpleFunction parameter("startOffset") parameter("endOffset") parameter("origin") @@ -195,7 +175,7 @@ internal fun printFactory(generationPath: File, model: Model): GeneratedFile { } addDeprecatedFunction(replacement("createPropertyWithLateBinding")) { - returnType = IrTree.property.toPoet() + returnType = IrTree.property parameter("startOffset") parameter("endOffset") parameter("origin") @@ -267,37 +247,64 @@ internal fun printFactory(generationPath: File, model: Model): GeneratedFile { parameter("isHidden") parameter("isAssignable") } - }.build() - - return printTypeCommon(generationPath, IR_FACTORY_TYPE.packageName, visitorType) + } + println("}") } -private class DeprecatedFunctionBuilder(private val replacement: FunSpec) { - val deprecatedFunctionParameterSpecs = mutableListOf() +private class FactoryMethod(val element: Element) { + + val name = "create" + element.name.capitalizeAsciiOnly() + + val parameters = (element.allFieldsRecursively() + element.additionalFactoryMethodParameters) + .filterNot { it.name in element.fieldsToSkipInIrFactoryMethod } + .mapNotNull { field -> + (field.useInIrFactoryStrategy as? UseFieldAsParameterInIrFactoryStrategy.Yes)?.let { + FunctionParameter(field.name, field.typeRef, it.defaultValue) + } + } + .sortedBy { it.defaultValue != null } // All parameters with default values must go last + .toMutableList() + + fun addParameter(name: String, type: TypeRef): FactoryMethod { + parameters.add(FunctionParameter(name, type)) + return this + } +} + +private const val MAX_FUNCTION_PARAMETERS_ON_ONE_LINE = 2 + +context(ImportCollector) +private fun SmartPrinter.printFactoryMethod(factoryMethod: FactoryMethod) { + println() + printFunctionDeclaration( + name = factoryMethod.name, + parameters = factoryMethod.parameters, + returnType = factoryMethod.element, + typeParameters = factoryMethod.element.params, + allParametersOnSeparateLines = factoryMethod.parameters.size > MAX_FUNCTION_PARAMETERS_ON_ONE_LINE, + ) + println() +} + +private class DeprecatedFunctionBuilder(private val replacement: FactoryMethod) { + val deprecatedFunctionParameters = mutableListOf() var oldName = replacement.name - var returnType = replacement.returnType + var returnType: TypeRef = replacement.element var deprecationMessage: String? = null - val defaultValue = mutableMapOf() + val defaultValue = mutableMapOf() 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() - ) + deprecatedFunctionParameters.add(if (removeDefaultValue) replacementParameter.copy(defaultValue = null) else replacementParameter) } } -private fun TypeSpec.Builder.addDeprecatedFunction( - replacement: FunSpec, +context(ImportCollector) +private fun SmartPrinter.addDeprecatedFunction( + replacement: FactoryMethod, build: DeprecatedFunctionBuilder.() -> Unit -): TypeSpec.Builder { - +) { val builder = DeprecatedFunctionBuilder(replacement) builder.build() @@ -307,46 +314,39 @@ private fun TypeSpec.Builder.addDeprecatedFunction( "The method's parameters were reordered." } - return addFunction( - FunSpec.builder(builder.oldName) - .addTypeVariables(replacement.typeVariables) - .addCode( - CodeBlock.builder() - .add("return ") - .add("%N(\n", replacement) - .apply { - for (parameter in replacement.parameters) { - if (builder.deprecatedFunctionParameterSpecs.any { it.name == parameter.name }) { - indent() - add("%N,\n", parameter) - unindent() - } else { - val value = builder.defaultValue[parameter.name] - if (value != null) { - indent() - add("$value,\n") - unindent() - } - } - } - } - .add(")") - .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("level = %T.%N", DeprecationLevel::class, DeprecationLevel.HIDDEN.name) - .build(), - ) - .addParameters(builder.deprecatedFunctionParameterSpecs) - .apply { - builder.returnType?.let { returns(it) } - } - .build(), + println() + println("@Deprecated(") + withIndent { + println("message = \"", message, "\" +") + println(" \" This variant of the method will be removed when the 2024.2 IntelliJ platform is shipped (see KTIJ-26314).\",") + println("level = DeprecationLevel.HIDDEN,") + } + println(")") + val allParametersOnSeparateLines = builder.deprecatedFunctionParameters.size > MAX_FUNCTION_PARAMETERS_ON_ONE_LINE + printFunctionDeclaration( + name = builder.oldName, + parameters = builder.deprecatedFunctionParameters, + returnType = builder.returnType, + typeParameters = replacement.element.params, + allParametersOnSeparateLines = allParametersOnSeparateLines, ) -} \ No newline at end of file + print(" = ", replacement.name, "(") + + val renderedParameters = replacement.parameters.mapNotNull { parameter -> + if (builder.deprecatedFunctionParameters.any { it.name == parameter.name }) { + parameter.name + } else { + builder.defaultValue[parameter.name] + } + } + + if (allParametersOnSeparateLines) { + println() + withIndent { + renderedParameters.forEach { println(it, ",") } + } + } else { + print(renderedParameters.joinToString()) + } + println(")") +} diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/TypeRef.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/TypeRef.kt index bc3e99707a1..7bfeba72722 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/TypeRef.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/TypeRef.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.generators.tree import org.jetbrains.kotlin.generators.tree.printer.braces import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.addToStdlib.joinToWithBuffer import java.util.* import kotlin.reflect.KClass @@ -168,6 +169,34 @@ data class ElementRef, Field : Abstrac } } +data class Lambda( + val receiver: TypeRefWithNullability?, + val parameterTypes: List = emptyList(), + val returnType: TypeRefWithNullability, + override val nullable: Boolean = false, +) : TypeRefWithNullability { + override fun substitute(map: TypeParameterSubstitutionMap) = + Lambda( + receiver?.substitute(map) as TypeRefWithNullability?, + parameterTypes.map { it.substitute(map) as TypeRefWithNullability }, + returnType.substitute(map) as TypeRefWithNullability, + nullable, + ) + + context(ImportCollector) + override fun renderTo(appendable: Appendable) { + if (nullable) appendable.append("(") + receiver?.let { + it.renderTo(appendable) + appendable.append('.') + } + parameterTypes.joinToWithBuffer(appendable, prefix = "(", postfix = ") -> ") { it.renderTo(this) } + returnType.renderTo(appendable) + if (nullable) appendable.append(")?") + } + + override fun copy(nullable: Boolean) = Lambda(receiver, parameterTypes, returnType, nullable) +} sealed interface TypeParameterRef : TypeRef, TypeRefWithNullability { override fun substitute(map: TypeParameterSubstitutionMap): TypeRef = map[this] ?: this @@ -216,7 +245,7 @@ interface TypeRefWithNullability : TypeRef { fun copy(nullable: Boolean): TypeRefWithNullability } -private fun TypeRefWithNullability.renderNullabilityTo(appendable: Appendable) { +fun TypeRefWithNullability.renderNullabilityTo(appendable: Appendable) { if (nullable) { appendable.append('?') } @@ -232,7 +261,7 @@ interface ParametrizedTypeRef, P : TypeParam } context(ImportCollector) -private fun ParametrizedTypeRef<*, *>.renderArgsTo(appendable: Appendable) { +fun ParametrizedTypeRef<*, *>.renderArgsTo(appendable: Appendable) { if (args.isNotEmpty()) { args.values.joinTo(appendable, prefix = "<", postfix = ">") { it.renderTo(appendable)