FIR: report resolve-time errors on qualified access instead of reference
This commit is contained in:
+21
-1
@@ -11,17 +11,18 @@ import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||
import org.jetbrains.kotlin.fir.resolve.ImplicitReceiverStack
|
||||
import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack
|
||||
import org.jetbrains.kotlin.fir.resolve.SessionHolder
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitReceiverValue
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableArgumentDiagnostic
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
abstract class CheckerContext {
|
||||
abstract val implicitReceiverStack: ImplicitReceiverStack
|
||||
abstract val containingDeclarations: List<FirDeclaration>
|
||||
abstract val qualifiedAccesses: List<FirQualifiedAccess>
|
||||
abstract val sessionHolder: SessionHolder
|
||||
abstract val returnTypeCalculator: ReturnTypeCalculator
|
||||
abstract val suppressedDiagnostics: Set<String>
|
||||
@@ -48,6 +49,7 @@ abstract class CheckerContext {
|
||||
class PersistentCheckerContext private constructor(
|
||||
override val implicitReceiverStack: PersistentImplicitReceiverStack,
|
||||
override val containingDeclarations: PersistentList<FirDeclaration>,
|
||||
override val qualifiedAccesses: PersistentList<FirQualifiedAccess>,
|
||||
override val sessionHolder: SessionHolder,
|
||||
override val returnTypeCalculator: ReturnTypeCalculator,
|
||||
override val suppressedDiagnostics: PersistentSet<String>,
|
||||
@@ -58,6 +60,7 @@ class PersistentCheckerContext private constructor(
|
||||
constructor(sessionHolder: SessionHolder, returnTypeCalculator: ReturnTypeCalculator) : this(
|
||||
PersistentImplicitReceiverStack(),
|
||||
persistentListOf(),
|
||||
persistentListOf(),
|
||||
sessionHolder,
|
||||
returnTypeCalculator,
|
||||
persistentSetOf(),
|
||||
@@ -70,6 +73,7 @@ class PersistentCheckerContext private constructor(
|
||||
return PersistentCheckerContext(
|
||||
implicitReceiverStack.add(name, value),
|
||||
containingDeclarations,
|
||||
qualifiedAccesses,
|
||||
sessionHolder,
|
||||
returnTypeCalculator,
|
||||
suppressedDiagnostics,
|
||||
@@ -83,6 +87,21 @@ class PersistentCheckerContext private constructor(
|
||||
return PersistentCheckerContext(
|
||||
implicitReceiverStack,
|
||||
containingDeclarations.add(declaration),
|
||||
qualifiedAccesses,
|
||||
sessionHolder,
|
||||
returnTypeCalculator,
|
||||
suppressedDiagnostics,
|
||||
allInfosSuppressed,
|
||||
allWarningsSuppressed,
|
||||
allErrorsSuppressed
|
||||
)
|
||||
}
|
||||
|
||||
fun addQualifiedAccess(qualifiedAccess: FirQualifiedAccess): PersistentCheckerContext {
|
||||
return PersistentCheckerContext(
|
||||
implicitReceiverStack,
|
||||
containingDeclarations,
|
||||
qualifiedAccesses.add(qualifiedAccess),
|
||||
sessionHolder,
|
||||
returnTypeCalculator,
|
||||
suppressedDiagnostics,
|
||||
@@ -102,6 +121,7 @@ class PersistentCheckerContext private constructor(
|
||||
return PersistentCheckerContext(
|
||||
implicitReceiverStack,
|
||||
containingDeclarations,
|
||||
qualifiedAccesses,
|
||||
sessionHolder,
|
||||
returnTypeCalculator,
|
||||
suppressedDiagnostics.addAll(diagnosticNames),
|
||||
|
||||
+19
@@ -208,6 +208,14 @@ abstract class AbstractDiagnosticCollector(
|
||||
resolvedTypeRef.delegatedTypeRef?.accept(this, data)
|
||||
}
|
||||
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Nothing?) {
|
||||
visitWithQualifiedAccess(functionCall)
|
||||
}
|
||||
|
||||
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: Nothing?) {
|
||||
visitWithQualifiedAccess(qualifiedAccessExpression)
|
||||
}
|
||||
|
||||
private inline fun visitWithDeclaration(
|
||||
declaration: FirDeclaration,
|
||||
block: () -> Unit = { declaration.acceptChildren(this, null) }
|
||||
@@ -237,6 +245,17 @@ abstract class AbstractDiagnosticCollector(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun visitWithQualifiedAccess(qualifiedAccess: FirQualifiedAccess) {
|
||||
val existingContext = context
|
||||
context = context.addQualifiedAccess(qualifiedAccess)
|
||||
try {
|
||||
qualifiedAccess.runComponents()
|
||||
qualifiedAccess.acceptChildren(this, null)
|
||||
} finally {
|
||||
context = existingContext
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onDeclarationEnter(declaration: FirDeclaration): DiagnosticCollectorDeclarationAction =
|
||||
|
||||
+2
-1
@@ -34,7 +34,8 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
||||
}
|
||||
|
||||
override fun visitErrorNamedReference(errorNamedReference: FirErrorNamedReference, data: CheckerContext) {
|
||||
val source = errorNamedReference.source ?: return
|
||||
val source = data.qualifiedAccesses.lastOrNull()?.source?.takeIf { it.elementType == KtNodeTypes.DOT_QUALIFIED_EXPRESSION }
|
||||
?: errorNamedReference.source ?: return
|
||||
// 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
|
||||
reportFirDiagnostic(errorNamedReference.diagnostic, source, reporter, data)
|
||||
|
||||
Reference in New Issue
Block a user