GwtAstBuilder better handling of JSNI refs to constants.
Turns out the target GWT field is not always fully baked, as it was in GenerateJavaAST. Using JDT to get the compile-time constant is the right approach.
http://gwt-code-reviews.appspot.com/1449818/
Review by: jbrosenberg@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10337 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
index 6a461eb..6b594f7 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -34,7 +34,6 @@
import com.google.gwt.dev.jjs.ast.JMethodBody;
import com.google.gwt.dev.jjs.ast.JNullType;
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.JType;
@@ -63,7 +62,6 @@
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
@@ -570,27 +568,9 @@
private JField createField(SourceInfo info, FieldBinding binding, JDeclaredType enclosingType) {
JType type = getType(binding.type);
-
- boolean isCompileTimeConstant =
- binding.isStatic() && (binding.isFinal()) && (binding.constant() != Constant.NotAConstant)
- && (binding.type.isBaseType());
- assert (type instanceof JPrimitiveType || !isCompileTimeConstant);
-
- assert (!binding.isFinal() || !binding.isVolatile());
- Disposition disposition;
- if (isCompileTimeConstant) {
- disposition = Disposition.COMPILE_TIME_CONSTANT;
- } else if (binding.isFinal()) {
- disposition = Disposition.FINAL;
- } else if (binding.isVolatile()) {
- disposition = Disposition.VOLATILE;
- } else {
- disposition = Disposition.NONE;
- }
-
JField field =
program.createField(info, String.valueOf(binding.name), enclosingType, type, binding
- .isStatic(), disposition);
+ .isStatic(), GwtAstBuilder.getFieldDisposition(binding));
typeMap.put(binding, field);
info.addCorrelation(info.getCorrelator().by(field));
return field;
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 3297187..8fad08b 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
@@ -236,6 +236,7 @@
* Resolves local references to function parameters, and JSNI references.
*/
private class JsniResolver extends JsModVisitor {
+ private final GenerateJavaScriptLiterals generator = new GenerateJavaScriptLiterals();
private final JsniMethodBody nativeMethodBody;
private JsniResolver(JsniMethodBody nativeMethodBody) {
@@ -260,8 +261,23 @@
JType type = typeMap.get((TypeBinding) binding);
processClassLiteral(x, info, type, ctx);
} else if (binding instanceof FieldBinding) {
- JField field = typeMap.get((FieldBinding) binding);
- processField(x, info, field, ctx);
+ FieldBinding fieldBinding = (FieldBinding) binding;
+ /*
+ * We must replace any compile-time constants with the constant
+ * value of the field.
+ */
+ if (isCompileTimeConstant(fieldBinding)) {
+ assert !ctx.isLvalue();
+ JExpression constant = getConstant(info, fieldBinding.constant());
+ generator.accept(constant);
+ JsExpression result = generator.pop();
+ assert (result != null);
+ ctx.replaceMe(result);
+ } else {
+ // Normal: create a jsniRef.
+ JField field = typeMap.get(fieldBinding);
+ processField(x, info, field, ctx);
+ }
} else {
JMethod method = typeMap.get((MethodBinding) binding);
processMethod(x, info, method);
@@ -276,25 +292,6 @@
}
private void processField(JsNameRef nameRef, SourceInfo info, JField field, JsContext ctx) {
- /*
- * We must replace any compile-time constants with the constant value of
- * the field.
- */
- if (field.isCompileTimeConstant()) {
- assert !ctx.isLvalue();
- JLiteral initializer = field.getConstInitializer();
- JType type = initializer.getType();
- if (type instanceof JPrimitiveType || initializer instanceof JStringLiteral) {
- GenerateJavaScriptLiterals generator = new GenerateJavaScriptLiterals();
- generator.accept(initializer);
- JsExpression result = generator.peek();
- assert (result != null);
- ctx.replaceMe(result);
- return;
- }
- }
-
- // Normal: create a jsniRef.
JsniFieldRef fieldRef =
new JsniFieldRef(info, nameRef.getIdent(), field, curClass.type, ctx.isLvalue());
nativeMethodBody.addJsniRef(fieldRef);
@@ -2811,6 +2808,20 @@
return result.toString();
}
+ static Disposition getFieldDisposition(FieldBinding binding) {
+ Disposition disposition;
+ if (isCompileTimeConstant(binding)) {
+ disposition = Disposition.COMPILE_TIME_CONSTANT;
+ } else if (binding.isFinal()) {
+ disposition = Disposition.FINAL;
+ } else if (binding.isVolatile()) {
+ disposition = Disposition.VOLATILE;
+ } else {
+ disposition = Disposition.NONE;
+ }
+ return disposition;
+ }
+
static String intern(char[] cs) {
return intern(String.valueOf(cs));
}
@@ -2823,6 +2834,16 @@
return binding.isNestedType() && !binding.isStatic();
}
+ private static boolean isCompileTimeConstant(FieldBinding binding) {
+ assert !binding.isFinal() || !binding.isVolatile();
+ boolean isCompileTimeConstant =
+ binding.isStatic() && binding.isFinal() && (binding.constant() != Constant.NotAConstant);
+ if (isCompileTimeConstant) {
+ assert binding.type.isBaseType() || (binding.type.id == TypeIds.T_JavaLangString);
+ }
+ return isCompileTimeConstant;
+ }
+
/**
* Returns <code>true</code> if JDT optimized the condition to
* <code>false</code>.
@@ -2971,26 +2992,9 @@
new JEnumField(info, intern(binding.name), binding.original().id,
(JEnumType) enclosingType, (JClassType) type);
} else {
- boolean isCompileTimeConstant =
- binding.isStatic() && (binding.isFinal())
- && (binding.constant() != Constant.NotAConstant) && (binding.type.isBaseType());
- assert (type instanceof JPrimitiveType || !isCompileTimeConstant);
-
- assert (!binding.isFinal() || !binding.isVolatile());
- Disposition disposition;
- if (isCompileTimeConstant) {
- disposition = Disposition.COMPILE_TIME_CONSTANT;
- } else if (binding.isFinal()) {
- disposition = Disposition.FINAL;
- } else if (binding.isVolatile()) {
- disposition = Disposition.VOLATILE;
- } else {
- disposition = Disposition.NONE;
- }
-
field =
new JField(info, intern(binding.name), enclosingType, type, binding.isStatic(),
- disposition);
+ getFieldDisposition(binding));
}
enclosingType.addField(field);
typeMap.setField(binding, field);
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 2b19c5c..2d99763 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
@@ -24,7 +24,6 @@
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JEnumType;
import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JField.Disposition;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JNullType;
@@ -34,7 +33,6 @@
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.util.StringInterner;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
@@ -242,27 +240,9 @@
private JField createField(FieldBinding binding) {
JDeclaredType enclosingType = (JDeclaredType) get(binding.declaringClass);
-
- boolean isCompileTimeConstant =
- binding.isStatic() && (binding.isFinal()) && (binding.constant() != Constant.NotAConstant)
- && (binding.type.isBaseType());
- assert (get(binding.type) instanceof JPrimitiveType || !isCompileTimeConstant);
-
- assert (!binding.isFinal() || !binding.isVolatile());
- Disposition disposition;
- if (isCompileTimeConstant) {
- disposition = Disposition.COMPILE_TIME_CONSTANT;
- } else if (binding.isFinal()) {
- disposition = Disposition.FINAL;
- } else if (binding.isVolatile()) {
- disposition = Disposition.VOLATILE;
- } else {
- disposition = Disposition.NONE;
- }
-
JField field =
new JField(SourceOrigin.UNKNOWN, intern(binding.name), enclosingType, get(binding.type),
- binding.isStatic(), disposition);
+ binding.isStatic(), GwtAstBuilder.getFieldDisposition(binding));
enclosingType.addField(field);
return field;
}