JS: use prototype when checking is against interface
See KT-20527
This commit is contained in:
@@ -52,22 +52,22 @@ Kotlin.callSetter = function (thisObject, klass, propertyName, value) {
|
||||
}
|
||||
};
|
||||
|
||||
function isInheritanceFromInterface(metadata, iface) {
|
||||
if (metadata == null) return false;
|
||||
function isInheritanceFromInterface(ctor, iface) {
|
||||
if (ctor === iface) return true;
|
||||
|
||||
var interfaces = metadata.interfaces;
|
||||
var i;
|
||||
for (i = 0; i < interfaces.length; i++) {
|
||||
if (interfaces[i] === iface) {
|
||||
return true;
|
||||
var metadata = ctor.$metadata$;
|
||||
if (metadata != null) {
|
||||
var interfaces = metadata.interfaces;
|
||||
for (var i = 0; i < interfaces.length; i++) {
|
||||
if (isInheritanceFromInterface(interfaces[i], iface)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < interfaces.length; i++) {
|
||||
if (isInheritanceFromInterface(interfaces[i].$metadata$, iface)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
var superPrototype = ctor.prototype != null ? Object.getPrototypeOf(ctor.prototype) : null;
|
||||
var superConstructor = superPrototype != null ? superPrototype.constructor : null;
|
||||
return superConstructor != null && isInheritanceFromInterface(superConstructor, iface);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,10 +114,7 @@ Kotlin.isType = function (object, klass) {
|
||||
}
|
||||
|
||||
if (klassMetadata.kind === Kotlin.Kind.INTERFACE && object.constructor != null) {
|
||||
metadata = object.constructor.$metadata$;
|
||||
if (metadata != null) {
|
||||
return isInheritanceFromInterface(metadata, klass);
|
||||
}
|
||||
return isInheritanceFromInterface(object.constructor, klass);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -7667,6 +7667,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("prototypeUsedToFindInterface.kt")
|
||||
public void testPrototypeUsedToFindInterface() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/rtti/prototypeUsedToFindInterface.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("rttiForClass.kt")
|
||||
public void testRttiForClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/rtti/rttiForClass.kt");
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1112
|
||||
interface A {
|
||||
fun foo(): String
|
||||
}
|
||||
|
||||
class B : A {
|
||||
override fun foo(): String = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val b = B::class.js
|
||||
val c = js("""
|
||||
function C() {
|
||||
b.call(this);
|
||||
};
|
||||
C.prototype = Object.create(b.prototype);
|
||||
C.prototype.constructor = C;
|
||||
new C();
|
||||
""")
|
||||
|
||||
if (c !is B) return "fail: c !is B"
|
||||
if (c !is A) return "fail: c !is A"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user