JS: disable mangling for PublishedApi. Export declarations marked with PublishedApi. See KT-15442

This commit is contained in:
Alexey Andreev
2016-12-27 14:23:04 +03:00
parent ed7ac7cea9
commit 27c2a4f6a8
12 changed files with 120 additions and 7 deletions
+5 -1
View File
@@ -1,3 +1,5 @@
// MODULE: lib
// FILE: lib.kt
class A {
@PublishedApi
@@ -7,6 +9,8 @@ class A {
}
fun box() : String {
// MODULE: main(lib)
// FILE: main.kt
fun box(): String {
return A().test()
}
+10
View File
@@ -0,0 +1,10 @@
// MODULE: lib
// FILE: lib.kt
@PublishedApi
internal fun published() = "OK"
inline fun test() = published()
// MODULE: main(lib)
// FILE: main.kt
fun box() = test()
@@ -6,6 +6,6 @@ public final class A {
}
@kotlin.Metadata
public final class SimpleKt {
public final class MainKt {
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
}
@@ -0,0 +1,8 @@
public final class LibKt {
public final static @kotlin.PublishedApi @org.jetbrains.annotations.NotNull method published(): java.lang.String
public final static @org.jetbrains.annotations.NotNull method test(): java.lang.String
}
public final class MainKt {
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
}
@@ -11899,6 +11899,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/simple.kt");
doTest(fileName);
}
@TestMetadata("topLevel.kt")
public void testTopLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/topLevel.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/ranges")
@@ -11899,6 +11899,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/simple.kt");
doTest(fileName);
}
@TestMetadata("topLevel.kt")
public void testTopLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/topLevel.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/ranges")
@@ -11899,6 +11899,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/simple.kt");
doTest(fileName);
}
@TestMetadata("topLevel.kt")
public void testTopLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/topLevel.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/ranges")
@@ -120,7 +120,7 @@ class NameSuggestion {
var liftedName = ownName
var hasInline = false
while (container is FunctionDescriptor) {
if (container.isInline && container.visibility.isPublicAPI) {
if (container.isInline && container.ownEffectiveVisibility.isPublicAPI) {
hasInline = true
}
liftedName = getSuggestedName(container) + "$" + liftedName
@@ -257,20 +257,24 @@ class NameSuggestion {
fun mangledAndStable() = NameAndStability(getStableMangledName(baseName, getArgumentTypesAsString(descriptor)), true)
fun mangledPrivate() = NameAndStability(getPrivateMangledName(baseName, descriptor), false)
val effectiveVisibility = descriptor.ownEffectiveVisibility
val containingDeclaration = descriptor.containingDeclaration
return when (containingDeclaration) {
is PackageFragmentDescriptor -> if (descriptor.visibility.isPublicAPI) mangledAndStable() else regularAndUnstable()
is PackageFragmentDescriptor -> if (effectiveVisibility.isPublicAPI) mangledAndStable() else regularAndUnstable()
is ClassDescriptor -> {
// valueOf() is created in the library with a mangled name for every enum class
if (descriptor is FunctionDescriptor && descriptor.isEnumValueOfMethod()) return mangledAndStable()
// Make all public declarations stable
if (descriptor.visibility == Visibilities.PUBLIC) return mangledAndStable()
if (effectiveVisibility == Visibilities.PUBLIC) {
return mangledAndStable()
}
if (descriptor is CallableMemberDescriptor && descriptor.isOverridableOrOverrides) return mangledAndStable()
// Make all protected declarations of non-final public classes stable
if (descriptor.visibility == Visibilities.PROTECTED &&
if (effectiveVisibility == Visibilities.PROTECTED &&
!containingDeclaration.isFinalClass &&
containingDeclaration.visibility.isPublicAPI
) {
@@ -323,5 +327,8 @@ class NameSuggestion {
val absHashCode = Math.abs(forCalculateId.hashCode())
return if (absHashCode != 0) Integer.toString(absHashCode, Character.MAX_RADIX) else ""
}
private val DeclarationDescriptorWithVisibility.ownEffectiveVisibility
get() = visibility.effectiveVisibility(this, checkPublishedApi = true).toVisibility()
}
}
@@ -5330,6 +5330,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName);
}
@TestMetadata("publishedApiMangling.kt")
public void testPublishedApiMangling() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModule/publishedApiMangling.kt");
doTest(fileName);
}
@TestMetadata("useElementsFromDefaultPackageInAnotherModule.kt")
public void testUseElementsFromDefaultPackageInAnotherModule() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModule/useElementsFromDefaultPackageInAnotherModule.kt");
@@ -14006,6 +14006,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/simple.kt");
doTest(fileName);
}
@TestMetadata("topLevel.kt")
public void testTopLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/publishedApi/topLevel.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/box/ranges")
@@ -142,4 +142,4 @@ internal class DeclarationExporter(val context: StaticContext) {
}
private fun MemberDescriptor.shouldBeExported(force: Boolean) =
force || isEffectivelyPublicApi || AnnotationsUtils.getJsNameAnnotation(this) != null
force || effectiveVisibility(checkPublishedApi = true).publicApi || AnnotationsUtils.getJsNameAnnotation(this) != null
@@ -0,0 +1,54 @@
// MODULE: lib
// FILE: lib.kt
class A {
@PublishedApi
internal fun published(x: String) = "${x}K"
fun template(x: String): String = TODO("")
}
@PublishedApi
internal fun publishedTopLevel(x: String) = "${x}K"
fun templateTopLevel(x: String): String = TODO("")
interface I {
fun test(): String
}
@PublishedApi
internal class B(val x: String) : I {
override fun test() = x + "K"
}
// MODULE: main(lib)
// FILE: main.kt
import kotlin.text.Regex
inline fun templates() {
A().template("X")
templateTopLevel("X")
}
fun box(): String {
val testFunctionName = "published" + extractSuffix("template")
val a = A()
var result = a.asDynamic()[testFunctionName].call(a, "O")
if (result != "OK") return "fail1: $result"
val topLevelName = "publishedTopLevel" + extractSuffix("templateTopLevel")
result = js("lib")[topLevelName]("O")
if (result != "OK") return "fail2: $result"
val b: I = js("new lib.B('O')")
result = b.test()
if (result != "OK") return "fail3: $result"
return "OK"
}
private fun extractSuffix(prefix: String): String {
val functionBody: String = js("_").templates.toString()
val regex = Regex(prefix + "(_[\\\$a-zA-Z0-9]+)")
return regex.find(functionBody)!!.groupValues[1]
}