[FIR] Create FirResolvedErrorReference for error reference with single candidate
Note that this reference won't be created for hidden candidates, because they are designed to be truly invisible from the user side
This commit is contained in:
committed by
Space Team
parent
9e4e5eed68
commit
dde64c10ea
+22
-21
@@ -44,10 +44,7 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
|||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.realPsi
|
import org.jetbrains.kotlin.fir.realPsi
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.AbstractCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.AbstractCandidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError
|
import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError
|
||||||
@@ -176,9 +173,29 @@ internal class KtFirCallResolver(
|
|||||||
resolveFragmentOfCall = resolveFragmentOfCall
|
resolveFragmentOfCall = resolveFragmentOfCall
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> transformErrorReference(call: FirResolvable, calleeReference: T): KtCallInfo where T : FirNamedReference, T : FirDiagnosticHolder {
|
||||||
|
val diagnostic = calleeReference.diagnostic
|
||||||
|
val ktDiagnostic = calleeReference.createKtDiagnostic(psi)
|
||||||
|
|
||||||
|
if (diagnostic is ConeHiddenCandidateError)
|
||||||
|
return KtErrorCallInfo(emptyList(), ktDiagnostic, token)
|
||||||
|
|
||||||
|
val candidateCalls = mutableListOf<KtCall>()
|
||||||
|
if (diagnostic is ConeDiagnosticWithCandidates) {
|
||||||
|
diagnostic.candidates.mapNotNullTo(candidateCalls) {
|
||||||
|
createKtCall(psi, call, it, resolveFragmentOfCall)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
candidateCalls.addIfNotNull(createKtCall(psi, call, null, resolveFragmentOfCall))
|
||||||
|
}
|
||||||
|
return KtErrorCallInfo(candidateCalls, ktDiagnostic, token)
|
||||||
|
}
|
||||||
|
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirResolvable -> {
|
is FirResolvable -> {
|
||||||
when (val calleeReference = calleeReference) {
|
when (val calleeReference = calleeReference) {
|
||||||
|
is FirResolvedErrorReference -> transformErrorReference(this, calleeReference)
|
||||||
is FirResolvedNamedReference -> when (calleeReference.resolvedSymbol) {
|
is FirResolvedNamedReference -> when (calleeReference.resolvedSymbol) {
|
||||||
// `calleeReference.resolvedSymbol` isn't guaranteed to be callable. For example, function type parameters used in
|
// `calleeReference.resolvedSymbol` isn't guaranteed to be callable. For example, function type parameters used in
|
||||||
// expression positions (e.g. `T` in `println(T)`) are parsed as `KtSimpleNameExpression` and built into
|
// expression positions (e.g. `T` in `println(T)`) are parsed as `KtSimpleNameExpression` and built into
|
||||||
@@ -194,23 +211,7 @@ internal class KtFirCallResolver(
|
|||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
is FirErrorNamedReference -> {
|
is FirErrorNamedReference -> transformErrorReference(this, calleeReference)
|
||||||
val diagnostic = calleeReference.diagnostic
|
|
||||||
val ktDiagnostic = calleeReference.createKtDiagnostic(psi)
|
|
||||||
|
|
||||||
if (diagnostic is ConeHiddenCandidateError)
|
|
||||||
return KtErrorCallInfo(emptyList(), ktDiagnostic, token)
|
|
||||||
|
|
||||||
val candidateCalls = mutableListOf<KtCall>()
|
|
||||||
if (diagnostic is ConeDiagnosticWithCandidates) {
|
|
||||||
diagnostic.candidates.mapNotNullTo(candidateCalls) {
|
|
||||||
createKtCall(psi, this@toKtCallInfo, it, resolveFragmentOfCall)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
candidateCalls.addIfNotNull(createKtCall(psi, this, null, resolveFragmentOfCall))
|
|
||||||
}
|
|
||||||
KtErrorCallInfo(candidateCalls, ktDiagnostic, token)
|
|
||||||
}
|
|
||||||
// Unresolved delegated constructor call is untransformed and end up as an `FirSuperReference`
|
// Unresolved delegated constructor call is untransformed and end up as an `FirSuperReference`
|
||||||
is FirSuperReference -> {
|
is FirSuperReference -> {
|
||||||
val delegatedConstructorCall = this as? FirDelegatedConstructorCall ?: return null
|
val delegatedConstructorCall = this as? FirDelegatedConstructorCall ?: return null
|
||||||
|
|||||||
+3
-2
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
||||||
@@ -142,8 +143,8 @@ object FirNativeThrowsChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this is FirResolvable) {
|
if (this is FirResolvable) {
|
||||||
if (this.calleeReference is FirErrorNamedReference) {
|
when (this.calleeReference) {
|
||||||
return true
|
is FirErrorNamedReference, is FirResolvedErrorReference -> return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.modality
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
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.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -29,7 +30,9 @@ internal fun checkConstantArguments(
|
|||||||
expression: FirExpression,
|
expression: FirExpression,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
): ConstantArgumentKind? {
|
): ConstantArgumentKind? {
|
||||||
val expressionSymbol = expression.toResolvedCallableSymbol()
|
val expressionSymbol = expression.toResolvedCallableReference()
|
||||||
|
?.takeUnless { it is FirResolvedErrorReference }
|
||||||
|
?.resolvedSymbol as? FirCallableSymbol<*>
|
||||||
val classKindOfParent = (expressionSymbol?.getReferencedClassSymbol(session) as? FirRegularClassSymbol)
|
val classKindOfParent = (expressionSymbol?.getReferencedClassSymbol(session) as? FirRegularClassSymbol)
|
||||||
?.classKind
|
?.classKind
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
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.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
@@ -95,7 +96,9 @@ object FirCommonConstructorDelegationIssuesChecker : FirRegularClassChecker() {
|
|||||||
|
|
||||||
private fun FirConstructor.getDelegated(): FirConstructor? {
|
private fun FirConstructor.getDelegated(): FirConstructor? {
|
||||||
this.symbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
this.symbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
||||||
val delegatedConstructorSymbol = (delegatedConstructor?.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol
|
val delegatedConstructorSymbol = (delegatedConstructor?.calleeReference as? FirResolvedNamedReference)
|
||||||
|
.takeUnless { it is FirResolvedErrorReference }
|
||||||
|
?.resolvedSymbol
|
||||||
@OptIn(SymbolInternals::class)
|
@OptIn(SymbolInternals::class)
|
||||||
return delegatedConstructorSymbol?.fir as? FirConstructor
|
return delegatedConstructorSymbol?.fir as? FirConstructor
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-7
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
|
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.arguments
|
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -63,15 +64,20 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
|
|||||||
* @return true if any error was reported; false otherwise.
|
* @return true if any error was reported; false otherwise.
|
||||||
*/
|
*/
|
||||||
private fun checkFunctionReferenceErrors(functionCall: FirFunctionCall): Boolean {
|
private fun checkFunctionReferenceErrors(functionCall: FirFunctionCall): Boolean {
|
||||||
val errorNamedReference = functionCall.calleeReference as? FirErrorNamedReference ?: return false
|
val reference = functionCall.calleeReference
|
||||||
if (errorNamedReference.source?.kind != KtFakeSourceElementKind.DelegatedPropertyAccessor) return false
|
val diagnostic = when (reference) {
|
||||||
|
is FirErrorNamedReference -> reference.diagnostic
|
||||||
|
is FirResolvedErrorReference -> reference.diagnostic
|
||||||
|
else -> return false
|
||||||
|
}
|
||||||
|
if (reference.source?.kind != KtFakeSourceElementKind.DelegatedPropertyAccessor) return false
|
||||||
val expectedFunctionSignature =
|
val expectedFunctionSignature =
|
||||||
(if (isGet) "getValue" else "setValue") + "(${functionCall.arguments.joinToString(", ") { it.typeRef.coneType.renderReadable() }})"
|
(if (isGet) "getValue" else "setValue") + "(${functionCall.arguments.joinToString(", ") { it.typeRef.coneType.renderReadable() }})"
|
||||||
val delegateDescription = if (isGet) "delegate" else "delegate for var (read-write property)"
|
val delegateDescription = if (isGet) "delegate" else "delegate for var (read-write property)"
|
||||||
|
|
||||||
fun reportInapplicableDiagnostics(candidates: Collection<FirBasedSymbol<*>>) {
|
fun reportInapplicableDiagnostics(candidates: Collection<FirBasedSymbol<*>>) {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
errorNamedReference.source,
|
reference.source,
|
||||||
FirErrors.DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE,
|
FirErrors.DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE,
|
||||||
expectedFunctionSignature,
|
expectedFunctionSignature,
|
||||||
candidates,
|
candidates,
|
||||||
@@ -80,9 +86,9 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var errorReported = true
|
var errorReported = true
|
||||||
when (val diagnostic = errorNamedReference.diagnostic) {
|
when (diagnostic) {
|
||||||
is ConeUnresolvedNameError -> reporter.reportOn(
|
is ConeUnresolvedNameError -> reporter.reportOn(
|
||||||
errorNamedReference.source,
|
reference.source,
|
||||||
FirErrors.DELEGATE_SPECIAL_FUNCTION_MISSING,
|
FirErrors.DELEGATE_SPECIAL_FUNCTION_MISSING,
|
||||||
expectedFunctionSignature,
|
expectedFunctionSignature,
|
||||||
delegateType,
|
delegateType,
|
||||||
@@ -94,7 +100,7 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
|
|||||||
if (diagnostic.applicability.isSuccess) {
|
if (diagnostic.applicability.isSuccess) {
|
||||||
// Match is successful but there are too many matches! So we report DELEGATE_SPECIAL_FUNCTION_AMBIGUITY.
|
// Match is successful but there are too many matches! So we report DELEGATE_SPECIAL_FUNCTION_AMBIGUITY.
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
errorNamedReference.source,
|
reference.source,
|
||||||
FirErrors.DELEGATE_SPECIAL_FUNCTION_AMBIGUITY,
|
FirErrors.DELEGATE_SPECIAL_FUNCTION_AMBIGUITY,
|
||||||
expectedFunctionSignature,
|
expectedFunctionSignature,
|
||||||
diagnostic.candidates.map { it.symbol },
|
diagnostic.candidates.map { it.symbol },
|
||||||
@@ -106,7 +112,7 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ConeInapplicableWrongReceiver -> reporter.reportOn(
|
is ConeInapplicableWrongReceiver -> reporter.reportOn(
|
||||||
errorNamedReference.source,
|
reference.source,
|
||||||
FirErrors.DELEGATE_SPECIAL_FUNCTION_MISSING,
|
FirErrors.DELEGATE_SPECIAL_FUNCTION_MISSING,
|
||||||
expectedFunctionSignature,
|
expectedFunctionSignature,
|
||||||
delegateType,
|
delegateType,
|
||||||
|
|||||||
+21
-14
@@ -15,10 +15,12 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.resolvedSymbol
|
import org.jetbrains.kotlin.fir.resolvedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
@@ -70,19 +72,24 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
|||||||
else -> null
|
else -> null
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
when (val reference = componentCall.calleeReference) {
|
val diagnostic = when (val reference = componentCall.calleeReference) {
|
||||||
is FirErrorNamedReference ->
|
is FirErrorNamedReference -> reference.diagnostic
|
||||||
checkComponentCall(
|
is FirResolvedErrorReference -> reference.diagnostic
|
||||||
originalDestructuringDeclarationOrInitializerSource,
|
else -> null
|
||||||
originalDestructuringDeclarationType,
|
|
||||||
reference,
|
|
||||||
declaration,
|
|
||||||
componentCall,
|
|
||||||
originalDestructuringDeclaration,
|
|
||||||
reporter,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
if (diagnostic != null) {
|
||||||
|
checkComponentCall(
|
||||||
|
originalDestructuringDeclarationOrInitializerSource,
|
||||||
|
originalDestructuringDeclarationType,
|
||||||
|
diagnostic,
|
||||||
|
declaration,
|
||||||
|
componentCall,
|
||||||
|
originalDestructuringDeclaration,
|
||||||
|
reporter,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkInitializer(
|
private fun checkInitializer(
|
||||||
@@ -105,14 +112,14 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
|||||||
private fun checkComponentCall(
|
private fun checkComponentCall(
|
||||||
source: KtSourceElement,
|
source: KtSourceElement,
|
||||||
destructuringDeclarationType: ConeKotlinType,
|
destructuringDeclarationType: ConeKotlinType,
|
||||||
reference: FirErrorNamedReference,
|
diagnostic: ConeDiagnostic,
|
||||||
property: FirProperty,
|
property: FirProperty,
|
||||||
componentCall: FirComponentCall,
|
componentCall: FirComponentCall,
|
||||||
destructuringDeclaration: FirVariable,
|
destructuringDeclaration: FirVariable,
|
||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
context: CheckerContext
|
context: CheckerContext
|
||||||
) {
|
) {
|
||||||
when (val diagnostic = reference.diagnostic) {
|
when (diagnostic) {
|
||||||
is ConeUnresolvedNameError -> {
|
is ConeUnresolvedNameError -> {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
source,
|
source,
|
||||||
|
|||||||
+4
-2
@@ -26,10 +26,12 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NEXT_NONE_APPLICA
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_MODIFIER_REQUIRED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_MODIFIER_REQUIRED
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
import org.jetbrains.kotlin.fir.expressions.FirWhileLoop
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
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.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.UnsafeCall
|
import org.jetbrains.kotlin.fir.resolve.calls.UnsafeCall
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||||
@@ -104,8 +106,8 @@ object FirForLoopChecker : FirBlockChecker() {
|
|||||||
unsafeCallFactory: KtDiagnosticFactory0? = null,
|
unsafeCallFactory: KtDiagnosticFactory0? = null,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
when (val calleeReference = call.calleeReference) {
|
when (val calleeReference = call.calleeReference) {
|
||||||
is FirErrorNamedReference -> {
|
is FirErrorNamedReference, is FirResolvedErrorReference -> {
|
||||||
when (val diagnostic = calleeReference.diagnostic) {
|
when (val diagnostic = (calleeReference as FirDiagnosticHolder).diagnostic) {
|
||||||
is ConeAmbiguityError -> if (diagnostic.applicability.isSuccess) {
|
is ConeAmbiguityError -> if (diagnostic.applicability.isSuccess) {
|
||||||
reporter.reportOn(reportSource, ambiguityFactory, diagnostic.candidates.map { it.symbol }, context)
|
reporter.reportOn(reportSource, ambiguityFactory, diagnostic.candidates.map { it.symbol }, context)
|
||||||
} else if (noneApplicableFactory != null) {
|
} else if (noneApplicableFactory != null) {
|
||||||
|
|||||||
+2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
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.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.fir.types.coneType
|
|||||||
object FirSealedClassConstructorCallChecker : FirQualifiedAccessExpressionChecker() {
|
object FirSealedClassConstructorCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val constructorSymbol = (expression.calleeReference as? FirResolvedNamedReference)
|
val constructorSymbol = (expression.calleeReference as? FirResolvedNamedReference)
|
||||||
|
?.takeUnless { it is FirResolvedErrorReference }
|
||||||
?.resolvedSymbol as? FirConstructorSymbol
|
?.resolvedSymbol as? FirConstructorSymbol
|
||||||
?: return
|
?: return
|
||||||
|
|
||||||
|
|||||||
+9
-10
@@ -11,13 +11,12 @@ import org.jetbrains.kotlin.fir.analysis.checkers.checkUpperBoundViolated
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||||
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.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableWrongReceiver
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableWrongReceiver
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.isTypeAliasedConstructor
|
import org.jetbrains.kotlin.fir.resolve.isTypeAliasedConstructor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
@@ -29,15 +28,15 @@ object FirUpperBoundViolatedExpressionChecker : FirQualifiedAccessExpressionChec
|
|||||||
// declarations with their declared bounds.
|
// declarations with their declared bounds.
|
||||||
// it may be the called function declaration
|
// it may be the called function declaration
|
||||||
// or the class declaration
|
// or the class declaration
|
||||||
val calleeReference = expression.calleeReference
|
val calleeSymbol = when (val calleeReference = expression.calleeReference) {
|
||||||
var calleeSymbol: FirCallableSymbol<*>? = null
|
is FirResolvedErrorReference -> {
|
||||||
if (calleeReference is FirResolvedNamedReference) {
|
if (calleeReference.diagnostic is ConeInapplicableWrongReceiver) {
|
||||||
calleeSymbol = calleeReference.toResolvedCallableSymbol()
|
return
|
||||||
} else if (calleeReference is FirErrorNamedReference) {
|
}
|
||||||
if (calleeReference.diagnostic is ConeInapplicableWrongReceiver) {
|
calleeReference.toResolvedCallableSymbol()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
calleeSymbol = calleeReference.candidateSymbol as? FirCallableSymbol<*>
|
is FirResolvedNamedReference -> calleeReference.toResolvedCallableSymbol()
|
||||||
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeArguments: List<TypeArgumentWithSourceInfo>
|
val typeArguments: List<TypeArgumentWithSourceInfo>
|
||||||
|
|||||||
+2
-2
@@ -26,11 +26,11 @@ object RedundantExplicitTypeChecker : FirPropertyChecker() {
|
|||||||
if (!declaration.isLocal) return
|
if (!declaration.isLocal) return
|
||||||
|
|
||||||
val initializer = declaration.initializer ?: return
|
val initializer = declaration.initializer ?: return
|
||||||
val typeReference = declaration.returnTypeRef
|
val typeReference = declaration.returnTypeRef.takeUnless { it is FirErrorTypeRef } ?: return
|
||||||
|
|
||||||
if (typeReference.source?.kind is KtFakeSourceElementKind) return
|
if (typeReference.source?.kind is KtFakeSourceElementKind) return
|
||||||
|
|
||||||
val type = declaration.returnTypeRef.coneType
|
val type = typeReference.coneType
|
||||||
|
|
||||||
if (type.toSymbol(context.session) is FirTypeAliasSymbol) return
|
if (type.toSymbol(context.session) is FirTypeAliasSymbol) return
|
||||||
if (typeReference.annotations.isNotEmpty()) return
|
if (typeReference.annotations.isNotEmpty()) return
|
||||||
|
|||||||
+17
-7
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
|||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||||
@@ -52,20 +54,28 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorNamedReference(errorNamedReference: FirErrorNamedReference, data: CheckerContext) {
|
override fun visitErrorNamedReference(errorNamedReference: FirErrorNamedReference, data: CheckerContext) {
|
||||||
val source = errorNamedReference.source ?: return
|
processErrorReference(errorNamedReference, errorNamedReference.diagnostic, data)
|
||||||
val qualifiedAccessOrAnnotationCall = data.qualifiedAccessOrAnnotationCalls.lastOrNull()?.takeIf {
|
}
|
||||||
|
|
||||||
|
override fun visitResolvedErrorReference(resolvedErrorReference: FirResolvedErrorReference, data: CheckerContext) {
|
||||||
|
processErrorReference(resolvedErrorReference, resolvedErrorReference.diagnostic, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processErrorReference(reference: FirNamedReference, diagnostic: ConeDiagnostic, context: CheckerContext) {
|
||||||
|
val source = reference.source ?: return
|
||||||
|
val qualifiedAccessOrAnnotationCall = context.qualifiedAccessOrAnnotationCalls.lastOrNull()?.takeIf {
|
||||||
// Use the source of the enclosing FirQualifiedAccess if it is exactly the call to the erroneous callee.
|
// Use the source of the enclosing FirQualifiedAccess if it is exactly the call to the erroneous callee.
|
||||||
when (it) {
|
when (it) {
|
||||||
is FirQualifiedAccess -> it.calleeReference == errorNamedReference
|
is FirQualifiedAccess -> it.calleeReference == reference
|
||||||
is FirAnnotationCall -> it.calleeReference == errorNamedReference
|
is FirAnnotationCall -> it.calleeReference == reference
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
|
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
|
||||||
if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && errorNamedReference.diagnostic is ConeUnresolvedNameError) return
|
if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && diagnostic is ConeUnresolvedNameError) return
|
||||||
// Already reported in FirConventionFunctionCallChecker
|
// Already reported in FirConventionFunctionCallChecker
|
||||||
if (source.kind == KtFakeSourceElementKind.ArrayAccessNameReference &&
|
if (source.kind == KtFakeSourceElementKind.ArrayAccessNameReference &&
|
||||||
errorNamedReference.diagnostic is ConeUnresolvedNameError
|
diagnostic is ConeUnresolvedNameError
|
||||||
) return
|
) return
|
||||||
|
|
||||||
// If the receiver cannot be resolved, we skip reporting any further problems for this call.
|
// If the receiver cannot be resolved, we skip reporting any further problems for this call.
|
||||||
@@ -76,7 +86,7 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
) return
|
) return
|
||||||
}
|
}
|
||||||
|
|
||||||
reportFirDiagnostic(errorNamedReference.diagnostic, source, data, qualifiedAccessOrAnnotationCall?.source)
|
reportFirDiagnostic(diagnostic, source, context, qualifiedAccessOrAnnotationCall?.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirExpression?.cannotBeResolved(): Boolean {
|
private fun FirExpression?.cannotBeResolved(): Boolean {
|
||||||
|
|||||||
@@ -1302,6 +1302,18 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
|||||||
simpleName(reference.name)
|
simpleName(reference.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is FirResolvedErrorReference -> {
|
||||||
|
errorWithDiagnostic {
|
||||||
|
resolved {
|
||||||
|
symbolRef(reference.resolvedSymbol) {
|
||||||
|
simpleName(reference.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diagnosticHover {
|
||||||
|
generate(reference.diagnostic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
is FirResolvedNamedReference -> {
|
is FirResolvedNamedReference -> {
|
||||||
resolved {
|
resolved {
|
||||||
symbolRef(reference.resolvedSymbol) {
|
symbolRef(reference.resolvedSymbol) {
|
||||||
|
|||||||
@@ -197,15 +197,6 @@ fun FirReference.toSymbolForCall(
|
|||||||
isReference
|
isReference
|
||||||
)
|
)
|
||||||
|
|
||||||
is FirErrorNamedReference ->
|
|
||||||
candidateSymbol?.toSymbolForCall(
|
|
||||||
dispatchReceiver,
|
|
||||||
preferGetter,
|
|
||||||
explicitReceiver,
|
|
||||||
isDelegate,
|
|
||||||
isReference
|
|
||||||
)
|
|
||||||
|
|
||||||
is FirThisReference -> {
|
is FirThisReference -> {
|
||||||
when (val boundSymbol = boundSymbol) {
|
when (val boundSymbol = boundSymbol) {
|
||||||
is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol).owner.thisReceiver?.symbol
|
is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol).owner.thisReceiver?.symbol
|
||||||
|
|||||||
+3
-6
@@ -1066,12 +1066,9 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
if (ownerFunction?.extensionReceiverParameter != null) {
|
if (ownerFunction?.extensionReceiverParameter != null) {
|
||||||
extensionReceiver = qualifiedAccess.findIrExtensionReceiver(explicitReceiverExpression)?.let {
|
extensionReceiver = qualifiedAccess.findIrExtensionReceiver(explicitReceiverExpression)?.let {
|
||||||
val symbol = when (val reference = qualifiedAccess.calleeReference) {
|
val symbol = qualifiedAccess.calleeReference.toResolvedCallableSymbol()
|
||||||
is FirResolvedNamedReference -> reference.resolvedSymbol
|
?: error("Symbol for call ${qualifiedAccess.render()} not found")
|
||||||
is FirErrorNamedReference -> reference.candidateSymbol
|
symbol.fir.receiverParameter?.typeRef?.let { receiverType ->
|
||||||
else -> null
|
|
||||||
} ?: error("Symbol for call ${qualifiedAccess.render()} not found")
|
|
||||||
(symbol.fir as? FirCallableDeclaration)?.receiverParameter?.typeRef?.let { receiverType ->
|
|
||||||
with(visitor.implicitCastInserter) {
|
with(visitor.implicitCastInserter) {
|
||||||
it.cast(
|
it.cast(
|
||||||
qualifiedAccess.extensionReceiver,
|
qualifiedAccess.extensionReceiver,
|
||||||
|
|||||||
+10
-6
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirElement
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||||
@@ -18,6 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
|||||||
import org.jetbrains.kotlin.fir.isCatchParameter
|
import org.jetbrains.kotlin.fir.isCatchParameter
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.renderer.FirRenderer
|
import org.jetbrains.kotlin.fir.renderer.FirRenderer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
@@ -82,12 +84,14 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitQualifiedAccess(qualifiedAccess: FirQualifiedAccess, data: FirElement) {
|
override fun visitQualifiedAccess(qualifiedAccess: FirQualifiedAccess, data: FirElement) {
|
||||||
val calleeReference = qualifiedAccess.calleeReference
|
when (val calleeReference = qualifiedAccess.calleeReference) {
|
||||||
if (calleeReference is FirErrorNamedReference) {
|
is FirErrorNamedReference, is FirResolvedErrorReference -> {
|
||||||
errorReferences++
|
errorReferences++
|
||||||
println(calleeReference.diagnostic.reason)
|
println((calleeReference as FirDiagnosticHolder).diagnostic.reason)
|
||||||
} else {
|
}
|
||||||
normalReferences++
|
else -> {
|
||||||
|
normalReferences++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
visitStatement(qualifiedAccess, data)
|
visitStatement(qualifiedAccess, data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -285,6 +285,7 @@ class FirCallResolver(
|
|||||||
|
|
||||||
val diagnostic = when (nameReference) {
|
val diagnostic = when (nameReference) {
|
||||||
is FirErrorReferenceWithCandidate -> nameReference.diagnostic
|
is FirErrorReferenceWithCandidate -> nameReference.diagnostic
|
||||||
|
is FirResolvedErrorReference -> nameReference.diagnostic
|
||||||
is FirErrorNamedReference -> nameReference.diagnostic
|
is FirErrorNamedReference -> nameReference.diagnostic
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -371,7 +372,7 @@ class FirCallResolver(
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
noSuccessfulCandidates -> {
|
noSuccessfulCandidates -> {
|
||||||
val errorReference = buildErrorReference(
|
val errorReference = buildReferenceWithErrorCandidate(
|
||||||
info,
|
info,
|
||||||
if (applicability == CandidateApplicability.K2_UNSUPPORTED) {
|
if (applicability == CandidateApplicability.K2_UNSUPPORTED) {
|
||||||
val unsupportedResolutionDiagnostic = reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported
|
val unsupportedResolutionDiagnostic = reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported
|
||||||
@@ -386,7 +387,7 @@ class FirCallResolver(
|
|||||||
}
|
}
|
||||||
reducedCandidates.size > 1 -> {
|
reducedCandidates.size > 1 -> {
|
||||||
if (resolvedCallableReferenceAtom.hasBeenPostponed) {
|
if (resolvedCallableReferenceAtom.hasBeenPostponed) {
|
||||||
val errorReference = buildErrorReference(
|
val errorReference = buildReferenceWithErrorCandidate(
|
||||||
info,
|
info,
|
||||||
ConeAmbiguityError(info.name, applicability, reducedCandidates),
|
ConeAmbiguityError(info.name, applicability, reducedCandidates),
|
||||||
callableReferenceAccess.source
|
callableReferenceAccess.source
|
||||||
@@ -530,7 +531,7 @@ class FirCallResolver(
|
|||||||
explicitReceiver = null
|
explicitReceiver = null
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
buildErrorReference(
|
buildReferenceWithErrorCandidate(
|
||||||
callInfo,
|
callInfo,
|
||||||
if (annotationClassSymbol != null) ConeIllegalAnnotationError(reference.name)
|
if (annotationClassSymbol != null) ConeIllegalAnnotationError(reference.name)
|
||||||
//calleeReference and annotationTypeRef are both error nodes so we need to avoid doubling of the diagnostic report
|
//calleeReference and annotationTypeRef are both error nodes so we need to avoid doubling of the diagnostic report
|
||||||
@@ -635,133 +636,132 @@ class FirCallResolver(
|
|||||||
expectedCandidates: Collection<Candidate>? = null
|
expectedCandidates: Collection<Candidate>? = null
|
||||||
): FirNamedReference {
|
): FirNamedReference {
|
||||||
val source = reference.source
|
val source = reference.source
|
||||||
return when {
|
|
||||||
|
val diagnostic = when {
|
||||||
expectedCallKind != null -> {
|
expectedCallKind != null -> {
|
||||||
fun isValueParametersNotEmpty(candidate: Candidate): Boolean {
|
fun isValueParametersNotEmpty(candidate: Candidate): Boolean {
|
||||||
return (candidate.symbol.fir as? FirFunction)?.valueParameters?.size?.let { it > 0 } ?: false
|
return (candidate.symbol.fir as? FirFunction)?.valueParameters?.size?.let { it > 0 } ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
val candidate = candidates.singleOrNull()
|
when (expectedCallKind) {
|
||||||
|
CallKind.Function -> ConeFunctionCallExpectedError(name, candidates.any { isValueParametersNotEmpty(it) }, candidates)
|
||||||
|
else -> {
|
||||||
|
val singleExpectedCandidate = expectedCandidates?.singleOrNull()
|
||||||
|
|
||||||
val diagnostic = if (expectedCallKind == CallKind.Function) {
|
var fir = singleExpectedCandidate?.symbol?.fir
|
||||||
ConeFunctionCallExpectedError(name, candidates.any { isValueParametersNotEmpty(it) }, candidates)
|
if (fir is FirTypeAlias) {
|
||||||
} else {
|
fir = (fir.expandedTypeRef.coneType.fullyExpandedType(session).toSymbol(session) as? FirRegularClassSymbol)?.fir
|
||||||
val singleExpectedCandidate = expectedCandidates?.singleOrNull()
|
}
|
||||||
|
|
||||||
var fir = singleExpectedCandidate?.symbol?.fir
|
when (fir) {
|
||||||
if (fir is FirTypeAlias) {
|
is FirRegularClass -> {
|
||||||
fir = (fir.expandedTypeRef.coneType.fullyExpandedType(session).toSymbol(session) as? FirRegularClassSymbol)?.fir
|
ConeResolutionToClassifierError(singleExpectedCandidate!!, fir.symbol)
|
||||||
}
|
|
||||||
|
|
||||||
if (fir is FirRegularClass) {
|
|
||||||
ConeResolutionToClassifierError(singleExpectedCandidate!!, fir.symbol)
|
|
||||||
} else {
|
|
||||||
val coneType = explicitReceiver?.typeRef?.coneType
|
|
||||||
when {
|
|
||||||
coneType != null && !coneType.isUnit -> {
|
|
||||||
ConeFunctionExpectedError(
|
|
||||||
name.asString(),
|
|
||||||
(fir as? FirCallableDeclaration)?.returnTypeRef?.coneType ?: coneType
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
singleExpectedCandidate != null && !singleExpectedCandidate.currentApplicability.isSuccess -> {
|
else -> {
|
||||||
createConeDiagnosticForCandidateWithError(
|
val coneType = explicitReceiver?.typeRef?.coneType
|
||||||
singleExpectedCandidate.currentApplicability,
|
when {
|
||||||
singleExpectedCandidate
|
coneType != null && !coneType.isUnit -> {
|
||||||
)
|
ConeFunctionExpectedError(
|
||||||
|
name.asString(),
|
||||||
|
(fir as? FirCallableDeclaration)?.returnTypeRef?.coneType ?: coneType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
singleExpectedCandidate != null && !singleExpectedCandidate.currentApplicability.isSuccess -> {
|
||||||
|
createConeDiagnosticForCandidateWithError(
|
||||||
|
singleExpectedCandidate.currentApplicability,
|
||||||
|
singleExpectedCandidate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> ConeUnresolvedNameError(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> ConeUnresolvedNameError(name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidate != null) {
|
|
||||||
createErrorReferenceWithExistingCandidate(
|
|
||||||
candidate,
|
|
||||||
diagnostic,
|
|
||||||
source,
|
|
||||||
transformer.resolutionContext,
|
|
||||||
components.resolutionStageRunner
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
buildErrorReference(callInfo, diagnostic, source)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates.isEmpty() -> {
|
candidates.isEmpty() -> {
|
||||||
val diagnostic = if (name.asString() == "invoke" && explicitReceiver is FirConstExpression<*>) {
|
if (name.asString() == "invoke" && explicitReceiver is FirConstExpression<*>) {
|
||||||
ConeFunctionExpectedError(explicitReceiver.value?.toString() ?: "", explicitReceiver.typeRef.coneType)
|
ConeFunctionExpectedError(explicitReceiver.value?.toString() ?: "", explicitReceiver.typeRef.coneType)
|
||||||
} else {
|
} else {
|
||||||
ConeUnresolvedNameError(name)
|
ConeUnresolvedNameError(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
buildErrorReference(
|
|
||||||
callInfo,
|
|
||||||
diagnostic,
|
|
||||||
source
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates.size > 1 -> buildErrorReference(
|
candidates.size > 1 -> ConeAmbiguityError(name, applicability, candidates)
|
||||||
callInfo,
|
|
||||||
ConeAmbiguityError(name, applicability, candidates),
|
|
||||||
source
|
|
||||||
)
|
|
||||||
|
|
||||||
!applicability.isSuccess -> {
|
!applicability.isSuccess -> {
|
||||||
val candidate = candidates.single()
|
val candidate = candidates.single()
|
||||||
val diagnostic = createConeDiagnosticForCandidateWithError(applicability, candidate)
|
createConeDiagnosticForCandidateWithError(applicability, candidate)
|
||||||
createErrorReferenceWithExistingCandidate(
|
|
||||||
candidate,
|
|
||||||
diagnostic,
|
|
||||||
source,
|
|
||||||
transformer.resolutionContext,
|
|
||||||
components.resolutionStageRunner
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> null
|
||||||
val candidate = candidates.single()
|
}
|
||||||
val coneSymbol = candidate.symbol
|
|
||||||
if (coneSymbol is FirBackingFieldSymbol) {
|
if (diagnostic != null) {
|
||||||
coneSymbol.fir.propertySymbol.fir.isReferredViaField = true
|
return createErrorReferenceForSingleCandidate(candidates.singleOrNull(), diagnostic, callInfo, source)
|
||||||
return buildBackingFieldReference {
|
}
|
||||||
this.source = source
|
|
||||||
resolvedSymbol = coneSymbol
|
// successful candidate
|
||||||
}
|
|
||||||
}
|
val candidate = candidates.single()
|
||||||
if ((coneSymbol as? FirPropertySymbol)?.hasExplicitBackingField == true) {
|
val coneSymbol = candidate.symbol
|
||||||
return FirPropertyWithExplicitBackingFieldResolvedNamedReference(
|
if (coneSymbol is FirBackingFieldSymbol) {
|
||||||
source, name, candidate.symbol, candidate.hasVisibleBackingField
|
coneSymbol.fir.propertySymbol.fir.isReferredViaField = true
|
||||||
)
|
return buildBackingFieldReference {
|
||||||
}
|
this.source = source
|
||||||
/*
|
resolvedSymbol = coneSymbol
|
||||||
* This `if` is an optimization for local variables and properties without type parameters
|
|
||||||
* Since they have no type variables, so we can don't run completion on them at all and create
|
|
||||||
* resolved reference immediately
|
|
||||||
*
|
|
||||||
* But for callable reference resolution we should keep candidate, because it was resolved
|
|
||||||
* with special resolution stages, which saved in candidate additional reference info,
|
|
||||||
* like `resultingTypeForCallableReference`
|
|
||||||
*/
|
|
||||||
if (
|
|
||||||
createResolvedReferenceWithoutCandidateForLocalVariables &&
|
|
||||||
explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() == null &&
|
|
||||||
coneSymbol is FirVariableSymbol &&
|
|
||||||
(coneSymbol !is FirPropertySymbol || (coneSymbol.fir as FirMemberDeclaration).typeParameters.isEmpty())
|
|
||||||
) {
|
|
||||||
return buildResolvedNamedReference {
|
|
||||||
this.source = source
|
|
||||||
this.name = name
|
|
||||||
resolvedSymbol = coneSymbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FirNamedReferenceWithCandidate(source, name, candidate)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((coneSymbol as? FirPropertySymbol)?.hasExplicitBackingField == true) {
|
||||||
|
return FirPropertyWithExplicitBackingFieldResolvedNamedReference(
|
||||||
|
source, name, candidate.symbol, candidate.hasVisibleBackingField
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This `if` is an optimization for local variables and properties without type parameters
|
||||||
|
* Since they have no type variables, so we can don't run completion on them at all and create
|
||||||
|
* resolved reference immediately
|
||||||
|
*
|
||||||
|
* But for callable reference resolution we should keep candidate, because it was resolved
|
||||||
|
* with special resolution stages, which saved in candidate additional reference info,
|
||||||
|
* like `resultingTypeForCallableReference`
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
createResolvedReferenceWithoutCandidateForLocalVariables &&
|
||||||
|
explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() == null &&
|
||||||
|
coneSymbol is FirVariableSymbol &&
|
||||||
|
(coneSymbol !is FirPropertySymbol || (coneSymbol.fir as FirMemberDeclaration).typeParameters.isEmpty())
|
||||||
|
) {
|
||||||
|
return buildResolvedNamedReference {
|
||||||
|
this.source = source
|
||||||
|
this.name = name
|
||||||
|
resolvedSymbol = coneSymbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FirNamedReferenceWithCandidate(source, name, candidate)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createErrorReferenceForSingleCandidate(
|
||||||
|
candidate: Candidate?,
|
||||||
|
diagnostic: ConeDiagnostic,
|
||||||
|
callInfo: CallInfo,
|
||||||
|
source: KtSourceElement?
|
||||||
|
): FirNamedReference {
|
||||||
|
if (candidate == null) return buildReferenceWithErrorCandidate(callInfo, diagnostic, source)
|
||||||
|
return when (diagnostic) {
|
||||||
|
is ConeUnresolvedError, is ConeHiddenCandidateError -> buildReferenceWithErrorCandidate(callInfo, diagnostic, source)
|
||||||
|
else -> createErrorReferenceWithExistingCandidate(
|
||||||
|
candidate,
|
||||||
|
diagnostic,
|
||||||
|
source,
|
||||||
|
transformer.resolutionContext,
|
||||||
|
components.resolutionStageRunner
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildErrorReference(
|
private fun buildReferenceWithErrorCandidate(
|
||||||
callInfo: CallInfo,
|
callInfo: CallInfo,
|
||||||
diagnostic: ConeDiagnostic,
|
diagnostic: ConeDiagnostic,
|
||||||
source: KtSourceElement?
|
source: KtSourceElement?
|
||||||
|
|||||||
+25
-16
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameterCopy
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirPropertyAccessExpressionImpl
|
|||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
@@ -37,9 +39,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.ConvertibleIntegerOperators.binaryOp
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
|
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperator
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperatorForUnsignedType
|
import org.jetbrains.kotlin.fir.scopes.impl.isWrappedIntegerOperatorForUnsignedType
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
@@ -379,11 +379,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, typeRef.source ?: callableReferenceAccess.source, context.file.source)
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, typeRef.source ?: callableReferenceAccess.source, context.file.source)
|
||||||
|
|
||||||
val resolvedReference = when (calleeReference) {
|
val resolvedReference = when (calleeReference) {
|
||||||
is FirErrorReferenceWithCandidate -> buildErrorNamedReference {
|
is FirErrorReferenceWithCandidate -> calleeReference.toErrorReference(calleeReference.diagnostic)
|
||||||
source = calleeReference.source
|
|
||||||
diagnostic = calleeReference.diagnostic
|
|
||||||
candidateSymbol = calleeReference.candidateSymbol
|
|
||||||
}
|
|
||||||
else -> buildResolvedCallableReference {
|
else -> buildResolvedCallableReference {
|
||||||
source = calleeReference.source
|
source = calleeReference.source
|
||||||
name = calleeReference.name
|
name = calleeReference.name
|
||||||
@@ -400,6 +396,23 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
.transformExtensionReceiver(StoreReceiver, subCandidate.chosenExtensionReceiverExpression())
|
.transformExtensionReceiver(StoreReceiver, subCandidate.chosenExtensionReceiverExpression())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirNamedReferenceWithCandidate.toErrorReference(diagnostic: ConeDiagnostic): FirNamedReference {
|
||||||
|
val calleeReference = this
|
||||||
|
return when (calleeReference.candidateSymbol) {
|
||||||
|
is FirErrorPropertySymbol, is FirErrorFunctionSymbol -> buildErrorNamedReference {
|
||||||
|
source = calleeReference.source
|
||||||
|
candidateSymbol = calleeReference.candidateSymbol
|
||||||
|
this.diagnostic = diagnostic
|
||||||
|
}
|
||||||
|
else -> buildResolvedErrorReference {
|
||||||
|
source = calleeReference.source
|
||||||
|
name = calleeReference.name
|
||||||
|
resolvedSymbol = calleeReference.candidateSymbol
|
||||||
|
this.diagnostic = diagnostic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun transformVariableAssignment(
|
override fun transformVariableAssignment(
|
||||||
variableAssignment: FirVariableAssignment,
|
variableAssignment: FirVariableAssignment,
|
||||||
data: ExpectedArgumentType?,
|
data: ExpectedArgumentType?,
|
||||||
@@ -866,18 +879,14 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (errorDiagnostic != null) {
|
return when (errorDiagnostic) {
|
||||||
buildErrorNamedReference {
|
null -> buildResolvedNamedReference {
|
||||||
source = this@toResolvedReference.source
|
|
||||||
diagnostic = errorDiagnostic
|
|
||||||
candidateSymbol = this@toResolvedReference.candidateSymbol
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buildResolvedNamedReference {
|
|
||||||
source = this@toResolvedReference.source
|
source = this@toResolvedReference.source
|
||||||
name = this@toResolvedReference.name
|
name = this@toResolvedReference.name
|
||||||
resolvedSymbol = this@toResolvedReference.candidateSymbol
|
resolvedSymbol = this@toResolvedReference.candidateSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else -> toErrorReference(errorDiagnostic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-5
@@ -14,13 +14,13 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
|
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.scope
|
import org.jetbrains.kotlin.fir.resolve.scope
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolvedSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.scopes.getFunctions
|
import org.jetbrains.kotlin.fir.scopes.getFunctions
|
||||||
@@ -90,13 +90,21 @@ class IntegerLiteralAndOperatorApproximationTransformer(
|
|||||||
val wrappedFunctionSymbol = calleeReference.resolvedSymbol as FirNamedFunctionSymbol
|
val wrappedFunctionSymbol = calleeReference.resolvedSymbol as FirNamedFunctionSymbol
|
||||||
val originalFunctionSymbol = wrappedFunctionSymbol.fir.originalForWrappedIntegerOperator!!
|
val originalFunctionSymbol = wrappedFunctionSymbol.fir.originalForWrappedIntegerOperator!!
|
||||||
|
|
||||||
call.replaceCalleeReference(
|
val newCalleeReference = when (calleeReference) {
|
||||||
buildResolvedNamedReference {
|
is FirResolvedErrorReference -> buildResolvedErrorReference {
|
||||||
|
name = calleeReference.name
|
||||||
|
source = calleeReference.source
|
||||||
|
resolvedSymbol = originalFunctionSymbol
|
||||||
|
diagnostic = calleeReference.diagnostic
|
||||||
|
}
|
||||||
|
else -> buildResolvedNamedReference {
|
||||||
name = calleeReference.name
|
name = calleeReference.name
|
||||||
source = calleeReference.source
|
source = calleeReference.source
|
||||||
resolvedSymbol = originalFunctionSymbol
|
resolvedSymbol = originalFunctionSymbol
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
|
call.replaceCalleeReference(newCalleeReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (approximatedType.isInt || approximatedType.isUInt) return call
|
if (approximatedType.isInt || approximatedType.isUInt) return call
|
||||||
|
|||||||
+2
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArrayOfCall
|
import org.jetbrains.kotlin.fir.expressions.builder.buildArrayOfCall
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
@@ -79,6 +80,7 @@ internal class FirArrayOfCallTransformer : FirDefaultTransformer<Nothing?>() {
|
|||||||
|
|
||||||
private fun FirFunctionCall.getOriginalFunction(): FirCallableDeclaration? {
|
private fun FirFunctionCall.getOriginalFunction(): FirCallableDeclaration? {
|
||||||
val symbol: FirBasedSymbol<*>? = when (val reference = calleeReference) {
|
val symbol: FirBasedSymbol<*>? = when (val reference = calleeReference) {
|
||||||
|
is FirResolvedErrorReference -> null
|
||||||
is FirResolvedNamedReference -> reference.resolvedSymbol
|
is FirResolvedNamedReference -> reference.resolvedSymbol
|
||||||
is FirNamedReferenceWithCandidate -> reference.candidateSymbol
|
is FirNamedReferenceWithCandidate -> reference.candidateSymbol
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
+3
-1
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildReturnExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildReturnExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildUnitExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildUnitExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirLazyBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirLazyBlock
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||||
@@ -362,7 +363,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
|
|||||||
return provideDelegateCall
|
return provideDelegateCall
|
||||||
}
|
}
|
||||||
|
|
||||||
if (provideDelegateCall.calleeReference is FirResolvedNamedReference) {
|
val provideDelegateReference = provideDelegateCall.calleeReference
|
||||||
|
if (provideDelegateReference is FirResolvedNamedReference && provideDelegateReference !is FirResolvedErrorReference) {
|
||||||
return provideDelegateCall
|
return provideDelegateCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.extensions.extensionService
|
|||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
||||||
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.*
|
||||||
@@ -891,9 +892,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val altererNames = alteredAssignments.map { it.second::class.qualifiedName }
|
val altererNames = alteredAssignments.map { it.second::class.qualifiedName }
|
||||||
val errorReference = buildErrorNamedReference {
|
val errorReference = buildResolvedErrorReference {
|
||||||
source = resolvedReference.source
|
source = resolvedReference.source
|
||||||
candidateSymbol = resolvedReference.resolvedSymbol
|
name = resolvedReference.name
|
||||||
|
resolvedSymbol = resolvedReference.resolvedSymbol
|
||||||
diagnostic = ConeAmbiguousAlteredAssign(altererNames)
|
diagnostic = ConeAmbiguousAlteredAssign(altererNames)
|
||||||
}
|
}
|
||||||
completeAssignment.replaceCalleeReference(errorReference)
|
completeAssignment.replaceCalleeReference(errorReference)
|
||||||
|
|||||||
@@ -839,9 +839,16 @@ class FirRenderer(
|
|||||||
}
|
}
|
||||||
print(">")
|
print(">")
|
||||||
}
|
}
|
||||||
|
if (resolvedNamedReference is FirResolvedErrorReference) {
|
||||||
|
print("<${resolvedNamedReference.diagnostic.reason}>#")
|
||||||
|
}
|
||||||
print("|")
|
print("|")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitResolvedErrorReference(resolvedErrorReference: FirResolvedErrorReference) {
|
||||||
|
visitResolvedNamedReference(resolvedErrorReference)
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirBasedSymbol<*>.unwrapIntersectionOverrides(): FirBasedSymbol<*> {
|
private fun FirBasedSymbol<*>.unwrapIntersectionOverrides(): FirBasedSymbol<*> {
|
||||||
(this as? FirCallableSymbol<*>)?.baseForIntersectionOverride?.let { return it.unwrapIntersectionOverrides() }
|
(this as? FirCallableSymbol<*>)?.baseForIntersectionOverride?.let { return it.unwrapIntersectionOverrides() }
|
||||||
return this
|
return this
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ import org.jetbrains.kotlin.KtIoFileSourceFile
|
|||||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirGlobalResolveProcessor
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirGlobalResolveProcessor
|
||||||
@@ -281,8 +283,8 @@ class FirResolveBench(val withProgress: Boolean, val listener: BenchListener? =
|
|||||||
if (type is ConeErrorType) {
|
if (type is ConeErrorType) {
|
||||||
errorFunctionCallTypes++
|
errorFunctionCallTypes++
|
||||||
val psi = callee.psi
|
val psi = callee.psi
|
||||||
if (callee is FirErrorNamedReference && psi != null) {
|
if ((callee is FirErrorNamedReference || callee is FirResolvedErrorReference) && psi != null) {
|
||||||
reportProblem(callee.diagnostic.reason, psi)
|
reportProblem((callee as FirDiagnosticHolder).diagnostic.reason, psi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,8 +300,8 @@ class FirResolveBench(val withProgress: Boolean, val listener: BenchListener? =
|
|||||||
if (type is ConeErrorType) {
|
if (type is ConeErrorType) {
|
||||||
errorQualifiedAccessTypes++
|
errorQualifiedAccessTypes++
|
||||||
val psi = callee.psi
|
val psi = callee.psi
|
||||||
if (callee is FirErrorNamedReference && psi != null) {
|
if ((callee is FirErrorNamedReference || callee is FirResolvedErrorReference) && psi != null) {
|
||||||
reportProblem(callee.diagnostic.reason, psi)
|
reportProblem((callee as FirDiagnosticHolder).diagnostic.reason, psi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-2
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
@@ -675,12 +676,16 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
|
|
||||||
override fun visitNamedReference(namedReference: FirNamedReference, data: StringBuilder) {
|
override fun visitNamedReference(namedReference: FirNamedReference, data: StringBuilder) {
|
||||||
if (namedReference is FirErrorNamedReference) {
|
if (namedReference is FirErrorNamedReference) {
|
||||||
data.append("[ERROR : ${namedReference.diagnostic.reason}]")
|
data.append(namedReference.diagnostic.dump())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
visitElement(namedReference, data)
|
visitElement(namedReference, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ConeDiagnostic.dump(): String {
|
||||||
|
return "[ERROR : ${reason}]"
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitResolvedNamedReference(resolvedNamedReference: FirResolvedNamedReference, data: StringBuilder) {
|
override fun visitResolvedNamedReference(resolvedNamedReference: FirResolvedNamedReference, data: StringBuilder) {
|
||||||
val symbol = resolvedNamedReference.resolvedSymbol
|
val symbol = resolvedNamedReference.resolvedSymbol
|
||||||
renderImplicitReceiver(symbol, resolvedNamedReference.source.psi)
|
renderImplicitReceiver(symbol, resolvedNamedReference.source.psi)
|
||||||
@@ -698,6 +703,11 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitResolvedErrorReference(resolvedErrorReference: FirResolvedErrorReference, data: StringBuilder) {
|
||||||
|
visitResolvedNamedReference(resolvedErrorReference, data)
|
||||||
|
data.append(resolvedErrorReference.diagnostic.dump())
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitResolvedCallableReference(resolvedCallableReference: FirResolvedCallableReference, data: StringBuilder) {
|
override fun visitResolvedCallableReference(resolvedCallableReference: FirResolvedCallableReference, data: StringBuilder) {
|
||||||
when (val symbol = resolvedCallableReference.resolvedSymbol) {
|
when (val symbol = resolvedCallableReference.resolvedSymbol) {
|
||||||
is FirPropertySymbol -> renderPropertySymbol(symbol, data)
|
is FirPropertySymbol -> renderPropertySymbol(symbol, data)
|
||||||
@@ -772,8 +782,11 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
is FirConstructorSymbol -> visitConstructor(callee.resolvedSymbol.fir as FirConstructor, data)
|
is FirConstructorSymbol -> visitConstructor(callee.resolvedSymbol.fir as FirConstructor, data)
|
||||||
else -> renderFunctionSymbol(callee.resolvedSymbol as FirNamedFunctionSymbol, data, functionCall)
|
else -> renderFunctionSymbol(callee.resolvedSymbol as FirNamedFunctionSymbol, data, functionCall)
|
||||||
}
|
}
|
||||||
|
if (callee is FirResolvedErrorReference) {
|
||||||
|
data.append(callee.diagnostic.dump())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is FirErrorNamedReference -> data.append("[ERROR : ${callee.diagnostic.reason}]")
|
is FirErrorNamedReference -> data.append(callee.diagnostic.dump())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -16,10 +16,12 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
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.expression.FirFunctionCallChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.arguments
|
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithSingleCandidate
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithSingleCandidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||||
@@ -42,10 +44,13 @@ object FirAssignmentPluginFunctionCallChecker : FirFunctionCallChecker() {
|
|||||||
private fun FirFunctionCall.isOverloadAssignCallCandidate() =
|
private fun FirFunctionCall.isOverloadAssignCallCandidate() =
|
||||||
arguments.size == 1 && source?.kind == KtFakeSourceElementKind.DesugaredCompoundAssignment
|
arguments.size == 1 && source?.kind == KtFakeSourceElementKind.DesugaredCompoundAssignment
|
||||||
|
|
||||||
private fun FirFunctionCall.isFunctionResolveError() = calleeReference is FirErrorNamedReference
|
private fun FirFunctionCall.isFunctionResolveError() = when(calleeReference){
|
||||||
|
is FirErrorNamedReference, is FirResolvedErrorReference -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirFunctionCall.isOverloadedAssignCallError(session: FirSession): Boolean {
|
private fun FirFunctionCall.isOverloadedAssignCallError(session: FirSession): Boolean {
|
||||||
val functionName = when (val diagnostic = (calleeReference as? FirErrorNamedReference)?.diagnostic) {
|
val functionName = when (val diagnostic = (calleeReference as? FirDiagnosticHolder)?.diagnostic) {
|
||||||
is ConeAmbiguityError -> diagnostic.name
|
is ConeAmbiguityError -> diagnostic.name
|
||||||
is ConeDiagnosticWithSingleCandidate -> diagnostic.candidate.callInfo.name
|
is ConeDiagnosticWithSingleCandidate -> diagnostic.candidate.callInfo.name
|
||||||
is ConeUnresolvedNameError -> diagnostic.name
|
is ConeUnresolvedNameError -> diagnostic.name
|
||||||
|
|||||||
Reference in New Issue
Block a user