Remove JAnnotation from GWT AST.
It's taking up extra memory and conceptual baggage, and it's making my GwtAstBuilder work more complicated. Instead, record ArtificialRescues directly during AST constructions and don't keep annotation nodes around.
http://gwt-code-reviews.appspot.com/1420803/
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10024 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/ArtificialRescueChecker.java b/dev/core/src/com/google/gwt/dev/javac/ArtificialRescueChecker.java
index eee5bbd..8387190 100644
--- a/dev/core/src/com/google/gwt/dev/javac/ArtificialRescueChecker.java
+++ b/dev/core/src/com/google/gwt/dev/javac/ArtificialRescueChecker.java
@@ -17,57 +17,322 @@
import com.google.gwt.core.client.impl.ArtificialRescue;
import com.google.gwt.dev.jdt.SafeASTVisitor;
-import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.dev.util.JsniRef;
import com.google.gwt.dev.util.collect.Lists;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
-import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
-import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
+import org.eclipse.jdt.internal.compiler.impl.StringConstant;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* Checks the validity of ArtificialRescue annotations.
*
* <ul>
* <li>(1) The ArtificialRescue annotation is only used in generated code.</li>
- * <li>(2) The className value names a type known to GWT (ignoring access rules)
- * </li>
- * <li>(3) The methods and fields of the type are known to GWT</li>
+ * <li>(2) The className value names a type known to GWT.</li>
+ * <li>(3) The methods and fields of the type are known to GWT.</li>
* </ul>
*/
-public class ArtificialRescueChecker {
- private class Visitor extends SafeASTVisitor {
+public abstract class ArtificialRescueChecker {
- {
- assert collectTypes || reportErrors : "No work to be done";
+ /**
+ * Represents a single
+ * {@link com.google.gwt.core.client.impl.ArtificialRescue.Rescue}.
+ * <p>
+ * Only public so it can be used by
+ * {@link com.google.gwt.dev.jjs.impl.GenerateJavaAST}.
+ */
+ public static class RescueData {
+ private static final RescueData[] EMPTY_RESCUEDATA = new RescueData[0];
+
+ public static RescueData[] createFromAnnotations(Annotation[] annotations) {
+ RescueData[] result = EMPTY_RESCUEDATA;
+ for (Annotation a : annotations) {
+ ReferenceBinding binding = (ReferenceBinding) a.resolvedType;
+ String name = CharOperation.toString(binding.compoundName);
+ if (!name.equals(ArtificialRescue.class.getName())) {
+ continue;
+ }
+ return createFromArtificialRescue(a);
+ }
+ return result;
}
+ public static RescueData[] createFromArtificialRescue(Annotation artificialRescue) {
+ Object[] values = null;
+ RescueData[] result = EMPTY_RESCUEDATA;
+ for (ElementValuePair pair : artificialRescue.computeElementValuePairs()) {
+ if ("value".equals(String.valueOf(pair.getName()))) {
+ Object value = pair.getValue();
+ if (value instanceof AnnotationBinding) {
+ values = new Object[]{value};
+ } else {
+ values = (Object[]) value;
+ }
+ break;
+ }
+ }
+ assert values != null;
+ if (values.length > 0) {
+ result = new RescueData[values.length];
+ for (int i = 0; i < result.length; ++i) {
+ result[i] = createFromRescue((AnnotationBinding) values[i]);
+ }
+ }
+ return result;
+ }
+
+ private static RescueData createFromRescue(AnnotationBinding rescue) {
+ String className = null;
+ boolean instantiable = false;
+ String[] methods = Empty.STRINGS;
+ String[] fields = Empty.STRINGS;
+ for (ElementValuePair pair : rescue.getElementValuePairs()) {
+ String name = String.valueOf(pair.getName());
+ if ("className".equals(name)) {
+ className = ((StringConstant) pair.getValue()).stringValue();
+ } else if ("instantiable".equals(name)) {
+ BooleanConstant value = (BooleanConstant) pair.getValue();
+ instantiable = value.booleanValue();
+ } else if ("methods".equals(name)) {
+ methods = getValueAsStringArray(pair.getValue());
+ } else if ("fields".equals(name)) {
+ fields = getValueAsStringArray(pair.getValue());
+ } else {
+ assert false : "Unknown ArtificialRescue field";
+ }
+ }
+ assert className != null;
+ return new RescueData(className, instantiable, fields, methods);
+ }
+
+ private static String[] getValueAsStringArray(Object value) {
+ if (value instanceof StringConstant) {
+ return new String[]{((StringConstant) value).stringValue()};
+ }
+ Object[] values = (Object[]) value;
+ String[] toReturn = new String[values.length];
+ for (int i = 0; i < toReturn.length; ++i) {
+ toReturn[i] = ((StringConstant) values[i]).stringValue();
+ }
+ return toReturn;
+ }
+
+ private final String className;
+ private final String[] fields;
+ private final boolean instantiable;
+ private final String[] methods;
+
+ RescueData(String className, boolean instantiable, String[] fields, String[] methods) {
+ this.className = className;
+ this.instantiable = instantiable;
+ this.methods = methods;
+ this.fields = fields;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String[] getFields() {
+ return fields;
+ }
+
+ public String[] getMethods() {
+ return methods;
+ }
+
+ public boolean isInstantiable() {
+ return instantiable;
+ }
+ }
+
+ /**
+ * Checks that references are legal and resolve to a known element. Collects
+ * the rescued elements per type for later user.
+ */
+ private static class Checker extends ArtificialRescueChecker {
+ private final Map<TypeDeclaration, Binding[]> artificialRescues;
+ private transient List<Binding> currentBindings = new ArrayList<Binding>();
+
+ public Checker(CompilationUnitDeclaration cud, Map<TypeDeclaration, Binding[]> artificialRescues) {
+ super(cud);
+ this.artificialRescues = artificialRescues;
+ }
+
+ @Override
+ protected void processRescue(RescueData rescue) {
+ String className = rescue.getClassName();
+ // Strip off any array-like extensions and just find base type
+ int arrayDims = 0;
+ while (className.endsWith("[]")) {
+ className = className.substring(0, className.length() - 2);
+ ++arrayDims;
+ }
+
+ // Goal (2) The className value names a type known to GWT.
+ char[][] compoundName = CharOperation.splitOn('.', className.toCharArray());
+ TypeBinding typeBinding = cud.scope.getType(compoundName, compoundName.length);
+ if (typeBinding == null) {
+ error(notFound(className));
+ return;
+ }
+ if (typeBinding instanceof ProblemReferenceBinding) {
+ ProblemReferenceBinding problem = (ProblemReferenceBinding) typeBinding;
+ if (problem.problemId() == ProblemReasons.NotVisible) {
+ // Ignore
+ } else if (problem.problemId() == ProblemReasons.NotFound) {
+ error(notFound(className));
+ } else {
+ error(unknownProblem(className, problem));
+ }
+ return;
+ }
+ if (arrayDims > 0) {
+ typeBinding = cud.scope.createArrayType(typeBinding, arrayDims);
+ }
+ if (rescue.isInstantiable()) {
+ currentBindings.add(typeBinding);
+ }
+ if (typeBinding instanceof BaseTypeBinding || arrayDims > 0) {
+ // No methods or fields on primitive types or array types (3)
+ if (rescue.getMethods().length > 0) {
+ error(noMethodsAllowed());
+ }
+
+ if (rescue.getFields().length > 0) {
+ error(noFieldsAllowed());
+ }
+ return;
+ }
+
+ // Goal (3) The methods and fields of the type are known to GWT.
+ ReferenceBinding ref = (ReferenceBinding) typeBinding;
+ for (String field : rescue.getFields()) {
+ FieldBinding fieldBinding = ref.getField(field.toCharArray(), false);
+ if (fieldBinding == null) {
+ error(unknownField(field));
+ } else {
+ currentBindings.add(fieldBinding);
+ }
+ }
+ for (String method : rescue.getMethods()) {
+ if (method.contains("@")) {
+ error(nameAndTypesOnly());
+ continue;
+ }
+ // Method signatures use the same format as JSNI method refs.
+ JsniRef jsni = JsniRef.parse("@foo::" + method);
+ if (jsni == null) {
+ error(badMethodSignature(method));
+ continue;
+ }
+
+ MethodBinding[] methodBindings;
+ if (jsni.memberName().equals(String.valueOf(ref.compoundName[ref.compoundName.length - 1]))) {
+ // Constructor
+ methodBindings = ref.getMethods("<init>".toCharArray());
+ } else {
+ methodBindings = ref.getMethods(jsni.memberName().toCharArray());
+ }
+ boolean found = false;
+ for (MethodBinding methodBinding : methodBindings) {
+ if (jsni.matchesAnyOverload() || jsni.paramTypesString().equals(sig(methodBinding))) {
+ currentBindings.add(methodBinding);
+ found = true;
+ }
+ }
+ if (!found) {
+ error(noMethod(className, jsni.memberSignature()));
+ continue;
+ }
+ }
+ }
+
+ @Override
+ protected void processType(TypeDeclaration x) {
+ super.processType(x);
+ if (currentBindings.size() > 0) {
+ Binding[] result = currentBindings.toArray(new Binding[currentBindings.size()]);
+ artificialRescues.put(x, result);
+ currentBindings = new ArrayList<Binding>();
+ }
+ }
+
+ private String sig(MethodBinding methodBinding) {
+ StringBuilder sb = new StringBuilder();
+ for (TypeBinding paramType : methodBinding.parameters) {
+ sb.append(paramType.signature());
+ }
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Collects only the names of the rescued types; does not report errors.
+ */
+ private static class Collector extends ArtificialRescueChecker {
+ private final List<String> referencedTypes;
+
+ public Collector(CompilationUnitDeclaration cud, List<String> referencedTypes) {
+ super(cud);
+ this.referencedTypes = referencedTypes;
+ }
+
+ @Override
+ protected void processRescue(RescueData rescue) {
+ String className = rescue.getClassName();
+ while (className.endsWith("[]")) {
+ className = className.substring(0, className.length() - 2);
+ }
+ referencedTypes.add(className);
+ }
+ }
+
+ /**
+ * Records an error if artificial rescues are used at all.
+ */
+ private static class Disallowed extends ArtificialRescueChecker {
+ public Disallowed(CompilationUnitDeclaration cud) {
+ super(cud);
+ }
+
+ @Override
+ protected void processRescue(RescueData rescue) {
+ // Goal (1) ArtificialRescue annotation is only used in generated code.
+ error(onlyGeneratedCode());
+ }
+ }
+
+ private class Visitor extends SafeASTVisitor {
@Override
public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
processType(memberTypeDeclaration);
}
@Override
- public void endVisit(TypeDeclaration typeDeclaration,
- CompilationUnitScope scope) {
+ public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
processType(typeDeclaration);
}
@@ -75,234 +340,29 @@
public void endVisitValid(TypeDeclaration localTypeDeclaration, BlockScope scope) {
processType(localTypeDeclaration);
}
-
- private void processArtificialRescue(Annotation rescue) {
- if (!allowArtificialRescue) {
- // Goal (1)
- GWTProblem.recordError(rescue, cud, onlyGeneratedCode(), null);
- return;
- }
-
- String className = null;
- String[] methods = Empty.STRINGS;
- String[] fields = Empty.STRINGS;
- for (MemberValuePair pair : rescue.memberValuePairs()) {
- String name = String.valueOf(pair.name);
- if ("className".equals(name)) {
- className = pair.value.constant.stringValue();
- } else if ("methods".equals(name)) {
- methods = stringArrayFromValue(pair.value);
- } else if ("fields".equals(name)) {
- fields = stringArrayFromValue(pair.value);
- }
- }
-
- assert className != null;
-
- if (collectTypes) {
- referencedTypes = Lists.add(referencedTypes, className);
- }
-
- boolean isArray = false;
- while (className.endsWith("[]")) {
- className = className.substring(0, className.length() - 2);
- if (collectTypes) {
- referencedTypes = Lists.add(referencedTypes, className);
- }
- isArray = true;
- }
-
- if (!reportErrors) {
- // Nothing else to do
- return;
- }
-
- // Goal (2)
- // Strip off any array-like extensions and just find base type
-
- // Fix JSNI primitive type names to something JDT will understand
- if (isArray && className.length() == 1) {
- switch (className.charAt(0)) {
- case 'B':
- className = "byte";
- break;
- case 'C':
- className = "char";
- break;
- case 'D':
- className = "double";
- break;
- case 'F':
- className = "float";
- break;
- case 'I':
- className = "int";
- break;
- case 'J':
- className = "long";
- break;
- case 'S':
- className = "short";
- break;
- case 'Z':
- className = "boolean";
- break;
- }
- }
-
- char[][] compoundName = CharOperation.splitOn('.',
- className.toCharArray());
- TypeBinding typeBinding = cud.scope.getType(compoundName,
- compoundName.length);
- if (typeBinding == null) {
- GWTProblem.recordError(rescue, cud, notFound(className), null);
- } else if (typeBinding instanceof ProblemReferenceBinding) {
- ProblemReferenceBinding problem = (ProblemReferenceBinding) typeBinding;
- if (problem.problemId() == ProblemReasons.NotVisible) {
- // Ignore
- } else if (problem.problemId() == ProblemReasons.NotFound) {
- GWTProblem.recordError(rescue, cud, notFound(className), null);
- } else {
- GWTProblem.recordError(rescue, cud,
- unknownProblem(className, problem), null);
- }
- } else if (typeBinding instanceof BaseTypeBinding) {
- // No methods or fields on primitive types (3)
- if (methods.length > 0) {
- GWTProblem.recordError(rescue, cud, noMethodsAllowed(), null);
- }
-
- if (fields.length > 0) {
- GWTProblem.recordError(rescue, cud, noFieldsAllowed(), null);
- }
- } else if (typeBinding instanceof ReferenceBinding) {
- ReferenceBinding ref = (ReferenceBinding) typeBinding;
-
- if (isArray) {
- // No methods or fields on array types (3)
- if (methods.length > 0) {
- GWTProblem.recordError(rescue, cud, noMethodsAllowed(), null);
- }
-
- if (fields.length > 0) {
- GWTProblem.recordError(rescue, cud, noFieldsAllowed(), null);
- }
- } else {
- // Check methods on reference types (3)
- for (String method : methods) {
- if (method.contains("@")) {
- GWTProblem.recordError(rescue, cud, nameAndTypesOnly(), null);
- continue;
- }
- JsniRef jsni = JsniRef.parse("@foo::" + method);
- if (jsni == null) {
- GWTProblem.recordError(rescue, cud, badMethodSignature(method),
- null);
- continue;
- }
-
- if (jsni.memberName().equals(
- String.valueOf(ref.compoundName[ref.compoundName.length - 1]))) {
- // Constructor
- } else {
- MethodBinding[] methodBindings = ref.getMethods(jsni.memberName().toCharArray());
- if (methodBindings == null || methodBindings.length == 0) {
- GWTProblem.recordError(rescue, cud, noMethod(className,
- jsni.memberName()), null);
- continue;
- }
- }
- }
-
- // Check fields on reference types (3)
- for (String field : fields) {
- if (ref.getField(field.toCharArray(), false) == null) {
- GWTProblem.recordError(rescue, cud, unknownField(field), null);
- }
- }
- }
- }
- }
-
- /**
- * Examine a TypeDeclaration for ArtificialRescue annotations. Delegates to
- * {@link #processArtificialRescue(Annotation)} to complete the processing.
- */
- private void processType(TypeDeclaration x) {
- if (x.annotations == null) {
- return;
- }
-
- for (Annotation a : x.annotations) {
- if (!ArtificialRescue.class.getName().equals(
- CharOperation.toString(((ReferenceBinding) a.resolvedType).compoundName))) {
- continue;
- }
-
- // Sometimes it's a SingleMemberAnnotation, other times it's not
- Expression value = null;
- if (a instanceof SingleMemberAnnotation) {
- value = ((SingleMemberAnnotation) a).memberValue;
- } else {
- for (MemberValuePair pair : a.memberValuePairs()) {
- if ("value".equals(String.valueOf(pair.name))) {
- value = pair.value;
- break;
- }
- }
- }
-
- assert value != null;
- if (value instanceof ArrayInitializer) {
- for (Expression e : ((ArrayInitializer) value).expressions) {
- processArtificialRescue((Annotation) e);
- }
- } else if (value instanceof Annotation) {
- processArtificialRescue((Annotation) value);
- } else {
- throw new InternalCompilerException(
- "Unable to process annotation with value of type "
- + value.getClass().getName());
- }
-
- return;
- }
- }
-
- private String[] stringArrayFromValue(Expression value) {
- if (value instanceof StringLiteral) {
- return new String[] {value.constant.stringValue()};
- } else if (value instanceof ArrayInitializer) {
- ArrayInitializer init = (ArrayInitializer) value;
- String[] toReturn = new String[init.expressions == null ? 0
- : init.expressions.length];
- for (int i = 0; i < toReturn.length; i++) {
- toReturn[i] = init.expressions[i].constant.stringValue();
- }
- return toReturn;
- } else {
- throw new InternalCompilerException("Unhandled value type "
- + value.getClass().getName());
- }
- }
}
/**
* Check the {@link ArtificialRescue} annotations in a CompilationUnit. Errors
* are reported through {@link GWTProblem}.
*/
- public static void check(CompilationUnitDeclaration cud,
- boolean allowArtificialRescue) {
- new ArtificialRescueChecker(cud, allowArtificialRescue).check();
+ public static void check(CompilationUnitDeclaration cud, boolean allowArtificialRescue,
+ Map<TypeDeclaration, Binding[]> artificialRescues) {
+ if (allowArtificialRescue) {
+ new Checker(cud, artificialRescues).exec();
+ } else {
+ new Disallowed(cud).exec();
+ }
}
/**
* Report all types named in {@link ArtificialRescue} annotations in a CUD. No
* error checking is done.
*/
- public static List<String> collectReferencedTypes(
- CompilationUnitDeclaration cud) {
- return new ArtificialRescueChecker(cud).collect();
+ public static List<String> collectReferencedTypes(CompilationUnitDeclaration cud) {
+ ArrayList<String> result = new ArrayList<String>();
+ new Collector(cud, result).exec();
+ return Lists.normalize(result);
}
static String badMethodSignature(String method) {
@@ -317,8 +377,8 @@
return "Cannot refer to fields on array or primitive types";
}
- static String noMethod(String className, String methodName) {
- return "No method named " + methodName + " in type " + className;
+ static String noMethod(String className, String methodSig) {
+ return "No method " + methodSig + " in type " + className;
}
static String noMethodsAllowed() {
@@ -340,44 +400,47 @@
}
static String unknownProblem(String className, ProblemReferenceBinding problem) {
- return "Unknown problem: "
- + ProblemReferenceBinding.problemReasonString(problem.problemId())
+ return "Unknown problem: " + ProblemReferenceBinding.problemReasonString(problem.problemId())
+ " " + className;
}
- private final boolean allowArtificialRescue;
+ protected final CompilationUnitDeclaration cud;
- private boolean collectTypes;
-
- private final CompilationUnitDeclaration cud;
-
- private List<String> referencedTypes;
-
- private boolean reportErrors;
+ private Annotation errorNode;
private ArtificialRescueChecker(CompilationUnitDeclaration cud) {
- allowArtificialRescue = true;
this.cud = cud;
}
- private ArtificialRescueChecker(CompilationUnitDeclaration cud,
- boolean allowArtificialRescue) {
- this.cud = cud;
- this.allowArtificialRescue = allowArtificialRescue;
+ protected final void error(String msg) {
+ GWTProblem.recordError(errorNode, cud, msg, null);
}
- private void check() {
- collectTypes = false;
- reportErrors = true;
+ protected final void exec() {
cud.traverse(new Visitor(), cud.scope);
}
- private List<String> collect() {
- collectTypes = true;
- referencedTypes = Lists.create();
- reportErrors = false;
- cud.traverse(new Visitor(), cud.scope);
- return referencedTypes;
- }
+ protected abstract void processRescue(RescueData rescue);
+ /**
+ * Examine a TypeDeclaration for ArtificialRescue annotations.
+ */
+ protected void processType(TypeDeclaration x) {
+ if (x.annotations == null) {
+ return;
+ }
+ for (Annotation a : x.annotations) {
+ ReferenceBinding binding = (ReferenceBinding) a.resolvedType;
+ String name = CharOperation.toString(binding.compoundName);
+ if (!name.equals(ArtificialRescue.class.getName())) {
+ continue;
+ }
+ errorNode = a;
+ RescueData[] rescues = RescueData.createFromArtificialRescue(a);
+ for (RescueData rescue : rescues) {
+ processRescue(rescue);
+ }
+ break;
+ }
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
index 874a31e..a07a5c5 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
@@ -36,6 +36,7 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
@@ -88,7 +89,9 @@
}
});
- ArtificialRescueChecker.check(cud, builder.isGenerated());
+ Map<TypeDeclaration, Binding[]> artificialRescues =
+ new HashMap<TypeDeclaration, Binding[]>();
+ ArtificialRescueChecker.check(cud, builder.isGenerated(), artificialRescues);
BinaryTypeReferenceRestrictionsChecker.check(cud);
MethodArgNamesLookup methodArgs = MethodParamCollector.collect(cud);
@@ -117,7 +120,7 @@
if (GwtAstBuilder.ENABLED) {
if (!cud.compilationResult().hasErrors()) {
// Make a GWT AST.
- types = astBuilder.process(cud, jsniMethods, jsniRefs);
+ types = astBuilder.process(cud, artificialRescues, jsniMethods, jsniRefs);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java b/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java
deleted file mode 100644
index f256ff9..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2010 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.dev.jjs;
-
-import com.google.gwt.core.client.impl.ArtificialRescue;
-import com.google.gwt.core.client.impl.ArtificialRescue.Rescue;
-import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.JAnnotation;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JInterfaceType;
-import com.google.gwt.dev.jjs.ast.JNode;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.ast.JReferenceType;
-import com.google.gwt.dev.jjs.ast.JType;
-import com.google.gwt.dev.jjs.ast.JVisitor;
-import com.google.gwt.dev.jjs.impl.JsniRefLookup;
-import com.google.gwt.dev.util.JsniRef;
-import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
-import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Process ArtificialRescue annotations.
- */
-public class ArtificialRescueRecorder {
- private class Recorder extends JVisitor {
- private JDeclaredType currentClass;
-
- @Override
- public void endVisit(JAnnotation x, Context ctx) {
- if (x.getType() == artificialRescueType) {
- ArtificialRescue annotation = JAnnotation.createAnnotation(
- ArtificialRescue.class, x);
- for (Rescue rescue : annotation.value()) {
- process(rescue);
- }
- }
- }
-
- @Override
- public void endVisit(JDeclaredType x, Context ctx) {
- assert currentClass == x;
- }
-
- @Override
- public boolean visit(JDeclaredType x, Context ctx) {
- currentClass = x;
-
- /*
- * We only care about annotations declared on the type itself, so we can
- * skip the traversal of fields and methods.
- */
- accept(x.getAnnotations());
- return false;
- }
-
- private void process(Rescue rescue) {
- assert rescue != null : "rescue";
-
- String typeName = rescue.className();
- JReferenceType classType = (JReferenceType) program.getTypeFromJsniRef(typeName);
- String[] fields = rescue.fields();
- boolean instantiable = rescue.instantiable();
- String[] methods = rescue.methods();
-
- assert classType != null : "classType " + typeName;
- assert fields != null : "fields";
- assert methods != null : "methods";
-
- if (instantiable) {
- currentClass.addArtificialRescue(classType);
- }
-
- if (classType instanceof JDeclaredType) {
- List<String> toRescue = new ArrayList<String>();
- Collections.addAll(toRescue, fields);
- Collections.addAll(toRescue, methods);
-
- for (String name : toRescue) {
- JsniRef ref = JsniRef.parse("@" + classType.getName() + "::" + name);
- final String[] errors = {null};
- JNode node = JsniRefLookup.findJsniRefTarget(ref, program,
- new JsniRefLookup.ErrorReporter() {
- public void reportError(String error) {
- errors[0] = error;
- }
- });
- if (errors[0] != null) {
- // Should have been caught by ArtificialRescueChecker
- throw new InternalCompilerException(
- "Unable to artificially rescue " + name + ": " + errors[0]);
- }
-
- if (node instanceof JType) {
- // Already added the type above.
- } else {
- currentClass.addArtificialRescue(node);
- }
- if (node instanceof JField) {
- JField field = (JField) node;
- if (!field.isFinal()) {
- field.setVolatile();
- }
- }
- }
- }
- }
- }
-
- public static void exec(JProgram program) {
- Event artificialRescueReorderEvent =
- SpeedTracerLogger.start(CompilerEventType.ARTIFICIAL_RESCUE_REORDER);
- new ArtificialRescueRecorder(program).execImpl();
- artificialRescueReorderEvent.end();
- }
-
- private final JInterfaceType artificialRescueType;
- private final JProgram program;
-
- private ArtificialRescueRecorder(JProgram program) {
- this.program = program;
- artificialRescueType = (JInterfaceType) program.getFromTypeMap(ArtificialRescue.class.getName());
- }
-
- private void execImpl() {
- new Recorder().accept(program);
- }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index a2264ec..60d889f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -593,7 +593,6 @@
}
// (3) Perform Java AST normalizations.
- ArtificialRescueRecorder.exec(jprogram);
FixAssignmentToUnbox.exec(jprogram);
/*
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/HasAnnotations.java b/dev/core/src/com/google/gwt/dev/jjs/ast/HasAnnotations.java
deleted file mode 100644
index 53bf557..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/HasAnnotations.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2010 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.dev.jjs.ast;
-
-import java.util.List;
-
-/**
- * Provides access to the annotations defined on an AST node.
- */
-public interface HasAnnotations {
- /**
- * Add a annotation to the node.
- */
- void addAnnotation(JAnnotation annotation);
-
- /**
- * Returns the annotation declared on the node of the given type or
- * <code>null</code> if no such annotation exists. For annotations on
- * subclasses of JDeclaredType, this method will not search the supertypes.
- */
- JAnnotation findAnnotation(String className);
-
- /**
- * Return the annotations associated with the node.
- */
- List<JAnnotation> getAnnotations();
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JAnnotation.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JAnnotation.java
deleted file mode 100644
index 44d7ece..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JAnnotation.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright 2010 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.dev.jjs.ast;
-
-import com.google.gwt.dev.jjs.SourceInfo;
-import com.google.gwt.dev.util.StringInterner;
-import com.google.gwt.dev.util.collect.Lists;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.List;
-
-/**
- * Represents a java annotation.
- */
-public class JAnnotation extends JNode implements JAnnotationArgument {
- /**
- * Represents a value contained within an annotation. Single-valued and
- * array-valued properties are both represented by this type.
- *
- * @param <T> the type of JAnnotationValue node that the Property
- * encapsulates.
- * @see {@link #of}
- */
- public static class Property extends JNode {
- private final String name;
- private List<JAnnotationArgument> values;
-
- public Property(SourceInfo sourceInfo, String name,
- List<JAnnotationArgument> values) {
- super(sourceInfo);
- this.name = StringInterner.get().intern(name);
- this.values = Lists.normalize(values);
- }
-
- public Property(SourceInfo sourceInfo, String name,
- JAnnotationArgument value) {
- this(sourceInfo, name, Lists.create(value));
- }
-
- public void addValue(JAnnotationArgument value) {
- values = Lists.add(values, value);
- }
-
- public String getName() {
- return name;
- }
-
- public JAnnotationArgument getSingleValue() {
- if (values.size() != 1) {
- throw new IllegalStateException(
- "Expecting single-valued property, found " + values.size()
- + " values");
- }
- return values.get(0);
- }
-
- public List<JAnnotationArgument> getValues() {
- return Lists.normalizeUnmodifiable(values);
- }
-
- public List<JNode> getValuesAsNodes() {
- // Lists.normalizeUnmodifiable would have allocated a new list anyway
- List<JNode> toReturn = Lists.create();
- for (JAnnotationArgument value : values) {
- toReturn = Lists.add(toReturn, value.annotationNode());
- }
- return toReturn;
- }
-
- @SuppressWarnings("unchecked")
- public void traverse(JVisitor visitor, Context ctx) {
- if (visitor.visit(this, ctx)) {
- // This is a shady cast to a raw list
- List nodes = visitor.acceptImmutable((List) values);
-
- // JNode and JAnnotationArgument types have disjoint hierarchies
- if (JAnnotation.class.desiredAssertionStatus()) {
- for (int i = 0, j = nodes.size(); i < j; i++) {
- assert nodes.get(i) instanceof JAnnotationArgument : "Expecting a "
- + "JAnnotationArgument at index " + i + " found a "
- + nodes.get(i).getClass().getCanonicalName();
- }
- }
-
- // This is a shady assignment
- values = nodes;
- }
- visitor.endVisit(this, ctx);
- }
- }
-
- /**
- * This runtime exception is thrown when calling a Class-valued annotation
- * method when the referenced class is not available to the JVM.
- */
- public static class SourceOnlyClassException extends RuntimeException {
- private final JClassLiteral literal;
-
- public SourceOnlyClassException(JClassLiteral literal) {
- super("The type " + literal.getRefType().getName()
- + " is available only in the module source");
- this.literal = literal;
- }
-
- public JClassLiteral getLiteral() {
- return literal;
- }
- }
-
- /**
- * This handles reflective dispatch for Proxy instances onto the data stored
- * in the AST.
- *
- * @param <T> the type of Annotation
- */
- private static class AnnotationInvocationHandler<T> implements
- InvocationHandler {
- private final Class<T> clazz;
- private final JAnnotation annotation;
-
- private AnnotationInvocationHandler(Class<T> clazz, JAnnotation annotation) {
- this.clazz = clazz;
- this.annotation = annotation;
- }
-
- /**
- * Handles method invocations.
- */
- public Object invoke(Object instance, Method method, Object[] arguments)
- throws Throwable {
-
- // Use the proxy object to handle trivial stuff
- if (method.getDeclaringClass() == Object.class) {
- return method.invoke(this, arguments);
- }
-
- Property prop = annotation.getProperty(method.getName());
- if (prop == null) {
- // This works because we're working with real Methods
- return method.getDefaultValue();
- }
-
- if (method.getReturnType().isArray()) {
- List<JAnnotationArgument> values = prop.getValues();
- Object toReturn = Array.newInstance(
- method.getReturnType().getComponentType(), values.size());
- for (int i = 0, j = values.size(); i < j; i++) {
- Object value = evaluate(values.get(i));
- Array.set(toReturn, i, value);
- }
- return toReturn;
- }
-
- return evaluate(prop.getSingleValue());
- }
-
- /**
- * Convert a JLiteral value into an Object the caller can work with.
- */
- private Object evaluate(JAnnotationArgument value)
- throws ClassNotFoundException {
-
- if (value instanceof JValueLiteral) {
- // Primitives
- return ((JValueLiteral) value).getValueObj();
-
- } else if (value instanceof JClassLiteral) {
- String clazzName = ((JClassLiteral) value).getRefType().getName();
- try {
- return Class.forName(clazzName, true, clazz.getClassLoader());
- } catch (ClassNotFoundException e) {
- throw new SourceOnlyClassException((JClassLiteral) value);
- }
-
- } else if (value instanceof JAnnotation) {
- // Determine the synthetic annotation's type
- String clazzName = ((JAnnotation) value).getType().getName();
- // Load the annotation class
- Class<? extends Annotation> annotationType = Class.forName(clazzName,
- true, clazz.getClassLoader()).asSubclass(Annotation.class);
- // Creating the backing annotation
- return createAnnotation(annotationType, (JAnnotation) value);
- }
-
- // Unhandled type
- throw new RuntimeException("Cannot convert "
- + value.getClass().getCanonicalName() + " into an Object");
- }
- }
-
- /**
- * Create a synthetic Annotation instance, based on the data in a JAnnatation.
- *
- * @param clazz the type of Annotation
- * @param annotation the backing data
- *
- * @param <T> the type of Annotation
- * @return an instance of <code>clazz</code>
- */
- public static <T extends Annotation> T createAnnotation(Class<T> clazz,
- JAnnotation annotation) {
- // Create the annotation as a reflective Proxy instance
- Object o = Proxy.newProxyInstance(clazz.getClassLoader(),
- new Class<?>[] {clazz}, new AnnotationInvocationHandler<T>(clazz,
- annotation));
-
- return clazz.cast(o);
- }
-
- /**
- * A utility method to retrieve an annotation of the named type. This method
- * will not search supertypes or superinterfaces if <code>x</code> is a
- * JDeclaredType.
- *
- * @return the annotation of the requested type, or <code>null</code>
- */
- public static JAnnotation findAnnotation(HasAnnotations x,
- String annotationTypeName) {
- for (JAnnotation a : x.getAnnotations()) {
- if (a.getType().getName().equals(annotationTypeName)) {
- return a;
- }
- }
- return null;
- }
-
- private final JInterfaceType type;
- private List<Property> properties = Lists.create();
-
- public JAnnotation(SourceInfo sourceInfo, JInterfaceType type) {
- super(sourceInfo);
- this.type = type;
- }
-
- public void addValue(Property value) {
- properties = Lists.add(properties, value);
- }
-
- public JNode annotationNode() {
- return this;
- }
-
- public List<Property> getProperties() {
- return Lists.normalizeUnmodifiable(properties);
- }
-
- /**
- * Returns the named property or <code>null</code> if it does not exist.
- */
- public Property getProperty(String name) {
- for (Property p : properties) {
- if (p.getName().equals(name)) {
- return p;
- }
- }
- return null;
- }
-
- public JInterfaceType getType() {
- return type;
- }
-
- public void traverse(JVisitor visitor, Context ctx) {
- if (visitor.visit(this, ctx)) {
- properties = visitor.acceptImmutable(properties);
- }
- visitor.endVisit(this, ctx);
- }
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JAnnotationArgument.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JAnnotationArgument.java
deleted file mode 100644
index 673d06a..0000000
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JAnnotationArgument.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2010 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.dev.jjs.ast;
-
-/**
- * A tag interface for JNodes that are legal values for annotation properties.
- */
-public interface JAnnotationArgument {
- /**
- * A convenience method to avoid explicit casts.
- */
- JNode annotationNode();
-}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
index 2e33f6d..d1a4444 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
@@ -25,7 +25,7 @@
* ClassLiteralHolder. That field contains the class object allocation
* initializer.
*/
-public class JClassLiteral extends JLiteral implements JAnnotationArgument {
+public class JClassLiteral extends JLiteral {
private static SourceInfo addCorrelation(SourceInfo info) {
info.addCorrelation(info.getCorrelator().by(Literal.CLASS));
@@ -41,10 +41,6 @@
refType = type;
}
- public JNode annotationNode() {
- return this;
- }
-
/**
* Returns the field holding my allocated object.
*/
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 b044ebb..3962459 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
@@ -93,7 +93,6 @@
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
- annotations = visitor.acceptImmutable(annotations);
fields = visitor.acceptWithInsertRemoveImmutable(fields);
methods = visitor.acceptWithInsertRemoveImmutable(methods);
}
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 40a01f8..faeb049 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
@@ -29,12 +29,7 @@
/**
* Base class for any reference type.
*/
-public abstract class JDeclaredType extends JReferenceType implements
- HasAnnotations {
- /**
- * Annotations applied to the type. Special serialization treatment.
- */
- protected transient List<JAnnotation> annotations = Lists.create();
+public abstract class JDeclaredType extends JReferenceType {
/**
* The other nodes that this node should implicitly rescue. Special
@@ -83,10 +78,6 @@
super(info, name);
}
- public void addAnnotation(JAnnotation annotation) {
- annotations = Lists.add(annotations, annotation);
- }
-
public void addArtificialRescue(JNode node) {
artificialRescues = Lists.add(artificialRescues, node);
}
@@ -153,14 +144,6 @@
return this.getClinitTarget() != targetType.getClinitTarget();
}
- public JAnnotation findAnnotation(String className) {
- return JAnnotation.findAnnotation(this, className);
- }
-
- public List<JAnnotation> getAnnotations() {
- return Lists.normalizeUnmodifiable(annotations);
- }
-
public List<JNode> getArtificialRescues() {
return artificialRescues;
}
@@ -310,7 +293,6 @@
fields = (List<JField>) stream.readObject();
methods = (List<JMethod>) stream.readObject();
artificialRescues = (List<JNode>) stream.readObject();
- annotations = (List<JAnnotation>) stream.readObject();
}
/**
@@ -355,7 +337,6 @@
stream.writeObject(fields);
stream.writeObject(methods);
stream.writeObject(artificialRescues);
- stream.writeObject(annotations);
}
/**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java
index bf561e4..9b3bc0c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java
@@ -144,7 +144,6 @@
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
- annotations = visitor.acceptImmutable(annotations);
// Do not visit declStmt, it gets visited within its own code block.
}
visitor.endVisit(this, ctx);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java
index ff30331..2b01b77 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JInterfaceType.java
@@ -63,7 +63,6 @@
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
- annotations = visitor.acceptImmutable(annotations);
fields = visitor.acceptWithInsertRemoveImmutable(fields);
methods = visitor.acceptWithInsertRemoveImmutable(methods);
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JLocal.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JLocal.java
index c03bd69..e725118 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JLocal.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JLocal.java
@@ -40,7 +40,6 @@
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
- annotations = visitor.acceptImmutable(annotations);
// Do not visit declStmt, it gets visited within its own code block.
}
visitor.endVisit(this, ctx);
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 9bf6869..4d7ebef 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
@@ -33,8 +33,8 @@
/**
* A Java method implementation.
*/
-public class JMethod extends JNode implements HasAnnotations, HasEnclosingType,
- HasName, HasType, CanBeAbstract, CanBeSetFinal, CanBeNative, CanBeStatic {
+public class JMethod extends JNode implements HasEnclosingType, HasName, HasType, CanBeAbstract,
+ CanBeSetFinal, CanBeNative, CanBeStatic {
private static class ExternalSerializedForm implements Serializable {
@@ -66,8 +66,6 @@
protected transient String signature;
- private List<JAnnotation> annotations = Lists.create();
-
/**
* Special serialization treatment.
*/
@@ -111,10 +109,6 @@
this.isPrivate = isPrivate;
}
- public void addAnnotation(JAnnotation annotation) {
- annotations = Lists.add(annotations, annotation);
- }
-
/**
* Add a method that this method overrides.
*/
@@ -155,10 +149,6 @@
return !isStatic() && !isPrivate();
}
- public JAnnotation findAnnotation(String className) {
- return JAnnotation.findAnnotation(this, className);
- }
-
public void freezeParamTypes() {
List<JType> paramTypes = new ArrayList<JType>();
for (JParameter param : params) {
@@ -167,10 +157,6 @@
setOriginalTypes(returnType, paramTypes);
}
- public List<JAnnotation> getAnnotations() {
- return Lists.normalizeUnmodifiable(annotations);
- }
-
public JAbstractMethodBody getBody() {
assert !enclosingType.isExternal() : "External types do not have method bodies.";
return body;
@@ -358,7 +344,6 @@
}
protected void visitChildren(JVisitor visitor) {
- annotations = visitor.acceptImmutable(annotations);
params = visitor.acceptImmutable(params);
if (body != null) {
body = (JAbstractMethodBody) visitor.accept(body);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JParameter.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JParameter.java
index 7331cf1..9e3fe20 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JParameter.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JParameter.java
@@ -64,7 +64,6 @@
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
- annotations = visitor.acceptImmutable(annotations);
}
visitor.endVisit(this, ctx);
}
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 e2ab10b..6af8399 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
@@ -87,13 +87,6 @@
"com.google.gwt.lang.EntryMethodHolder",
"com.google.gwt.core.client.prefetch.RunAsyncCode"));
- /**
- * Only annotations defined in the following packages or sub-packages thereof
- * will be recorded in the Java AST.
- */
- public static final Set<String> RECORDED_ANNOTATION_PACKAGES = new LinkedHashSet<String>(
- Arrays.asList("com.google.gwt.core.client.impl"));
-
static final Map<String, Set<String>> traceMethods = new HashMap<String, Set<String>>();
private static final Comparator<JArrayType> ARRAYTYPE_COMPARATOR = new ArrayTypeComparator();
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JValueLiteral.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JValueLiteral.java
index 1cbfe78..ff715d0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JValueLiteral.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JValueLiteral.java
@@ -20,17 +20,12 @@
/**
* Base class for any Java literal expression.
*/
-public abstract class JValueLiteral extends JLiteral implements
- JAnnotationArgument {
+public abstract class JValueLiteral extends JLiteral {
public JValueLiteral(SourceInfo sourceInfo) {
super(sourceInfo);
}
- public JNode annotationNode() {
- return this;
- }
-
public abstract Object getValueObj();
protected abstract JValueLiteral cloneFrom(JValueLiteral value);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JVariable.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JVariable.java
index 0928cf8..0338a67 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JVariable.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JVariable.java
@@ -17,17 +17,13 @@
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.util.StringInterner;
-import com.google.gwt.dev.util.collect.Lists;
-
-import java.util.List;
/**
* Base class for any storage location.
*/
public abstract class JVariable extends JNode implements CanBeSetFinal,
- CanHaveInitializer, HasAnnotations, HasName, HasType {
+ CanHaveInitializer, HasName, HasType {
- protected List<JAnnotation> annotations = Lists.create();
protected JDeclarationStatement declStmt = null;
private boolean isFinal;
private final String name;
@@ -41,18 +37,6 @@
this.isFinal = isFinal;
}
- public void addAnnotation(JAnnotation annotation) {
- annotations = Lists.add(annotations, annotation);
- }
-
- public JAnnotation findAnnotation(String className) {
- return JAnnotation.findAnnotation(this, className);
- }
-
- public List<JAnnotation> getAnnotations() {
- return Lists.normalizeUnmodifiable(annotations);
- }
-
public JLiteral getConstInitializer() {
JExpression initializer = getInitializer();
if (isFinal() && initializer instanceof JLiteral) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java
index 97591a7..ae7c201 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JVisitor.java
@@ -182,14 +182,6 @@
endVisit((JNode) x, ctx);
}
- public void endVisit(JAnnotation x, Context ctx) {
- endVisit((JNode) x, ctx);
- }
-
- public void endVisit(JAnnotation.Property x, Context ctx) {
- endVisit((JNode) x, ctx);
- }
-
public void endVisit(JArrayLength x, Context ctx) {
endVisit((JExpression) x, ctx);
}
@@ -502,14 +494,6 @@
return visit((JNode) x, ctx);
}
- public boolean visit(JAnnotation x, Context ctx) {
- return visit((JNode) x, ctx);
- }
-
- public boolean visit(JAnnotation.Property x, Context ctx) {
- return visit((JNode) x, ctx);
- }
-
public boolean visit(JArrayLength x, Context ctx) {
return visit((JExpression) x, ctx);
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
index 91ce358..f286b79 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -15,17 +15,13 @@
*/
package com.google.gwt.dev.jjs.impl;
+import com.google.gwt.dev.javac.ArtificialRescueChecker.RescueData;
import com.google.gwt.dev.javac.JsniCollector;
-import com.google.gwt.dev.jjs.HasSourceInfo;
import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.JJSOptions;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.SourceOrigin;
import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.HasAnnotations;
-import com.google.gwt.dev.jjs.ast.JAnnotation;
-import com.google.gwt.dev.jjs.ast.JAnnotation.Property;
-import com.google.gwt.dev.jjs.ast.JAnnotationArgument;
import com.google.gwt.dev.jjs.ast.JArrayLength;
import com.google.gwt.dev.jjs.ast.JArrayRef;
import com.google.gwt.dev.jjs.ast.JArrayType;
@@ -102,13 +98,11 @@
import com.google.gwt.dev.js.ast.JsModVisitor;
import com.google.gwt.dev.js.ast.JsNameRef;
import com.google.gwt.dev.util.JsniRef;
-import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.collect.Maps;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
-import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
@@ -175,10 +169,8 @@
import org.eclipse.jdt.internal.compiler.impl.LongConstant;
import org.eclipse.jdt.internal.compiler.impl.ShortConstant;
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
-import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
@@ -451,7 +443,7 @@
*/
public void processType(TypeDeclaration x) {
currentClass = (JDeclaredType) typeMap.get(x.binding);
- processHasAnnotations(currentClass, x.annotations);
+ processArtificialRescues(x.annotations);
try {
currentClassScope = x.scope;
currentSeparatorPositions = x.compilationResult.lineSeparatorPositions;
@@ -717,7 +709,6 @@
void processConstructor(ConstructorDeclaration x) {
JConstructor ctor = (JConstructor) typeMap.get(x.binding);
try {
- processHasAnnotations(ctor, x.annotations);
SourceInfo info = ctor.getSourceInfo();
currentMethod = ctor;
@@ -1489,7 +1480,6 @@
void processField(FieldDeclaration declaration) {
JField field = (JField) typeMap.tryGet(declaration.binding);
- processHasAnnotations(field, declaration.annotations);
if (field == null) {
/*
* When anonymous classes declare constant fields, the field declaration
@@ -1536,14 +1526,6 @@
MethodBinding b = x.binding;
JMethod method = (JMethod) typeMap.get(b);
try {
- processHasAnnotations(method, x.annotations);
- if (x.arguments != null) {
- for (int i = 0, j = x.arguments.length; i < j; i++) {
- JParameter p = (JParameter) typeMap.get(x.arguments[i].binding);
- processHasAnnotations(p, x.arguments[i].annotations);
- }
- }
-
if (!b.isStatic() && (b.isImplementing() || b.isOverriding())) {
tryFindUpRefs(method, b);
}
@@ -1815,7 +1797,6 @@
JStatement processStatement(LocalDeclaration x) {
SourceInfo info = makeSourceInfo(x);
JLocal local = (JLocal) typeMap.get(x.binding);
- processHasAnnotations(local, x.annotations);
JLocalRef localRef = new JLocalRef(info, local);
JExpression initializer = dispProcessExpression(x.initialization);
return new JDeclarationStatement(info, localRef, initializer);
@@ -2552,72 +2533,59 @@
return variable;
}
- private void processAnnotationProperties(SourceInfo sourceInfo,
- JAnnotation annotation, ElementValuePair[] elementValuePairs) {
- if (elementValuePairs == null) {
- return;
+ /**
+ * Process a {@link ArtificialRescue.Rescue} element.
+ */
+ private void processArtificialRescue(RescueData rescue) {
+ JReferenceType classType = (JReferenceType) program.getTypeFromJsniRef(rescue.getClassName());
+ assert classType != null;
+ if (rescue.isInstantiable()) {
+ currentClass.addArtificialRescue(classType);
}
- for (ElementValuePair pair : elementValuePairs) {
- String name = CharOperation.charToString(pair.getName());
- List<JAnnotationArgument> values = processAnnotationPropertyValue(
- sourceInfo, pair.getValue());
- annotation.addValue(new Property(sourceInfo, name, values));
+ if (classType instanceof JDeclaredType) {
+ List<String> toRescue = new ArrayList<String>();
+ Collections.addAll(toRescue, rescue.getFields());
+ Collections.addAll(toRescue, rescue.getMethods());
+
+ for (String name : toRescue) {
+ JsniRef ref = JsniRef.parse("@" + classType.getName() + "::" + name);
+ final String[] errors = {null};
+ JNode node =
+ JsniRefLookup.findJsniRefTarget(ref, program, new JsniRefLookup.ErrorReporter() {
+ public void reportError(String error) {
+ errors[0] = error;
+ }
+ });
+ if (errors[0] != null) {
+ // Should have been caught by ArtificialRescueChecker
+ throw new InternalCompilerException("Unable to artificially rescue " + name + ": "
+ + errors[0]);
+ }
+
+ if (node instanceof JType) {
+ // Already added the type above.
+ } else {
+ currentClass.addArtificialRescue(node);
+ }
+ if (node instanceof JField) {
+ JField field = (JField) node;
+ if (!field.isFinal()) {
+ field.setVolatile();
+ }
+ }
+ }
}
}
- private List<JAnnotationArgument> processAnnotationPropertyValue(
- SourceInfo info, Object value) {
- if (value instanceof TypeBinding) {
- JType type = (JType) typeMap.tryGet((TypeBinding) value);
- if (type == null) {
- // Indicates a binary-only class literal
- type = getOrCreateExternalType(info,
- ((ReferenceBinding) value).compoundName);
- }
- return Lists.<JAnnotationArgument> create(new JClassLiteral(
- info.makeChild(), type));
-
- } else if (value instanceof Constant) {
- return Lists.create((JAnnotationArgument) dispatch("processConstant",
- value));
-
- } else if (value instanceof Object[]) {
- Object[] array = (Object[]) value;
- List<JAnnotationArgument> toReturn = Lists.create();
- for (int i = 0, j = array.length; i < j; i++) {
- toReturn = Lists.add(toReturn,
- processAnnotationPropertyValue(info, array[i]).get(0));
- }
- return toReturn;
-
- } else if (value instanceof AnnotationBinding) {
- AnnotationBinding annotationBinding = (AnnotationBinding) value;
- ReferenceBinding annotationType = annotationBinding.getAnnotationType();
- JInterfaceType type = (JInterfaceType) typeMap.tryGet(annotationType);
- JAnnotation toReturn;
- if (type != null) {
- toReturn = new JAnnotation(info, type);
- } else {
- JInterfaceType external = getOrCreateExternalType(info,
- annotationType.compoundName);
- toReturn = new JAnnotation(info, external);
- }
-
- // Load the properties for the annotation value
- processAnnotationProperties(info, toReturn,
- annotationBinding.getElementValuePairs());
-
- return Lists.<JAnnotationArgument> create(toReturn);
- } else if (value instanceof FieldBinding) {
- FieldBinding fieldBinding = (FieldBinding) value;
- assert fieldBinding.constant() != null : "Expecting constant-valued field";
- return Lists.create((JAnnotationArgument) dispatch("processConstant",
- fieldBinding.constant()));
+ private void processArtificialRescues(Annotation[] annotations) {
+ if (annotations == null) {
+ return;
}
-
- throw new InternalCompilerException("Unable to process value "
- + value.getClass().getName());
+ RescueData[] rescues = RescueData.createFromAnnotations(annotations);
+ for (RescueData rescue : rescues) {
+ processArtificialRescue(rescue);
+ }
}
/**
@@ -2638,44 +2606,6 @@
return binaryOperation;
}
- /**
- * It is safe to pass a null array.
- */
- private <T extends HasAnnotations & HasSourceInfo> void processHasAnnotations(
- T x, Annotation[] annotations) {
- if (annotations == null) {
- return;
- }
-
- for (Annotation a : annotations) {
- JAnnotation annotation;
- ReferenceBinding binding = (ReferenceBinding) a.resolvedType;
- String name = CharOperation.toString(binding.compoundName);
- boolean record = false;
- for (String prefix : JProgram.RECORDED_ANNOTATION_PACKAGES) {
- if (name.startsWith(prefix + ".")) {
- record = true;
- break;
- }
- }
- if (!record) {
- continue;
- }
- JInterfaceType annotationType = (JInterfaceType) typeMap.tryGet(binding);
- if (annotationType != null) {
- annotation = new JAnnotation(x.getSourceInfo(), annotationType);
- } else {
- // Indicates a binary-only annotation type
- JInterfaceType externalType = getOrCreateExternalType(
- x.getSourceInfo(), binding.compoundName);
- annotation = new JAnnotation(x.getSourceInfo(), externalType);
- }
- processAnnotationProperties(x.getSourceInfo(), annotation,
- a.computeElementValuePairs());
- x.addAnnotation(annotation);
- }
- }
-
private JExpression processQualifiedThisOrSuperRef(
QualifiedThisReference x, JClassType qualType) {
/*
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 95e97ca..32034c9 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
@@ -1718,7 +1718,7 @@
public boolean visit(TypeDeclaration x, CompilationUnitScope scope) {
return visit(x);
}
-
+
@Override
public boolean visit(WhileStatement x, BlockScope scope) {
// SEE NOTE ON JDT FORCED OPTIMIZATIONS
@@ -1769,6 +1769,21 @@
addBridgeMethods(x.binding);
}
+ Binding[] rescues = artificialRescues.get(x);
+ if (rescues != null) {
+ for (Binding rescue : rescues) {
+ if (rescue instanceof TypeBinding) {
+ type.addArtificialRescue(typeMap.get((TypeBinding) rescue));
+ } else if (rescue instanceof FieldBinding) {
+ type.addArtificialRescue(typeMap.get((FieldBinding) rescue));
+ } else if (rescue instanceof MethodBinding) {
+ type.addArtificialRescue(typeMap.get((MethodBinding) rescue));
+ } else {
+ throw new InternalCompilerException("Unknown artifical rescue binding type.");
+ }
+ }
+ }
+
// TODO: uprefs???
curClass = classStack.pop();
@@ -2831,6 +2846,8 @@
return false;
}
+ Map<TypeDeclaration, Binding[]> artificialRescues;
+
CudInfo curCud = null;
JClassType javaLangClass = null;
@@ -2850,10 +2867,12 @@
private List<JDeclaredType> newTypes;
public List<JDeclaredType> process(CompilationUnitDeclaration cud,
+ Map<TypeDeclaration, Binding[]> artificialRescues,
Map<MethodDeclaration, JsniMethod> jsniMethods, Map<String, Binding> jsniRefs) {
if (cud.types == null) {
return Collections.emptyList();
}
+ this.artificialRescues = artificialRescues;
this.jsniRefs = jsniRefs;
this.jsniMethods = jsniMethods;
newTypes = new ArrayList<JDeclaredType>();
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 e0e2612..f1a3230 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
@@ -350,7 +350,7 @@
sb.append('.');
sb.append(binding.name);
sb.append(':');
- sb.append(binding.type.constantPoolName());
+ sb.append(binding.type.signature());
return sb.toString();
}
@@ -361,10 +361,10 @@
sb.append(binding.selector);
sb.append('(');
for (TypeBinding paramType : binding.parameters) {
- sb.append(paramType.constantPoolName());
+ sb.append(paramType.signature());
}
sb.append(')');
- sb.append(binding.returnType.constantPoolName());
+ sb.append(binding.returnType.signature());
return sb.toString();
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
index 1bf3ea5..4ca8593 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
@@ -23,7 +23,6 @@
import com.google.gwt.dev.jjs.ast.HasName;
import com.google.gwt.dev.jjs.ast.HasType;
import com.google.gwt.dev.jjs.ast.JAbsentArrayDimension;
-import com.google.gwt.dev.jjs.ast.JAnnotation;
import com.google.gwt.dev.jjs.ast.JArrayLength;
import com.google.gwt.dev.jjs.ast.JArrayRef;
import com.google.gwt.dev.jjs.ast.JArrayType;
@@ -162,34 +161,6 @@
}
@Override
- public boolean visit(JAnnotation x, Context ctx) {
- print('@');
- print(x.getType().getName());
- lparen();
- visitCollectionWithCommas(x.getProperties().iterator());
- rparen();
- return false;
- }
-
- @Override
- public boolean visit(JAnnotation.Property x, Context ctx) {
- print(x.getName());
- print('=');
- switch (x.getValues().size()) {
- case 1:
- accept(x.getSingleValue().annotationNode());
- break;
- case 0:
- default:
- print('{');
- visitCollectionWithCommas(x.getValuesAsNodes().iterator());
- print('}');
- break;
- }
- return false;
- }
-
- @Override
public boolean visit(JArrayLength x, Context ctx) {
JExpression instance = x.getInstance();
parenPush(x, instance);
diff --git a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
index eb90244..3fa39b4 100644
--- a/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
+++ b/dev/core/src/com/google/gwt/dev/util/log/speedtracer/CompilerEventType.java
@@ -62,7 +62,6 @@
BUILD_TYPE_MAP_FOR_AST("BuildTypeMapForAST", "LightSeaGreen"), //
GET_COMPILATION_UNITS("GetCompilationUnitDeclarations", "Gainsboro"), //
GENERATE_JAVA_AST("GenerateJavaAST", "DodgerBlue"), //
- ARTIFICIAL_RESCUE_REORDER("ArtificialRescueReorder", "LightCyan"), //
FIX_ASSIGNMENT_TO_UNBOX("FixAssignmentToUnbox", "Orange"), //
ASSERTION_NORMALIZER("AssertionNormalizer", "LightPink"), //
ASSERTION_REMOVER("AssertionRemover", "LightSalmon"), //
diff --git a/dev/core/super/com/google/gwt/core/client/impl/ArtificialRescue.java b/dev/core/super/com/google/gwt/core/client/impl/ArtificialRescue.java
index 68af063..8fbbf4e 100644
--- a/dev/core/super/com/google/gwt/core/client/impl/ArtificialRescue.java
+++ b/dev/core/super/com/google/gwt/core/client/impl/ArtificialRescue.java
@@ -25,6 +25,11 @@
*/
@Target(ElementType.TYPE)
public @interface ArtificialRescue {
+ /*
+ * Special compiler support, changing this interface in any way requires
+ * changes to ArtificialRescueChecker.
+ */
+
/**
* Specifies the elements of a single type to rescue.
*/
diff --git a/dev/core/test/com/google/gwt/dev/javac/ArtificialRescueCheckerTest.java b/dev/core/test/com/google/gwt/dev/javac/ArtificialRescueCheckerTest.java
index c7b7d9b..7ad8712 100644
--- a/dev/core/test/com/google/gwt/dev/javac/ArtificialRescueCheckerTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/ArtificialRescueCheckerTest.java
@@ -51,7 +51,7 @@
builder.append("@ArtificialRescue(@Rescue(className=\"Target\", methods=\"blah()\"))\n");
builder.append("class Buggy{}");
shouldGenerateError(builder, targetClass(), 3,
- ArtificialRescueChecker.noMethod("Target", "blah"));
+ ArtificialRescueChecker.noMethod("Target", "blah()"));
}
public void testBadMethodSignature() {
@@ -107,7 +107,7 @@
public void testOkPrimitiveArray() {
StringBuilder builder = builder();
- builder.append("@ArtificialRescue(@Rescue(className=\"Z[]\"))\n");
+ builder.append("@ArtificialRescue(@Rescue(className=\"boolean[]\"))\n");
builder.append("class Buggy{}");
shouldGenerateNoError(builder, targetClass());
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java
index 11289f3..fe732e7 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/AdditionalTypeProviderDelegateTest.java
@@ -19,16 +19,9 @@
import com.google.gwt.dev.javac.GeneratedUnit;
import com.google.gwt.dev.javac.JdtCompiler.AdditionalTypeProviderDelegate;
import com.google.gwt.dev.javac.impl.MockJavaResource;
-import com.google.gwt.dev.jjs.ast.JAnnotation;
-import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JLocal;
import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.ast.JAnnotation.Property;
-import com.google.gwt.dev.jjs.ast.JAnnotation.SourceOnlyClassException;
/**
* Tests that a AdditionalTypeProviderDelegate correctly gets control when an unknown
@@ -193,17 +186,17 @@
assertNotNull("Unknown class A", goodClassType);
}
- public void testUnknownClass() throws UnableToCompleteException {
+ public void testUnknownClass() {
try {
- JProgram program = compileSnippet("void", "new test.C();");
+ compileSnippet("void", "new test.C();");
fail("Shouldn't have compiled");
} catch (UnableToCompleteException expected) {
}
}
- public void testUnknownClassNoImport() throws UnableToCompleteException {
+ public void testUnknownClassNoImport() {
try {
- JProgram program = compileSnippet("void", "new test.D();");
+ compileSnippet("void", "new test.D();");
fail("Shouldn't have compiled");
} catch (UnableToCompleteException expected) {
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/JAnnotationTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/JAnnotationTest.java
deleted file mode 100644
index 129981c..0000000
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/JAnnotationTest.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright 2010 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.dev.jjs.impl;
-
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.dev.javac.impl.MockJavaResource;
-import com.google.gwt.dev.jjs.ast.JAnnotation;
-import com.google.gwt.dev.jjs.ast.JClassLiteral;
-import com.google.gwt.dev.jjs.ast.JDeclaredType;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JLocal;
-import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JParameter;
-import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.ast.JAnnotation.Property;
-import com.google.gwt.dev.jjs.ast.JAnnotation.SourceOnlyClassException;
-
-/**
- * Tests AST setup of JAnnotation nodes as well as the reflective proxy for
- * accessing their data.
- */
-public class JAnnotationTest extends JJSTestBase {
-
- /**
- * A test class for binary-only annotations.
- */
- public @interface BinaryAnnotation {
- Class<?> c() default Object.class;
-
- int i() default 2;
-
- int[] iOne() default 1;
-
- int[] iTwo() default {1, 2};
-
- int[] iZero() default {};
-
- OtherAnnotation[] o() default {
- @OtherAnnotation("Hello 1"), @OtherAnnotation("Hello 2")};
-
- String s() default "Hello String";
- }
-
- /**
- * Used to test binary-only class literal behavior.
- */
- public @interface ClassAnnotation {
- Class<?> value();
- }
-
- /**
- * A test case for meta-annotations.
- */
- public @interface OtherAnnotation {
- String value();
- }
-
- private static void assertEquals(int[] a, int[] b) {
- assertEquals(a.length, b.length);
- for (int i = 0, j = a.length; i < j; i++) {
- assertEquals(a[i], b[i]);
- }
- }
-
- public void setUp() {
- // These packages have annotations required by this test
- JProgram.RECORDED_ANNOTATION_PACKAGES.add("com.google.gwt.dev.jjs");
- JProgram.RECORDED_ANNOTATION_PACKAGES.add("test");
-
- sourceOracle.addOrReplace(new MockJavaResource("test.SourceClassAnnotation") {
- @Override
- protected CharSequence getContent() {
- StringBuffer code = new StringBuffer();
- code.append("package test;\n");
- code.append("public @interface SourceClassAnnotation {\n");
- code.append(" Class<?> value();\n");
- code.append("}\n");
- return code;
- }
- });
- sourceOracle.addOrReplace(new MockJavaResource("test.Tag") {
- @Override
- protected CharSequence getContent() {
- StringBuffer code = new StringBuffer();
- code.append("package test;\n");
- code.append("@Tag\n");
- code.append("public @interface Tag {\n");
- code.append("}\n");
- return code;
- }
- });
- sourceOracle.addOrReplace(new MockJavaResource("test.WithTag") {
- @Override
- protected CharSequence getContent() {
- StringBuffer code = new StringBuffer();
- code.append("package test;\n");
- code.append("@Tag\n");
- code.append("public class WithTag {\n");
- code.append(" @Tag String field;\n");
- code.append(" @Tag WithTag(){}\n");
- code.append(" @Tag void method(@Tag String p) {@Tag String local;}\n");
- code.append("}\n");
- return code;
- }
- });
- sourceOracle.addOrReplace(new MockJavaResource("test.WithBinary") {
- @Override
- protected CharSequence getContent() {
- StringBuffer code = new StringBuffer();
- code.append("package test;\n");
- code.append("import " + BinaryAnnotation.class.getCanonicalName()
- + ";\n");
- code.append("import " + ClassAnnotation.class.getCanonicalName()
- + ";\n");
- code.append("import " + OtherAnnotation.class.getCanonicalName()
- + ";\n");
- code.append("public class WithBinary {\n");
- code.append(" public static final String EXPR = \"Expression\";\n");
- code.append(" @ClassAnnotation("
- + JAnnotationTest.class.getCanonicalName() + ".class)\n");
- code.append(" void useBinaryClassReference() {}\n");
- code.append(" @BinaryAnnotation\n");
- code.append(" void useDefaults() {}\n");
- code.append(" @SourceClassAnnotation("
- + JAnnotationTest.class.getCanonicalName() + ".class)\n");
- code.append(" void useSourceClassAnnotation() {}\n");
- code.append(" @BinaryAnnotation(c=Tag.class, i=42, s=\"foo\", o= @OtherAnnotation(\"Hello \" + EXPR))\n");
- code.append(" void useValues() {}\n");
- code.append("}\n");
- return code;
- }
- });
- }
-
- public void testAllElementTypes() throws UnableToCompleteException {
- JProgram program = compileSnippet("void", "new test.WithTag();");
-
- // ANNOTATION_TYPE
- JDeclaredType tag = findType(program, "test.Tag");
- assertEquals(1, tag.getAnnotations().size());
-
- // TYPE
- JDeclaredType withTag = findType(program, "test.WithTag");
- assertEquals(1, withTag.getAnnotations().size());
-
- // CONSTRUCTOR
- JMethod constructor = findMethod(withTag, "WithTag");
- assertEquals(1, constructor.getAnnotations().size());
-
- // METHOD
- JMethod method = findMethod(withTag, "method");
- assertEquals(1, method.getAnnotations().size());
-
- // FIELD
- JField field = findField(withTag, "field");
- assertEquals(1, field.getAnnotations().size());
-
- // LOCAL_VARIABLE
- JLocal local = findLocal(method, "local");
- assertEquals(1, local.getAnnotations().size());
-
- // PARAMETER
- JParameter param = method.getParams().get(0);
- assertEquals(1, param.getAnnotations().size());
-
- // There are no representations for PACKAGE in our AST
- }
-
- public void testAnnotationBinaryOnlyClassLiterals()
- throws UnableToCompleteException {
- JProgram program = compileSnippet("void", "new test.WithBinary();");
-
- JDeclaredType t = findType(program, "test.WithBinary");
- JMethod m = findMethod(t, "useBinaryClassReference");
- JAnnotation a = JAnnotation.findAnnotation(m,
- ClassAnnotation.class.getName());
- assertNotNull(a);
-
- ClassAnnotation instance = JAnnotation.createAnnotation(
- ClassAnnotation.class, a);
-
- assertSame(JAnnotationTest.class, instance.value());
- }
-
- public void testAnnotationProxyCustomValues()
- throws UnableToCompleteException {
- JProgram program = compileSnippet("void", "new test.WithBinary();");
-
- JDeclaredType t = findType(program, "test.WithBinary");
- JMethod useValues = findMethod(t, "useValues");
- JAnnotation a = JAnnotation.findAnnotation(useValues,
- BinaryAnnotation.class.getName());
- assertNotNull(a);
- BinaryAnnotation instance = JAnnotation.createAnnotation(
- BinaryAnnotation.class, a);
- assertNotNull(instance);
-
- // A source-only annotation, unavailable to the JVM
- try {
- instance.c();
- } catch (SourceOnlyClassException e) {
- // Expected
- assertEquals(findType(program, "test.Tag"), e.getLiteral().getRefType());
- }
- assertEquals(42, instance.i());
- assertEquals("foo", instance.s());
- assertEquals(1, instance.o().length);
- assertEquals("Hello Expression", instance.o()[0].value());
- }
-
- public void testAnnotationProxyDefaultValues()
- throws UnableToCompleteException {
- JProgram program = compileSnippet("void", "new test.WithBinary();");
-
- JDeclaredType t = findType(program, "test.WithBinary");
- JMethod useDefaults = findMethod(t, "useDefaults");
- JAnnotation a = JAnnotation.findAnnotation(useDefaults,
- BinaryAnnotation.class.getName());
- assertNotNull(a);
- assertTrue(a.getType().isExternal());
-
- BinaryAnnotation instance = JAnnotation.createAnnotation(
- BinaryAnnotation.class, a);
- assertNotNull(instance);
-
- // Test Object methods
- assertEquals(instance.hashCode(), instance.hashCode());
- assertNotNull(instance.toString());
-
- // Test default-valued
- assertSame(Object.class, instance.c());
- assertEquals(2, instance.i());
- assertEquals(new int[] {1}, instance.iOne());
- assertEquals(new int[] {1, 2}, instance.iTwo());
- assertEquals(new int[] {}, instance.iZero());
- assertNotNull(instance.o());
- assertEquals(2, instance.o().length);
- assertEquals("Hello 1", instance.o()[0].value());
- assertEquals("Hello 2", instance.o()[1].value());
- assertEquals("Hello String", instance.s());
- }
-
- public void testSourceAnnotationWithBinaryClass()
- throws UnableToCompleteException {
- JProgram program = compileSnippet("void", "new test.WithBinary();");
-
- JDeclaredType t = findType(program, "test.WithBinary");
- JMethod m = findMethod(t, "useSourceClassAnnotation");
- JAnnotation a = JAnnotation.findAnnotation(m, "test.SourceClassAnnotation");
- assertNotNull(a);
-
- Property p = a.getProperty("value");
- JClassLiteral literal = (JClassLiteral) p.getSingleValue();
- JDeclaredType type = (JDeclaredType) literal.getRefType();
- assertTrue(type.isExternal());
- assertEquals(JAnnotationTest.class.getName(), type.getName());
- }
-}