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 { +}