[FIR/IR generator] Use TypeRef for working with types in fields
- Don't inherit `AbstractField` from `Importable`, because it really is not - Remove the `arguments` and `nullable` properties from `AbstractField`. Both properties can be derived from the field's `typeRef`. - Make `AbstractField`'s `typeRef` property of type `TypeRefWithNullability` instead of just `TypeRef`, because fields can always be nullable.
This commit is contained in:
committed by
Space Team
parent
f30bf0e7e2
commit
de4e39906c
+1
-1
@@ -445,7 +445,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
||||
|
||||
configureFieldInAllLeafBuilders(
|
||||
field = "attributes",
|
||||
fieldPredicate = { it.type == declarationAttributesType.type }
|
||||
fieldPredicate = { it.typeRef == declarationAttributesType }
|
||||
) {
|
||||
default(it, "${declarationAttributesType.type}()")
|
||||
}
|
||||
|
||||
+14
-5
@@ -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)
|
||||
|
||||
+19
-17
@@ -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>(FirTreeBuilder) {
|
||||
@@ -91,11 +93,11 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(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<FirTreeBuilder>(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<DeserializedContainerSource>(), nullable = true)
|
||||
+field("dispatchReceiverType", coneSimpleKotlinTypeType, nullable = true)
|
||||
@@ -115,7 +117,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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<FirTreeBuilder>(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)
|
||||
|
||||
+9
-4
@@ -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<ConeSimpleKotlinType>()
|
||||
val coneClassLikeTypeType = type<ConeClassLikeType>()
|
||||
val standardClassIdsType = type<StandardClassIds>()
|
||||
|
||||
val whenRefType = generatedType("", "FirExpressionRef<FirWhenExpression>")
|
||||
val referenceToSimpleExpressionType = generatedType("", "FirExpressionRef<FirExpression>")
|
||||
val safeCallCheckedSubjectReferenceType = generatedType("", "FirExpressionRef<FirCheckedSafeCallSubject>")
|
||||
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")
|
||||
|
||||
+2
-8
@@ -104,7 +104,7 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
existingField.needTransformInOtherChildren = existingField.needTransformInOtherChildren || parentField.needTransformInOtherChildren
|
||||
existingField.withReplace = parentField.withReplace || existingField.withReplace
|
||||
existingField.parentHasSeparateTransform = parentField.needsSeparateTransform
|
||||
if (parentField.type != existingField.type && parentField.withReplace) {
|
||||
if (parentField.typeRef.copy(nullable = false) != existingField.typeRef.copy(nullable = false) && parentField.withReplace) {
|
||||
existingField.overridenTypes += parentField.typeRef
|
||||
overridenFields[existingField, parentField] = false
|
||||
} else {
|
||||
@@ -126,15 +126,9 @@ class Element(override val name: String, kind: Kind) : AbstractElement<Element,
|
||||
val parent = parentRef.element
|
||||
val fields = parent.allFields.map { field ->
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
+8
-26
@@ -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<TypeRef, List<TypeRef>>, 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
|
||||
}
|
||||
}
|
||||
|
||||
+12
-42
@@ -29,7 +29,7 @@ sealed class Field : AbstractField() {
|
||||
open var isMutableInInterface: Boolean = false
|
||||
open val fromDelegate: Boolean get() = false
|
||||
|
||||
open val overridenTypes: MutableSet<TypeRef> = mutableSetOf()
|
||||
open val overridenTypes: MutableSet<TypeRefWithNullability> = 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<TypeRef>
|
||||
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<TypeRef>
|
||||
override val overridenTypes: MutableSet<TypeRefWithNullability>
|
||||
get() = origin.overridenTypes
|
||||
|
||||
override val arbitraryImportables: MutableList<Importable>
|
||||
@@ -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<PositionTypeParameterRef>
|
||||
get() = StandardTypes.list.withArgs(baseType)
|
||||
|
||||
override var isVolatile: Boolean = false
|
||||
override var isFinal: Boolean = false
|
||||
|
||||
+8
-5
@@ -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<Boolean, Boolean> {
|
||||
@@ -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}")
|
||||
}
|
||||
|
||||
+1
-1
@@ -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")
|
||||
|
||||
+11
-4
@@ -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()
|
||||
|
||||
+8
-6
@@ -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)")
|
||||
}
|
||||
}
|
||||
|
||||
+16
-22
@@ -30,8 +30,9 @@ fun Builder.collectImports(): List<String> {
|
||||
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<String> {
|
||||
}
|
||||
|
||||
private fun Element.collectImportsInternal(base: List<String>, kind: ImportKind): List<String> {
|
||||
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 <D> transform$transformName(transformer: FirTransformer<D>, 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 } }
|
||||
?: ""
|
||||
|
||||
+3
-3
@@ -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<GenericElementOrRef<*, *>>()
|
||||
val usedAsFieldType = hashSetOf<Element>()
|
||||
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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
+2
-1
@@ -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,
|
||||
|
||||
+3
-5
@@ -62,6 +62,8 @@ class ElementConfig(
|
||||
override fun copy(args: Map<NamedTypeParameterRef, TypeRef>) = 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,
|
||||
|
||||
+4
-14
@@ -116,7 +116,6 @@ typealias ElementOrRef = GenericElementOrRef<Element, Field>
|
||||
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<PositionTypeParameterRef>,
|
||||
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)
|
||||
}
|
||||
|
||||
+13
-7
@@ -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<Element>, 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<ElementConfig, Eleme
|
||||
for (field in el.fields) {
|
||||
when (field) {
|
||||
is SingleField -> {
|
||||
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<Element>) {
|
||||
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)
|
||||
|
||||
-1
@@ -235,7 +235,6 @@ fun printElements(generationPath: File, model: Model) = sequence {
|
||||
val elRef = child.typeRef as GenericElementRef<Element, Field>
|
||||
if (!elRef.element.hasTransformMethod) {
|
||||
append(" as %T")
|
||||
if (child.nullable) append("?")
|
||||
args.add(elRef.toPoet())
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -55,4 +55,7 @@ abstract class AbstractElement<Element, Field> : ElementOrRef<Element, Field>, F
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
final override fun copy(args: Map<NamedTypeParameterRef, TypeRef>) =
|
||||
ElementRef(this as Element, args, nullable)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun substitute(map: TypeParameterSubstitutionMap): Element = this as Element
|
||||
}
|
||||
|
||||
+5
-7
@@ -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<TypeRef>()
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+67
-12
@@ -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<P : TypeParameterRef> 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<P : TypeParameterRef> 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<out FirClass>`.
|
||||
*/
|
||||
data class TypeRefWithVariance<out T : TypeRef>(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<Element, Field> : ParametrizedTypeRef<ElementOrRef<Element, Field>, NamedTypeParameterRef>, ClassOrElementRef
|
||||
where Element : AbstractElement<Element, Field>,
|
||||
Field : AbstractField {
|
||||
val element: Element
|
||||
|
||||
override fun copy(nullable: Boolean): ElementRef<Element, Field>
|
||||
}
|
||||
|
||||
data class ElementRef<Element : AbstractElement<Element, Field>, Field : AbstractField>(
|
||||
@@ -98,10 +137,6 @@ data class ElementRef<Element : AbstractElement<Element, Field>, 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<Element : AbstractElement<Element, Field>, 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<Self, P : TypeParameterRef> : TypeRef {
|
||||
interface ParametrizedTypeRef<Self : ParametrizedTypeRef<Self, P>, P : TypeParameterRef> : TypeRef {
|
||||
val args: Map<P, TypeRef>
|
||||
|
||||
fun copy(args: Map<P, TypeRef>): 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<out TypeParameterRef, TypeRef>
|
||||
|
||||
val ParametrizedTypeRef<*, *>.generics: String
|
||||
get() = if (args.isEmpty()) "" else args.values.joinToString(prefix = "<", postfix = ">") { it.typeWithArguments }
|
||||
|
||||
fun <T> ParametrizedTypeRef<T, NamedTypeParameterRef>.withArgs(vararg args: Pair<String, TypeRef>) =
|
||||
copy(args.associate { (k, v) -> NamedTypeParameterRef(k) to v })
|
||||
fun <Self : ParametrizedTypeRef<Self, NamedTypeParameterRef>> ParametrizedTypeRef<Self, NamedTypeParameterRef>.withArgs(
|
||||
vararg args: Pair<String, TypeRef>
|
||||
) = copy(args.associate { (k, v) -> NamedTypeParameterRef(k) to v })
|
||||
|
||||
fun <T> ParametrizedTypeRef<T, PositionTypeParameterRef>.withArgs(vararg args: TypeRef) =
|
||||
copy(args.withIndex().associate { (i, t) -> PositionTypeParameterRef(i) to t })
|
||||
fun <Self : ParametrizedTypeRef<Self, PositionTypeParameterRef>> ParametrizedTypeRef<Self, PositionTypeParameterRef>.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
|
||||
|
||||
Reference in New Issue
Block a user