diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index 2e831a71bc1..b13212c34be 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -445,7 +445,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree configureFieldInAllLeafBuilders( field = "attributes", - fieldPredicate = { it.type == declarationAttributesType.type } + fieldPredicate = { it.typeRef == declarationAttributesType } ) { default(it, "${declarationAttributesType.type}()") } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt index a4e86effdc9..ad1f3cc581e 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt @@ -16,8 +16,12 @@ import org.jetbrains.kotlin.fir.tree.generator.FirTreeBuilder.typeParameter import org.jetbrains.kotlin.fir.tree.generator.FirTreeBuilder.typeParameterRef import org.jetbrains.kotlin.fir.tree.generator.FirTreeBuilder.typeProjection import org.jetbrains.kotlin.fir.tree.generator.FirTreeBuilder.typeRef +import org.jetbrains.kotlin.fir.tree.generator.context.AbstractFieldConfigurator import org.jetbrains.kotlin.fir.tree.generator.context.type import org.jetbrains.kotlin.fir.tree.generator.model.* +import org.jetbrains.kotlin.generators.tree.TypeRefWithVariance +import org.jetbrains.kotlin.generators.tree.withArgs +import org.jetbrains.kotlin.types.Variance object FieldSets { val calleeReference by lazy { field("calleeReference", reference, withReplace = true) } @@ -45,12 +49,17 @@ object FieldSets { ).withTransform(needTransformInOtherChildren = true) } - fun symbolWithPackage(packageName: String, symbolClassName: String, argument: String? = null): Field { - return field("symbol", type(packageName, symbolClassName), argument) - } + fun AbstractFieldConfigurator<*>.ConfigureContext.symbolWithPackageWithArgument(packageName: String, symbolClassName: String) = + field("symbol", type(packageName, symbolClassName).withArgs(TypeRefWithVariance(Variance.OUT_VARIANCE, element))) - fun symbol(symbolClassName: String, argument: String? = null): Field = - symbolWithPackage("fir.symbols.impl", symbolClassName, argument) + fun symbolWithPackage(packageName: String, symbolClassName: String): Field = + field("symbol", type(packageName, symbolClassName)) + + fun AbstractFieldConfigurator<*>.ConfigureContext.symbolWithArgument(symbolClassName: String): Field = + symbolWithPackageWithArgument("fir.symbols.impl", symbolClassName) + + fun symbol(symbolClassName: String): Field = + symbolWithPackage("fir.symbols.impl", symbolClassName) fun body(nullable: Boolean = false, withReplace: Boolean = false) = field("body", block, nullable, withReplace = withReplace) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index d3195827dbc..04f7195d63a 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -23,7 +23,8 @@ import org.jetbrains.kotlin.fir.tree.generator.FieldSets.smartcastStability import org.jetbrains.kotlin.fir.tree.generator.FieldSets.status import org.jetbrains.kotlin.fir.tree.generator.FieldSets.superTypeRefs import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbol -import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbolWithPackage +import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbolWithArgument +import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbolWithPackageWithArgument import org.jetbrains.kotlin.fir.tree.generator.FieldSets.typeArguments import org.jetbrains.kotlin.fir.tree.generator.FieldSets.typeParameterRefs import org.jetbrains.kotlin.fir.tree.generator.FieldSets.typeParameters @@ -35,6 +36,7 @@ import org.jetbrains.kotlin.fir.tree.generator.context.type import org.jetbrains.kotlin.fir.tree.generator.model.* import org.jetbrains.kotlin.generators.tree.StandardTypes import org.jetbrains.kotlin.generators.tree.TypeRef +import org.jetbrains.kotlin.generators.tree.withArgs import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuilder) { @@ -91,11 +93,11 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } fileAnnotationsContainer.configure { - +field("containingFileSymbol", type("fir.symbols.impl", "FirFileSymbol"), argument = null) + +field("containingFileSymbol", type("fir.symbols.impl", "FirFileSymbol")) } declaration.configure { - +symbolWithPackage("fir.symbols", "FirBasedSymbol", "out FirDeclaration") + +symbolWithPackageWithArgument("fir.symbols", "FirBasedSymbol") +field("moduleData", firModuleDataType) +field("origin", declarationOriginType) +field("attributes", declarationAttributesType) @@ -106,7 +108,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild +field("returnTypeRef", typeRef, withReplace = true).withTransform() +field("receiverParameter", receiverParameter, nullable = true, withReplace = true).withTransform() +field("deprecationsProvider", deprecationsProviderType).withReplace().apply { isMutable = true } - +symbol("FirCallableSymbol", "out FirCallableDeclaration") + +symbolWithArgument("FirCallableSymbol") +field("containerSource", type(), nullable = true) +field("dispatchReceiverType", coneSimpleKotlinTypeType, nullable = true) @@ -115,7 +117,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } function.configure { - +symbol("FirFunctionSymbol", "out FirFunction") + +symbolWithArgument("FirFunctionSymbol") +fieldList(valueParameter, withReplace = true).withTransform() +body(nullable = true, withReplace = true).withTransform() } @@ -162,7 +164,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild jump.configure { val e = withArg("E", targetElement) - +field("target", jumpTargetType to listOf(e)) + +field("target", jumpTargetType.withArgs(e)) } loopJump.configure { @@ -227,7 +229,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild constExpression.configure { val t = withArg("T") - +field("kind", constKindType to listOf(t), withReplace = true) + +field("kind", constKindType.withArgs(t), withReplace = true) +field("value", t) } @@ -278,12 +280,12 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } classLikeDeclaration.configure { - +symbol("FirClassLikeSymbol", "out FirClassLikeDeclaration") + +symbolWithArgument("FirClassLikeSymbol") +field("deprecationsProvider", deprecationsProviderType).withReplace().apply { isMutable = true } } klass.configure { - +symbol("FirClassSymbol", "out FirClass") + +symbolWithArgument("FirClassSymbol") +classKind +superTypeRefs(withReplace = true).withTransform() +declarations.withTransform() @@ -338,7 +340,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild typeParameter.configure { +name +symbol("FirTypeParameterSymbol") - +field("containingDeclarationSymbol", firBasedSymbolType to listOf(TypeRef.Star)).apply { + +field("containingDeclarationSymbol", firBasedSymbolType.withArgs(TypeRef.Star)).apply { withBindThis = false } +field(varianceType) @@ -427,7 +429,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild valueParameter.configure { +symbol("FirValueParameterSymbol") +field("defaultValue", expression, nullable = true, withReplace = true) - +field("containingFunctionSymbol", functionSymbolType, "*").apply { + +field("containingFunctionSymbol", functionSymbolType.withArgs(TypeRef.Star)).apply { withBindThis = false } generateBooleanFields("crossinline", "noinline", "vararg") @@ -440,7 +442,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild variable.configure { +name - +symbol("FirVariableSymbol", "out FirVariable") + +symbolWithArgument("FirVariableSymbol") +initializer.withTransform().withReplace() +field("delegate", expression, nullable = true, withReplace = true).withTransform() generateBooleanFields("var", "val") @@ -548,7 +550,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } annotationArgumentMapping.configure { - +field("mapping", StandardTypes.map to listOf(nameType, expression)) + +field("mapping", StandardTypes.map.withArgs(nameType, expression)) } augmentedArraySetCall.configure { @@ -571,7 +573,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild smartCastExpression.configure { +field("originalExpression", expression, withReplace = true).withTransform() - +field("typesFromSmartCast", StandardTypes.collection to listOf(coneKotlinTypeType)) + +field("typesFromSmartCast", StandardTypes.collection.withArgs(coneKotlinTypeType)) +field("smartcastType", typeRef) +field("smartcastTypeWithoutNullableNothing", typeRef, nullable = true) +booleanField("isStable") @@ -667,11 +669,11 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } namedReferenceWithCandidateBase.configure { - +field("candidateSymbol", firBasedSymbolType, "*") + +field("candidateSymbol", firBasedSymbolType.withArgs(TypeRef.Star)) } resolvedNamedReference.configure { - +field("resolvedSymbol", firBasedSymbolType, "*") + +field("resolvedSymbol", firBasedSymbolType.withArgs(TypeRef.Star)) } resolvedCallableReference.configure { @@ -694,7 +696,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild thisReference.configure { +stringField("labelName", nullable = true) - +field("boundSymbol", firBasedSymbolType, "*", nullable = true, withReplace = true) + +field("boundSymbol", firBasedSymbolType.withArgs(TypeRef.Star), nullable = true, withReplace = true) +intField("contextReceiverNumber", withReplace = true) +booleanField("isImplicit") +field("diagnostic", coneDiagnosticType, nullable = true, withReplace = true) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index 919eb5ec228..eba389108de 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType import org.jetbrains.kotlin.generators.tree.TypeKind +import org.jetbrains.kotlin.generators.tree.TypeRef +import org.jetbrains.kotlin.generators.tree.withArgs import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -52,9 +54,12 @@ val coneSimpleKotlinTypeType = type() val coneClassLikeTypeType = type() val standardClassIdsType = type() -val whenRefType = generatedType("", "FirExpressionRef") -val referenceToSimpleExpressionType = generatedType("", "FirExpressionRef") -val safeCallCheckedSubjectReferenceType = generatedType("", "FirExpressionRef") +val whenRefType = generatedType("", "FirExpressionRef") + .withArgs(FirTreeBuilder.whenExpression) +val referenceToSimpleExpressionType = generatedType("", "FirExpressionRef") + .withArgs(FirTreeBuilder.expression) +val safeCallCheckedSubjectReferenceType = generatedType("", "FirExpressionRef") + .withArgs(FirTreeBuilder.checkedSafeCallSubject) val firModuleDataType = type("fir", "FirModuleData") val firImplicitTypeWithoutSourceType = generatedType("types.impl", "FirImplicitTypeRefImplWithoutSource") @@ -75,7 +80,7 @@ val firBasedSymbolType = type("fir.symbols", "FirBasedSymbol") val functionSymbolType = type("fir.symbols.impl", "FirFunctionSymbol") val backingFieldSymbolType = type("fir.symbols.impl", "FirBackingFieldSymbol") val delegateFieldSymbolType = type("fir.symbols.impl", "FirDelegateFieldSymbol") -val classLikeSymbolType = type("fir.symbols.impl", "FirClassLikeSymbol<*>") +val classLikeSymbolType = type("fir.symbols.impl", "FirClassLikeSymbol").withArgs(TypeRef.Star) val regularClassSymbolType = type("fir.symbols.impl", "FirRegularClassSymbol") val typeParameterSymbolType = type("fir.symbols.impl", "FirTypeParameterSymbol") val emptyArgumentListType = type("fir.expressions", "FirEmptyArgumentList") diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt index 66b52d80259..d3d9b99792d 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Element.kt @@ -104,7 +104,7 @@ class Element(override val name: String, kind: Kind) : AbstractElement val copy = (field as? SimpleField)?.let { simpleField -> - // FIXME: Replace with parentRef.args[simpleField.typeRef] - parentRef.args[NamedTypeParameterRef(simpleField.type)]?.let { - simpleField.replaceType(it) - } + simpleField.replaceType(simpleField.typeRef.substitute(parentRef.args) as TypeRefWithNullability) } ?: field.copy() copy.apply { - arguments.replaceAll { - parentRef.args[it] ?: it - } fromParent = true } } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt index b42e932264c..c60d50a08ef 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt @@ -5,26 +5,16 @@ package org.jetbrains.kotlin.fir.tree.generator.model -import org.jetbrains.kotlin.generators.tree.NamedTypeParameterRef -import org.jetbrains.kotlin.generators.tree.StandardTypes -import org.jetbrains.kotlin.generators.tree.TypeRef -import org.jetbrains.kotlin.generators.tree.typeWithArguments +import org.jetbrains.kotlin.generators.tree.* // ----------- Simple field ----------- -fun field(name: String, type: TypeRef, nullable: Boolean = false, withReplace: Boolean = false): Field { - return SimpleField(name, type.typeWithArguments, type.packageName, nullable, withReplace) +fun field(name: String, type: TypeRefWithNullability, nullable: Boolean = false, withReplace: Boolean = false): Field { + return SimpleField(name, type.copy(nullable), withReplace) } -fun field(name: String, typeWithArgs: Pair>, nullable: Boolean = false, withReplace: Boolean = false): Field { - val (type, args) = typeWithArgs - return SimpleField(name, type.typeWithArguments, type.packageName, nullable, withReplace).apply { - arguments += args - } -} - -fun field(type: TypeRef, nullable: Boolean = false, withReplace: Boolean = false): Field { - return SimpleField(type.type.replaceFirstChar(Char::lowercaseChar), type.typeWithArguments, type.packageName, nullable, withReplace) +fun field(type: TypeRefWithNullability, nullable: Boolean = false, withReplace: Boolean = false): Field { + return SimpleField(type.type.replaceFirstChar(Char::lowercaseChar), type.copy(nullable), withReplace) } fun booleanField(name: String, withReplace: Boolean = false): Field { @@ -41,20 +31,12 @@ fun intField(name: String, withReplace: Boolean = false): Field { // ----------- Fir field ----------- -fun field(name: String, type: TypeRef, argument: String? = null, nullable: Boolean = false, withReplace: Boolean = false): Field { - return if (argument == null) { - field(name, type, nullable, withReplace) - } else { - field(name, type to listOf(NamedTypeParameterRef(argument)), nullable, withReplace) - } -} - fun field(name: String, element: ElementOrRef, nullable: Boolean = false, withReplace: Boolean = false): Field { - return FirField(name, element, nullable, withReplace) + return FirField(name, element.copy(nullable), withReplace) } fun field(element: Element, nullable: Boolean = false, withReplace: Boolean = false): Field { - return FirField(element.name.replaceFirstChar(Char::lowercaseChar), element, nullable, withReplace) + return FirField(element.name.replaceFirstChar(Char::lowercaseChar), element.copy(nullable), withReplace) } // ----------- Field list ----------- @@ -91,4 +73,4 @@ fun Field.withTransform(needTransformInOtherChildren: Boolean = false): Field = fun Field.withReplace(): Field = copy().apply { withReplace = true -} \ No newline at end of file +} diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt index fa596a181db..65d54456c3f 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt @@ -29,7 +29,7 @@ sealed class Field : AbstractField() { open var isMutableInInterface: Boolean = false open val fromDelegate: Boolean get() = false - open val overridenTypes: MutableSet = mutableSetOf() + open val overridenTypes: MutableSet = mutableSetOf() open var useNullableForReplace: Boolean = false open var notNull: Boolean = false @@ -45,16 +45,12 @@ sealed class Field : AbstractField() { abstract override var isMutable: Boolean - override fun getTypeWithArguments(notNull: Boolean): String = type + generics + if (nullable && !notNull) "?" else "" - fun copy(): Field = internalCopy().also { updateFieldsInCopy(it) } protected fun updateFieldsInCopy(copy: Field) { if (copy !is FieldWithDefault) { - copy.arguments.clear() - copy.arguments.addAll(arguments) copy.needsSeparateTransform = needsSeparateTransform copy.needTransformInOtherChildren = needTransformInOtherChildren copy.useInBaseTransformerDetection = useInBaseTransformerDetection @@ -77,13 +73,11 @@ sealed class Field : AbstractField() { class FieldWithDefault(val origin: Field) : Field() { override val name: String get() = origin.name - override val type: String get() = origin.type + override val typeRef: TypeRefWithNullability get() = origin.typeRef override var isVolatile: Boolean = origin.isVolatile - override val nullable: Boolean get() = origin.nullable override var withReplace: Boolean get() = origin.withReplace set(_) {} - override val packageName: String? get() = origin.packageName override val isFirType: Boolean get() = origin.isFirType override var needsSeparateTransform: Boolean get() = origin.needsSeparateTransform @@ -93,12 +87,6 @@ class FieldWithDefault(val origin: Field) : Field() { get() = origin.needTransformInOtherChildren set(_) {} - override val arguments: MutableList - get() = origin.arguments - - override val fullQualifiedName: String? - get() = origin.fullQualifiedName - override var isFinal: Boolean get() = origin.isFinal set(_) {} @@ -128,7 +116,7 @@ class FieldWithDefault(val origin: Field) : Field() { override var customSetter: String? = null override var fromDelegate: Boolean = false var needAcceptAndTransform: Boolean = true - override val overridenTypes: MutableSet + override val overridenTypes: MutableSet get() = origin.overridenTypes override val arbitraryImportables: MutableList @@ -151,9 +139,7 @@ class FieldWithDefault(val origin: Field) : Field() { class SimpleField( override val name: String, - override val type: String, - override val packageName: String?, - override val nullable: Boolean, + override val typeRef: TypeRefWithNullability, override var withReplace: Boolean, override var isVolatile: Boolean = false, override var isFinal: Boolean = false, @@ -167,9 +153,7 @@ class SimpleField( override fun internalCopy(): Field { return SimpleField( name = name, - type = type, - packageName = packageName, - nullable = nullable, + typeRef = typeRef, withReplace = withReplace, isVolatile = isVolatile, isFinal = isFinal, @@ -180,11 +164,9 @@ class SimpleField( } } - fun replaceType(newType: TypeRef) = SimpleField( + fun replaceType(newType: TypeRefWithNullability) = SimpleField( name = name, - type = newType.type, - packageName = newType.packageName, - nullable = nullable, + typeRef = newType, withReplace = withReplace, isVolatile = isVolatile, isFinal = isFinal, @@ -198,18 +180,14 @@ class SimpleField( class FirField( override val name: String, - val element: ElementOrRef, - override val nullable: Boolean, + val element: ElementRef, override var withReplace: Boolean, ) : Field() { - init { - arguments += element.args.values - } - override val type: String get() = element.type + override val typeRef: TypeRefWithNullability + get() = element override var isVolatile: Boolean = false override var isFinal: Boolean = false - override val packageName: String? get() = element.packageName override val isFirType: Boolean = true override var isMutable: Boolean = true @@ -217,14 +195,10 @@ class FirField( override var isLateinit: Boolean = false override var isParameter: Boolean = false - override fun getTypeWithArguments(notNull: Boolean): String = - element.getTypeWithArguments(notNull) + if (nullable && !notNull) "?" else "" - override fun internalCopy(): Field { return FirField( name, element, - nullable, withReplace ).apply { withBindThis = this@FirField.withBindThis @@ -241,12 +215,8 @@ class FieldList( useMutableOrEmpty: Boolean = false ) : Field() { override var defaultValueInImplementation: String? = null - override val packageName: String? get() = baseType.packageName - override val fullQualifiedName: String? get() = baseType.fullQualifiedName - override val type: String = "List<${baseType.typeWithArguments}>" - - override val nullable: Boolean - get() = false + override val typeRef: ClassRef + get() = StandardTypes.list.withArgs(baseType) override var isVolatile: Boolean = false override var isFinal: Boolean = false diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt index 7c544ec1ae7..f85ebf55a67 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.tree.generator.printer import org.jetbrains.kotlin.fir.tree.generator.declarationAttributesType import org.jetbrains.kotlin.fir.tree.generator.model.* +import org.jetbrains.kotlin.generators.tree.StandardTypes +import org.jetbrains.kotlin.generators.tree.TypeRefWithNullability import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType import org.jetbrains.kotlin.generators.tree.typeWithArguments @@ -129,7 +131,8 @@ private fun FieldWithDefault.needBackingField(fieldIsUseless: Boolean) = defaultValueInBuilder == null } -private fun FieldWithDefault.needNotNullDelegate(fieldIsUseless: Boolean) = needBackingField(fieldIsUseless) && (type == "Boolean" || type == "Int") +private fun FieldWithDefault.needNotNullDelegate(fieldIsUseless: Boolean) = + needBackingField(fieldIsUseless) && (typeRef == StandardTypes.boolean || typeRef == StandardTypes.int) private fun SmartPrinter.printFieldInBuilder(field: FieldWithDefault, builder: Builder, fieldIsUseless: Boolean): Pair { @@ -139,7 +142,7 @@ private fun SmartPrinter.printFieldInBuilder(field: FieldWithDefault, builder: B return true to false } val name = field.name - val type = field.getTypeWithArguments(field.notNull) + val type = field.typeRef.getTypeWithArguments(field.notNull) val defaultValue = if (fieldIsUseless) field.defaultValueInImplementation.also { requireNotNull(it) } else @@ -168,7 +171,7 @@ private fun SmartPrinter.printFieldInBuilder(field: FieldWithDefault, builder: B false } field.needNotNullDelegate(fieldIsUseless) -> { - println(" by kotlin.properties.Delegates.notNull<${field.type}>()") + println(" by kotlin.properties.Delegates.notNull<${field.typeRef.type}>()") hasRequiredFields = true true } @@ -206,7 +209,7 @@ private fun SmartPrinter.printDeprecationOnUselessFieldIfNeeded(field: Field, bu private fun SmartPrinter.printFieldListInBuilder(field: FieldList, builder: Builder, fieldIsUseless: Boolean) { printDeprecationOnUselessFieldIfNeeded(field, builder, fieldIsUseless) printModifiers(builder, field, fieldIsUseless) - print("val ${field.name}: ${field.getMutableType(forBuilder = true)}") + print("val ${field.name}: ${field.getMutableType(forBuilder = true).typeWithArguments}") if (builder is LeafBuilder) { print(" = mutableListOf()") } @@ -301,7 +304,7 @@ private fun SmartPrinter.printDslBuildCopyFunction( when { field.invisibleField -> {} field.origin is FieldList -> println("copyBuilder.${field.name}.addAll(original.${field.name})") - field.type == declarationAttributesType.type -> println("copyBuilder.${field.name} = original.${field.name}.copy()") + field.typeRef == declarationAttributesType -> println("copyBuilder.${field.name} = original.${field.name}.copy()") field.notNull -> println("original.${field.name}?.let { copyBuilder.${field.name} = it }") else -> println("copyBuilder.${field.name} = original.${field.name}") } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt index fcf780b18c7..22c3e301a8a 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt @@ -82,7 +82,7 @@ fun SmartPrinter.printElement(element: Element) { } } - fun Field.replaceDeclaration(override: Boolean, overridenType: TypeRef? = null, forceNullable: Boolean = false) { + fun Field.replaceDeclaration(override: Boolean, overridenType: TypeRefWithNullability? = null, forceNullable: Boolean = false) { println() if (name == "source") { println("@FirImplementationDetail") diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/field.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/field.kt index 73c62e0fad4..769b611550c 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/field.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/field.kt @@ -6,11 +6,18 @@ package org.jetbrains.kotlin.fir.tree.generator.printer import org.jetbrains.kotlin.fir.tree.generator.model.Field +import org.jetbrains.kotlin.generators.tree.typeWithArguments import org.jetbrains.kotlin.utils.SmartPrinter import org.jetbrains.kotlin.utils.withIndent -fun SmartPrinter.printField(field: Field, isImplementation: Boolean, override: Boolean, inConstructor: Boolean = false, notNull: Boolean = false, modifiers: SmartPrinter.() -> Unit = {}) { +fun SmartPrinter.printField( + field: Field, + isImplementation: Boolean, + override: Boolean, + inConstructor: Boolean = false, + modifiers: SmartPrinter.() -> Unit = {}, +) { if (!field.isVal && field.isVolatile) { println("@Volatile") } @@ -32,8 +39,8 @@ fun SmartPrinter.printField(field: Field, isImplementation: Boolean, override: B } else { print("val") } - val type = if (isImplementation) field.getMutableType(notNull = notNull) else field.getTypeWithArguments(notNull = notNull) - print(" ${field.name}: $type") + val type = if (isImplementation) field.getMutableType() else field.typeRef + print(" ${field.name}: ${type.typeWithArguments}") if (inConstructor) print(",") println() } @@ -52,7 +59,7 @@ fun SmartPrinter.printFieldWithDefaultInImplementation(field: Field) { } else { print("var") } - print(" ${field.name}: ${field.getMutableType()}") + print(" ${field.name}: ${field.getMutableType().typeWithArguments}") if (field.withGetter) { println() pushIndent() diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt index d28c0af9d73..1c1cab79090 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt @@ -79,9 +79,11 @@ fun SmartPrinter.printImplementation(implementation: Implementation) { withIndent { fieldsWithoutDefault.forEachIndexed { _, field -> if (field.isParameter) { - println("${field.name}: ${field.typeWithArguments},") + print("${field.name}: ${field.typeRef.typeWithArguments}") + if (field.nullable) print("?") + println(",") } else if (!field.isFinal) { - printField(field, isImplementation = true, override = true, inConstructor = true, notNull = field.notNull) + printField(field, isImplementation = true, override = true, inConstructor = true) } } } @@ -99,7 +101,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) { allFields.forEach { abstract() - printField(it, isImplementation = true, override = true, notNull = it.notNull) + printField(it, isImplementation = true, override = true) } } else { fieldsWithDefault.forEach { @@ -112,7 +114,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) { val bindingCalls = element.allFields.filter { - it.withBindThis && it.type.contains("Symbol") && it !is FieldList && it.name != "companionObjectSymbol" + it.withBindThis && it.typeRef.type.contains("Symbol") && it !is FieldList && it.name != "companionObjectSymbol" }.takeIf { it.isNotEmpty() && !isInterface && !isAbstract && !element.type.contains("Reference") @@ -322,7 +324,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) { fun generateReplace( field: Field, - overridenType: TypeRef? = null, + overridenType: TypeRefWithNullability? = null, forceNullable: Boolean = false, body: () -> Unit, ) { @@ -375,7 +377,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) { for (overridenType in field.overridenTypes) { generateReplace(field, overridenType) { - println("require($newValue is ${field.typeWithArguments})") + println("require($newValue is ${field.typeRef.typeWithArguments})") println("replace$capitalizedFieldName($newValue)") } } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt index f46ad8d0409..64d9a1beb5b 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/utils.kt @@ -30,8 +30,9 @@ fun Builder.collectImports(): List { usedTypes.mapNotNullTo(this) { it.fullQualifiedName } for (field in allFields) { if (field.invisibleField) continue - field.fullQualifiedName?.let(this::add) - field.arguments.mapNotNullTo(this) { it.fullQualifiedName } + // TODO: Use recursive import collection for TypeRefs + field.typeRef.fullQualifiedName?.let(this::add) + (field.typeRef as? ParametrizedTypeRef<*, *>)?.args?.values?.mapNotNullTo(this) { it.fullQualifiedName } } add(materializedElement?.fullQualifiedName ?: throw IllegalStateException(type)) @@ -72,9 +73,9 @@ fun Element.collectImports(): List { } private fun Element.collectImportsInternal(base: List, kind: ImportKind): List { - val fqns = base + allFields.mapNotNull { it.fullQualifiedName } + + val fqns = base + allFields.mapNotNull { it.typeRef.fullQualifiedName } + allFields.flatMap { it.overridenTypes.mapNotNull { it.fullQualifiedName } + it.arbitraryImportables.mapNotNull { it.fullQualifiedName } } + - allFields.flatMap { it.arguments.mapNotNull { it.fullQualifiedName } } + + allFields.flatMap { (it.typeRef as? ParametrizedTypeRef<*, *>)?.args?.values?.mapNotNull { it.fullQualifiedName } ?: emptyList() } + // TODO: Use recursive import collection for TypeRefs params.flatMap { it.bounds.mapNotNull { it.fullQualifiedName } } val result = fqns.filterRedundantImports(packageName, kind).toMutableList() @@ -122,23 +123,21 @@ fun transformFunctionDeclaration(transformName: String, returnType: String): Str return "fun transform$transformName(transformer: FirTransformer, data: D): $returnType" } -fun Field.replaceFunctionDeclaration(overridenType: TypeRef? = null, forceNullable: Boolean = false): String { +fun Field.replaceFunctionDeclaration(overridenType: TypeRefWithNullability? = null, forceNullable: Boolean = false): String { val capName = name.replaceFirstChar(Char::uppercaseChar) - val type = overridenType?.typeWithArguments ?: typeWithArguments - - val typeWithNullable = if (forceNullable && !type.endsWith("?")) "$type?" else type - - return "fun replace$capName(new$capName: $typeWithNullable)" + val type = overridenType ?: typeRef + val typeWithNullable = if (forceNullable) type.copy(nullable = true) else type + return "fun replace$capName(new$capName: ${typeWithNullable.typeWithArguments})" } -fun Field.getMutableType(forBuilder: Boolean = false, notNull: Boolean = false): String = when (this) { +fun Field.getMutableType(forBuilder: Boolean = false): TypeRef = when (this) { is FieldList -> when { - isMutableOrEmpty && !forBuilder -> "MutableOrEmpty$typeWithArguments" - isMutable -> "Mutable$typeWithArguments" - else -> typeWithArguments - } - is FieldWithDefault -> if (isMutable) origin.getMutableType(notNull) else getTypeWithArguments(notNull) - else -> getTypeWithArguments(notNull) + isMutableOrEmpty && !forBuilder -> type(BASE_PACKAGE, "MutableOrEmptyList", kind = TypeKind.Class) + isMutable -> StandardTypes.mutableList + else -> StandardTypes.list + }.withArgs(baseType).copy(nullable) + is FieldWithDefault -> if (isMutable) origin.getMutableType() else typeRef + else -> typeRef } fun Field.call(): String = if (nullable) "?." else "." @@ -147,8 +146,3 @@ val Element.safeDecapitalizedName: String get() = if (name == "Class") "klass" e val ImplementationWithArg.generics: String get() = argument?.let { "<${it.type}>" } ?: "" - -val Field.generics: String - get() = arguments.takeIf { it.isNotEmpty() } - ?.let { it.joinToString(", ", "<", ">") { it.typeWithArguments } } - ?: "" diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/BaseTransformerTypeFinder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/BaseTransformerTypeFinder.kt index 1210cc59105..04960907fb3 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/BaseTransformerTypeFinder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/util/BaseTransformerTypeFinder.kt @@ -17,13 +17,13 @@ import org.jetbrains.kotlin.generators.tree.ElementOrRef as GenericElementOrRef * a type of [Field], except when that [Field] is explicitly opted out of it via [Field.useInBaseTransformerDetection]. */ fun detectBaseTransformerTypes(builder: AbstractFirTreeBuilder) { - val usedAsFieldType = hashSetOf>() + val usedAsFieldType = hashSetOf() for (element in builder.elements) { for (field in element.allFirFields) { if (!field.useInBaseTransformerDetection) continue val fieldElement = when (field) { - is FirField -> field.element - is FieldList -> field.baseType as GenericElementOrRef<*, *> + is FirField -> field.element.element + is FieldList -> (field.baseType as GenericElementOrRef<*, *>).element as Element else -> error("Invalid field type: $field") } if (fieldElement == AbstractFirTreeBuilder.baseFirElement) continue 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 16fa63991b9..e1cb9cedc1f 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 @@ -33,7 +33,7 @@ import org.jetbrains.kotlin.types.Variance // 2) parents // 3) fields object IrTree : AbstractTreeBuilder() { - private fun symbol(type: TypeRef, mutable: Boolean = false): SimpleFieldConfig = + private fun symbol(type: TypeRefWithNullability, mutable: Boolean = false): SimpleFieldConfig = field("symbol", type, mutable = mutable) private fun descriptor(typeName: String, nullable: Boolean = false): SimpleFieldConfig = diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/AbstractTreeBuilder.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/AbstractTreeBuilder.kt index 2f5bdc59cc7..6282cd73c8b 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/AbstractTreeBuilder.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/config/AbstractTreeBuilder.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.generator.config import org.jetbrains.kotlin.generators.tree.TypeRef +import org.jetbrains.kotlin.generators.tree.TypeRefWithNullability import org.jetbrains.kotlin.generators.tree.TypeVariable import org.jetbrains.kotlin.generators.tree.type import org.jetbrains.kotlin.types.Variance @@ -36,7 +37,7 @@ abstract class AbstractTreeBuilder { protected fun field( name: String, - type: TypeRef?, + type: TypeRefWithNullability?, nullable: Boolean = false, mutable: Boolean = true, isChild: Boolean = false, 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 b4b1ce6af8b..a75d20ce16d 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 @@ -62,6 +62,8 @@ class ElementConfig( override fun copy(args: Map) = ElementConfigRef(this, args, false) override fun copy(nullable: Boolean) = ElementConfigRef(this, args, nullable) + override fun substitute(map: TypeParameterSubstitutionMap): ElementConfig = this + operator fun TypeVariable.unaryPlus() = apply { params.add(this) } @@ -78,8 +80,6 @@ class ElementConfig( override val type: String get() = Element.elementName2typeName(name) - override fun getTypeWithArguments(notNull: Boolean): String = type - enum class Category(private val packageDir: String, val defaultVisitorParam: String) { Expression("expressions", "expression"), Declaration("declarations", "declaration"), @@ -108,8 +108,6 @@ class ElementConfigRef( override val packageName: String get() = element.packageName - - override fun getTypeWithArguments(notNull: Boolean): String = type + generics } sealed class UseFieldAsParameterInIrFactoryStrategy { @@ -152,7 +150,7 @@ sealed class FieldConfig( class SimpleFieldConfig( name: String, - val type: TypeRef?, + val type: TypeRefWithNullability?, val nullable: Boolean, val mutable: Boolean, isChildElement: Boolean, diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt index 20cdcc09c6b..737eb355bbb 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Model.kt @@ -116,7 +116,6 @@ typealias ElementOrRef = GenericElementOrRef sealed class Field( config: FieldConfig, override val name: String, - override val nullable: Boolean, override var isMutable: Boolean, val isChild: Boolean, ) : AbstractField() { @@ -145,25 +144,17 @@ sealed class Field( override val isParameter: Boolean get() = false - - override val type: String - get() = typeRef.type - override val packageName: String? - get() = typeRef.packageName - - override fun getTypeWithArguments(notNull: Boolean): String = typeRef.getTypeWithArguments(notNull) } class SingleField( config: FieldConfig, name: String, - override var typeRef: TypeRef, - nullable: Boolean, + override var typeRef: TypeRefWithNullability, mutable: Boolean, isChild: Boolean, override val baseDefaultValue: CodeBlock?, override val baseGetter: CodeBlock?, -) : Field(config, name, nullable, mutable, isChild) { +) : Field(config, name, mutable, isChild) { override val transformable: Boolean get() = isMutable } @@ -173,13 +164,12 @@ class ListField( name: String, var elementType: TypeRef, private val listType: ClassRef, - nullable: Boolean, mutable: Boolean, isChild: Boolean, override val transformable: Boolean, override val baseDefaultValue: CodeBlock?, override val baseGetter: CodeBlock?, -) : Field(config, name, nullable, mutable, isChild) { - override val typeRef: TypeRef +) : Field(config, name, mutable, isChild) { + override val typeRef: TypeRefWithNullability get() = listType.withArgs(elementType) } diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt index 3c5e4c1e5d0..a6bda4ecde5 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/model/Transformations.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.castAll import org.jetbrains.kotlin.utils.addToStdlib.partitionIsInstance import org.jetbrains.kotlin.generators.tree.ElementRef as GenericElementRef -private object InferredOverriddenType : TypeRef { +private object InferredOverriddenType : TypeRefWithNullability { override val type: String get() = error("not supported") override val packageName: String? @@ -22,6 +22,13 @@ private object InferredOverriddenType : TypeRef { override fun getTypeWithArguments(notNull: Boolean): String { error("not supported") } + + override fun substitute(map: TypeParameterSubstitutionMap) = this + + override val nullable: Boolean + get() = false + + override fun copy(nullable: Boolean) = this } data class Model(val elements: List, val rootElement: Element) @@ -57,8 +64,7 @@ private fun transformFieldConfig(fc: FieldConfig): Field = when (fc) { is SimpleFieldConfig -> SingleField( fc, fc.name, - fc.type ?: InferredOverriddenType, - fc.nullable, + fc.type?.copy(fc.nullable) ?: InferredOverriddenType, fc.mutable, fc.isChild, fc.baseDefaultValue, @@ -74,8 +80,7 @@ private fun transformFieldConfig(fc: FieldConfig): Field = when (fc) { fc, fc.name, fc.elementType ?: InferredOverriddenType, - listType, - fc.nullable, + listType.copy(fc.nullable), fc.mutability == ListFieldConfig.Mutability.Var, fc.isChild, fc.mutability != ListFieldConfig.Mutability.Immutable, @@ -127,7 +132,7 @@ private fun replaceElementRefs(config: Config, mapping: Map { - field.typeRef = transform(field.typeRef) + field.typeRef = transform(field.typeRef) as TypeRefWithNullability } is ListField -> { field.elementType = transform(field.elementType) @@ -186,7 +191,8 @@ private fun processFieldOverrides(elements: List) { type.takeUnless { it is InferredOverriddenType } ?: overriddenType when (field) { is SingleField -> { - field.typeRef = transformInferredType(field.typeRef, (overriddenField as SingleField).typeRef) + field.typeRef = + transformInferredType(field.typeRef, (overriddenField as SingleField).typeRef) as TypeRefWithNullability } is ListField -> { field.elementType = transformInferredType(field.elementType, (overriddenField as ListField).elementType) diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt index 999830183bd..f043bf038ad 100644 --- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt +++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/print/Elements.kt @@ -235,7 +235,6 @@ fun printElements(generationPath: File, model: Model) = sequence { val elRef = child.typeRef as GenericElementRef if (!elRef.element.hasTransformMethod) { append(" as %T") - if (child.nullable) append("?") args.add(elRef.toPoet()) } } diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt index 999d5da7912..a9a8ea66bd6 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractElement.kt @@ -55,4 +55,7 @@ abstract class AbstractElement : ElementOrRef, F @Suppress("UNCHECKED_CAST") final override fun copy(args: Map) = ElementRef(this as Element, args, nullable) + + @Suppress("UNCHECKED_CAST") + override fun substitute(map: TypeParameterSubstitutionMap): Element = this as Element } diff --git a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractField.kt b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractField.kt index aebfad6c8b1..28217e7da72 100644 --- a/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractField.kt +++ b/generators/tree-generator-common/src/org/jetbrains/kotlin/generators/tree/AbstractField.kt @@ -5,16 +5,14 @@ package org.jetbrains.kotlin.generators.tree -abstract class AbstractField : Importable { +abstract class AbstractField { abstract val name: String - open val typeRef: TypeRef - get() = type(packageName!!, type).withArgs(*arguments.toTypedArray()).copy(nullable = nullable) + abstract val typeRef: TypeRefWithNullability - open val arguments = mutableListOf() - - abstract val nullable: Boolean + val nullable: Boolean + get() = typeRef.nullable abstract val isVolatile: Boolean @@ -49,4 +47,4 @@ abstract class AbstractField : Importable { override fun hashCode(): Int { return name.hashCode() } -} \ No newline at end of file +} 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 3e5d1a76289..d05e2b818c2 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 @@ -11,6 +11,13 @@ import java.util.* import kotlin.reflect.KClass interface TypeRef : Importable { + + /** + * Constructs a new [TypeRef] by recursively replacing referenced [TypeParameterRef]s with other types according to the provided + * substitution map. + */ + fun substitute(map: TypeParameterSubstitutionMap): TypeRef + object Star : TypeRef { override val type: String get() = "*" @@ -20,6 +27,8 @@ interface TypeRef : Importable { override fun getTypeWithArguments(notNull: Boolean): String = type + override fun substitute(map: TypeParameterSubstitutionMap) = this + override fun toString(): String = type } } @@ -65,8 +74,6 @@ class ClassRef

private constructor( override val fullQualifiedName: String get() = canonicalName - override fun getTypeWithArguments(notNull: Boolean): String = type + generics - /** * The enclosing classes, outermost first, followed by the simple name. This is `["Map", "Entry"]` * for `Map.Entry`. @@ -77,12 +84,44 @@ class ClassRef

private constructor( override fun copy(nullable: Boolean) = ClassRef(kind, names, args, nullable) override fun toString() = canonicalName + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is ClassRef<*>) return false + return kind == other.kind && args == other.args && nullable == other.nullable && names == other.names + } + + override fun hashCode(): Int = Objects.hash(kind, args, nullable, names) +} + +/** + * Used for specifying a type argument with use-site variance, e.g. `FirClassSymbol`. + */ +data class TypeRefWithVariance(val variance: Variance, val typeRef: T) : TypeRef { + + override val type: String + get() = buildString { + if (variance != Variance.INVARIANT) { + append(variance) + append(" ") + } + append(typeRef.typeWithArguments) + } + + override val packageName: String? + get() = null + + override fun getTypeWithArguments(notNull: Boolean): String = type + + override fun substitute(map: TypeParameterSubstitutionMap): TypeRefWithVariance<*> = + TypeRefWithVariance(variance, typeRef.substitute(map)) } interface ElementOrRef : ParametrizedTypeRef, NamedTypeParameterRef>, ClassOrElementRef where Element : AbstractElement, Field : AbstractField { val element: Element + + override fun copy(nullable: Boolean): ElementRef } data class ElementRef, Field : AbstractField>( @@ -98,10 +137,6 @@ data class ElementRef, Field : Abstrac override val packageName: String? get() = element.packageName - override fun getTypeWithArguments(notNull: Boolean): String { - return element.type + generics - } - override fun toString() = buildString { append(element.name) append("<") @@ -114,10 +149,13 @@ data class ElementRef, Field : Abstrac } -sealed interface TypeParameterRef : TypeRef +sealed interface TypeParameterRef : TypeRef, TypeRefWithNullability { + override fun substitute(map: TypeParameterSubstitutionMap): TypeRef = map[this] ?: this +} data class PositionTypeParameterRef( val index: Int, + override val nullable: Boolean = false, ) : TypeParameterRef { override fun toString() = index.toString() @@ -128,10 +166,13 @@ data class PositionTypeParameterRef( get() = null override fun getTypeWithArguments(notNull: Boolean): String = type + + override fun copy(nullable: Boolean) = PositionTypeParameterRef(index, nullable) } open class NamedTypeParameterRef( val name: String, + override val nullable: Boolean = false, ) : TypeParameterRef { override fun equals(other: Any?): Boolean { return other is NamedTypeParameterRef && other.name == name @@ -150,6 +191,8 @@ open class NamedTypeParameterRef( get() = null override fun getTypeWithArguments(notNull: Boolean) = name + + final override fun copy(nullable: Boolean) = NamedTypeParameterRef(name, nullable) } interface TypeRefWithNullability : TypeRef { @@ -158,20 +201,29 @@ interface TypeRefWithNullability : TypeRef { fun copy(nullable: Boolean): TypeRefWithNullability } -interface ParametrizedTypeRef : TypeRef { +interface ParametrizedTypeRef, P : TypeParameterRef> : TypeRef { val args: Map fun copy(args: Map): Self + + override fun substitute(map: TypeParameterSubstitutionMap): Self = + copy(args.mapValues { it.value.substitute(map) }) + + override fun getTypeWithArguments(notNull: Boolean): String = type + generics + (if (nullable) "?" else "") } +typealias TypeParameterSubstitutionMap = Map + val ParametrizedTypeRef<*, *>.generics: String get() = if (args.isEmpty()) "" else args.values.joinToString(prefix = "<", postfix = ">") { it.typeWithArguments } -fun ParametrizedTypeRef.withArgs(vararg args: Pair) = - copy(args.associate { (k, v) -> NamedTypeParameterRef(k) to v }) +fun > ParametrizedTypeRef.withArgs( + vararg args: Pair +) = copy(args.associate { (k, v) -> NamedTypeParameterRef(k) to v }) -fun ParametrizedTypeRef.withArgs(vararg args: TypeRef) = - copy(args.withIndex().associate { (i, t) -> PositionTypeParameterRef(i) to t }) +fun > ParametrizedTypeRef.withArgs( + vararg args: TypeRef +) = copy(args.withIndex().associate { (i, t) -> PositionTypeParameterRef(i) to t }) class TypeVariable( @@ -211,3 +263,6 @@ fun ClassOrElementRef.inheritanceClauseParenthesis(): String = when (this) { TypeKind.Interface -> "" } } + +val TypeRef.nullable: Boolean + get() = (this as? TypeRefWithNullability)?.nullable ?: false