From c1420794b4be892904357be0bc4cce39fcad1990 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Tue, 24 Jan 2023 16:34:59 +0100 Subject: [PATCH] FIR: add checker for local extension properties ^KT-56013 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 6 ++++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 ++++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 5 +++++ ...CompilerTestFE10TestdataTestGenerated.java | 6 ++++++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++++++ .../diagnostics/FirDiagnosticsList.kt | 2 ++ .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../checkers/CommonDeclarationCheckers.kt | 1 + .../FirLocalExtensionPropertyChecker.kt | 21 +++++++++++++++++++ .../diagnostics/FirErrorsDefaultMessages.kt | 3 +++ .../converter/DeclarationsConverter.kt | 3 ++- .../kotlin/fir/builder/RawFirBuilder.kt | 2 +- .../properties/localPropertyExtensions.fir.kt | 5 +++++ .../properties/localPropertyExtensions.kt | 5 +++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 16 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalExtensionPropertyChecker.kt create mode 100644 compiler/testData/diagnostics/tests/properties/localPropertyExtensions.fir.kt create mode 100644 compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index a13d87312ce..e04d8e85fd1 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -3043,6 +3043,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.LOCAL_EXTENSION_PROPERTY) { firDiagnostic -> + LocalExtensionPropertyImpl( + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.EXPECTED_DECLARATION_WITH_BODY) { firDiagnostic -> ExpectedDeclarationWithBodyImpl( firDiagnostic as KtPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index d72df577a34..b446c2b720a 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2145,6 +2145,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val declaration: KtSymbol } + abstract class LocalExtensionProperty : KtFirDiagnostic() { + override val diagnosticClass get() = LocalExtensionProperty::class + } + abstract class ExpectedDeclarationWithBody : KtFirDiagnostic() { override val diagnosticClass get() = ExpectedDeclarationWithBody::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 39094a20cc5..ef344e1749b 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -2586,6 +2586,11 @@ internal class LateinitIntrinsicCallOnNonAccessiblePropertyImpl( override val token: KtLifetimeToken, ) : KtFirDiagnostic.LateinitIntrinsicCallOnNonAccessibleProperty(), KtAbstractFirDiagnostic +internal class LocalExtensionPropertyImpl( + override val firDiagnostic: KtPsiDiagnostic, + override val token: KtLifetimeToken, +) : KtFirDiagnostic.LocalExtensionProperty(), KtAbstractFirDiagnostic + internal class ExpectedDeclarationWithBodyImpl( override val firDiagnostic: KtPsiDiagnostic, override val token: KtLifetimeToken, diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 992443957b0..c720247fbe1 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -24840,6 +24840,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt"); } + @Test + @TestMetadata("localPropertyExtensions.kt") + public void testLocalPropertyExtensions() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt"); + } + @Test @TestMetadata("protectedGetterWithPublicSetter.kt") public void testProtectedGetterWithPublicSetter() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 9c11ef56e4e..4f2df20673b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -24846,6 +24846,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt"); } + @Test + @TestMetadata("localPropertyExtensions.kt") + public void testLocalPropertyExtensions() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt"); + } + @Test @TestMetadata("protectedGetterWithPublicSetter.kt") public void testProtectedGetterWithPublicSetter() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 2fd5e73b57c..19fce4400d1 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -24840,6 +24840,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt"); } + @Test + @TestMetadata("localPropertyExtensions.kt") + public void testLocalPropertyExtensions() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt"); + } + @Test @TestMetadata("protectedGetterWithPublicSetter.kt") public void testProtectedGetterWithPublicSetter() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 0a7a08db8df..a7d58b1fb25 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1035,6 +1035,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY by error() { parameter("declaration") } + + val LOCAL_EXTENSION_PROPERTY by error() } val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index f4498d0a4fa..84c282195e3 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -565,6 +565,7 @@ object FirErrors { val LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT by error0() val LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION by error0() val LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY by error1>() + val LOCAL_EXTENSION_PROPERTY by error0() // Multi-platform projects val EXPECTED_DECLARATION_WITH_BODY by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index c0ce80ffc35..cc86361314b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -72,6 +72,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirLocalVariableTypeParametersSyntaxChecker, FirDelegateUsesExtensionPropertyTypeParameterChecker, FirTopLevelPropertiesChecker, + FirLocalExtensionPropertyChecker, ) override val backingFieldCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalExtensionPropertyChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalExtensionPropertyChecker.kt new file mode 100644 index 00000000000..bd96af742e5 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalExtensionPropertyChecker.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.utils.isExtension + +object FirLocalExtensionPropertyChecker : FirPropertyChecker() { + override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration.isLocal && declaration.isExtension) { + reporter.reportOn(declaration.receiverParameter?.source, FirErrors.LOCAL_EXTENSION_PROPERTY, context) + } + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index d9400b24189..ede68b4c78e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -300,6 +300,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_NULLABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_EXTENSION_PROPERTY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_NOT_ALLOWED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_VARIABLE_WITH_TYPE_PARAMETERS @@ -1668,6 +1669,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION, "This declaration can not be used inside an inline function") map.put(LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY, "Backing field of ''{0}'' is not accessible at this point", SYMBOL) + map.put(LOCAL_EXTENSION_PROPERTY, "Local extension properties are not allowed") + map.put(CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT, "Const 'val' are only allowed on top level, in named objects, or in companion objects") map.put(CONST_VAL_WITH_GETTER, "Const 'val' should not have a getter") map.put(CONST_VAL_WITH_DELEGATE, "Const 'val' should not have a delegate") diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index b506970a797..6fd60feec71 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -1198,6 +1198,8 @@ class DeclarationsConverter( returnTypeRef = returnType name = propertyName this.isVar = isVar + + receiverParameter = receiverType?.convertToReceiverParameter() initializer = propertyInitializer //probably can do this for delegateExpression itself @@ -1234,7 +1236,6 @@ class DeclarationsConverter( ) } else { this.isLocal = false - receiverParameter = receiverType?.convertToReceiverParameter() dispatchReceiverType = currentDispatchReceiverType() withCapturedTypeParameters(true, propertySource, firTypeParameters) { diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index c407fac4cf3..ce6ea9cb2a2 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1730,6 +1730,7 @@ open class RawFirBuilder( name = propertyName this.isVar = isVar + receiverParameter = receiverTypeReference.convertSafe()?.convertToReceiverParameter() initializer = propertyInitializer val propertyAnnotations = mutableListOf() @@ -1772,7 +1773,6 @@ open class RawFirBuilder( } } else { isLocal = false - receiverParameter = receiverTypeReference.convertSafe()?.convertToReceiverParameter() symbol = FirPropertySymbol(callableIdForName(propertyName)) dispatchReceiverType = currentDispatchReceiverType() extractTypeParametersTo(this, symbol) diff --git a/compiler/testData/diagnostics/tests/properties/localPropertyExtensions.fir.kt b/compiler/testData/diagnostics/tests/properties/localPropertyExtensions.fir.kt new file mode 100644 index 00000000000..e020502a3e2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/properties/localPropertyExtensions.fir.kt @@ -0,0 +1,5 @@ +// SKIP_TXT + +fun test() { + val String.count = 42 +} diff --git a/compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt b/compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt new file mode 100644 index 00000000000..e752642d8ca --- /dev/null +++ b/compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt @@ -0,0 +1,5 @@ +// SKIP_TXT + +fun test() { + val String.count = 42 +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 620097ac62e..a67047f53ad 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -24846,6 +24846,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.kt"); } + @Test + @TestMetadata("localPropertyExtensions.kt") + public void testLocalPropertyExtensions() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/localPropertyExtensions.kt"); + } + @Test @TestMetadata("protectedGetterWithPublicSetter.kt") public void testProtectedGetterWithPublicSetter() throws Exception {