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; }