From ec42b588773b560c780bca2134ff48d397131267 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Wed, 11 Jan 2017 10:43:38 +0100 Subject: [PATCH] Fix @PublishedApi checking --- .../diagnostics/tests/inline/publishedApi.kt | 141 +++++++++++++++++- .../diagnostics/tests/inline/publishedApi.txt | 10 +- .../kotlin/descriptors/EffectiveVisibility.kt | 7 +- 3 files changed, 151 insertions(+), 7 deletions(-) diff --git a/compiler/testData/diagnostics/tests/inline/publishedApi.kt b/compiler/testData/diagnostics/tests/inline/publishedApi.kt index 6ff39d4e6be..ff9db30a34e 100644 --- a/compiler/testData/diagnostics/tests/inline/publishedApi.kt +++ b/compiler/testData/diagnostics/tests/inline/publishedApi.kt @@ -1,9 +1,40 @@ // !DIAGNOSTICS: -EXPOSED_PARAMETER_TYPE -NOTHING_TO_INLINE inline fun call(a: A) { a.test() - testTopLevel() + publishedTopLevel() + + a.publishedVar + a.publishedVar = 1 + + publishedVarTopLevel + publishedVarTopLevel = 1 } +inline var inlineVar: Int + get() { + val a = A() + a.test() + publishedTopLevel() + + a.publishedVar + a.publishedVar = 1 + + publishedVarTopLevel + publishedVarTopLevel = 1 + return 1 + } + set(value) { + val a = A() + a.test() + publishedTopLevel() + + a.publishedVar + a.publishedVar = 1 + + publishedVarTopLevel + publishedVarTopLevel = 1 + } + @PublishedApi internal class A { @PublishedApi @@ -11,6 +42,16 @@ internal class A { publicFun() internalFun() privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 + + publishedVar + publishedVar = 1 } @PublishedApi @@ -18,25 +59,117 @@ internal class A { publicFun() internalFun() privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 + + publishedVar + publishedVar = 1 } + + + @PublishedApi + internal inline var publishedVar: Int + get() { + publicFun() + internalFun() + privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 + return 1 + } + + set(value) { + publicFun() + internalFun() + privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 + } + } - @PublishedApi -internal fun testTopLevel() { +internal fun publishedTopLevel() { publicFun() internalFun() + privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 } @PublishedApi -inline internal fun testTopLevelInline() { +inline internal fun publishedTopLevelInline() { publicFun() internalFun() privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 } +@PublishedApi +inline internal var publishedVarTopLevel: Int + get() { + publicFun() + internalFun() + privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 + return 1 + } + + set(value) { + publicFun() + internalFun() + privateFun() + + publicVarTopLevel + publicVarTopLevel = 1 + internalVarTopLevel + internalVarTopLevel = 1 + privateVarTopLevel + privateVarTopLevel = 1 + } + + fun publicFun() {} internal fun internalFun() {} private fun privateFun() {} + + +var publicVarTopLevel = 1 + +internal var internalVarTopLevel = 1 + +private var privateVarTopLevel = 1 \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inline/publishedApi.txt b/compiler/testData/diagnostics/tests/inline/publishedApi.txt index f67ea45b77e..e3952da46df 100644 --- a/compiler/testData/diagnostics/tests/inline/publishedApi.txt +++ b/compiler/testData/diagnostics/tests/inline/publishedApi.txt @@ -1,14 +1,20 @@ package +public var inlineVar: kotlin.Int +internal var internalVarTopLevel: kotlin.Int +private var privateVarTopLevel: kotlin.Int +public var publicVarTopLevel: kotlin.Int +@kotlin.PublishedApi internal var publishedVarTopLevel: kotlin.Int public inline fun call(/*0*/ a: A): kotlin.Unit internal fun internalFun(): kotlin.Unit private fun privateFun(): kotlin.Unit public fun publicFun(): kotlin.Unit -@kotlin.PublishedApi internal fun testTopLevel(): kotlin.Unit -@kotlin.PublishedApi internal inline fun testTopLevelInline(): kotlin.Unit +@kotlin.PublishedApi internal fun publishedTopLevel(): kotlin.Unit +@kotlin.PublishedApi internal inline fun publishedTopLevelInline(): kotlin.Unit @kotlin.PublishedApi internal final class A { public constructor A() + @kotlin.PublishedApi internal final var publishedVar: 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 @kotlin.PublishedApi internal final fun test(): kotlin.Unit diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt index bf23f53b130..3b2ebbec734 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt @@ -238,13 +238,18 @@ private fun Visibility.forVisibility(descriptor: DeclarationDescriptor, checkPub Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS, Visibilities.INVISIBLE_FAKE -> Private Visibilities.PROTECTED -> Protected(descriptor.containingDeclaration as? ClassDescriptor) Visibilities.INTERNAL -> if (!checkPublishedApi || - !descriptor.annotations.hasAnnotation(KotlinBuiltIns.FQ_NAMES.publishedApi)) Internal else Public + !descriptor.isPublishedApi()) Internal else Public Visibilities.PUBLIC -> Public Visibilities.LOCAL -> Local // NB: visibility must be already normalized here, so e.g. no JavaVisibilities are possible at this point else -> throw AssertionError("Visibility $name is not allowed in forVisibility") } +private fun DeclarationDescriptor.isPublishedApi(): Boolean { + val descriptor = if (this is CallableMemberDescriptor) DescriptorUtils.getDirectMember(this) else this + return descriptor.annotations.hasAnnotation(KotlinBuiltIns.FQ_NAMES.publishedApi) +} + fun effectiveVisibility(visibility: Visibility, descriptor: DeclarationDescriptor, checkPublishedApi: Boolean = false) = visibility.forVisibility(descriptor, checkPublishedApi)