Use 'boolean' instead of 'Z' for JSNI primitive type qualifiers.
This change is transitional, we will continue to support the only style for now.
http://gwt-code-reviews.appspot.com/1295805/show
Review by: robertvawter@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9649 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java b/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java
index c5a492b..c2add7d 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java
@@ -280,13 +280,27 @@
className = className.substring(0, className.length() - 2);
}
- /*
- * TODO(bobv): OMG WTF LOL. Okay, but seriously, the LHS of a JSNI ref for
- * a primitive type should be the keyword, e.g. "int.class".
- */
- ReferenceBinding clazz = findClass(className);
- boolean isPrimitive = (clazz == null) && className.length() == 1
- && "ZBCDFIJSV".indexOf(className.charAt(0)) >= 0;
+ boolean isPrimitive = false;
+ TypeBinding binding = method.scope.getBaseType(className.toCharArray());
+ if (binding != null) {
+ isPrimitive = true;
+ } else {
+ binding = findClass(className);
+ }
+
+ // TODO(deprecation): remove this support eventually.
+ if (binding == null && className.length() == 1
+ && "ZBCDFIJSV".indexOf(className.charAt(0)) >= 0) {
+ isPrimitive = true;
+ binding = getTypeBinding(className.charAt(0));
+ assert binding != null;
+ JsniCollector.reportJsniWarning(
+ errorInfo,
+ method,
+ "Referencing primitive type '" + className
+ + "': this is deprecated, use '"
+ + String.valueOf(binding.sourceName()) + "' instead");
+ }
if (isArray || isPrimitive) {
if (!jsniRef.isField() || !jsniRef.memberName().equals("class")) {
@@ -302,26 +316,26 @@
return;
}
- // TODO(bobv): uncomment this.
- // ReferenceBinding clazz = findClass(className);
if (looksLikeAnonymousClass(jsniRef)
- || (clazz != null && clazz.isAnonymousType())) {
+ || (binding != null && binding.isAnonymousType())) {
emitError("Referencing class '" + className
+ ": JSNI references to anonymous classes are illegal");
- } else if (clazz != null) {
- if (clazz.isDeprecated()) {
- emitWarning("deprecation", "Referencing deprecated class '"
- + className + "'");
- }
-
- if (jsniRef.isMethod()) {
- checkMethodRef(clazz, jsniRef);
- } else {
- checkFieldRef(clazz, jsniRef);
- }
- } else {
+ return;
+ } else if (binding == null) {
emitError("JSNI Referencing class '" + className
+ "': unable to resolve class, expect subsequent failures");
+ return;
+ }
+ ReferenceBinding clazz = (ReferenceBinding) binding;
+ if (clazz.isDeprecated()) {
+ emitWarning("deprecation", "Referencing deprecated class '" + className
+ + "'");
+ }
+
+ if (jsniRef.isMethod()) {
+ checkMethodRef(clazz, jsniRef);
+ } else {
+ checkFieldRef(clazz, jsniRef);
}
}
@@ -406,6 +420,32 @@
return null;
}
+ @Deprecated
+ private TypeBinding getTypeBinding(char c) {
+ switch (c) {
+ case 'I':
+ return TypeBinding.INT;
+ case 'Z':
+ return TypeBinding.BOOLEAN;
+ case 'V':
+ return TypeBinding.VOID;
+ case 'C':
+ return TypeBinding.CHAR;
+ case 'D':
+ return TypeBinding.DOUBLE;
+ case 'B':
+ return TypeBinding.BYTE;
+ case 'F':
+ return TypeBinding.FLOAT;
+ case 'J':
+ return TypeBinding.LONG;
+ case 'S':
+ return TypeBinding.SHORT;
+ default:
+ return null;
+ }
+ }
+
private boolean looksLikeAnonymousClass(JsniRef jsniRef) {
char[][] compoundName = getCompoundName(jsniRef);
for (char[] part : compoundName) {
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 233c0e9..a4ca996 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
@@ -106,6 +106,11 @@
private static final int IS_NULL = 0;
+ private static final Map<String, JPrimitiveType> primitiveTypes = new HashMap<String, JPrimitiveType>();
+
+ @Deprecated
+ private static final Map<String, JPrimitiveType> primitiveTypesDeprecated = new HashMap<String, JPrimitiveType>();
+
static {
INDEX_TYPES_SET.addAll(CODEGEN_TYPES_SET);
@@ -133,6 +138,35 @@
}
}
}
+
+ primitiveTypes.put(JPrimitiveType.BOOLEAN.getName(), JPrimitiveType.BOOLEAN);
+ primitiveTypes.put(JPrimitiveType.BYTE.getName(), JPrimitiveType.BYTE);
+ primitiveTypes.put(JPrimitiveType.CHAR.getName(), JPrimitiveType.CHAR);
+ primitiveTypes.put(JPrimitiveType.DOUBLE.getName(), JPrimitiveType.DOUBLE);
+ primitiveTypes.put(JPrimitiveType.FLOAT.getName(), JPrimitiveType.FLOAT);
+ primitiveTypes.put(JPrimitiveType.INT.getName(), JPrimitiveType.INT);
+ primitiveTypes.put(JPrimitiveType.LONG.getName(), JPrimitiveType.LONG);
+ primitiveTypes.put(JPrimitiveType.SHORT.getName(), JPrimitiveType.SHORT);
+ primitiveTypes.put(JPrimitiveType.VOID.getName(), JPrimitiveType.VOID);
+
+ primitiveTypesDeprecated.put(JPrimitiveType.BOOLEAN.getJsniSignatureName(),
+ JPrimitiveType.BOOLEAN);
+ primitiveTypesDeprecated.put(JPrimitiveType.BYTE.getJsniSignatureName(),
+ JPrimitiveType.BYTE);
+ primitiveTypesDeprecated.put(JPrimitiveType.CHAR.getJsniSignatureName(),
+ JPrimitiveType.CHAR);
+ primitiveTypesDeprecated.put(JPrimitiveType.DOUBLE.getJsniSignatureName(),
+ JPrimitiveType.DOUBLE);
+ primitiveTypesDeprecated.put(JPrimitiveType.FLOAT.getJsniSignatureName(),
+ JPrimitiveType.FLOAT);
+ primitiveTypesDeprecated.put(JPrimitiveType.INT.getJsniSignatureName(),
+ JPrimitiveType.INT);
+ primitiveTypesDeprecated.put(JPrimitiveType.LONG.getJsniSignatureName(),
+ JPrimitiveType.LONG);
+ primitiveTypesDeprecated.put(JPrimitiveType.SHORT.getJsniSignatureName(),
+ JPrimitiveType.SHORT);
+ primitiveTypesDeprecated.put(JPrimitiveType.VOID.getJsniSignatureName(),
+ JPrimitiveType.VOID);
}
/**
@@ -1054,29 +1088,14 @@
className = className.substring(0, className.length() - 2);
}
- JType type;
- if ("Z".equals(className)) {
- type = getTypePrimitiveBoolean();
- } else if ("B".equals(className)) {
- type = getTypePrimitiveByte();
- } else if ("C".equals(className)) {
- type = getTypePrimitiveChar();
- } else if ("D".equals(className)) {
- type = getTypePrimitiveDouble();
- } else if ("F".equals(className)) {
- type = getTypePrimitiveFloat();
- } else if ("I".equals(className)) {
- type = getTypePrimitiveInt();
- } else if ("J".equals(className)) {
- type = getTypePrimitiveLong();
- } else if ("S".equals(className)) {
- type = getTypePrimitiveShort();
- } else if ("V".equals(className)) {
- type = getTypeVoid();
- } else {
+ JType type = primitiveTypes.get(className);
+ if (type == null) {
type = getFromTypeMap(className);
}
-
+ // TODO(deprecation): remove support for this.
+ if (type == null) {
+ type = primitiveTypesDeprecated.get(className);
+ }
if (type == null || dim == 0) {
return type;
} else {
diff --git a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
index 9e1e93d..d5ed6ed 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
@@ -208,45 +208,31 @@
* class name could not be found
*/
private Class<?> getClassFromBinaryName(String binaryClassName) {
- try {
- int dims = 0;
- while (binaryClassName.endsWith("[]")) {
- dims++;
- binaryClassName = binaryClassName.substring(0,
- binaryClassName.length() - 2);
- }
+ int dims = 0;
+ while (binaryClassName.endsWith("[]")) {
+ dims++;
+ binaryClassName = binaryClassName.substring(0,
+ binaryClassName.length() - 2);
+ }
- Class<?> clazz;
- if ("Z".equals(binaryClassName)) {
- clazz = boolean.class;
- } else if ("B".equals(binaryClassName)) {
- clazz = byte.class;
- } else if ("C".equals(binaryClassName)) {
- clazz = char.class;
- } else if ("D".equals(binaryClassName)) {
- clazz = double.class;
- } else if ("F".equals(binaryClassName)) {
- clazz = float.class;
- } else if ("I".equals(binaryClassName)) {
- clazz = int.class;
- } else if ("J".equals(binaryClassName)) {
- clazz = long.class;
- } else if ("S".equals(binaryClassName)) {
- clazz = short.class;
- } else if ("V".equals(binaryClassName)) {
- clazz = void.class;
- } else {
+ Class<?> clazz = primitiveTypes.get(binaryClassName);
+ if (clazz == null) {
+ try {
clazz = Class.forName(binaryClassName, false,
CompilingClassLoader.this);
+ } catch (ClassNotFoundException e) {
}
-
- if (dims > 0) {
- return Array.newInstance(clazz, new int[dims]).getClass();
- } else {
- return clazz;
- }
- } catch (ClassNotFoundException e) {
- return null;
+ }
+ // TODO(deprecation): remove this support eventually.
+ if (clazz == null && binaryClassName.length() == 1
+ && "ZBCDFIJSV".indexOf(binaryClassName.charAt(0)) >= 0) {
+ clazz = getDeprecatedPrimitiveType(binaryClassName.charAt(0));
+ assert clazz != null;
+ }
+ if (dims > 0) {
+ return Array.newInstance(clazz, new int[dims]).getClass();
+ } else {
+ return clazz;
}
}
@@ -320,6 +306,32 @@
return dispClassInfo;
}
+ @Deprecated
+ private Class<?> getDeprecatedPrimitiveType(char c) {
+ switch (c) {
+ case 'Z':
+ return boolean.class;
+ case 'B':
+ return byte.class;
+ case 'C':
+ return char.class;
+ case 'D':
+ return double.class;
+ case 'F':
+ return float.class;
+ case 'I':
+ return int.class;
+ case 'J':
+ return long.class;
+ case 'S':
+ return short.class;
+ case 'V':
+ return void.class;
+ default:
+ return null;
+ }
+ }
+
/**
* Synthesizes a dispatch identifier for the given class and member ids.
*
@@ -706,6 +718,20 @@
*/
private static byte[] javaScriptHostBytes;
+ private static final Map<String, Class<?>> primitiveTypes = new HashMap<String, Class<?>>();
+
+ static {
+ primitiveTypes.put(boolean.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(byte.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(char.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(double.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(float.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(int.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(long.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(short.class.getSimpleName(), boolean.class);
+ primitiveTypes.put(void.class.getSimpleName(), boolean.class);
+ }
+
static {
for (Class<?> c : BRIDGE_CLASSES) {
BRIDGE_CLASS_NAMES.put(c.getName(), c);
diff --git a/dev/core/test/com/google/gwt/dev/javac/JsniCheckerTest.java b/dev/core/test/com/google/gwt/dev/javac/JsniCheckerTest.java
index e32b59e..b4006c0 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JsniCheckerTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JsniCheckerTest.java
@@ -466,25 +466,36 @@
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" native void jsniMethod() /*-{\n");
- code.append(" @Z::blah;\n");
+ code.append(" @boolean::blah;\n");
code.append(" }-*/;\n");
code.append("}\n");
shouldGenerateError(
code,
3,
- "Referencing member 'Z.blah': 'class' is the only legal reference for primitive types");
+ "Referencing member 'boolean.blah': 'class' is the only legal reference for primitive types");
}
public void testPrimitiveClass() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" native void jsniMethod() /*-{\n");
- code.append(" @Z::class;\n");
+ code.append(" @boolean::class;\n");
code.append(" }-*/;\n");
code.append("}\n");
shouldGenerateNoWarning(code);
}
+ public void testPrimitiveClassDeprecated() {
+ StringBuffer code = new StringBuffer();
+ code.append("class Buggy {\n");
+ code.append(" native void jsniMethod() /*-{\n");
+ code.append(" @Z::class;\n");
+ code.append(" }-*/;\n");
+ code.append("}\n");
+ shouldGenerateWarning(code, 3,
+ "Referencing primitive type 'Z': this is deprecated, use 'boolean' instead");
+ }
+
public void testRefInString() {
{
StringBuffer code = new StringBuffer();
diff --git a/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java b/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java
index 19e33bc..7ea1bac 100644
--- a/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java
+++ b/user/src/com/google/gwt/rpc/rebind/RpcProxyCreator.java
@@ -323,19 +323,10 @@
JPrimitiveType serializablePrimitive = serializableType.isPrimitive();
if (serializableArray != null) {
sb.append("\n@Rescue(className = \"");
- if (serializableArray.getLeafType() instanceof JPrimitiveType) {
- sb.append(serializableArray.getLeafType().getJNISignature());
- for (int i = 0, j = serializableArray.getRank(); i < j; i++) {
- sb.append("[]");
- }
- } else {
- sb.append(serializableArray.getQualifiedSourceName());
- }
+ sb.append(serializableArray.getQualifiedSourceName());
sb.append("\",\n instantiable = true),");
-
} else if (serializableClass != null) {
writeSingleRescue(typeOracle, deserializationSto, sb, serializableClass);
-
} else if (serializablePrimitive != null) {
JClassType boxedClass = typeOracle.findType(serializablePrimitive.getQualifiedBoxedSourceName());
assert boxedClass != null : "No boxed version of "
diff --git a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
index 0f7726a..423591e 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/TypeSerializerCreator.java
@@ -574,20 +574,13 @@
continue;
}
- String jsniTypeRef;
- jsniTypeRef = SerializationUtils.getRpcTypeName(type.getLeafType());
- while (type.isArray() != null) {
- jsniTypeRef += "[]";
- type = type.isArray().getComponentType();
- }
-
if (shard && ++shardCount % shardSize == 0) {
srcWriter.println("})();");
srcWriter.println("(function() {");
}
srcWriter.println("result[@com.google.gwt.core.client.impl.Impl::getHashCode(Ljava/lang/Object;)(@"
- + jsniTypeRef + "::class)] = \"" + typeString + "\";");
+ + type.getQualifiedSourceName() + "::class)] = \"" + typeString + "\";");
}
if (shard) {