FIR: Simplify FirQualifiedAccess hiearchy
Mostly, it's getting rid of FirQualifiedAccessWithoutCallee and FirModifiableQualifiedAccess The latter was only used during FIR building to set explicit receiver that might be done by replace call on explicit receiver The problem with replaceExplicitReceiver is that for FirComponentCall explicitReceiver should be not null, so it's needed to perform those tricks at the generatot
This commit is contained in:
+2
-2
@@ -24,7 +24,7 @@ object FieldSets {
|
||||
val calleeReference = field("calleeReference", reference, withReplace = true)
|
||||
|
||||
val receivers = fieldSet(
|
||||
field("explicitReceiver", expression, nullable = true).withTransform(),
|
||||
field("explicitReceiver", expression, nullable = true, withReplace = true).withTransform(),
|
||||
field("dispatchReceiver", expression).withTransform(),
|
||||
field("extensionReceiver", expression).withTransform()
|
||||
)
|
||||
@@ -83,4 +83,4 @@ object FieldSets {
|
||||
val modality = field(modalityType, nullable = true)
|
||||
|
||||
val scopeProvider = field("scopeProvider", firScopeProviderType)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -90,8 +90,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
|
||||
val equalityOperatorCall = element("EqualityOperatorCall", Expression, expression, call)
|
||||
val whenExpression = element("WhenExpression", Expression, expression, resolvable)
|
||||
val whenBranch = element("WhenBranch", Expression)
|
||||
val qualifiedAccessWithoutCallee = element("QualifiedAccessWithoutCallee", Expression, statement)
|
||||
val qualifiedAccess = element("QualifiedAccess", Expression, qualifiedAccessWithoutCallee, resolvable)
|
||||
val qualifiedAccess = element("QualifiedAccess", Expression, resolvable, statement)
|
||||
val checkNotNullCall = element("CheckNotNullCall", Expression, expression, call, resolvable)
|
||||
val elvisExpression = element("ElvisExpression", Expression, expression, resolvable)
|
||||
|
||||
|
||||
+2
-13
@@ -74,11 +74,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
|
||||
impl(arrayOfCall)
|
||||
|
||||
val modifiableQualifiedAccess = impl(qualifiedAccessWithoutCallee, "FirModifiableQualifiedAccess") {}
|
||||
|
||||
impl(callableReferenceAccess) {
|
||||
parents += modifiableQualifiedAccess
|
||||
}
|
||||
impl(callableReferenceAccess)
|
||||
|
||||
impl(componentCall) {
|
||||
default("calleeReference", "FirSimpleNamedReference(source, Name.identifier(\"component\$componentIndex\"), null)")
|
||||
@@ -128,14 +124,10 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
}
|
||||
|
||||
impl(functionCall) {
|
||||
parents += modifiableQualifiedAccess
|
||||
kind = OpenClass
|
||||
}
|
||||
|
||||
impl(qualifiedAccessExpression) {
|
||||
parents += modifiableQualifiedAccess
|
||||
}
|
||||
|
||||
impl(qualifiedAccessExpression)
|
||||
|
||||
noImpl(expressionWithSmartcast)
|
||||
|
||||
@@ -269,7 +261,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
}
|
||||
|
||||
impl(thisReceiverExpression) {
|
||||
parents += modifiableQualifiedAccess
|
||||
defaultNoReceivers()
|
||||
}
|
||||
|
||||
@@ -280,8 +271,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
}
|
||||
|
||||
impl(variableAssignment) {
|
||||
parents += modifiableQualifiedAccess
|
||||
|
||||
default("lValue") {
|
||||
value = "calleeReference"
|
||||
customSetter = "calleeReference = value"
|
||||
|
||||
+2
-2
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.tree.generator.FieldSets.calleeReference
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.classKind
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.controlFlowGraphReferenceField
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.declarations
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.effectiveVisibility
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.initializer
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.modality
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.name
|
||||
@@ -192,7 +191,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+field("rhs", expression).withTransform()
|
||||
}
|
||||
|
||||
qualifiedAccessWithoutCallee.configure {
|
||||
qualifiedAccess.configure {
|
||||
+typeArguments.withTransform()
|
||||
+receivers
|
||||
}
|
||||
@@ -354,6 +353,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
delegatedConstructorCall.configure {
|
||||
+field("constructedTypeRef", typeRef, withReplace = true)
|
||||
+field("dispatchReceiver", expression).withTransform()
|
||||
+field("calleeReference", reference, withReplace = true)
|
||||
generateBooleanFields("this", "super")
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -33,6 +33,7 @@ interface AbstractElement : FieldContainer, KindOwner {
|
||||
val defaultImplementation: Implementation?
|
||||
val customImplementations: List<Implementation>
|
||||
val overridenFields: Map<Field, Map<Importable, Boolean>>
|
||||
val useNullableForReplace: Set<Field>
|
||||
|
||||
override val allParents: List<KindOwner> get() = parents
|
||||
}
|
||||
@@ -63,6 +64,7 @@ class Element(val name: String, kind: Kind) : AbstractElement {
|
||||
|
||||
override val needTransformOtherChildren: Boolean get() = _needTransformOtherChildren || parents.any { it.needTransformOtherChildren }
|
||||
override val overridenFields: MutableMap<Field, MutableMap<Importable, Boolean>> = mutableMapOf()
|
||||
override val useNullableForReplace: MutableSet<Field> = mutableSetOf()
|
||||
override val allImplementations: List<Implementation> by lazy {
|
||||
if (doesNotNeedImplementation) {
|
||||
emptyList()
|
||||
@@ -90,6 +92,9 @@ class Element(val name: String, kind: Kind) : AbstractElement {
|
||||
overridenFields[existingField, parentField] = false
|
||||
} else {
|
||||
overridenFields[existingField, parentField] = true
|
||||
if (parentField.nullable != existingField.nullable) {
|
||||
existingField.useNullableForReplace = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
overridenFields[parentField, parentField] = true
|
||||
@@ -174,4 +179,4 @@ class TypeArgumentWithMultipleUpperBounds(name: String, override val upperBounds
|
||||
}
|
||||
}
|
||||
|
||||
data class ArbitraryImportable(override val packageName: String, override val type: String) : Importable
|
||||
data class ArbitraryImportable(override val packageName: String, override val type: String) : Importable
|
||||
|
||||
+6
@@ -26,6 +26,7 @@ sealed class Field : Importable {
|
||||
open val fromDelegate: Boolean get() = false
|
||||
|
||||
open val overridenTypes: MutableSet<Importable> = mutableSetOf()
|
||||
open var useNullableForReplace: Boolean = false
|
||||
|
||||
fun copy(): Field = internalCopy().also {
|
||||
updateFieldsInCopy(it)
|
||||
@@ -39,6 +40,7 @@ sealed class Field : Importable {
|
||||
copy.needTransformInOtherChildren = needTransformInOtherChildren
|
||||
copy.isMutable = isMutable
|
||||
copy.overridenTypes += overridenTypes
|
||||
copy.useNullableForReplace = useNullableForReplace
|
||||
}
|
||||
copy.fromParent = fromParent
|
||||
}
|
||||
@@ -98,6 +100,10 @@ class FieldWithDefault(val origin: Field) : Field() {
|
||||
override val overridenTypes: MutableSet<Importable>
|
||||
get() = origin.overridenTypes
|
||||
|
||||
override var useNullableForReplace: Boolean
|
||||
get() = origin.useNullableForReplace
|
||||
set(_) {}
|
||||
|
||||
override fun internalCopy(): Field {
|
||||
return FieldWithDefault(origin).also {
|
||||
it.defaultValueInImplementation = defaultValueInImplementation
|
||||
|
||||
+3
-3
@@ -84,15 +84,15 @@ fun SmartPrinter.printElement(element: Element) {
|
||||
override()
|
||||
println("fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visit$name(this, data)")
|
||||
|
||||
fun Field.replaceDeclaration(override: Boolean, overridenType: Importable? = null) {
|
||||
fun Field.replaceDeclaration(override: Boolean, overridenType: Importable? = null, forceNullable: Boolean = false) {
|
||||
println()
|
||||
abstract()
|
||||
if (override) print("override ")
|
||||
println(replaceFunctionDeclaration(overridenType))
|
||||
println(replaceFunctionDeclaration(overridenType, forceNullable))
|
||||
}
|
||||
|
||||
allFields.filter { it.withReplace }.forEach {
|
||||
it.replaceDeclaration(overridenFields[it, it])
|
||||
it.replaceDeclaration(overridenFields[it, it], forceNullable = it.useNullableForReplace)
|
||||
for (overridenType in it.overridenTypes) {
|
||||
it.replaceDeclaration(true, overridenType)
|
||||
}
|
||||
|
||||
+11
-3
@@ -303,10 +303,15 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
|
||||
}
|
||||
}
|
||||
|
||||
fun generateReplace(field: Field, overridenType: Importable? = null, body: () -> Unit) {
|
||||
fun generateReplace(
|
||||
field: Field,
|
||||
overridenType: Importable? = null,
|
||||
forceNullable: Boolean = false,
|
||||
body: () -> Unit,
|
||||
) {
|
||||
println()
|
||||
abstract()
|
||||
print("override ${field.replaceFunctionDeclaration(overridenType)}")
|
||||
print("override ${field.replaceFunctionDeclaration(overridenType, forceNullable)}")
|
||||
if (isInterface || isAbstract) {
|
||||
println()
|
||||
return
|
||||
@@ -326,7 +331,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
|
||||
for (field in allFields.filter { it.withReplace }) {
|
||||
val capitalizedFieldName = field.name.capitalize()
|
||||
val newValue = "new$capitalizedFieldName"
|
||||
generateReplace(field) {
|
||||
generateReplace(field, forceNullable = field.useNullableForReplace) {
|
||||
when {
|
||||
field.withGetter -> {}
|
||||
|
||||
@@ -336,6 +341,9 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
|
||||
}
|
||||
|
||||
else -> {
|
||||
if (field.useNullableForReplace) {
|
||||
println("require($newValue != null)")
|
||||
}
|
||||
println("${field.name} = $newValue")
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -96,10 +96,13 @@ fun transformFunctionDeclaration(transformName: String, returnType: String): Str
|
||||
return "fun <D> transform$transformName(transformer: FirTransformer<D>, data: D): $returnType"
|
||||
}
|
||||
|
||||
fun Field.replaceFunctionDeclaration(overridenType: Importable? = null): String {
|
||||
fun Field.replaceFunctionDeclaration(overridenType: Importable? = null, forceNullable: Boolean = false): String {
|
||||
val capName = name.capitalize()
|
||||
val type = overridenType?.typeWithArguments ?: typeWithArguments
|
||||
return "fun replace$capName(new$capName: $type)"
|
||||
|
||||
val typeWithNullable = if (forceNullable && !type.endsWith("?")) "$type?" else type
|
||||
|
||||
return "fun replace$capName(new$capName: $typeWithNullable)"
|
||||
}
|
||||
|
||||
val Field.mutableType: String
|
||||
|
||||
Reference in New Issue
Block a user