fix: change logic of calculation fqName for export model.

This commit is contained in:
Artem Kobzar
2022-04-28 15:54:50 +00:00
committed by Space
parent 58885a1b07
commit 025a21761b
6 changed files with 77 additions and 18 deletions
@@ -504,8 +504,10 @@ class ExportModelGenerator(
classifier is IrClassSymbol -> {
val klass = classifier.owner
val isImplicitlyExported = !klass.isExported(context) && !klass.isExternal
val name = klass.getExportableName()
val isExported = klass.isExported(context)
val isImplicitlyExported = !isExported && !klass.isExternal
val isNonExportedExternal = klass.isExternal && !isExported
val name = klass.getFqNameWithJsNameWhenAvailable(!isNonExportedExternal && generateNamespacesForPackages).asString()
when (klass.kind) {
ClassKind.ANNOTATION_CLASS,
@@ -531,19 +533,6 @@ class ExportModelGenerator(
return exportedType.withNullability(isMarkedNullable)
}
private fun IrClass.getExportableName(): String {
val qualifier = (parent as? IrFile)?.getJsQualifier()
val supQualifier = (parent as? IrClass)?.getExportableName()
val name = getJsNameOrKotlinName()
return when {
qualifier != null -> "$qualifier.$name"
isExternal && !isExported(context) -> "${supQualifier?.plus(".") ?: ""}$name"
generateNamespacesForPackages -> fqNameWhenAvailable!!.asString()
else -> name.asString()
}
}
private fun IrDeclarationWithName.getExportedIdentifier(): String =
with(getJsNameOrKotlinName()) {
if (isSpecial)
@@ -9,12 +9,11 @@ import org.jetbrains.kotlin.descriptors.isClass
import org.jetbrains.kotlin.descriptors.isInterface
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.export.isExported
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithVisibility
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrReturn
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.name.FqName
fun IrDeclaration.isExportedMember(context: JsIrBackendContext) =
(this is IrDeclarationWithVisibility && visibility.isPublicAPI) &&
@@ -29,3 +28,16 @@ fun IrDeclaration?.isExportedInterface(context: JsIrBackendContext) =
fun IrReturn.isTheLastReturnStatementIn(target: IrReturnableBlockSymbol): Boolean {
return target.owner.statements.lastOrNull() === this
}
fun IrDeclarationWithName.getFqNameWithJsNameWhenAvailable(shouldIncludePackage: Boolean): FqName {
val name = getJsNameOrKotlinName()
return when (val parent = parent) {
is IrDeclarationWithName -> parent.getFqNameWithJsNameWhenAvailable(shouldIncludePackage).child(name)
is IrPackageFragment -> getKotlinOrJsQualifier(parent, shouldIncludePackage)?.child(name) ?: FqName(name.identifier)
else -> FqName(name.identifier)
}
}
private fun getKotlinOrJsQualifier(parent: IrPackageFragment, shouldIncludePackage: Boolean): FqName? {
return (parent as? IrFile)?.getJsQualifier()?.let { FqName(it) } ?: parent.fqName.takeIf { shouldIncludePackage }
}
@@ -167,5 +167,20 @@ declare namespace JS_TESTS {
then(): number;
catch(): number;
}
class JsNameTest {
private constructor();
get value(): number;
runTest(): string;
static get Companion(): {
create(): foo.JsNameTest;
createChild(value: number): foo.JsNameTest.NestedJsName;
};
}
namespace JsNameTest {
class NestedJsName {
constructor(__value: number);
get value(): number;
}
}
}
}
@@ -219,4 +219,31 @@ class OuterClass {
class KT38262 {
fun then(): Int = 42
fun catch(): Int = 24
}
@JsExport
@JsName("JsNameTest")
class __JsNameTest private constructor() {
@JsName("value")
val __value = 4
@JsName("runTest")
fun __runTest(): String {
return "JsNameTest"
}
companion object {
@JsName("create")
fun __create(): __JsNameTest {
return __JsNameTest()
}
@JsName("createChild")
fun __createChild(value: Int): __NestJsNameTest {
return __NestJsNameTest(value)
}
}
@JsName("NestedJsName")
class __NestJsNameTest(@JsName("value") val __value: Int)
}
@@ -31,6 +31,7 @@ var TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
var processInterface = JS_TESTS.foo.processInterface;
var OuterClass = JS_TESTS.foo.OuterClass;
var KT38262 = JS_TESTS.foo.KT38262;
var JsNameTest = JS_TESTS.foo.JsNameTest;
function assert(condition) {
if (!condition) {
throw "Assertion failed";
@@ -129,5 +130,10 @@ function box() {
assert(OuterClass.NestedEnum.B.ordinal === 1);
assert(new KT38262().then() == 42);
assert(new KT38262().catch() == 24);
var jsNameTest = JsNameTest.Companion.create();
assert(jsNameTest.value === 4);
assert(jsNameTest.runTest() === "JsNameTest");
var jsNameNestedTest = JsNameTest.Companion.createChild(42);
assert(jsNameNestedTest.value === 42);
return "OK";
}
@@ -31,6 +31,7 @@ import TestInterfaceImpl = JS_TESTS.foo.TestInterfaceImpl;
import processInterface = JS_TESTS.foo.processInterface;
import OuterClass = JS_TESTS.foo.OuterClass;
import KT38262 = JS_TESTS.foo.KT38262;
import JsNameTest = JS_TESTS.foo.JsNameTest;
function assert(condition: boolean) {
if (!condition) {
@@ -156,5 +157,14 @@ function box(): string {
assert(new KT38262().then() == 42)
assert(new KT38262().catch() == 24)
const jsNameTest = JsNameTest.Companion.create();
assert(jsNameTest.value === 4)
assert(jsNameTest.runTest() === "JsNameTest")
const jsNameNestedTest = JsNameTest.Companion.createChild(42);
assert(jsNameNestedTest.value === 42)
return "OK";
}