[FIR] Report PROPERTY_AS_OPERATOR for all operator conventions

^KT-62347 Fixed
^KT-59715 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-12-11 13:21:32 +02:00
committed by Space Team
parent 92c75fb7ab
commit 93563d7c80
18 changed files with 24 additions and 110 deletions
@@ -16064,12 +16064,6 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/delegatedProperty/varInInnerClass.kt");
}
@Test
@TestMetadata("withInvoke.kt")
public void testWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/delegateToAnother")
@TestDataPath("$PROJECT_ROOT")
@@ -16064,12 +16064,6 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/delegatedProperty/varInInnerClass.kt");
}
@Test
@TestMetadata("withInvoke.kt")
public void testWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/delegateToAnother")
@TestDataPath("$PROJECT_ROOT")
@@ -47,11 +47,6 @@ object FirConventionFunctionCallChecker : FirFunctionCallChecker() {
) {
if (callExpression.dispatchReceiver?.resolvedType is ConeDynamicType) return
// KT-61905: TODO: Return also in case of error type.
val sourceKind = callExpression.source?.kind
if (sourceKind !is KtRealSourceElementKind &&
sourceKind !is KtFakeSourceElementKind.GeneratedComparisonExpression &&
sourceKind !is KtFakeSourceElementKind.DesugaredCompoundAssignment
) return
val unwrapped = receiver?.unwrapSmartcastExpression()
if (unwrapped !is FirPropertyAccessExpression) return
val diagnostic = unwrapped.nonFatalDiagnostics.firstIsInstanceOrNull<ConePropertyAsOperator>() ?: return
@@ -16005,12 +16005,6 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/delegatedProperty/varInInnerClass.kt");
}
@Test
@TestMetadata("withInvoke.kt")
public void testWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/delegateToAnother")
@TestDataPath("$PROJECT_ROOT")
@@ -16005,12 +16005,6 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
runTest("compiler/testData/codegen/box/delegatedProperty/varInInnerClass.kt");
}
@Test
@TestMetadata("withInvoke.kt")
public void testWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/delegateToAnother")
@TestDataPath("$PROJECT_ROOT")
@@ -16005,12 +16005,6 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/delegatedProperty/varInInnerClass.kt");
}
@Test
@TestMetadata("withInvoke.kt")
public void testWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/delegateToAnother")
@TestDataPath("$PROJECT_ROOT")
@@ -100,9 +100,16 @@ class CandidateFactory private constructor(
} else if (objectsByName && symbol.isRegularClassWithoutCompanion(callInfo.session)) {
result.addDiagnostic(NoCompanionObject)
}
if (callInfo.origin == FirFunctionCallOrigin.Operator && symbol is FirPropertySymbol) {
// Flag all property references that are resolved from an convention operator call.
result.addDiagnostic(PropertyAsOperator)
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))
}
}
if (symbol is FirPropertySymbol &&
!context.session.languageVersionSettings.supportsFeature(LanguageFeature.PrioritizedEnumEntries)
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionResultOverridesOtherToPreserveCompatibility
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.resolve.inference.ResolvedLambdaAtom
@@ -50,6 +47,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import kotlin.collections.component1
import kotlin.collections.component2
@@ -148,8 +146,8 @@ class FirCallCompletionResultsWriterTransformer(
qualifiedAccessExpression.replaceContextReceiverArguments(subCandidate.contextReceiverArguments())
if (qualifiedAccessExpression is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.K2_PROPERTY_AS_OPERATOR) {
val conePropertyAsOperator = ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol)
subCandidate.diagnostics.firstIsInstanceOrNull<PropertyAsOperator>()?.let { propertyAsOperator ->
val conePropertyAsOperator = ConePropertyAsOperator(propertyAsOperator.propertySymbol)
val nonFatalDiagnostics: List<ConeDiagnostic> = buildList {
addAll(qualifiedAccessExpression.nonFatalDiagnostics)
add(conePropertyAsOperator)
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
@@ -15,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
@@ -134,7 +134,7 @@ class OperatorCallOfConstructor(val constructor: FirConstructorSymbol) : Resolut
class InferenceError(val constraintError: ConstraintSystemError) : ResolutionDiagnostic(constraintError.applicability)
class Unsupported(val message: String, val source: KtSourceElement?) : ResolutionDiagnostic(K2_UNSUPPORTED)
object PropertyAsOperator : ResolutionDiagnostic(K2_PROPERTY_AS_OPERATOR)
class PropertyAsOperator(val propertySymbol: FirPropertySymbol) : ResolutionDiagnostic(K2_PROPERTY_AS_OPERATOR)
class DslScopeViolation(val calleeSymbol: FirBasedSymbol<*>) : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
@@ -158,4 +158,4 @@ object TypeParameterAsExpression : ResolutionDiagnostic(INAPPLICABLE)
class StubBuilderInferenceReceiver(
val typeParameterSymbol: FirTypeParameterSymbol
) : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
) : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
@@ -1,17 +0,0 @@
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_K1: JVM_IR
// ISSUE: KT-61633
class C<T3>(val p: T3)
class D<T4>(val p: T4)
val <X3> C<X3>.getValue: D<X3> get() = D(p)
operator fun <X4> D<X4>.invoke(x: Any?, y: Any?): X4 = p
fun foo(c: C<String>): String {
val y1 by c
return y1
}
fun box(): String = foo(C("OK"))
@@ -12,11 +12,11 @@ val <X3> C<X3>.getValue: D<X3> get() = TODO()
operator fun <X4> D<X4>.invoke(x: Any?, y: Any?): X4 = TODO()
fun foo(a: A<String>, c: C<String>) {
val x1 by a
val x1 by <!PROPERTY_AS_OPERATOR!>a<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>x1<!>
x1.length
val y1 by c
val y1 by <!PROPERTY_AS_OPERATOR!>c<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>y1<!>
y1.length
}
}
@@ -67,7 +67,7 @@ fun useSet() { <!PROPERTY_AS_OPERATOR!>e[1]<!> = 3 }
val E.contains: I get() = I()
val useContains = 1 <!PROPERTY_AS_OPERATOR!>in<!> e
val useNotContains = 1 <!PROPERTY_AS_OPERATOR!>!in<!> e
val useNotContains = 1 <!PROPERTY_AS_OPERATOR, PROPERTY_AS_OPERATOR!>!in<!> e
val E.invoke: I get() = I()
val useInvoke = <!NONE_APPLICABLE!>e<!>()
@@ -1,23 +0,0 @@
// ISSUE: KT-59715
class FunctionComponent {
val component1: () -> String = { "hello" }
}
class I {
operator fun invoke(): String = "hello"
}
class InvokeComponent {
val component1: I = I()
}
fun test_1(c: FunctionComponent) {
val (x) = FunctionComponent()
val (y) = c
}
fun test_2(c: InvokeComponent) {
val (x) = FunctionComponent()
val (y) = c
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ISSUE: KT-59715
class FunctionComponent {
@@ -16005,12 +16005,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/delegatedProperty/varInInnerClass.kt");
}
@Test
@TestMetadata("withInvoke.kt")
public void testWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/delegateToAnother")
@TestDataPath("$PROJECT_ROOT")
@@ -16005,12 +16005,6 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/delegatedProperty/varInInnerClass.kt");
}
@Test
@TestMetadata("withInvoke.kt")
public void testWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/codegen/box/delegatedProperty/delegateToAnother")
@TestDataPath("$PROJECT_ROOT")
@@ -12854,11 +12854,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/delegatedProperty/genericDelegateUncheckedCast2.kt");
}
@TestMetadata("withInvoke.kt")
public void ignoreWithInvoke() throws Exception {
runTest("compiler/testData/codegen/box/delegatedProperty/withInvoke.kt");
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
@@ -25,7 +25,7 @@ fun case1() {
}
class B() {
val p: String by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!> // DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE expected
val p: String by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, PROPERTY_AS_OPERATOR!>Delegate()<!> // DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE expected
}
class Delegate {
@@ -50,7 +50,7 @@ fun case2() {
}
class B() {
var p: String by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!> // DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE expected
var p: String by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, PROPERTY_AS_OPERATOR, PROPERTY_AS_OPERATOR!>Delegate()<!> // DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE expected
}
class Delegate {