[FIR] Add exhaustive checker for when expressions

Also remove generating default else branch introduced in 38fa0122 and 54eb4cf9
This commit is contained in:
Dmitriy Novozhilov
2019-10-15 12:52:02 +03:00
parent 25e853606e
commit f19a878948
93 changed files with 5003 additions and 5464 deletions
@@ -41,15 +41,15 @@ abstract class FirSession(val sessionProvider: FirSessionProvider?) {
}
class BuiltinTypes {
val unitType: FirTypeRef = FirImplicitUnitTypeRef(null)
val anyType: FirTypeRef = FirImplicitAnyTypeRef(null)
val nullableAnyType: FirTypeRef = FirImplicitNullableAnyTypeRef(null)
val enumType: FirTypeRef = FirImplicitEnumTypeRef(null)
val annotationType: FirTypeRef = FirImplicitAnnotationTypeRef(null)
val booleanType: FirTypeRef = FirImplicitBooleanTypeRef(null)
val nothingType: FirTypeRef = FirImplicitNothingTypeRef(null)
val nullableNothingType: FirTypeRef = FirImplicitNullableNothingTypeRef(null)
val stringType: FirTypeRef = FirImplicitStringTypeRef(null)
val unitType: FirImplicitBuiltinTypeRef = FirImplicitUnitTypeRef(null)
val anyType: FirImplicitBuiltinTypeRef = FirImplicitAnyTypeRef(null)
val nullableAnyType: FirImplicitBuiltinTypeRef = FirImplicitNullableAnyTypeRef(null)
val enumType: FirImplicitBuiltinTypeRef = FirImplicitEnumTypeRef(null)
val annotationType: FirImplicitBuiltinTypeRef = FirImplicitAnnotationTypeRef(null)
val booleanType: FirImplicitBuiltinTypeRef = FirImplicitBooleanTypeRef(null)
val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null)
val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null)
val stringType: FirImplicitBuiltinTypeRef = FirImplicitStringTypeRef(null)
}
interface FirSessionProvider {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.declarations
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.declarations.impl.FirEnumEntryImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirModifiableRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
@@ -59,4 +60,9 @@ val FirTypeAlias.expandedConeType: ConeClassLikeType? get() = expandedTypeRef.co
val FirRegularClass.classId get() = symbol.classId
val FirClass.superConeTypes get() = superTypeRefs.mapNotNull { it.coneTypeSafe<ConeClassLikeType>() }
val FirClass.superConeTypes get() = superTypeRefs.mapNotNull { it.coneTypeSafe<ConeClassLikeType>() }
fun FirRegularClass.collectEnumEntries(): Collection<FirEnumEntry> {
assert(classKind == ClassKind.ENUM_CLASS)
return declarations.filterIsInstance<FirEnumEntry>()
}
@@ -24,9 +24,12 @@ interface FirWhenExpression : FirExpression, FirResolvable {
val subject: FirExpression?
val subjectVariable: FirVariable<*>?
val branches: List<FirWhenBranch>
val isExhaustive: Boolean
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitWhenExpression(this, data)
fun replaceIsExhaustive(newIsExhaustive: Boolean)
override fun <D> transformCalleeReference(transformer: FirTransformer<D>, data: D): FirWhenExpression
fun <D> transformSubject(transformer: FirTransformer<D>, data: D): FirWhenExpression
@@ -32,6 +32,7 @@ class FirWhenExpressionImpl(
override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
override var calleeReference: FirReference = FirStubReference()
override val branches: MutableList<FirWhenBranch> = mutableListOf()
override var isExhaustive: Boolean = false
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
@@ -81,4 +82,8 @@ class FirWhenExpressionImpl(
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
typeRef = newTypeRef
}
override fun replaceIsExhaustive(newIsExhaustive: Boolean) {
isExhaustive = newIsExhaustive
}
}
@@ -425,6 +425,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
impl(whenExpression) {
default("calleeReference", "FirStubReference()")
defaultFalse("isExhaustive")
useTypes(stubReferenceType)
}
@@ -500,6 +500,7 @@ object NodeConfigurator : AbstractFieldConfigurator() {
+field("subject", expression, nullable = true).withTransform()
+field("subjectVariable", variable.withArgs("F" to "*"), nullable = true)
+fieldList("branches", whenBranch).withTransform()
+booleanField("isExhaustive", withReplace = true)
needTransformOtherChildren()
}