From 0e6d9e857c5977ce700cd875709b17964fc83537 Mon Sep 17 00:00:00 2001 From: Erokhin Stanislav Date: Fri, 20 Sep 2013 16:22:14 +0400 Subject: [PATCH] JS backend: fix is for trait. #KT-3519 fixed --- .../k2js/test/semantics/RTTITest.java | 8 +++++ .../testFiles/kotlin_lib_ecma5.js | 30 +++++++++++++++- .../testFiles/rtti/cases/rttiForTrait.kt | 20 +++++++++++ .../testFiles/rtti/cases/rttiForTrait2.kt | 36 +++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testFiles/rtti/cases/rttiForTrait.kt create mode 100644 js/js.translator/testFiles/rtti/cases/rttiForTrait2.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java index bd8d86e84bd..aea6d567ae7 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/RTTITest.java @@ -28,6 +28,14 @@ public class RTTITest extends SingleFileTranslationTest { checkFooBoxIsOk(); } + public void testRttiForTrait() throws Exception { + checkFooBoxIsOk(); + } + + public void testRttiForTrait2() throws Exception { + checkFooBoxIsOk(); + } + public void testIsSameClass() throws Exception { fooBoxTest(); } diff --git a/js/js.translator/testFiles/kotlin_lib_ecma5.js b/js/js.translator/testFiles/kotlin_lib_ecma5.js index 71253f00c29..6609d589fab 100644 --- a/js/js.translator/testFiles/kotlin_lib_ecma5.js +++ b/js/js.translator/testFiles/kotlin_lib_ecma5.js @@ -202,6 +202,7 @@ var Kotlin = {}; } Object.defineProperties(prototypeObj, metadata.properties); copyProperties(prototypeObj, metadata.functions); + prototypeObj.constructor = constructor; if (metadata.baseClass != null) { constructor.baseInitializer = metadata.baseClass; @@ -231,11 +232,38 @@ var Kotlin = {}; return obj; }; + function isInheritanceFromTrait (objConstructor, trait) { + if (isNativeClass(objConstructor) || objConstructor.$metadata$.classIndex < trait.$metadata$.classIndex) { + return false; + } + var baseClasses = objConstructor.$metadata$.baseClasses; + var i; + for (i = 0; i < baseClasses.length; i++) { + if (baseClasses[i] === trait) { + return true; + } + } + for (i = 0; i < baseClasses.length; i++) { + if (isInheritanceFromTrait(baseClasses[i], trait)) { + return true; + } + } + return false; + } + Kotlin.isType = function (object, klass) { if (object == null || klass == null) { return false; } else { - return object instanceof klass; // TODO trait support + if (object instanceof klass) { + return true; + } + else if (isNativeClass(klass) || klass.$metadata$.type == Kotlin.TYPE.CLASS) { + return false; + } + else { + return isInheritanceFromTrait(object.constructor, klass); + } } }; diff --git a/js/js.translator/testFiles/rtti/cases/rttiForTrait.kt b/js/js.translator/testFiles/rtti/cases/rttiForTrait.kt new file mode 100644 index 00000000000..6f82b71ddad --- /dev/null +++ b/js/js.translator/testFiles/rtti/cases/rttiForTrait.kt @@ -0,0 +1,20 @@ +package foo + + +open class A + +trait B + +class C: A(), B + +fun box(): String { + + val a = A() + val b = object : B {} + val c = C() + + if (a is B) return "a is B" + if (b !is B) return "b !is B" + if (c !is B) return "c !is B" + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testFiles/rtti/cases/rttiForTrait2.kt b/js/js.translator/testFiles/rtti/cases/rttiForTrait2.kt new file mode 100644 index 00000000000..d0d7f96d419 --- /dev/null +++ b/js/js.translator/testFiles/rtti/cases/rttiForTrait2.kt @@ -0,0 +1,36 @@ +package foo + +trait A +trait B : A +trait C : A +trait D : B, C +trait E : C + +open class CB: B +class CB2: CB() + +class CD: D + +fun testPhrase(o: Any): String { + var s = "" + s += if(o is A) "Y" else "N" + s += if(o is B) "Y" else "N" + s += if(o is C) "Y" else "N" + s += if(o is D) "Y" else "N" + s += if(o is E) "Y" else "N" + return s +} + +fun box(): String { + val b = CB() + val b2 = CB2() + val d = CD() + val e = object : E {} + + if (testPhrase(b) != "YYNNN") return "bad b, it: ${testPhrase(b)}" + if (testPhrase(b2) != "YYNNN") return "bad b2, it: ${testPhrase(b2)}" + if (testPhrase(d) != "YYYYN") return "bad d, it: ${testPhrase(d)}" + if (testPhrase(e) != "YNYNY") return "bad e, it: ${testPhrase(e)}" + + return "OK" +} \ No newline at end of file