From d3e8cc577cc28ca2fe64fd506952b33045bc7723 Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Thu, 2 Sep 2021 15:02:34 -0700 Subject: [PATCH] FIR checker: fix local type approximation on delegated property Previously types of delegated property is not approximated, which can cause local types to leak through public APIs. --- ...CompilerTestFE10TestdataTestGenerated.java | 6 ++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++ ...rCallCompletionResultsWriterTransformer.kt | 77 ++++++++++++------- .../FirDeclarationsResolveTransformer.kt | 5 +- .../ambiguousObjectExpressionType.fir.kt | 56 +++++++++++++- .../ambiguousObjectExpressionType.kt | 56 +++++++++++++- .../ambiguousObjectExpressionType.txt | 23 +++++- .../localObjectInInnerClass.fir.kt | 30 ++++++++ .../localObjectInInnerClass.kt | 30 ++++++++ .../localObjectInInnerClass.txt | 44 +++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++ 12 files changed, 314 insertions(+), 31 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.fir.kt create mode 100644 compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt create mode 100644 compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.txt 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 502e28f748b..eec7c710c3c 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 @@ -7543,6 +7543,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/declarationChecks/localFunctionNoInheritVisibility.kt"); } + @Test + @TestMetadata("localObjectInInnerClass.kt") + public void testLocalObjectInInnerClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt"); + } + @Test @TestMetadata("LocalVariableWithNoTypeInformation.kt") public void testLocalVariableWithNoTypeInformation() 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 4acd3ef5722..66c838c8d04 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 @@ -7543,6 +7543,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/declarationChecks/localFunctionNoInheritVisibility.kt"); } + @Test + @TestMetadata("localObjectInInnerClass.kt") + public void testLocalObjectInInnerClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt"); + } + @Test @TestMetadata("LocalVariableWithNoTypeInformation.kt") public void testLocalVariableWithNoTypeInformation() 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 04a8945cec9..24327f137e8 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 @@ -7543,6 +7543,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/declarationChecks/localFunctionNoInheritVisibility.kt"); } + @Test + @TestMetadata("localObjectInInnerClass.kt") + public void testLocalObjectInInnerClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt"); + } + @Test @TestMetadata("LocalVariableWithNoTypeInformation.kt") public void testLocalVariableWithNoTypeInformation() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index 1f550ca2a85..5528777d135 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -6,10 +6,13 @@ package org.jetbrains.kotlin.fir.resolve.transformers import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isInline +import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isSuspend +import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* @@ -68,7 +71,7 @@ class FirCallCompletionResultsWriterTransformer( private val mode: Mode = Mode.Normal ) : FirAbstractTreeTransformer(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { - private val declarationWriter by lazy { FirDeclarationCompletionResultsWriter(finalSubstitutor) } + private val declarationWriter by lazy { FirDeclarationCompletionResultsWriter(finalSubstitutor, typeApproximator, session.typeContext) } private val arrayOfCallTransformer = FirArrayOfCallTransformer() private var enableArrayOfCallTransformation = false @@ -169,7 +172,10 @@ class FirCallCompletionResultsWriterTransformer( session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, null) if (mode == Mode.DelegatedPropertyCompletion) { - subCandidate.symbol.fir.transformSingle(declarationWriter, null) + subCandidate.symbol.fir.transformSingle( + declarationWriter, + FirDeclarationCompletionResultsWriter.ApproximationData.NoApproximation + ) val typeUpdater = TypeUpdaterForDelegateArguments() result.transformExplicitReceiver(typeUpdater, null) } @@ -235,7 +241,10 @@ class FirCallCompletionResultsWriterTransformer( session.lookupTracker?.recordTypeResolveAsLookup(resultType, functionCall.source, null) if (mode == Mode.DelegatedPropertyCompletion) { - subCandidate.symbol.fir.transformSingle(declarationWriter, null) + subCandidate.symbol.fir.transformSingle( + declarationWriter, + FirDeclarationCompletionResultsWriter.ApproximationData.NoApproximation + ) val typeUpdater = TypeUpdaterForDelegateArguments() result.argumentList.transformArguments(typeUpdater, null) result.transformExplicitReceiver(typeUpdater, null) @@ -832,46 +841,62 @@ private fun ExpectedArgumentType.getExpectedType(argument: FirElement): ConeKotl fun ConeKotlinType.toExpectedType(): ExpectedArgumentType = ExpectedArgumentType.ExpectedType(this) -class FirDeclarationCompletionResultsWriter(private val finalSubstitutor: ConeSubstitutor) : FirDefaultTransformer() { - override fun transformElement(element: E, data: Any?): E { +internal class FirDeclarationCompletionResultsWriter( + private val finalSubstitutor: ConeSubstitutor, + private val typeApproximator: ConeTypeApproximator, + private val typeContext: ConeInferenceContext +) : FirDefaultTransformer() { + override fun transformElement(element: E, data: ApproximationData): E { return element } - override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?): FirStatement { - simpleFunction.transformReturnTypeRef(this, data) - simpleFunction.transformValueParameters(this, data) - simpleFunction.transformReceiverTypeRef(this, data) + override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: ApproximationData): FirStatement { + return super.transformAnonymousObject(anonymousObject, ApproximationData.NoApproximation) + } + + override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: ApproximationData): FirStatement { + val newData = if (simpleFunction.isLocal || data == ApproximationData.NoApproximation) ApproximationData.NoApproximation + else ApproximationData.ApproximateByStatus(simpleFunction.visibility, simpleFunction.isInline) + simpleFunction.transformReturnTypeRef(this, newData) + simpleFunction.transformValueParameters(this, ApproximationData.NoApproximation) + simpleFunction.transformReceiverTypeRef(this, newData) return simpleFunction } - override fun transformProperty(property: FirProperty, data: Any?): FirStatement { - property.transformGetter(this, data) - property.transformSetter(this, data) - property.transformReturnTypeRef(this, data) - property.transformReceiverTypeRef(this, data) + override fun transformProperty(property: FirProperty, data: ApproximationData): FirStatement { + val newData = if (property.isLocal || data == ApproximationData.NoApproximation) ApproximationData.NoApproximation + else ApproximationData.ApproximateByStatus(property.visibility, false) + property.transformGetter(this, newData) + property.transformSetter(this, newData) + property.transformReturnTypeRef(this, newData) + property.transformReceiverTypeRef(this, newData) return property } - override fun transformPropertyAccessor( - propertyAccessor: FirPropertyAccessor, - data: Any? - ): FirStatement { + override fun transformPropertyAccessor(propertyAccessor: FirPropertyAccessor, data: ApproximationData): FirStatement { propertyAccessor.transformReturnTypeRef(this, data) - propertyAccessor.transformValueParameters(this, data) + propertyAccessor.transformValueParameters(this, ApproximationData.NoApproximation) return propertyAccessor } - override fun transformValueParameter( - valueParameter: FirValueParameter, - data: Any? - ): FirStatement { - valueParameter.transformReturnTypeRef(this, data) + override fun transformValueParameter(valueParameter: FirValueParameter, data: ApproximationData): FirStatement { + valueParameter.transformReturnTypeRef(this, ApproximationData.NoApproximation) return valueParameter } - override fun transformTypeRef(typeRef: FirTypeRef, data: Any?): FirTypeRef { - return finalSubstitutor.substituteOrNull(typeRef.coneType)?.let { + override fun transformTypeRef(typeRef: FirTypeRef, data: ApproximationData): FirTypeRef { + val result = finalSubstitutor.substituteOrNull(typeRef.coneType)?.let { typeRef.resolvedTypeFromPrototype(it) } ?: typeRef + if (data is ApproximationData.ApproximateByStatus) { + return result.approximatedIfNeededOrSelf(typeApproximator, data.visibility, typeContext, data.isInline) + } + return result + } + + sealed class ApproximationData { + class ApproximateByStatus(val visibility: Visibility?, val isInline: Boolean) : ApproximationData() + object NoApproximation : ApproximationData() + object Default : ApproximationData() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index ca5373fa61a..e9a3881fcbd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -264,8 +264,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor completedCalls.forEach { it.transformSingle(callCompletionResultsWriter, null) } - val declarationCompletionResultsWriter = FirDeclarationCompletionResultsWriter(finalSubstitutor) - property.transformSingle(declarationCompletionResultsWriter, null) + val declarationCompletionResultsWriter = + FirDeclarationCompletionResultsWriter(finalSubstitutor, inferenceComponents.approximator, session.typeContext) + property.transformSingle(declarationCompletionResultsWriter, FirDeclarationCompletionResultsWriter.ApproximationData.Default) } } diff --git a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.fir.kt index 8d209447626..b5dba09b804 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.fir.kt @@ -1,3 +1,9 @@ +interface Lazy { + operator fun getValue(a1: Any, a2: Any): T +} + +fun lazy(f: () -> T): Lazy = throw Exception() + interface MyTrait { fun f1() {} } @@ -7,13 +13,21 @@ open class MyClass { } -class Foo { +class Foo(val myTrait: MyTrait) { private val privateProperty = object : MyClass(), MyTrait {} + val publicPropertyWithSingleSuperType = object : MyClass() { + fun onlyFromAnonymousObject() {} + } + private val privatePropertyWithSingleSuperType = object : MyClass() { + fun onlyFromAnonymousObject() {} + } init { privateProperty.f1() privateProperty.f2() + publicPropertyWithSingleSuperType.onlyFromAnonymousObject() // unresolved due to approximation + privatePropertyWithSingleSuperType.onlyFromAnonymousObject() // resolvable since private } protected val protectedProperty = object : MyClass(), MyTrait {} @@ -27,6 +41,46 @@ class Foo { val propertyWithGetter get() = object: MyClass(), MyTrait {} + private val privateDelegateProperty by lazy { object : MyClass(), MyTrait {} } + val publicDelegatePropertyWithSingleSuperType by lazy { + object : MyClass() { + fun onlyFromAnonymousObject() {} + } + } + private val privateDelegatePropertyWithSingleSuperType by lazy { + object : MyClass() { + fun onlyFromAnonymousObject() {} + } + } + + init { + privateDelegateProperty.f1() + privateDelegateProperty.f2() + publicDelegatePropertyWithSingleSuperType.onlyFromAnonymousObject() // unresolved due to approximation + privateDelegatePropertyWithSingleSuperType.onlyFromAnonymousObject() // resolvable since private + } + + protected val protectedDelegateProperty by lazy { object : MyClass(), MyTrait {} } + + val internalDelegateProperty by lazy { object : MyClass(), MyTrait {} } + + internal val internal2DelegateProperty by lazy { object : MyClass(), MyTrait {} } + + public val publicDelegateProperty by lazy { object : MyClass(), MyTrait {} } + + private val privateDelegate = object : MyTrait by myTrait { + fun f2() {} + } + val delegate = object : MyTrait by myTrait { + fun f2() {} + } + + init { + privateDelegate.f1() + privateDelegate.f2() + delegate.f1() + delegate.f2() + } private fun privateFunction() = object : MyClass(), MyTrait {} diff --git a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt index ed77c5f5800..e02c8f6d41f 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt @@ -1,3 +1,9 @@ +interface Lazy { + operator fun getValue(a1: Any, a2: Any): T +} + +fun lazy(f: () -> T): Lazy = throw Exception() + interface MyTrait { fun f1() {} } @@ -7,13 +13,21 @@ open class MyClass { } -class Foo { +class Foo(val myTrait: MyTrait) { private val privateProperty = object : MyClass(), MyTrait {} + val publicPropertyWithSingleSuperType = object : MyClass() { + fun onlyFromAnonymousObject() {} + } + private val privatePropertyWithSingleSuperType = object : MyClass() { + fun onlyFromAnonymousObject() {} + } init { privateProperty.f1() privateProperty.f2() + publicPropertyWithSingleSuperType.onlyFromAnonymousObject() // unresolved due to approximation + privatePropertyWithSingleSuperType.onlyFromAnonymousObject() // resolvable since private } protected val protectedProperty = object : MyClass(), MyTrait {} @@ -27,6 +41,46 @@ class Foo { val propertyWithGetter get() = object: MyClass(), MyTrait {} + private val privateDelegateProperty by lazy { object : MyClass(), MyTrait {} } + val publicDelegatePropertyWithSingleSuperType by lazy { + object : MyClass() { + fun onlyFromAnonymousObject() {} + } + } + private val privateDelegatePropertyWithSingleSuperType by lazy { + object : MyClass() { + fun onlyFromAnonymousObject() {} + } + } + + init { + privateDelegateProperty.f1() + privateDelegateProperty.f2() + publicDelegatePropertyWithSingleSuperType.onlyFromAnonymousObject() // unresolved due to approximation + privateDelegatePropertyWithSingleSuperType.onlyFromAnonymousObject() // resolvable since private + } + + protected val protectedDelegateProperty by lazy { object : MyClass(), MyTrait {} } + + val internalDelegateProperty by lazy { object : MyClass(), MyTrait {} } + + internal val internal2DelegateProperty by lazy { object : MyClass(), MyTrait {} } + + public val publicDelegateProperty by lazy { object : MyClass(), MyTrait {} } + + private val privateDelegate = object : MyTrait by myTrait { + fun f2() {} + } + val delegate = object : MyTrait by myTrait { + fun f2() {} + } + + init { + privateDelegate.f1() + privateDelegate.f2() + delegate.f1() + delegate.f2() + } private fun privateFunction() = object : MyClass(), MyTrait {} diff --git a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.txt b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.txt index dd73bbc41bc..a3f20f3b8e3 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.txt +++ b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.txt @@ -6,19 +6,32 @@ private val packagePrivateProperty: packagePrivateProperty. protected val packageProtectedProperty: packageProtectedProperty. public val packagePublicProperty: packagePublicProperty. public fun fooPackage(): kotlin.Unit +public fun lazy(/*0*/ f: () -> T): Lazy internal fun packageInternal2Function(): packageInternal2Function. public fun packageInternalFunction(): packageInternalFunction. protected fun packageProtectedFunction(): packageProtectedFunction. public fun packagePublicFunction(): packagePublicFunction. public final class Foo { - public constructor Foo() + public constructor Foo(/*0*/ myTrait: MyTrait) + public final val delegate: MyTrait + internal final val internal2DelegateProperty: Foo.internal2DelegateProperty.. internal final val internal2Property: Foo.internal2Property. + public final val internalDelegateProperty: Foo.internalDelegateProperty.. public final val internalProperty: Foo.internalProperty. + public final val myTrait: MyTrait + private final val privateDelegate: Foo.privateDelegate. + private final val privateDelegateProperty: Foo.privateDelegateProperty.. + private final val privateDelegatePropertyWithSingleSuperType: Foo.privateDelegatePropertyWithSingleSuperType.. private final val privateProperty: Foo.privateProperty. + private final val privatePropertyWithSingleSuperType: Foo.privatePropertyWithSingleSuperType. public final val propertyWithGetter: Foo.. + protected final val protectedDelegateProperty: Foo.protectedDelegateProperty.. protected final val protectedProperty: Foo.protectedProperty. + public final val publicDelegateProperty: Foo.publicDelegateProperty.. + public final val publicDelegatePropertyWithSingleSuperType: MyClass public final val publicProperty: Foo.publicProperty. + public final val publicPropertyWithSingleSuperType: MyClass public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public final fun foo(): kotlin.Unit public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int @@ -47,6 +60,13 @@ public final class Foo { } } +public interface Lazy { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract operator fun getValue(/*0*/ a1: kotlin.Any, /*1*/ a2: kotlin.Any): T + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + public open class MyClass { public constructor MyClass() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -61,3 +81,4 @@ public interface MyTrait { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + diff --git a/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.fir.kt new file mode 100644 index 00000000000..9f18186758b --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.fir.kt @@ -0,0 +1,30 @@ +interface I1 +interface I2 + +interface Lazy { + operator fun getValue(a1: Any, a2: Any): T +} + +fun lazy(f: () -> T): Lazy = throw Exception() + +class A { + private inner class B { + val o1 = object : I1 {} + val o2 by lazy { + object : I1 {} + } + val o3 = object : I1, I2 {} // FIR allows this since the containing class is private + val o4 by lazy { // FIR allows this since the containing class is private + object : I1, I2 {} + } + + private val privateO1 = object : I1 {} + private val privateO2 by lazy { + object : I1 {} + } + private val privateO3 = object : I1, I2 {} + private val privateO4 by lazy { + object : I1, I2 {} + } + } +} diff --git a/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt b/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt new file mode 100644 index 00000000000..df3d189d5d3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt @@ -0,0 +1,30 @@ +interface I1 +interface I2 + +interface Lazy { + operator fun getValue(a1: Any, a2: Any): T +} + +fun lazy(f: () -> T): Lazy = throw Exception() + +class A { + private inner class B { + val o1 = object : I1 {} + val o2 by lazy { + object : I1 {} + } + val o3 = object : I1, I2 {} // FIR allows this since the containing class is private + val o4 by lazy { // FIR allows this since the containing class is private + object : I1, I2 {} + } + + private val privateO1 = object : I1 {} + private val privateO2 by lazy { + object : I1 {} + } + private val privateO3 = object : I1, I2 {} + private val privateO4 by lazy { + object : I1, I2 {} + } + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.txt b/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.txt new file mode 100644 index 00000000000..1073b6b8d65 --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.txt @@ -0,0 +1,44 @@ +package + +public fun lazy(/*0*/ f: () -> T): Lazy + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + private final inner class B { + public constructor B() + public final val o1: I1 + public final val o2: I1 + public final val o3: A.B.o3. + public final val o4: A.B.o4.. + private final val privateO1: A.B.privateO1. + private final val privateO2: A.B.privateO2.. + private final val privateO3: A.B.privateO3. + private final val privateO4: A.B.privateO4.. + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public interface I1 { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface I2 { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Lazy { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract operator fun getValue(/*0*/ a1: kotlin.Any, /*1*/ a2: kotlin.Any): T + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} 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 7c60c5c1c5a..e36b79ec086 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 @@ -7549,6 +7549,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/declarationChecks/localFunctionNoInheritVisibility.kt"); } + @Test + @TestMetadata("localObjectInInnerClass.kt") + public void testLocalObjectInInnerClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/declarationChecks/localObjectInInnerClass.kt"); + } + @Test @TestMetadata("LocalVariableWithNoTypeInformation.kt") public void testLocalVariableWithNoTypeInformation() throws Exception {