This patch makes gjavah have the same behaviour as OpenJDK's javah
in producing header files for any inner classes found in the classes
being parsed.

ChangeLog:

2011-09-09  Andrew John Hughes  <ahug...@redhat.com>

        PR classpath/45526: Produce header files for
        any inner classes found.
        * tools/gnu/classpath/tools/javah/Main.java:
        (parsed): Set of class names that have been parsed.
        (writeHeader(Map,Printer)): Take a general Map
        rather than a specific HashMap.
        (parseClasses(Iterator<Object>)): Factor out
        the parsing of class files into a separate
        method so it can be called recursively for
        inner classes.
        (getClass(String)): Remove redundant cast.

-- 
Andrew :)

Free Java Software Engineer
Red Hat, Inc. (http://www.redhat.com)

Support Free Java!
Contribute to GNU Classpath and IcedTea
http://www.gnu.org/software/classpath
http://icedtea.classpath.org
PGP Key: F5862A37 (https://keys.indymedia.org/)
Fingerprint = EA30 D855 D50F 90CD F54D  0698 0713 C3ED F586 2A37
Index: tools/gnu/classpath/tools/javah/Main.java
===================================================================
RCS file: 
/sources/classpath/classpath/tools/gnu/classpath/tools/javah/Main.java,v
retrieving revision 1.13
diff -u -u -r1.13 Main.java
--- tools/gnu/classpath/tools/javah/Main.java   3 Jun 2010 19:14:37 -0000       
1.13
+++ tools/gnu/classpath/tools/javah/Main.java   9 Sep 2011 04:59:31 -0000
@@ -58,9 +58,11 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 import java.util.Map;
 
 import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.tree.InnerClassNode;
 
 public class Main
 {
@@ -101,6 +103,9 @@
   // Map class names to lists of Text objects.
   HashMap<String,ArrayList<Text>> textMap = new 
HashMap<String,ArrayList<Text>>();
 
+  // Set of classes which have been parsed
+  Set<String> parsed = new HashSet<String>();
+
   void readCommandFile(String textFileName) throws OptionException
   {
     FileInputStream fis;
@@ -317,7 +322,7 @@
     return result;
   }
 
-  private void writeHeaders(HashMap<File,ClassWrapper> klasses, Printer 
printer)
+  private void writeHeaders(Map<File,ClassWrapper> klasses, Printer printer)
       throws IOException
   {
     Iterator<Map.Entry<File,ClassWrapper>> i = klasses.entrySet().iterator();
@@ -332,6 +337,53 @@
       }
   }
 
+  private Map<File,ClassWrapper> parseClasses(Iterator<Object> inputs)
+    throws IOException
+  {
+    Map<File,ClassWrapper> results = new HashMap<File,ClassWrapper>();
+    while (inputs.hasNext())
+      {
+        // Let user specify either kind of class name or a
+        // file name.
+        Object item = inputs.next();
+        ClassWrapper klass;
+        File filename;
+        if (item instanceof File)
+          {
+            // Load class from file.
+            if (verbose)
+              System.err.println("[reading file " + item + "]");
+            klass = getClass((File) item);
+            filename = new File(klass.name);
+          }
+        else
+          {
+            // Load class given the class name.
+            String className = ((String) item).replace('.', '/');
+            if (verbose)
+              System.err.println("[reading class " + className + "]");
+            // Use the name the user specified, even if it is
+            // different from the ultimate class name.
+            filename = new File(className);
+            klass = getClass(className);
+          }
+        results.put(filename, klass);
+        parsed.add(item.toString());
+
+        // Check to see if there are inner classes to also parse
+        Iterator<?> innerClasses = klass.innerClasses.iterator();
+        HashSet<Object> innerNames = new HashSet<Object>();
+        while (innerClasses.hasNext())
+          {
+            String innerName = ((InnerClassNode) innerClasses.next()).name;
+            if (!parsed.contains(innerName))
+              innerNames.add(innerName);
+          }
+        results.putAll(parseClasses(innerNames.iterator()));
+      }
+    return results;
+  }
+
   protected void postParse(String[] names)
   {
     // Nothing here.
@@ -385,40 +437,12 @@
           }
       }
 
-    Iterator<Object> i = klasses.iterator();
-    HashMap<File,ClassWrapper> results = new HashMap<File,ClassWrapper>();
-    while (i.hasNext())
-      {
-        // Let user specify either kind of class name or a
-        // file name.
-        Object item = i.next();
-        ClassWrapper klass;
-        File filename;
-        if (item instanceof File)
-          {
-            // Load class from file.
-            if (verbose)
-              System.err.println("[reading file " + item + "]");
-            klass = getClass((File) item);
-            filename = new File(klass.name);
-          }
-        else
-          {
-            // Load class given the class name.
-            String className = ((String) item).replace('.', '/');
-            if (verbose)
-              System.err.println("[reading class " + className + "]");
-            // Use the name the user specified, even if it is
-            // different from the ultimate class name.
-            filename = new File(className);
-            klass = getClass(className);
-          }
-        results.put(filename, klass);
-      }
+    Map<File, ClassWrapper> results = parseClasses(klasses.iterator());
 
     writeHeaders(results, printer);
   }
 
+
   public ArrayList<Text> getClassTextList(String name)
   {
     return textMap.get(name);
@@ -457,7 +481,7 @@
         ClassWrapper result = readClass(is);
         classMap.put(name, result);
       }
-    return (ClassWrapper) classMap.get(name);
+    return classMap.get(name);
   }
 
   public static void main(String[] args) throws IOException

Reply via email to