[FIR] Add meaningful diagnostics in all error elements

This commit is contained in:
Dmitriy Novozhilov
2019-10-31 13:00:28 +03:00
parent 7503449e8d
commit a501e514c9
13 changed files with 97 additions and 36 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
@@ -261,7 +262,7 @@ private fun JavaAnnotationArgument.toFirExpression(
null null
} }
this.calleeReference = calleeReference this.calleeReference = calleeReference
?: FirErrorNamedReferenceImpl(null, FirSimpleDiagnostic("Strange Java enum value: $classId.$entryName")) ?: FirErrorNamedReferenceImpl(null, FirSimpleDiagnostic("Strange Java enum value: $classId.$entryName", DiagnosticKind.Java))
} }
} }
is JavaClassObjectAnnotationArgument -> FirGetClassCallImpl(null).apply { is JavaClassObjectAnnotationArgument -> FirGetClassCallImpl(null).apply {
@@ -271,7 +272,7 @@ private fun JavaAnnotationArgument.toFirExpression(
) )
} }
is JavaAnnotationAsAnnotationArgument -> getAnnotation().toFirAnnotationCall(session, javaTypeParameterStack) is JavaAnnotationAsAnnotationArgument -> getAnnotation().toFirAnnotationCall(session, javaTypeParameterStack)
else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unknown JavaAnnotationArgument: ${this::class.java}")) else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unknown JavaAnnotationArgument: ${this::class.java}", DiagnosticKind.Java))
} }
} }
@@ -305,7 +306,7 @@ internal fun Any?.createConstant(session: FirSession): FirExpression {
is BooleanArray -> toList().createArrayOfCall(session, IrConstKind.Boolean) is BooleanArray -> toList().createArrayOfCall(session, IrConstKind.Boolean)
null -> FirConstExpressionImpl(null, IrConstKind.Null, null) null -> FirConstExpressionImpl(null, IrConstKind.Null, null)
else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unknown value in JavaLiteralAnnotationArgument: $this")) else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unknown value in JavaLiteralAnnotationArgument: $this", DiagnosticKind.Java))
} }
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl import org.jetbrains.kotlin.fir.declarations.impl.FirPropertyImpl
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression
@@ -175,7 +176,7 @@ class KotlinDeserializedJvmSymbolsProvider(
FirResolvedTypeRefImpl( FirResolvedTypeRefImpl(
null, it.constructType(emptyList(), isNullable = false) null, it.constructType(emptyList(), isNullable = false)
) )
} ?: FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Symbol not found for $classId")) } ?: FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Symbol not found for $classId", DiagnosticKind.Java))
} }
@@ -227,7 +228,7 @@ class KotlinDeserializedJvmSymbolsProvider(
else -> { else -> {
FirErrorNamedReferenceImpl( FirErrorNamedReferenceImpl(
null, null,
FirSimpleDiagnostic("Strange deserialized enum value: ${this@toEnumEntryReferenceExpression}.$name") FirSimpleDiagnostic("Strange deserialized enum value: ${this@toEnumEntryReferenceExpression}.$name", DiagnosticKind.Java)
) )
} }
} }
@@ -19,6 +19,9 @@ import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirAmbiguityError
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirInapplicableCandidateError
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirUnresolvedNameError
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
@@ -366,12 +369,12 @@ class FirCallResolver(
val source = namedReference.source val source = namedReference.source
return when { return when {
candidates.isEmpty() -> FirErrorNamedReferenceImpl( candidates.isEmpty() -> FirErrorNamedReferenceImpl(
source, FirSimpleDiagnostic("Unresolved name: $name") source, FirUnresolvedNameError(name)
) )
applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> { applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> {
FirErrorNamedReferenceImpl( FirErrorNamedReferenceImpl(
source, source,
FirSimpleDiagnostic("Inapplicable($applicability): ${candidates.map { describeSymbol(it.symbol) }}") FirInapplicableCandidateError(applicability, candidates.map { it.symbol })
) )
} }
candidates.size == 1 -> { candidates.size == 1 -> {
@@ -388,17 +391,8 @@ class FirCallResolver(
} }
} }
else -> FirErrorNamedReferenceImpl( else -> FirErrorNamedReferenceImpl(
source, FirSimpleDiagnostic("Ambiguity: $name, ${candidates.map { describeSymbol(it.symbol) }}") source, FirAmbiguityError(name, candidates.map { it.symbol })
) )
} }
} }
private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String {
return when (symbol) {
is FirClassLikeSymbol<*> -> symbol.classId.asString()
is FirCallableSymbol<*> -> symbol.callableId.toString()
else -> "$symbol"
}
}
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.deserialization
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -15,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.*
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl
import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirUnresolvedSymbolError
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
@@ -97,7 +99,7 @@ abstract class AbstractAnnotationDeserializer(
FirResolvedTypeRefImpl( FirResolvedTypeRefImpl(
null, it.constructType(emptyList(), isNullable = false) null, it.constructType(emptyList(), isNullable = false)
) )
} ?: FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Symbol not found for $classId")) } ?: FirErrorTypeRefImpl(null, FirUnresolvedSymbolError(classId))
).apply { ).apply {
this.arguments += arguments this.arguments += arguments
} }
@@ -138,7 +140,7 @@ abstract class AbstractAnnotationDeserializer(
FirResolvedNamedReferenceImpl(null, entryName, it) FirResolvedNamedReferenceImpl(null, entryName, it)
} ?: FirErrorNamedReferenceImpl( } ?: FirErrorNamedReferenceImpl(
null, null,
FirSimpleDiagnostic("Strange deserialized enum value: $classId.$entryName") FirSimpleDiagnostic("Strange deserialized enum value: $classId.$entryName", DiagnosticKind.DeserializationError)
) )
} }
// ARRAY -> { // ARRAY -> {
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.componentArrayAccessor import org.jetbrains.kotlin.fir.componentArrayAccessor
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.FirResolvable import org.jetbrains.kotlin.fir.expressions.FirResolvable
@@ -330,7 +331,7 @@ private fun BodyResolveComponents.typeFromSymbol(symbol: AbstractFirBasedSymbol<
if (fir is FirEnumEntry) { if (fir is FirEnumEntry) {
(fir.superTypeRefs.firstOrNull() as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl( (fir.superTypeRefs.firstOrNull() as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(
null, null,
FirSimpleDiagnostic("no enum item supertype") FirSimpleDiagnostic("No enum item supertype", DiagnosticKind.EnumAsSupertype)
) )
} else } else
FirResolvedTypeRefImpl( FirResolvedTypeRefImpl(
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirUnresolvedReferenceError
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
import org.jetbrains.kotlin.fir.symbols.StandardClassIds.Unit import org.jetbrains.kotlin.fir.symbols.StandardClassIds.Unit
@@ -85,7 +86,7 @@ class PostponedArgumentsAnalyzer(
candidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> candidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED ->
FirErrorNamedReferenceImpl( FirErrorNamedReferenceImpl(
callableReferenceAccess.source, callableReferenceAccess.source,
FirSimpleDiagnostic("Unresolved reference: ${callableReferenceAccess.calleeReference.name}") FirUnresolvedReferenceError(callableReferenceAccess.calleeReference.name)
) )
else -> FirNamedReferenceWithCandidate(callableReferenceAccess.source, callableReferenceAccess.calleeReference.name, candidate) else -> FirNamedReferenceWithCandidate(callableReferenceAccess.source, callableReferenceAccess.calleeReference.name, candidate)
} }
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.resolve.diagnostics
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.resolve.calls.CandidateApplicability
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
class FirUnresolvedReferenceError(val name: Name? = null) : FirDiagnostic() {
override val reason: String get() = "Unresolved reference" + (name?.asString() ?: "")
}
class FirUnresolvedSymbolError(val classId: ClassId) : FirDiagnostic() {
override val reason: String get() = "Symbol not found for $classId"
}
class FirUnresolvedNameError(val name: Name) : FirDiagnostic() {
override val reason: String get() = "Unresolved name: $name"
}
class FirInapplicableCandidateError(val applicability: CandidateApplicability, val candidates: Collection<AbstractFirBasedSymbol<*>>) : FirDiagnostic() {
override val reason: String get() = "Inapplicable($applicability): $candidates"
}
class FirAmbiguityError(val name: Name, val candidates: Collection<AbstractFirBasedSymbol<*>>) : FirDiagnostic() {
override val reason: String get() = "Ambiguity: $name, ${candidates.map { describeSymbol(it) }}"
}
class FirOperatorAmbiguityError(val candidates: Collection<AbstractFirBasedSymbol<*>>) : FirDiagnostic() {
override val reason: String get() = "Operator overload ambiguity. Compatible candidates: ${candidates.map { describeSymbol(it) }}"
}
private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String {
return when (symbol) {
is FirClassLikeSymbol<*> -> symbol.classId.asString()
is FirCallableSymbol<*> -> symbol.callableId.toString()
else -> "$symbol"
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
@@ -165,7 +166,7 @@ class FirSupertypeResolverTransformer : FirAbstractTreeTransformer(phase = FirRe
val coneType = (superTypeRef as FirResolvedTypeRef).type val coneType = (superTypeRef as FirResolvedTypeRef).type
if (coneType is ConeTypeParameterType) { if (coneType is ConeTypeParameterType) {
resultingTypeRefs.add( resultingTypeRefs.add(
FirErrorTypeRefImpl(superTypeRef.source, FirSimpleDiagnostic("Type parameter cannot be a super-type: ${coneType.render()}")) FirErrorTypeRefImpl(superTypeRef.source, FirSimpleDiagnostic("Type parameter cannot be a super-type: ${coneType.render()}", DiagnosticKind.TypeParameterAsSupertype))
) )
continue continue
} }
@@ -174,7 +175,7 @@ class FirSupertypeResolverTransformer : FirAbstractTreeTransformer(phase = FirRe
if (superTypeClassId.outerClasses().any { it.areSupertypesComputing() }) { if (superTypeClassId.outerClasses().any { it.areSupertypesComputing() }) {
resultingTypeRefs.add( resultingTypeRefs.add(
FirErrorTypeRefImpl(superTypeRef.source, FirSimpleDiagnostic("Recursion detected: ${superTypeRef.render()}")) FirErrorTypeRefImpl(superTypeRef.source, FirSimpleDiagnostic("Recursion detected: ${superTypeRef.render()}", DiagnosticKind.RecursionInSupertypes))
) )
continue continue
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
@@ -32,7 +33,7 @@ class ReturnTypeCalculatorWithJump(val session: FirSession, val scopeSession: Sc
if (declaration.returnTypeRef is FirComputingImplicitTypeRef) { if (declaration.returnTypeRef is FirComputingImplicitTypeRef) {
declaration.transformReturnTypeRef( declaration.transformReturnTypeRef(
TransformImplicitType, TransformImplicitType,
FirErrorTypeRefImpl(null, FirSimpleDiagnostic("cycle")) FirErrorTypeRefImpl(null, FirSimpleDiagnostic("cycle", DiagnosticKind.RecursionInImplicitTypes))
) )
return declaration.returnTypeRef as FirResolvedTypeRef return declaration.returnTypeRef as FirResolvedTypeRef
} }
@@ -69,7 +70,7 @@ class ReturnTypeCalculatorWithJump(val session: FirSession, val scopeSession: Sc
}.mapTo(mutableListOf()) { provider.getFirClassifierByFqName(it) } }.mapTo(mutableListOf()) { provider.getFirClassifierByFqName(it) }
if (file == null || outerClasses.any { it == null }) { if (file == null || outerClasses.any { it == null }) {
return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Cannot calculate return type (local class/object?)")) return FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Cannot calculate return type (local class/object?)", DiagnosticKind.InferenceError))
} }
declaration.transformReturnTypeRef( declaration.transformReturnTypeRef(
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.fir.FirTargetElement import org.jetbrains.kotlin.fir.FirTargetElement
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
@@ -72,7 +73,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression) ?: run { whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression) ?: run {
whenExpression = whenExpression.transformSingle(whenExhaustivenessTransformer, null) whenExpression = whenExpression.transformSingle(whenExhaustivenessTransformer, null)
dataFlowAnalyzer.exitWhenExpression(whenExpression) dataFlowAnalyzer.exitWhenExpression(whenExpression)
whenExpression.resultType = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("")) whenExpression.resultType = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Can't resolve when expression", DiagnosticKind.InferenceError))
return@with whenExpression.compose() return@with whenExpression.compose()
} }
@@ -137,7 +138,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
val expectedTypeRef = data as FirTypeRef? val expectedTypeRef = data as FirTypeRef?
callCompleter.completeCall(it, expectedTypeRef) callCompleter.completeCall(it, expectedTypeRef)
} ?: run { } ?: run {
tryExpression.resultType = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("")) tryExpression.resultType = FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Can't resolve try expression", DiagnosticKind.InferenceError))
tryExpression tryExpression
} }
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.copy
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
@@ -337,7 +338,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
val bodyExpectedType = returnTypeRefFromResolvedAtom ?: data val bodyExpectedType = returnTypeRefFromResolvedAtom ?: data
af = transformFunction(af, bodyExpectedType).single as FirAnonymousFunction af = transformFunction(af, bodyExpectedType).single as FirAnonymousFunction
af = af.copy( af = af.copy(
returnTypeRef = af.body?.resultType ?: FirErrorTypeRefImpl(af.source, FirSimpleDiagnostic("No result type for lambda")) returnTypeRef = af.body?.resultType ?: FirErrorTypeRefImpl(af.source, FirSimpleDiagnostic("No result type for lambda", DiagnosticKind.InferenceError))
) )
af.replaceTypeRef(af.constructFunctionalTypeRef(session)) af.replaceTypeRef(af.constructFunctionalTypeRef(session))
af.compose() af.compose()
@@ -384,7 +385,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
when (val resultType = initializer.resultType) { when (val resultType = initializer.resultType) {
is FirImplicitTypeRef -> FirErrorTypeRefImpl( is FirImplicitTypeRef -> FirErrorTypeRefImpl(
null, null,
FirSimpleDiagnostic("No result type for initializer") FirSimpleDiagnostic("No result type for initializer", DiagnosticKind.InferenceError)
) )
else -> resultType else -> resultType
} }
@@ -396,7 +397,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
when (val resultType = variable.getter?.returnTypeRef) { when (val resultType = variable.getter?.returnTypeRef) {
is FirImplicitTypeRef -> FirErrorTypeRefImpl( is FirImplicitTypeRef -> FirErrorTypeRefImpl(
null, null,
FirSimpleDiagnostic("No result type for getter") FirSimpleDiagnostic("No result type for getter", DiagnosticKind.InferenceError)
) )
else -> resultType else -> resultType
} }
@@ -404,7 +405,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
} }
else -> { else -> {
variable.transformReturnTypeRef( variable.transformReturnTypeRef(
transformer, FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Cannot infer variable type without initializer / getter / delegate")) transformer, FirErrorTypeRefImpl(null, FirSimpleDiagnostic("Cannot infer variable type without initializer / getter / delegate", DiagnosticKind.InferenceError))
) )
} }
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirCallResolver import org.jetbrains.kotlin.fir.FirCallResolver
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
@@ -24,6 +25,8 @@ import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
import org.jetbrains.kotlin.fir.resolve.calls.candidate import org.jetbrains.kotlin.fir.resolve.calls.candidate
import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.constructType
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirOperatorAmbiguityError
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirUnresolvedReferenceError
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
@@ -56,7 +59,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
override fun transformExpression(expression: FirExpression, data: Any?): CompositeTransformResult<FirStatement> { override fun transformExpression(expression: FirExpression, data: Any?): CompositeTransformResult<FirStatement> {
if (expression.resultType is FirImplicitTypeRef && expression !is FirWrappedExpression) { if (expression.resultType is FirImplicitTypeRef && expression !is FirWrappedExpression) {
val type = FirErrorTypeRefImpl(expression.source, FirSimpleDiagnostic("Type calculating for ${expression::class} is not supported")) val type = FirErrorTypeRefImpl(expression.source, FirSimpleDiagnostic("Type calculating for ${expression::class} is not supported", DiagnosticKind.InferenceError))
expression.resultType = type expression.resultType = type
} }
return (expression.transformChildren(transformer, data) as FirStatement).compose() return (expression.transformChildren(transformer, data) as FirStatement).compose()
@@ -84,7 +87,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
} else { } else {
val superTypeRef = implicitReceiverStack.lastDispatchReceiver() val superTypeRef = implicitReceiverStack.lastDispatchReceiver()
?.boundSymbol?.phasedFir?.superTypeRefs?.firstOrNull() ?.boundSymbol?.phasedFir?.superTypeRefs?.firstOrNull()
?: FirErrorTypeRefImpl(qualifiedAccessExpression.source, FirSimpleDiagnostic("No super type")) ?: FirErrorTypeRefImpl(qualifiedAccessExpression.source, FirSimpleDiagnostic("No super type", DiagnosticKind.NoSupertype))
qualifiedAccessExpression.resultType = superTypeRef qualifiedAccessExpression.resultType = superTypeRef
callee.replaceSuperTypeRef(superTypeRef) callee.replaceSuperTypeRef(superTypeRef)
} }
@@ -172,7 +175,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
block.resultType = if (resultExpression == null) { block.resultType = if (resultExpression == null) {
FirImplicitUnitTypeRef(block.source) FirImplicitUnitTypeRef(block.source)
} else { } else {
(resultExpression.resultType as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(null, FirSimpleDiagnostic("No type for block")) (resultExpression.resultType as? FirResolvedTypeRef) ?: FirErrorTypeRefImpl(null, FirSimpleDiagnostic("No type for block", DiagnosticKind.InferenceError))
} }
dataFlowAnalyzer.exitBlock(block) dataFlowAnalyzer.exitBlock(block)
return block.compose() return block.compose()
@@ -229,13 +232,13 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
val assignment = val assignment =
FirVariableAssignmentImpl(operatorCall.source, false, resolvedOperatorCall, FirOperation.ASSIGN).apply { FirVariableAssignmentImpl(operatorCall.source, false, resolvedOperatorCall, FirOperation.ASSIGN).apply {
lValue = (leftArgument as? FirQualifiedAccess)?.calleeReference lValue = (leftArgument as? FirQualifiedAccess)?.calleeReference
?: FirErrorNamedReferenceImpl(null, FirSimpleDiagnostic("Unresolved reference")) ?: FirErrorNamedReferenceImpl(null, FirUnresolvedReferenceError())
} }
assignment.transform(transformer, noExpectedType) assignment.transform(transformer, noExpectedType)
} }
else -> FirErrorExpressionImpl( else -> FirErrorExpressionImpl(
operatorCall.source, operatorCall.source,
FirSimpleDiagnostic("Operator overload ambiguity. $assignmentOperatorName and $simpleOperatorName are compatible") FirOperatorAmbiguityError(listOf(operatorCallReference.resolvedSymbol, assignCallReference.resolvedSymbol))
).compose() ).compose()
} }
} }
@@ -13,5 +13,13 @@ enum class DiagnosticKind {
UnresolvedLabel, UnresolvedLabel,
IllegalConstExpression, IllegalConstExpression,
ConstructorInObject, ConstructorInObject,
DeserializationError,
InferenceError,
NoSupertype,
TypeParameterAsSupertype,
EnumAsSupertype,
RecursionInSupertypes,
RecursionInImplicitTypes,
Java,
Other Other
} }