[FIR] Use super<Enum> as delegated calls in enum constructors

This commit is contained in:
Mikhail Glukhikh
2020-02-19 13:32:49 +03:00
parent f173af9238
commit b1e9dbf994
35 changed files with 96 additions and 52 deletions
@@ -410,12 +410,18 @@ class Fir2IrVisitor(
?: return null
return convertWithOffsets { startOffset, endOffset ->
val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol
if (constructorSymbol.fir.isFromEnumClass) {
if (constructorSymbol.fir.isFromEnumClass || constructorSymbol.fir.returnTypeRef.isEnum) {
IrEnumConstructorCallImpl(
startOffset, endOffset,
constructedIrType,
irConstructorSymbol
)
).apply {
val typeArguments = (constructedTypeRef as? FirResolvedTypeRef)?.type?.typeArguments
if (typeArguments?.isNotEmpty() == true) {
val irType = (typeArguments.first() as ConeTypedProjection).type.toIrType(session, declarationStorage, irBuiltIns)
putTypeArgument(0, irType)
}
}
} else {
IrDelegatingConstructorCallImpl(
startOffset, endOffset,
@@ -398,13 +398,14 @@ class DeclarationsConverter(
when {
modifiers.isEnum() && (classKind == ClassKind.ENUM_CLASS) -> {
superTypeRefs += buildResolvedTypeRef {
delegatedSuperTypeRef = buildResolvedTypeRef {
type = ConeClassLikeTypeImpl(
implicitEnumType.type.lookupTag,
arrayOf(selfType.coneTypeUnsafe()),
isNullable = false
)
}
superTypeRefs += delegatedSuperTypeRef!!
}
modifiers.isAnnotation() && (classKind == ClassKind.ANNOTATION_CLASS) -> {
superTypeRefs += implicitAnnotationType
@@ -408,13 +408,14 @@ class RawFirBuilder(
* for correct resolve of super constructor call or just call kotlin.Any constructor
* and convert it to right call at backend, because of it doesn't affects frontend work
*/
container.superTypeRefs += buildResolvedTypeRef {
delegatedSuperTypeRef = buildResolvedTypeRef {
type = ConeClassLikeTypeImpl(
implicitEnumType.type.lookupTag,
delegatedSelfTypeRef?.coneTypeUnsafe<ConeKotlinType>()?.let { arrayOf(it) } ?: emptyArray(),
isNullable = false,
)
}
container.superTypeRefs += delegatedSuperTypeRef
}
this is KtClass && classKind == ClassKind.ANNOTATION_CLASS -> {
container.superTypeRefs += implicitAnnotationType
@@ -26,7 +26,7 @@ FILE: annotation.kt
}
@base() public? final? enum class My : R|kotlin/Enum<My>| {
private constructor(): R|My| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<My>|>()
}
public final static enum entry FIRST: R|My| = @base() object : R|My| {
@@ -10,7 +10,7 @@ FILE: constructorInObject.kt
}
public? final? enum class B : R|kotlin/Enum<B>| {
private constructor(): R|B| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<B>|>()
}
public final static enum entry X: R|B| = object : R|B| {
@@ -1,7 +1,7 @@
FILE: enums.kt
public? final? enum class Order : R|kotlin/Enum<Order>| {
private constructor(): R|Order| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<Order>|>()
}
public final static enum entry FIRST: R|Order| = object : R|Order| {
@@ -34,7 +34,7 @@ FILE: enums.kt
}
public? final? enum class Planet : R|kotlin/Enum<Planet>| {
public? constructor(m: Double, r: Double): R|Planet| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<Planet>|>()
}
public? final? val m: Double = R|<local>/m|
@@ -15,7 +15,7 @@ FILE: enums2.kt
}
public? final? enum class SomeEnum : R|kotlin/Enum<SomeEnum>| {
public? constructor(x: Some): R|SomeEnum| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<SomeEnum>|>()
}
public? final? val x: Some = R|<local>/x|
@@ -157,6 +157,11 @@ 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
@@ -15,7 +15,7 @@ FILE: enum.kt
}
public final enum class SomeEnum : R|kotlin/Enum<SomeEnum>| {
private constructor(x: R|Some|): R|SomeEnum| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<SomeEnum>|>()
}
public final val x: R|Some| = R|<local>/x|
@@ -1,7 +1,7 @@
FILE: enumWithCompanion.kt
public final enum class EC : R|kotlin/Enum<EC>| {
private constructor(): R|EC| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<EC>|>()
}
public final static enum entry A: R|EC| = object : R|EC| {
@@ -1,7 +1,7 @@
FILE: main.kt
public final enum class E : R|kotlin/Enum<E>| {
private constructor(): R|E| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<E>|>()
}
public final static enum entry A: R|E| = object : R|E| {
@@ -1,7 +1,7 @@
FILE: exhaustiveness_enum.kt
public final enum class Enum : R|kotlin/Enum<Enum>| {
private constructor(): R|Enum| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<Enum>|>()
}
public final static enum entry A: R|Enum| = object : R|Enum| {
@@ -1,7 +1,7 @@
FILE: enumEntryUse.kt
public final enum class TestEnum : R|kotlin/Enum<TestEnum>| {
private constructor(): R|TestEnum| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<TestEnum>|>()
}
public final static enum entry FIRST: R|TestEnum| = object : R|TestEnum| {
@@ -1,7 +1,7 @@
FILE: enumValues.kt
public final enum class MyEnum : R|kotlin/Enum<MyEnum>| {
private constructor(): R|MyEnum| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<MyEnum>|>()
}
public final static enum entry FIRST: R|MyEnum| = object : R|MyEnum| {
@@ -30,7 +30,7 @@ FILE: qualifiedExpressions.kt
}
public final enum class E : R|kotlin/Enum<a/b/E>| {
private constructor(): R|a/b/E| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<a/b/E>|>()
}
public final static enum entry entry: R|a/b/E| = object : R|a/b/E| {
@@ -63,7 +63,7 @@ FILE: qualifierPriority.kt
public get(): R|kotlin/Unit|
public final enum class G : R|kotlin/Enum<G>| {
private constructor(): R|G| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<G>|>()
}
public final static enum entry H: R|G| = object : R|G| {
@@ -1,7 +1,7 @@
FILE: enums.kt
public final enum class Order : R|kotlin/Enum<Order>| {
private constructor(): R|Order| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<Order>|>()
}
public final static enum entry FIRST: R|Order| = object : R|Order| {
@@ -34,7 +34,7 @@ FILE: enums.kt
}
public final enum class Planet : R|kotlin/Enum<Planet>| {
private constructor(m: R|kotlin/Double|, r: R|kotlin/Double|): R|Planet| {
super<R|kotlin/Any|>()
super<R|kotlin/Enum<Planet>|>()
}
public final val m: R|kotlin/Double| = R|<local>/m|
@@ -21,6 +21,7 @@ val FirTypeRef.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing
val FirTypeRef.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true)
val FirTypeRef.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false)
val FirTypeRef.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false)
val FirTypeRef.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
private fun FirTypeRef.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
val type = when (this) {