diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 4bf9042216d..922a4e87893 100644 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -846,6 +846,10 @@ fun main(args: Array) { testClass(javaClass()) { model("inlineSizeReduction/cases") } + + testClass(javaClass()) { + model("reified/cases") + } } testGroup("js/js.tests/test", "compiler/testData") { diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/AbstractReifiedTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/AbstractReifiedTest.kt new file mode 100644 index 00000000000..147c12fee17 --- /dev/null +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/AbstractReifiedTest.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.test.semantics + +import org.jetbrains.kotlin.js.test.SingleFileTranslationTest + +public abstract class AbstractReifiedTest : SingleFileTranslationTest("reified/") \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/ReifiedTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/ReifiedTestGenerated.java new file mode 100644 index 00000000000..dc260b3afff --- /dev/null +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/ReifiedTestGenerated.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.test.semantics; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.JetTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("js/js.translator/testData/reified/cases") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class ReifiedTestGenerated extends AbstractReifiedTest { + public void testAllFilesPresentInCases() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/reified/cases"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("callChain.kt") + public void testCallChain() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/callChain.kt"); + doTest(fileName); + } + + @TestMetadata("extensionMethod.kt") + public void testExtensionMethod() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/extensionMethod.kt"); + doTest(fileName); + } + + @TestMetadata("innerObject.kt") + public void testInnerObject() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/innerObject.kt"); + doTest(fileName); + } + + @TestMetadata("isBool.kt") + public void testIsBool() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/isBool.kt"); + doTest(fileName); + } + + @TestMetadata("isChar.kt") + public void testIsChar() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/isChar.kt"); + doTest(fileName); + } + + @TestMetadata("isClass.kt") + public void testIsClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/isClass.kt"); + doTest(fileName); + } + + @TestMetadata("isNumber.kt") + public void testIsNumber() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/isNumber.kt"); + doTest(fileName); + } + + @TestMetadata("isString.kt") + public void testIsString() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/isString.kt"); + doTest(fileName); + } + + @TestMetadata("lambdaNameClash.kt") + public void testLambdaNameClash() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/lambdaNameClash.kt"); + doTest(fileName); + } + + @TestMetadata("method.kt") + public void testMethod() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/method.kt"); + doTest(fileName); + } + + @TestMetadata("multipleTypeParameters.kt") + public void testMultipleTypeParameters() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/multipleTypeParameters.kt"); + doTest(fileName); + } + + @TestMetadata("noValueParameters.kt") + public void testNoValueParameters() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/noValueParameters.kt"); + doTest(fileName); + } + + @TestMetadata("parameterSwap.kt") + public void testParameterSwap() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/parameterSwap.kt"); + doTest(fileName); + } + + @TestMetadata("vararg.kt") + public void testVararg() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/reified/cases/vararg.kt"); + doTest(fileName); + } +} diff --git a/js/js.translator/testData/reified/_commonFiles/isInstance.kt b/js/js.translator/testData/reified/_commonFiles/isInstance.kt new file mode 100644 index 00000000000..bbe8a1c81d9 --- /dev/null +++ b/js/js.translator/testData/reified/_commonFiles/isInstance.kt @@ -0,0 +1,4 @@ +package foo + +inline fun isInstance(x: Any): Boolean = + x is T \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/callChain.kt b/js/js.translator/testData/reified/cases/callChain.kt new file mode 100644 index 00000000000..48a298d9bc4 --- /dev/null +++ b/js/js.translator/testData/reified/cases/callChain.kt @@ -0,0 +1,18 @@ +package foo + +// CHECK_NOT_CALLED: test +// CHECK_NOT_CALLED: test1 + +class A +class B + +inline fun test(x: Any): Boolean = test1(x) + +inline fun test1(x: Any): Boolean = x is R + +fun box(): String { + assertEquals(true, test(A()), "test(A())") + assertEquals(false, test(B()), "test(B())") + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/extensionMethod.kt b/js/js.translator/testData/reified/cases/extensionMethod.kt new file mode 100644 index 00000000000..6024ef9ad84 --- /dev/null +++ b/js/js.translator/testData/reified/cases/extensionMethod.kt @@ -0,0 +1,29 @@ +package foo + +// CHECK_NOT_CALLED: test +// CHECK_NOT_CALLED: fn + +class A(val x: Any? = null) { + inline + fun test(b: B) = b.fn() + + inline + fun B.fn() = x is T && y is R +} + +class B(val y: Any? = null) + +class X +class Y + +fun box(): String { + val x = X() + val y = Y() + + assertEquals(true, A(x).test(B(y)), "A(x).test(B(y))") + assertEquals(false, A(y).test(B(y)), "A(y).test(B(y))") + assertEquals(false, A(y).test(B(x)), "A(y).test(B(x))") + assertEquals(false, A(x).test(B(x)), "A(x).test(B(x))") + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/innerObject.kt b/js/js.translator/testData/reified/cases/innerObject.kt new file mode 100644 index 00000000000..c0d35e452d7 --- /dev/null +++ b/js/js.translator/testData/reified/cases/innerObject.kt @@ -0,0 +1,31 @@ +package foo + +// CHECK_NOT_CALLED: typePredicate + +open class A + +class B + +class C : A() + +trait TypePredicate { + fun invoke(x: Any): Boolean +} + +inline fun typePredicate(): TypePredicate = + object : TypePredicate { + override fun invoke(x: Any): Boolean = x is T + } + +fun box(): String { + val isA = typePredicate() + val a: Any = A() + val b: Any = B() + val c: Any = C() + + assertEquals(true, isA(a), "isA(a)") + assertEquals(false, isA(b), "isA(b)") + assertEquals(true, isA(c), "isA(c)") + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/isBool.kt b/js/js.translator/testData/reified/cases/isBool.kt new file mode 100644 index 00000000000..02f87afbaeb --- /dev/null +++ b/js/js.translator/testData/reified/cases/isBool.kt @@ -0,0 +1,11 @@ +package foo + +// CHECK_NOT_CALLED: isInstance + +fun box(): String { + assertEquals(true, isInstance(true)) + assertEquals(true, isInstance(false)) + assertEquals(false, isInstance("true")) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/isChar.kt b/js/js.translator/testData/reified/cases/isChar.kt new file mode 100644 index 00000000000..9923f91f663 --- /dev/null +++ b/js/js.translator/testData/reified/cases/isChar.kt @@ -0,0 +1,11 @@ +package foo + +// CHECK_NOT_CALLED: isInstance + +fun box(): String { + assertEquals(true, isInstance('c')) + assertEquals(false, isInstance("")) + assertEquals(false, isInstance("cc")) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/isClass.kt b/js/js.translator/testData/reified/cases/isClass.kt new file mode 100644 index 00000000000..fa5e92ff89d --- /dev/null +++ b/js/js.translator/testData/reified/cases/isClass.kt @@ -0,0 +1,21 @@ +package foo + +// CHECK_NOT_CALLED: isInstance + +trait A +trait B + +open class C : A, B + +class D : C() + +fun box(): String { + assertEquals(false, isInstance(0)) + assertEquals(false, isInstance("")) + assertEquals(true, isInstance(C())) + assertEquals(true, isInstance(D())) + assertEquals(true, isInstance(D())) + assertEquals(true, isInstance(D())) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/isNumber.kt b/js/js.translator/testData/reified/cases/isNumber.kt new file mode 100644 index 00000000000..1adbf2acbe0 --- /dev/null +++ b/js/js.translator/testData/reified/cases/isNumber.kt @@ -0,0 +1,19 @@ +package foo + +// CHECK_NOT_CALLED: isInstance + +fun box(): String { + assertEquals(true, isInstance(0.toShort())) + assertEquals(true, isInstance(0.toByte())) + assertEquals(true, isInstance(0)) + assertEquals(true, isInstance(0.toLong())) + assertEquals(true, isInstance(0.toDouble())) + assertEquals(true, isInstance(0.toFloat())) + + assertEquals(true, isInstance(0)) + assertEquals(true, isInstance(0.toLong())) + assertEquals(true, isInstance(0.0)) + assertEquals(false, isInstance("0")) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/isString.kt b/js/js.translator/testData/reified/cases/isString.kt new file mode 100644 index 00000000000..e4602ee944b --- /dev/null +++ b/js/js.translator/testData/reified/cases/isString.kt @@ -0,0 +1,10 @@ +package foo + +// CHECK_NOT_CALLED: isInstance + +fun box(): String { + assertEquals(true, isInstance("")) + assertEquals(true, isInstance("a")) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/lambdaNameClash.kt b/js/js.translator/testData/reified/cases/lambdaNameClash.kt new file mode 100644 index 00000000000..dc52445f933 --- /dev/null +++ b/js/js.translator/testData/reified/cases/lambdaNameClash.kt @@ -0,0 +1,33 @@ +package foo + +// CHECK_CALLED: doRun +// CHECK_NOT_CALLED: test + +class X +class Y + +noinline +fun doRun(fn: ()->R): R = fn() + +inline fun test(x: Any, y: Any): Boolean = + doRun { + val isA = null + x is A + } + && doRun { + val result = y is B + val isB = null + result + } + +fun box(): String { + val x = X() + val y = Y() + + assertEquals(true, test(x, y), "test(x, y)") + assertEquals(false, test(x, x), "test(x, x)") + assertEquals(false, test(y, x), "test(y, x)") + assertEquals(false, test(y, y), "test(y, y)") + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/method.kt b/js/js.translator/testData/reified/cases/method.kt new file mode 100644 index 00000000000..41bb3363031 --- /dev/null +++ b/js/js.translator/testData/reified/cases/method.kt @@ -0,0 +1,17 @@ +package foo + +// CHECK_NOT_CALLED: test + +class A(val x: Any? = null) { + inline + fun test() = x is T +} + +class B + +fun box(): String { + assertEquals(true, A(A()).test(), "A(A()).test()") + assertEquals(false, A(B()).test(), "A(B()).test()") + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/multipleTypeParameters.kt b/js/js.translator/testData/reified/cases/multipleTypeParameters.kt new file mode 100644 index 00000000000..aef387f85cd --- /dev/null +++ b/js/js.translator/testData/reified/cases/multipleTypeParameters.kt @@ -0,0 +1,20 @@ +package foo + +class X +class Y +class Z + +inline fun test(x: Any): String = + when (x) { + is A -> "A" + is C -> "C" + else -> "Unknown" + } + +fun box(): String { + assertEquals("A", test(X())) + assertEquals("Unknown", test(Y())) + assertEquals("C", test(Z())) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/noValueParameters.kt b/js/js.translator/testData/reified/cases/noValueParameters.kt new file mode 100644 index 00000000000..a0b424c0f02 --- /dev/null +++ b/js/js.translator/testData/reified/cases/noValueParameters.kt @@ -0,0 +1,18 @@ +package foo + +// CHECK_NOT_CALLED: test + +class A + +inline fun test(): String { + val a: Any = A() + + return if (a is T) "A" else "Unknown" +} + +fun box(): String { + assertEquals("A", test()) + assertEquals("Unknown", test()) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/parameterSwap.kt b/js/js.translator/testData/reified/cases/parameterSwap.kt new file mode 100644 index 00000000000..f90628a66f6 --- /dev/null +++ b/js/js.translator/testData/reified/cases/parameterSwap.kt @@ -0,0 +1,22 @@ +package foo + +class A +class B +class C + +inline fun test(x: Any): String = test1(x) + +inline fun test1(x: Any): String = + when (x) { + is R -> "R" + is T -> "T" + else -> "Unknown" + } + +fun box(): String { + assertEquals("T", test(A()), "test(T())") + assertEquals("R", test(B()), "test(R())") + assertEquals("Unknown", test(C()), "test(L())") + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/reified/cases/vararg.kt b/js/js.translator/testData/reified/cases/vararg.kt new file mode 100644 index 00000000000..2c63b96a39c --- /dev/null +++ b/js/js.translator/testData/reified/cases/vararg.kt @@ -0,0 +1,34 @@ +package foo + +// CHECK_NOT_CALLED: test + +class A(val x: Int) +class B(val x: Int) + +inline +fun test(vararg xs: Any): List { + val ts = arrayListOf() + + for (x in xs) { + if (x is T) { + ts.add(x) + } + } + + return ts +} + +fun box(): String { + val a1 = A(1) + val b2 = B(2) + val a3 = A(3) + val b4 = B(4) + + assertEquals(listOf(a1), test(a1, b2), "test(a1, b2)") + assertEquals(listOf(b2, b4), test(a1, b2, a3, b4), "test(a1, b2, a3, b4)") + + val objects = arrayOf(a1, b2) + assertEquals(listOf(b2, b4), test(a1, a3, *objects, a3, b4), "test(a1, a3, *objects, a3, b4)") + + return "OK" +} \ No newline at end of file