JS backend: fixed ability to declare custom name for native properties and function parameters.

#KT-3643 fixed
This commit is contained in:
Zalim Bashorov
2013-10-25 15:28:18 +04:00
parent 3e205d162e
commit d6803fb5ff
7 changed files with 119 additions and 11 deletions
@@ -88,4 +88,8 @@ public final class NativeInteropTest extends SingleFileTranslationTest {
public void testKt2323() throws Exception {
fooBoxTest();
}
public void testNativePropertyWithCustomName() throws Exception {
checkFooBoxIsOk();
}
}
@@ -94,6 +94,10 @@ public final class PropertyAccessTest extends SingleFileTranslationTest {
fooBoxTest();
}
public void testNativePropertiesNameClashes() throws Exception {
checkFooBoxIsOk();
}
@Override
@NotNull
protected List<String> additionalJSFiles(@NotNull EcmaVersion ecmaVersion) {
@@ -35,14 +35,14 @@ import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.PredefinedAnnotation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*;
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.getNameForAnnotatedObject;
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.isLibraryObject;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMangledName;
@@ -298,7 +298,12 @@ public final class StaticContext {
return null;
}
String propertyName = propertyDescriptor.getName().asString();
String nameFromAnnotation = getNameForAnnotatedObject(propertyDescriptor);
if (nameFromAnnotation != null) {
return declarePropertyOrPropertyAccessorName(descriptor, nameFromAnnotation, false);
}
String propertyName = propertyDescriptor.getName().asString();
if (!isExtension(propertyDescriptor)) {
if (propertyDescriptor.getVisibility() == Visibilities.PRIVATE) {
@@ -321,17 +326,12 @@ public final class StaticContext {
Rule<JsName> predefinedObjectsHasUnobfuscatableNames = new Rule<JsName>() {
@Override
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
if (!hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
continue;
}
String name = getNameForAnnotatedObject(descriptor, annotation);
name = (name != null) ? name : descriptor.getName().asString();
return getEnclosingScope(descriptor).declareName(name);
}
String name = getNameForAnnotatedObject(descriptor);
if (name != null) return getEnclosingScope(descriptor).declareName(name);
return null;
}
};
Rule<JsName> overridingDescriptorsReferToOriginalName = new Rule<JsName>() {
@Override
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
@@ -67,6 +67,19 @@ public final class AnnotationsUtils {
return getAnnotationStringParameter(declarationDescriptor, annotation);
}
@Nullable
public static String getNameForAnnotatedObject(@NotNull DeclarationDescriptor descriptor) {
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
if (!hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
continue;
}
String name = getNameForAnnotatedObject(descriptor, annotation);
return name != null ? name : descriptor.getName().asString();
}
return null;
}
@Nullable
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor,
@NotNull PredefinedAnnotation annotation) {
@@ -0,0 +1,35 @@
package foo
val PACKAGE = "Kotlin.modules.JS_TESTS.foo"
native fun eval(e: String): Any? = noImpl
fun funToString(name: String) = eval("$PACKAGE.$name.toString()") as String
native("\"O\"") val foo: String = noImpl
native("boo") val bar: String = noImpl
class A
native("__proto__") val Any.proto: String = noImpl
native("__proto__") val A.proto: String = noImpl
fun actual(foo: String, native("boo") bar: String) = foo + bar
fun expected(foo: String, boo: String) = foo + boo
fun box(): String {
val OK = "OK"
if (foo + bar != OK) return "$foo + $bar != $OK"
val actualAsString = funToString("actual")
val expectedAsString = funToString("expected")
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 = 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
}
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2013 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.
*/
var boo = "K";
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2013 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 foo
val PACKAGE = "Kotlin.modules.JS_TESTS.foo"
native fun eval(e: String): Any? = noImpl
class A
native val Any.__proto__: String = noImpl
native val A.__proto__: String = 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"
}