From 75b40e4b75aff519a8889094180e401858d6542c Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Fri, 1 Oct 2021 00:05:49 +0300 Subject: [PATCH] [FIR] Add INVISIBLE_SETTER --- .../fir/generator/HLDiagnosticConverter.kt | 2 + .../diagnostics/KtFirDataClassConverters.kt | 9 ++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 8 ++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 9 ++ .../lazyResolve/annotationParameters.txt | 41 +++---- ...CompilerTestFE10TestdataTestGenerated.java | 12 ++ ...irOldFrontendDiagnosticsTestGenerated.java | 12 ++ ...DiagnosticsWithLightTreeTestGenerated.java | 12 ++ .../diagnostics/FirDiagnosticsList.kt | 6 + .../fir/analysis/diagnostics/FirErrors.kt | 2 + .../checkers/CommonExpressionCheckers.kt | 2 +- ...irReassignmentAndInvisibleSetterChecker.kt | 106 ++++++++++++++++++ .../expression/FirValReassignmentChecker.kt | 49 -------- .../diagnostics/FirDefaultErrorMessages.kt | 3 + .../diagnostics/FirDiagnosticRenderers.kt | 13 ++- .../fir/java/FirJavaVisibilityChecker.kt | 16 ++- .../rawBuilder/declarations/annotation.txt | 2 +- .../rawBuilder/declarations/derivedClass.txt | 2 +- .../rawBuilder/declarations/enums.txt | 6 +- .../rawBuilder/declarations/enums2.txt | 2 +- .../rawBuilder/declarations/nestedClass.txt | 2 +- .../rawBuilder/expressions/annotated.txt | 4 +- .../rawBuilder/expressions/arrayAccess.txt | 2 +- .../testData/rawBuilder/expressions/calls.txt | 4 +- .../expressions/collectionLiterals.txt | 6 +- .../rawBuilder/expressions/destructuring.txt | 6 +- .../testData/rawBuilder/expressions/for.txt | 4 +- .../rawBuilder/expressions/lambda.txt | 4 +- .../rawBuilder/expressions/locals.txt | 2 +- .../testData/rawBuilder/expressions/unary.txt | 4 +- .../kotlin/fir/FirVisibilityChecker.kt | 66 ++++++++--- .../tests/OverridenSetterVisibility.fir.kt | 29 ----- .../tests/OverridenSetterVisibility.kt | 1 + .../tests/controlFlowAnalysis/kt2330.fir.kt | 10 +- .../tests/controlFlowAnalysis/kt2960.fir.kt | 36 ------ .../tests/controlFlowAnalysis/kt2960.kt | 1 + .../controlFlowAnalysis/privateSetter.fir.kt | 17 --- .../controlFlowAnalysis/privateSetter.kt | 1 + .../tests/privateInFile/visibility.fir.kt | 2 +- ...ectedWithGenericsInDifferentPackage.fir.kt | 4 +- .../tests/scopes/invisibleSetter.fir.kt | 9 -- .../tests/scopes/invisibleSetter.kt | 1 + .../protectedPropertyInPrimaryConstructor.kt | 9 ++ .../protectedPropertyInPrimaryConstructor.txt | 11 ++ .../syntheticPropertyExtensions.fir.kt | 8 +- .../syntheticPropertyExtensions.kt | 2 - .../protectedVisibility/withSmartcast.fir.kt | 2 +- .../visibleSetterFromSyntheticProperty.kt | 21 ++++ .../visibleSetterFromSyntheticProperty.txt | 13 +++ .../javaProperties/OnlyPublic.fir.kt | 2 +- .../invisibleSetterOfJavaClass.fir.kt | 8 +- ...etterOfJavaClassWithDisabledFeature.fir.kt | 4 +- ...sibleSetterOfJavaClassInSamePackage.fir.kt | 4 +- .../test/runners/DiagnosticTestGenerated.java | 12 ++ 54 files changed, 393 insertions(+), 232 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/OverridenSetterVisibility.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/scopes/invisibleSetter.fir.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.txt create mode 100644 compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.txt diff --git a/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt b/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt index 5e619c24197..0560c97346d 100644 --- a/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt +++ b/analysis/analysis-api-fir/analysis-api-fir-generator/src/org/jetbrains/kotlin/analysis/api/fir/generator/HLDiagnosticConverter.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtExpression @@ -340,6 +341,7 @@ private object FirToKtConversionCreator { FirModuleData::class, ExpectActualCompatibility.Incompatible::class, DeprecationInfo::class, + CallableId::class ) private val KType.kClass: KClass<*> 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 f33574fd614..1eef99131b1 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 @@ -246,6 +246,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.INVISIBLE_SETTER) { firDiagnostic -> + InvisibleSetterImpl( + firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir), + firDiagnostic.b, + firDiagnostic.c, + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.INVISIBLE_REFERENCE) { firDiagnostic -> InvisibleReferenceImpl( firSymbolBuilder.buildSymbol(firDiagnostic.a.fir), 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 e7233c4cd16..81b1f597b7e 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 @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -203,6 +204,13 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val valOrVar: KtKeywordToken } + abstract class InvisibleSetter : KtFirDiagnostic() { + override val diagnosticClass get() = InvisibleSetter::class + abstract val property: KtVariableSymbol + abstract val visibility: Visibility + abstract val callableId: CallableId + } + abstract class InvisibleReference : KtFirDiagnostic() { override val diagnosticClass get() = InvisibleReference::class abstract val reference: KtSymbol 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 151a374d66d..65b0de8c1db 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 @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -231,6 +232,14 @@ internal class ValOrVarOnSecondaryConstructorParameterImpl( override val token: ValidityToken, ) : KtFirDiagnostic.ValOrVarOnSecondaryConstructorParameter(), KtAbstractFirDiagnostic +internal class InvisibleSetterImpl( + override val property: KtVariableSymbol, + override val visibility: Visibility, + override val callableId: CallableId, + override val firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.InvisibleSetter(), KtAbstractFirDiagnostic + internal class InvisibleReferenceImpl( override val reference: KtSymbol, override val firDiagnostic: FirPsiDiagnostic, diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt index 2c8c64fc4ef..89cebb6da8b 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt @@ -1,3 +1,4 @@ + RAW_FIR: FILE: annotationParameters.kt public? final? [RAW_FIR] enum class X : R|kotlin/Enum| { @@ -19,7 +20,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [RAW_FIR] class B : R|kotlin/Any| { @@ -56,7 +57,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [RAW_FIR] class B : R|kotlin/Any| { @@ -93,7 +94,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [RAW_FIR] class B : R|kotlin/Any| { @@ -130,7 +131,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [SUPER_TYPES] class B : R|kotlin/Any| { @@ -167,7 +168,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [SUPER_TYPES] class B : R|kotlin/Any| { @@ -204,7 +205,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [SUPER_TYPES] class B : R|kotlin/Any| { @@ -241,7 +242,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [SUPER_TYPES] class B : R|kotlin/Any| { @@ -278,7 +279,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [STATUS] class B : R|kotlin/Any| { @@ -315,7 +316,7 @@ FILE: annotationParameters.kt } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [STATUS] class B : R|kotlin/Any| { @@ -352,7 +353,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [RAW_FIR] class B : R|kotlin/Any| { @@ -389,7 +390,7 @@ FILE: annotationParameters.kt } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [STATUS] class B : R|kotlin/Any| { @@ -426,7 +427,7 @@ FILE: annotationParameters.kt } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [STATUS] class B : R|kotlin/Any| { @@ -463,7 +464,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [RAW_FIR] class B : R|kotlin/Any| { @@ -500,7 +501,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [SUPER_TYPES] class B : R|kotlin/Any| { @@ -537,7 +538,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [SUPER_TYPES] class B : R|kotlin/Any| { @@ -574,7 +575,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [SUPER_TYPES] class B : R|kotlin/Any| { @@ -611,7 +612,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public final [SUPER_TYPES] class B : R|kotlin/Any| { @@ -648,7 +649,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [SUPER_TYPES] class B : R|kotlin/Any| { @@ -685,7 +686,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| - [TYPES] public? get(): A.X + [TYPES] [ContainingClassKey=Anno] public? get(): A.X } public? final? [SUPER_TYPES] class B : R|kotlin/Any| { @@ -722,7 +723,7 @@ FILE: annotationParameters.kt } public final [BODY_RESOLVE] [IsFromPrimaryConstructor=true] val args: = R|/args| - [BODY_RESOLVE] public get(): + [BODY_RESOLVE] [ContainingClassKey=Anno] public get(): } public final [BODY_RESOLVE] class B : R|kotlin/Any| { 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 ca3250a6414..c4a00818364 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 @@ -25481,6 +25481,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/scopes/VisibilityInheritModifier.kt"); } + @Test + @TestMetadata("visibleSetterFromSyntheticProperty.kt") + public void testVisibleSetterFromSyntheticProperty() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/scopes/classHeader") @TestDataPath("$PROJECT_ROOT") @@ -25920,6 +25926,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedCallOnSubClass.kt"); } + @Test + @TestMetadata("protectedPropertyInPrimaryConstructor.kt") + public void testProtectedPropertyInPrimaryConstructor() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt"); + } + @Test @TestMetadata("smartcastOnExtensionReceiver.kt") public void testSmartcastOnExtensionReceiver() 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 1a3aa6621a8..e52390f03be 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 @@ -25481,6 +25481,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/scopes/VisibilityInheritModifier.kt"); } + @Test + @TestMetadata("visibleSetterFromSyntheticProperty.kt") + public void testVisibleSetterFromSyntheticProperty() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/scopes/classHeader") @TestDataPath("$PROJECT_ROOT") @@ -25920,6 +25926,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedCallOnSubClass.kt"); } + @Test + @TestMetadata("protectedPropertyInPrimaryConstructor.kt") + public void testProtectedPropertyInPrimaryConstructor() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt"); + } + @Test @TestMetadata("smartcastOnExtensionReceiver.kt") public void testSmartcastOnExtensionReceiver() 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 9e5c1cc9ece..92e3fa10c29 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 @@ -25481,6 +25481,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/scopes/VisibilityInheritModifier.kt"); } + @Test + @TestMetadata("visibleSetterFromSyntheticProperty.kt") + public void testVisibleSetterFromSyntheticProperty() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/scopes/classHeader") @TestDataPath("$PROJECT_ROOT") @@ -25920,6 +25926,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedCallOnSubClass.kt"); } + @Test + @TestMetadata("protectedPropertyInPrimaryConstructor.kt") + public void testProtectedPropertyInPrimaryConstructor() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt"); + } + @Test @TestMetadata("smartcastOnExtensionReceiver.kt") public void testSmartcastOnExtensionReceiver() 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 7a175b93c3b..67d7253b8d5 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 @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* @@ -88,6 +89,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning(PositioningStrategy.VAL_OR_VAR_NODE) { parameter("valOrVar") } + val INVISIBLE_SETTER by error(PositioningStrategy.ASSIGNMENT_LHS) { + parameter("property") + parameter("visibility") + parameter("callableId") + } } val UNRESOLVED by object : DiagnosticGroup("Unresolved") { 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 86fe9e291ae..84e166bb8d6 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 @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtKeywordToken import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtAnnotationEntry @@ -128,6 +129,7 @@ object FirErrors { val VAL_OR_VAR_ON_FUN_PARAMETER by warning1(SourceElementPositioningStrategies.VAL_OR_VAR_NODE) val VAL_OR_VAR_ON_CATCH_PARAMETER by warning1(SourceElementPositioningStrategies.VAL_OR_VAR_NODE) val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning1(SourceElementPositioningStrategies.VAL_OR_VAR_NODE) + val INVISIBLE_SETTER by error3(SourceElementPositioningStrategies.ASSIGNMENT_LHS) // Unresolved val INVISIBLE_REFERENCE by error1>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt index 753b8a67a94..890471b5b24 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt @@ -67,7 +67,7 @@ object CommonExpressionCheckers : ExpressionCheckers() { override val variableAssignmentCheckers: Set get() = setOf( - FirValReassignmentChecker, + FirReassignmentAndInvisibleSetterChecker, FirAssignmentTypeMismatchChecker ) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt new file mode 100644 index 00000000000..34d5b64a9f6 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReassignmentAndInvisibleSetterChecker.kt @@ -0,0 +1,106 @@ +/* + * Copyright 2010-2021 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.expression + +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest +import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor +import org.jetbrains.kotlin.fir.declarations.utils.visibility +import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast +import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment +import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol +import org.jetbrains.kotlin.fir.originalForSubstitutionOverride +import org.jetbrains.kotlin.fir.references.FirBackingFieldReference +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue +import org.jetbrains.kotlin.fir.symbols.SymbolInternals +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol +import org.jetbrains.kotlin.fir.visibilityChecker + +object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() { + override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) { + checkInvisibleSetter(expression, context, reporter) + checkValReassignmentViaBackingField(expression, context, reporter) + checkValReassignmentOnValueParameter(expression, context, reporter) + } + + private fun checkInvisibleSetter( + expression: FirVariableAssignment, + context: CheckerContext, + reporter: DiagnosticReporter + ) { + fun shouldInvisibleSetterBeReported(symbol: FirPropertySymbol): Boolean { + @OptIn(SymbolInternals::class) + val setterFir = symbol.setterSymbol?.fir ?: symbol.originalForSubstitutionOverride?.setterSymbol?.fir + if (setterFir != null) { + return !context.session.visibilityChecker.isVisible( + setterFir, + context.session, + context.findClosest()!!, + context.containingDeclarations, + ExpressionReceiverValue(expression.dispatchReceiver), + ) + } + + return false + } + + val callableSymbol = expression.calleeReference.toResolvedCallableSymbol() + if (callableSymbol is FirPropertySymbol && shouldInvisibleSetterBeReported(callableSymbol)) { + val explicitReceiver = expression.explicitReceiver + // Try to get type from smartcast + if (explicitReceiver is FirExpressionWithSmartcast) { + val symbol = explicitReceiver.originalType.toRegularClassSymbol(context.session) + if (symbol != null) { + for (declarationSymbol in symbol.declarationSymbols) { + if (declarationSymbol is FirPropertySymbol && declarationSymbol.name == callableSymbol.name) { + if (!shouldInvisibleSetterBeReported(declarationSymbol)) { + return + } + } + } + } + } + reporter.reportOn( + expression.source, + FirErrors.INVISIBLE_SETTER, + callableSymbol, + callableSymbol.setterSymbol?.visibility ?: Visibilities.Private, + callableSymbol.callableId, + context + ) + } + } + + private fun checkValReassignmentViaBackingField( + expression: FirVariableAssignment, + context: CheckerContext, + reporter: DiagnosticReporter + ) { + val backingFieldReference = expression.lValue as? FirBackingFieldReference ?: return + val propertySymbol = backingFieldReference.resolvedSymbol + if (propertySymbol.isVar) return + val closestGetter = context.findClosest { it.isGetter }?.symbol ?: return + if (propertySymbol.getterSymbol != closestGetter) return + + reporter.reportOn(backingFieldReference.source, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, propertySymbol, context) + } + + private fun checkValReassignmentOnValueParameter( + expression: FirVariableAssignment, + context: CheckerContext, + reporter: DiagnosticReporter + ) { + val valueParameter = (expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol as? FirValueParameterSymbol ?: return + reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter, context) + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentChecker.kt index 6f26394dd78..e69de29bb2d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirValReassignmentChecker.kt @@ -1,49 +0,0 @@ -/* - * Copyright 2010-2021 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.expression - -import org.jetbrains.kotlin.config.LanguageFeature -import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest -import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors -import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn -import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor -import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment -import org.jetbrains.kotlin.fir.languageVersionSettings -import org.jetbrains.kotlin.fir.references.FirBackingFieldReference -import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol - -object FirValReassignmentChecker : FirVariableAssignmentChecker() { - override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) { - checkValReassignmentViaBackingField(expression, context, reporter) - checkValReassignmentOnValueParameter(expression, context, reporter) - } - - private fun checkValReassignmentViaBackingField( - expression: FirVariableAssignment, - context: CheckerContext, - reporter: DiagnosticReporter - ) { - val backingFieldReference = expression.lValue as? FirBackingFieldReference ?: return - val propertySymbol = backingFieldReference.resolvedSymbol - if (propertySymbol.isVar) return - val closestGetter = context.findClosest { it.isGetter }?.symbol ?: return - if (propertySymbol.getterSymbol != closestGetter) return - - reporter.reportOn(backingFieldReference.source, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, propertySymbol, context) - } - - private fun checkValReassignmentOnValueParameter( - expression: FirVariableAssignment, - context: CheckerContext, - reporter: DiagnosticReporter - ) { - val valueParameter = (expression.lValue as? FirResolvedNamedReference)?.resolvedSymbol as? FirValueParameterSymbol ?: return - reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, valueParameter, context) - } -} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index fe7ebb123d6..905e70a9e4c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTION_PARAMETERS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.MODULE_DATA +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME_OF_CONTAINING_DECLARATION_OR_FILE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT @@ -247,6 +248,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_DEFAULT_F import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_REFERENCE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_SETTER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IS_ENUM_ENTRY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ITERATOR_AMBIGUITY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE @@ -554,6 +556,7 @@ class FirDefaultErrorMessages { // Unresolved map.put(INVISIBLE_REFERENCE, "Symbol {0} is invisible", SYMBOL) + map.put(INVISIBLE_SETTER, "Cannot access ''{0}'': it is {1} in {2}", VARIABLE_NAME, VISIBILITY, NAME_OF_CONTAINING_DECLARATION_OR_FILE) map.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", NULLABLE_STRING) map.put(UNRESOLVED_LABEL, "Unresolved label") map.put(DESERIALIZATION_ERROR, "Deserialization error") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index 2bbf26ea377..1513dbe8f8f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -14,16 +14,14 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderer import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirRenderer -import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.render -import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.render +import org.jetbrains.kotlin.name.CallableId object FirDiagnosticRenderers { val NULLABLE_STRING = Renderer { it ?: "null" } @@ -139,6 +137,15 @@ object FirDiagnosticRenderers { "Module ${it.name}" } + val NAME_OF_CONTAINING_DECLARATION_OR_FILE = Renderer { symbol: CallableId -> + val classId = symbol.classId + if (classId == null) { + "file" + } else { + "'${classId}'" + } + } + @Suppress("FunctionName") fun COLLECTION(renderer: ContextIndependentParameterRenderer): ContextIndependentParameterRenderer> { return Renderer { list -> diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt index 83ca1d5fe6b..2b4a9ad78ac 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt @@ -11,11 +11,13 @@ import org.jetbrains.kotlin.descriptors.java.JavaVisibilities import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertySymbol import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol @NoMutableState @@ -37,19 +39,25 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() { val ownerLookupTag = symbol.getOwnerLookupTag() ?: return false if (canSeeProtectedMemberOf( containingDeclarations, dispatchReceiver, ownerLookupTag, session, - isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol + isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol || symbol is FirPropertyAccessorSymbol, + isSyntheticProperty = symbol.fir is FirSyntheticPropertyAccessor ) ) return true // FE1.0 allows calling public setters with property assignment syntax if the getter is protected. if (!isCallToPropertySetter || symbol !is FirSyntheticPropertySymbol) return false - val setterVisibility = symbol.setterSymbol?.visibility - setterVisibility != null && setterVisibility == Visibilities.Public + symbol.setterSymbol?.visibility == Visibilities.Public } } JavaVisibilities.PackageVisibility -> { - symbol.packageFqName() == useSiteFile.packageFqName + if (symbol.packageFqName() == useSiteFile.packageFqName) { + true + } else if (symbol.fir is FirSyntheticPropertyAccessor) { + symbol.getOwnerLookupTag()?.classId?.packageFqName == useSiteFile.packageFqName + } else { + false + } } else -> true diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.txt index 3a780f34ad4..977e48123dc 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.txt @@ -17,7 +17,7 @@ FILE: annotation.kt } @base() public? final? [IsFromPrimaryConstructor=true] val x: Int = R|/x| - public? get(): Int + [ContainingClassKey=correct] public? get(): Int @base() public? [ContainingClassKey=correct] constructor(): R|correct| { this(IntegerLiteral(0)) diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.txt index 53ecbc6f651..0579e42c780 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.txt @@ -5,7 +5,7 @@ FILE: derivedClass.kt } public? final? [IsFromPrimaryConstructor=true] val x: T = R|/x| - public? get(): T + [ContainingClassKey=Base] public? get(): T } public? final? class Derived : Base { diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.txt index 3b13e972119..c0f9f7059cd 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.txt @@ -20,10 +20,10 @@ FILE: enums.kt } public? final? [IsFromPrimaryConstructor=true] val m: Double = R|/m| - public? get(): Double + [ContainingClassKey=Planet] public? get(): Double internal final? [IsFromPrimaryConstructor=true] val r: Double = R|/r| - internal get(): Double + [ContainingClassKey=Planet] internal get(): Double public final static [ContainingClassKey=Planet] enum entry MERCURY: R|Planet| = object : R|Planet| { private [ContainingClassKey=] constructor(): R|| { @@ -86,7 +86,7 @@ FILE: enums.kt } public? final? [IsFromPrimaryConstructor=true] val signature: String = R|/signature| - public? get(): String + [ContainingClassKey=PseudoInsn] public? get(): String public final static [ContainingClassKey=PseudoInsn] enum entry FIX_STACK_BEFORE_JUMP: R|PseudoInsn| = object : R|PseudoInsn| { private [ContainingClassKey=] constructor(): R|| { diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.txt index b55a76a0577..176f4863b0e 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.txt @@ -19,7 +19,7 @@ FILE: enums2.kt } public? final? [IsFromPrimaryConstructor=true] val x: Some = R|/x| - public? get(): Some + [ContainingClassKey=SomeEnum] public? get(): Some public final static [ContainingClassKey=SomeEnum] enum entry FIRST: R|SomeEnum| = object : R|SomeEnum| { private [ContainingClassKey=] constructor(): R|| { diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.txt index 49d09061a30..118a96bd357 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.txt @@ -5,7 +5,7 @@ FILE: nestedClass.kt } public? final? [IsFromPrimaryConstructor=true] val s: String = R|/s| - public? get(): String + [ContainingClassKey=Base] public? get(): String } public? final? class Outer : R|kotlin/Any| { diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.txt index 7f39ccd7c30..9d3488a3e19 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.txt @@ -26,10 +26,10 @@ FILE: annotated.kt } public? final? [IsFromPrimaryConstructor=true] val x: Int = R|/x| - public? get(): Int + [ContainingClassKey=Two] public? get(): Int public? final? [IsFromPrimaryConstructor=true] val y: Int = R|/y| - public? get(): Int + [ContainingClassKey=Two] public? get(): Int public final operator fun component1(): Int diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt index d7e5460fb14..2e90a3353fa 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt @@ -10,7 +10,7 @@ FILE: arrayAccess.kt } public? final? [IsFromPrimaryConstructor=true] val v: IntArray = R|/v| - public? get(): IntArray + [ContainingClassKey=Wrapper] public? get(): IntArray } public? final? fun test(a: IntArray, w: Wrapper): { diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.txt index f2456c0b04a..1b412d64b11 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.txt @@ -14,8 +14,8 @@ FILE: calls.kt } public? final? [IsFromPrimaryConstructor=true] var x: Int = R|/x| - public? get(): Int - public? set(value: Int): R|kotlin/Unit| + [ContainingClassKey=My] public? get(): Int + [ContainingClassKey=My] public? set(value: Int): R|kotlin/Unit| public? final? operator fun invoke(): { ^invoke x# diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt index d9d66d54da9..ad3e0e42498 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt @@ -5,7 +5,7 @@ FILE: collectionLiterals.kt } public? final? [IsFromPrimaryConstructor=true] val arr: IntArray = R|/arr| - public? get(): IntArray + [ContainingClassKey=Ann1] public? get(): IntArray } public? final? annotation class Ann2 : R|kotlin/Annotation| { @@ -14,7 +14,7 @@ FILE: collectionLiterals.kt } public? final? [IsFromPrimaryConstructor=true] val arr: DoubleArray = R|/arr| - public? get(): DoubleArray + [ContainingClassKey=Ann2] public? get(): DoubleArray } public? final? annotation class Ann3 : R|kotlin/Annotation| { @@ -23,7 +23,7 @@ FILE: collectionLiterals.kt } public? final? [IsFromPrimaryConstructor=true] val arr: Array = R|/arr| - public? get(): Array + [ContainingClassKey=Ann3] public? get(): Array } @Ann1(()) @Ann2(()) @Ann3(()) public? final? class Zero : R|kotlin/Any| { diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt index f6e3bbab64a..a24b4937c40 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt @@ -5,13 +5,13 @@ FILE: destructuring.kt } public? final? [IsFromPrimaryConstructor=true] val first: Int = R|/first| - public? get(): Int + [ContainingClassKey=Some] public? get(): Int public? final? [IsFromPrimaryConstructor=true] val second: Double = R|/second| - public? get(): Double + [ContainingClassKey=Some] public? get(): Double public? final? [IsFromPrimaryConstructor=true] val third: String = R|/third| - public? get(): String + [ContainingClassKey=Some] public? get(): String public final operator fun component1(): Int diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.txt index 83d82532f06..e64defce226 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.txt @@ -55,10 +55,10 @@ FILE: for.kt } public? final? [IsFromPrimaryConstructor=true] val x: Int = R|/x| - public? get(): Int + [ContainingClassKey=Some] public? get(): Int public? final? [IsFromPrimaryConstructor=true] val y: Int = R|/y| - public? get(): Int + [ContainingClassKey=Some] public? get(): Int public final operator fun component1(): Int diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.txt index b42fc2acc1a..8eeee45ad9c 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.txt @@ -5,10 +5,10 @@ FILE: lambda.kt } public? final? [IsFromPrimaryConstructor=true] val x: Int = R|/x| - public? get(): Int + [ContainingClassKey=Tuple] public? get(): Int public? final? [IsFromPrimaryConstructor=true] val y: Int = R|/y| - public? get(): Int + [ContainingClassKey=Tuple] public? get(): Int public final operator fun component1(): Int diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.txt index f4ea94c861e..7d0e996c9d5 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.txt @@ -6,7 +6,7 @@ FILE: locals.kt } public? final? [IsFromPrimaryConstructor=true] val pp: Int = R|/pp| - public? get(): Int + [ContainingClassKey=Local] public? get(): Int public? final? fun diff(): { ^diff pp#.minus#(p#) diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt index 8111e78ee58..05e25517cd0 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt @@ -36,7 +36,7 @@ FILE: unary.kt } public? final? [IsFromPrimaryConstructor=true] val i: Int = R|/i| - public? get(): Int + [ContainingClassKey=X] public? get(): Int } public? final? fun test2(x: X): R|kotlin/Unit| { @@ -79,7 +79,7 @@ FILE: unary.kt } public? final? [IsFromPrimaryConstructor=true] val arr: Array = R|/arr| - public? get(): Array + [ContainingClassKey=Y] public? get(): Array } public? final? fun test4(y: Y): R|kotlin/Unit| { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt index bc8d6042b26..05672fa9240 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -5,18 +5,17 @@ package org.jetbrains.kotlin.fir +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.resolve.* -import org.jetbrains.kotlin.fir.resolve.calls.Candidate -import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue -import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol -import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue +import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* @@ -167,7 +166,8 @@ abstract class FirVisibilityChecker : FirSessionComponent { val ownerId = symbol.getOwnerLookupTag() ownerId != null && canSeeProtectedMemberOf( containingDeclarations, dispatchReceiver, ownerId, session, - isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol + isVariableOrNamedFunction = symbol is FirVariableSymbol || symbol is FirNamedFunctionSymbol || symbol is FirPropertyAccessorSymbol, + symbol.fir is FirSyntheticPropertyAccessor ) } @@ -233,7 +233,8 @@ abstract class FirVisibilityChecker : FirSessionComponent { dispatchReceiver: ReceiverValue?, ownerLookupTag: ConeClassLikeLookupTag, session: FirSession, - isVariableOrNamedFunction: Boolean + isVariableOrNamedFunction: Boolean, + isSyntheticProperty: Boolean ): Boolean { dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerLookupTag -> if (containingUseSiteClass.isSubClass(companionOwnerLookupTag, session)) return true @@ -241,7 +242,13 @@ abstract class FirVisibilityChecker : FirSessionComponent { return when { !containingUseSiteClass.isSubClass(ownerLookupTag, session) -> false - isVariableOrNamedFunction -> doesReceiverFitForProtectedVisibility(dispatchReceiver, containingUseSiteClass, session) + isVariableOrNamedFunction -> doesReceiverFitForProtectedVisibility( + dispatchReceiver, + containingUseSiteClass, + ownerLookupTag, + isSyntheticProperty, + session + ) else -> true } } @@ -249,6 +256,8 @@ abstract class FirVisibilityChecker : FirSessionComponent { private fun doesReceiverFitForProtectedVisibility( dispatchReceiver: ReceiverValue?, containingUseSiteClass: FirClass, + ownerLookupTag: ConeClassLikeLookupTag, + isSyntheticProperty: Boolean, session: FirSession ): Boolean { if (dispatchReceiver == null) return true @@ -264,9 +273,21 @@ abstract class FirVisibilityChecker : FirSessionComponent { errorTypesEqualToAnything = false, stubTypesEqualToAnything = false ) - return AbstractTypeChecker.isSubtypeOf( - typeCheckerState, dispatchReceiverType.fullyExpandedType(session), containingUseSiteClass.typeWithStarProjections() - ) + if (AbstractTypeChecker.isSubtypeOf( + typeCheckerState, dispatchReceiverType.fullyExpandedType(session), containingUseSiteClass.typeWithStarProjections() + ) + ) { + return true + } + + if (isSyntheticProperty) { + return if (session.languageVersionSettings.supportsFeature(LanguageFeature.ImproveReportingDiagnosticsOnProtectedMembersOfBaseClass)) + containingUseSiteClass.classId.packageFqName == ownerLookupTag.classId.packageFqName + else + true + } + + return false } private fun FirClass.isSubClass(ownerLookupTag: ConeClassLikeLookupTag, session: FirSession): Boolean { @@ -295,14 +316,31 @@ abstract class FirVisibilityChecker : FirSessionComponent { dispatchReceiver: ReceiverValue?, ownerLookupTag: ConeClassLikeLookupTag, session: FirSession, - isVariableOrNamedFunction: Boolean + isVariableOrNamedFunction: Boolean, + isSyntheticProperty: Boolean ): Boolean { if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerLookupTag, session)) return true for (containingDeclaration in containingDeclarationOfUseSite) { - if (containingDeclaration !is FirClass) continue - val boundSymbol = containingDeclaration.symbol - if (canSeeProtectedMemberOf(boundSymbol.fir, dispatchReceiver, ownerLookupTag, session, isVariableOrNamedFunction)) return true + if (containingDeclaration is FirClass) { + val boundSymbol = containingDeclaration.symbol + if (canSeeProtectedMemberOf( + boundSymbol.fir, + dispatchReceiver, + ownerLookupTag, + session, + isVariableOrNamedFunction, + isSyntheticProperty + ) + ) return true + } else if (containingDeclaration is FirFile) { + if (isSyntheticProperty && + session.languageVersionSettings.supportsFeature(LanguageFeature.ImproveReportingDiagnosticsOnProtectedMembersOfBaseClass) && + containingDeclaration.packageFqName == ownerLookupTag.classId.packageFqName + ) { + return true + } + } } return false diff --git a/compiler/testData/diagnostics/tests/OverridenSetterVisibility.fir.kt b/compiler/testData/diagnostics/tests/OverridenSetterVisibility.fir.kt deleted file mode 100644 index a64fb768a94..00000000000 --- a/compiler/testData/diagnostics/tests/OverridenSetterVisibility.fir.kt +++ /dev/null @@ -1,29 +0,0 @@ -public interface ITest { - public var prop : Int - get() = 12 - set(value) {} -} - -abstract class ATest { - protected open var prop2 : Int - get() = 13 - set(value) {} -} - -class Test: ATest(), ITest { - override var prop : Int - get() = 12 - private set(value) {} - - override var prop2 : Int - get() = 14 - internal set(value) {} -} - -fun main() { - val test = Test() - test.prop = 12 - - val itest: ITest = test - itest.prop = 12 // No error here -} diff --git a/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt b/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt index b0faa7dcb3d..58df8486b5e 100644 --- a/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt +++ b/compiler/testData/diagnostics/tests/OverridenSetterVisibility.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL public interface ITest { public var prop : Int get() = 12 diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2330.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2330.fir.kt index 2964014cd39..23e18692ae9 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2330.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2330.fir.kt @@ -23,23 +23,23 @@ class P { fun foo() { val p = P() - p.x = 34 //should be an error here + p.x = 34 //should be an error here p.y = 23 fun inner() { - p.x = 44 + p.x = 44 } } class R { val p = P(); init { - p.x = 42 + p.x = 42 } val testInGetterInOtherClass : Int get() { - p.x = 33 + p.x = 33 return 3 } } @@ -50,4 +50,4 @@ fun test() { p.x = 43 } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.fir.kt deleted file mode 100644 index 24429bf8014..00000000000 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.fir.kt +++ /dev/null @@ -1,36 +0,0 @@ -//KT-2960 Perform control flow checks for package property initializers - -package b - -class P { - var x : Int = 0 - private set -} - -val p = P() -var f = { -> p.x = 32 } - -val o = object { - fun run() { - p.x = 4 - - val z : Int - doSmth(z) - } -} - -val g = { -> - val x: Int - doSmth(x) -} - -class A { - val a : Int = 1 - get() { - val x : Int - doSmth(x) - return field - } -} - -fun doSmth(i: Int) = i \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt index f09f34d3411..ff06fda7566 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL //KT-2960 Perform control flow checks for package property initializers package b diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.fir.kt deleted file mode 100644 index 87364ae72a8..00000000000 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.fir.kt +++ /dev/null @@ -1,17 +0,0 @@ -open class X(s : String) { - public var n: String = s - private set - -} - -class Z : X("subclass") { - fun print(): String { - n = n - return n; - } -} - - -fun box() : String { - return Z().print() //error -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.kt index b4335ce390e..c5afe3b301b 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/privateSetter.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class X(s : String) { public var n: String = s private set diff --git a/compiler/testData/diagnostics/tests/privateInFile/visibility.fir.kt b/compiler/testData/diagnostics/tests/privateInFile/visibility.fir.kt index b179904c0cf..905eb64e3ab 100644 --- a/compiler/testData/diagnostics/tests/privateInFile/visibility.fir.kt +++ b/compiler/testData/diagnostics/tests/privateInFile/visibility.fir.kt @@ -40,7 +40,7 @@ fun test() { val po = PO val v = xx - xx = 40 + xx = 40 } class B : A() {} diff --git a/compiler/testData/diagnostics/tests/protectedWithGenericsInDifferentPackage.fir.kt b/compiler/testData/diagnostics/tests/protectedWithGenericsInDifferentPackage.fir.kt index c9fd9028fd7..af2e80afaac 100644 --- a/compiler/testData/diagnostics/tests/protectedWithGenericsInDifferentPackage.fir.kt +++ b/compiler/testData/diagnostics/tests/protectedWithGenericsInDifferentPackage.fir.kt @@ -28,14 +28,14 @@ fun test(s: bar.Sub) { s.name s.name = "" s.name2 - s.name2 = "" + s.name2 = "" s.doSomething() s.doSomething2() val s2: Super = s s2.name s2.name = "" s2.name2 - s2.name2 = "" + s2.name2 = "" s2.doSomething() s2.doSomething2() } diff --git a/compiler/testData/diagnostics/tests/scopes/invisibleSetter.fir.kt b/compiler/testData/diagnostics/tests/scopes/invisibleSetter.fir.kt deleted file mode 100644 index d37a025755f..00000000000 --- a/compiler/testData/diagnostics/tests/scopes/invisibleSetter.fir.kt +++ /dev/null @@ -1,9 +0,0 @@ -class A { - public var x: Int = 0 - private set -} - -fun main() { - val a = A() - a.x = 1 -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/invisibleSetter.kt b/compiler/testData/diagnostics/tests/scopes/invisibleSetter.kt index 09e2f95e1ea..95ff8ee22fd 100644 --- a/compiler/testData/diagnostics/tests/scopes/invisibleSetter.kt +++ b/compiler/testData/diagnostics/tests/scopes/invisibleSetter.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class A { public var x: Int = 0 private set diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt new file mode 100644 index 00000000000..da2052f988d --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt @@ -0,0 +1,9 @@ +// FIR_IDENTICAL +class Test(protected var prop1: Int = 1) { + protected var prop2: Int = 2 + + private fun test() { + prop1 = 3 + prop2 = 4 + } +} diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.txt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.txt new file mode 100644 index 00000000000..4ad1882a9bf --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.txt @@ -0,0 +1,11 @@ +package + +public final class Test { + public constructor Test(/*0*/ prop1: kotlin.Int = ...) + protected final var prop1: kotlin.Int + protected final var prop2: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + private final fun test(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.fir.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.fir.kt index 2b6a674e52d..286d569e69e 100644 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.fir.kt @@ -22,8 +22,7 @@ class B : A() { b.bar = b.bar + "" a.foo - // TODO: should be INVISIBLE_SETTER - a.bar = a.bar + "" + a.bar = a.bar + "" if (a is B) { a.foo @@ -33,13 +32,12 @@ class B : A() { if (d.x is B) { d.x.abc // Ok d.x.foo - // TODO: should be INVISIBLE_SETTER - d.x.bar = d.x.bar + "" + d.x.bar = d.x.bar + "" } } } fun baz(a: A) { a.foo - a.bar = a.bar + "" + a.bar = a.bar + "" } diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.kt index a26cafecede..656a477f5ba 100644 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.kt +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticPropertyExtensions.kt @@ -22,7 +22,6 @@ class B : A() { b.bar = b.bar + "" a.foo - // TODO: should be INVISIBLE_SETTER a.bar = a.bar + "" if (a is B) { @@ -33,7 +32,6 @@ class B : A() { if (d.x is B) { d.x.abc // Ok d.x.foo - // TODO: should be INVISIBLE_SETTER d.x.bar = d.x.bar + "" } } diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt index 0086e6c7c70..d3859c5764c 100644 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt @@ -15,7 +15,7 @@ class Derived : Base() { x.bar() x.x = x.x + 1 - x.y = x.y + 1 + x.y = x.y + 1 if (x is Derived) { x.foo() diff --git a/compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt b/compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt new file mode 100644 index 00000000000..3f93d4f7fa3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt @@ -0,0 +1,21 @@ +// FIR_IDENTICAL + +// FILE: Java.java + +public abstract class Java { + private String _name = null; + + void setName(String name) { + this._name = name; + } + + public String getName() { + return _name; + } +} + +// FILE: main.kt + +fun Java.test(name: String) { + this.name = name +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.txt b/compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.txt new file mode 100644 index 00000000000..c8123e91298 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.txt @@ -0,0 +1,13 @@ +package + +public fun Java.test(/*0*/ name: kotlin.String): kotlin.Unit + +public abstract class Java { + public constructor Java() + private final var _name: kotlin.String! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun getName(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public/*package*/ open fun setName(/*0*/ name: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OnlyPublic.fir.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OnlyPublic.fir.kt index 12b86439d5d..dfda95bed2c 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OnlyPublic.fir.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/OnlyPublic.fir.kt @@ -8,7 +8,7 @@ fun foo(javaClass: JavaClass) { javaClass.somethingProtected javaClass.somethingPrivate javaClass.somethingPackage - javaClass.somethingPublic = 1 + javaClass.somethingPublic = 1 } // FILE: JavaClass.java diff --git a/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClass.fir.kt b/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClass.fir.kt index bd3fbbf6a49..f4b5a37cda9 100644 --- a/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClass.fir.kt +++ b/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClass.fir.kt @@ -18,12 +18,12 @@ class Data(var x: Foo) class B : Foo() { fun baz(a: Foo, t: Foo, d: Data) { - a.bar = t.bar - a.foo = t.foo + a.bar = t.bar + a.foo = t.foo if (d.x is B) { - d.x.bar = d.x.bar + "" - d.x.foo = d.x.foo + "" + d.x.bar = d.x.bar + "" + d.x.foo = d.x.foo + "" } } } diff --git a/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClassWithDisabledFeature.fir.kt b/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClassWithDisabledFeature.fir.kt index 9ee3b7b757d..90ec72a9356 100644 --- a/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClassWithDisabledFeature.fir.kt +++ b/compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClassWithDisabledFeature.fir.kt @@ -19,11 +19,11 @@ class Data(var x: Foo) class B : Foo() { fun baz(a: Foo, t: Foo, d: Data) { a.bar = t.bar - a.foo = t.foo + a.foo = t.foo if (d.x is B) { d.x.bar = d.x.bar + "" - d.x.foo = d.x.foo + "" + d.x.foo = d.x.foo + "" } } } diff --git a/compiler/testData/diagnostics/tests/visibility/lackOfInvisibleSetterOfJavaClassInSamePackage.fir.kt b/compiler/testData/diagnostics/tests/visibility/lackOfInvisibleSetterOfJavaClassInSamePackage.fir.kt index 7c542493194..8d6b426f6db 100644 --- a/compiler/testData/diagnostics/tests/visibility/lackOfInvisibleSetterOfJavaClassInSamePackage.fir.kt +++ b/compiler/testData/diagnostics/tests/visibility/lackOfInvisibleSetterOfJavaClassInSamePackage.fir.kt @@ -13,11 +13,11 @@ class Data(var x: Foo) class B : Foo() { fun baz(a: Foo, t: Foo, d: Data) { a.bar = t.bar - a.foo = t.foo + a.foo = t.foo if (d.x is B) { d.x.bar = d.x.bar + "" - d.x.foo = d.x.foo + "" + d.x.foo = d.x.foo + "" } } } 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 248ab0f93f6..57692385ea5 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 @@ -25493,6 +25493,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/scopes/VisibilityInheritModifier.kt"); } + @Test + @TestMetadata("visibleSetterFromSyntheticProperty.kt") + public void testVisibleSetterFromSyntheticProperty() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/visibleSetterFromSyntheticProperty.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/scopes/classHeader") @TestDataPath("$PROJECT_ROOT") @@ -25932,6 +25938,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedCallOnSubClass.kt"); } + @Test + @TestMetadata("protectedPropertyInPrimaryConstructor.kt") + public void testProtectedPropertyInPrimaryConstructor() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/protectedVisibility/protectedPropertyInPrimaryConstructor.kt"); + } + @Test @TestMetadata("smartcastOnExtensionReceiver.kt") public void testSmartcastOnExtensionReceiver() throws Exception {