Skip to content

Commit

Permalink
Starts calling constructor of super native types.
Browse files Browse the repository at this point in the history
This mimics the ES6 style class constructor behavior
and also a better match for Java semantics.

Change-Id: I103557142ba5a5487cbe034a4a7558d2f60c72e5
Review-Link: https://gwt-review.googlesource.com/#/c/13913/
  • Loading branch information
gkdn committed Nov 5, 2015
1 parent 3345e54 commit 38039e3
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 47 deletions.
Expand Up @@ -893,11 +893,10 @@ private JsExpression dispatchToStatic(JsExpression unnecessaryQualifier, JMethod
private JsExpression dispatchToSuper( private JsExpression dispatchToSuper(
JsExpression instance, JMethod method, List<JsExpression> args, SourceInfo sourceInfo) { JsExpression instance, JMethod method, List<JsExpression> args, SourceInfo sourceInfo) {
JsNameRef methodNameRef; JsNameRef methodNameRef;
if (method.isConstructor()) { if (method.isJsNative()) {
// We don't generate calls to super native constructors (yet). // Construct Constructor.prototype.jsname or Constructor.
if (method.isJsNative()) { methodNameRef = createJsQualifier(method.getQualifiedJsName(), sourceInfo);
return JsNullLiteral.INSTANCE; } else if (method.isConstructor()) {
}
/* /*
* Constructor calls through {@code this} and {@code super} are always dispatched statically * Constructor calls through {@code this} and {@code super} are always dispatched statically
* using the constructor function name (constructors are always defined as top level * using the constructor function name (constructors are always defined as top level
Expand All @@ -913,13 +912,8 @@ private JsExpression dispatchToSuper(
// {@link Impl.getNameOf} or calls to the native classes. // {@link Impl.getNameOf} or calls to the native classes.


JDeclaredType superClass = method.getEnclosingType(); JDeclaredType superClass = method.getEnclosingType();
if (method.isJsNative()) { JsExpression protoRef = getPrototypeQualifierViaLookup(superClass, sourceInfo);
// Construct jsPrototype.prototype.jsname methodNameRef = polymorphicNames.get(method).makeQualifiedRef(sourceInfo, protoRef);
methodNameRef = createJsQualifier(method.getQualifiedJsName(), sourceInfo);
} else {
JsExpression protoRef = getPrototypeQualifierViaLookup(superClass, sourceInfo);
methodNameRef = polymorphicNames.get(method).makeQualifiedRef(sourceInfo, protoRef);
}
} }


// <method_qualifier>.call(instance, args); // <method_qualifier>.call(instance, args);
Expand Down
45 changes: 41 additions & 4 deletions user/test/com/google/gwt/core/client/interop/JsPropertyTest.java
Expand Up @@ -15,8 +15,6 @@
*/ */
package com.google.gwt.core.client.interop; package com.google.gwt.core.client.interop;


import static com.google.gwt.core.client.ScriptInjector.TOP_WINDOW;

import static jsinterop.annotations.JsPackage.GLOBAL; import static jsinterop.annotations.JsPackage.GLOBAL;


import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JavaScriptObject;
Expand All @@ -43,15 +41,16 @@ public String getModuleName() {


@Override @Override
protected void gwtSetUp() throws Exception { protected void gwtSetUp() throws Exception {
ScriptInjector.fromString("function JsPropertyTest_MyNativeJsType() {}\n" ScriptInjector.fromString(
"function JsPropertyTest_MyNativeJsType(x) { this.x = x; this.ctorExecuted = true; }\n"
+ "JsPropertyTest_MyNativeJsType.staticX = 33;" + "JsPropertyTest_MyNativeJsType.staticX = 33;"
+ "JsPropertyTest_MyNativeJsType.answerToLife = function() { return 42;};" + "JsPropertyTest_MyNativeJsType.answerToLife = function() { return 42;};"
+ "JsPropertyTest_MyNativeJsType.prototype.sum = " + "JsPropertyTest_MyNativeJsType.prototype.sum = "
+ " function sum(bias) { return this.x + bias; };" + " function sum(bias) { return this.x + bias; };"
+ "function JsPropertyTest_MyNativeJsTypeInterface() {}\n" + "function JsPropertyTest_MyNativeJsTypeInterface() {}\n"
+ "JsPropertyTest_MyNativeJsTypeInterface.prototype.sum = " + "JsPropertyTest_MyNativeJsTypeInterface.prototype.sum = "
+ " function sum(bias) { return this.x + bias; };") + " function sum(bias) { return this.x + bias; };")
.setWindow(TOP_WINDOW).inject(); .setWindow(ScriptInjector.TOP_WINDOW).inject();
} }


@JsType @JsType
Expand Down Expand Up @@ -148,6 +147,8 @@ static class MyNativeJsType {


public static native int answerToLife(); public static native int answerToLife();


public boolean ctorExecuted;

public int x; public int x;


@JsProperty @JsProperty
Expand All @@ -166,6 +167,7 @@ public void testNativeJsType() {
assertEquals(42, MyNativeJsType.answerToLife()); assertEquals(42, MyNativeJsType.answerToLife());


MyNativeJsType obj = new MyNativeJsType(); MyNativeJsType obj = new MyNativeJsType();
assertTrue(obj.ctorExecuted);
assertTrue(isUndefined(obj.x)); assertTrue(isUndefined(obj.x));
obj.x = 72; obj.x = 72;
assertEquals(72, obj.x); assertEquals(72, obj.x);
Expand All @@ -191,6 +193,7 @@ public int sum(int bias) {


public void testNativeJsTypeSubclass() { public void testNativeJsTypeSubclass() {
MyNativeJsTypeSubclass mc = new MyNativeJsTypeSubclass(); MyNativeJsTypeSubclass mc = new MyNativeJsTypeSubclass();
assertTrue(mc.ctorExecuted);
assertEquals(143, mc.sum(1)); assertEquals(143, mc.sum(1));


mc.x = -mc.x; mc.x = -mc.x;
Expand All @@ -199,6 +202,40 @@ public void testNativeJsTypeSubclass() {
assertEquals(52, mc.getY()); assertEquals(52, mc.getY());
} }


static class MyNativeJsTypeSubclassNoOverride extends MyNativeJsType { }

// TODO(rluble): enable when the subclass is setup correctly.
public void _disabled_testNativeJsTypeSubclassNoOverride() {
MyNativeJsTypeSubclassNoOverride myNativeJsType = new MyNativeJsTypeSubclassNoOverride();
myNativeJsType.x = 12;
assertEquals(42, myNativeJsType.sum(30));
}

@JsType(isNative = true, namespace = GLOBAL, name = "JsPropertyTest_MyNativeJsType")
static class MyNativeJsTypeWithConstructor {
public MyNativeJsTypeWithConstructor(int x) { }
public boolean ctorExecuted;
public int x;
}

public void testNativeJsTypeWithConstructor() {
MyNativeJsTypeWithConstructor obj = new MyNativeJsTypeWithConstructor(12);
assertTrue(obj.ctorExecuted);
assertEquals(12, obj.x);
}

static class MyNativeJsTypeWithConstructorSubclass extends MyNativeJsTypeWithConstructor {
public MyNativeJsTypeWithConstructorSubclass(int x) {
super(x);
}
}

public void testNativeJsTypeWithConstructorSubclass() {
MyNativeJsTypeWithConstructorSubclass obj = new MyNativeJsTypeWithConstructorSubclass(12);
assertTrue(obj.ctorExecuted);
assertEquals(12, obj.x);
}

@JsType(isNative = true, namespace = GLOBAL, name = "JsPropertyTest_MyNativeJsTypeInterface") @JsType(isNative = true, namespace = GLOBAL, name = "JsPropertyTest_MyNativeJsTypeInterface")
interface MyNativeJsTypeInterface { interface MyNativeJsTypeInterface {
@JsProperty @JsProperty
Expand Down
52 changes: 21 additions & 31 deletions user/test/com/google/gwt/core/client/interop/JsTypeTest.java
Expand Up @@ -42,9 +42,7 @@ public String getModuleName() {


@Override @Override
protected void gwtSetUp() throws Exception { protected void gwtSetUp() throws Exception {
ScriptInjector.fromString("function JsTypeTest_MyNativeJsType() {}\n" ScriptInjector.fromString("function JsTypeTest_MyNativeJsType() {}")
+ "JsTypeTest_MyNativeJsType.prototype.sum = "
+ " function sum(bias) { return this.y + bias; };")
.setWindow(ScriptInjector.TOP_WINDOW) .setWindow(ScriptInjector.TOP_WINDOW)
.inject(); .inject();
} }
Expand Down Expand Up @@ -310,14 +308,29 @@ public void testInstanceOf_concreteJsType() {
assertFalse(object instanceof MyNativeJsTypeInterfaceImpl[][]); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl[][]);
} }


@JsType(isNative = true, namespace = GLOBAL, name = "JsTypeTest_MyNativeJsType")
static class MyNativeJsType { }

static class MyNativeJsTypeSubclass extends MyNativeJsType { }

static class MyNativeJsTypeSubclassWithIterator extends MyNativeJsType implements Iterable {
@Override
public Iterator iterator() {
return null;
}
}

public void testInstanceOf_extendsJsTypeWithProto() { public void testInstanceOf_extendsJsTypeWithProto() {
// Foils type tightening. // Foils type tightening.
Object object = new MyCustomHtmlButtonWithIterator(); Object object = new MyNativeJsTypeSubclassWithIterator();


assertTrue(object instanceof Object); assertTrue(object instanceof Object);
assertTrue(object instanceof HTMLElementAnotherConcreteNativeJsType); assertTrue(object instanceof MyNativeJsType);
assertTrue(object instanceof HTMLButtonElement); assertFalse(object instanceof MyNativeJsTypeSubclass);
assertTrue(object instanceof HTMLElementConcreteNativeJsType); assertTrue(object instanceof MyNativeJsTypeSubclassWithIterator);
assertFalse(object instanceof HTMLElementAnotherConcreteNativeJsType);
assertFalse(object instanceof HTMLButtonElement);
assertFalse(object instanceof HTMLElementConcreteNativeJsType);
assertTrue(object instanceof Iterable); assertTrue(object instanceof Iterable);
assertFalse(object instanceof MyNativeJsTypeInterfaceImpl); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl);
assertFalse(object instanceof ElementLikeNativeInterfaceImpl); assertFalse(object instanceof ElementLikeNativeInterfaceImpl);
Expand All @@ -328,34 +341,11 @@ public void testInstanceOf_extendsJsTypeWithProto() {
assertFalse(object instanceof MyNativeJsTypeInterfaceImpl[][]); assertFalse(object instanceof MyNativeJsTypeInterfaceImpl[][]);
} }


@JsType(isNative = true, namespace = GLOBAL, name = "JsTypeTest_MyNativeJsType")
static class MyNativeJsType {
@JsProperty
public native int getY();

@JsProperty
public native void setY(int value);

public native int sum(int bias);
}

static class MyNativeJsTypeSubclass extends MyNativeJsType {
}

// TODO(rluble): enable when the subclass is setup correctly.
public void _disabled_testNativeJsTypeSubclass() {
MyNativeJsTypeSubclass myNativeJsTypeSubclass = new MyNativeJsTypeSubclass();
myNativeJsTypeSubclass.setY(12);
assertEquals(42, myNativeJsTypeSubclass.sum(30));
assertTrue(myNativeJsTypeSubclass instanceof MyNativeJsType);
assertTrue(myNativeJsTypeSubclass instanceof MyNativeJsTypeSubclass);
}

@JsType(isNative = true, namespace = "testfoo.bar") @JsType(isNative = true, namespace = "testfoo.bar")
static class MyNamespacedNativeJsType { static class MyNamespacedNativeJsType {
} }


public void _testInstanceOf_withNameSpace() { public void testInstanceOf_withNameSpace() {
Object obj1 = createMyNamespacedJsInterface(); Object obj1 = createMyNamespacedJsInterface();
Object obj2 = createMyWrongNamespacedJsInterface(); Object obj2 = createMyWrongNamespacedJsInterface();


Expand Down

0 comments on commit 38039e3

Please sign in to comment.