JS: prohibit native (external) extension properties and functions. See KT-13896

This commit is contained in:
Alexey Andreev
2016-11-28 11:38:29 +03:00
parent cf25e17209
commit 3882bf7564
36 changed files with 48 additions and 346 deletions
@@ -1,19 +1,5 @@
package foo
// HACKS
external const val PATH_TO_F_CREATOR = "B\$far\$lambda"
external const val PATH_TO_G_CREATOR = "B\$gar\$lambda"
@JsName("$PATH_TO_F_CREATOR")
external val F_CREATOR: Any = noImpl
@JsName("$PATH_TO_G_CREATOR")
external val G_CREATOR: Any = noImpl
// Test
open class A {
fun foo() = "A::foo"
}
@@ -34,8 +20,8 @@ fun box(): String {
assertEquals("A::foo", f())
assertEquals("B::boo", g())
val fs = F_CREATOR.toString()
val gs = G_CREATOR.toString().replaceAll("boo", "foo").replaceAll("gar", "far")
val fs = js("B\$far\$lambda").toString() as String
val gs = (js("B\$gar\$lambda").toString() as String).replaceAll("boo", "foo").replaceAll("gar", "far")
assertEquals(gs, fs)
@@ -45,7 +31,7 @@ fun box(): String {
// Helpers
external fun String.replace(regexp: RegExp, replacement: String): String = noImpl
inline fun String.replace(regexp: RegExp, replacement: String): String = asDynamic().replace(regexp, replacement)
fun String.replaceAll(regexp: String, replacement: String): String = replace(RegExp(regexp, "g"), replacement)
@@ -1,10 +1,10 @@
package foo
external fun String.replace(regexp: RegExp, replacement: String): String = noImpl
inline fun String.replace(regexp: RegExp, replacement: String): String = asDynamic().replace(regexp, replacement)
fun String.replaceAll(regexp: String, replacement: String): String = replace(RegExp(regexp, "g"), replacement)
external fun String.search(regexp: RegExp): Int = noImpl
inline fun String.search(regexp: RegExp): Int = asDynamic().search(regexp)
external class RegExp(regexp: String, flags: String = "") {
fun exec(s: String): Array<String>? = noImpl
@@ -1,6 +1,6 @@
package foo
external fun String.charCodeAt(i: Int): Int = noImpl
inline fun String.charCodeAt(i: Int): Int = asDynamic().charCodeAt(i)
// Because String in JS doesn't have hashCode method
fun String.myHashCode(): Int {
@@ -28,9 +28,9 @@ package foo
// CHECK_NOT_CALLED: moveTo
external fun Array<Int>.push(element: Int): Unit = noImpl
inline fun Array<Int>.push(element: Int): Unit = asDynamic().push(element)
external fun Array<Int>.splice(index: Int, howMany: Int): Unit = noImpl
inline fun Array<Int>.splice(index: Int, howMany: Int): Unit = asDynamic().splice(index, howMany)
data class PairArray<T, R>(val fst: Array<T>, val snd: Array<R>)
-8
View File
@@ -1,8 +0,0 @@
function Wow() {
this.x = 1;
this.y = 2;
}
Wow.prototype.sum = function () {
return this.x + this.y;
};
-17
View File
@@ -1,17 +0,0 @@
package foo
external class Wow() {
val x: Int = noImpl
val y: Int = noImpl
}
external fun Wow.sum(): Int = noImpl
fun Wow.dblSum(): Int {
return 2 * sum()
}
fun box(): String {
return if (Wow().dblSum() == 6) "OK" else "fail"
}
@@ -1,5 +0,0 @@
function A(value) {
this.value = value;
}
A.prototype.bar = function() { return "A.bar " + this.value; };
@@ -1,39 +0,0 @@
package foo
external open class A(val value: String) {
}
class B : A("B") {
fun bar(): String = "B.bar ${value}"
var prop: String = "B prop"
}
external fun A.bar(): String = noImpl
external var A.prop: String
get() = noImpl
set(value) = noImpl
fun box(): String {
var a: A = A("A")
val b: B = B()
assertEquals("A.bar A", a.bar())
assertEquals("B.bar B", b.bar())
assertEquals("A.bar A", (A::bar)(a))
assertEquals("B.bar B", (A::bar)(b))
a.prop = "prop"
assertEquals("prop", a.prop)
assertEquals("prop", (A::prop).get(a))
a = b
assertEquals("B.bar B", a.bar())
assertEquals("B.bar B", (A::bar)(a))
assertEquals("B prop", a.prop)
assertEquals("B prop", (A::prop).get(a))
return "OK"
}
@@ -1 +0,0 @@
var boo = "K";
@@ -1,32 +0,0 @@
package foo
// TODO: this feature is deprecated, remove this test when either @native annotation or its parameter get eliminated.
internal @native("\"O\"") val foo: String = noImpl
internal @native("boo") val bar: String = noImpl
internal class A
internal @native("__proto__") val Any.proto: String get() = noImpl
internal @native("__proto__") val A.proto: String get() = noImpl
internal fun actual(foo: String, @native("boo") bar: String) = foo + bar
internal fun expected(foo: String, boo: String) = foo + boo
fun box(): String {
val OK = "OK"
if (foo + bar != OK) return "$foo + $bar != $OK"
val actualAsString = js("actual").toString()
val expectedAsString = js("expected").toString().replace("expected", "actual")
if (actualAsString != expectedAsString) return "$actualAsString != $expectedAsString"
if (actual("asd", "12345") != "asd12345") return "${actual("asd", "12345")} != \"asd12345\""
val a = A()
val any: Any = a
val protoA = A::class.js.asDynamic().prototype
if (a.proto != any.proto || a.proto != protoA)
return "a.proto != any.proto /*${a.proto != any.proto}*/ || a.proto != A.prototype /*${a.proto != protoA}*/"
return OK
}
@@ -4,11 +4,6 @@ external class A(val v: String) {
fun m(i:Int, s:String): String = noImpl
}
external fun A.nativeExt(i:Int, s:String): String = noImpl
@JsName("nativeExt2AnotherName")
external fun A.nativeExt2(i:Int, s:String): String = noImpl
fun bar(a: A, extLambda: A.(Int, String) -> String): String = a.(extLambda)(4, "boo")
fun box(): String {
@@ -17,11 +12,5 @@ fun box(): String {
assertEquals("A.m test 4 boo", a.m(4, "boo"))
assertEquals("A.m test 4 boo", bar(a, fun A.(i, s) = (A::m)(this, i, s)))
assertEquals("nativeExt test 4 boo", a.nativeExt(4, "boo"))
assertEquals("nativeExt test 4 boo", bar(a, fun A.(i, s) = (A::nativeExt)(this, i, s)))
assertEquals("nativeExt2 test 4 boo", a.nativeExt2(4, "boo"))
assertEquals("nativeExt2 test 4 boo", bar(a, fun A.(i, s) = (A::nativeExt2)(this, i, s)))
return "OK"
}
-7
View File
@@ -16,8 +16,6 @@ fun anotherCount(vararg a: Int) = anotherParamCount(*a)
external fun test3(bar: Bar, dummy: Int, vararg args: Int): Boolean = noImpl
external fun Bar.test2(order: Int, dummy: Int, vararg args: Int): Boolean = noImpl
external class Bar(val size: Int, order: Int = 0) {
fun test(order: Int, dummy: Int, vararg args: Int): Boolean = noImpl
companion object {
@@ -34,8 +32,6 @@ fun spreadInMethodCall(size: Int, vararg args: Int) = Bar(size).test(0, 1, *args
fun spreadInObjectMethodCall(size: Int, vararg args: Int) = obj.test(size, *args)
fun spreadInMethodCallWithReceiver(size: Int, vararg args: Int) = Bar(size).test2(0, 1, *args)
fun spreadInPackageMethodCall(size: Int, vararg args: Int) = test3(Bar(size), 1, *args)
external fun testNativeVarargWithFunLit(vararg args: Int, f: (a: IntArray) -> Boolean): Boolean = noImpl
@@ -98,9 +94,6 @@ fun box(): String {
if (!(spreadInObjectMethodCall(2, 1, 2)))
return "failed when call method of object using spread operator"
if (!spreadInMethodCallWithReceiver(2, 1, 2))
return "failed when call method using spread operator with receiver"
if (!spreadInPackageMethodCall(2, 1, 2))
return "failed when call package method using spread operator"
@@ -1,17 +0,0 @@
package foo
val PACKAGE = "kotlin.modules.JS_TESTS.foo"
class A
external val Any.__proto__: String get() = noImpl
external val A.__proto__: String get() = noImpl
fun box(): String {
val a = A()
val any: Any = a
val protoA = eval("$PACKAGE.A.prototype")
if (a.__proto__ != any.__proto__ || a.__proto__ != protoA)
return "a.__proto__ != any.__proto__ /*${a.__proto__ != any.__proto__}*/ || a.__proto__ != $PACKAGE.A.prototype /*${a.__proto__ != protoA}*/"
return "OK"
}