JS: allow to inherit external classes with overloaded functions in case we don't override them (see KT-13910).
This commit is contained in:
+9
@@ -0,0 +1,9 @@
|
||||
external open class A {
|
||||
open fun f(x: Int): Unit
|
||||
|
||||
<!JS_NAME_CLASH!>open fun f(x: String): Unit<!>
|
||||
}
|
||||
|
||||
class InheritClass : A() {
|
||||
<!JS_NAME_CLASH!>override fun f(x: Int): Unit<!> { }
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
public external open class A {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun f(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open fun f(/*0*/ x: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class InheritClass : A {
|
||||
public constructor InheritClass()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun f(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun f(/*0*/ x: kotlin.String): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -476,6 +476,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("overrideOverloadedNativeFunction.kt")
|
||||
public void testOverrideOverloadedNativeFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/name/overrideOverloadedNativeFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("packageAndMethod.kt")
|
||||
public void testPackageAndMethod() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/name/packageAndMethod.kt");
|
||||
|
||||
+7
-2
@@ -73,8 +73,8 @@ class JsNameClashChecker : SimpleDeclarationChecker {
|
||||
val overrideFqn = nameSuggestion.suggest(override)!!
|
||||
val scope = getScope(overrideFqn.scope)
|
||||
val name = overrideFqn.names.last()
|
||||
val existing = scope[name]
|
||||
if (existing != null && existing != overrideFqn.descriptor) {
|
||||
val existing = scope[name] as? CallableMemberDescriptor
|
||||
if (existing != null && existing != overrideFqn.descriptor && !isFakeOverridingNative(existing)) {
|
||||
diagnosticHolder.report(ErrorsJs.JS_FAKE_NAME_CLASH.on(declaration, name, override, existing))
|
||||
break
|
||||
}
|
||||
@@ -89,6 +89,11 @@ class JsNameClashChecker : SimpleDeclarationChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isFakeOverridingNative(descriptor: CallableMemberDescriptor): Boolean {
|
||||
return descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||
descriptor.overriddenDescriptors.all { !presentsInGeneratedCode(it) }
|
||||
}
|
||||
|
||||
private fun getScope(descriptor: DeclarationDescriptor) = scopes.getOrPut(descriptor) {
|
||||
val scope = mutableMapOf<String, DeclarationDescriptor>()
|
||||
when (descriptor) {
|
||||
|
||||
@@ -5681,6 +5681,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("overrideNativeOverloadedFunction.kt")
|
||||
public void testOverrideNativeOverloadedFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/overrideNativeOverloadedFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("passExtLambdaFromNative.kt")
|
||||
public void testPassExtLambdaFromNative() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/passExtLambdaFromNative.kt");
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
function A() {
|
||||
}
|
||||
A.prototype.f = function(x) {
|
||||
return typeof x;
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
external open class A {
|
||||
open fun f(x: Int) = "number"
|
||||
|
||||
open fun f(x: String) = "string"
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
fun g(x: Int) = "[${f(x)}]"
|
||||
|
||||
fun g(x: String) = "[${f(x)}]"
|
||||
}
|
||||
|
||||
interface I {
|
||||
fun f(x: Int): String
|
||||
}
|
||||
|
||||
class C : A(), I
|
||||
|
||||
external interface J {
|
||||
fun f(x: Int): String
|
||||
}
|
||||
|
||||
class D : A(), J
|
||||
|
||||
fun box(): String {
|
||||
var result = B().g(23) + B().g("foo")
|
||||
if (result != "[number][string]") return "fail1: $result"
|
||||
|
||||
result = C().f(42)
|
||||
if (result != "number") return "fail2: $result"
|
||||
|
||||
result = D().f("bar")
|
||||
if (result != "string") return "fail3: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user