[JS IR] fix name clashes for imported external declarations
This commit is contained in:
committed by
TeamCityServer
parent
6e40c814c8
commit
0182c09318
@@ -9,6 +9,10 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||||
|
|
||||||
class IrNamerImpl(
|
class IrNamerImpl(
|
||||||
@@ -28,4 +32,52 @@ class IrNamerImpl(
|
|||||||
require(!field.isStatic)
|
require(!field.isStatic)
|
||||||
return newNameTables.getNameForMemberField(field).toJsName()
|
return newNameTables.getNameForMemberField(field).toJsName()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getNameForField(field: IrField): JsName {
|
||||||
|
return if (field.isStatic || field.parent is IrScript) {
|
||||||
|
getNameForStaticDeclaration(field)
|
||||||
|
} else {
|
||||||
|
getNameForMemberField(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getNameForValueDeclaration(declaration: IrValueDeclaration): JsName =
|
||||||
|
getNameForStaticDeclaration(declaration)
|
||||||
|
|
||||||
|
override fun getNameForClass(klass: IrClass): JsName =
|
||||||
|
getNameForStaticDeclaration(klass)
|
||||||
|
|
||||||
|
override fun getNameForStaticFunction(function: IrSimpleFunction): JsName =
|
||||||
|
getNameForStaticDeclaration(function)
|
||||||
|
|
||||||
|
override fun getNameForProperty(property: IrProperty): JsName =
|
||||||
|
if (property.isTopLevel) getNameForStaticDeclaration(property) else property.getJsNameOrKotlinName().asString().toJsName()
|
||||||
|
|
||||||
|
override fun getRefForExternalClass(klass: IrClass): JsNameRef {
|
||||||
|
val parent = klass.parent
|
||||||
|
if (klass.isCompanion)
|
||||||
|
return getRefForExternalClass(parent as IrClass)
|
||||||
|
|
||||||
|
val currentClassName = if (klass.isTopLevel) getNameForStaticDeclaration(klass).ident else klass.getJsNameOrKotlinName().identifier
|
||||||
|
return when (parent) {
|
||||||
|
is IrClass ->
|
||||||
|
JsNameRef(currentClassName, getRefForExternalClass(parent))
|
||||||
|
|
||||||
|
is IrPackageFragment ->
|
||||||
|
JsNameRef(currentClassName)
|
||||||
|
|
||||||
|
else ->
|
||||||
|
error("Unsupported external class parent $parent")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val associatedObjectKeyMap = mutableMapOf<IrClass, Int>()
|
||||||
|
|
||||||
|
override fun getAssociatedObjectKey(irClass: IrClass): Int? {
|
||||||
|
if (irClass.isAssociatedObjectAnnotatedAnnotation) {
|
||||||
|
|
||||||
|
return associatedObjectKeyMap.getOrPut(irClass) { associatedObjectKeyMap.size }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ class NameTables(
|
|||||||
return
|
return
|
||||||
|
|
||||||
// TODO: Handle JsQualifier
|
// TODO: Handle JsQualifier
|
||||||
declaration.isEffectivelyExternal() && (declaration.getJsModule() == null || declaration.isJsNonModule()) -> {
|
declaration.isEffectivelyExternal() && !declaration.isImportedFromModuleOnly() -> {
|
||||||
if (declaration.file.getJsModule() != null) {
|
if (declaration.file.getJsModule() != null) {
|
||||||
globalNames.declareFreshName(declaration, declaration.name.asString())
|
globalNames.declareFreshName(declaration, declaration.name.asString())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-2
@@ -73,8 +73,7 @@ class StableNamesCollector : IrElementVisitorVoid {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val importedFromModuleOnly =
|
val importedFromModuleOnly = declaration.isImportedFromModuleOnly()
|
||||||
declaration.getJsModule() != null && !declaration.isJsNonModule()
|
|
||||||
|
|
||||||
val jsName = declaration.getJsName()
|
val jsName = declaration.getJsName()
|
||||||
val jsQualifier = declaration.getJsQualifier()
|
val jsQualifier = declaration.getJsQualifier()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.utils
|
package org.jetbrains.kotlin.ir.backend.js.utils
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
|
import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
@@ -18,6 +19,8 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||||
|
import org.jetbrains.kotlin.ir.types.isUnit
|
||||||
|
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration
|
import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -111,4 +114,8 @@ fun IrBody.prependFunctionCall(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrDeclaration.isImportedFromModuleOnly(): Boolean {
|
||||||
|
return isTopLevel && isEffectivelyExternal() && (getJsModule() != null && !isJsNonModule() || (parent as? IrAnnotationContainer)?.getJsModule() != null)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
define("a", [], function() {
|
||||||
|
|
||||||
|
function A() {}
|
||||||
|
|
||||||
|
A.prototype.foo = function () {
|
||||||
|
return "O";
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
A: A,
|
||||||
|
bar: function() { return 1; },
|
||||||
|
prop: 10
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
define("b", [], function() {
|
||||||
|
|
||||||
|
function A() {}
|
||||||
|
|
||||||
|
A.prototype.foo = function () {
|
||||||
|
return "K";
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
A: A,
|
||||||
|
bar: function() { return 2; },
|
||||||
|
prop: 20
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// EXPECTED_REACHABLE_NODES: 1284
|
||||||
|
// FILE: a.kt
|
||||||
|
// MODULE_KIND: AMD
|
||||||
|
@file:JsModule("a")
|
||||||
|
package a
|
||||||
|
|
||||||
|
external class A {
|
||||||
|
fun foo(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
external fun bar(): Int
|
||||||
|
|
||||||
|
external val prop: Int
|
||||||
|
|
||||||
|
// FILE: b.kt
|
||||||
|
// MODULE_KIND: AMD
|
||||||
|
@file:JsModule("b")
|
||||||
|
package b
|
||||||
|
|
||||||
|
external class A {
|
||||||
|
fun foo(): String
|
||||||
|
}
|
||||||
|
|
||||||
|
external fun bar(): Int
|
||||||
|
|
||||||
|
external var prop: Int
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
import a.A as O
|
||||||
|
import b.A as K
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (a.bar() != 1) return "fail 1"
|
||||||
|
if (a.prop != 10) return "fail 2"
|
||||||
|
if (b.bar() != 2) return "fail 3"
|
||||||
|
if (b.prop != 20) return "fail 4"
|
||||||
|
|
||||||
|
return O().foo() + K().foo()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user