JS backend: fixed accessing to nested native "elements".
#KT-4298 fixed
This commit is contained in:
@@ -116,4 +116,8 @@ public final class NativeInteropTest extends SingleFileTranslationTest {
|
||||
public void testPassTopLevelFunctionFromNative() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testNestedElements() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -170,13 +170,10 @@ object ConstructorCallCase : FunctionCallCase {
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
||||
if (isNative()) {
|
||||
return JsNew(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
val fqName = context.getQualifiedReference(callableDescriptor)
|
||||
|
||||
val functionRef = if (isNative()) fqName else context.aliasOrValue(callableDescriptor) { fqName }
|
||||
|
||||
val functionRef = context.aliasOrValue(callableDescriptor) {
|
||||
context.getQualifiedReference(it)
|
||||
}
|
||||
return JsNew(functionRef, argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
}
|
||||
@@ -209,4 +206,4 @@ fun FunctionCallInfo.translateFunctionCall(): JsExpression {
|
||||
else ->
|
||||
DefaultFunctionCallCase.translate(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,14 +32,12 @@ import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||
import org.jetbrains.k2js.translate.context.generator.Generator;
|
||||
import org.jetbrains.k2js.translate.context.generator.Rule;
|
||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.getNameForAnnotatedObjectWithOverrides;
|
||||
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.isLibraryObject;
|
||||
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMangledName;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getSuggestedName;
|
||||
@@ -436,6 +434,8 @@ public final class StaticContext {
|
||||
Rule<JsNameRef> packageLevelDeclarationsHaveEnclosingPackagesNamesAsQualifier = new Rule<JsNameRef>() {
|
||||
@Override
|
||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (isNativeObject(descriptor)) return null;
|
||||
|
||||
DeclarationDescriptor containingDescriptor = getContainingDeclaration(descriptor);
|
||||
if (!(containingDescriptor instanceof PackageFragmentDescriptor)) {
|
||||
return null;
|
||||
@@ -489,10 +489,25 @@ public final class StaticContext {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Rule<JsNameRef> nativeObjectsHaveNativePartOfFullQualifier = new Rule<JsNameRef>() {
|
||||
@Override
|
||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof ConstructorDescriptor || !isNativeObject(descriptor)) return null;
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration != null && isNativeObject(containingDeclaration)) {
|
||||
return getQualifiedReference(containingDeclaration);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
addRule(libraryObjectsHaveKotlinQualifier);
|
||||
addRule(constructorHaveTheSameQualifierAsTheClass);
|
||||
addRule(standardObjectsHaveKotlinQualifier);
|
||||
addRule(packageLevelDeclarationsHaveEnclosingPackagesNamesAsQualifier);
|
||||
addRule(nativeObjectsHaveNativePartOfFullQualifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,18 +523,7 @@ public final class StaticContext {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
//TODO: hack! it seems like needed, only for Inheritance from native class
|
||||
Rule<Boolean> nativeObjectsHaveNoQualifiers = new Rule<Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (!AnnotationsUtils.isNativeObject(descriptor)) {
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
addRule(propertiesInClassHaveNoQualifiers);
|
||||
addRule(nativeObjectsHaveNoQualifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +143,6 @@ public final class AnnotationsUtils {
|
||||
return true;
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
return containingClass != null && getAnnotationByName(containingClass, fqn) != null;
|
||||
return containingClass != null && hasAnnotationOrInsideAnnotatedClass(containingClass, fqn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
package foo
|
||||
|
||||
fun box(): String {
|
||||
// in object
|
||||
|
||||
assertEquals("Object.Object.a", Object.Object.a)
|
||||
assertEquals("Object.Object.b", Object.Object.b)
|
||||
assertEquals(123, Object.Object.test())
|
||||
|
||||
assertEquals("Object.Object.Class().a", Object.Object.Class("Object.Object.Class().a").a)
|
||||
assertEquals("Object.Object.Class().b", Object.Object.Class("something").b)
|
||||
assertEquals(42, Object.Object.Class("something").test())
|
||||
assertEquals("Object.Object.Class.a", Object.Object.Class.a)
|
||||
assertEquals("Object.Object.Class.b", Object.Object.Class.b)
|
||||
assertEquals(142, Object.Object.Class.test())
|
||||
|
||||
assertEquals("Object.Class().a", Object.Class("Object.Class().a").a)
|
||||
assertEquals("Object.Class().b", Object.Class("something").b)
|
||||
assertEquals(42, Object.Class("something").test())
|
||||
assertEquals("Object.Class.a", Object.Class.a)
|
||||
assertEquals("Object.Class.b", Object.Class.b)
|
||||
assertEquals(142, Object.Class.test())
|
||||
|
||||
assertEquals("Object.Trait.a", Object.Trait.a)
|
||||
assertEquals("Object.Trait.b", Object.Trait.b)
|
||||
assertEquals(324, Object.Trait.test())
|
||||
|
||||
assertEquals("Object.a.a", Object.a.a)
|
||||
assertEquals("Object.a.b", Object.a.b)
|
||||
assertEquals(34, Object.a.test())
|
||||
assertEquals("Object.b", Object.b)
|
||||
assertEquals(23, Object.test())
|
||||
|
||||
// in class
|
||||
|
||||
assertEquals("Class.Object.a", Class.Object.a)
|
||||
assertEquals("Class.Object.b", Class.Object.b)
|
||||
assertEquals(55, Class.Object.test())
|
||||
|
||||
assertEquals("Class.Class().a", Class.Class("Class.Class().a").a)
|
||||
assertEquals("Class.Class().b", Class.Class("something").b)
|
||||
assertEquals(66, Class.Class("something").test())
|
||||
assertEquals("Class.Class.a", Class.Class.a)
|
||||
assertEquals("Class.Class.b", Class.Class.b)
|
||||
assertEquals(88, Class.Class.test())
|
||||
|
||||
//TODO inner class
|
||||
// assertEquals("Class.InnerClass().a", Class().InnerClass("Class.InnerClass().a").a)
|
||||
// assertEquals("Class.InnerClass().b", Class().InnerClass("something").b)
|
||||
// assertEquals(66, Class().InnerClass("something").test())
|
||||
|
||||
assertEquals("Class.Trait.a", Class.Trait.a)
|
||||
assertEquals("Class.Trait.b", Class.Trait.b)
|
||||
assertEquals(55, Class.Trait.test())
|
||||
|
||||
assertEquals("Class.a.a", Class.a.a)
|
||||
assertEquals("Class.a.b", Class.a.b)
|
||||
assertEquals(22, Class.a.test())
|
||||
assertEquals("Class.b", Class.b)
|
||||
assertEquals(77, Class.test())
|
||||
|
||||
// in trit
|
||||
|
||||
assertEquals("Trait.Object.a", Trait.Object.a)
|
||||
assertEquals("Trait.Object.b", Trait.Object.b)
|
||||
assertEquals(90, Trait.Object.test())
|
||||
|
||||
assertEquals("Trait.Class().a", Trait.Class("Trait.Class().a").a)
|
||||
assertEquals("Trait.Class().b", Trait.Class("something").b)
|
||||
assertEquals(66, Trait.Class("something").test())
|
||||
assertEquals("Trait.Class.a", Trait.Class.a)
|
||||
assertEquals("Trait.Class.b", Trait.Class.b)
|
||||
assertEquals(88, Trait.Class.test())
|
||||
|
||||
assertEquals("Trait.Trait.a", Trait.Trait.a)
|
||||
assertEquals("Trait.Trait.b", Trait.Trait.b)
|
||||
assertEquals(55, Trait.Trait.test())
|
||||
|
||||
assertEquals("Trait.a.a", Trait.a.a)
|
||||
assertEquals("Trait.a.b", Trait.a.b)
|
||||
assertEquals(22, Trait.a.test())
|
||||
assertEquals("Trait.b", Trait.b)
|
||||
assertEquals(277, Trait.test())
|
||||
|
||||
return "OK";
|
||||
}
|
||||
|
||||
native
|
||||
object Object {
|
||||
object Object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
|
||||
native("AnotherClass")
|
||||
class Class(val a: String) {
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
|
||||
class object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Class(val a: String) {
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
|
||||
class object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
val a: String
|
||||
var b: String
|
||||
fun test(): Int = noImpl
|
||||
|
||||
class object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
|
||||
val a: Trait = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
|
||||
native("SomeClass")
|
||||
class Class {
|
||||
object Object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
|
||||
class Class(val a: String) {
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
|
||||
class object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
|
||||
inner class InnerClass(val a: String) {
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
val a: String
|
||||
var b: String
|
||||
fun test(): Int = noImpl
|
||||
|
||||
class object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
|
||||
class object {
|
||||
native("aaa")
|
||||
val a: Trait = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
|
||||
native
|
||||
trait Trait {
|
||||
native("SomeObject")
|
||||
object Object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
|
||||
class Class(val a: String) {
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
|
||||
class object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
|
||||
native("SomeTrait")
|
||||
trait Trait {
|
||||
val a: String
|
||||
var b: String
|
||||
fun test(): Int = noImpl
|
||||
|
||||
class object {
|
||||
val a: String = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
|
||||
class object {
|
||||
val a: Trait = noImpl
|
||||
var b: String = noImpl
|
||||
fun test(): Int = noImpl
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
var Object = createTestObject("Object", 23);
|
||||
extend(Object, {
|
||||
Object: extend(createTestObject("Object.Object", 123), { AnotherClass : createTestClass("Object.Object.Class", 42, 142) }),
|
||||
Class: createTestClass("Object.Class", 42, 142),
|
||||
Trait : createTestObject("Object.Trait", 324),
|
||||
a: createTestObject("Object.a", 34)
|
||||
});
|
||||
|
||||
var SomeClass = function () {};
|
||||
extend(SomeClass, createTestObject("Class", 77));
|
||||
extend(SomeClass, {
|
||||
Object: createTestObject("Class.Object", 55),
|
||||
Class: createTestClass("Class.Class", 66, 88),
|
||||
InnerClass: createTestInnerClass("Class.InnerClass", 57),
|
||||
Trait: createTestObject("Class.Trait", 55),
|
||||
aaa: createTestObject("Class.a", 22)
|
||||
});
|
||||
|
||||
var Trait = createTestObject("Trait", 277);
|
||||
extend(Trait, {
|
||||
SomeObject: createTestObject("Trait.Object", 90),
|
||||
Class: createTestClass("Trait.Class", 66, 88),
|
||||
SomeTrait: createTestObject("Trait.Trait", 55),
|
||||
a: createTestObject("Trait.a", 22)
|
||||
});
|
||||
|
||||
// Helpers
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) {
|
||||
if (source.hasOwnProperty(property)) {
|
||||
destination[property] = source[property];
|
||||
}
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
function createTestClass(fqName, memberFunResult, staticFunResult) {
|
||||
function Class(a) {
|
||||
this.a = a;
|
||||
this.b = fqName + "().b"
|
||||
}
|
||||
|
||||
Class.prototype.test = function () { return memberFunResult };
|
||||
|
||||
extend(Class, createTestObject(fqName, staticFunResult));
|
||||
|
||||
return Class;
|
||||
}
|
||||
|
||||
function createTestInnerClass(fqName, memberFunResult) {
|
||||
function Class(parent, a) {
|
||||
this.a = a;
|
||||
this.b = fqName + "().b"
|
||||
}
|
||||
|
||||
Class.prototype.test = function () { return memberFunResult };
|
||||
}
|
||||
|
||||
function createTestObject(fqName, funResult) {
|
||||
return {
|
||||
a: fqName + ".a",
|
||||
b: fqName + ".b",
|
||||
test: function () { return funResult }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user