Binary-only annotations were causing warnings to be generated by TypeOracle; this change makes it legal to use binary-only annotations without warning, provided you only use them as annotations (and not say, as an implemented interface on some source type).

Review by: jat (desk), mmendez (postmortem)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2576 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java b/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java
index c7a9e03..d3ae321 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java
@@ -15,11 +15,6 @@
  */
 package com.google.gwt.dev.jdt;
 
-import com.google.gwt.core.ext.typeinfo.JAnnotationMethod;
-import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.core.ext.typeinfo.JType;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
@@ -39,10 +34,11 @@
    */
   private static class AnnotationProxyInvocationHandler implements
       InvocationHandler {
+
     /**
-     * Returns <code>true</code> if the expected return type is assignable from 
-     * the actual return type or if the expected return type is a primitive and
-     * the actual return type is the corresponding wrapper type.
+     * Returns <code>true</code> if the expected return type is assignable
+     * from the actual return type or if the expected return type is a primitive
+     * and the actual return type is the corresponding wrapper type.
      */
     private static boolean isValidReturnType(Class<?> expectedReturnType,
         Class<? extends Object> actualReturnType) {
@@ -69,7 +65,7 @@
           return actualReturnType == Short.class;
         }
       }
-      
+
       return false;
     }
 
@@ -78,8 +74,6 @@
      */
     private Class<? extends Annotation> annotationClass;
 
-    private final JClassType annotationType;
-
     /**
      * Maps method names onto values. Note that methods on annotation types
      * cannot be overloaded because they have zero arguments.
@@ -91,10 +85,9 @@
      */
     private Annotation proxy;
 
-    public AnnotationProxyInvocationHandler(JClassType annotationType,
+    public AnnotationProxyInvocationHandler(
         Map<String, Object> identifierToValue,
         Class<? extends Annotation> annotationClass) {
-      this.annotationType = annotationType;
       this.identifierToValue = identifierToValue;
       this.annotationClass = annotationClass;
     }
@@ -104,9 +97,16 @@
       if (proxy == other) {
         return true;
       }
-      if (!annotationClass.isInstance(other)) {
+
+      if (!(other instanceof Annotation)) {
         return false;
       }
+
+      Annotation otherAnnotation = (Annotation) other;
+      if (annotationClass != otherAnnotation.annotationType()) {
+        return false;
+      }
+
       try {
         for (Method method : annotationClass.getDeclaredMethods()) {
           Object myVal = method.invoke(proxy);
@@ -215,30 +215,25 @@
     public Object invoke(Object proxy, Method method, Object[] args)
         throws Throwable {
 
-      String name = method.getName();
-
       Object value = null;
-      if (identifierToValue.containsKey(name)) {
-        // The value was explicitly provided
-        value = identifierToValue.get(name);
-        assert (value != null);
-      } else {
-        JMethod jMethod = annotationType.findMethod(name, new JType[0]);
-        if (jMethod != null) {
-          // The value will be the default value.
-          JAnnotationMethod annotationMethod = jMethod.isAnnotationMethod();
-          assert (annotationMethod != null);
-          value = annotationMethod.getDefaultValue();
+      if (args == null || args.length == 0) {
+        // A no-arg method, try to process as an annotation method.
+        String name = method.getName();
+        if (identifierToValue.containsKey(name)) {
+          // The value was explicitly provided
+          value = identifierToValue.get(name);
           assert (value != null);
-        } else if (method.getDeclaringClass() == Annotation.class
-            && "annotationType".equals(method.getName())) {
-          value = annotationClass;
+        } else {
+          if ("annotationType".equals(method.getName())) {
+            value = annotationClass;
+          } else {
+            value = method.getDefaultValue();
+          }
         }
-      }
-      
-      if (value != null) {
-        assert (isValidReturnType(method.getReturnType(), value.getClass()));
-        return value;
+        if (value != null) {
+          assert (isValidReturnType(method.getReturnType(), value.getClass()));
+          return value;
+        }
       }
 
       /*
@@ -254,8 +249,8 @@
     @Override
     public String toString() {
       final StringBuilder msg = new StringBuilder();
-      msg.append('@').append(annotationType.getQualifiedSourceName()).append(
-          '(');
+      String qualifiedSourceName = annotationClass.getName().replace('$', '.');
+      msg.append('@').append(qualifiedSourceName).append('(');
       boolean first = true;
       try {
         for (Method method : annotationClass.getDeclaredMethods()) {
@@ -285,9 +280,9 @@
   }
 
   public static Annotation create(Class<? extends Annotation> annotationClass,
-      JClassType annotationType, Map<String, Object> identifierToValue) {
+      Map<String, Object> identifierToValue) {
     AnnotationProxyInvocationHandler annotationInvocationHandler = new AnnotationProxyInvocationHandler(
-        annotationType, identifierToValue, annotationClass);
+        identifierToValue, annotationClass);
     Annotation proxy = (Annotation) Proxy.newProxyInstance(
         AnnotationProxyFactory.class.getClassLoader(), new Class<?>[] {
             java.lang.annotation.Annotation.class, annotationClass},
diff --git a/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java b/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java
index ca0e31c..f902f66 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java
@@ -546,8 +546,8 @@
       changedCudsByFileName.put(fileName, cud);
       /*
        * The CacheManager's cuds by file name may include the changed CUDs from
-       * a previous refresh.  So we remove them here to ensure that our sets
-       * do not overlap. 
+       * a previous refresh. So we remove them here to ensure that our sets do
+       * not overlap.
        */
       unchangedCudsByFileName.remove(fileName);
     }
@@ -694,14 +694,7 @@
       identifierToValue.put(identifier, elementValue);
     }
 
-    // Create the Annotation proxy
-    JClassType annotationType = (JClassType) resolveType(logger, resolvedType);
-    if (annotationType == null) {
-      return null;
-    }
-
-    return AnnotationProxyFactory.create(clazz, annotationType,
-        identifierToValue);
+    return AnnotationProxyFactory.create(clazz, identifierToValue);
   }
 
   private JClassType[] createTypeParameterBounds(TreeLogger logger,
@@ -922,16 +915,12 @@
   }
 
   private Class<?> getClassLiteral(TreeLogger logger, TypeBinding resolvedType) {
-    JType type = resolveType(logger, resolvedType);
-    if (type == null) {
-      return null;
-    }
-
-    if (type.isPrimitive() != null) {
-      return getClassLiteralForPrimitive(type.isPrimitive());
+    if (resolvedType instanceof BaseTypeBinding) {
+      return getClassLiteralForPrimitive((BaseTypeBinding) resolvedType);
     } else {
       try {
-        String className = computeBinaryClassName(type);
+        String className = String.valueOf(resolvedType.constantPoolName());
+        className = className.replace('/', '.');
         Class<?> clazz = Class.forName(className);
         return clazz;
       } catch (ClassNotFoundException e) {
@@ -941,27 +930,30 @@
     }
   }
 
-  private Class<?> getClassLiteralForPrimitive(JPrimitiveType type) {
-    if (type == JPrimitiveType.BOOLEAN) {
-      return boolean.class;
-    } else if (type == JPrimitiveType.BYTE) {
-      return byte.class;
-    } else if (type == JPrimitiveType.CHAR) {
-      return char.class;
-    } else if (type == JPrimitiveType.DOUBLE) {
-      return double.class;
-    } else if (type == JPrimitiveType.FLOAT) {
-      return float.class;
-    } else if (type == JPrimitiveType.INT) {
-      return int.class;
-    } else if (type == JPrimitiveType.LONG) {
-      return long.class;
-    } else if (type == JPrimitiveType.SHORT) {
-      return short.class;
+  private Class<?> getClassLiteralForPrimitive(BaseTypeBinding type) {
+    switch (type.id) {
+      case TypeIds.T_boolean:
+        return Boolean.TYPE;
+      case TypeIds.T_byte:
+        return Byte.TYPE;
+      case TypeIds.T_char:
+        return Character.TYPE;
+      case TypeIds.T_short:
+        return Short.TYPE;
+      case TypeIds.T_int:
+        return Integer.TYPE;
+      case TypeIds.T_long:
+        return Long.TYPE;
+      case TypeIds.T_float:
+        return Float.TYPE;
+      case TypeIds.T_double:
+        return Double.TYPE;
+      case TypeIds.T_void:
+        return Void.TYPE;
+      default:
+        assert false : "Unexpected base type id " + type.id;
+        return null;
     }
-
-    assert (false);
-    return null;
   }
 
   private CompilationUnitProvider getCup(TypeDeclaration typeDecl) {