Fix corner-cases in ConeTypeContext / FIR builder / FIR enhancements

This fixes a pack of FIR smoke diagnostic tests, now all of them pass
Related to KT-29962
This commit is contained in:
Mikhail Glukhikh
2019-03-14 16:43:36 +03:00
parent 8ea347653b
commit d65b30dd82
5 changed files with 42 additions and 26 deletions
@@ -146,7 +146,9 @@ private fun JavaClassifierType.enhanceInflexibleType(
mappedId = mappedId.readOnlyToMutable() ?: mappedId
}
}
session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(mappedId ?: classId)!!
val kotlinClassId = mappedId ?: classId
session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(kotlinClassId)
?: return ConeClassErrorType("Cannot find class-like symbol for $kotlinClassId during enhancement")
}
is JavaTypeParameter -> createTypeParameterSymbol(session, classifier.name)
else -> return toNotNullConeKotlinType(session)
@@ -198,6 +198,7 @@ class JavaClassEnhancementScope(
}
private fun StringBuilder.appendConeType(coneType: ConeKotlinType) {
if (coneType is ConeClassErrorType) return
append("L")
when (coneType) {
is ConeClassLikeType -> {
@@ -110,9 +110,11 @@ internal fun generateConstantExpressionByLiteral(session: FirSession, expression
FirConstExpressionImpl(
session, expression, IrConstKind.Long, convertedText, "Incorrect long: $text"
)
} else {
} else if (convertedText is Number) {
// TODO: support byte / short
FirConstExpressionImpl(session, expression, IrConstKind.Int, (convertedText as Number).toInt(), "Incorrect int: $text")
FirConstExpressionImpl(session, expression, IrConstKind.Int, convertedText.toInt(), "Incorrect int: $text")
} else {
FirErrorExpressionImpl(session, expression, reason = "Incorrect constant expression: $text")
}
KtNodeTypes.FLOAT_CONSTANT ->
if (convertedText is Float) {
@@ -175,7 +177,9 @@ internal fun IElementType.toFirOperation(): FirOperation =
else -> throw AssertionError(this.toString())
}
internal fun FirExpression.generateNotNullOrOther(session: FirSession, other: FirExpression, caseId: String, basePsi: KtElement): FirWhenExpression {
internal fun FirExpression.generateNotNullOrOther(
session: FirSession, other: FirExpression, caseId: String, basePsi: KtElement
): FirWhenExpression {
val subjectName = Name.special("<$caseId>")
val subjectVariable = generateTemporaryVariable(session, psi, subjectName, this)
val subjectExpression = FirWhenSubjectExpression(session, psi)
@@ -106,6 +106,19 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
private fun KtExpression.toFirStatement(): FirStatement =
convert()
private fun KtDeclaration.toFirDeclaration(
delegatedSuperType: FirTypeRef?, delegatedSelfType: FirTypeRef, hasPrimaryConstructor: Boolean
): FirDeclaration {
return when (this) {
is KtSecondaryConstructor -> toFirConstructor(
delegatedSuperType,
delegatedSelfType,
hasPrimaryConstructor
)
else -> convert<FirDeclaration>()
}
}
private fun KtExpression?.toFirBlock(): FirBlock =
when (this) {
is KtBlockExpression ->
@@ -413,14 +426,9 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
val delegatedSelfType = enumEntry.toDelegatedSelfType()
val delegatedSuperType = enumEntry.extractSuperTypeListEntriesTo(firEnumEntry, delegatedSelfType)
for (declaration in enumEntry.declarations) {
firEnumEntry.declarations += when (declaration) {
is KtSecondaryConstructor -> declaration.toFirConstructor(
delegatedSuperType,
delegatedSelfType,
hasPrimaryConstructor = true
)
else -> declaration.convert<FirDeclaration>()
}
firEnumEntry.declarations += declaration.toFirDeclaration(
delegatedSuperType, delegatedSelfType, hasPrimaryConstructor = true
)
}
firEnumEntry
}
@@ -484,14 +492,9 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
}
for (declaration in classOrObject.declarations) {
firClass.declarations += when (declaration) {
is KtSecondaryConstructor -> declaration.toFirConstructor(
delegatedSuperType,
delegatedSelfType,
classOrObject.primaryConstructor != null
)
else -> declaration.convert<FirDeclaration>()
}
firClass.declarations += declaration.toFirDeclaration(
delegatedSuperType, delegatedSelfType, hasPrimaryConstructor = classOrObject.primaryConstructor != null
)
}
firClass
@@ -506,7 +509,9 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
objectDeclaration.extractSuperTypeListEntriesTo(this, delegatedSelfType)
for (declaration in objectDeclaration.declarations) {
declarations += declaration.convert<FirDeclaration>()
declarations += declaration.toFirDeclaration(
delegatedSuperType = null, delegatedSelfType = delegatedSelfType, hasPrimaryConstructor = false
)
}
}
}
@@ -1278,9 +1283,11 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
override fun visitQualifiedExpression(expression: KtQualifiedExpression, data: Unit): FirElement {
val selector = expression.selectorExpression
?: return FirErrorExpressionImpl(session, expression, "Qualified expression without selector")
val firSelector = selector.toFirExpression("Incorrect selector expression") as FirModifiableQualifiedAccess
firSelector.safe = expression is KtSafeQualifiedExpression
firSelector.explicitReceiver = expression.receiverExpression.toFirExpression("Incorrect receiver expression")
val firSelector = selector.toFirExpression("Incorrect selector expression")
if (firSelector is FirModifiableQualifiedAccess) {
firSelector.safe = expression is KtSafeQualifiedExpression
firSelector.explicitReceiver = expression.receiverExpression.toFirExpression("Incorrect receiver expression")
}
return firSelector
}
@@ -106,6 +106,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
require(this is ConeLookupTagBasedType)
if (this is ConeClassErrorType) return ErrorTypeConstructor("No constructor: $reason")
return this.lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: ${this.lookupTag}")
}
@@ -214,8 +215,9 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
}
override fun isEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
assert(c1 is ConeSymbol)
assert(c2 is ConeSymbol)
if (c1 is ErrorTypeConstructor || c2 is ErrorTypeConstructor) return false
require(c1 is ConeSymbol)
require(c2 is ConeSymbol)
return c1 == c2
}