Disallow JsOptional on primitive typed parameters.
Change-Id: Ic9affb24a32317fe0cf99c910c98a9284838bb80
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
index ab8e301..572af74 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JArrayType.java
@@ -80,6 +80,11 @@
}
@Override
+ public boolean isPrimitiveType() {
+ return false;
+ }
+
+ @Override
public boolean isAbstract() {
return false;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java
index 8cd9505..8e62df3 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JPrimitiveType.java
@@ -80,6 +80,11 @@
}
@Override
+ public boolean isPrimitiveType() {
+ return true;
+ }
+
+ @Override
public boolean isJsType() {
return false;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java
index 57fc036..e3611d2 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JReferenceType.java
@@ -320,6 +320,11 @@
return "L" + name.replace('.', '/') + ';';
}
+ @Override
+ public boolean isPrimitiveType() {
+ return false;
+ }
+
public JReferenceType weakenToNullable() {
if (getUnderlyingType() == this) {
// Underlying types cannot be weakened.
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 7a62af4..4dfe990 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
@@ -64,6 +64,7 @@
public abstract boolean isArrayType();
+ public abstract boolean isPrimitiveType();
/**
* Returns {@code true} if this is {@link JReferenceType.JNullType.INSTANCE}.
*/
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 e822ac2..382212d 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
@@ -589,7 +589,7 @@
}
public boolean castSucceedsTrivially(JType fromType, JType toType) {
- if (fromType instanceof JPrimitiveType && toType instanceof JPrimitiveType) {
+ if (fromType.isPrimitiveType() && toType.isPrimitiveType()) {
return fromType == toType;
}
if (fromType instanceof JReferenceType && toType instanceof JReferenceType) {
@@ -688,7 +688,7 @@
}
}
- if (arrayType.getLeafType() instanceof JPrimitiveType) {
+ if (arrayType.getLeafType().isPrimitiveType()) {
castableDestinationTypes.add(arrayType);
} else {
// Class arrays reuse their leaf type castable destination types.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java
index c594100..b0d4990 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/AssertionNormalizer.java
@@ -24,7 +24,6 @@
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
import com.google.gwt.dev.jjs.ast.JPrefixOperation;
-import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JThrowStatement;
@@ -97,7 +96,7 @@
return "_Object";
}
- assert (argType instanceof JPrimitiveType);
+ assert (argType.isPrimitiveType());
return "_" + argType.getName();
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/CompileTimeConstantsReplacer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/CompileTimeConstantsReplacer.java
index 0491e08..8761313 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CompileTimeConstantsReplacer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CompileTimeConstantsReplacer.java
@@ -21,7 +21,6 @@
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JFieldRef;
import com.google.gwt.dev.jjs.ast.JModVisitor;
-import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
@@ -58,7 +57,7 @@
// clone it and recursively remove field references, and finally cache the results.
value = accept(new CloneExpressionVisitor().cloneExpression(field.getInitializer()));
JType fieldType = field.getType().getUnderlyingType();
- assert fieldType instanceof JPrimitiveType || fieldType == program.getTypeJavaLangString()
+ assert fieldType.isPrimitiveType() || fieldType == program.getTypeJavaLangString()
: fieldType.getName() + " is not a primitive nor String";
if (fieldType != value.getType()) {
value = new JCastOperation(value.getSourceInfo(), fieldType, value);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
index 5a326b9..26df51c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
@@ -1789,7 +1789,7 @@
* this value is not changed.
*/
// TODO(spoon): use Simplifier.cast to shorten this
- if ((x.getType() instanceof JPrimitiveType) && (lit instanceof JValueLiteral)) {
+ if (x.getType().isPrimitiveType() && (lit instanceof JValueLiteral)) {
JPrimitiveType xTypePrim = (JPrimitiveType) x.getType();
lit = xTypePrim.coerce((JValueLiteral) lit);
}
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 e1ecc9a..6e6e158 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
@@ -110,7 +110,7 @@
// It is a primitive type, perform the necessary coercion.
- assert toType instanceof JPrimitiveType;
+ assert toType.isPrimitiveType();
/*
* See JLS 5.1.3: if a cast narrows from one type to another, we must
* call a narrowing conversion function. EXCEPTION: we currently have no
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplicitUpcastAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplicitUpcastAnalyzer.java
index e38793e..a2d26f0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplicitUpcastAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplicitUpcastAnalyzer.java
@@ -93,11 +93,11 @@
@Override
public void endVisit(JField x, Context ctx) {
- if (x.getInitializer() == null && !x.isFinal()) {
- if (!(x.getType() instanceof JPrimitiveType)) {
- // if it is declared without an initial value, it defaults to null
- processIfTypesNotEqual(JReferenceType.NULL_TYPE, x.getType(), x.getSourceInfo());
- }
+ if (x.getInitializer() == null
+ && !x.isFinal()
+ && !x.getType().isPrimitiveType()) {
+ // if it is declared without an initial value, it defaults to null
+ processIfTypesNotEqual(JReferenceType.NULL_TYPE, x.getType(), x.getSourceInfo());
}
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java
index 9a34f4d..a781602 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JsInteropRestrictionChecker.java
@@ -393,6 +393,10 @@
boolean hasOptionalParameters = false;
for (JParameter parameter : method.getParams()) {
if (parameter.isOptional()) {
+ if (parameter.getType().isPrimitiveType()) {
+ logError(method, "JsOptional parameter '%s' in method %s cannot be of primitive type.",
+ parameter.getName(), getMemberDescription(method));
+ }
hasOptionalParameters = true;
continue;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
index fb47e92..ac577f8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
@@ -23,7 +23,6 @@
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JParameter;
-import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.util.JsniRef;
@@ -75,7 +74,7 @@
if (fieldName.equals(JsniRef.CLASS)) {
return type;
- } else if (type instanceof JPrimitiveType) {
+ } else if (type.isPrimitiveType()) {
errorReporter.reportError("May not refer to fields on primitive types");
return null;
@@ -94,7 +93,7 @@
errorReporter.reportError("Unresolvable native reference to field '" + fieldName
+ "' in type '" + className + "'");
return null;
- } else if (type instanceof JPrimitiveType) {
+ } else if (type.isPrimitiveType()) {
errorReporter.reportError("May not refer to methods on primitive types");
return null;
} else {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/PostOptimizationCompoundAssignmentNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/PostOptimizationCompoundAssignmentNormalizer.java
index 56fc8fd..5145253 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/PostOptimizationCompoundAssignmentNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/PostOptimizationCompoundAssignmentNormalizer.java
@@ -67,7 +67,7 @@
return false;
}
// break up so that result may be coerced to LHS type
- if (lhsType instanceof JPrimitiveType && rhsType instanceof JPrimitiveType
+ if (lhsType.isPrimitiveType() && rhsType.isPrimitiveType()
&& widenType(lhsType, rhsType) != lhsType) {
return true;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
index 6380929..d09974f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
@@ -39,7 +39,6 @@
import com.google.gwt.dev.jjs.ast.JNewInstance;
import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JParameter;
-import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JRuntimeTypeReference;
@@ -629,7 +628,7 @@
JType leafType = primitiveTypeOrNullTypeOrArray(program, ((JArrayType) type).getLeafType());
return program.getOrCreateArrayType(leafType, ((JArrayType) type).getDims());
}
- if (type instanceof JPrimitiveType) {
+ if (type.isPrimitiveType()) {
return type;
}
return JReferenceType.NULL_TYPE;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ReferenceMapper.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ReferenceMapper.java
index ff57f5b..46453a4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ReferenceMapper.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ReferenceMapper.java
@@ -127,7 +127,7 @@
JType type = types.get(key);
if (type != null) {
- assert type instanceof JPrimitiveType || type.isNullType() || type.isExternal();
+ assert type.isPrimitiveType() || type.isNullType() || type.isExternal();
return type;
}
assert !(binding instanceof BaseTypeBinding);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java
index 80fd5dd..9c6e22e 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java
@@ -133,7 +133,7 @@
return exp;
}
- if ((type instanceof JPrimitiveType) && (exp instanceof JValueLiteral)) {
+ if (type.isPrimitiveType() && (exp instanceof JValueLiteral)) {
// Statically evaluate casting literals.
JPrimitiveType primitiveType = (JPrimitiveType) type;
JValueLiteral expLit = (JValueLiteral) exp;
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 2c4831a..3772b19 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
@@ -94,7 +94,7 @@
* Determines the type category for a specific type.
*/
public static TypeCategory typeCategoryForType(JType type, JProgram program) {
- if (type instanceof JPrimitiveType) {
+ if (type.isPrimitiveType()) {
if (type == JPrimitiveType.BOOLEAN) {
return TypeCategory.TYPE_PRIMITIVE_BOOLEAN;
} else if (type == JPrimitiveType.LONG) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java b/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
index 9116dc3..6945f5f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
@@ -59,7 +59,6 @@
import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JNullLiteral;
import com.google.gwt.dev.jjs.ast.JPermutationDependentValue;
-import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JStringLiteral;
@@ -1630,7 +1629,7 @@
}
private JType translate(JType type) {
- if (type instanceof JPrimitiveType) {
+ if (type.isPrimitiveType()) {
return type;
}
return translate((JReferenceType) type);
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java
index e7edec8..e114806 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/JsInteropRestrictionCheckerTest.java
@@ -1505,7 +1505,7 @@
" @JsConstructor public Buggy(@JsOptional Object a) {}",
" @JsMethod public void fun(int a, Object b, @JsOptional String c) {}",
" @JsMethod public void bar(int a, @JsOptional Object b, @JsOptional String c) {}",
- " @JsMethod public void baz(@JsOptional int a, @JsOptional Object b) {}",
+ " @JsMethod public void baz(@JsOptional String a, @JsOptional Object b) {}",
"}");
assertBuggySucceeds();
@@ -1544,13 +1544,13 @@
addSnippetImport("jsinterop.annotations.JsOptional");
addSnippetClassDecl(
"public static class Buggy {",
- " @JsConstructor public Buggy(@JsOptional int a, Object b, @JsOptional String c) {}",
+ " @JsConstructor public Buggy(@JsOptional String a, Object b, @JsOptional String c) {}",
" @JsMethod public void bar(int a, @JsOptional Object b, String c) {}",
" @JsMethod public void baz(@JsOptional Object b, String c, Object... os) {}",
"}");
assertBuggyFails(
- "Line 7: JsOptional parameter 'b' in method 'EntryPoint.Buggy.EntryPoint$Buggy(int, "
+ "Line 7: JsOptional parameter 'b' in method 'EntryPoint.Buggy.EntryPoint$Buggy(String, "
+ "Object, String)' cannot precede parameters that are not optional.",
"Line 8: JsOptional parameter 'c' in method 'void EntryPoint.Buggy.bar(int, Object,"
+ " String)' cannot precede parameters that are not optional.",
@@ -1558,6 +1558,21 @@
+ "Object[])' cannot precede parameters that are not optional.");
}
+ public void testJsOptionalOnPrimitiveTypedParametersFails() throws Exception {
+ addSnippetImport("jsinterop.annotations.JsMethod");
+ addSnippetImport("jsinterop.annotations.JsOptional");
+ addSnippetClassDecl(
+ "public static class Buggy {",
+ " @JsMethod public void m(@JsOptional int i, @JsOptional byte b) {}",
+ "}");
+
+ assertBuggyFails(
+ "Line 6: JsOptional parameter 'b' in method 'void EntryPoint.Buggy.m(int, byte)' cannot be "
+ + "of primitive type.",
+ "Line 6: JsOptional parameter 'i' in method 'void EntryPoint.Buggy.m(int, byte)' cannot be "
+ + "of primitive type.");
+ }
+
public void testJsOptionalOnNonJsExposedMethodsFails() throws Exception {
addSnippetImport("jsinterop.annotations.JsProperty");
addSnippetImport("jsinterop.annotations.JsOptional");