[FIR] Add stub default values to kotlin.Enum constructor parameters

This commit is contained in:
Mikhail Glukhikh
2020-02-21 09:33:44 +03:00
parent 39bd97147f
commit 81f1f441fc
4 changed files with 26 additions and 11 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.*
@@ -417,7 +418,12 @@ class Fir2IrDeclarationStorage(
declareDefaultSetterParameter(type)
} else if (function != null) {
valueParameters = function.valueParameters.mapIndexed { index, valueParameter ->
createAndSaveIrParameter(valueParameter, index).apply { this.parent = parent }
createAndSaveIrParameter(
valueParameter, index,
useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum")
).apply {
this.parent = parent
}
}
}
if (function !is FirConstructor) {
@@ -739,7 +745,11 @@ class Fir2IrDeclarationStorage(
}
}
private fun createAndSaveIrParameter(valueParameter: FirValueParameter, index: Int = -1): IrValueParameter {
private fun createAndSaveIrParameter(
valueParameter: FirValueParameter,
index: Int = -1,
useStubForDefaultValueStub: Boolean = true
): IrValueParameter {
val descriptor = WrappedValueParameterDescriptor()
val origin = IrDeclarationOrigin.DEFINED
val type = valueParameter.returnTypeRef.toIrType(session, this)
@@ -755,7 +765,10 @@ class Fir2IrDeclarationStorage(
valueParameter.isCrossinline, valueParameter.isNoinline
).apply {
descriptor.bind(this)
if (valueParameter.defaultValue != null) {
if (valueParameter.defaultValue.let {
it != null && (useStubForDefaultValueStub || it !is FirExpressionStub)
}
) {
this.defaultValue = IrExpressionBodyImpl(
IrErrorExpressionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, type,
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.*
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
@@ -271,7 +272,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
this.symbol = symbol
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
this.typeParameters += typeParameters
valueParameters += local.memberDeserializer.valueParameters(proto.valueParameterList)
valueParameters += local.memberDeserializer.valueParameters(
proto.valueParameterList, addDefaultValue = classBuilder.symbol.classId == StandardClassIds.Enum
)
annotations += local.annotationDeserializer.loadConstructorAnnotations(proto, local.nameResolver)
}.build()
}
@@ -284,7 +287,8 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
}
private fun valueParameters(
valueParameters: List<ProtoBuf.ValueParameter>
valueParameters: List<ProtoBuf.ValueParameter>,
addDefaultValue: Boolean = false
): List<FirValueParameter> {
return valueParameters.map { proto ->
val flags = if (proto.hasFlags()) proto.flags else 0
@@ -295,6 +299,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
this.name = name
symbol = FirVariableSymbol(name)
defaultValue = defaultValue(flags)
if (addDefaultValue) {
defaultValue = buildExpressionStub()
}
isCrossinline = Flags.IS_CROSSINLINE.get(flags)
isNoinline = Flags.IS_NOINLINE.get(flags)
isVararg = proto.varargElementType(c.typeTable) != null
@@ -157,11 +157,6 @@ internal object MapArguments : ResolutionStage() {
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportApplicability(CandidateApplicability.HIDDEN)
val function = symbol.fir
if (function is FirConstructor && function.returnTypeRef.isEnum) {
// NB: we do not check kotlin.Enum constructor calls, because we do not pass arguments there
candidate.argumentMapping = mapOf()
return
}
val mapping = mapArguments(callInfo.arguments, function)
val argumentToParameterMapping = mutableMapOf<FirExpression, FirValueParameter>()
+1 -1
View File
@@ -515,7 +515,7 @@ public abstract class Enum<E> : R|kotlin/Comparable<E>| {
public final val ordinal: R|kotlin/Int|
public get(): R|kotlin/Int|
public constructor<E>(name: R|kotlin/String|, ordinal: R|kotlin/Int|): R|kotlin/Enum<E>|
public constructor<E>(name: R|kotlin/String| = STUB, ordinal: R|kotlin/Int| = STUB): R|kotlin/Enum<E>|
public final companion object Companion : R|kotlin/Any| {
private constructor(): R|kotlin/Enum.Companion|