langtools/test/tools/javac/lib/DPrinter.java
changeset 25443 9187d77f2c64
parent 25291 0fd42e6dfdf6
child 27857 7e913a535736
--- a/langtools/test/tools/javac/lib/DPrinter.java	Tue Jul 08 18:26:34 2014 -0700
+++ b/langtools/test/tools/javac/lib/DPrinter.java	Wed Jul 09 16:32:05 2014 +0200
@@ -31,6 +31,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -337,6 +338,8 @@
             printList(label, (List) item);
         } else if (item instanceof Name) {
             printName(label, (Name) item);
+        } else if (item instanceof Scope) {
+            printScope(label, (Scope) item);
         } else {
             printString(label, String.valueOf(item));
         }
@@ -356,7 +359,7 @@
                     out.print(label);
                     out.print(": [");
                     String sep = "";
-                    for (Symbol sym: scope.getElements()) {
+                    for (Symbol sym: scope.getSymbols()) {
                         out.print(sep);
                         out.print(sym.name);
                         sep = ",";
@@ -370,19 +373,7 @@
                     out.println(label);
 
                     indent(+1);
-                    printImplClass(scope, Scope.class);
-                    printSymbol("owner", scope.owner, Details.SUMMARY);
-                    printScope("next", scope.next, Details.SUMMARY);
-                    printObject("shared", getField(scope, Scope.class, "shared"), Details.SUMMARY);
-                    if (scope instanceof CompoundScope) {
-                        printObject("subScopes",
-                                getField(scope, CompoundScope.class, "subScopes"),
-                                Details.FULL);
-                    } else {
-                        for (Symbol sym : scope.getElements()) {
-                            printSymbol(sym.name.toString(), sym, Details.SUMMARY);
-                        }
-                    }
+                    printFullScopeImpl(scope);
                     indent(-1);
                     break;
                 }
@@ -390,6 +381,72 @@
         }
     }
 
+    void printFullScopeImpl(Scope scope) {
+        indent();
+        out.println(scope.getClass().getName());
+        printSymbol("owner", scope.owner, Details.SUMMARY);
+        if (SCOPE_IMPL_CLASS.equals(scope.getClass().getName())) {
+            printScope("next", (Scope) getField(scope, scope.getClass(), "next"), Details.SUMMARY);
+            printObject("shared", getField(scope, scope.getClass(), "shared"), Details.SUMMARY);
+            Object[] table = (Object[]) getField(scope, scope.getClass(), "table");
+            for (int i = 0; i < table.length; i++) {
+                if (i > 0)
+                    out.print(", ");
+                else
+                    indent();
+                out.print(i + ":" + entryToString(table[i], table, false));
+            }
+            out.println();
+        } else if (FILTER_SCOPE_CLASS.equals(scope.getClass().getName())) {
+            printScope("delegate",
+                    (Scope) getField(scope, scope.getClass(), "delegate"), Details.FULL);
+        } else if (scope instanceof CompoundScope) {
+            printList("delegates", (List<?>) getField(scope, CompoundScope.class, "subScopes"));
+        } else {
+            for (Symbol sym : scope.getSymbols()) {
+                printSymbol(sym.name.toString(), sym, Details.SUMMARY);
+            }
+        }
+    }
+        //where:
+        static final String SCOPE_IMPL_CLASS = "com.sun.tools.javac.code.Scope$ScopeImpl";
+        static final String FILTER_SCOPE_CLASS = "com.sun.tools.javac.code.Scope$FilterImportScope";
+
+    /**
+     * Create a string showing the contents of an entry, using the table
+     * to help identify cross-references to other entries in the table.
+     * @param e the entry to be shown
+     * @param table the table containing the other entries
+     */
+    String entryToString(Object e, Object[] table, boolean ref) {
+        if (e == null)
+            return "null";
+        Symbol sym = (Symbol) getField(e, e.getClass(), "sym");
+        if (sym == null)
+            return "sent"; // sentinel
+        if (ref) {
+            int index = indexOf(table, e);
+            if (index != -1)
+                return String.valueOf(index);
+        }
+        Scope scope = (Scope) getField(e, e.getClass(), "scope");
+        return "(" + sym.name + ":" + sym
+                + ",shdw:" + entryToString(callMethod(e, e.getClass(), "next"), table, true)
+                + ",sibl:" + entryToString(getField(e, e.getClass(), "sibling"), table, true)
+                + ((sym.owner != scope.owner)
+                    ? (",BOGUS[" + sym.owner + "," + scope.owner + "]")
+                    : "")
+                + ")";
+    }
+
+    <T> int indexOf(T[] array, T item) {
+        for (int i = 0; i < array.length; i++) {
+            if (array[i] == item)
+                return i;
+        }
+        return -1;
+    }
+
     public void printSource(String label, JCTree tree) {
         printString(label, Pretty.toSimpleString(tree, maxSrcLength));
     }
@@ -552,6 +609,23 @@
         }
     }
 
+    protected Object callMethod(Object o, Class<?> clazz, String name) {
+        try {
+            Method m = clazz.getDeclaredMethod(name);
+            boolean prev = m.isAccessible();
+            m.setAccessible(true);
+            try {
+                return m.invoke(o);
+            } finally {
+                m.setAccessible(prev);
+            }
+        } catch (ReflectiveOperationException e) {
+            return e;
+        } catch (SecurityException e) {
+            return e;
+        }
+    }
+
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="JCTree visitor methods">