From d65b30dd8251c3cca5d58741a68806fbecc8edd9 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 14 Mar 2019 16:43:36 +0300 Subject: [PATCH] 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 --- .../fir/java/enhancement/javaTypeUtils.kt | 4 +- .../java/scopes/JavaClassEnhancementScope.kt | 1 + .../kotlin/fir/builder/ConversionUtils.kt | 10 ++-- .../kotlin/fir/builder/RawFirBuilder.kt | 47 +++++++++++-------- .../kotlin/fir/types/ConeTypeContext.kt | 6 ++- 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index 21175ba89d3..663372d3940 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -146,7 +146,9 @@ private fun JavaClassifierType.enhanceInflexibleType( mappedId = mappedId.readOnlyToMutable() ?: mappedId } } - session.service().getClassLikeSymbolByFqName(mappedId ?: classId)!! + val kotlinClassId = mappedId ?: classId + session.service().getClassLikeSymbolByFqName(kotlinClassId) + ?: return ConeClassErrorType("Cannot find class-like symbol for $kotlinClassId during enhancement") } is JavaTypeParameter -> createTypeParameterSymbol(session, classifier.name) else -> return toNotNullConeKotlinType(session) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt index 5f69861799a..a65f00f4ad9 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt @@ -198,6 +198,7 @@ class JavaClassEnhancementScope( } private fun StringBuilder.appendConeType(coneType: ConeKotlinType) { + if (coneType is ConeClassErrorType) return append("L") when (coneType) { is ConeClassLikeType -> { diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index 75fce496618..f0e8b9aac44 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -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) diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index acec5a8b5b6..982d0b69fdd 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -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() + } + } + 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() - } + 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() - } + 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() + 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 } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index f8cc6388e4f..951a9fcf96c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -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 }