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