[FIR] Add utility for checking if FirReference is one of error reference
Also simplify relevant code in checkers
This commit is contained in:
committed by
Space Team
parent
7334694fd9
commit
34be0f05b2
+3
-4
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.isError
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
||||
@@ -142,10 +143,8 @@ object FirNativeThrowsChecker : FirBasicDeclarationChecker() {
|
||||
return expression.hasUnresolvedArgument()
|
||||
}
|
||||
|
||||
if (this is FirResolvable) {
|
||||
when (this.calleeReference) {
|
||||
is FirErrorNamedReference, is FirResolvedErrorReference -> return true
|
||||
}
|
||||
if (this is FirResolvable && calleeReference.isError()) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (this is FirVarargArgumentsExpression) {
|
||||
|
||||
+3
-5
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
@@ -30,11 +31,8 @@ internal fun checkConstantArguments(
|
||||
expression: FirExpression,
|
||||
session: FirSession,
|
||||
): ConstantArgumentKind? {
|
||||
val expressionSymbol = expression.toResolvedCallableReference()
|
||||
?.takeUnless { it is FirResolvedErrorReference }
|
||||
?.resolvedSymbol as? FirCallableSymbol<*>
|
||||
val classKindOfParent = (expressionSymbol?.getReferencedClassSymbol(session) as? FirRegularClassSymbol)
|
||||
?.classKind
|
||||
val expressionSymbol = expression.toReference()?.toResolvedCallableSymbol(discardErrorReference = true)
|
||||
val classKindOfParent = (expressionSymbol?.getReferencedClassSymbol(session) as? FirRegularClassSymbol)?.classKind
|
||||
|
||||
when {
|
||||
expression is FirNamedArgumentExpression -> {
|
||||
|
||||
+3
-8
@@ -13,9 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
@@ -94,12 +92,9 @@ object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() {
|
||||
return null
|
||||
}
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
private fun FirConstructor.getDelegated(): FirConstructor? {
|
||||
this.symbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
||||
val delegatedConstructorSymbol = (delegatedConstructor?.calleeReference as? FirResolvedNamedReference)
|
||||
.takeUnless { it is FirResolvedErrorReference }
|
||||
?.resolvedSymbol
|
||||
@OptIn(SymbolInternals::class)
|
||||
return delegatedConstructorSymbol?.fir as? FirConstructor
|
||||
return delegatedConstructor?.calleeReference?.toResolvedConstructorSymbol(discardErrorReference = true)?.fir
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
|
||||
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.isError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
@@ -65,11 +66,7 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
|
||||
*/
|
||||
private fun checkFunctionReferenceErrors(functionCall: FirFunctionCall): Boolean {
|
||||
val reference = functionCall.calleeReference
|
||||
val diagnostic = when (reference) {
|
||||
is FirErrorNamedReference -> reference.diagnostic
|
||||
is FirResolvedErrorReference -> reference.diagnostic
|
||||
else -> return false
|
||||
}
|
||||
val diagnostic = if (reference.isError()) reference.diagnostic else return false
|
||||
if (reference.source?.kind != KtFakeSourceElementKind.DelegatedPropertyAccessor) return false
|
||||
val expectedFunctionSignature =
|
||||
(if (isGet) "getValue" else "setValue") + "(${functionCall.arguments.joinToString(", ") { it.typeRef.coneType.renderReadable() }})"
|
||||
|
||||
+3
-6
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.isError
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
@@ -71,11 +72,8 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
||||
else -> null
|
||||
} ?: return
|
||||
|
||||
val diagnostic = when (val reference = componentCall.calleeReference) {
|
||||
is FirErrorNamedReference -> reference.diagnostic
|
||||
is FirResolvedErrorReference -> reference.diagnostic
|
||||
else -> null
|
||||
}
|
||||
val reference = componentCall.calleeReference
|
||||
val diagnostic = if (reference.isError()) reference.diagnostic else null
|
||||
if (diagnostic != null) {
|
||||
checkComponentCall(
|
||||
originalDestructuringDeclarationOrInitializerSource,
|
||||
@@ -88,7 +86,6 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun checkInitializer(
|
||||
|
||||
+6
-4
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.isError
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.UnsafeCall
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
|
||||
@@ -105,9 +106,10 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
noneApplicableFactory: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>>? = null,
|
||||
unsafeCallFactory: KtDiagnosticFactory0? = null,
|
||||
): Boolean {
|
||||
when (val calleeReference = call.calleeReference) {
|
||||
is FirErrorNamedReference, is FirResolvedErrorReference -> {
|
||||
when (val diagnostic = (calleeReference as FirDiagnosticHolder).diagnostic) {
|
||||
val calleeReference = call.calleeReference
|
||||
when {
|
||||
calleeReference.isError() -> {
|
||||
when (val diagnostic = calleeReference.diagnostic) {
|
||||
is ConeAmbiguityError -> if (diagnostic.applicability.isSuccess) {
|
||||
reporter.reportOn(reportSource, ambiguityFactory, diagnostic.candidates.map { it.symbol }, context)
|
||||
} else if (noneApplicableFactory != null) {
|
||||
@@ -140,7 +142,7 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
}
|
||||
return true
|
||||
}
|
||||
is FirResolvedNamedReference -> {
|
||||
calleeReference is FirResolvedNamedReference -> {
|
||||
val symbol = calleeReference.resolvedSymbol
|
||||
if (symbol is FirNamedFunctionSymbol) {
|
||||
if (!symbol.isOperator) {
|
||||
|
||||
+2
-4
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
@@ -23,10 +24,7 @@ import org.jetbrains.kotlin.fir.types.coneType
|
||||
|
||||
object FirSealedClassConstructorCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val constructorSymbol = (expression.calleeReference as? FirResolvedNamedReference)
|
||||
?.takeUnless { it is FirResolvedErrorReference }
|
||||
?.resolvedSymbol as? FirConstructorSymbol
|
||||
?: return
|
||||
val constructorSymbol = expression.calleeReference.toResolvedConstructorSymbol(discardErrorReference = true) ?: return
|
||||
|
||||
val typeSymbol = (constructorSymbol.resolvedReturnTypeRef.coneType.fullyExpandedType(context.session) as? ConeClassLikeType)
|
||||
?.lookupTag?.toSymbol(context.session) as? FirRegularClassSymbol
|
||||
|
||||
+7
-8
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.isCatchParameter
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.isError
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.renderer.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
@@ -84,14 +85,12 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
||||
}
|
||||
|
||||
override fun visitQualifiedAccess(qualifiedAccess: FirQualifiedAccess, data: FirElement) {
|
||||
when (val calleeReference = qualifiedAccess.calleeReference) {
|
||||
is FirErrorNamedReference, is FirResolvedErrorReference -> {
|
||||
errorReferences++
|
||||
println((calleeReference as FirDiagnosticHolder).diagnostic.reason)
|
||||
}
|
||||
else -> {
|
||||
normalReferences++
|
||||
}
|
||||
val calleeReference = qualifiedAccess.calleeReference
|
||||
if (calleeReference.isError()) {
|
||||
errorReferences++
|
||||
println((calleeReference as FirDiagnosticHolder).diagnostic.reason)
|
||||
} else {
|
||||
normalReferences++
|
||||
}
|
||||
visitStatement(qualifiedAccess, data)
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.references
|
||||
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
val FirReference.resolved: FirResolvedNamedReference? get() = this as? FirResolvedNamedReference
|
||||
|
||||
@@ -52,3 +55,14 @@ fun FirReference.toResolvedFunctionSymbol(discardErrorReference: Boolean = false
|
||||
fun FirReference.toResolvedConstructorSymbol(discardErrorReference: Boolean = false): FirConstructorSymbol? {
|
||||
return this.toResolvedSymbol<FirConstructorSymbol>(discardErrorReference)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
fun FirReference.isError(): Boolean {
|
||||
contract {
|
||||
returns(true) implies (this@isError is FirDiagnosticHolder)
|
||||
}
|
||||
return when (this) {
|
||||
is FirResolvedErrorReference, is FirErrorNamedReference -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.isError
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirGlobalResolveProcessor
|
||||
@@ -283,8 +284,8 @@ class FirResolveBench(val withProgress: Boolean, val listener: BenchListener? =
|
||||
if (type is ConeErrorType) {
|
||||
errorFunctionCallTypes++
|
||||
val psi = callee.psi
|
||||
if ((callee is FirErrorNamedReference || callee is FirResolvedErrorReference) && psi != null) {
|
||||
reportProblem((callee as FirDiagnosticHolder).diagnostic.reason, psi)
|
||||
if (callee.isError() && psi != null) {
|
||||
reportProblem(callee.diagnostic.reason, psi)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,8 +301,8 @@ class FirResolveBench(val withProgress: Boolean, val listener: BenchListener? =
|
||||
if (type is ConeErrorType) {
|
||||
errorQualifiedAccessTypes++
|
||||
val psi = callee.psi
|
||||
if ((callee is FirErrorNamedReference || callee is FirResolvedErrorReference) && psi != null) {
|
||||
reportProblem((callee as FirDiagnosticHolder).diagnostic.reason, psi)
|
||||
if (callee.isError() && psi != null) {
|
||||
reportProblem(callee.diagnostic.reason, psi)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-9
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.isError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithSingleCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||
@@ -33,8 +35,9 @@ object FirAssignmentPluginFunctionCallChecker : FirFunctionCallChecker() {
|
||||
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!expression.isOverloadAssignCallCandidate()) return
|
||||
|
||||
if (expression.isFunctionResolveError()) {
|
||||
if (expression.isOverloadedAssignCallError(context.session)) {
|
||||
val calleeReference = expression.calleeReference
|
||||
if (calleeReference.isError()) {
|
||||
if (expression.isOverloadedAssignCallError(context.session, calleeReference.diagnostic)) {
|
||||
reporter.reportOn(expression.source, NO_APPLICABLE_ASSIGN_METHOD, context)
|
||||
}
|
||||
} else if (expression.isOverloadedAssignCall(context.session) && !expression.isReturnTypeUnit()) {
|
||||
@@ -45,13 +48,8 @@ object FirAssignmentPluginFunctionCallChecker : FirFunctionCallChecker() {
|
||||
private fun FirFunctionCall.isOverloadAssignCallCandidate() =
|
||||
arguments.size == 1 && source?.kind == KtFakeSourceElementKind.DesugaredCompoundAssignment
|
||||
|
||||
private fun FirFunctionCall.isFunctionResolveError() = when(calleeReference){
|
||||
is FirErrorNamedReference, is FirResolvedErrorReference -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun FirFunctionCall.isOverloadedAssignCallError(session: FirSession): Boolean {
|
||||
val functionName = when (val diagnostic = (calleeReference as? FirDiagnosticHolder)?.diagnostic) {
|
||||
private fun FirFunctionCall.isOverloadedAssignCallError(session: FirSession, diagnostic: ConeDiagnostic): Boolean {
|
||||
val functionName = when (diagnostic) {
|
||||
is ConeAmbiguityError -> diagnostic.name
|
||||
is ConeDiagnosticWithSingleCandidate -> diagnostic.candidate.callInfo.name
|
||||
is ConeUnresolvedNameError -> diagnostic.name
|
||||
|
||||
Reference in New Issue
Block a user