From e86d52b681bc876b8383b7b292663ececa8c6848 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Tue, 11 Apr 2017 16:25:18 +0300 Subject: [PATCH] Fix return type of private members that return anonymous object #KT-16813 Fixed Anonymous objects returned from private-in-file members should behave as for private class members --- .../kotlin/resolve/DescriptorResolver.java | 3 +- .../anonymousObjectReturnsFromTopLevelFun.kt | 22 ++++ .../ambiguousObjectExpressionType.kt | 92 ++++++++-------- .../unambiguousObjectExpressionType.kt | 104 +++++++++--------- .../unambiguousObjectExpressionType.txt | 4 +- .../anonymousObjectFromTopLevelMember.kt | 24 ++++ .../anonymousObjectFromTopLevelMember.txt | 18 +++ .../subtyping/topLevelAnonymousObjects.kt | 3 +- .../subtyping/topLevelAnonymousObjects.txt | 2 +- .../ir/IrBlackBoxCodegenTestGenerated.java | 6 + .../checkers/DiagnosticsTestGenerated.java | 6 + .../codegen/BlackBoxCodegenTestGenerated.java | 6 + .../LightAnalysisModeTestGenerated.java | 6 + .../tinyApp/outs/ceAnonymousObject.out | 1 - .../compilingEvaluator/ceAnonymousObject.kt | 7 +- .../semantics/JsCodegenBoxTestGenerated.java | 6 + 16 files changed, 202 insertions(+), 108 deletions(-) create mode 100644 compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 010906ac3ea..ba3f832b287 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -907,8 +907,7 @@ public class DescriptorResolver { return type; } - boolean definedInClass = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) != null; - if (!definedInClass || !Visibilities.isPrivate(descriptor.getVisibility())) { + if (!Visibilities.isPrivate(descriptor.getVisibility())) { if (type.getConstructor().getSupertypes().size() == 1) { return type.getConstructor().getSupertypes().iterator().next(); } diff --git a/compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt b/compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt new file mode 100644 index 00000000000..c2f14068bfe --- /dev/null +++ b/compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt @@ -0,0 +1,22 @@ +interface IFoo { + fun foo(): String +} + +interface IBar + +private fun createAnonObject() = + object : IFoo, IBar { + override fun foo() = "foo" + fun qux(): String = "qux" + } + +fun useAnonObject() { + createAnonObject().foo() + createAnonObject().qux() +} + +fun box(): String { + if (createAnonObject().foo() != "foo") return "fail 1" + if (createAnonObject().qux() != "qux") return "fail 2" + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt index 7060e072d8e..ed77c5f5800 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt @@ -1,9 +1,9 @@ interface MyTrait { - fun f1() {} + fun f1() {} } open class MyClass { - fun f2() {} + fun f2() {} } @@ -12,8 +12,8 @@ class Foo { private val privateProperty = object : MyClass(), MyTrait {} init { - privateProperty.f1() - privateProperty.f2() + privateProperty.f1() + privateProperty.f2() } protected val protectedProperty = object : MyClass(), MyTrait {} @@ -25,14 +25,14 @@ class Foo { public val publicProperty = object : MyClass(), MyTrait {} val propertyWithGetter - get() = object: MyClass(), MyTrait {} + get() = object: MyClass(), MyTrait {} private fun privateFunction() = object : MyClass(), MyTrait {} init { - privateFunction().f1() - privateFunction().f2() + privateFunction().f1() + privateFunction().f2() } protected fun protectedFunction() = object : MyClass(), MyTrait {} @@ -45,53 +45,53 @@ class Foo { - class FooInner { - private val privatePropertyInner = object : MyClass(), MyTrait {} + class FooInner { + private val privatePropertyInner = object : MyClass(), MyTrait {} + + init { + privatePropertyInner.f1() + privatePropertyInner.f2() + } + + protected val protectedProperty = object : MyClass(), MyTrait {} + + val internalProperty = object : MyClass(), MyTrait {} + + internal val internal2Property = object : MyClass(), MyTrait {} + + public val publicProperty = object : MyClass(), MyTrait {} + + + private fun privateFunctionInner() = object : MyClass(), MyTrait {} + + init { + privateFunctionInner().f1() + privateFunctionInner().f2() + } + + protected fun protectedFunction() = object : MyClass(), MyTrait {} + + fun internalFunction() = object : MyClass(), MyTrait {} + + internal fun internal2Function() = object : MyClass(), MyTrait {} + + public fun publicFunction() = object : MyClass(), MyTrait {} - init { - privatePropertyInner.f1() - privatePropertyInner.f2() } - protected val protectedProperty = object : MyClass(), MyTrait {} + fun foo() { + val localVar = object : MyClass(), MyTrait {} + localVar.f1() + localVar.f2() - val internalProperty = object : MyClass(), MyTrait {} - - internal val internal2Property = object : MyClass(), MyTrait {} - - public val publicProperty = object : MyClass(), MyTrait {} - - - private fun privateFunctionInner() = object : MyClass(), MyTrait {} - - init { - privateFunctionInner().f1() - privateFunctionInner().f2() + fun foo2() = object : MyClass(), MyTrait {} + foo2().f1() + foo2().f2() } - protected fun protectedFunction() = object : MyClass(), MyTrait {} - - fun internalFunction() = object : MyClass(), MyTrait {} - - internal fun internal2Function() = object : MyClass(), MyTrait {} - - public fun publicFunction() = object : MyClass(), MyTrait {} - - } - - fun foo() { - val localVar = object : MyClass(), MyTrait {} - localVar.f1() - localVar.f2() - - fun foo2() = object : MyClass(), MyTrait {} - foo2().f1() - foo2().f2() - } - } -private val packagePrivateProperty = object : MyClass(), MyTrait {} +private val packagePrivateProperty = object : MyClass(), MyTrait {} protected val packageProtectedProperty = object : MyClass(), MyTrait {} diff --git a/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.kt b/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.kt index debcf612814..ee7e136d89e 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.kt @@ -1,5 +1,5 @@ open class MyClass { - fun f1() {} + fun f1() {} } @@ -19,15 +19,15 @@ class Foo { fun testProperties() { - privateProperty.f1() - internalProperty.f1() - protected2Property.f1() - public2Property.f1() + privateProperty.f1() + internalProperty.f1() + protected2Property.f1() + public2Property.f1() - privateProperty.visible() - protected2Property.invisible() - public2Property.invisible() - internalProperty.invisible() + privateProperty.visible() + protected2Property.invisible() + public2Property.invisible() + internalProperty.invisible() } @@ -45,15 +45,15 @@ class Foo { fun testFunctions() { - privateFunction().f1() - internalFunction().f1() - public2Function().f1() - protected2Function().f1() + privateFunction().f1() + internalFunction().f1() + public2Function().f1() + protected2Function().f1() - privateFunction().visible() - internalFunction().invisible() - public2Function().invisible() - protected2Function().invisible() + privateFunction().visible() + internalFunction().invisible() + public2Function().invisible() + protected2Function().invisible() } @@ -73,49 +73,49 @@ class Foo { fun testProperties() { - privateProperty.f1() - internalProperty.f1() - protected2Property.f1() - public2Property.f1() + privateProperty.f1() + internalProperty.f1() + protected2Property.f1() + public2Property.f1() - privateProperty.visible() - protected2Property.invisible() - public2Property.invisible() - internalProperty.invisible() + privateProperty.visible() + protected2Property.invisible() + public2Property.invisible() + internalProperty.invisible() } - protected fun protectedFunction() = object : MyClass() {} + protected fun protectedFunction() = object : MyClass() {} - public fun publicFunction() = object : MyClass() {} + public fun publicFunction() = object : MyClass() {} - protected fun protected2Function(): MyClass = object : MyClass() {fun visible() {}} + protected fun protected2Function(): MyClass = object : MyClass() {fun visible() {}} - public fun public2Function(): MyClass = object : MyClass() {fun visible() {}} + public fun public2Function(): MyClass = object : MyClass() {fun visible() {}} - private fun privateFunction() = object : MyClass() {fun visible() {}} + private fun privateFunction() = object : MyClass() {fun visible() {}} - internal fun internalFunction() = object : MyClass() {fun invisible() {}} + internal fun internalFunction() = object : MyClass() {fun invisible() {}} - fun testFunctions() { - privateFunction().f1() - internalFunction().f1() - public2Function().f1() - protected2Function().f1() + fun testFunctions() { + privateFunction().f1() + internalFunction().f1() + public2Function().f1() + protected2Function().f1() - privateFunction().visible() - internalFunction().invisible() - public2Function().invisible() - protected2Function().invisible() - } + privateFunction().visible() + internalFunction().invisible() + public2Function().invisible() + protected2Function().invisible() + } } fun foo() { - val localVar = object : MyClass() {} - localVar.f1() - fun foo2() = object : MyClass() {} - foo2().f1() + val localVar = object : MyClass() {} + localVar.f1() + fun foo2() = object : MyClass() {} + foo2().f1() } } @@ -136,7 +136,7 @@ fun testProperties() { packageInternalProperty.f1() packagePublic2Property.f1() - packagePrivateProperty.invisible() + packagePrivateProperty.invisible() packageInternalProperty.invisible() packagePublic2Property.invisible() } @@ -155,13 +155,13 @@ internal fun internalFunction() = object : MyClass() {fun invisible() {}} fun testFunctions() { - privateFunction().f1() - internalFunction().f1() - public2Function().f1() + privateFunction().f1() + internalFunction().f1() + public2Function().f1() - privateFunction().invisible() - internalFunction().invisible() - public2Function().invisible() + privateFunction().invisible() + internalFunction().invisible() + public2Function().invisible() } fun fooPackage() { diff --git a/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.txt b/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.txt index 423830089ed..51848324db2 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.txt +++ b/compiler/testData/diagnostics/tests/declarationChecks/unambiguousObjectExpressionType.txt @@ -1,13 +1,13 @@ package internal val packageInternalProperty: MyClass -private val packagePrivateProperty: MyClass +private val packagePrivateProperty: packagePrivateProperty. protected val packageProtectedProperty: MyClass public val packagePublic2Property: MyClass public val packagePublicProperty: MyClass public fun fooPackage(): kotlin.Unit internal fun internalFunction(): MyClass -private fun privateFunction(): MyClass +private fun privateFunction(): privateFunction. protected fun protectedFunction(): MyClass public fun public2Function(): MyClass public fun publicFunction(): MyClass diff --git a/compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.kt b/compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.kt new file mode 100644 index 00000000000..f3eb01d0944 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.kt @@ -0,0 +1,24 @@ +interface IFoo { + fun foo() +} + +interface IBar + +private fun createAnonObject() = + object : IFoo, IBar { + override fun foo() {} + fun qux() {} + } + +private val propOfAnonObject = object : IFoo, IBar { + override fun foo() {} + fun qux() {} + } + +fun useAnonObject() { + createAnonObject().foo() + createAnonObject().qux() + + propOfAnonObject.foo() + propOfAnonObject.qux() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.txt b/compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.txt new file mode 100644 index 00000000000..196c2a41d63 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.txt @@ -0,0 +1,18 @@ +package + +private val propOfAnonObject: propOfAnonObject. +private fun createAnonObject(): createAnonObject. +public fun useAnonObject(): kotlin.Unit + +public interface IBar { + 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 IFoo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun foo(): kotlin.Unit + 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/subtyping/topLevelAnonymousObjects.kt b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.kt index ffb3be8356c..6e6dc30d1c9 100644 --- a/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.kt +++ b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.kt @@ -1,6 +1,5 @@ private var x = object {} fun test() { - // No error, because the type of x is normalized to Any - x = object {} + x = object {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.txt b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.txt index 21fe69217ae..4a11ad07c91 100644 --- a/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.txt +++ b/compiler/testData/diagnostics/tests/subtyping/topLevelAnonymousObjects.txt @@ -1,4 +1,4 @@ package -private var x: kotlin.Any +private var x: x. public fun test(): kotlin.Unit diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 71ae06a33b5..501b1f4a446 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -11198,6 +11198,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("anonymousObjectReturnsFromTopLevelFun.kt") + public void testAnonymousObjectReturnsFromTopLevelFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt"); + doTest(fileName); + } + @TestMetadata("classCallsProtectedInheritedByCompanion.kt") public void testClassCallsProtectedInheritedByCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 38044ca4db2..50cff0711d6 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -17098,6 +17098,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("anonymousObjectFromTopLevelMember.kt") + public void testAnonymousObjectFromTopLevelMember() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/anonymousObjectFromTopLevelMember.kt"); + doTest(fileName); + } + @TestMetadata("capturedTypesInLambdaParameter.kt") public void testCapturedTypesInLambdaParameter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 672d589f456..771308b1b4e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11198,6 +11198,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("anonymousObjectReturnsFromTopLevelFun.kt") + public void testAnonymousObjectReturnsFromTopLevelFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt"); + doTest(fileName); + } + @TestMetadata("classCallsProtectedInheritedByCompanion.kt") public void testClassCallsProtectedInheritedByCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index e590cd438b0..4810de987d9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11198,6 +11198,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("anonymousObjectReturnsFromTopLevelFun.kt") + public void testAnonymousObjectReturnsFromTopLevelFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt"); + doTest(fileName); + } + @TestMetadata("classCallsProtectedInheritedByCompanion.kt") public void testClassCallsProtectedInheritedByCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt"); diff --git a/idea/testData/debugger/tinyApp/outs/ceAnonymousObject.out b/idea/testData/debugger/tinyApp/outs/ceAnonymousObject.out index a8c0f68a6d9..64b92adf560 100644 --- a/idea/testData/debugger/tinyApp/outs/ceAnonymousObject.out +++ b/idea/testData/debugger/tinyApp/outs/ceAnonymousObject.out @@ -3,7 +3,6 @@ Run Java Connected to the target VM ceAnonymousObject.kt:18 Compile bytecode for publicTopLevelObject -Compile bytecode for privateTopLevelObject Compile bytecode for publicObject Compile bytecode for protectedObject Compile bytecode for localObject diff --git a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceAnonymousObject.kt b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceAnonymousObject.kt index 9f2ef6200a2..9c8af006496 100644 --- a/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceAnonymousObject.kt +++ b/idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/compilingEvaluator/ceAnonymousObject.kt @@ -22,8 +22,11 @@ class MyClass { // EXPRESSION: publicTopLevelObject // RESULT: instance of ceAnonymousObject.CeAnonymousObjectKt$publicTopLevelObject$1(id=ID): LceAnonymousObject/CeAnonymousObjectKt$publicTopLevelObject$1; -// EXPRESSION: privateTopLevelObject -// RESULT: instance of ceAnonymousObject.CeAnonymousObjectKt$privateTopLevelObject$1(id=ID): LceAnonymousObject/CeAnonymousObjectKt$privateTopLevelObject$1; +// -EXPRESSION: privateTopLevelObject +// -RESULT: 1 + +// -EXPRESSION: privateTopLevelObject.test() +// -RESULT: 1: I // EXPRESSION: publicObject // RESULT: instance of ceAnonymousObject.MyClass$publicObject$1(id=ID): LceAnonymousObject/MyClass$publicObject$1; diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 9972d8dbfb0..2156cbe4569 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -12616,6 +12616,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("anonymousObjectReturnsFromTopLevelFun.kt") + public void testAnonymousObjectReturnsFromTopLevelFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/anonymousObjectReturnsFromTopLevelFun.kt"); + doTest(fileName); + } + @TestMetadata("classCallsProtectedInheritedByCompanion.kt") public void testClassCallsProtectedInheritedByCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt");