[FIR] Add session parameter to all "element --> reference" utilities
`FirDeserializedEnumAccessExpression` requires session to build proper reference, so it's important to have it in all utilities, which may pass this element as input ^KT-64975
This commit is contained in:
committed by
Space Team
parent
bd9cb2b7e0
commit
150ff1172e
+2
-1
@@ -35,7 +35,8 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirEx
|
||||
withClassEntry("annotationTypeRef", annotation.annotationTypeRef)
|
||||
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||
withClassEntry("coneTypeOrNull", annotation.coneTypeOrNull)
|
||||
annotation.toReference()?.let { withClassEntry("calleeReference", it) }
|
||||
@OptIn(UnsafeExpressionUtility::class)
|
||||
annotation.toReferenceUnsafe()?.let { withClassEntry("calleeReference", it) }
|
||||
}
|
||||
|
||||
return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name }
|
||||
|
||||
+5
-2
@@ -220,7 +220,7 @@ internal class KtFirCallResolver(
|
||||
|
||||
return when (this) {
|
||||
is FirResolvable, is FirVariableAssignment -> {
|
||||
when (val calleeReference = toReference()) {
|
||||
when (val calleeReference = toReference(analysisSession.useSiteSession)) {
|
||||
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
|
||||
@@ -794,7 +794,10 @@ internal class KtFirCallResolver(
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
private fun getInitializerOfReferencedLocalVariable(variableReference: FirExpression): FirFunctionCall? {
|
||||
return variableReference.toReference()?.toResolvedVariableSymbol()?.fir?.initializer as? FirFunctionCall
|
||||
return variableReference.toReference(firResolveSession.useSiteFirSession)
|
||||
?.toResolvedVariableSymbol()
|
||||
?.fir
|
||||
?.initializer as? FirFunctionCall
|
||||
}
|
||||
|
||||
private fun getOperationPartiallyAppliedSymbolsForCompoundVariableAccess(
|
||||
|
||||
+1
-1
@@ -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.toReference() as? FirResolvedNamedReference)?.resolvedSymbol
|
||||
val callee = (firCall.toReference(firResolveSession.useSiteFirSession) as? FirResolvedNamedReference)?.resolvedSymbol
|
||||
if (callee?.fir?.origin == FirDeclarationOrigin.SamConstructor) {
|
||||
val substitutor = (firCall as? FirQualifiedAccessExpression)
|
||||
?.createConeSubstitutorFromTypeArguments(discardErrorTypes = true)
|
||||
|
||||
-1
@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.unwrapNullability
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ private class CodeFragmentCapturedValueVisitor(
|
||||
override fun visitElement(element: FirElement) {
|
||||
processElement(element)
|
||||
|
||||
val lhs = (element as? FirVariableAssignment)?.lValue?.toResolvedCallableSymbol()
|
||||
val lhs = (element as? FirVariableAssignment)?.lValue?.toResolvedCallableSymbol(session)
|
||||
if (lhs != null) {
|
||||
assignmentLhs.add(lhs)
|
||||
}
|
||||
|
||||
+1
-1
@@ -138,7 +138,7 @@ class AllCandidatesResolver(private val firSession: FirSession) {
|
||||
*/
|
||||
private fun OverloadCandidate.preserveCalleeInapplicability() {
|
||||
val callSite = candidate.callInfo.callSite
|
||||
val calleeReference = callSite.toReference() as? FirDiagnosticHolder ?: return
|
||||
val calleeReference = callSite.toReference(firSession) as? FirDiagnosticHolder ?: return
|
||||
val diagnostic = calleeReference.diagnostic as? ConeInapplicableCandidateError ?: return
|
||||
if (diagnostic.applicability != CandidateApplicability.INAPPLICABLE) return
|
||||
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||
|
||||
object FirJsDefinedExternallyCallChecker : FirBasicExpressionChecker(MppCheckerKind.Common) {
|
||||
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val symbol = expression.toReference()?.toResolvedCallableSymbol() ?: return
|
||||
val symbol = expression.toReference(context.session)?.toResolvedCallableSymbol() ?: return
|
||||
|
||||
if (symbol.callableId !in JsStandardClassIds.Callables.definedExternallyPropertyNames) {
|
||||
return
|
||||
|
||||
+14
-14
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
|
||||
@@ -42,7 +43,7 @@ object FirJsDynamicCallChecker : FirQualifiedAccessExpressionChecker(MppCheckerK
|
||||
?: error("Resolved call callee without a callable symbol")
|
||||
|
||||
when {
|
||||
expression is FirCall && expression.isArrayAccessWithMultipleIndices -> reporter.reportOn(
|
||||
expression is FirCall && expression.isArrayAccessWithMultipleIndices(context.session) -> reporter.reportOn(
|
||||
expression.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "indexed access with more than one index", context
|
||||
)
|
||||
expression is FirFunctionCall && expression.isInOperator -> reporter.reportOn(
|
||||
@@ -62,22 +63,21 @@ object FirJsDynamicCallChecker : FirQualifiedAccessExpressionChecker(MppCheckerK
|
||||
}
|
||||
}
|
||||
|
||||
private val FirCall.isArrayAccessWithMultipleIndices: Boolean
|
||||
get() {
|
||||
val callee = toReference() as? FirNamedReference
|
||||
?: return false
|
||||
private fun FirCall.isArrayAccessWithMultipleIndices(session: FirSession): Boolean {
|
||||
val callee = toReference(session) as? FirNamedReference
|
||||
?: return false
|
||||
|
||||
if (callee.source?.kind != KtFakeSourceElementKind.ArrayAccessNameReference) {
|
||||
return false
|
||||
}
|
||||
|
||||
val arguments = (arguments.singleOrNull() as? FirVarargArgumentsExpression)?.arguments
|
||||
?: return false
|
||||
|
||||
return callee.name == OperatorNameConventions.GET && arguments.size >= 2
|
||||
|| callee.name == OperatorNameConventions.SET && arguments.size >= 3
|
||||
if (callee.source?.kind != KtFakeSourceElementKind.ArrayAccessNameReference) {
|
||||
return false
|
||||
}
|
||||
|
||||
val arguments = (arguments.singleOrNull() as? FirVarargArgumentsExpression)?.arguments
|
||||
?: return false
|
||||
|
||||
return callee.name == OperatorNameConventions.GET && arguments.size >= 2
|
||||
|| callee.name == OperatorNameConventions.SET && arguments.size >= 3
|
||||
}
|
||||
|
||||
private val FirFunctionCall.isInOperator
|
||||
get() = calleeReference.resolved?.name == OperatorNameConventions.CONTAINS && origin == FirFunctionCallOrigin.Operator
|
||||
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ object FirJvmProtectedInSuperClassCompanionCallChecker : FirBasicExpressionCheck
|
||||
} ?: return
|
||||
|
||||
val dispatchClassSymbol = dispatchReceiver.resolvedType.toRegularClassSymbol(context.session) ?: return
|
||||
val calleeReference = expression.toReference()
|
||||
val calleeReference = expression.toReference(context.session)
|
||||
val resolvedSymbol = calleeReference?.toResolvedCallableSymbol() ?: return
|
||||
|
||||
val visibility = if (resolvedSymbol is FirPropertySymbol) {
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.name.WebCommonStandardClassIds
|
||||
|
||||
object FirWasmDefinedExternallyCallChecker : FirBasicExpressionChecker(MppCheckerKind.Common) {
|
||||
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val symbol = expression.toReference()?.toResolvedCallableSymbol() ?: return
|
||||
val symbol = expression.toReference(context.session)?.toResolvedCallableSymbol() ?: return
|
||||
|
||||
if (symbol.callableId != WebCommonStandardClassIds.Callables.JsDefinedExternally) {
|
||||
return
|
||||
|
||||
+2
-3
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirField
|
||||
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isConst
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
@@ -194,7 +193,7 @@ private class FirConstCheckVisitor(private val session: FirSession) : FirVisitor
|
||||
override fun visitPropertyAccessExpression(
|
||||
propertyAccessExpression: FirPropertyAccessExpression, data: Nothing?
|
||||
): ConstantArgumentKind {
|
||||
val propertySymbol = propertyAccessExpression.toReference()?.toResolvedCallableSymbol(discardErrorReference = true)
|
||||
val propertySymbol = propertyAccessExpression.toReference(session)?.toResolvedCallableSymbol(discardErrorReference = true)
|
||||
when (propertySymbol) {
|
||||
// Null symbol means some error occurred.
|
||||
// We use the same logic as in `visitErrorExpression`.
|
||||
@@ -364,4 +363,4 @@ private class FirConstCheckVisitor(private val session: FirSession) : FirVisitor
|
||||
?.coneTypeSafe<ConeLookupTagBasedType>()
|
||||
?.lookupTag
|
||||
?.toSymbol(session)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.toReference()?.isError() == true
|
||||
val isReportedByErrorNodeDiagnosticCollector = initializer is FirCall && initializer.toReference(context.session)?.isError() == true
|
||||
|
||||
if (
|
||||
!isReportedByErrorNodeDiagnosticCollector &&
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ object FirEnumCompanionInEnumConstructorCallChecker : FirClassChecker(MppChecker
|
||||
is FirResolvedQualifier -> {
|
||||
this.resolvedType.toRegularClassSymbol(session)
|
||||
}
|
||||
else -> (this.toReference() as? FirThisReference)?.boundSymbol
|
||||
else -> (this.toReference(session) as? FirThisReference)?.boundSymbol
|
||||
} as? FirRegularClassSymbol
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -133,7 +133,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
val argumentMapping = functionCall.resolvedArgumentMapping ?: return
|
||||
for ((wrappedArgument, valueParameter) in argumentMapping) {
|
||||
val argument = wrappedArgument.unwrapArgument()
|
||||
val resolvedArgumentSymbol = argument.toResolvedCallableSymbol() as? FirVariableSymbol<*> ?: continue
|
||||
val resolvedArgumentSymbol = argument.toResolvedCallableSymbol(session) as? FirVariableSymbol<*> ?: continue
|
||||
|
||||
val valueParameterOfOriginalInlineFunction = inlinableParameters.firstOrNull { it == resolvedArgumentSymbol }
|
||||
if (valueParameterOfOriginalInlineFunction != null) {
|
||||
@@ -163,7 +163,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
reporter: DiagnosticReporter,
|
||||
) {
|
||||
if (receiverExpression == null) return
|
||||
val receiverSymbol = receiverExpression.toResolvedCallableSymbol() as? FirValueParameterSymbol ?: return
|
||||
val receiverSymbol = receiverExpression.toResolvedCallableSymbol(session) as? FirValueParameterSymbol ?: return
|
||||
if (receiverSymbol in inlinableParameters) {
|
||||
if (!isInvokeOrInlineExtension(targetSymbol)) {
|
||||
reporter.reportOn(
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ sealed class FirValueClassDeclarationChecker(mppKind: MppCheckerKind) : FirRegul
|
||||
|
||||
is FirField -> {
|
||||
if (innerDeclaration.isSynthetic) {
|
||||
val symbol = innerDeclaration.initializer?.toResolvedCallableSymbol()
|
||||
val symbol = innerDeclaration.initializer?.toResolvedCallableSymbol(context.session)
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.InlineClassImplementationByDelegation) &&
|
||||
symbol != null && symbol in primaryConstructorParametersSymbolsSet
|
||||
) {
|
||||
|
||||
+1
-1
@@ -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.toReference()?.resolved ?: return
|
||||
val resolvedReference = expression.toReference(context.session)?.resolved ?: return
|
||||
val referencedSymbol = resolvedReference.resolvedSymbol as? FirCallableSymbol ?: return
|
||||
|
||||
val containingClassId = (expression as? FirQualifiedAccessExpression)?.dispatchReceiver?.resolvedType?.fullyExpandedClassId(context.session)
|
||||
|
||||
+1
-1
@@ -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.toReference() ?: return
|
||||
val calleeReference = expression.toReference(context.session) ?: return
|
||||
val resolvedReference = calleeReference.resolved ?: return
|
||||
val referencedSymbol = resolvedReference.resolvedSymbol
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ object FirOptInUsageAccessChecker : FirBasicExpressionChecker(MppCheckerKind.Com
|
||||
|
||||
if (expression.isLhsOfAssignment(context)) return
|
||||
|
||||
val resolvedSymbol = expression.toReference()?.toResolvedBaseSymbol() ?: return
|
||||
val resolvedSymbol = expression.toReference(context.session)?.toResolvedBaseSymbol() ?: return
|
||||
|
||||
with(FirOptInUsageBaseChecker) {
|
||||
when {
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ object FirUselessTypeOperationCallChecker : FirTypeOperatorCallChecker(MppChecke
|
||||
return when (expression.operation) {
|
||||
FirOperation.AS, FirOperation.SAFE_AS -> {
|
||||
if (arg is FirFunctionCall) {
|
||||
val functionSymbol = arg.toResolvedCallableSymbol() as? FirFunctionSymbol<*>
|
||||
val functionSymbol = arg.toResolvedCallableSymbol(context.session) as? FirFunctionSymbol<*>
|
||||
if (functionSymbol != null && functionSymbol.isFunctionForExpectTypeFromCastFeature()) return false
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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.toReference() == reference
|
||||
it.toReference(session) == 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
|
||||
|
||||
+3
-4
@@ -14,9 +14,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
||||
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.toReference
|
||||
import org.jetbrains.kotlin.fir.expressions.unwrapSmartcastExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||
@@ -84,7 +82,8 @@ object FirDiagnosticRenderers {
|
||||
}
|
||||
|
||||
val CALLEE_NAME = Renderer { element: FirExpression ->
|
||||
when (val reference = element.unwrapSmartcastExpression().toReference()) {
|
||||
@OptIn(UnsafeExpressionUtility::class)
|
||||
when (val reference = element.unwrapSmartcastExpression().toReferenceUnsafe()) {
|
||||
is FirNamedReference -> reference.name.asString()
|
||||
is FirThisReference -> "this"
|
||||
is FirSuperReference -> "super"
|
||||
|
||||
+1
-2
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.resolvedType
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||
@@ -108,7 +107,7 @@ internal object FirToConstantValueTransformer : FirDefaultVisitor<ConstantValue<
|
||||
val mapping = annotation.argumentMapping.mapping.convertToConstantValues(
|
||||
data.session,
|
||||
data.constValueProvider
|
||||
).addEmptyVarargValuesFor(annotation.toReference()?.toResolvedFunctionSymbol())
|
||||
).addEmptyVarargValuesFor(annotation.toReference(data.session)?.toResolvedFunctionSymbol())
|
||||
return AnnotationValue.create(annotation.annotationTypeRef.coneType, mapping)
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -776,7 +776,7 @@ class CallAndReferenceGenerator(
|
||||
)
|
||||
}
|
||||
|
||||
val firConstructorSymbol = annotation.toResolvedCallableSymbol() as? FirConstructorSymbol
|
||||
val firConstructorSymbol = annotation.toResolvedCallableSymbol(session) as? FirConstructorSymbol
|
||||
?: run {
|
||||
// Fallback for FirReferencePlaceholderForResolvedAnnotations from jar
|
||||
val fir = coneType.lookupTag.toSymbol(session)?.fir as? FirClass
|
||||
@@ -1021,7 +1021,7 @@ class CallAndReferenceGenerator(
|
||||
putValueArgument(valueParameters.indexOf(parameter) + contextReceiverCount, irArgument)
|
||||
}
|
||||
if (visitor.annotationMode) {
|
||||
val function = call.toReference()?.toResolvedCallableSymbol()?.fir as? FirFunction
|
||||
val function = call.toReference(session)?.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.toReference()?.toResolvedCallableSymbol()?.let {
|
||||
argument.toReference(session)?.toResolvedCallableSymbol()?.let {
|
||||
it.resolvedStatus.isConst && it.isMarkedWithImplicitIntegerCoercion
|
||||
} == true
|
||||
) {
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ class FirAnnotationTypeQualifierResolver(
|
||||
is FirArrayLiteral -> arguments.flatMap { it.toEnumNames() }
|
||||
is FirVarargArgumentsExpression -> arguments.flatMap { it.toEnumNames() }
|
||||
else -> {
|
||||
val name = when (val reference = toReference()) {
|
||||
val name = when (val reference = toReference(session)) {
|
||||
is FirResolvedNamedReference ->
|
||||
(reference.resolvedSymbol as? FirCallableSymbol<*>)?.callableId?.callableName?.asString()
|
||||
is FirFromMissingDependenciesNamedReference -> reference.name.asString()
|
||||
|
||||
@@ -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?.toReference() as? FirNamedReferenceWithCandidate)?.candidate?.updateSourcesOfReceivers()
|
||||
(resolvedReceiver?.toReference(session) 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.toReference()?.toResolvedCallableSymbol()?.takeIf {
|
||||
argument.toReference(session)?.toResolvedCallableSymbol()?.takeIf {
|
||||
it.rawStatus.isConst && it.isMarkedWithImplicitIntegerCoercion
|
||||
}?.resolvedReturnType
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ object CheckDslScopeViolation : ResolutionStage() {
|
||||
|
||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||
fun checkReceiver(receiver: FirExpression?) {
|
||||
val thisReference = receiver?.toReference() as? FirThisReference ?: return
|
||||
val thisReference = receiver?.toReference(context.session) as? FirThisReference ?: return
|
||||
if (thisReference.isImplicit) {
|
||||
checkImpl(
|
||||
candidate,
|
||||
@@ -755,7 +755,7 @@ internal object CheckHiddenDeclaration : ResolutionStage() {
|
||||
/** Actual declarations are checked by [FirDeprecationChecker] */
|
||||
if (symbol.isActual) return
|
||||
val deprecation = symbol.getDeprecation(context.session, callInfo.callSite)
|
||||
if (deprecation?.deprecationLevel == DeprecationLevelValue.HIDDEN || isHiddenForThisCallSite(symbol, callInfo, candidate)) {
|
||||
if (deprecation?.deprecationLevel == DeprecationLevelValue.HIDDEN || isHiddenForThisCallSite(symbol, callInfo, candidate, context.session)) {
|
||||
sink.yieldDiagnostic(HiddenCandidate)
|
||||
}
|
||||
}
|
||||
@@ -764,8 +764,9 @@ internal object CheckHiddenDeclaration : ResolutionStage() {
|
||||
symbol: FirCallableSymbol<*>,
|
||||
callInfo: CallInfo,
|
||||
candidate: Candidate,
|
||||
session: FirSession
|
||||
): Boolean {
|
||||
val isSuperCall = callInfo.callSite.isSuperCall()
|
||||
val isSuperCall = callInfo.callSite.isSuperCall(session)
|
||||
if (symbol.fir.dispatchReceiverType == null || symbol !is FirNamedFunctionSymbol) return false
|
||||
if (symbol.isHidden(isSuperCall)) return true
|
||||
|
||||
@@ -784,8 +785,8 @@ internal object CheckHiddenDeclaration : ResolutionStage() {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FirElement.isSuperCall(): Boolean =
|
||||
this is FirQualifiedAccessExpression && explicitReceiver?.toReference() is FirSuperReference
|
||||
private fun FirElement.isSuperCall(session: FirSession): Boolean =
|
||||
this is FirQualifiedAccessExpression && explicitReceiver?.toReference(session) is FirSuperReference
|
||||
|
||||
private fun FirCallableSymbol<*>.isHidden(isSuperCall: Boolean): Boolean {
|
||||
val fir = fir
|
||||
|
||||
@@ -166,7 +166,8 @@ private fun FirMemberDeclaration.getBackingFieldIfApplicable(): FirBackingField?
|
||||
private fun isExplicitReceiverExpression(receiverExpression: FirExpression?): Boolean {
|
||||
if (receiverExpression == null) return false
|
||||
// Only FirThisReference may be a reference in implicit receiver
|
||||
val thisReference = receiverExpression.toReference() as? FirThisReference ?: return true
|
||||
@OptIn(UnsafeExpressionUtility::class)
|
||||
val thisReference = receiverExpression.toReferenceUnsafe() as? FirThisReference ?: return true
|
||||
return !thisReference.isImplicit
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -306,7 +306,9 @@ private object WhenOnEnumExhaustivenessChecker : WhenExhaustivenessChecker() {
|
||||
override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: MutableSet<FirEnumEntry>) {
|
||||
if (!equalityOperatorCall.operation.let { it == FirOperation.EQ || it == FirOperation.IDENTITY }) return
|
||||
val argument = equalityOperatorCall.arguments[1]
|
||||
val symbol = argument.toResolvedCallableReference()?.resolvedSymbol as? FirVariableSymbol<*> ?: return
|
||||
|
||||
@OptIn(UnsafeExpressionUtility::class)
|
||||
val symbol = argument.toResolvedCallableReferenceUnsafe()?.resolvedSymbol as? FirVariableSymbol<*> ?: return
|
||||
val checkedEnumEntry = symbol.fir as? FirEnumEntry ?: return
|
||||
data.add(checkedEnumEntry)
|
||||
}
|
||||
@@ -360,7 +362,8 @@ private object WhenOnSealedClassExhaustivenessChecker : WhenExhaustivenessChecke
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
argument.toResolvedCallableSymbol()?.takeIf { it.fir is FirEnumEntry }
|
||||
@OptIn(UnsafeExpressionUtility::class)
|
||||
argument.toResolvedCallableSymbolUnsafe()?.takeIf { it.fir is FirEnumEntry }
|
||||
}
|
||||
} ?: return
|
||||
processBranch(symbol, isNegated, data)
|
||||
|
||||
+2
-2
@@ -591,7 +591,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
||||
|
||||
val generator = GeneratorOfPlusAssignCalls(
|
||||
assignmentOperatorStatement,
|
||||
assignmentOperatorStatement.toReference()?.source,
|
||||
assignmentOperatorStatement.toReference(session)?.source,
|
||||
operation,
|
||||
leftArgument,
|
||||
rightArgument
|
||||
@@ -623,7 +623,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
||||
// following `!!` is safe since `operatorIsSuccessful = true` implies `operatorCallReference != null`
|
||||
val operatorReturnTypeMatches = operatorIsSuccessful && operatorReturnTypeMatches(operatorCallReference!!.candidate)
|
||||
|
||||
val lhsReference = leftArgument.toReference()
|
||||
val lhsReference = leftArgument.toReference(session)
|
||||
val lhsSymbol = lhsReference?.toResolvedVariableSymbol()
|
||||
val lhsVariable = lhsSymbol?.fir
|
||||
val lhsIsVar = lhsVariable?.isVar == true
|
||||
|
||||
+1
-1
@@ -235,7 +235,7 @@ class ConeEffectExtractor(
|
||||
|
||||
private fun FirExpression.parseInvocationKind(): EventOccurrencesRange? {
|
||||
if (this !is FirQualifiedAccessExpression) return null
|
||||
val resolvedId = toResolvedCallableSymbol()?.callableId ?: return null
|
||||
val resolvedId = toResolvedCallableSymbol(session)?.callableId ?: return null
|
||||
return when (resolvedId) {
|
||||
FirContractsDslNames.EXACTLY_ONCE_KIND -> EventOccurrencesRange.EXACTLY_ONCE
|
||||
FirContractsDslNames.AT_LEAST_ONCE_KIND -> EventOccurrencesRange.AT_LEAST_ONCE
|
||||
|
||||
+1
-1
@@ -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.toReference() as? FirSimpleNamedReference)?.name?.identifier }
|
||||
.mapNotNull { (it.toReference(session) as? FirSimpleNamedReference)?.name?.identifier }
|
||||
.toList()
|
||||
|
||||
if (segments.isNotEmpty() && FqName.fromSegments(segments.asReversed()) != symbol.classId.packageFqName) {
|
||||
|
||||
@@ -6,36 +6,106 @@
|
||||
package org.jetbrains.kotlin.fir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.resolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
|
||||
fun FirElement.toReference(): FirReference? {
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||
annotation class UnsafeExpressionUtility
|
||||
|
||||
/**
|
||||
* Returns the [FirReference] of this [FirElement], if available.
|
||||
* The reference is resolved in the context of a use-site [session], which may be required to find a symbol for an ID-based expression.
|
||||
*/
|
||||
fun FirElement.toReference(session: FirSession): FirReference? {
|
||||
return when (this) {
|
||||
is FirExpression -> toReference()
|
||||
is FirExpression -> toReferenceImpl(session)
|
||||
is FirVariableAssignment -> calleeReference
|
||||
is FirResolvable -> calleeReference
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun FirExpression.toReference(): FirReference? {
|
||||
/**
|
||||
* Returns the [FirReference] of this [FirExpression], if available.
|
||||
* The reference is resolved in the context of a use-site [session], which may be required to find a symbol for an ID-based expression.
|
||||
*/
|
||||
fun FirExpression.toReference(session: FirSession): FirReference? {
|
||||
return toReferenceImpl(session)
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility won't return proper reference for `FirEnumEntryDeserializedAccessExpression`,
|
||||
* so use only if you are really sure that it be never called on this node
|
||||
*
|
||||
* In most cases it's better to use safe [toReference] methods with session parameter.
|
||||
*/
|
||||
@UnsafeExpressionUtility
|
||||
fun FirExpression.toReferenceUnsafe(): FirReference? {
|
||||
return toReferenceImpl(session = null)
|
||||
}
|
||||
|
||||
private fun FirExpression.toReferenceImpl(session: FirSession?): FirReference? {
|
||||
return when (this) {
|
||||
is FirWrappedArgumentExpression -> expression.toResolvedCallableReference()
|
||||
is FirSmartCastExpression -> originalExpression.toReference()
|
||||
is FirDesugaredAssignmentValueReferenceExpression -> expressionRef.value.toReference()
|
||||
is FirWrappedArgumentExpression -> expression.toResolvedCallableReferenceImpl(session)
|
||||
is FirSmartCastExpression -> originalExpression.toReferenceImpl(session)
|
||||
is FirDesugaredAssignmentValueReferenceExpression -> expressionRef.value.toReferenceImpl(session)
|
||||
is FirResolvable -> calleeReference
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
val FirVariableAssignment.calleeReference: FirReference? get() = lValue.toReference()
|
||||
val FirVariableAssignment.calleeReference: FirReference?
|
||||
get() {
|
||||
// non-nullable session for `toReferenceImpl` is needed only for `FirEnumEntryDeserializedAccessExpression` value,
|
||||
// which never can appear in the lhs of variable assignment
|
||||
return lValue.toReferenceImpl(session = null)
|
||||
}
|
||||
|
||||
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||
return toReference()?.resolved
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
|
||||
fun FirExpression.toResolvedCallableReference(session: FirSession): FirResolvedNamedReference? {
|
||||
return toResolvedCallableReferenceImpl(session)
|
||||
}
|
||||
|
||||
fun FirExpression.toResolvedCallableSymbol(): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReference()?.resolvedSymbol as? FirCallableSymbol<*>?
|
||||
fun FirResolvable.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||
return calleeReference.resolved
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility won't return proper reference for `FirEnumEntryDeserializedAccessExpression`,
|
||||
* so use only if you are really sure that it be never called on this node
|
||||
*
|
||||
* In most cases it's better to use safe [toResolvedCallableReference] methods with session parameter
|
||||
*/
|
||||
@UnsafeExpressionUtility
|
||||
fun FirExpression.toResolvedCallableReferenceUnsafe(): FirResolvedNamedReference? {
|
||||
return toResolvedCallableReferenceImpl(session = null)
|
||||
}
|
||||
|
||||
fun FirExpression.toResolvedCallableReferenceImpl(session: FirSession?): FirResolvedNamedReference? {
|
||||
return toReferenceImpl(session)?.resolved
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
|
||||
fun FirExpression.toResolvedCallableSymbol(session: FirSession): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReference(session)?.resolvedSymbol as? FirCallableSymbol<*>?
|
||||
}
|
||||
|
||||
fun FirResolvable.toResolvedCallableSymbol(): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReference()?.resolvedSymbol as? FirCallableSymbol<*>
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility won't return proper reference for `FirEnumEntryDeserializedAccessExpression`,
|
||||
* so use only if you are really sure that it be never called on this node
|
||||
*
|
||||
* In most cases it's better to use safe [toResolvedCallableSymbol] methods with session parameter
|
||||
*/
|
||||
@UnsafeExpressionUtility
|
||||
fun FirExpression.toResolvedCallableSymbolUnsafe(): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReferenceUnsafe()?.resolvedSymbol as? FirCallableSymbol<*>?
|
||||
}
|
||||
|
||||
+4
-6
@@ -8,11 +8,7 @@ package org.jetbrains.kotlin.lombok.k2.config
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.findArgumentByName
|
||||
import org.jetbrains.kotlin.fir.declarations.getStringArgument
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.lombok.config.AccessLevel
|
||||
import org.jetbrains.kotlin.lombok.utils.trimToNull
|
||||
@@ -27,8 +23,10 @@ private fun FirAnnotation.getArgumentAsString(field: Name): String? {
|
||||
val argument = findArgumentByName(field) ?: return null
|
||||
return when (argument) {
|
||||
is FirConstExpression<*> -> argument.value as? String
|
||||
is FirEnumEntryDeserializedAccessExpression -> argument.enumEntryName.identifier
|
||||
is FirQualifiedAccessExpression -> {
|
||||
val symbol = argument.toResolvedCallableSymbol()
|
||||
@OptIn(UnsafeExpressionUtility::class)
|
||||
val symbol = argument.toResolvedCallableSymbolUnsafe()
|
||||
if (symbol is FirEnumEntrySymbol) {
|
||||
symbol.callableId.callableName.identifier
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user