[IR generator] Better support for fields' default value in base classes

- Allows using those with the incoming IR implementation printer.
- Moves the logic to common tree generator, so other trees can specify
default values in base classes as well, if needed.

^KT-65773 In Progress
This commit is contained in:
Wojciech Litewka
2024-02-15 19:11:25 +01:00
committed by Space Team
parent 288351d733
commit 4d9d1974ec
9 changed files with 56 additions and 30 deletions
@@ -52,14 +52,15 @@ abstract class AbstractElementPrinter<Element : AbstractElement<Element, Field,
withIndent {
for (field in filterFields(element)) {
if (field.isParameter) continue
if (!field.withGetter && field.defaultValueInImplementation == null && field.isFinal && field.fromParent) {
if (!field.withGetter && field.defaultValueInImplementation == null && field.defaultValueInBase == null && field.isFinal && field.fromParent) {
continue
}
if (separateFieldsWithBlankLine) println()
fieldPrinter.printField(
field,
inImplementation = false,
override = field.fromParent,
modality = Modality.ABSTRACT.takeIf { !field.isFinal && !kind.isInterface },
modality = Modality.ABSTRACT.takeIf { !field.isFinal && !kind.isInterface && field.defaultValueInBase == null },
)
}
printAdditionalMethods(element)
@@ -49,6 +49,7 @@ abstract class AbstractField<Field : AbstractField<Field>> {
open val containsElement: Boolean
get() = typeRef is ElementOrRef<*> || this is ListField && baseType is ElementOrRef<*>
open val defaultValueInBase: String? get() = null
open val defaultValueInImplementation: String? get() = null
/**
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.generators.tree
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.generators.tree.printer.VariableKind
import org.jetbrains.kotlin.generators.tree.printer.printBlock
import org.jetbrains.kotlin.generators.tree.printer.printKDoc
import org.jetbrains.kotlin.generators.tree.printer.printPropertyDeclaration
import org.jetbrains.kotlin.generators.tree.printer.printKDoc
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent
@@ -33,12 +33,13 @@ abstract class AbstractFieldPrinter<Field : AbstractField<*>>(
context(ImportCollector)
fun printField(
field: Field,
inImplementation: Boolean,
override: Boolean,
inConstructor: Boolean = false,
modality: Modality? = null,
) {
printer.run {
val defaultValue = field.defaultValueInImplementation
val defaultValue = if (inImplementation) field.defaultValueInImplementation else field.defaultValueInBase
printPropertyDeclaration(
name = field.name,
type = actualTypeOfField(field),
@@ -47,8 +48,8 @@ abstract class AbstractFieldPrinter<Field : AbstractField<*>>(
visibility = field.visibility,
modality = modality,
override = override,
isLateinit = field.isLateinit,
isVolatile = field.isVolatile,
isLateinit = (inImplementation || field.isFinal) && field.isLateinit,
isVolatile = (inImplementation || field.isFinal) && field.isVolatile,
optInAnnotation = field.optInAnnotation,
printOptInWrapped = defaultValue != null,
deprecation = field.deprecation,
@@ -68,11 +68,12 @@ abstract class AbstractImplementation<Implementation, Element, Field>(
return allFields.firstOrNull { it.name == fieldName }
}
private fun withDefault(field: Field) = !field.isFinal && (field.defaultValueInImplementation != null || field.isLateinit)
private fun withDefault(field: Field) =
!field.isFinal && (field.defaultValueInImplementation != null || field.defaultValueInBase != null || field.isLateinit)
val fieldsInConstructor by lazy { allFields.filterNot(::withDefault) }
val fieldsInBody by lazy { allFields.filter(::withDefault) }
val fieldsInBody by lazy { allFields.filter(::withDefault).filter { it.defaultValueInBase == null } }
var requiresOptIn = false
@@ -28,7 +28,8 @@ abstract class AbstractImplementationPrinter<Implementation, Element, Implementa
protected abstract fun makeFieldPrinter(printer: SmartPrinter): AbstractFieldPrinter<ImplementationField>
context(ImportCollector)
protected open fun SmartPrinter.printAdditionalMethods(implementation: Implementation) {}
protected open fun SmartPrinter.printAdditionalMethods(implementation: Implementation) {
}
context(ImportCollector)
fun printImplementation(implementation: Implementation) {
@@ -72,7 +73,7 @@ abstract class AbstractImplementationPrinter<Implementation, Element, Implementa
print(field.name, ": ", field.typeRef.render())
println(",")
} else if (!field.isFinal) {
fieldPrinter.printField(field, override = true, inConstructor = true)
fieldPrinter.printField(field, inImplementation = true, override = true, inConstructor = true)
}
}
}
@@ -87,11 +88,20 @@ abstract class AbstractImplementationPrinter<Implementation, Element, Implementa
printBlock {
if (isInterface || isAbstract) {
implementation.allFields.forEach {
fieldPrinter.printField(it, override = true, modality = Modality.ABSTRACT.takeIf { isAbstract })
fieldPrinter.printField(
it,
inImplementation = true,
override = true,
modality = Modality.ABSTRACT.takeIf { isAbstract }
)
}
} else {
implementation.fieldsInBody.forEach {
fieldPrinter.printField(it, override = true)
fieldPrinter.printField(
it,
inImplementation = true,
override = true
)
}
}