Author: j...@google.com
Date: Wed Feb  4 16:56:06 2009
New Revision: 4631

Added:
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompiledClass.java  
  
(contents, props changed)
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/SourceCompiledClass.java  
  
(contents, props changed)
Removed:
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompiledClassVisitor.java
Modified:
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnit.java
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnitBuilder.java
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompilationUnitInvalidator.java
    changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompilationUnit.java
    changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
    changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
     
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java

Log:
Split CompiledClass into BinaryCompiledClass and SourceCompiledClass.


Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnit.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnit.java
         
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnit.java
         
Wed Feb  4 16:56:06 2009
@@ -18,6 +18,7 @@

  import org.eclipse.jdt.core.compiler.CategorizedProblem;

+import java.util.HashSet;
  import java.util.Set;

  /**
@@ -26,6 +27,8 @@
   */
  public class BinaryCompilationUnit extends CompilationUnit {

+  private Set<BinaryCompiledClass> compiledClasses = new  
HashSet<BinaryCompiledClass>();;
+
    /* (non-Javadoc)
     * @see com.google.gwt.dev.javac.CompilationUnit#getDisplayLocation()
     */
@@ -54,7 +57,6 @@
     */
    @Override
    public String getSource() {
-    // TODO(jat): Auto-generated method stub
      return null;
    }

@@ -85,19 +87,16 @@
      return false;
    }

-  /* (non-Javadoc)
-   * @see com.google.gwt.dev.javac.CompilationUnit#isSuperSource()
-   */
    @Override
    public boolean isSuperSource() {
-    // TODO(jat): Auto-generated method stub
      return false;
    }

    @Override
    protected Set<CompiledClass> computeCompiledClasses() {
-    // TODO(jat): Auto-generated method stub
-    return null;
+    Set<CompiledClass> classes = new HashSet<CompiledClass>();
+    classes.addAll(compiledClasses);
+    return classes;
    }

    /* (non-Javadoc)
@@ -105,22 +104,18 @@
     */
    @Override
    protected Set<String> computeFileNameRefs() {
-    // TODO(jat): Auto-generated method stub
+    Set<String> filenames = new HashSet<String>();
+    for (BinaryCompiledClass compiledClass : compiledClasses) {
+      filenames.add(compiledClass.getClassResource().getLocation());
+    }
      return null;
    }

-  /* (non-Javadoc)
-   * @see com.google.gwt.dev.javac.CompilationUnit#getErrors()
-   */
    @Override
    CategorizedProblem[] getErrors() {
-    // TODO(jat): Auto-generated method stub
      return null;
    }

-  /* (non-Javadoc)
-   * @see  
com.google.gwt.dev.javac.CompilationUnit#setState(com.google.gwt.dev.javac.CompilationUnit.State)
-   */
    @Override
    void setState(State newState) {
      // TODO(jat): Auto-generated method stub

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnitBuilder.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnitBuilder.java
  
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompilationUnitBuilder.java
  
Wed Feb  4 16:56:06 2009
@@ -17,21 +17,150 @@
  package com.google.gwt.dev.javac;

  import com.google.gwt.dev.asm.ClassReader;
-import  
com.google.gwt.dev.javac.BinaryCompiledClassVisitor.ClassNotSuitableException;
+import com.google.gwt.dev.asm.FieldVisitor;
+import com.google.gwt.dev.asm.MethodVisitor;
+import com.google.gwt.dev.asm.Opcodes;
+import com.google.gwt.dev.asm.commons.EmptyVisitor;
  import com.google.gwt.dev.resource.Resource;
  import com.google.gwt.dev.util.Util;

  import java.io.InputStream;
  import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
  import java.util.Map;
+import java.util.Set;

  /**
   * Builds a BinaryCompilationUnit from a set of class files.
   */
  public class BinaryCompilationUnitBuilder {

+  /**
+   * Exception thrown when the supplied class is not suitable for use from  
a
+   * class file rather than source.
+   */
+  public static class ClassNotSuitableException extends RuntimeException {
+
+    public ClassNotSuitableException(String msg) {
+      super(msg);
+    }
+  }
+
+  /**
+   * Reads the bytecode for a class and, if suitable, builds a
+   * BinaryCompilationUnit and its BinaryCompileClass entries.
+   */
+  public class BinaryCompiledClassVisitor extends EmptyVisitor {
+
+    private String source = null;
+    private List<Resource> innerClasses = new ArrayList<Resource>();
+    private String name;
+    private String signature;
+    private String superName;
+    private String[] interfaces;
+    private byte[] bytes;
+    private Resource classResource;
+
+    public BinaryCompiledClassVisitor(Resource classResource, byte[]  
bytes) {
+      this.classResource = classResource;
+      this.bytes = bytes;
+    }
+
+    public BinaryCompiledClass getBinaryCompiledClass() {
+      CompiledClass enclosingClass = null;
+      // TODO(jat): Auto-generated method stub
+      return new BinaryCompiledClass(classResource, bytes, enclosingClass,  
name, signature, superName,
+          interfaces, innerClasses);
+    }
+
+    /**
+     * Called at the beginning of visiting the class.
+     *
+     * @param version classfile version (ie, Opcodes.V1_5 etc)
+     * @param access access flags (ie, bitwise or of Opcodes.ACC_*)
+     * @param name binary name of this class (ie, com/google/Foo)
+     * @param signature generic signature or null
+     * @param superName binary name of superclass (ie, java/lang/Object)
+     * @param interfaces array of binary names of implemented interfaces
+     */
+    @Override
+    public void visit(int version, int access, String name, String  
signature,
+        String superName, String[] interfaces) {
+      // Is there anything we should check here, such as if it implements  
a JSO?
+      this.name = name;
+      this.signature = signature;
+      this.superName = superName;
+      this.interfaces = interfaces;
+    }
+
+    /**
+     * Called for each field.
+     *
+     * @param access access flags for field
+     * @param name field name
+     * @param desc type descriptor (ie, Ljava/lang/String;)
+     * @param signature generic signature (null if not generic)
+     * @param value initialized value if constant
+     */
+    @Override
+    public FieldVisitor visitField(int access, String name, String desc,
+        String signature, Object value) {
+      // TODO(jat): Collect fields & annotations for TypeOracle building
+      return null;
+    }
+
+    /**
+     * Called once for every inner class of this class.
+     *
+     * @param name binary name of inner class (ie, com/google/Foo$1)
+     * @param outerName binary name of enclosing class (null if not a  
member
+     *     class or anonymous)
+     * @param innerName simple name of the inner class (null if anonymous)
+     * @param access access flags (bitwise or of Opcodes.ACC_*) as  
declared in
+     *     the enclosing class
+     */
+    @Override
+    public void visitInnerClass(String name, String outerName, String  
innerName,
+        int access) {
+      Resource innerClass = binaryMap.get(innerName + ".class");
+      if (innerClass != null) {
+        addClass(innerClass);
+        innerClasses.add(innerClass);
+      }
+    }
+
+    @Override
+    public MethodVisitor visitMethod(int access, String name, String desc,
+        String signature, String[] exceptions) {
+      if ((access & Opcodes.ACC_NATIVE) != 0) {
+        throw new ClassNotSuitableException("Has native methods");
+      }
+      // TODO(jat): Collect annotations/etc for TypeOracle
+      return null;
+    }
+
+    @Override
+    public void visitOuterClass(String owner, String name, String desc) {
+      // TODO(jat): Auto-generated method stub
+      super.visitOuterClass(owner, name, desc);
+    }
+
+    /**
+     * If compiled with debug, visit the source information.
+     *
+     * @param source unqualified filename containing source (ie, Foo.java)
+     * @param debug additional debug information (may be null)
+     */
+    @Override
+    public void visitSource(String source, String debug) {
+      this.source = source;
+    }
+  }
+
+  private final Map<String, Resource> binaryMap;
+
    private ArrayList<Resource> processQueue = new ArrayList<Resource>();
-  private Map<String, Resource> binaryMap;
    private ArrayList<BinaryCompiledClass> classes = new  
ArrayList<BinaryCompiledClass>();

    public BinaryCompilationUnitBuilder(Map<String, Resource> binaryMap) {
@@ -43,13 +172,18 @@
    }

    public BinaryCompilationUnit getBinaryCompilationUnit() {
+    Set<BinaryCompiledClass> seen = new HashSet<BinaryCompiledClass>();
      while (!processQueue.isEmpty()) {
        BinaryCompiledClass compiledClass =  
processClass(processQueue.remove(0));
+      if (seen.contains(compiledClass)) {
+        continue;
+      }
+      seen.add(compiledClass);
        if (compiledClass != null) {
          classes.add(compiledClass);
        }
      }
-    return null;
+    return new BinaryCompilationUnit();
    }

    private BinaryCompiledClass processClass(Resource classResource) {
@@ -63,7 +197,8 @@
      }
      try {
        ClassReader reader = new ClassReader(classBytes);
-      BinaryCompiledClassVisitor visitor = new  
BinaryCompiledClassVisitor();
+      BinaryCompiledClassVisitor visitor = new BinaryCompiledClassVisitor(
+          classResource, classBytes);
        reader.accept(visitor, ClassReader.SKIP_CODE);
        return visitor.getBinaryCompiledClass();
      } catch (ClassNotSuitableException e) {

Added:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompiledClass.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/BinaryCompiledClass.java  
 
Wed Feb  4 16:56:06 2009
@@ -0,0 +1,107 @@
+/*
+ * 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.dev.js.ast.JsProgram;
+import com.google.gwt.dev.resource.Resource;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author j...@google.com (Your Name Here)
+ *
+ */
+public class BinaryCompiledClass extends CompiledClass {
+
+  private String name;
+  private String signature;
+  private Object superName;
+  private String[] interfaces;
+  private List<Resource> innerClasses;
+  private Resource classResource;
+
+  BinaryCompiledClass(CompiledClass enclosingClass) {
+    super(null, enclosingClass);
+    // TODO Auto-generated constructor stub
+  }
+
+  public BinaryCompiledClass(Resource classResource, byte[] bytes,
+      CompiledClass enclosingClass, String name, String signature,
+      String superName, String[] interfaces, List<Resource> innerClasses) {
+    super(null, enclosingClass);
+    this.classResource = classResource;
+    this.bytes = bytes;
+    this.name = name;
+    this.signature = signature;
+    this.superName = superName;
+    this.interfaces = interfaces;
+    this.innerClasses = innerClasses;
+  }
+
+  Resource getClassResource() {
+    return classResource;
+  }
+
+  private byte[] bytes;
+
+  @Override
+  void checked() {
+    // TODO Auto-generated method stub
+
+  }
+
+  @Override
+  public String getBinaryName() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /* (non-Javadoc)
+   * @see com.google.gwt.dev.javac.CompiledClass#getBytes()
+   */
+  @Override
+  public byte[] getBytes() {
+    return bytes;
+  }
+
+  /* (non-Javadoc)
+   * @see com.google.gwt.dev.javac.CompiledClass#getPackageName()
+   */
+  @Override
+  public String getPackageName() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /* (non-Javadoc)
+   * @see com.google.gwt.dev.javac.CompiledClass#getSourceName()
+   */
+  @Override
+  public String getSourceName() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  @Override
+  public List<JsniMethod> getJsniMethods(JsProgram program,
+      JnsiErrorCallback callback) {
+    // Currently we do not support JSNI in binary classes.
+    return Collections.emptyList();
+  }
+
+}

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompilationUnitInvalidator.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompilationUnitInvalidator.java
    
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompilationUnitInvalidator.java
    
Wed Feb  4 16:56:06 2009
@@ -106,7 +106,7 @@
        changed = false;
        Set<String> validRefs = new HashSet<String>();
        for (CompilationUnit unit : validUnits) {
-        validRefs.add(unit.getDisplayLocation());
+        validRefs.addAll(unit.getFileNameRefs());
        }
        for (Iterator<CompilationUnit> it = validUnits.iterator();  
it.hasNext();) {
          CompilationUnit unit = it.next();

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java        
 
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java        
 
Wed Feb  4 16:56:06 2009
@@ -16,152 +16,89 @@
  package com.google.gwt.dev.javac;

  import com.google.gwt.core.ext.typeinfo.JRealClassType;
-import com.google.gwt.dev.javac.impl.Shared;
+import com.google.gwt.dev.js.ast.JsProgram;

-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ClassFile;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
-import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
-import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import java.util.List;

  /**
   * Encapsulates the state of a single compiled class file.
   */
-public final class CompiledClass {
+public abstract class CompiledClass {

-  private static ClassFile getClassFile(TypeDeclaration typeDecl,
-      String binaryName) {
-    for (ClassFile tryClassFile :  
typeDecl.compilationResult().getClassFiles()) {
-      char[] tryBinaryName = CharOperation.concatWith(
-          tryClassFile.getCompoundName(), '/');
-      if (binaryName.equals(String.valueOf(tryBinaryName))) {
-        return tryClassFile;
-      }
-    }
-    assert false;
-    return null;
-  }
+  /**
+   * @author j...@google.com (Your Name Here)
+   *
+   */
+  public interface JnsiErrorCallback {

-  private static String getPackagePrefix(String packageName) {
-    return packageName.length() > 0 ? packageName + "." : "";
+    boolean reportError(String msg);
    }

-  protected final String binaryName;
-  protected final byte[] bytes;
    protected final CompiledClass enclosingClass;
-  protected final String location;
-  protected final String packageName;
-  protected final String sourceName;
-  protected final CompilationUnit unit;
+  protected CompilationUnit unit;

    // The state below is transient.
-  private NameEnvironmentAnswer nameEnvironmentAnswer;
    private JRealClassType realClassType;
-  // Can be killed after parent is CHECKED.
-  private TypeDeclaration typeDeclaration;

-  CompiledClass(CompilationUnit unit, TypeDeclaration typeDeclaration,
-      CompiledClass enclosingClass) {
+  CompiledClass(CompilationUnit unit, CompiledClass enclosingClass) {
      this.unit = unit;
-    this.typeDeclaration = typeDeclaration;
      this.enclosingClass = enclosingClass;
-    SourceTypeBinding binding = typeDeclaration.binding;
-    this.binaryName =  
CharOperation.charToString(binding.constantPoolName());
-    this.packageName = Shared.getPackageNameFromBinary(binaryName);
-    if (binding instanceof LocalTypeBinding) {
-      // The source name of a local type must be determined from binary.
-      String qualifiedName = binaryName.replace('/', '.');
-      this.sourceName = qualifiedName.replace('$', '.');
-    } else {
-      this.sourceName = getPackagePrefix(packageName)
-          + String.valueOf(binding.qualifiedSourceName());
-    }
-    ClassFile classFile = getClassFile(typeDeclaration, binaryName);
-    this.bytes = classFile.getBytes();
-    this.location = String.valueOf(classFile.fileName());
    }

    /**
     * Returns the binary class name, e.g. {...@code java/util/Map$Entry}.
     */
-  public String getBinaryName() {
-    return binaryName;
-  }
+  public abstract String getBinaryName();

    /**
     * Returns the bytes of the compiled class.
     */
-  public byte[] getBytes() {
-    return bytes;
-  }
+  public abstract byte[] getBytes();

-  public CompiledClass getEnclosingClass() {
+  public final CompiledClass getEnclosingClass() {
      return enclosingClass;
    }
+
+  public abstract List<JsniMethod> getJsniMethods(JsProgram program,
+      JnsiErrorCallback callback);

    /**
     * Returns the enclosing package, e.g. {...@code java.util}.
     */
-  public String getPackageName() {
-    return packageName;
-  }
+  public abstract String getPackageName();

    /**
     * Returns the qualified source name, e.g. {...@code java.util.Map.Entry}.
     */
-  public String getSourceName() {
-    return sourceName;
-  }
+  public abstract String getSourceName();

-  public CompilationUnit getUnit() {
+  public final CompilationUnit getUnit() {
      return unit;
    }

    @Override
    public String toString() {
-    return binaryName;
+    return getBinaryName();
    }

    /**
     * All checking is done, free up internal state.
     */
    void checked() {
-    this.typeDeclaration = null;
    }

-  NameEnvironmentAnswer getNameEnvironmentAnswer() {
-    if (nameEnvironmentAnswer == null) {
-      try {
-        ClassFileReader cfr = new ClassFileReader(bytes,  
location.toCharArray());
-        nameEnvironmentAnswer = new NameEnvironmentAnswer(cfr, null);
-      } catch (ClassFormatException e) {
-        throw new RuntimeException("Unexpectedly unable to parse class  
file", e);
-      }
-    }
-    return nameEnvironmentAnswer;
-  }
-
-  JRealClassType getRealClassType() {
+  final JRealClassType getRealClassType() {
      return realClassType;
    }

-  TypeDeclaration getTypeDeclaration() {
-    return typeDeclaration;
-  }
-
    void invalidate() {
-    nameEnvironmentAnswer = null;
-    typeDeclaration = null;
      if (realClassType != null) {
        realClassType.invalidate();
        realClassType = null;
      }
    }

-  void setRealClassType(JRealClassType realClassType) {
+  final void setRealClassType(JRealClassType realClassType) {
      this.realClassType = realClassType;
    }
  }

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompilationUnit.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompilationUnit.java   
 
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompilationUnit.java   
 
Wed Feb  4 16:56:06 2009
@@ -55,7 +55,7 @@
         * uninstantiable, it won't bother allocating a local name.
         */
        if (typeDecl.binding.constantPoolName() != null) {
-        CompiledClass newClass = new CompiledClass(JdtCompilationUnit.this,
+        CompiledClass newClass = new  
SourceCompiledClass(JdtCompilationUnit.this,
              typeDecl, enclosingClass);
          map.put(typeDecl.binding, newClass);
        }
@@ -66,7 +66,7 @@
      public boolean visit(TypeDeclaration typeDecl, ClassScope scope) {
        CompiledClass enclosingClass =  
map.get(typeDecl.binding.enclosingType());
        assert (enclosingClass != null);
-      CompiledClass newClass = new CompiledClass(JdtCompilationUnit.this,
+      CompiledClass newClass = new  
SourceCompiledClass(JdtCompilationUnit.this,
            typeDecl, enclosingClass);
        map.put(typeDecl.binding, newClass);
        return true;
@@ -75,7 +75,7 @@
      @Override
      public boolean visit(TypeDeclaration typeDecl, CompilationUnitScope  
scope) {
        assert (typeDecl.binding.enclosingType() == null);
-      CompiledClass newClass = new CompiledClass(JdtCompilationUnit.this,
+      CompiledClass newClass = new  
SourceCompiledClass(JdtCompilationUnit.this,
            typeDecl, null);
        map.put(typeDecl.binding, newClass);
        return true;

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
==============================================================================
--- changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java      
 
(original)
+++ changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java      
 
Wed Feb  4 16:56:06 2009
@@ -132,11 +132,20 @@
        char[] binaryNameChars =  
CharOperation.concatWith(compoundTypeName, '/');
        String binaryName = String.valueOf(binaryNameChars);
        CompiledClass compiledClass = binaryTypes.get(binaryName);
-      if (compiledClass != null) {
-        return compiledClass.getNameEnvironmentAnswer();
+      if (compiledClass instanceof SourceCompiledClass) {
+        return ((SourceCompiledClass)  
compiledClass).getNameEnvironmentAnswer();
        }
        if (isPackage(binaryName)) {
          return null;
+      }
+      if (compiledClass != null) {
+        try {
+          // TODO(jat): is this right?
+          ClassFileReader cfr = new  
ClassFileReader(compiledClass.getBytes(),
+              compiledClass.getSourceName().toCharArray());
+          return new NameEnvironmentAnswer(cfr, null);
+        } catch (ClassFormatException e) {
+        }
        }
        try {
          URL resource = getClassLoader().getResource(binaryName + ".class");

Modified:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java
==============================================================================
---  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java        
 
(original)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/JsniCollector.java        
 
Wed Feb  4 16:56:06 2009
@@ -17,6 +17,7 @@

  import com.google.gwt.core.ext.TreeLogger;
  import com.google.gwt.dev.javac.CompilationUnit.State;
+import com.google.gwt.dev.javac.CompiledClass.JnsiErrorCallback;
  import com.google.gwt.dev.js.JsParser;
  import com.google.gwt.dev.js.JsParserException;
  import com.google.gwt.dev.js.JsParserException.SourceDetail;
@@ -29,8 +30,6 @@

  import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.util.Util;

  import java.io.IOException;
  import java.io.StringReader;
@@ -57,7 +56,7 @@
      }
    }

-  private static final class JsniMethodImpl extends JsniMethod {
+  static final class JsniMethodImpl extends JsniMethod {
      private JsFunction func;
      private final int line;
      private final String location;
@@ -66,7 +65,7 @@
      private final String source;
      private final JsProgram program;

-    private JsniMethodImpl(String name, String source, String[] paramNames,
+    JsniMethodImpl(String name, String source, String[] paramNames,
          int line, String location, JsProgram program) {
        this.name = name;
        this.source = source;
@@ -157,40 +156,17 @@
    /**
     * TODO: log real errors, replacing GenerateJavaScriptAST?
     */
-  private static List<JsniMethod> collectJsniMethods(TreeLogger logger,
+  private static List<JsniMethod> collectJsniMethods(final TreeLogger  
logger,
        String loc, String source, CompiledClass compiledClass, JsProgram  
program) {
-    TypeDeclaration typeDecl = compiledClass.getTypeDeclaration();
-    int[] lineEnds =  
typeDecl.compilationResult.getLineSeparatorPositions();
-    List<JsniMethod> jsniMethods = new ArrayList<JsniMethod>();
-    String enclosingType = compiledClass.getBinaryName().replace('/', '.');
-    AbstractMethodDeclaration[] methods = typeDecl.methods;
-    if (methods != null) {
-      for (AbstractMethodDeclaration method : methods) {
-        if (!method.isNative()) {
-          continue;
-        }
-        Interval interval = findJsniSource(source, method);
-        if (interval == null) {
-          String msg = "No JavaScript body found for native method '" +  
method
-              + "' in type '" + compiledClass.getSourceName() + "'";
-          logger.log(TreeLogger.ERROR, msg, null);
-          continue;
-        }
-
-        String js = source.substring(interval.start, interval.end);
-        int startLine = Util.getLineNumber(interval.start, lineEnds, 0,
-            lineEnds.length - 1);
-        String jsniSignature = getJsniSignature(enclosingType, method);
-        String[] paramNames = getParamNames(method);
-
-        jsniMethods.add(new JsniMethodImpl(jsniSignature, js, paramNames,
-            startLine, loc, program));
+    return compiledClass.getJsniMethods(program, new JnsiErrorCallback() {
+      public boolean reportError(String msg) {
+        logger.log(TreeLogger.ERROR, msg, null);
+        return true;
        }
-    }
-    return jsniMethods;
+    });
    }

-  private static Interval findJsniSource(String source,
+  static Interval findJsniSource(String source,
        AbstractMethodDeclaration method) {
      assert (method.isNative());
      int bodyStart = method.bodyStart;
@@ -218,7 +194,7 @@
     * Gets a unique name for this method and its signature (this is used to
     * determine whether one method overrides another).
     */
-  private static String getJsniSignature(String enclosingType,
+  static String getJsniSignature(String enclosingType,
        AbstractMethodDeclaration method) {
      return '@' + enclosingType + "::" + getMemberSignature(method);
    }
@@ -241,7 +217,7 @@
      return sb.toString();
    }

-  private static String[] getParamNames(AbstractMethodDeclaration method) {
+  static String[] getParamNames(AbstractMethodDeclaration method) {
      if (method.arguments != null) {
        String[] paramNames = new String[method.arguments.length];
        for (int i = 0; i < paramNames.length; ++i) {

Added:  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/SourceCompiledClass.java
==============================================================================
--- (empty file)
+++  
changes/jat/ihm/dev/core/src/com/google/gwt/dev/javac/SourceCompiledClass.java  
 
Wed Feb  4 16:56:06 2009
@@ -0,0 +1,194 @@
+/*
+ * 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;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.typeinfo.JRealClassType;
+import com.google.gwt.dev.javac.JsniCollector.Interval;
+import com.google.gwt.dev.javac.JsniCollector.JsniMethodImpl;
+import com.google.gwt.dev.javac.impl.Shared;
+import com.google.gwt.dev.js.ast.JsProgram;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Encapsulates the state of a single compiled class file.
+ */
+public class SourceCompiledClass extends CompiledClass {
+
+  private static ClassFile getClassFile(TypeDeclaration typeDecl,
+      String binaryName) {
+    for (ClassFile tryClassFile :  
typeDecl.compilationResult().getClassFiles()) {
+      char[] tryBinaryName = CharOperation.concatWith(
+          tryClassFile.getCompoundName(), '/');
+      if (binaryName.equals(String.valueOf(tryBinaryName))) {
+        return tryClassFile;
+      }
+    }
+    assert false;
+    return null;
+  }
+
+  private static String getPackagePrefix(String packageName) {
+    return packageName.length() > 0 ? packageName + "." : "";
+  }
+
+  protected final byte[] bytes;
+  protected final String binaryName;
+  protected final String location;
+  protected final String packageName;
+  protected final String sourceName;
+
+  // The state below is transient.
+  private NameEnvironmentAnswer nameEnvironmentAnswer;
+  private JRealClassType realClassType;
+  // Can be killed after parent is CHECKED.
+  private TypeDeclaration typeDeclaration;
+
+  SourceCompiledClass(CompilationUnit unit, TypeDeclaration  
typeDeclaration,
+      CompiledClass enclosingClass) {
+    super(unit, enclosingClass);
+    this.typeDeclaration = typeDeclaration;
+    SourceTypeBinding binding = typeDeclaration.binding;
+    this.binaryName =  
CharOperation.charToString(binding.constantPoolName());
+    this.packageName = Shared.getPackageNameFromBinary(binaryName);
+    if (binding instanceof LocalTypeBinding) {
+      // The source name of a local type must be determined from binary.
+      String qualifiedName = binaryName.replace('/', '.');
+      this.sourceName = qualifiedName.replace('$', '.');
+    } else {
+      this.sourceName = getPackagePrefix(packageName)
+          + String.valueOf(binding.qualifiedSourceName());
+    }
+    ClassFile classFile = getClassFile(typeDeclaration, binaryName);
+    this.bytes = classFile.getBytes();
+    this.location = String.valueOf(classFile.fileName());
+  }
+
+  /**
+   * Returns the binary class name, e.g. {...@code java/util/Map$Entry}.
+   */
+  @Override
+  public String getBinaryName() {
+    return binaryName;
+  }
+
+  /**
+   * Returns the bytes of the compiled class.
+   */
+  @Override
+  public byte[] getBytes() {
+    return bytes;
+  }
+
+  /**
+   * Returns the enclosing package, e.g. {...@code java.util}.
+   */
+  @Override
+  public String getPackageName() {
+    return packageName;
+  }
+
+  /**
+   * Returns the qualified source name, e.g. {...@code java.util.Map.Entry}.
+   */
+  @Override
+  public String getSourceName() {
+    return sourceName;
+  }
+
+  /**
+   * All checking is done, free up internal state.
+   */
+  @Override
+  void checked() {
+    this.typeDeclaration = null;
+  }
+
+  NameEnvironmentAnswer getNameEnvironmentAnswer() {
+    if (nameEnvironmentAnswer == null) {
+      try {
+        ClassFileReader cfr = new ClassFileReader(bytes,  
location.toCharArray());
+        nameEnvironmentAnswer = new NameEnvironmentAnswer(cfr, null);
+      } catch (ClassFormatException e) {
+        throw new RuntimeException("Unexpectedly unable to parse class  
file", e);
+      }
+    }
+    return nameEnvironmentAnswer;
+  }
+
+  TypeDeclaration getTypeDeclaration() {
+    return typeDeclaration;
+  }
+
+  @Override
+  void invalidate() {
+    nameEnvironmentAnswer = null;
+    typeDeclaration = null;
+    super.invalidate();
+  }
+
+  @Override
+  public List<JsniMethod> getJsniMethods(JsProgram program,
+      JnsiErrorCallback callback) {
+    TypeDeclaration typeDecl = typeDeclaration;
+    int[] lineEnds =  
typeDecl.compilationResult.getLineSeparatorPositions();
+    List<JsniMethod> jsniMethods = new ArrayList<JsniMethod>();
+    String enclosingType = getBinaryName().replace('/', '.');
+    String source = unit.getSource();
+    AbstractMethodDeclaration[] methods = typeDecl.methods;
+    if (methods != null) {
+      for (AbstractMethodDeclaration method : methods) {
+        if (!method.isNative()) {
+          continue;
+        }
+        Interval interval = JsniCollector.findJsniSource(source, method);
+        if (interval == null) {
+          String msg = "No JavaScript body found for native method '" +  
method
+              + "' in type '" + getSourceName() + "'";
+          if (callback.reportError(msg)) {
+            continue;
+          } else {
+            break;
+          }
+        }
+
+        String js = source.substring(interval.start, interval.end);
+        int startLine = Util.getLineNumber(interval.start, lineEnds, 0,
+            lineEnds.length - 1);
+        String jsniSignature =  
JsniCollector.getJsniSignature(enclosingType,
+            method);
+        String[] paramNames = JsniCollector.getParamNames(method);
+
+        jsniMethods.add(new JsniCollector.JsniMethodImpl(jsniSignature, js,
+            paramNames, startLine, unit.getDisplayLocation(), program));
+      }
+    }
+    return jsniMethods;
+  }
+}

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   
 
Wed Feb  4 16:56:06 2009
@@ -389,12 +389,16 @@
        Set<CompiledClass> compiledClasses = unit.getCompiledClasses();
        for (CompiledClass compiledClass : compiledClasses) {
          if (unresolvedTypes.remove(compiledClass.getRealClassType())) {
-          TypeDeclaration typeDeclaration =  
compiledClass.getTypeDeclaration();
-          if (!resolveTypeDeclaration(cudLogger, unit.getSource(),
-              typeDeclaration)) {
-            logger.log(TreeLogger.WARN,
-                "Unexpectedly unable to fully resolve type "
-                    + compiledClass.getSourceName());
+          // TODO(jat): do we need to do anything here for binary classes?
+          if (compiledClass instanceof SourceCompiledClass) {
+            SourceCompiledClass srcClass = (SourceCompiledClass)  
compiledClass;
+            TypeDeclaration typeDeclaration =  
srcClass.getTypeDeclaration();
+            if (!resolveTypeDeclaration(cudLogger, unit.getSource(),
+                typeDeclaration)) {
+              logger.log(TreeLogger.WARN,
+                  "Unexpectedly unable to fully resolve type "
+                  + compiledClass.getSourceName());
+            }
            }
          }
        }
@@ -475,8 +479,12 @@
        realClassType = createType(compiledClass, enclosingType);
        if (realClassType != null) {
          unresolvedTypes.add(realClassType);
-        sourceMapper.put(compiledClass.getTypeDeclaration().binding,
-            realClassType);
+        // TODO(jat): anything here for binary classes?
+        if (compiledClass instanceof SourceCompiledClass) {
+          SourceCompiledClass srcClass = (SourceCompiledClass)  
compiledClass;
+          sourceMapper.put(srcClass.getTypeDeclaration().binding,
+              realClassType);
+        }
          compiledClass.setRealClassType(realClassType);
        }
      }
@@ -489,6 +497,29 @@
     * TypeParameters are mapped into JTypeParameters.
     */
    private JRealClassType createType(CompiledClass compiledClass,
+      JRealClassType enclosingType) {
+    if (compiledClass instanceof SourceCompiledClass) {
+      return createTypeFromSource((SourceCompiledClass) compiledClass,
+          enclosingType);
+    } else if (compiledClass instanceof BinaryCompiledClass) {
+      return createTypeFromClass((BinaryCompiledClass) compiledClass,
+          enclosingType);
+    }
+    return null;
+  }
+
+  private JRealClassType createTypeFromClass(BinaryCompiledClass  
compiledClass,
+      JRealClassType enclosingType) {
+    // TODO(jat): implement
+    return null;
+  }
+
+  /**
+   * Maps a TypeDeclaration into a JRealClassType. If the TypeDeclaration  
has
+   * TypeParameters (i.e, it is a generic type or method), then the
+   * TypeParameters are mapped into JTypeParameters.
+   */
+  private JRealClassType createTypeFromSource(SourceCompiledClass  
compiledClass,
        JRealClassType enclosingType) {
      TypeDeclaration typeDecl = compiledClass.getTypeDeclaration();
      SourceTypeBinding binding = typeDecl.binding;

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

Reply via email to