Introduces native JsType.
This CL introduces native JsType based on prototype attribute
which will later be replaced by isNative attribute.
The patch doesn't handle static JsMethods/JsProperties, a follow
up patch will fix that.
Change-Id: Ibe5bf89978bb063ad86b003fe296acd02a362ff4
Review-Link: https://gwt-review.googlesource.com/#/c/13520/
diff --git a/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java b/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java
index 9236164..58fe3c4 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java
@@ -18,7 +18,6 @@
import com.google.gwt.dev.jdt.SafeASTVisitor;
import com.google.gwt.dev.util.InstalledHelpInfo;
import com.google.gwt.dev.util.collect.Stack;
-import com.google.gwt.thirdparty.guava.common.base.Strings;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
@@ -29,7 +28,6 @@
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
@@ -67,18 +65,17 @@
"@JsExport and @JsNoExport is not allowed at the same time.";
public static final String ERR_JSEXPORT_ON_ENUMERATION =
"@JsExport is not allowed on individual enumerations";
- public static final String ERR_MUST_EXTEND_MAGIC_PROTOTYPE_CLASS =
- "Classes implementing @JsType with a prototype must extend that interface's Prototype class";
- public static final String ERR_CLASS_EXTENDS_MAGIC_PROTOTYPE_BUT_NO_PROTOTYPE_ATTRIBUTE =
- "Classes implementing a @JsType without a prototype should not extend the Prototype class";
public static final String ERR_CONSTRUCTOR_WITH_PARAMETERS =
"Constructors must not have parameters in subclasses of JavaScriptObject";
- public static final String ERR_INSTANCE_FIELD = "Instance fields cannot be used in subclasses of JavaScriptObject";
+ public static final String ERR_INSTANCE_FIELD =
+ "Instance fields cannot be used in subclasses of JavaScriptObject";
public static final String ERR_INSTANCE_METHOD_NONFINAL =
"Instance methods must be 'final' in non-final subclasses of JavaScriptObject";
- public static final String ERR_IS_NONSTATIC_NESTED = "Nested classes must be 'static' if they extend JavaScriptObject";
+ public static final String ERR_IS_NONSTATIC_NESTED =
+ "Nested classes must be 'static' if they extend JavaScriptObject";
public static final String ERR_NEW_JSO =
- "'new' cannot be used to create instances of JavaScriptObject subclasses; instances must originate in JavaScript";
+ "'new' cannot be used to create instances of JavaScriptObject subclasses; "
+ + "instances must originate in JavaScript";
public static final String ERR_NONEMPTY_CONSTRUCTOR =
"Constructors must be totally empty in subclasses of JavaScriptObject";
public static final String ERR_NONPROTECTED_CONSTRUCTOR =
@@ -86,13 +83,10 @@
public static final String ERR_OVERRIDDEN_METHOD =
"Methods cannot be overridden in JavaScriptObject subclasses";
public static final String JSO_CLASS = "com/google/gwt/core/client/JavaScriptObject";
- public static final String ERR_FORGOT_TO_MAKE_PROTOTYPE_IMPL_JSTYPE = "@JsType subtype extends magic _Prototype class, but _Prototype class doesn't implement JsType";
- public static final String ERR_JS_TYPE_WITH_PROTOTYPE_SET_NOT_ALLOWED_ON_CLASS_TYPES = "@JsType with prototype set not allowed on class types";
public static final String ERR_JS_FUNCTION_ONLY_ALLOWED_ON_FUNCTIONAL_INTERFACE =
"@JsFunction is only allowed on functional interface";
public static final String ERR_JS_FUNCTION_CANNOT_HAVE_DEFAULT_METHODS =
"JsFunction cannot have default methods";
- static boolean LINT_MODE = false;
private enum ClassState {
NORMAL, JSO
@@ -247,18 +241,6 @@
}
}
- private void checkJsType(TypeDeclaration type, TypeBinding typeBinding) {
- ReferenceBinding binding = (ReferenceBinding) typeBinding;
- if (binding.isClass()) {
- AnnotationBinding jsinterfaceAnn = JdtUtil.getAnnotation(typeBinding,
- JsInteropUtil.JSTYPE_CLASS);
- String jsPrototype = JdtUtil.getAnnotationParameterString(jsinterfaceAnn, "prototype");
- if (jsPrototype != null && !"".equals(jsPrototype)) {
- errorOn(type, ERR_JS_TYPE_WITH_PROTOTYPE_SET_NOT_ALLOWED_ON_CLASS_TYPES);
- }
- }
- }
-
private void checkJsExport(MethodBinding mb) {
if (JdtUtil.getAnnotation(mb, JsInteropUtil.JSEXPORT_CLASS) != null) {
boolean isStatic = mb.isConstructor() || mb.isStatic();
@@ -294,14 +276,6 @@
private ClassState checkType(TypeDeclaration type) {
SourceTypeBinding binding = type.binding;
checkJsFunction(type, binding);
- if (isJsType(type.binding)) {
- checkJsType(type, type.binding);
- return ClassState.NORMAL;
- }
-
- if (checkClassImplementingJsType(type)) {
- return ClassState.NORMAL;
- }
if (!isJsoSubclass(binding)) {
return ClassState.NORMAL;
@@ -332,91 +306,6 @@
return ClassState.JSO;
}
- private boolean checkClassImplementingJsType(TypeDeclaration type) {
- ReferenceBinding jsInterface = findNearestJsTypeRecursive(type.binding);
- if (jsInterface == null) {
- return false;
- }
-
- AnnotationBinding jsinterfaceAnn = JdtUtil.getAnnotation(jsInterface,
- JsInteropUtil.JSTYPE_CLASS);
- String jsPrototype = JdtUtil.getAnnotationParameterString(jsinterfaceAnn, "prototype");
- boolean shouldExtend = !Strings.isNullOrEmpty(jsPrototype);
- checkClassExtendsMagicPrototype(type, jsInterface, shouldExtend);
-
- // TODO(cromwellian) add multiple-inheritance checks when ambiguity in spec is resolved
- return true;
- }
-
- private void checkClassExtendsMagicPrototype(TypeDeclaration type, ReferenceBinding jsInterface,
- boolean shouldExtend) {
- ReferenceBinding superClass = type.binding.superclass();
- // if type is the _Prototype stub (implements JsType) exit
- if (isMagicPrototype(type.binding, jsInterface)) {
- return;
- } else if (isMagicPrototypeStub(type)) {
- errorOn(type, ERR_FORGOT_TO_MAKE_PROTOTYPE_IMPL_JSTYPE);
- }
-
- if (shouldExtend) {
- // super class should be SomeInterface.Prototype, so enclosing type should match the jsInterface
- if (LINT_MODE && (superClass == null || !isMagicPrototype(superClass, jsInterface))) {
- errorOn(type, ERR_MUST_EXTEND_MAGIC_PROTOTYPE_CLASS);
- }
- } else {
- if (superClass != null && isMagicPrototype(superClass, jsInterface)) {
- errorOn(type, ERR_CLASS_EXTENDS_MAGIC_PROTOTYPE_BUT_NO_PROTOTYPE_ATTRIBUTE);
- }
- }
- }
-
- // Roughly parallels JProgram.isJsTypePrototype()
- private boolean isMagicPrototype(ReferenceBinding type, ReferenceBinding jsInterface) {
- if (isMagicPrototypeStub(type)) {
- for (ReferenceBinding intf : type.superInterfaces()) {
- if (intf == jsInterface) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean isMagicPrototypeStub(TypeDeclaration type) {
- return isMagicPrototypeStub(type.binding);
- }
-
- private boolean isMagicPrototypeStub(ReferenceBinding binding) {
- return JdtUtil.getAnnotation(binding, JsInteropUtil.JSTYPEPROTOTYPE_CLASS) != null;
- }
-
- /**
- * Walks up chain of interfaces and superinterfaces to find the first one marked with @JsType.
- */
- private ReferenceBinding findNearestJsType(ReferenceBinding binding) {
- if (isJsType(binding)) {
- return binding;
- }
-
- for (ReferenceBinding intb : binding.superInterfaces()) {
- ReferenceBinding checkSuperInt = findNearestJsType(intb);
- if (checkSuperInt != null) {
- return checkSuperInt;
- }
- }
- return null;
- }
-
- private ReferenceBinding findNearestJsTypeRecursive(ReferenceBinding binding) {
- ReferenceBinding nearest = findNearestJsType(binding);
- if (nearest != null) {
- return nearest;
- } else if (binding.superclass() != null) {
- return findNearestJsTypeRecursive(binding.superclass());
- }
- return null;
- }
-
private boolean areAllEnclosingClassesPublic() {
for (SourceTypeBinding typeBinding : typeBindingStack) {
if (!typeBinding.isPublic()) {
@@ -470,19 +359,6 @@
}
/**
- * Returns the first JsType annotation encountered traversing the type hierarchy upwards from the type.
- */
- private boolean isJsType(TypeBinding typeBinding) {
-
- if (!(typeBinding instanceof ReferenceBinding) || !(typeBinding instanceof SourceTypeBinding)) {
- return false;
- }
-
- AnnotationBinding jsInterface = JdtUtil.getAnnotation(typeBinding, JsInteropUtil.JSTYPE_CLASS);
- return jsInterface != null;
- }
-
- /**
* Returns {@code true} if {@code typeBinding} is a subtype of
* {@code JavaScriptObject}, but not {@code JavaScriptObject} itself.
*/
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsInteropUtil.java b/dev/core/src/com/google/gwt/dev/javac/JsInteropUtil.java
index 8eb6492..455eed5 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsInteropUtil.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsInteropUtil.java
@@ -24,7 +24,6 @@
import com.google.gwt.thirdparty.guava.common.base.Strings;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import java.beans.Introspector;
@@ -40,8 +39,6 @@
public static final String JSNOEXPORT_CLASS = "com.google.gwt.core.client.js.JsNoExport";
public static final String JSPROPERTY_CLASS = "com.google.gwt.core.client.js.JsProperty";
public static final String JSTYPE_CLASS = "com.google.gwt.core.client.js.JsType";
- public static final String JSTYPEPROTOTYPE_CLASS =
- "com.google.gwt.core.client.js.impl.PrototypeOfJsType";
public static void maybeSetJsInteropProperties(JDeclaredType type, Annotation... annotations) {
AnnotationBinding jsType = JdtUtil.getAnnotation(annotations, JSTYPE_CLASS);
@@ -106,10 +103,6 @@
return member instanceof JConstructor ? "" : member.getName();
}
- public static boolean isJsPrototypeFlag(TypeDeclaration x) {
- return JdtUtil.getAnnotation(x.annotations, JSTYPEPROTOTYPE_CLASS) != null;
- }
-
private static String maybeGetJsNamespace(Annotation[] annotations) {
AnnotationBinding jsNamespace = JdtUtil.getAnnotation(annotations, JSNAMESPACE_CLASS);
return JdtUtil.getAnnotationParameterString(jsNamespace, "value");
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniMethodCollector.java b/dev/core/src/com/google/gwt/dev/javac/JsniMethodCollector.java
index 741ba92..a38936c 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniMethodCollector.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniMethodCollector.java
@@ -187,10 +187,6 @@
int startPos = jsniCode.indexOf("/*-{");
int endPos = jsniCode.lastIndexOf("}-*/");
if (startPos < 0 && endPos < 0) {
- reportJsniError(
- info,
- method,
- "Native methods require a JavaScript implementation enclosed with /*-{ and }-*/");
return null;
}
if (startPos < 0) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
index 4b94ea6..d2a7f6a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
@@ -42,7 +42,6 @@
private final boolean isFinal;
private boolean isJso;
private JClassType superClass;
- private boolean isJsPrototypeStub;
public JClassType(SourceInfo info, String name, boolean isAbstract, boolean isFinal) {
super(info, name);
@@ -113,6 +112,11 @@
return false;
}
+ @Override
+ public boolean canBeImplementedExternally() {
+ return isJsNative();
+ }
+
/**
* Sets this type's super class.
*/
@@ -125,14 +129,6 @@
}
}
- public boolean isJsPrototypeStub() {
- return isJsPrototypeStub;
- }
-
- public void setJsPrototypeStub(boolean isJsPrototype) {
- this.isJsPrototypeStub = isJsPrototype;
- }
-
@Override
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
index 01c201a..400b3c4 100755
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
@@ -50,12 +50,12 @@
*/
public abstract class JDeclaredType extends JReferenceType {
- private String jsPrototype;
private boolean isJsFunction;
private boolean isJsType;
private boolean isClassWideExport;
private String jsNamespace = null;
private String jsName = null;
+ private String jsPrototype;
/**
* The types of nested classes, https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
@@ -380,6 +380,11 @@
return jsPrototype;
}
+ @Override
+ public boolean isJsNative() {
+ return jsPrototype != null;
+ }
+
/**
* Returns this type's super class, or <code>null</code> if this type is
* {@link Object} or an interface.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
index c260486..d345b66 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
@@ -91,7 +91,7 @@
}
public boolean canBeImplementedExternally() {
- return isJsFunctionMethod() || isJsInterfaceMethod();
+ return isJsNative() || isJsFunctionMethod() || isJsInterfaceMethod();
}
private boolean isJsInterfaceMethod() {
@@ -226,6 +226,10 @@
return false;
}
+ public boolean isJsNative() {
+ return enclosingType != null && enclosingType.isJsNative();
+ }
+
public void setSpecialization(List<JType> paramTypes, JType returnsType, String targetMethod) {
this.specialization = new Specialization(paramTypes,
returnsType == null ? this.getOriginalReturnType() : returnsType, targetMethod);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
index a437cda..3f7607e 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -130,13 +130,6 @@
}
}
- /**
- * Returns whether a class is a synthetic Prototype class generated by APT or user.
- */
- public boolean isJsTypePrototype(JDeclaredType classType) {
- return classType instanceof JClassType && ((JClassType) classType).isJsPrototypeStub();
- }
-
private static final class TreeStatistics extends JVisitor {
private int nodeCount = 0;
@@ -1177,20 +1170,6 @@
return staticToInstanceMap.containsKey(method);
}
- public static JInterfaceType maybeGetJsTypeFromPrototype(JDeclaredType classType) {
- if (classType == null) {
- return null;
- }
- if (classType instanceof JClassType && ((JClassType) classType).isJsPrototypeStub()) {
- for (JInterfaceType intf : classType.getImplements()) {
- if (intf.isJsType() && intf.getJsPrototype() != null) {
- return intf;
- }
- }
- }
- return null;
- }
-
/**
* If the type is a JSO or an array of JSOs it returns cggcc.JavaScriptObject or an array of
* cggcc.JavaScriptObject respectively; otherwise returns {@code type}.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
index d7b7904..6394224 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JType.java
@@ -77,6 +77,10 @@
return false;
}
+ public boolean isJsNative() {
+ return false;
+ }
+
public boolean canBeImplementedExternally() {
return false;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
index e295c47..0156519 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
@@ -21,7 +21,6 @@
import com.google.gwt.thirdparty.guava.common.base.Function;
import com.google.gwt.thirdparty.guava.common.base.Objects;
import com.google.gwt.thirdparty.guava.common.base.Predicate;
-import com.google.gwt.thirdparty.guava.common.base.Strings;
import com.google.gwt.thirdparty.guava.common.collect.HashMultimap;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSetMultimap;
@@ -657,31 +656,6 @@
}
}
- /**
- * Get the nearest JS type.
- */
- public JDeclaredType getNearestJsType(JType type, boolean mustHavePrototype) {
- type = type.getUnderlyingType();
-
- if (!(type instanceof JDeclaredType)) {
- return null;
- }
-
- JDeclaredType dtype = (JDeclaredType) type;
- if (dtype.isJsType() && (!mustHavePrototype || !Strings.isNullOrEmpty(dtype.getJsPrototype()))) {
- return dtype;
- }
-
- for (JInterfaceType superIntf : dtype.getImplements()) {
- JDeclaredType jsIntf = getNearestJsType(superIntf, mustHavePrototype);
- if (jsIntf != null) {
- return jsIntf;
- }
- }
-
- return null;
- }
-
public JMethod getInstanceMethodBySignature(JClassType type, String signature) {
return getOrCreateInstanceMethodsBySignatureForType(type).get(signature);
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
index b263b4c..d185fdb 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
@@ -618,7 +618,7 @@
// Returning from this method passes a value from JavaScript into Java.
maybeRescueJavaScriptObjectPassingIntoJava(method.getType());
}
- if (method.canBeCalledExternally()) {
+ if (method.canBeCalledExternally() || method.canBeImplementedExternally()) {
for (JParameter param : method.getParams()) {
// Parameters in JsExport, JsType, JsFunction methods should not be pruned in order to
// keep the API intact.
@@ -630,13 +630,6 @@
rescueClassLiteralsIfGetClassIsLive();
}
- if (program.isJsTypePrototype(method.getEnclosingType())) {
- // for JsInterface Prototype methods, rescue all parameters
- // because these are stub methods and the parameters would get pruned ordinarily
- for (JParameter param : method.getParams()) {
- rescue(param);
- }
- }
if (method.getSpecialization() != null) {
rescue(method.getSpecialization().getTargetMethod());
}
@@ -774,9 +767,7 @@
for (int c = params.size(); i < c; ++i) {
JExpression arg = args.get(i);
JParameter param = params.get(i);
- if (arg.hasSideEffects() || liveFieldsAndMethods.contains(param)
- // rescue any args of JsInterface Prototype methods
- || program.isJsTypePrototype(method.getEnclosingType())) {
+ if (arg.hasSideEffects() || liveFieldsAndMethods.contains(param)) {
this.accept(arg);
continue;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index c609e35..2c98b69 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -518,7 +518,7 @@
recordSymbol(x, jsName);
// My class scope
- if (x.getSuperClass() == null || x.getSuperClass().isJsPrototypeStub()) {
+ if (x.getSuperClass() == null) {
myScope = objectScope;
} else {
JsScope parentScope = classScopes.get(x.getSuperClass());
@@ -610,7 +610,7 @@
* 1:1 mapping to obfuscated symbols. Leaving them in global scope
* causes no harm.
*/
- jsFunction = new JsFunction(x.getSourceInfo(), topScope, globalName, true);
+ jsFunction = new JsFunction(x.getSourceInfo(), topScope, globalName, !x.isJsNative());
}
if (polymorphicNames.containsKey(x)) {
polymorphicJsFunctions.add(jsFunction);
@@ -848,8 +848,8 @@
alreadyRan.add(x);
- if (program.isJsTypePrototype(x)) {
- // Don't generate JS for magic @PrototypeOfJsType stubs classes, strip them from output
+ if (x.isJsNative()) {
+ // Don't generate JS for native JsType.
return;
}
@@ -857,7 +857,6 @@
assert !program.immortalCodeGenTypes.contains(x);
// Super classes should be emitted before the actual class.
assert x.getSuperClass() == null || program.isReferenceOnly(x.getSuperClass()) ||
- program.isJsTypePrototype(x.getSuperClass()) ||
alreadyRan.contains(x.getSuperClass());
List<JsFunction> jsFuncs = popList(x.getMethods().size()); // methods
@@ -1142,7 +1141,7 @@
globalStmts.add(clinitFunc.makeStmt());
}
- assert jsFuncs.get(0).getName().getShortIdent().startsWith(GwtAstBuilder.CLINIT_NAME + "_");
+ assert jsFuncs.get(0) == methodBodyMap.get(x.getClinitMethod().getBody());
jsFuncs.remove(0);
// declare all static methods (Java8) into the global scope
@@ -1301,7 +1300,7 @@
*/
JDeclaredType type = method.getEnclosingType();
JDeclaredType clinitTarget = type.getClinitTarget();
- if (clinitTarget == null || program.isJsTypePrototype(clinitTarget)) {
+ if (clinitTarget == null) {
if (x.getInstance() != null) {
pop(); // instance
}
@@ -1387,7 +1386,7 @@
jsInvocation.getArguments().addAll(args);
// Is this method targeting a Foo_Prototype class?
- if (program.isJsTypePrototype(method.getEnclosingType())) {
+ if (method.getEnclosingType().isJsNative()) {
// TODO(goktug): inline following for further simplifications.
return dispatchToSuperPrototype(x, method, qualifiedMethodName, jsInvocation);
} else {
@@ -1417,17 +1416,19 @@
/**
* Setup qualifier and methodRef to dispatch to super-ctor or super-method.
+ * TODO: review this code
*/
private JsExpression dispatchToSuperPrototype(JMethodCall x, JMethod method,
JsNameRef qualifier, JsInvocation jsInvocation) {
// in JsType case, super.foo() call requires SuperCtor.prototype.foo.call(this, args)
// the method target should be on a class that ends with $Prototype and implements a JsType
+ // TODO: if should be an assert instead
if (!(method instanceof JConstructor) && method.isOrOverridesJsMethod()) {
JsNameRef protoRef = prototype.makeRef(x.getSourceInfo());
JsNameRef methodName = new JsNameRef(x.getSourceInfo(), method.getName());
// add qualifier so we have jsPrototype.prototype.methodName.call(this, args)
- String jsPrototype = getJsPrototype(method.getEnclosingType());
+ String jsPrototype = method.getEnclosingType().getJsPrototype();
protoRef.setQualifier(createJsQualifier(jsPrototype, x.getSourceInfo()));
methodName.setQualifier(protoRef);
qualifier.setQualifier(methodName);
@@ -1437,22 +1438,6 @@
return JsNullLiteral.INSTANCE;
}
- private String getJsPrototype(JDeclaredType type) {
- String jsPrototype = null;
- // find JsType of Prototype method being invoked.
- for (JInterfaceType intf : type.getImplements()) {
- JDeclaredType jsIntf = typeOracle.getNearestJsType(intf, true);
- assert jsIntf instanceof JInterfaceType;
-
- if (jsIntf != null) {
- jsPrototype = jsIntf.getJsPrototype();
- break;
- }
- }
- assert jsPrototype != null : "Unable to find JsType with prototype";
- return jsPrototype;
- }
-
@Override
public void endVisit(JMultiExpression x, Context ctx) {
List<JsExpression> exprs = popList(x.getNumberOfExpressions());
@@ -1485,20 +1470,27 @@
@Override
public void endVisit(JNewInstance x, Context ctx) {
- JsName ctorName = names.get(x.getTarget());
- JsNew newOp = new JsNew(x.getSourceInfo(), ctorName.makeRef(x.getSourceInfo()));
+ SourceInfo sourceInfo = x.getSourceInfo();
+ JConstructor ctor = x.getTarget();
+ JsName ctorName = names.get(ctor);
+ JsNew newOp = new JsNew(sourceInfo, ctorName.makeRef(sourceInfo));
popList(newOp.getArguments(), x.getArgs().size()); // args
JsExpression newExpr = newOp;
- if (x.getClassType().isJsFunctionImplementation()) {
+ if (ctor.isJsNative()) {
+ String nativeName = ctor.getEnclosingType().getJsPrototype();
+ newExpr = new JsNew(sourceInfo, createJsQualifier(nativeName, sourceInfo));
+ } else if (x.getClassType().isJsFunctionImplementation()) {
+ // Foo.prototype.samMethod
+ JMethod jsFunctionMethod = getJsFunctionMethod(x.getClassType());
+ JsNameRef funcNameRef = polymorphicNames.get(jsFunctionMethod).makeRef(sourceInfo);
+ JsNameRef protoRef = prototype.makeRef(sourceInfo);
+ funcNameRef.setQualifier(protoRef);
+ protoRef.setQualifier(ctorName.makeRef(sourceInfo));
+
+ // makeLambdaFunction(Foo.prototype.samMethod, new Foo(...))
JsFunction makeLambdaFunc =
indexedFunctions.get("JavaClassHierarchySetupUtil.makeLambdaFunction");
- JMethod jsFunctionMethod = getJsFunctionMethod(x.getClassType());
- JsNameRef funcNameRef = polymorphicNames.get(jsFunctionMethod).makeRef(x.getSourceInfo());
- JsNameRef protoRef = prototype.makeRef(x.getSourceInfo());
- funcNameRef.setQualifier(protoRef);
- protoRef.setQualifier(ctorName.makeRef(x.getSourceInfo()));
- // makeLambdaFunction(Foo.prototype.samMethod, new Foo(...))
- newExpr = new JsInvocation(x.getSourceInfo(), makeLambdaFunc, funcNameRef, newOp);
+ newExpr = new JsInvocation(sourceInfo, makeLambdaFunc, funcNameRef, newOp);
}
push(newExpr);
}
@@ -1663,8 +1655,7 @@
return false;
}
- // Don't generate JS for magic @PrototypeOfJsType classes
- if (program.isJsTypePrototype(x)) {
+ if (x.isJsNative()) {
return false;
}
@@ -2473,36 +2464,42 @@
JExpression typeId = getRuntimeTypeReference(x);
JClassType superClass = x.getSuperClass();
JExpression superTypeId = (superClass == null) ? JNullLiteral.INSTANCE :
- getRuntimeTypeReference(x.getSuperClass());
- // check if there's an overriding prototype
- JInterfaceType jsPrototypeIntf = JProgram.maybeGetJsTypeFromPrototype(superClass);
- String jsPrototype = jsPrototypeIntf != null ? jsPrototypeIntf.getJsPrototype() : null;
- if (x.isJsFunctionImplementation()) {
- jsPrototype = "Function";
- }
+ getRuntimeTypeReference(superClass);
+ String jsPrototype = getSuperPrototype(x);
List<JsExpression> defineClassArguments = Lists.newArrayList();
defineClassArguments.add(convertJavaLiteral(typeId));
- // setup superclass normally
- if (jsPrototype == null) {
- defineClassArguments.add(convertJavaLiteral(superTypeId));
- } else {
- // setup extension of native JS object
- // TODO(goktug): need to stash Object methods to the prototype as they are not inhertied.
- defineClassArguments.add(createJsQualifier(jsPrototype, x.getSourceInfo()));
- }
- JsExpression castMap = generateCastableTypeMap(x);
- defineClassArguments.add(castMap);
-
+ defineClassArguments.add(jsPrototype == null ? convertJavaLiteral(superTypeId) :
+ createJsQualifier(jsPrototype, x.getSourceInfo()));
+ defineClassArguments.add(generateCastableTypeMap(x));
defineClassArguments.addAll(constructorArgs);
- // choose appropriate setup function
// JavaClassHierarchySetupUtil.defineClass(typeId, superTypeId, castableMap, constructors)
JsStatement defineClassStatement = constructInvocation(x.getSourceInfo(),
"JavaClassHierarchySetupUtil.defineClass", defineClassArguments).makeStmt();
globalStmts.add(defineClassStatement);
typeForStatMap.put(defineClassStatement, x);
+
+ if (jsPrototype != null) {
+ JExpression objectTypeId = getRuntimeTypeReference(program.getTypeJavaLangObject());
+ JsStatement statement =
+ constructInvocation(x.getSourceInfo(), "JavaClassHierarchySetupUtil.copyObjectMethods",
+ convertJavaLiteral(objectTypeId)).makeStmt();
+ globalStmts.add(statement);
+ typeForStatMap.put(statement, x);
+ }
+ }
+
+ private String getSuperPrototype(JClassType x) {
+ if (x.isJsFunctionImplementation()) {
+ return "Function";
+ }
+ JClassType superClass = x.getSuperClass();
+ if (superClass != null && superClass.isJsNative()) {
+ return superClass.getJsPrototype();
+ }
+ return null;
}
private void generateClassDefinition(JClassType x, List<JsStatement> globalStmts) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
index 1768df2..771d3c6 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -3089,7 +3089,9 @@
private void processNativeMethod(MethodDeclaration x) {
JMethod method = curMethod.method;
JsniMethod jsniMethod = jsniMethods.get(x);
- assert jsniMethod != null;
+ if (jsniMethod == null) {
+ return;
+ }
SourceInfo info = method.getSourceInfo();
JsFunction jsFunction = jsniMethod.function();
JsniMethodBody body = new JsniMethodBody(info);
@@ -4191,9 +4193,6 @@
JDeclaredType type;
if (binding.isClass()) {
type = new JClassType(info, name, binding.isAbstract(), binding.isFinal());
- if (isJsInteropEnabled) {
- ((JClassType) type).setJsPrototypeStub(JsInteropUtil.isJsPrototypeFlag(x));
- }
} else if (binding.isInterface() || binding.isAnnotationType()) {
type = new JInterfaceType(info, name);
} else if (binding.isEnum()) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementCastsAndTypeChecks.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementCastsAndTypeChecks.java
index 71cb6c9..553a1a4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementCastsAndTypeChecks.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementCastsAndTypeChecks.java
@@ -21,9 +21,9 @@
import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JCastOperation;
+import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JInstanceOf;
-import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
@@ -263,7 +263,7 @@
assert targetTypeCategory == TypeCategory.TYPE_JS_PROTOTYPE;
call.addArg(program.getStringLiteral(sourceInfo,
- ((JInterfaceType) targetType).getJsPrototype()));
+ ((JDeclaredType) targetType).getJsPrototype()));
}
return call;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
index 9e6c555..1f07892 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
@@ -22,7 +22,6 @@
import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JEnumType;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JField;
@@ -350,18 +349,7 @@
if (!(type instanceof JClassType) || ((JClassType) type).getSuperClass() == null) {
return JNullLiteral.INSTANCE;
}
- JClassType classType = (JClassType) type;
- if (program.isJsTypePrototype(classType)) {
- /*
- * When a Java type extends a JS prototype stub, we make the superclass literal
- * equal to the Js interface.
- */
- JDeclaredType jsInterface = program.typeOracle.getNearestJsType(type, true);
- assert jsInterface != null;
- return createDependentClassLiteral(info, jsInterface);
- }
-
- return createDependentClassLiteral(info, classType.getSuperClass());
+ return createDependentClassLiteral(info, ((JClassType) type).getSuperClass());
}
private JClassLiteral createDependentClassLiteral(SourceInfo info, JType type) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
index 3c018ee..5806da0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
@@ -151,7 +151,7 @@
@Override
public boolean visit(JMethod x, Context ctx) {
// Let's do it!
- JDeclaredType enclosingType = (JDeclaredType) x.getEnclosingType();
+ JDeclaredType enclosingType = x.getEnclosingType();
JType returnType = x.getType();
SourceInfo sourceInfo = x.getSourceInfo().makeChild();
int myIndexInClass = enclosingType.getMethods().indexOf(x);
@@ -299,6 +299,9 @@
if (method.isAbstract()) {
return false;
}
+ if (method.isJsNative()) {
+ return false;
+ }
if (method == program.getNullMethod()) {
// Special case: we don't make calls to this method static.
return false;
@@ -309,10 +312,6 @@
return false;
}
- if (program.isJsTypePrototype(method.getEnclosingType())) {
- return false;
- }
-
return true;
}
}
@@ -378,11 +377,9 @@
* Optionally adds a null check on the former "this" parameter.
*/
static class StaticCallConverter {
- private final JProgram program;
private final JMethod checkNotNull;
StaticCallConverter(JProgram program, boolean addNullChecksForThis) {
- this.program = program;
if (addNullChecksForThis) {
checkNotNull = program.getIndexedMethod("Exceptions.checkNotNull");
} else {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
index a688750..b232bb6 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
@@ -123,15 +123,8 @@
private InlineResult tryInlineMethodCall(JMethodCall x, Context ctx) {
JMethod method = x.getTarget();
- if (program.isJsTypePrototype(method.getEnclosingType())) {
- /*
- * Don't inline calls to JsType Prototype methods, since these are merely stubs to
- * preserve super calls to JS prototype methods.
- */
- return InlineResult.BLACKLIST;
- }
- if (!method.isStatic() || method.isNative()) {
+ if (!method.isStatic() || method.isNative() || method.canBeImplementedExternally()) {
// Only inline static methods that are not native.
return InlineResult.BLACKLIST;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/RemoveEmptySuperCalls.java b/dev/core/src/com/google/gwt/dev/jjs/impl/RemoveEmptySuperCalls.java
index eac0a0b..35cced8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/RemoveEmptySuperCalls.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/RemoveEmptySuperCalls.java
@@ -33,23 +33,13 @@
* Removes calls to no-op super constructors.
*/
public static class EmptySuperCallVisitor extends JModVisitor {
- private JProgram program;
-
- public EmptySuperCallVisitor(JProgram program) {
- this.program = program;
- }
-
@Override
public void endVisit(JExpressionStatement x, Context ctx) {
if (x.getExpr() instanceof JMethodCall && !(x.getExpr() instanceof JNewInstance)) {
JMethodCall call = (JMethodCall) x.getExpr();
if (call.getTarget() instanceof JConstructor) {
JConstructor ctor = (JConstructor) call.getTarget();
- if (program.isJsTypePrototype(ctor.getEnclosingType())) {
- // don't remove calls to JsType super-constructors;
- return;
- }
- if (ctor.isEmpty()) {
+ if (ctor.isEmpty() && !ctor.isJsNative()) {
// TODO: move this 3-way into Simplifier.
if (call.getArgs().isEmpty()) {
ctx.removeMe();
@@ -67,7 +57,7 @@
}
public static boolean exec(JProgram program) {
- EmptySuperCallVisitor v = new EmptySuperCallVisitor(program);
+ EmptySuperCallVisitor v = new EmptySuperCallVisitor();
v.accept(program);
return v.didChange();
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeCategory.java b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeCategory.java
index b7f73f0..e81da83 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeCategory.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeCategory.java
@@ -67,7 +67,7 @@
} else if (program.typeOracle.isDualJsoInterface(type)
|| program.typeOracle.isJsTypeInterfaceWithoutPrototype(type)) {
return TypeCategory.TYPE_JAVA_OBJECT_OR_JSO;
- } else if (program.typeOracle.isJsTypeInterfaceWithPrototype(type)) {
+ } else if (type.isJsNative()) {
return TypeCategory.TYPE_JS_PROTOTYPE;
} else if (type.isJsFunction()) {
return TypeCategory.TYPE_JS_FUNCTION;
diff --git a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
index ce2ac4b..b7b2000 100644
--- a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
+++ b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
@@ -97,6 +97,15 @@
return @JavaClassHierarchySetupUtil::portableObjCreate(*)(superPrototype);
}-*/;
+ public static native void copyObjectMethods(JavaScriptObject objectPrototypeId) /*-{
+ var prototype = @JavaClassHierarchySetupUtil::prototypesByTypeId[objectPrototypeId];
+ for (var property in prototype) {
+ if (_[property] === undefined) {
+ _[property] = prototype[property];
+ }
+ }
+ }-*/;
+
/**
* Retrieves the class literal if stored in a place holder, {@code null} otherwise.
*/
diff --git a/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java b/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java
index d3575f2..d452ba9 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java
@@ -562,98 +562,6 @@
+ JSORestrictionsChecker.ERR_EITHER_JSEXPORT_JSNOEXPORT);
}
- public void testJsPrototypeNotOnClass() {
- StringBuilder buggyCode = new StringBuilder();
- buggyCode.append("import com.google.gwt.core.client.js.JsType;\n");
- buggyCode.append("@JsType(prototype = \"foo\")\n");
- buggyCode.append("public class Buggy {\n");
- buggyCode.append("void foo() {}\n");
- buggyCode.append("}\n");
-
- shouldGenerateError(buggyCode, "Line 3: "
- + JSORestrictionsChecker.ERR_JS_TYPE_WITH_PROTOTYPE_SET_NOT_ALLOWED_ON_CLASS_TYPES);
- }
-
- public void testJsTypePrototypeExtensionNotAllowed() {
- StringBuilder buggyCode = new StringBuilder();
- buggyCode.append("import com.google.gwt.core.client.js.JsType;\n");
- buggyCode.append("import com.google.gwt.core.client.js.impl.PrototypeOfJsType;\n");
- buggyCode.append("public class Buggy {\n");
- buggyCode.append("@JsType interface Foo { " +
- "@PrototypeOfJsType static class Foo_Prototype implements Foo {} }\n");
- buggyCode.append("static class BuggyFoo extends Foo.Foo_Prototype {\n");
- buggyCode.append("}\n");
- buggyCode.append("}\n");
-
- shouldGenerateError(buggyCode, "Line 5: "
- + JSORestrictionsChecker.ERR_CLASS_EXTENDS_MAGIC_PROTOTYPE_BUT_NO_PROTOTYPE_ATTRIBUTE);
- }
-
- public void testJsTypePrototypeExtensionNoError() {
- StringBuilder buggyCode = new StringBuilder();
- buggyCode.append("import com.google.gwt.core.client.js.JsType;\n");
- buggyCode.append("import com.google.gwt.core.client.js.impl.PrototypeOfJsType;\n");
- buggyCode.append("public class Buggy {\n");
- buggyCode.append("@JsType (prototype =\"foo\") interface Foo { " +
- "@PrototypeOfJsType static class Foo_Prototype implements Foo {} }\n");
- buggyCode.append("static class BuggyFoo extends Foo.Foo_Prototype {\n");
- buggyCode.append("}\n");
- buggyCode.append("}\n");
-
- shouldGenerateNoError(buggyCode);
- }
-
- public void testJsTypePrototypeExtensionNoError2() {
- StringBuilder buggyCode = new StringBuilder();
- buggyCode.append("import com.google.gwt.core.client.js.JsType;\n");
- buggyCode.append("import com.google.gwt.core.client.js.impl.PrototypeOfJsType;\n");
- buggyCode.append("public class Buggy {\n");
- buggyCode.append("@JsType (prototype =\"foo\") interface Foo { }\n ");
- buggyCode.append("@PrototypeOfJsType static class Foo_Prototype implements Foo {}\n");
- buggyCode.append("static class BuggyFoo extends Foo_Prototype {\n");
- buggyCode.append("}\n");
- buggyCode.append("}\n");
-
- shouldGenerateNoError(buggyCode);
- }
-
- public void testJsTypePrototypeExtensionNotAllowed2() {
- // TODO (cromwellian): add a command-line flag for this later
- JSORestrictionsChecker.LINT_MODE = true;
- StringBuilder buggyCode = new StringBuilder();
- buggyCode.append("import com.google.gwt.core.client.js.JsType;\n");
- buggyCode.append("public class Buggy {\n");
- buggyCode.append("@JsType (prototype =\"foo\") interface Foo { }\n");
- buggyCode.append("static class BuggyBar {}\n");
- buggyCode.append("static class BuggyFoo extends BuggyBar implements Foo {\n");
- buggyCode.append("}\n");
- buggyCode.append("}\n");
-
- shouldGenerateError(buggyCode, "Line 5: "
- + JSORestrictionsChecker.ERR_MUST_EXTEND_MAGIC_PROTOTYPE_CLASS);
- }
-
- public void testJsPropertyNoErrors() {
- StringBuilder buggyCode = new StringBuilder();
- buggyCode.append("import com.google.gwt.core.client.js.JsType;\n");
- buggyCode.append("import com.google.gwt.core.client.js.JsProperty;\n");
- buggyCode.append("@JsType public interface Buggy {\n");
-
- buggyCode.append("@JsProperty int foo();\n");
- buggyCode.append("@JsProperty void foo(int x);\n");
-
- buggyCode.append("@JsProperty int getFoo();\n");
- buggyCode.append("@JsProperty void setFoo(int x);\n");
-
- buggyCode.append("@JsProperty boolean hasFoo();\n");
- buggyCode.append("@JsProperty boolean isFoo();\n");
- buggyCode.append("@JsProperty Buggy setFoo(String x);\n");
-
- buggyCode.append("}\n");
-
- shouldGenerateNoError(buggyCode);
- }
-
public void testJsFunctionOnFunctionalInterface() {
StringBuilder goodCode = new StringBuilder();
goodCode.append("import com.google.gwt.core.client.js.JsFunction;\n");
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/PrunerTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/PrunerTest.java
index 42a43dc..babeca0 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/PrunerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/PrunerTest.java
@@ -76,29 +76,24 @@
addSnippetClassDecl("interface UnusedInterface { void foo(); }");
addSnippetImport("com.google.gwt.core.client.js.JsType");
addSnippetImport("com.google.gwt.core.client.js.JsExport");
- addSnippetImport("com.google.gwt.core.client.js.impl"
- + ".PrototypeOfJsType");
addSnippetClassDecl("interface Callback { void go(); }");
addSnippetImport("com.google.gwt.core.client.js.JsType");
addSnippetImport("com.google.gwt.core.client.js.JsExport");
addSnippetClassDecl("@JsType interface Js { void doIt(Callback cb); }");
- addSnippetClassDecl("@JsType(prototype=\"Foo\") interface JsProto { " +
- "@PrototypeOfJsType static class Prototype implements JsProto {" +
- "public Prototype(int arg) {}" +
- "}" +
+ addSnippetClassDecl("@JsType(prototype=\"Foo\") static class JsProto { ",
+ "public JsProto(int arg) {}",
"}");
- addSnippetClassDecl("static class JsProtoImpl "
- + "extends JsProto.Prototype {" +
- "public JsProtoImpl() { super(10); }" +
+ addSnippetClassDecl("static class JsProtoImpl extends JsProto {",
+ "public JsProtoImpl() { super(10); }",
"}");
- addSnippetClassDecl("static class JsProtoImpl2 extends JsProto.Prototype {" +
- "@JsExport(\"foo\") public JsProtoImpl2() { super(10); }" +
+ addSnippetClassDecl("static class JsProtoImpl2 extends JsProto {",
+ "@JsExport(\"foo\") public JsProtoImpl2() { super(10); }",
"}");
- addSnippetClassDecl("static class JsProtoImpl3 extends JsProto.Prototype {" +
- "public JsProtoImpl3() { super(10); }" +
+ addSnippetClassDecl("static class JsProtoImpl3 extends JsProto {",
+ "public JsProtoImpl3() { super(10); }",
"}");
Result result;
diff --git a/tools/api-checker/config/gwt27_28userApi.conf b/tools/api-checker/config/gwt27_28userApi.conf
index bdf843e..1f1704b 100644
--- a/tools/api-checker/config/gwt27_28userApi.conf
+++ b/tools/api-checker/config/gwt27_28userApi.conf
@@ -131,6 +131,7 @@
#excluded packages colon separated list
excludedPackages com.google.gwt.core.client.impl\
:com.google.gwt.core.shared.impl\
+:com.google.gwt.core.client.js.impl\
:com.google.gwt.editor.client.impl\
:com.google.gwt.i18n.client.impl\
:com.google.gwt.junit.client.impl\
diff --git a/user/src/com/google/gwt/core/client/js/impl/PrototypeOfJsType.java b/user/src/com/google/gwt/core/client/js/impl/PrototypeOfJsType.java
deleted file mode 100644
index 9cf795f..0000000
--- a/user/src/com/google/gwt/core/client/js/impl/PrototypeOfJsType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * 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 com.google.gwt.core.client.js.impl;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Marker annotation used to indicate which JsType stub classes trigger prototype overriding
- * behavior in subtypes. This class is meant to be used by implementers of annotation processors.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Documented
-public @interface PrototypeOfJsType {
-}
diff --git a/user/test/com/google/gwt/core/client/interop/HTMLAnotherElement.java b/user/test/com/google/gwt/core/client/interop/HTMLAnotherElement.java
index e7d4925..2c2ca7e 100644
--- a/user/test/com/google/gwt/core/client/interop/HTMLAnotherElement.java
+++ b/user/test/com/google/gwt/core/client/interop/HTMLAnotherElement.java
@@ -16,11 +16,7 @@
package com.google.gwt.core.client.interop;
import com.google.gwt.core.client.js.JsType;
-import com.google.gwt.core.client.js.impl.PrototypeOfJsType;
@JsType(prototype = "HTMLElement")
-interface HTMLAnotherElement {
- @PrototypeOfJsType
- static class Prototype implements HTMLAnotherElement {
- }
+class HTMLAnotherElement {
}
diff --git a/user/test/com/google/gwt/core/client/interop/HTMLButtonElement.java b/user/test/com/google/gwt/core/client/interop/HTMLButtonElement.java
index 6e2242d..7c1c532 100644
--- a/user/test/com/google/gwt/core/client/interop/HTMLButtonElement.java
+++ b/user/test/com/google/gwt/core/client/interop/HTMLButtonElement.java
@@ -16,11 +16,7 @@
package com.google.gwt.core.client.interop;
import com.google.gwt.core.client.js.JsType;
-import com.google.gwt.core.client.js.impl.PrototypeOfJsType;
@JsType(prototype = "HTMLButtonElement")
-interface HTMLButtonElement extends HTMLElement {
- @PrototypeOfJsType
- static class Prototype implements HTMLButtonElement {
- }
+class HTMLButtonElement extends HTMLElement {
}
diff --git a/user/test/com/google/gwt/core/client/interop/HTMLElement.java b/user/test/com/google/gwt/core/client/interop/HTMLElement.java
index 385954e..41e9c3a 100644
--- a/user/test/com/google/gwt/core/client/interop/HTMLElement.java
+++ b/user/test/com/google/gwt/core/client/interop/HTMLElement.java
@@ -16,11 +16,7 @@
package com.google.gwt.core.client.interop;
import com.google.gwt.core.client.js.JsType;
-import com.google.gwt.core.client.js.impl.PrototypeOfJsType;
@JsType(prototype = "HTMLElement")
-interface HTMLElement {
- @PrototypeOfJsType
- static class Prototype implements HTMLElement {
- }
+class HTMLElement {
}
diff --git a/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java b/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java
index 659f584..8bb7025 100644
--- a/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java
+++ b/user/test/com/google/gwt/core/client/interop/JsFunctionTest.java
@@ -185,8 +185,13 @@
assertNotNull(c3);
MyJsFunctionIdentityInterface c4 = (MyJsFunctionIdentityInterface) object;
assertNotNull(c4);
- ElementLikeJsInterface c5 = (ElementLikeJsInterface) object;
- assertNotNull(c5);
+ try {
+ ElementLikeJsInterface c5 = (ElementLikeJsInterface) object;
+ assertNotNull(c5);
+ fail("ClassCastException should be caught.");
+ } catch (ClassCastException cce) {
+ // Expected.
+ }
}
public void testCast_crossCastJavaInstance() {
@@ -219,7 +224,7 @@
assertTrue(object instanceof MyJsFunctionInterfaceImpl);
assertTrue(object instanceof MyJsFunctionIdentityInterface);
assertTrue(object instanceof MyJsFunctionWithOnlyInstanceofReference);
- assertTrue(object instanceof ElementLikeJsInterface);
+ assertFalse(object instanceof ElementLikeJsInterface);
}
// uncomment when Java8 is supported.
diff --git a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
index 4914698..836c428 100644
--- a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
+++ b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
@@ -137,7 +137,15 @@
assertTrue(hasField(revealedOverrideSubType, "run"));
}
- public void testSubClassWithSuperCalls() {
+ public void testConcreteNativeType() {
+ MyJsClassWithPrototype obj = new MyJsClassWithPrototype();
+ assertTrue(isUndefined(obj.getX()));
+ obj.setX(72);
+ assertEquals(72, obj.getX());
+ assertEquals(74, obj.sum(2));
+ }
+
+ public void testConcreteNativeType_sublasss() {
MyClassExtendsJsPrototype mc = new MyClassExtendsJsPrototype();
assertEquals(143, mc.sum(1));
@@ -219,7 +227,8 @@
assertTrue(object instanceof ElementLikeJsInterface);
assertFalse(object instanceof ElementLikeJsInterfaceImpl);
assertTrue(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
- assertFalse(object instanceof MyJsPrototypeWithOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsInterfaceWithPrototypeAndOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsClassWithPrototypeAndOnlyInstanceofReference);
assertFalse(object instanceof ConcreteJsType);
}
@@ -236,7 +245,8 @@
assertTrue(object instanceof ElementLikeJsInterface);
assertFalse(object instanceof ElementLikeJsInterfaceImpl);
assertTrue(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
- assertFalse(object instanceof MyJsPrototypeWithOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsInterfaceWithPrototypeAndOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsClassWithPrototypeAndOnlyInstanceofReference);
assertFalse(object instanceof ConcreteJsType);
}
@@ -253,7 +263,8 @@
assertTrue(object instanceof ElementLikeJsInterface);
assertFalse(object instanceof ElementLikeJsInterfaceImpl);
assertTrue(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
- assertTrue(object instanceof MyJsPrototypeWithOnlyInstanceofReference);
+ assertTrue(object instanceof MyJsInterfaceWithPrototypeAndOnlyInstanceofReference);
+ assertTrue(object instanceof MyJsClassWithPrototypeAndOnlyInstanceofReference);
assertFalse(object instanceof ConcreteJsType);
}
@@ -271,7 +282,8 @@
assertTrue(object instanceof ElementLikeJsInterface);
assertTrue(object instanceof ElementLikeJsInterfaceImpl);
assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
- assertFalse(object instanceof MyJsPrototypeWithOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsInterfaceWithPrototypeAndOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsClassWithPrototypeAndOnlyInstanceofReference);
assertFalse(object instanceof ConcreteJsType);
}
@@ -289,7 +301,8 @@
assertFalse(object instanceof ElementLikeJsInterface);
assertFalse(object instanceof ElementLikeJsInterfaceImpl);
assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
- assertFalse(object instanceof MyJsPrototypeWithOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsInterfaceWithPrototypeAndOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsClassWithPrototypeAndOnlyInstanceofReference);
assertFalse(object instanceof ConcreteJsType);
}
@@ -307,7 +320,8 @@
assertFalse(object instanceof ElementLikeJsInterface);
assertFalse(object instanceof ElementLikeJsInterfaceImpl);
assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
- assertFalse(object instanceof MyJsPrototypeWithOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsInterfaceWithPrototypeAndOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsClassWithPrototypeAndOnlyInstanceofReference);
assertTrue(object instanceof ConcreteJsType);
}
@@ -320,16 +334,14 @@
assertTrue(object instanceof HTMLButtonElement);
assertTrue(object instanceof HTMLElement);
assertTrue(object instanceof Iterable);
- /*
- * TODO: this works, but only because Object can't be type-tightened to HTMLElement. But it will
- * evaluate statically to false for HTMLElement instanceof HTMLAnotherElement. Depending on what
- * the spec decides, fix JTypeOracle so that canTheoreticallyCast returns the appropriate
- * result, as well as add a test here that can be type-tightened.
- */
assertFalse(object instanceof MyJsInterfaceWithPrototype);
- assertTrue(object instanceof ElementLikeJsInterface);
- assertTrue(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
- assertTrue(object instanceof MyJsPrototypeWithOnlyInstanceofReference);
+ assertFalse(object instanceof MyJsInterfaceWithPrototypeImpl);
+ assertFalse(object instanceof ElementLikeJsInterface);
+ assertFalse(object instanceof ElementLikeJsInterfaceImpl);
+ assertFalse(object instanceof MyJsInterfaceWithOnlyInstanceofReference);
+ assertTrue(object instanceof MyJsInterfaceWithPrototypeAndOnlyInstanceofReference);
+ assertTrue(object instanceof MyJsClassWithPrototypeAndOnlyInstanceofReference);
+ assertFalse(object instanceof ConcreteJsType);
}
public void testInstanceOfWithNameSpace() {
diff --git a/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java b/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java
index 22c6543..faf7049 100644
--- a/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java
+++ b/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java
@@ -15,7 +15,7 @@
*/
package com.google.gwt.core.client.interop;
-class MyClassExtendsJsPrototype extends MyJsInterfaceWithPrototype.Prototype {
+class MyClassExtendsJsPrototype extends MyJsClassWithPrototype {
MyClassExtendsJsPrototype() {
setX(42);
diff --git a/user/test/com/google/gwt/core/client/interop/MyCustomHtmlButtonWithIterator.java b/user/test/com/google/gwt/core/client/interop/MyCustomHtmlButtonWithIterator.java
index d04ede1..89e2ed4 100644
--- a/user/test/com/google/gwt/core/client/interop/MyCustomHtmlButtonWithIterator.java
+++ b/user/test/com/google/gwt/core/client/interop/MyCustomHtmlButtonWithIterator.java
@@ -17,7 +17,7 @@
import java.util.Iterator;
-class MyCustomHtmlButtonWithIterator extends HTMLButtonElement.Prototype implements Iterable {
+class MyCustomHtmlButtonWithIterator extends HTMLButtonElement implements Iterable {
@Override
public Iterator iterator() {
return null;
diff --git a/user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java b/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototype.java
similarity index 69%
copy from user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java
copy to user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototype.java
index bf195de..03e6e80 100644
--- a/user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java
+++ b/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototype.java
@@ -15,11 +15,19 @@
*/
package com.google.gwt.core.client.interop;
+import com.google.gwt.core.client.js.JsProperty;
import com.google.gwt.core.client.js.JsType;
/**
- * A test class marked with JsType but isn't referenced from any Java code except instanceof.
+ * A class that represents an existing native type.
*/
-@JsType(prototype = "HTMLButtonElement")
-public interface MyJsPrototypeWithOnlyInstanceofReference {
-}
\ No newline at end of file
+@JsType(prototype = "MyJsInterface")
+public class MyJsClassWithPrototype {
+ @JsProperty
+ public native int getX();
+
+ @JsProperty
+ public native void setX(int x);
+
+ public native int sum(int bias);
+}
diff --git a/user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java b/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototypeAndOnlyInstanceofReference.java
similarity index 92%
rename from user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java
rename to user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototypeAndOnlyInstanceofReference.java
index bf195de..d4a013d 100644
--- a/user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java
+++ b/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototypeAndOnlyInstanceofReference.java
@@ -21,5 +21,5 @@
* A test class marked with JsType but isn't referenced from any Java code except instanceof.
*/
@JsType(prototype = "HTMLButtonElement")
-public interface MyJsPrototypeWithOnlyInstanceofReference {
-}
\ No newline at end of file
+public class MyJsClassWithPrototypeAndOnlyInstanceofReference {
+}
diff --git a/user/test/com/google/gwt/core/client/interop/MyJsInterfaceWithPrototype.java b/user/test/com/google/gwt/core/client/interop/MyJsInterfaceWithPrototype.java
index e710eea..a80f7d1 100644
--- a/user/test/com/google/gwt/core/client/interop/MyJsInterfaceWithPrototype.java
+++ b/user/test/com/google/gwt/core/client/interop/MyJsInterfaceWithPrototype.java
@@ -17,7 +17,6 @@
import com.google.gwt.core.client.js.JsProperty;
import com.google.gwt.core.client.js.JsType;
-import com.google.gwt.core.client.js.impl.PrototypeOfJsType;
@JsType(prototype = "MyJsInterface")
interface MyJsInterfaceWithPrototype {
@@ -29,22 +28,4 @@
void setX(int a);
int sum(int bias);
-
- @PrototypeOfJsType
- static class Prototype implements MyJsInterfaceWithPrototype {
-
- @Override
- public int getX() {
- return 0;
- }
-
- @Override
- public void setX(int a) {
- }
-
- @Override
- public int sum(int bias) {
- return 0;
- }
- }
}
diff --git a/user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java b/user/test/com/google/gwt/core/client/interop/MyJsInterfaceWithPrototypeAndOnlyInstanceofReference.java
similarity index 91%
copy from user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java
copy to user/test/com/google/gwt/core/client/interop/MyJsInterfaceWithPrototypeAndOnlyInstanceofReference.java
index bf195de..d8e7b69 100644
--- a/user/test/com/google/gwt/core/client/interop/MyJsPrototypeWithOnlyInstanceofReference.java
+++ b/user/test/com/google/gwt/core/client/interop/MyJsInterfaceWithPrototypeAndOnlyInstanceofReference.java
@@ -21,5 +21,5 @@
* A test class marked with JsType but isn't referenced from any Java code except instanceof.
*/
@JsType(prototype = "HTMLButtonElement")
-public interface MyJsPrototypeWithOnlyInstanceofReference {
-}
\ No newline at end of file
+public interface MyJsInterfaceWithPrototypeAndOnlyInstanceofReference {
+}