diff --git a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt index 9b278f5ac9c..4248be75f49 100644 --- a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt +++ b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/jsScopes.kt @@ -95,7 +95,7 @@ open class JsFunctionScope(parent: JsScope, description: String) : JsScope(paren "eval", "arguments", // global identifiers usually declared in a typical JS interpreter - "NaN", "Infinity", "undefined", + "NaN", "isNaN", "Infinity", "undefined", "Error", "Object", "Math", "String", "Number", "Boolean", "Date", "Array", "RegExp", "JSON", // global identifiers usually declared in know environments (node.js, browser, require.js, WebWorkers, etc) diff --git a/js/js.libraries/src/builtins/Enum.kt b/js/js.libraries/src/builtins/Enum.kt index 8577a7eb5ec..a5185ebbc34 100644 --- a/js/js.libraries/src/builtins/Enum.kt +++ b/js/js.libraries/src/builtins/Enum.kt @@ -30,7 +30,7 @@ public class Enum> : Comparable> { override fun equals(other: Any?) = this === other - override fun hashCode(): Int = js("Kotlin.identityHashCode(this)") + override fun hashCode(): Int = js("Kotlin.identityHashCode")(this) override fun toString() = name diff --git a/js/js.libraries/src/core/console.kt b/js/js.libraries/src/core/console.kt index 2330773a11e..966312c80fe 100644 --- a/js/js.libraries/src/core/console.kt +++ b/js/js.libraries/src/core/console.kt @@ -18,7 +18,7 @@ internal abstract class BaseOutput { @JsName("println") open fun println(a: Any?) { - if (js("typeof a") !== "undefined") { + if (jsTypeOf(a) != "undefined") { print(a) } print("\n") @@ -43,7 +43,7 @@ internal class OutputToConsoleLog : BaseOutput() { } override fun println(a: Any?) { - console.log(if (js("typeof a") !== "undefined") a else "") + console.log(if (jsTypeOf(a) != "undefined") a else "") } } @@ -85,4 +85,4 @@ internal var `out` = { if (isNode) NodeJsOutput(js("process.stdout")) else BufferedOutputToConsoleLog() }() -private inline fun String(value: Any?): String = js("String(value)") +private inline fun String(value: Any?): String = js("String")(value) diff --git a/js/js.libraries/src/core/core.kt b/js/js.libraries/src/core/core.kt index 2a8a202349e..c6558ee01a5 100644 --- a/js/js.libraries/src/core/core.kt +++ b/js/js.libraries/src/core/core.kt @@ -32,7 +32,7 @@ public external fun js(code: String): dynamic = noImpl /** * Function corresponding to JavaScript's `typeof` operator */ -public inline fun jsTypeOf(a: Any?): String = js("typeof a") +public inline fun jsTypeOf(a: Any?): String = js("Kotlin").jsTypeOf(a) @library internal fun deleteProperty(`object`: Any, property: Any): Unit = noImpl \ No newline at end of file diff --git a/js/js.libraries/src/core/dynamic.kt b/js/js.libraries/src/core/dynamic.kt index 3f194b901f5..3424b10f957 100644 --- a/js/js.libraries/src/core/dynamic.kt +++ b/js/js.libraries/src/core/dynamic.kt @@ -30,7 +30,7 @@ public operator fun dynamic.iterator(): Iterator { return when { this["iterator"] != null -> this["iterator"]() - js("Array.isArray(r)") -> + js("Array").isArray(r) -> r.unsafeCast>().iterator() else -> diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 50802e5e57e..998a2031747 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -3788,18 +3788,6 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } - @TestMetadata("jsCode.kt") - public void testJsCode() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inline/jsCode.kt"); - doTest(fileName); - } - - @TestMetadata("jsCodeVarDeclared.kt") - public void testJsCodeVarDeclared() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inline/jsCodeVarDeclared.kt"); - doTest(fileName); - } - @TestMetadata("lambdaInLambda.kt") public void testLambdaInLambda() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inline/lambdaInLambda.kt"); @@ -5575,6 +5563,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/nameClashes/propertyAndNativeMethod.kt"); doTest(fileName); } + + @TestMetadata("topLevelFunctionAndParameter.kt") + public void testTopLevelFunctionAndParameter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/nameClashes/topLevelFunctionAndParameter.kt"); + doTest(fileName); + } } @TestMetadata("js/js.translator/testData/box/native") @@ -5657,6 +5651,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("jsTypeOf.kt") + public void testJsTypeOf() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/jsTypeOf.kt"); + doTest(fileName); + } + @TestMetadata("kt2209.kt") public void testKt2209() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/kt2209.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index 6352280908f..21db13e2caa 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -369,7 +369,9 @@ public final class StaticContext { JsName name = nameCache.get(suggested.getDescriptor()); if (name == null) { String baseName = suggested.getNames().get(0); - if (suggested.getDescriptor() instanceof LocalVariableDescriptor) { + if (suggested.getDescriptor() instanceof LocalVariableDescriptor || + suggested.getDescriptor() instanceof ValueParameterDescriptor + ) { name = scope.declareTemporaryName(baseName); } else { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java index 881e71165fc..561c2463fd6 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/FunctionTranslator.java @@ -149,7 +149,7 @@ public final class FunctionTranslator extends AbstractTranslator { jsParameters.add(new JsParameter(paramNameForType)); String suggestedName = Namer.isInstanceSuggestedName(type); - JsName paramName = functionObject.getScope().declareName(suggestedName); + JsName paramName = functionObject.getScope().declareTemporaryName(suggestedName); jsParameters.add(new JsParameter(paramName)); aliases.put(type, paramName.makeRef()); } diff --git a/js/js.translator/testData/box/inline/jsCode.kt b/js/js.translator/testData/box/inline/jsCode.kt deleted file mode 100644 index 5c2013cee92..00000000000 --- a/js/js.translator/testData/box/inline/jsCode.kt +++ /dev/null @@ -1,14 +0,0 @@ -package foo - -// CHECK_CONTAINS_NO_CALLS: test - -internal inline fun sum(x: Int, y: Int): Int = js("x + y") - -internal fun test(x: Int, y: Int): Int = sum(sum(x, x), sum(y, y)) - -fun box(): String { - assertEquals(4, test(1, 1)) - assertEquals(8, test(1, 3)) - - return "OK" -} \ No newline at end of file diff --git a/js/js.translator/testData/box/inline/jsCodeVarDeclared.kt b/js/js.translator/testData/box/inline/jsCodeVarDeclared.kt deleted file mode 100644 index 474e0277071..00000000000 --- a/js/js.translator/testData/box/inline/jsCodeVarDeclared.kt +++ /dev/null @@ -1,20 +0,0 @@ -package foo - -// CHECK_CONTAINS_NO_CALLS: test - -internal inline fun sum(x: Int, y: Int): Int = js("var a = x; a + y") - -internal fun test(x: Int, y: Int): Int { - val xx = sum(x, x) - js("var a = 0;") - val yy = sum(y, y) - - return sum(xx, yy) -} - -fun box(): String { - assertEquals(4, test(1, 1)) - assertEquals(8, test(1, 3)) - - return "OK" -} \ No newline at end of file diff --git a/js/js.translator/testData/box/nameClashes/topLevelFunctionAndParameter.kt b/js/js.translator/testData/box/nameClashes/topLevelFunctionAndParameter.kt new file mode 100644 index 00000000000..e9fbf7437ba --- /dev/null +++ b/js/js.translator/testData/box/nameClashes/topLevelFunctionAndParameter.kt @@ -0,0 +1,9 @@ +fun f(x: Int) = x * 2 + +fun test(f: (Long) -> Long) = Pair(f(23 as Int), f(42L)) + +fun box(): String { + val result = test { it * 3 } + if (result != Pair(46, 126L)) return "fail: $result" + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/native/jsTypeOf.kt b/js/js.translator/testData/box/native/jsTypeOf.kt new file mode 100644 index 00000000000..c8b623e2f6d --- /dev/null +++ b/js/js.translator/testData/box/native/jsTypeOf.kt @@ -0,0 +1,18 @@ +fun box(): String { + var result = jsTypeOf(23) + if (result != "number") return "fail1: $result" + + result = jsTypeOf("23") + if (result != "string") return "fail2: $result" + + result = jsTypeOf({ x: Int -> x }) + if (result != "function") return "fail3: $result" + + result = jsTypeOf(object {}) + if (result != "object") return "fail4: $result" + + result = jsTypeOf(true) + if (result != "boolean") return "fail5: $result" + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/kotlin_lib_ecma5.js b/js/js.translator/testData/kotlin_lib_ecma5.js index 25f229e278f..933beda7bb2 100644 --- a/js/js.translator/testData/kotlin_lib_ecma5.js +++ b/js/js.translator/testData/kotlin_lib_ecma5.js @@ -270,6 +270,7 @@ return cache.value; } + Kotlin.jsTypeOf = function(a) { return typeof a; }; ////////////////////////////////// packages & modules //////////////////////////////