[FIR] Refactor val FirElement.calleeReference utility

1. Convert it to `toReference()` function to make it consistent with other
   similar utilities
2. Provide the proper implementation

^KT-64975
This commit is contained in:
Dmitriy Novozhilov
2024-01-17 16:17:42 +02:00
committed by Space Team
parent 36958d585f
commit bd9cb2b7e0
21 changed files with 42 additions and 35 deletions
@@ -35,7 +35,7 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirEx
withClassEntry("annotationTypeRef", annotation.annotationTypeRef)
@OptIn(UnresolvedExpressionTypeAccess::class)
withClassEntry("coneTypeOrNull", annotation.coneTypeOrNull)
annotation.calleeReference?.let { withClassEntry("calleeReference", it) }
annotation.toReference()?.let { withClassEntry("calleeReference", it) }
}
return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name }
@@ -202,4 +202,4 @@ internal fun hasAnnotation(
private fun FirBasedSymbol<*>.isFromCompilerRequiredAnnotationsPhase(classId: ClassId, session: FirSession): Boolean {
val requiredAnnotations = session.annotationPlatformSupport.requiredAnnotations
return fir.resolvePhase < FirResolvePhase.TYPES && classId in requiredAnnotations
}
}
@@ -220,7 +220,7 @@ internal class KtFirCallResolver(
return when (this) {
is FirResolvable, is FirVariableAssignment -> {
when (val calleeReference = calleeReference) {
when (val calleeReference = toReference()) {
is FirResolvedErrorReference -> transformErrorReference(this, calleeReference)
is FirResolvedNamedReference -> when (calleeReference.resolvedSymbol) {
// `calleeReference.resolvedSymbol` isn't guaranteed to be callable. For example, function type parameters used in
@@ -222,7 +222,7 @@ internal class KtFirExpressionTypeProvider(
val (ktCallElement, argumentExpression) = expression.getFunctionCallAsWithThisAsParameter() ?: return null
val firCall = ktCallElement.getOrBuildFir(firResolveSession)?.unwrapSafeCall() as? FirCall ?: return null
val callee = (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol
val callee = (firCall.toReference() as? FirResolvedNamedReference)?.resolvedSymbol
if (callee?.fir?.origin == FirDeclarationOrigin.SamConstructor) {
val substitutor = (firCall as? FirQualifiedAccessExpression)
?.createConeSubstitutorFromTypeArguments(discardErrorTypes = true)
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableCandidate
@@ -138,7 +138,7 @@ class AllCandidatesResolver(private val firSession: FirSession) {
*/
private fun OverloadCandidate.preserveCalleeInapplicability() {
val callSite = candidate.callInfo.callSite
val calleeReference = callSite.calleeReference as? FirDiagnosticHolder ?: return
val calleeReference = callSite.toReference() as? FirDiagnosticHolder ?: return
val diagnostic = calleeReference.diagnostic as? ConeInapplicableCandidateError ?: return
if (diagnostic.applicability != CandidateApplicability.INAPPLICABLE) return
@@ -15,13 +15,14 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
import org.jetbrains.kotlin.fir.analysis.js.checkers.isPredefinedObject
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.name.JsStandardClassIds
object FirJsDefinedExternallyCallChecker : FirBasicExpressionChecker(MppCheckerKind.Common) {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
val symbol = expression.calleeReference?.toResolvedCallableSymbol() ?: return
val symbol = expression.toReference()?.toResolvedCallableSymbol() ?: return
if (symbol.callableId !in JsStandardClassIds.Callables.definedExternallyPropertyNames) {
return
@@ -64,7 +64,7 @@ object FirJsDynamicCallChecker : FirQualifiedAccessExpressionChecker(MppCheckerK
private val FirCall.isArrayAccessWithMultipleIndices: Boolean
get() {
val callee = calleeReference as? FirNamedReference
val callee = toReference() as? FirNamedReference
?: return false
if (callee.source?.kind != KtFakeSourceElementKind.ArrayAccessNameReference) {
@@ -39,7 +39,7 @@ object FirJvmProtectedInSuperClassCompanionCallChecker : FirBasicExpressionCheck
} ?: return
val dispatchClassSymbol = dispatchReceiver.resolvedType.toRegularClassSymbol(context.session) ?: return
val calleeReference = expression.calleeReference
val calleeReference = expression.toReference()
val resolvedSymbol = calleeReference?.toResolvedCallableSymbol() ?: return
val visibility = if (resolvedSymbol is FirPropertySymbol) {
@@ -14,13 +14,13 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionC
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors
import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.name.WebCommonStandardClassIds
object FirWasmDefinedExternallyCallChecker : FirBasicExpressionChecker(MppCheckerKind.Common) {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
val symbol = expression.calleeReference?.toResolvedCallableSymbol() ?: return
val symbol = expression.toReference()?.toResolvedCallableSymbol() ?: return
if (symbol.callableId != WebCommonStandardClassIds.Callables.JsDefinedExternally) {
return
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.delegateFieldsMap
import org.jetbrains.kotlin.fir.expressions.FirCall
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.coneType
@@ -27,7 +27,7 @@ object FirDelegateFieldTypeMismatchChecker : FirRegularClassChecker(MppCheckerKi
val supertype = declaration.superTypeRefs[it]
val field = declaration.delegateFieldsMap?.get(it)?.fir ?: continue
val initializer = field.initializer ?: continue
val isReportedByErrorNodeDiagnosticCollector = initializer is FirCall && initializer.calleeReference?.isError() == true
val isReportedByErrorNodeDiagnosticCollector = initializer is FirCall && initializer.toReference()?.isError() == true
if (
!isReportedByErrorNodeDiagnosticCollector &&
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClassId
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
@@ -40,7 +40,7 @@ abstract class AbstractFirReflectionApiCallChecker : FirBasicExpressionChecker(M
// Do not report the diagnostic on kotlin-reflect sources.
if (isReflectionSource(context)) return
val resolvedReference = expression.calleeReference?.resolved ?: return
val resolvedReference = expression.toReference()?.resolved ?: return
val referencedSymbol = resolvedReference.resolvedSymbol as? FirCallableSymbol ?: return
val containingClassId = (expression as? FirQualifiedAccessExpression)?.dispatchReceiver?.resolvedType?.fullyExpandedClassId(context.session)
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.fir.declarations.getOwnDeprecation
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.resolve.firClassLike
@@ -49,7 +49,7 @@ object FirDeprecationChecker : FirBasicExpressionChecker(MppCheckerKind.Common)
if (expression is FirAnnotation) return // checked by FirDeprecatedTypeChecker
if (expression.isLhsOfAssignment(context)) return
val calleeReference = expression.calleeReference ?: return
val calleeReference = expression.toReference() ?: return
val resolvedReference = calleeReference.resolved ?: return
val referencedSymbol = resolvedReference.resolvedSymbol
@@ -28,7 +28,7 @@ object FirOptInUsageAccessChecker : FirBasicExpressionChecker(MppCheckerKind.Com
if (expression.isLhsOfAssignment(context)) return
val resolvedSymbol = expression.calleeReference?.toResolvedBaseSymbol() ?: return
val resolvedSymbol = expression.toReference()?.toResolvedBaseSymbol() ?: return
with(FirOptInUsageBaseChecker) {
when {
@@ -60,7 +60,7 @@ class ErrorNodeDiagnosticCollectorComponent(
var source = reference.source
val callOrAssignment = context.callsOrAssignments.lastOrNull()?.takeIf {
// Use the source of the enclosing FirQualifiedAccess if it is exactly the call to the erroneous callee.
it.calleeReference == reference
it.toReference() == reference
}
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
if (source?.elementType == KtNodeTypes.ANNOTATION_ENTRY && diagnostic is ConeUnresolvedNameError) return
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.toReference
import org.jetbrains.kotlin.fir.expressions.unwrapSmartcastExpression
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference
@@ -84,7 +84,7 @@ object FirDiagnosticRenderers {
}
val CALLEE_NAME = Renderer { element: FirExpression ->
when (val reference = element.unwrapSmartcastExpression().calleeReference) {
when (val reference = element.unwrapSmartcastExpression().toReference()) {
is FirNamedReference -> reference.name.asString()
is FirThisReference -> "this"
is FirSuperReference -> "super"
@@ -1021,7 +1021,7 @@ class CallAndReferenceGenerator(
putValueArgument(valueParameters.indexOf(parameter) + contextReceiverCount, irArgument)
}
if (visitor.annotationMode) {
val function = call.calleeReference?.toResolvedCallableSymbol()?.fir as? FirFunction
val function = call.toReference()?.toResolvedCallableSymbol()?.fir as? FirFunction
for ((index, parameter) in valueParameters.withIndex()) {
if (parameter.isVararg && !argumentMapping.containsValue(parameter)) {
val value = if (function?.itOrExpectHasDefaultParameterValue(index) == true) {
@@ -1132,7 +1132,7 @@ class CallAndReferenceGenerator(
irConversionFunction: IrSimpleFunctionSymbol,
): IrExpression {
return if (argument.isIntegerLiteralOrOperatorCall() ||
argument.calleeReference?.toResolvedCallableSymbol()?.let {
argument.toReference()?.toResolvedCallableSymbol()?.let {
it.resolvedStatus.isConst && it.isMarkedWithImplicitIntegerCoercion
} == true
) {
@@ -114,7 +114,7 @@ class FirCallResolver(
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
// This branch support case for the call of the type `a.invoke()`
// 1. Handle candidate for `a`
(resolvedReceiver?.calleeReference as? FirNamedReferenceWithCandidate)?.candidate?.updateSourcesOfReceivers()
(resolvedReceiver?.toReference() as? FirNamedReferenceWithCandidate)?.candidate?.updateSourcesOfReceivers()
// 2. Handle candidate for `invoke`
candidate.updateSourcesOfReceivers()
functionCall.copyAsImplicitInvokeCall {
@@ -533,7 +533,7 @@ private fun getExpectedTypeWithImplicitIntegerCoercion(
if (argument.isIntegerLiteralOrOperatorCall()) {
argument.resolvedType
} else {
argument.calleeReference?.toResolvedCallableSymbol()?.takeIf {
argument.toReference()?.toResolvedCallableSymbol()?.takeIf {
it.rawStatus.isConst && it.isMarkedWithImplicitIntegerCoercion
}?.resolvedReturnType
}
@@ -785,7 +785,7 @@ internal object CheckHiddenDeclaration : ResolutionStage() {
}
private fun FirElement.isSuperCall(): Boolean =
this is FirQualifiedAccessExpression && explicitReceiver?.calleeReference is FirSuperReference
this is FirQualifiedAccessExpression && explicitReceiver?.toReference() is FirSuperReference
private fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean): Boolean {
val fir = fir
@@ -591,7 +591,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val generator = GeneratorOfPlusAssignCalls(
assignmentOperatorStatement,
assignmentOperatorStatement.calleeReference?.source,
assignmentOperatorStatement.toReference()?.source,
operation,
leftArgument,
rightArgument
@@ -213,7 +213,7 @@ abstract class AbstractFirSpecificAnnotationResolveTransformer(
// If fully qualified, check that given package name matches the resolved one.
val segments = generateSequence(receiver.explicitReceiver) { (it as? FirQualifiedAccessExpression)?.explicitReceiver }
.mapNotNull { (it.calleeReference as? FirSimpleNamedReference)?.name?.identifier }
.mapNotNull { (it.toReference() as? FirSimpleNamedReference)?.name?.identifier }
.toList()
if (segments.isNotEmpty() && FqName.fromSegments(segments.asReversed()) != symbol.classId.packageFqName) {
@@ -11,8 +11,13 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
return toReference()?.resolved
fun FirElement.toReference(): FirReference? {
return when (this) {
is FirExpression -> toReference()
is FirVariableAssignment -> calleeReference
is FirResolvable -> calleeReference
else -> null
}
}
fun FirExpression.toReference(): FirReference? {
@@ -25,11 +30,12 @@ fun FirExpression.toReference(): FirReference? {
}
}
val FirVariableAssignment.calleeReference: FirReference? get() = lValue.toReference()
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
return toReference()?.resolved
}
fun FirExpression.toResolvedCallableSymbol(): FirCallableSymbol<*>? {
return toResolvedCallableReference()?.resolvedSymbol as? FirCallableSymbol<*>?
}
val FirElement.calleeReference: FirReference?
get() = (this as? FirResolvable)?.calleeReference ?: (this as? FirVariableAssignment)?.calleeReference
val FirVariableAssignment.calleeReference: FirReference? get() = lValue.toReference()