Exclude inline reified functions and properties from public API

Public inline reified functions are getting into public API dump after
changing their visibility generation strategy (see KT-18563)
from always private to public synthetic. However, they still do not
constitute public binary API, since they can be removed without breaking
compatibility with an already compiled code.
This commit is contained in:
Ilya Gorbunov
2019-06-12 16:50:01 +03:00
parent 95a71f60ca
commit 1960161e78
2 changed files with 15 additions and 14 deletions
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.tools package org.jetbrains.kotlin.tools
import kotlinx.metadata.Flag import kotlinx.metadata.*
import kotlinx.metadata.Flags
import kotlinx.metadata.KmDeclarationContainer
import kotlinx.metadata.flagsOf
import kotlinx.metadata.jvm.* import kotlinx.metadata.jvm.*
import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.tree.ClassNode
@@ -42,9 +39,9 @@ fun KotlinClassMetadata.toClassVisibility(classNode: ClassNode): ClassVisibility
var _facadeClassName: String? = null var _facadeClassName: String? = null
val members = mutableListOf<MemberVisibility>() val members = mutableListOf<MemberVisibility>()
fun addMember(signature: JvmMemberSignature?, flags: Flags) { fun addMember(signature: JvmMemberSignature?, flags: Flags, isReified: Boolean) {
if (signature != null) { if (signature != null) {
members.add(MemberVisibility(signature, flags)) members.add(MemberVisibility(signature, flags, isReified))
} }
} }
@@ -54,7 +51,7 @@ fun KotlinClassMetadata.toClassVisibility(classNode: ClassNode): ClassVisibility
flags = klass.flags flags = klass.flags
for (constructor in klass.constructors) { for (constructor in klass.constructors) {
addMember(constructor.signature, constructor.flags) addMember(constructor.signature, constructor.flags, isReified = false)
} }
} }
is KotlinClassMetadata.FileFacade -> is KotlinClassMetadata.FileFacade ->
@@ -65,20 +62,23 @@ fun KotlinClassMetadata.toClassVisibility(classNode: ClassNode): ClassVisibility
} }
if (container != null) { if (container != null) {
fun List<KmTypeParameter>.containsReified() = any { Flag.TypeParameter.IS_REIFIED(it.flags) }
for (function in container.functions) { for (function in container.functions) {
addMember(function.signature, function.flags) addMember(function.signature, function.flags, function.typeParameters.containsReified())
} }
for (property in container.properties) { for (property in container.properties) {
addMember(property.getterSignature, property.getterFlags) val isReified = property.typeParameters.containsReified()
addMember(property.setterSignature, property.setterFlags) addMember(property.getterSignature, property.getterFlags, isReified)
addMember(property.setterSignature, property.setterFlags, isReified)
val fieldVisibility = when { val fieldVisibility = when {
Flag.Property.IS_LATEINIT(property.flags) -> property.setterFlags Flag.Property.IS_LATEINIT(property.flags) -> property.setterFlags
property.getterSignature == null && property.setterSignature == null -> property.flags // JvmField or const case property.getterSignature == null && property.setterSignature == null -> property.flags // JvmField or const case
else -> flagsOf(Flag.IS_PRIVATE) else -> flagsOf(Flag.IS_PRIVATE)
} }
addMember(property.fieldSignature, fieldVisibility) addMember(property.fieldSignature, fieldVisibility, isReified = false)
} }
} }
@@ -26,7 +26,7 @@ fun ClassVisibility.findMember(signature: JvmMemberSignature): MemberVisibility?
members[signature] ?: partVisibilities.mapNotNull { it.members[signature] }.firstOrNull() members[signature] ?: partVisibilities.mapNotNull { it.members[signature] }.firstOrNull()
data class MemberVisibility(val member: JvmMemberSignature, val visibility: Flags?) data class MemberVisibility(val member: JvmMemberSignature, val visibility: Flags?, val isReified: Boolean)
private fun isPublic(visibility: Flags?, isPublishedApi: Boolean) = private fun isPublic(visibility: Flags?, isPublishedApi: Boolean) =
visibility == null visibility == null
@@ -35,8 +35,9 @@ private fun isPublic(visibility: Flags?, isPublishedApi: Boolean) =
|| (isPublishedApi && Flag.IS_INTERNAL(visibility)) || (isPublishedApi && Flag.IS_INTERNAL(visibility))
fun ClassVisibility.isPublic(isPublishedApi: Boolean) = isPublic(visibility, isPublishedApi) fun ClassVisibility.isPublic(isPublishedApi: Boolean) = isPublic(visibility, isPublishedApi)
fun MemberVisibility.isPublic(isPublishedApi: Boolean) = isPublic(visibility, isPublishedApi) fun MemberVisibility.isPublic(isPublishedApi: Boolean) =
// Assuming isReified implies inline
!isReified && isPublic(visibility, isPublishedApi)