Author: j...@google.com
Date: Thu Jul  2 07:57:32 2009
New Revision: 5659

Added:
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeParameterLookup.java
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassSignature.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleMocks.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/ResolveGenericsTest.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestHandler.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestHandler1.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter0.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter1.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter2.java
Removed:
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassTypeVariables.java
Modified:
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveParameterizedType.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/MockCompilationUnit.java
     
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java

Log:
Test for generics resolution.


Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java   
 
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java   
 
Thu Jul  2 07:57:32 2009
@@ -48,7 +48,7 @@
  import com.google.gwt.dev.javac.asm.CollectFieldData;
  import com.google.gwt.dev.javac.asm.CollectMethodData;
  import com.google.gwt.dev.javac.asm.CollectTypeParams;
-import com.google.gwt.dev.javac.asm.ResolveClassTypeVariables;
+import com.google.gwt.dev.javac.asm.ResolveClassSignature;
  import com.google.gwt.dev.javac.asm.ResolveMethodSignature;
  import com.google.gwt.dev.javac.asm.ResolveParameterizedType;
  import com.google.gwt.dev.javac.asm.CollectAnnotationData.AnnotationData;
@@ -65,7 +65,6 @@
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.HashSet;
-import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
@@ -77,51 +76,8 @@
  public class TypeOracleMediator {

    /**
-   * Handles lookup of type parameters, handling a scope stack.
+   * Pairs of bits to convert from ASM Opcodes.* to Shared.* bitfields.
     */
-  public static class TypeParameterLookup {
-
-    private LinkedList<HashMap<String, JTypeParameter>> scopeStack = new  
LinkedList<HashMap<String, JTypeParameter>>();
-
-    public JTypeParameter lookup(String name) {
-      for (HashMap<String, JTypeParameter> scope : scopeStack) {
-        if (scope.containsKey(name)) {
-          return scope.get(name);
-        }
-      }
-      return null;
-    }
-
-    public void popScope() {
-      scopeStack.remove();
-    }
-
-    public void pushEnclosingScopes(JClassType type) {
-      if (type == null) {
-        return;
-      }
-      pushEnclosingScopes(type.getEnclosingType());
-      JGenericType genericType = type.isGenericType();
-      if (genericType != null) {
-        pushScope(genericType.getTypeParameters());
-      }
-    }
-
-    public void pushScope(JTypeParameter[] typeParams) {
-      // push empty scopes to keep pops in sync
-      scopeStack.addFirst(buildScope(typeParams));
-    }
-
-    private HashMap<String, JTypeParameter> buildScope(
-        JTypeParameter[] typeParams) {
-      HashMap<String, JTypeParameter> scope = new HashMap<String,  
JTypeParameter>();
-      for (JTypeParameter typeParam : typeParams) {
-        scope.put(typeParam.getName(), typeParam);
-      }
-      return scope;
-    }
-  }
-
    private static final int[] ASM_TO_SHARED_MODIFIERS = new int[] {
        Opcodes.ACC_PUBLIC, Shared.MOD_PUBLIC,
        Opcodes.ACC_PRIVATE, Shared.MOD_PRIVATE,
@@ -172,13 +128,13 @@
    }

    private static JTypeParameter[] collectTypeParams(String signature) {
-    // TODO(jat): more efficient when signature is null
-    List<JTypeParameter> params = new ArrayList<JTypeParameter>();
      if (signature != null) {
+      List<JTypeParameter> params = new ArrayList<JTypeParameter>();
        SignatureReader reader = new SignatureReader(signature);
        reader.accept(new CollectTypeParams(params));
+      return params.toArray(new JTypeParameter[params.size()]);
      }
-    return params.toArray(new JTypeParameter[params.size()]);
+    return new JTypeParameter[0];
    }

    private static <T> Class<? extends T> getClassLiteral(TreeLogger logger,
@@ -583,6 +539,16 @@
      }
    }

+  private boolean isPrivateEnumConstructor(JAbstractMethod method,
+      Type[] argTypes) {
+    return "<init>".equals(method.getName())
+        && method.isPrivate()
+        && method.getEnclosingType().isEnum() != null
+        && argTypes.length >= 2
+        && "Ljava/lang/String;".equals(argTypes[0].getDescriptor())
+        && argTypes[1].getSort() == Type.INT;
+  }
+
    /**
     * Map a bitset onto a different bitset.
     *
@@ -739,7 +705,7 @@
          }
          // TODO(jat): other checks?
          try {
-          // TODO(jat): can we use Class.forName here?
+          // TODO(jat): is it safe to use Class.forName here?
            return Class.forName(objType.getQualifiedBinaryName(), false,
                TypeOracleMediator.class.getClassLoader());
          } catch (ClassNotFoundException e) {
@@ -876,7 +842,7 @@
      if (signature != null) {
        // If we have a signature, use it for superclass and interfaces
        SignatureReader reader = new SignatureReader(signature);
-      ResolveClassTypeVariables resolver = new ResolveClassTypeVariables(
+      ResolveClassSignature resolver = new ResolveClassSignature(
            typeOracle, binaryMapper, logger, type, typeParamLookup);
        reader.accept(resolver);
        resolver.finish();
@@ -1075,20 +1041,10 @@
        method.setFakeArgNames();
      }

-    // if (!resolveBoundsForTypeParameters(logger, type, method,  
methodData,
-    // typeParamLookup)) {
-    // return false;
-    // }
-
      String signature = methodData.getSignature();
      Type[] argTypes = methodData.getArgTypes();
      String[] argNames = methodData.getArgNames();
-    if ("<init>".equals(method.getName())
-        && method.isPrivate()
-        && method.getEnclosingType().isEnum() != null
-        && argTypes.length >= 2
-        && "Ljava/lang/String;".equals(argTypes[0].getDescriptor())
-        && argTypes[1].getSort() == Type.INT) {
+    if (isPrivateEnumConstructor(method, argTypes)) {
        // Handle enum private constructors specially, by removing the two
        // hidden fields for the name and ordinal.
        Type[] newTypes = new Type[argTypes.length - 2];
@@ -1101,8 +1057,8 @@
      if (signature != null) {
        // If we have a signature, use it for superclass and interfaces
        SignatureReader reader = new SignatureReader(signature);
-      ResolveMethodSignature resolver = new ResolveMethodSignature(this,  
logger,
-          method, typeParamLookup, hasReturnType, methodData, argTypes,
+      ResolveMethodSignature resolver = new ResolveMethodSignature(this,
+          logger, method, typeParamLookup, hasReturnType, methodData,  
argTypes,
            argNames);
        // TraceSignatureVisitor trace = new TraceSignatureVisitor(
        // methodData.getAccess());

Added:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeParameterLookup.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeParameterLookup.java  
 
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009 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.javac;
+
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JGenericType;
+import com.google.gwt.core.ext.typeinfo.JTypeParameter;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+/**
+ * Handles lookup of type parameters, using a scope stack.
+ */
+public class TypeParameterLookup {
+
+  private LinkedList<HashMap<String, JTypeParameter>> scopeStack = new  
LinkedList<HashMap<String, JTypeParameter>>();
+
+  public JTypeParameter lookup(String name) {
+    for (HashMap<String, JTypeParameter> scope : scopeStack) {
+      if (scope.containsKey(name)) {
+        return scope.get(name);
+      }
+    }
+    return null;
+  }
+
+  public void popScope() {
+    scopeStack.remove();
+  }
+
+  public void pushEnclosingScopes(JClassType type) {
+    if (type == null) {
+      return;
+    }
+    pushEnclosingScopes(type.getEnclosingType());
+    JGenericType genericType = type.isGenericType();
+    if (genericType != null) {
+      pushScope(genericType.getTypeParameters());
+    }
+  }
+
+  public void pushScope(JTypeParameter[] typeParams) {
+    // push empty scopes to keep pops in sync
+    scopeStack.addFirst(buildScope(typeParams));
+  }
+
+  private HashMap<String, JTypeParameter> buildScope(
+      JTypeParameter[] typeParams) {
+    HashMap<String, JTypeParameter> scope = new HashMap<String,  
JTypeParameter>();
+    for (JTypeParameter typeParam : typeParams) {
+      scope.put(typeParam.getName(), typeParam);
+    }
+    return scope;
+  }
+}
\ No newline at end of file

Added:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassSignature.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveClassSignature.java
     
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2009 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.javac.asm;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JRealClassType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.JTypeParameter;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.dev.asm.signature.SignatureVisitor;
+import com.google.gwt.dev.javac.TypeParameterLookup;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Signature visitor that resolves all the type variables and their bounds  
for
+ * a given class.
+ */
+public class ResolveClassSignature extends EmptySignatureVisitor {
+
+  private final TypeOracle typeOracle;
+  private final Map<String, JRealClassType> binaryMapper;
+  private final TreeLogger logger;
+  private final JRealClassType type;
+  private final TypeParameterLookup lookup;
+
+  private JTypeParameter currentParam = null;
+  private ArrayList<JType[]> bounds = null;
+  private JType[] superClass = new JType[1];
+  private List<JType[]> interfaces = new ArrayList<JType[]>();
+
+  public ResolveClassSignature(TypeOracle typeOracle,
+      Map<String, JRealClassType> binaryMapper, TreeLogger logger,
+      JRealClassType type, TypeParameterLookup lookup) {
+    this.typeOracle = typeOracle;
+    this.binaryMapper = binaryMapper;
+    this.logger = logger;
+    this.type = type;
+    this.lookup = lookup;
+  }
+
+  public void finish() {
+    if (currentParam != null) {
+      int n = bounds.size();
+      JClassType[] boundTypes = new JClassType[n];
+      for (int i = 0; i < n; ++i) {
+        boundTypes[i] = (JClassType) bounds.get(i)[0];
+      }
+      currentParam.setBounds(boundTypes);
+      currentParam = null;
+      // TODO(jat): remove after debugging phase
+      bounds = null;
+    }
+    if (superClass[0] != null) {
+      if (type.isInterface() != null) {
+        // The generic signature contains a superclass for interfaces,
+        // but TypeOracle doesn't like that -- verify that we were
+        // told Object is the superclass and ignore it.
+        assert superClass[0].equals(typeOracle.getJavaLangObject());
+      } else {
+        type.setSuperclass((JClassType) superClass[0]);
+      }
+      superClass[0] = null;
+    }
+    for (JType[] intfRef : interfaces) {
+      if (intfRef[0] != null) {
+        type.addImplementedInterface((JClassType) intfRef[0]);
+      }
+    }
+    interfaces.clear();
+  }
+
+  @Override
+  public SignatureVisitor visitArrayType() {
+    assert false : "visitArrayType called on ResolveClassTypeVariables";
+    return null;
+  }
+
+  @Override
+  public SignatureVisitor visitClassBound() {
+    JType[] bound = new JType[1];
+    bounds.add(bound);
+    return new ResolveParameterizedType(typeOracle, binaryMapper, logger,  
bound, lookup, null);
+  }
+
+  @Override
+  public void visitFormalTypeParameter(String name) {
+    finish();
+    currentParam = lookup.lookup(name);
+    bounds = new ArrayList<JType[]>();
+  }
+
+  @Override
+  public SignatureVisitor visitInterface() {
+    finish();
+    JType[] intf = new JType[1];
+    interfaces.add(intf);
+    return new ResolveParameterizedType(typeOracle, binaryMapper, logger,  
intf, lookup, null);
+  }
+
+  @Override
+  public SignatureVisitor visitInterfaceBound() {
+    JType[] bound = new JType[1];
+    bounds.add(bound);
+    return new ResolveParameterizedType(typeOracle, binaryMapper, logger,  
bound, lookup, null);
+  }
+
+  @Override
+  public SignatureVisitor visitSuperclass() {
+    finish();
+    return new ResolveParameterizedType(typeOracle, binaryMapper, logger,  
superClass, lookup, null);
+  }
+}
\ No newline at end of file

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java
    
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveMethodSignature.java
    
Thu Jul  2 07:57:32 2009
@@ -25,7 +25,7 @@
  import com.google.gwt.dev.asm.Type;
  import com.google.gwt.dev.asm.signature.SignatureVisitor;
  import com.google.gwt.dev.javac.TypeOracleMediator;
-import com.google.gwt.dev.javac.TypeOracleMediator.TypeParameterLookup;
+import com.google.gwt.dev.javac.TypeParameterLookup;

  import java.lang.annotation.Annotation;
  import java.util.ArrayList;

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveParameterizedType.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveParameterizedType.java
  
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/asm/ResolveParameterizedType.java
  
Thu Jul  2 07:57:32 2009
@@ -27,7 +27,7 @@
  import com.google.gwt.core.ext.typeinfo.NotFoundException;
  import com.google.gwt.core.ext.typeinfo.TypeOracle;
  import com.google.gwt.dev.asm.signature.SignatureVisitor;
-import com.google.gwt.dev.javac.TypeOracleMediator.TypeParameterLookup;
+import com.google.gwt.dev.javac.TypeParameterLookup;
  import com.google.gwt.dev.util.Name;

  import java.util.ArrayList;
@@ -55,11 +55,17 @@
    /**
     * Resolve a parameterized type.
     *
+   * @param typeOracle
+   * @param binaryMapper
+   * @param logger
     * @param returnTypeRef "pointer" to return location, ie. 1-element array
+   * @param lookup
+   * @param enclosingClass
     */
-  public ResolveParameterizedType(TypeOracle typeOracle, Map<String,  
JRealClassType> binaryMapper,
-      TreeLogger logger, JType[] returnTypeRef,
-      TypeParameterLookup lookup, JClassType enclosingClass) {
+  public ResolveParameterizedType(TypeOracle typeOracle,
+      Map<String, JRealClassType> binaryMapper, TreeLogger logger,
+      JType[] returnTypeRef, TypeParameterLookup lookup,
+      JClassType enclosingClass) {
      this(typeOracle, binaryMapper, logger, returnTypeRef, lookup,
          enclosingClass, '=');
    }

Added:  
changes/jat/ihm/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleMocks.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleMocks.java
      
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.javac.CompilationUnit;
+import com.google.gwt.dev.javac.MockCompilationUnit;
+import com.google.gwt.dev.javac.TypeOracleMediator;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Contains mocks of the base JRE classes for tests as compilation units.
+ */
+public class TypeOracleMocks {
+
+  /**
+   * A minimal TypeOracle mock that adds java.lang.Object and exposes
+   * the addNewType hook to callers.
+   */
+  public static class BareTypeOracle extends TypeOracle {
+
+    public BareTypeOracle() {
+      JPackage javaLang = getOrCreatePackage("java.lang");
+      JRealClassType javaLangObject = new JRealClassType(this, javaLang,
+          null, false, "Object", false);
+      addNewType(javaLangObject);
+    }
+
+    // Increases visibility so tests in other packages can hook this.
+    @Override
+    protected void addNewType(JRealClassType newType) {
+      super.addNewType(newType);
+    }
+  }
+
+  private TreeLogger logger;
+  private TypeOracleMediator mediator;
+
+  public TypeOracleMocks() {
+    mediator = new TypeOracleMediator();
+    if (false) {
+      logger = new PrintWriterTreeLogger();
+    } else {
+      logger = TreeLogger.NULL;
+    }
+  }
+
+  public void addMock(String pkg, String name, String src) {
+    List<CompilationUnit> units = new ArrayList<CompilationUnit>();
+    units.add(buildMockForClass(pkg, name, src));
+    mediator.addNewUnits(logger, units);
+  }
+
+  public void addJreMocks() {
+    List<CompilationUnit> units = new ArrayList<CompilationUnit>();
+    units.add(buildMockForClass("java.lang", "Class", null));
+    units.add(buildMockForClass("java.lang", "Object", null));
+    units.add(buildMockForClass("java.lang", "Throwable", null));
+    units.add(buildMockForClass("java.util", "Map",
+        "public interface Map<K, V> {" +
+        "  interface Entry<K, V> {" +
+        "    K getKey();" +
+        "    V getValue();" +
+        "  }" +
+        "  boolean contains(K key);" +
+        "  V put(K key, V value);" +
+        "  V get(K key);"
+        ));
+    mediator.addNewUnits(logger, units);
+  }
+
+  public TypeOracleMediator getMediator() {
+    return mediator;
+  }
+
+  public TypeOracle getTypeOracle() {
+    return mediator.getTypeOracle();
+  }
+
+  private CompilationUnit buildMockForClass(String pkg, String name,
+      String src) {
+    if (src == null) {
+      src = "public class " + name + " { }";
+    }
+    src = "package " + pkg + ";" + src;
+    return new MockCompilationUnit(name, src);
+  }
+}

Modified:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/MockCompilationUnit.java
==============================================================================
---  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/MockCompilationUnit.java 
 
(original)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/MockCompilationUnit.java 
 
Thu Jul  2 07:57:32 2009
@@ -30,6 +30,7 @@
      this.source = source;
    }

+  @Override
    public String getDisplayLocation() {
      return "/mock/" + getTypeName();
    }
@@ -45,10 +46,12 @@
      return source;
    }

+  @Override
    public String getTypeName() {
      return typeName;
    }

+  @Override
    public boolean isGenerated() {
      return true;
    }

Modified:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java
==============================================================================
---  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java     
 
(original)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/AsmTestCase.java     
 
Thu Jul  2 07:57:32 2009
@@ -46,7 +46,6 @@
      return getClassBytes(clazz.getName());
    }

-
    /**
     * Read the bytes of a class.
     *
@@ -60,5 +59,30 @@
        return null;
      }
      return Util.readStreamAsBytes(str);
+  }
+
+  /**
+   * Reads the source for a class.
+   *
+   * @param clazz class literal of the class to read
+   * @return source from .java file or null if not found
+   */
+  protected String getClassSource(Class<?> clazz) {
+    return getClassSource(clazz.getName());
+  }
+
+  /**
+   * Reads the source for a class.
+   *
+   * @param className binary name (ie com.Foo$Bar) of the class to read
+   * @return source from .java file or null if not found
+   */
+  protected String getClassSource(String className) {
+    InputStream str = CLASSLOADER.getResourceAsStream(
+        className.replace('.', '/') + ".java");
+    if (str == null) {
+      return null;
+    }
+    return Util.readStreamAsString(str);
    }
  }

Added:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/ResolveGenericsTest.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/ResolveGenericsTest.java
      
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2009 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.javac.asm;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JGenericType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JPackage;
+import com.google.gwt.core.ext.typeinfo.JParameter;
+import com.google.gwt.core.ext.typeinfo.JParameterizedType;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JRealClassType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.JTypeParameter;
+import com.google.gwt.core.ext.typeinfo.JWildcardType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
+import com.google.gwt.core.ext.typeinfo.TypeOracleMocks.BareTypeOracle;
+import com.google.gwt.dev.asm.Opcodes;
+import com.google.gwt.dev.asm.Type;
+import com.google.gwt.dev.asm.signature.SignatureReader;
+import com.google.gwt.dev.javac.TypeOracleMediator;
+import com.google.gwt.dev.javac.TypeParameterLookup;
+import com.google.gwt.dev.javac.asm.CollectClassData.ClassType;
+import com.google.gwt.dev.util.log.AbstractTreeLogger;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.TypeVariable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tests for {...@link ResolveClassSignature} and
+ * {...@link ResolveMethodSignature}.
+ */
+public class ResolveGenericsTest extends AsmTestCase {
+
+  public static class FailErrorTreeLogger extends AbstractTreeLogger {
+    @Override
+    protected AbstractTreeLogger doBranch() {
+      // TODO(jat): Auto-generated method stub
+      return null;
+    }
+
+    @Override
+    protected void doCommitBranch(AbstractTreeLogger childBeingCommitted,
+        com.google.gwt.core.ext.TreeLogger.Type type, String msg,
+        Throwable caught, HelpInfo helpInfo) {
+      if (type == TreeLogger.ERROR) {
+        fail(msg);
+      }
+    }
+
+    @Override
+    protected void doLog(int indexOfLogEntryWithinParentLogger,
+        com.google.gwt.core.ext.TreeLogger.Type type, String msg,
+        Throwable caught, HelpInfo helpInfo) {
+      if (type == TreeLogger.ERROR) {
+        fail(msg);
+      }
+    }
+  }
+
+  /**
+   * An extension of JMethod which keeps the reflected Method around.
+   */
+  public static class ReflectedMethod extends JMethod {
+    private Method method;
+
+    public ReflectedMethod(JClassType type, String methodName,
+        Map<Class<? extends Annotation>, Annotation> annotations,
+        JTypeParameter[] typeParams, Method method) {
+      super(type, methodName, annotations, typeParams);
+      this.method = method;
+    }
+
+    public Method getMethod() {
+      return method;
+    }
+  }
+
+  public static class ResolverMockTypeOracle extends BareTypeOracle {
+
+    private Map<String, JRealClassType> binaryMapper;
+
+    public Map<String, JRealClassType> getBinaryMapper() {
+      ensureBinaryMapper();
+      return binaryMapper;
+    }
+
+    @Override
+    public JParameterizedType getParameterizedType(JGenericType  
genericType,
+        JClassType enclosingType, JClassType[] typeArgs) {
+      // TODO(jat): Auto-generated method stub
+      return super.getParameterizedType(genericType, enclosingType,  
typeArgs);
+    }
+
+    @Override
+    public JWildcardType getWildcardType(BoundType boundType,
+        JClassType typeBound) {
+      // TODO(jat): Auto-generated method stub
+      return super.getWildcardType(boundType, typeBound);
+    }
+
+    @Override
+    protected void addNewType(JRealClassType type) {
+      super.addNewType(type);
+      String name = type.getQualifiedBinaryName().replace('.', '/');
+      ensureBinaryMapper();
+      binaryMapper.put(name, type);
+    }
+
+    private void ensureBinaryMapper() {
+      if (binaryMapper == null) {
+        binaryMapper = new HashMap<String, JRealClassType>();
+      }
+    }
+  }
+
+  private static final TreeLogger failTreeLogger = new  
FailErrorTreeLogger();
+
+  private static final String OUTER_CLASS_SIG
+      = "<H:Lcom/google/gwt/dev/javac/asm/TestHandler;>Ljava/lang/Object;";
+  private static final String OUTER_METHOD_SIG = "(TH;)V";
+
+  private static final String OUTER1_CLASS_SIG
+      = "<V:Ljava/lang/Object;>Lcom/google/gwt/dev/javac/asm/TestOuter0<"
+        + "Lcom/google/gwt/dev/javac/asm/TestHandler1<TV;>;>;";
+  private static final String OUTER1_METHOD_SIG
+      = "(Lcom/google/gwt/dev/javac/asm/TestHandler1<TV;>;)V";
+
+  private static final String OUTER2_CLASS_SIG
+      = "Lcom/google/gwt/dev/javac/asm/TestOuter1<Ljava/lang/String;>;";
+  private static final String OUTER2_METHOD_SIG
+       
= "(Lcom/google/gwt/dev/javac/asm/TestHandler1<Ljava/lang/String;>;)V";
+
+  private ResolverMockTypeOracle oracle;
+
+  @SuppressWarnings("unused")
+  private JRealClassType testHandler;
+  @SuppressWarnings("unused")
+  private JRealClassType testHandler1;
+
+  private JRealClassType testOuter0;
+  private JRealClassType testOuter1;
+  private JRealClassType testOuter2;
+
+  private ReflectedMethod testOuter0dispatch;
+  private ReflectedMethod testOuter1dispatch;
+  private ReflectedMethod testOuter2dispatch;
+
+  @SuppressWarnings("unused")
+  private JRealClassType testType;
+
+  @Override
+  public void setUp() {
+    oracle = new ResolverMockTypeOracle();
+    testHandler = createUnresolvedClass(TestHandler.class, null);
+    testHandler1 = createUnresolvedClass(TestHandler1.class, null);
+    testOuter0 = createUnresolvedClass(TestOuter0.class, null);
+    testType = createUnresolvedClass(TestOuter0.Type.class, testOuter0);
+    testOuter1 = createUnresolvedClass(TestOuter1.class, null);
+    testOuter2 = createUnresolvedClass(TestOuter2.class, null);
+    testOuter0dispatch = createUnresolvedMethod(testOuter0,  
TestOuter0.class,
+        "dispatch", TestHandler.class);
+    testOuter1dispatch = createUnresolvedMethod(testOuter1,  
TestOuter1.class,
+        "dispatch", TestHandler.class);
+    testOuter2dispatch = createUnresolvedMethod(testOuter2,  
TestOuter2.class,
+        "dispatch", TestHandler.class);
+  }
+
+  public void testOuter0Class() {
+    resolveClassSignature(testOuter0, OUTER_CLASS_SIG);
+    assertNotNull(testOuter0.getSuperclass());
+    // TODO(jat): additional checks?
+  }
+
+  public void testOuter0Method() {
+    resolveMethodSignature(testOuter0dispatch, OUTER_METHOD_SIG);
+    // TODO(jat): meaningful tests besides no errors?
+  }
+
+  public void testOuter1Class() {
+    resolveClassSignature(testOuter1, OUTER1_CLASS_SIG);
+    JClassType superClass = testOuter1.getSuperclass();
+    assertNotNull(superClass);
+    assertNotNull(superClass.isParameterized());
+    // TODO(jat): additional checks?
+  }
+
+  public void testOuter1Method() {
+    resolveMethodSignature(testOuter1dispatch, OUTER1_METHOD_SIG);
+    // TODO(jat): meaningful tests besides no errors?
+  }
+
+  public void testOuter2Class() {
+    resolveClassSignature(testOuter2, OUTER2_CLASS_SIG);
+    JClassType superClass = testOuter2.getSuperclass();
+    assertNotNull(superClass);
+    assertNotNull(superClass.isParameterized());
+    // TODO(jat): additional checks?
+  }
+
+  public void testOuter2Method() {
+    resolveMethodSignature(testOuter2dispatch, OUTER2_METHOD_SIG);
+    // TODO(jat): meaningful tests besides no errors?
+  }
+
+  private JTypeParameter[] createTypeParams(TypeVariable<?>[] typeParams) {
+    int n = typeParams.length;
+    JTypeParameter[] params = new JTypeParameter[n];
+    for (int i = 0; i < n; ++i) {
+      params[i] = new JTypeParameter(typeParams[i].getName(), i);
+    }
+    return params;
+  }
+
+  private JRealClassType createUnresolvedClass(Class<?> clazz,
+      JRealClassType enclosingType) {
+    String pkgName = clazz.getPackage().getName();
+    JPackage pkg = oracle.getOrCreatePackage(pkgName);
+    TypeVariable<?>[] typeParams = clazz.getTypeParameters();
+    JRealClassType type;
+    int n = typeParams.length;
+    if (n == 0) {
+      type = new JRealClassType(oracle, pkg, enclosingType,
+        false, clazz.getSimpleName(), clazz.isInterface());
+    } else {
+      JTypeParameter[] params = createTypeParams(typeParams);
+      type = new JGenericType(oracle, pkg, enclosingType, false,
+          clazz.getSimpleName(), clazz.isInterface(), params);
+    }
+    return type;
+  }
+
+  private ReflectedMethod createUnresolvedMethod(JClassType type, Class<?>  
clazz,
+      String methodName, Class<?>... paramTypes) {
+    Method method = null;
+    try {
+      method = clazz.getMethod(methodName, paramTypes);
+    } catch (SecurityException e) {
+      fail("Exception " + e + " creating method " + methodName + " on " +  
clazz);
+    } catch (NoSuchMethodException e) {
+      fail("Exception " + e + " creating method " + methodName + " on " +  
clazz);
+    }
+    JTypeParameter[] typeParams =  
createTypeParams(method.getTypeParameters());
+    Map<Class<? extends Annotation>, Annotation> emptyMap
+        = Collections.emptyMap();
+    return new ReflectedMethod(type, methodName, emptyMap, typeParams,  
method);
+  }
+
+  private Type getAsmType(JType type) {
+    JPrimitiveType primitiveType = type.isPrimitive();
+    if (primitiveType != null) {
+      if (primitiveType == JPrimitiveType.BOOLEAN) {
+        return Type.BOOLEAN_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.BYTE) {
+        return Type.BYTE_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.CHAR) {
+        return Type.CHAR_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.DOUBLE) {
+        return Type.DOUBLE_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.FLOAT) {
+        return Type.FLOAT_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.INT) {
+        return Type.INT_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.LONG) {
+        return Type.LONG_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.SHORT) {
+        return Type.SHORT_TYPE;
+      }
+      if (primitiveType == JPrimitiveType.VOID) {
+        return Type.VOID_TYPE;
+      }
+      fail("Unexpected primitive type " + primitiveType);
+    }
+    return  
Type.getObjectType(type.getQualifiedBinaryName().replace('.', '/'));
+  }
+
+  private void resolveClassSignature(JRealClassType type, String  
signature) {
+    Map<String, JRealClassType> binaryMapper = oracle.getBinaryMapper();
+    TypeParameterLookup lookup = new TypeParameterLookup();
+    lookup.pushEnclosingScopes(type);
+    ResolveClassSignature resolver = new ResolveClassSignature(oracle,
+        binaryMapper, failTreeLogger, type, lookup);
+    new SignatureReader(signature).accept(resolver);
+    resolver.finish();
+  }
+
+  private void resolveMethodSignature(ReflectedMethod method,
+      String signature) {
+    TypeParameterLookup lookup = new TypeParameterLookup();
+    lookup.pushEnclosingScopes(method.getEnclosingType());
+    lookup.pushScope(method.getTypeParameters());
+    TypeOracleMediator mediator = new TypeOracleMediator() {
+      @Override
+      public Map<String, JRealClassType> getBinaryMapper() {
+        return oracle.getBinaryMapper();
+      }
+
+      @Override
+      public TypeOracle getTypeOracle() {
+        return oracle;
+      }
+
+      @Override
+      public boolean resolveAnnotations(TreeLogger logger,
+          List<CollectAnnotationData> annotations,
+          Map<Class<? extends Annotation>, Annotation>  
declaredAnnotations) {
+        return true;
+      }
+    };
+    int access = Opcodes.ACC_PUBLIC;
+    String desc = Type.getMethodDescriptor(method.getMethod());
+    CollectMethodData methodData = new  
CollectMethodData(ClassType.TopLevel,
+        access, method.getName(), desc, signature, null);
+    JParameter[] params = method.getParameters();
+    int n = params.length;
+    Type[] argTypes = new Type[n];
+    String[] argNames = new String[n];
+    for (int i = 0; i < n; ++i) {
+      argNames[i] = "arg" + i;
+      argTypes[i] = getAsmType(params[i].getType());
+    }
+    ResolveMethodSignature resolver = new ResolveMethodSignature(mediator,
+        failTreeLogger, method, lookup, true, methodData, argTypes,  
argNames);
+    new SignatureReader(signature).accept(resolver);
+    resolver.finish();
+  }
+}

Added:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestHandler.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestHandler.java     
 
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2008 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.javac.asm;
+
+public interface TestHandler {
+}
\ No newline at end of file

Added:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestHandler1.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestHandler1.java    
 
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2009 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.javac.asm;
+
+/**
+ * Test class for generic signature validation.
+ *
+ * @param <V>
+ */
+public class TestHandler1<V> implements TestHandler {
+}

Added:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter0.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter0.java      
 
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2009 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.javac.asm;
+
+public abstract class TestOuter0<H extends TestHandler> {
+  public static class Type<H> {
+    public Type() {
+    }
+  }
+
+  public abstract void dispatch(H handler);
+}
\ No newline at end of file

Added:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter1.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter1.java      
 
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2009 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.javac.asm;
+
+public class TestOuter1<V> extends TestOuter0<TestHandler1<V>> {
+
+  @Override
+  public void dispatch(TestHandler1<V> handler) {
+  }
+}

Added:  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter2.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/test/com/google/gwt/dev/javac/asm/TestOuter2.java      
 
Thu Jul  2 07:57:32 2009
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2009 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.javac.asm;
+
+public class TestOuter2 extends TestOuter1<String> {
+
+  @Override
+  public void dispatch(TestHandler1<String> handler) {
+  }
+}

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to