[FIR] Require not-null source in buildImplicitTypeRef

KT-56906
This commit is contained in:
Kirill Rakhman
2023-03-02 17:44:04 +01:00
committed by Space Team
parent 04d57eb2f9
commit 81f858a3c4
14 changed files with 48 additions and 39 deletions
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImplWithoutSource
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -94,9 +94,7 @@ internal fun generateTemporaryVariable(
this.source = source
this.moduleData = moduleData
origin = FirDeclarationOrigin.Source
returnTypeRef = typeRef ?: buildImplicitTypeRef {
this.source = source
}
returnTypeRef = typeRef ?: FirImplicitTypeRefImplWithoutSource
this.name = name
this.initializer = initializer
symbol = FirPropertySymbol(name)
@@ -240,9 +240,7 @@ open class RawFirBuilder(
valueParameter.toFirValueParameter(defaultTypeRef, functionSymbol, valueParameterDeclaration, additionalAnnotations)
private fun KtTypeReference?.toFirOrImplicitType(): FirTypeRef =
convertSafe() ?: buildImplicitTypeRef {
source = this@toFirOrImplicitType?.toFirSourceElement(KtFakeSourceElementKind.ImplicitTypeRef)
}
this?.toFirOrErrorType() ?: FirImplicitTypeRefImplWithoutSource
private fun KtTypeReference?.toFirOrUnitType(): FirTypeRef =
convertSafe() ?: implicitUnitType
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.fir.visitors.*
@FirBuilderDsl
class FirImplicitTypeRefBuilder {
var source: KtSourceElement? = null
lateinit var source: KtSourceElement
fun build(): FirImplicitTypeRef {
return FirImplicitTypeRefImpl(
@@ -34,7 +34,7 @@ class FirImplicitTypeRefBuilder {
}
@OptIn(ExperimentalContracts::class)
inline fun buildImplicitTypeRef(init: FirImplicitTypeRefBuilder.() -> Unit = {}): FirImplicitTypeRef {
inline fun buildImplicitTypeRef(init: FirImplicitTypeRefBuilder.() -> Unit): FirImplicitTypeRef {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
@@ -42,11 +42,11 @@ inline fun buildImplicitTypeRef(init: FirImplicitTypeRefBuilder.() -> Unit = {})
}
@OptIn(ExperimentalContracts::class)
inline fun buildImplicitTypeRefCopy(original: FirImplicitTypeRef, init: FirImplicitTypeRefBuilder.() -> Unit = {}): FirImplicitTypeRef {
inline fun buildImplicitTypeRefCopy(original: FirImplicitTypeRef, init: FirImplicitTypeRefBuilder.() -> Unit): FirImplicitTypeRef {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
val copyBuilder = FirImplicitTypeRefBuilder()
copyBuilder.source = original.source
original.source?.let { copyBuilder.source = it }
return copyBuilder.apply(init).build()
}
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
*/
internal class FirImplicitTypeRefImpl(
override val source: KtSourceElement?,
override val source: KtSourceElement,
) : FirImplicitTypeRef() {
override val annotations: List<FirAnnotation> get() = emptyList()
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImplWithoutSource
import org.jetbrains.kotlin.name.Name
fun FirVariable.toQualifiedAccess(
@@ -51,9 +52,7 @@ fun generateTemporaryVariable(
this.source = source
this.moduleData = moduleData
origin = FirDeclarationOrigin.Source
returnTypeRef = typeRef ?: buildImplicitTypeRef {
this.source = source
}
returnTypeRef = typeRef ?: FirImplicitTypeRefImplWithoutSource
this.name = name
this.initializer = initializer
symbol = FirPropertySymbol(name)
@@ -52,9 +52,9 @@ fun <R : FirTypeRef> R.copyWithNewSource(newSource: KtSourceElement?): R {
qualifier += typeRef.qualifier
annotations += typeRef.annotations
}
is FirImplicitTypeRef -> buildImplicitTypeRefCopy(typeRef) {
source = newSource
}
is FirImplicitTypeRef -> newSource?.let {
buildImplicitTypeRefCopy(typeRef) { source = it }
} ?: FirImplicitTypeRefImplWithoutSource
is FirFunctionTypeRefImpl -> buildFunctionTypeRefCopy(typeRef) {
source = newSource
}
@@ -482,6 +482,9 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
impl(functionTypeRef)
impl(implicitTypeRef) {
defaultEmptyList("annotations")
default("source") {
notNull = true
}
}
impl(reference, "FirStubReference") {
@@ -69,9 +69,11 @@ abstract class AbstractBuilderConfigurator<T : AbstractFirTreeBuilder>(val firTr
inner class DefaultValueContext(private val field: FieldWithDefault) {
var value: String? = null
var notNull: Boolean? = null
fun applyConfiguration() {
if (value != null) field.defaultValueInBuilder = value
if (notNull != null) field.notNull = notNull!!
}
}
}
@@ -217,11 +217,17 @@ abstract class AbstractFirTreeImplementationConfigurator {
var needAcceptAndTransform: Boolean = true
var notNull: Boolean = false
fun applyConfiguration() {
field.withGetter = withGetter
field.customSetter = customSetter
isMutable?.let { field.isMutable = it }
field.needAcceptAndTransform = needAcceptAndTransform
if (notNull) {
field.notNull = true
}
when {
value != null -> field.defaultValueInImplementation = value
delegate != null -> {
@@ -30,6 +30,7 @@ sealed class Field : Importable {
open val overridenTypes: MutableSet<Importable> = mutableSetOf()
open var useNullableForReplace: Boolean = false
open var notNull: Boolean = false
var withBindThis = true
@@ -129,7 +129,7 @@ private fun SmartPrinter.printBuilder(builder: Builder) {
private val String.nullable: String get() = if (endsWith("?")) this else "$this?"
private fun FieldWithDefault.needBackingField(fieldIsUseless: Boolean) = !nullable && origin !is FieldList && if (fieldIsUseless) {
private fun FieldWithDefault.needBackingField(fieldIsUseless: Boolean) = (!nullable || notNull) && origin !is FieldList && if (fieldIsUseless) {
defaultValueInImplementation == null
} else {
defaultValueInBuilder == null
@@ -145,7 +145,7 @@ private fun SmartPrinter.printFieldInBuilder(field: FieldWithDefault, builder: B
return true to false
}
val name = field.name
val type = field.typeWithArguments
val type = field.getTypeWithArguments(field.notNull)
val defaultValue = if (fieldIsUseless)
field.defaultValueInImplementation.also { requireNotNull(it) }
else
@@ -305,6 +305,7 @@ private fun SmartPrinter.printDslBuildCopyFunction(
when {
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.notNull -> println("original.${field.name}?.let { copyBuilder.${field.name} = it }")
else -> println("copyBuilder.${field.name} = original.${field.name}")
}
}
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.tree.generator.model.SimpleField
import org.jetbrains.kotlin.util.SmartPrinter
fun SmartPrinter.printField(field: Field, isImplementation: Boolean, override: Boolean, end: String) {
fun SmartPrinter.printField(field: Field, isImplementation: Boolean, override: Boolean, end: String, notNull: Boolean = false) {
if (isImplementation && !field.isVal && field.isVolatile) {
println("@Volatile")
}
@@ -22,7 +22,7 @@ fun SmartPrinter.printField(field: Field, isImplementation: Boolean, override: B
} else {
print("var")
}
val type = if (isImplementation) field.getMutableType() else field.typeWithArguments
val type = if (isImplementation) field.getMutableType(notNull = notNull) else field.getTypeWithArguments(notNull = notNull)
println(" ${field.name}: $type$end")
}
@@ -77,7 +77,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
withIndent {
fieldsWithoutDefault.forEachIndexed { _, field ->
printField(field, isImplementation = true, override = true, end = ",")
printField(field, isImplementation = true, override = true, end = ",", notNull = field.notNull)
}
}
print(")")
@@ -94,7 +94,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
allFields.forEach {
abstract()
printField(it, isImplementation = true, override = true, end = "")
printField(it, isImplementation = true, override = true, end = "", notNull = it.notNull)
}
} else {
fieldsWithDefault.forEach {
@@ -122,14 +122,14 @@ fun Field.replaceFunctionDeclaration(overridenType: Importable? = null, forceNul
return "fun replace$capName(new$capName: $typeWithNullable)"
}
fun Field.getMutableType(forBuilder: Boolean = false): String = when (this) {
fun Field.getMutableType(forBuilder: Boolean = false, notNull: Boolean = false): String = when (this) {
is FieldList -> when {
isMutableOrEmpty && !forBuilder -> "MutableOrEmpty$typeWithArguments"
isMutable -> "Mutable$typeWithArguments"
else -> typeWithArguments
}
is FieldWithDefault -> if (isMutable) origin.getMutableType() else typeWithArguments
else -> typeWithArguments
is FieldWithDefault -> if (isMutable) origin.getMutableType(notNull) else getTypeWithArguments(notNull)
else -> getTypeWithArguments(notNull)
}
fun Field.call(): String = if (nullable) "?." else "."
@@ -151,18 +151,19 @@ fun Kind?.braces(): String = when (this) {
val Element.safeDecapitalizedName: String get() = if (name == "Class") "klass" else name.replaceFirstChar(Char::lowercaseChar)
val Importable.typeWithArguments: String
get() = when (this) {
is AbstractElement -> type + generics
is Implementation -> type + element.generics
is FirField -> element.typeWithArguments + if (nullable) "?" else ""
is Field -> type + generics + if (nullable) "?" else ""
is Type -> type + generics
is ImplementationWithArg -> type + generics
is LeafBuilder -> type + implementation.element.generics
is IntermediateBuilder -> type
else -> throw IllegalArgumentException()
}
val Importable.typeWithArguments: String get() = getTypeWithArguments()
fun Importable.getTypeWithArguments(notNull: Boolean = false): String = when (this) {
is AbstractElement -> type + generics
is Implementation -> type + element.generics
is FirField -> element.getTypeWithArguments(notNull) + if (nullable && !notNull) "?" else ""
is Field -> type + generics + if (nullable && !notNull) "?" else ""
is Type -> type + generics
is ImplementationWithArg -> type + generics
is LeafBuilder -> type + implementation.element.generics
is IntermediateBuilder -> type
else -> throw IllegalArgumentException()
}
val ImplementationWithArg.generics: String
get() = argument?.let { "<${it.type}>" } ?: ""