KT-2752: add draft implementation of JsName annotation. Fix some tests using the annotation
This commit is contained in:
@@ -23,7 +23,8 @@ enum class PredefinedAnnotation(fqName: String) {
|
||||
NATIVE("kotlin.js.native"),
|
||||
NATIVE_INVOKE("kotlin.js.nativeInvoke"),
|
||||
NATIVE_GETTER("kotlin.js.nativeGetter"),
|
||||
NATIVE_SETTER("kotlin.js.nativeSetter");
|
||||
NATIVE_SETTER("kotlin.js.nativeSetter"),
|
||||
JS_NAME("kotlin.js.JsName");
|
||||
|
||||
val fqName: FqName = FqName(fqName)
|
||||
|
||||
|
||||
@@ -135,11 +135,12 @@ class FQNGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
return if (needsStableMangling(resolvedDescriptor)) {
|
||||
Pair(getStableMangledName(baseName, getArgumentTypesAsString(resolvedDescriptor)), true)
|
||||
}
|
||||
else {
|
||||
Pair(baseName, false)
|
||||
val explicitName = getJsName(descriptor)
|
||||
return when {
|
||||
explicitName != null -> Pair(explicitName, true)
|
||||
needsStableMangling(resolvedDescriptor) ->
|
||||
Pair(getStableMangledName(baseName, getArgumentTypesAsString(resolvedDescriptor)), true)
|
||||
else -> Pair(baseName, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,8 +168,7 @@ class FQNGenerator {
|
||||
}
|
||||
|
||||
private fun getStableMangledName(suggestedName: String, forCalculateId: String): String {
|
||||
val absHashCode = Math.abs(forCalculateId.hashCode())
|
||||
val suffix = if (absHashCode == 0) "" else "_" + Integer.toString(absHashCode, Character.MAX_RADIX) + "$"
|
||||
val suffix = if (forCalculateId.isEmpty()) "" else "_${mangledId(forCalculateId)}\$"
|
||||
return suggestedName + suffix
|
||||
}
|
||||
|
||||
@@ -187,7 +187,9 @@ class FQNGenerator {
|
||||
return when (containingDeclaration) {
|
||||
is PackageFragmentDescriptor -> descriptor.visibility.isPublicAPI
|
||||
is ClassDescriptor -> {
|
||||
if (descriptor.modality == Modality.OPEN || descriptor.modality == Modality.ABSTRACT) return true
|
||||
if (descriptor.modality == Modality.OPEN || descriptor.modality == Modality.ABSTRACT) {
|
||||
return descriptor.visibility.isPublicAPI
|
||||
}
|
||||
|
||||
// valueOf() is created in the library with a mangled name for every enum class
|
||||
if (descriptor is FunctionDescriptor && descriptor.isEnumValueOfMethod()) return true
|
||||
@@ -210,4 +212,11 @@ class FQNGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic fun mangledId(forCalculateId: String): String {
|
||||
val absHashCode = Math.abs(forCalculateId.hashCode())
|
||||
return if (absHashCode != 0) Integer.toString(absHashCode, Character.MAX_RADIX) else ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,19 @@ public final class AnnotationsUtils {
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.LIBRARY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getJsName(@NotNull DeclarationDescriptor descriptor) {
|
||||
AnnotationDescriptor annotation = getAnnotationByName(descriptor, PredefinedAnnotation.JS_NAME.getFqName());
|
||||
if (annotation == null) return null;
|
||||
|
||||
ConstantValue<?> value = annotation.getAllValueArguments().values().iterator().next();
|
||||
assert value != null : "JsName annotation should always declare string parameter";
|
||||
|
||||
Object result = value.getValue();
|
||||
assert result instanceof String : "Parameter of JsName annotation should be string";
|
||||
return (String) result;
|
||||
}
|
||||
|
||||
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
|
||||
if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
|
||||
|
||||
@@ -46,4 +46,8 @@ public annotation class enumerable()
|
||||
@native
|
||||
@Target(CLASS)
|
||||
@Deprecated("Do not use this annotation: it is for internal use only")
|
||||
public annotation class marker
|
||||
public annotation class marker
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@Target(CLASS, FUNCTION, PROPERTY, CONSTRUCTOR)
|
||||
annotation class JsName(val name: String)
|
||||
@@ -45,6 +45,7 @@ val Element?.elements: List<Element>
|
||||
get() = this?.elements() ?: emptyList()
|
||||
|
||||
@Deprecated("Use non-nullable receiver version elements()", ReplaceWith("this?.elements(localName) ?: emptyList()"))
|
||||
@JsName("deprecated_elements")
|
||||
fun Element?.elements(localName: String): List<Element> = this?.elements(localName) ?: emptyList()
|
||||
|
||||
/** Returns all the descendant elements given the local element name */
|
||||
@@ -53,11 +54,13 @@ fun Element.elements(localName: String = "*"): List<Element> {
|
||||
}
|
||||
|
||||
/** Returns all the descendant elements given the local element name */
|
||||
@JsName("deprecated_document_elements")
|
||||
fun Document?.elements(localName: String = "*"): List<Element> {
|
||||
return this?.getElementsByTagName(localName)?.asElementList() ?: emptyList()
|
||||
}
|
||||
|
||||
@Deprecated("Use non-nullable elements function instead", ReplaceWith("this?.elements(namespaceUri, localName) ?: emptyList()"))
|
||||
@JsName("deprecated_elements_2")
|
||||
fun Element?.elements(namespaceUri: String, localName: String): List<Element> = this?.elements(namespaceUri, localName) ?: emptyList()
|
||||
|
||||
/** Returns all the descendant elements given the namespace URI and local element name */
|
||||
@@ -71,6 +74,7 @@ fun Document?.elements(namespaceUri: String, localName: String): List<Element> {
|
||||
}
|
||||
|
||||
@Deprecated("Use non-null function instead with elvis", ReplaceWith("this?.asList() ?: emptyList()"))
|
||||
@JsName("deprecated_asList")
|
||||
fun NodeList?.asList(): List<Node> = this?.asList() ?: emptyList()
|
||||
|
||||
fun NodeList.asList(): List<Node> = NodeListAsList(this)
|
||||
|
||||
@@ -17,48 +17,48 @@
|
||||
package kotlin.js.internal
|
||||
|
||||
private object DoubleCompanionObject {
|
||||
val MIN_VALUE: Double = js("Number.MIN_VALUE")
|
||||
val MAX_VALUE: Double = js("Number.MAX_VALUE")
|
||||
val POSITIVE_INFINITY: Double = js("Number.POSITIVE_INFINITY")
|
||||
val NEGATIVE_INFINITY: Double = js("Number.NEGATIVE_INFINITY")
|
||||
val NaN: Double = js("Number.NaN")
|
||||
@JsName("MIN_VALUE") val MIN_VALUE: Double = js("Number.MIN_VALUE")
|
||||
@JsName("MAX_VALUE") val MAX_VALUE: Double = js("Number.MAX_VALUE")
|
||||
@JsName("POSITIVE_INFINITY") val POSITIVE_INFINITY: Double = js("Number.POSITIVE_INFINITY")
|
||||
@JsName("NEGATIVE_INFINITY") val NEGATIVE_INFINITY: Double = js("Number.NEGATIVE_INFINITY")
|
||||
@JsName("NaN") val NaN: Double = js("Number.NaN")
|
||||
}
|
||||
|
||||
private object FloatCompanionObject {
|
||||
val MIN_VALUE: Float = js("Number.MIN_VALUE")
|
||||
val MAX_VALUE: Float = js("Number.MAX_VALUE")
|
||||
val POSITIVE_INFINITY: Float = js("Number.POSITIVE_INFINITY")
|
||||
val NEGATIVE_INFINITY: Float = js("Number.NEGATIVE_INFINITY")
|
||||
val NaN: Float = js("Number.NaN")
|
||||
@JsName("MIN_VALUE") val MIN_VALUE: Float = js("Number.MIN_VALUE")
|
||||
@JsName("MAX_VALUE") val MAX_VALUE: Float = js("Number.MAX_VALUE")
|
||||
@JsName("POSITIVE_INFINITY") val POSITIVE_INFINITY: Float = js("Number.POSITIVE_INFINITY")
|
||||
@JsName("NEGATIVE_INFINITY") val NEGATIVE_INFINITY: Float = js("Number.NEGATIVE_INFINITY")
|
||||
@JsName("NaN") val NaN: Float = js("Number.NaN")
|
||||
}
|
||||
|
||||
private object IntCompanionObject {
|
||||
val MIN_VALUE: Int = -2147483647 - 1
|
||||
val MAX_VALUE: Int = 2147483647
|
||||
@JsName("MIN_VALUE") val MIN_VALUE: Int = -2147483647 - 1
|
||||
@JsName("MAX_VALUE") val MAX_VALUE: Int = 2147483647
|
||||
}
|
||||
|
||||
private object LongCompanionObject {
|
||||
val MIN_VALUE: Long = js("Kotlin.Long.MIN_VALUE")
|
||||
val MAX_VALUE: Long = js("Kotlin.Long.MAX_VALUE")
|
||||
@JsName("MIN_VALUE") val MIN_VALUE: Long = js("Kotlin.Long.MIN_VALUE")
|
||||
@JsName("MAX_VALUE") val MAX_VALUE: Long = js("Kotlin.Long.MAX_VALUE")
|
||||
}
|
||||
|
||||
private object ShortCompanionObject {
|
||||
val MIN_VALUE: Short = -32768
|
||||
val MAX_VALUE: Short = 32767
|
||||
@JsName("MIN_VALUE") val MIN_VALUE: Short = -32768
|
||||
@JsName("MAX_VALUE") val MAX_VALUE: Short = 32767
|
||||
}
|
||||
|
||||
private object ByteCompanionObject {
|
||||
val MIN_VALUE: Byte = -128
|
||||
val MAX_VALUE: Byte = 127
|
||||
@JsName("MIN_VALUE") val MIN_VALUE: Byte = -128
|
||||
@JsName("MAX_VALUE") val MAX_VALUE: Byte = 127
|
||||
}
|
||||
|
||||
private object CharCompanionObject {
|
||||
public const val MIN_HIGH_SURROGATE: Char = '\uD800'
|
||||
public const val MAX_HIGH_SURROGATE: Char = '\uDBFF'
|
||||
public const val MIN_LOW_SURROGATE: Char = '\uDC00'
|
||||
public const val MAX_LOW_SURROGATE: Char = '\uDFFF'
|
||||
public const val MIN_SURROGATE: Char = MIN_HIGH_SURROGATE
|
||||
public const val MAX_SURROGATE: Char = MAX_LOW_SURROGATE
|
||||
@JsName("MIN_HIGH_SURROGATE") public const val MIN_HIGH_SURROGATE: Char = '\uD800'
|
||||
@JsName("MAX_HIGH_SURROGATE") public const val MAX_HIGH_SURROGATE: Char = '\uDBFF'
|
||||
@JsName("MIN_LOW_SURROGATE") public const val MIN_LOW_SURROGATE: Char = '\uDC00'
|
||||
@JsName("MAX_LOW_SURROGATE") public const val MAX_LOW_SURROGATE: Char = '\uDFFF'
|
||||
@JsName("MIN_SURROGATE") public const val MIN_SURROGATE: Char = MIN_HIGH_SURROGATE
|
||||
@JsName("MAX_SURROGATE") public const val MAX_SURROGATE: Char = MAX_LOW_SURROGATE
|
||||
}
|
||||
|
||||
private object StringCompanionObject {}
|
||||
|
||||
@@ -56,12 +56,12 @@ val mixed_b = { mixed_boo() + mixed_boo(1) + mixed_boo("str") + mixed_boo("str",
|
||||
|
||||
|
||||
class TestInternal {
|
||||
fun foo(): Int = 1
|
||||
fun foo(i: Int): Int = 2
|
||||
@JsName("foo") internal fun foo(): Int = 1
|
||||
@JsName("foo_2") internal fun foo(i: Int): Int = 2
|
||||
|
||||
fun boo(i: Int): Int = 2
|
||||
fun boo(s: String): Int = 3
|
||||
fun boo(): Int = 1
|
||||
@JsName("boo_2") internal fun boo(i: Int): Int = 2
|
||||
@JsName("boo_3") internal fun boo(s: String): Int = 3
|
||||
@JsName("boo") internal fun boo(): Int = 1
|
||||
}
|
||||
|
||||
val internal_in_class_f = { TestInternal().foo() + TestInternal().foo(1) }
|
||||
@@ -128,25 +128,15 @@ val public_ext_f: A.() -> Int = { -> this.foo() + this.foo }
|
||||
val public_ext_b: A.() -> Int = { -> this.boo() + this.boo }
|
||||
|
||||
interface TestPublicInTrait {
|
||||
public fun foo(): Int = 2
|
||||
public val foo: Int
|
||||
public val boo: Int
|
||||
public fun boo(): Int = 2
|
||||
@JsName("foo") fun foo(): Int = 2
|
||||
@JsName("fooProp") val foo: Int
|
||||
@JsName("booProp") val boo: Int
|
||||
@JsName("boo") fun boo(): Int = 2
|
||||
}
|
||||
|
||||
val public_in_trait_f = { obj: TestPublicInTrait -> obj.foo() + obj.foo }
|
||||
val public_in_trait_b = { obj: TestPublicInTrait -> obj.boo() + obj.boo }
|
||||
|
||||
interface TestInternalInTrait {
|
||||
fun foo(): Int = 2
|
||||
val foo: Int
|
||||
val boo: Int
|
||||
fun boo(): Int = 2
|
||||
}
|
||||
|
||||
val internal_in_trait_f = { obj: TestInternalInTrait -> obj.foo() + obj.foo }
|
||||
val internal_in_trait_b = { obj: TestInternalInTrait -> obj.boo() + obj.boo }
|
||||
|
||||
//Testing
|
||||
|
||||
fun test(testName: String, ff: Any, fb: Any) {
|
||||
@@ -169,7 +159,6 @@ fun box(): String {
|
||||
|
||||
test("public_ext_prop", public_ext_f, public_ext_b)
|
||||
test("public_in_trait", public_in_trait_f, public_in_trait_b)
|
||||
test("internal_in_trait", internal_in_trait_f, internal_in_trait_b)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ class TrafficLight(override var pos: Vector, val direction: String, val startCol
|
||||
var timer = Timer(Vector(pos.x + 6, pos.y + 12))
|
||||
var currentColor = startColor;
|
||||
var isForceColorChange = false
|
||||
var changeColorForward = (startColor == "red")
|
||||
private var changeColorForward = (startColor == "red")
|
||||
|
||||
init {
|
||||
list.add(TrafficLightItem(v(pos.x, pos.y), PATH_TO_IMAGES + "red_color.png"))
|
||||
|
||||
Reference in New Issue
Block a user