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 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) is JavaTypeParameter -> createTypeParameterSymbol(session, classifier.name)
else -> return toNotNullConeKotlinType(session) else -> return toNotNullConeKotlinType(session)
@@ -198,6 +198,7 @@ class JavaClassEnhancementScope(
} }
private fun StringBuilder.appendConeType(coneType: ConeKotlinType) { private fun StringBuilder.appendConeType(coneType: ConeKotlinType) {
if (coneType is ConeClassErrorType) return
append("L") append("L")
when (coneType) { when (coneType) {
is ConeClassLikeType -> { is ConeClassLikeType -> {
@@ -110,9 +110,11 @@ internal fun generateConstantExpressionByLiteral(session: FirSession, expression
FirConstExpressionImpl( FirConstExpressionImpl(
session, expression, IrConstKind.Long, convertedText, "Incorrect long: $text" session, expression, IrConstKind.Long, convertedText, "Incorrect long: $text"
) )
} else { } else if (convertedText is Number) {
// TODO: support byte / short // 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 -> KtNodeTypes.FLOAT_CONSTANT ->
if (convertedText is Float) { if (convertedText is Float) {
@@ -175,7 +177,9 @@ internal fun IElementType.toFirOperation(): FirOperation =
else -> throw AssertionError(this.toString()) 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 subjectName = Name.special("<$caseId>")
val subjectVariable = generateTemporaryVariable(session, psi, subjectName, this) val subjectVariable = generateTemporaryVariable(session, psi, subjectName, this)
val subjectExpression = FirWhenSubjectExpression(session, psi) val subjectExpression = FirWhenSubjectExpression(session, psi)
@@ -106,6 +106,19 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
private fun KtExpression.toFirStatement(): FirStatement = private fun KtExpression.toFirStatement(): FirStatement =
convert() 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 = private fun KtExpression?.toFirBlock(): FirBlock =
when (this) { when (this) {
is KtBlockExpression -> is KtBlockExpression ->
@@ -413,14 +426,9 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
val delegatedSelfType = enumEntry.toDelegatedSelfType() val delegatedSelfType = enumEntry.toDelegatedSelfType()
val delegatedSuperType = enumEntry.extractSuperTypeListEntriesTo(firEnumEntry, delegatedSelfType) val delegatedSuperType = enumEntry.extractSuperTypeListEntriesTo(firEnumEntry, delegatedSelfType)
for (declaration in enumEntry.declarations) { for (declaration in enumEntry.declarations) {
firEnumEntry.declarations += when (declaration) { firEnumEntry.declarations += declaration.toFirDeclaration(
is KtSecondaryConstructor -> declaration.toFirConstructor( delegatedSuperType, delegatedSelfType, hasPrimaryConstructor = true
delegatedSuperType, )
delegatedSelfType,
hasPrimaryConstructor = true
)
else -> declaration.convert<FirDeclaration>()
}
} }
firEnumEntry firEnumEntry
} }
@@ -484,14 +492,9 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
} }
for (declaration in classOrObject.declarations) { for (declaration in classOrObject.declarations) {
firClass.declarations += when (declaration) { firClass.declarations += declaration.toFirDeclaration(
is KtSecondaryConstructor -> declaration.toFirConstructor( delegatedSuperType, delegatedSelfType, hasPrimaryConstructor = classOrObject.primaryConstructor != null
delegatedSuperType, )
delegatedSelfType,
classOrObject.primaryConstructor != null
)
else -> declaration.convert<FirDeclaration>()
}
} }
firClass firClass
@@ -506,7 +509,9 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
objectDeclaration.extractSuperTypeListEntriesTo(this, delegatedSelfType) objectDeclaration.extractSuperTypeListEntriesTo(this, delegatedSelfType)
for (declaration in objectDeclaration.declarations) { 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 { override fun visitQualifiedExpression(expression: KtQualifiedExpression, data: Unit): FirElement {
val selector = expression.selectorExpression val selector = expression.selectorExpression
?: return FirErrorExpressionImpl(session, expression, "Qualified expression without selector") ?: return FirErrorExpressionImpl(session, expression, "Qualified expression without selector")
val firSelector = selector.toFirExpression("Incorrect selector expression") as FirModifiableQualifiedAccess val firSelector = selector.toFirExpression("Incorrect selector expression")
firSelector.safe = expression is KtSafeQualifiedExpression if (firSelector is FirModifiableQualifiedAccess) {
firSelector.explicitReceiver = expression.receiverExpression.toFirExpression("Incorrect receiver expression") firSelector.safe = expression is KtSafeQualifiedExpression
firSelector.explicitReceiver = expression.receiverExpression.toFirExpression("Incorrect receiver expression")
}
return firSelector return firSelector
} }
@@ -106,6 +106,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker { override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
require(this is ConeLookupTagBasedType) require(this is ConeLookupTagBasedType)
if (this is ConeClassErrorType) return ErrorTypeConstructor("No constructor: $reason")
return this.lookupTag.toSymbol(session) ?: ErrorTypeConstructor("Unresolved: ${this.lookupTag}") 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 { override fun isEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
assert(c1 is ConeSymbol) if (c1 is ErrorTypeConstructor || c2 is ErrorTypeConstructor) return false
assert(c2 is ConeSymbol) require(c1 is ConeSymbol)
require(c2 is ConeSymbol)
return c1 == c2 return c1 == c2
} }