[FIR] Disallow operators not on functions
Introduce `NOT_FUNCTION_AS_OPERATOR` and use it instead of `PROPERTY_AS_OPERATOR` ^KT-65881 Fixed Merge-request: KT-MR-14547
This commit is contained in:
committed by
Space Team
parent
df9d59851d
commit
2d4f4b9bb5
@@ -124,15 +124,12 @@ class CandidateFactory private constructor(
|
||||
result.addDiagnostic(NoCompanionObject)
|
||||
}
|
||||
if (callInfo.origin == FirFunctionCallOrigin.Operator) {
|
||||
val propertySymbol = when {
|
||||
symbol is FirPropertySymbol -> symbol
|
||||
callInfo.candidateForCommonInvokeReceiver != null -> callInfo.candidateForCommonInvokeReceiver.symbol as? FirPropertySymbol
|
||||
else -> null
|
||||
}
|
||||
if (propertySymbol != null) {
|
||||
// Flag all property references that are resolved from an convention operator call.
|
||||
result.addDiagnostic(PropertyAsOperator(propertySymbol))
|
||||
val normalizedSymbol = when (symbol) {
|
||||
!is FirFunctionSymbol -> symbol
|
||||
else -> callInfo.candidateForCommonInvokeReceiver?.symbol?.takeIf { it !is FirFunctionSymbol }
|
||||
}
|
||||
// Flag all references that are resolved from an convention operator call.
|
||||
normalizedSymbol?.let { result.addDiagnostic(NotFunctionAsOperator(normalizedSymbol)) }
|
||||
}
|
||||
if (symbol is FirPropertySymbol &&
|
||||
!context.session.languageVersionSettings.supportsFeature(LanguageFeature.PrioritizedEnumEntries)
|
||||
|
||||
+16
-8
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.FirPropertyAccessExpressionBuilder
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConePropertyAsOperator
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeNotFunctionAsOperator
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
|
||||
internal class FirInvokeResolveTowerExtension(
|
||||
private val context: ResolutionContext,
|
||||
@@ -288,18 +289,26 @@ private fun BodyResolveComponents.createExplicitReceiverForInvoke(
|
||||
invokeBuiltinExtensionMode: Boolean,
|
||||
extensionReceiverExpression: FirExpression?
|
||||
): FirExpression? {
|
||||
val notFunctionAsOperatorDiagnostics = runIf (candidate.currentApplicability == CandidateApplicability.K2_NOT_FUNCTION_AS_OPERATOR) {
|
||||
candidate.diagnostics.filterIsInstance<NotFunctionAsOperator>().map { ConeNotFunctionAsOperator(it.symbol) }
|
||||
} ?: emptyList()
|
||||
return when (val symbol = candidate.symbol) {
|
||||
is FirCallableSymbol<*> -> createExplicitReceiverForInvokeByCallable(
|
||||
candidate, info, invokeBuiltinExtensionMode, extensionReceiverExpression, symbol
|
||||
candidate, info, invokeBuiltinExtensionMode, extensionReceiverExpression, symbol, notFunctionAsOperatorDiagnostics
|
||||
)
|
||||
is FirRegularClassSymbol -> buildResolvedQualifierForClass(
|
||||
symbol,
|
||||
sourceElement = info.fakeSourceForImplicitInvokeCallReceiver
|
||||
sourceElement = info.fakeSourceForImplicitInvokeCallReceiver,
|
||||
nonFatalDiagnostics = notFunctionAsOperatorDiagnostics,
|
||||
)
|
||||
is FirTypeAliasSymbol -> {
|
||||
val type = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>().fullyExpandedType(session)
|
||||
val expansionRegularClassSymbol = type.lookupTag.toSymbol(session) ?: return null
|
||||
buildResolvedQualifierForClass(expansionRegularClassSymbol, sourceElement = symbol.fir.source)
|
||||
buildResolvedQualifierForClass(
|
||||
expansionRegularClassSymbol,
|
||||
sourceElement = symbol.fir.source,
|
||||
nonFatalDiagnostics = notFunctionAsOperatorDiagnostics,
|
||||
)
|
||||
}
|
||||
else -> throw AssertionError()
|
||||
}
|
||||
@@ -310,7 +319,8 @@ private fun BodyResolveComponents.createExplicitReceiverForInvokeByCallable(
|
||||
info: CallInfo,
|
||||
invokeBuiltinExtensionMode: Boolean,
|
||||
extensionReceiverExpression: FirExpression?,
|
||||
symbol: FirCallableSymbol<*>
|
||||
symbol: FirCallableSymbol<*>,
|
||||
nonFatalDiagnostics: List<ConeNotFunctionAsOperator>,
|
||||
): FirExpression {
|
||||
return FirPropertyAccessExpressionBuilder().apply {
|
||||
val fakeSource = info.fakeSourceForImplicitInvokeCallReceiver
|
||||
@@ -337,9 +347,7 @@ private fun BodyResolveComponents.createExplicitReceiverForInvokeByCallable(
|
||||
explicitReceiver = info.explicitReceiver
|
||||
}
|
||||
|
||||
if (candidate.currentApplicability == CandidateApplicability.K2_PROPERTY_AS_OPERATOR) {
|
||||
nonFatalDiagnostics.add(ConePropertyAsOperator(candidate.symbol as FirPropertySymbol))
|
||||
}
|
||||
this.nonFatalDiagnostics.addAll(nonFatalDiagnostics)
|
||||
|
||||
candidate.updateSourcesOfReceivers()
|
||||
|
||||
|
||||
+3
-3
@@ -170,11 +170,11 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
|
||||
qualifiedAccessExpression.replaceContextReceiverArguments(subCandidate.contextReceiverArguments())
|
||||
|
||||
subCandidate.diagnostics.firstIsInstanceOrNull<PropertyAsOperator>()?.let { propertyAsOperator ->
|
||||
val conePropertyAsOperator = ConePropertyAsOperator(propertyAsOperator.propertySymbol)
|
||||
subCandidate.diagnostics.firstIsInstanceOrNull<NotFunctionAsOperator>()?.let { propertyAsOperator ->
|
||||
val coneNotFunctionAsOperator = ConeNotFunctionAsOperator(propertyAsOperator.symbol)
|
||||
val nonFatalDiagnostics: List<ConeDiagnostic> = buildList {
|
||||
addAll(qualifiedAccessExpression.nonFatalDiagnostics)
|
||||
add(conePropertyAsOperator)
|
||||
add(coneNotFunctionAsOperator)
|
||||
}
|
||||
qualifiedAccessExpression.replaceNonFatalDiagnostics(nonFatalDiagnostics)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user