1 2 package polyglot.util.typedump; 3 4 import polyglot.util.*; 5 import polyglot.types.*; 6 import java.lang.reflect.Field ; 7 import java.lang.reflect.Modifier ; 8 import java.util.Date ; 9 import java.util.Map ; 10 import java.util.Set ; 11 12 class TypeDumper { 13 static Set dontExpand; 14 static { 15 Object [] primitiveLike = { 16 Void .class, 17 Boolean .class, 18 Short .class, 19 Integer .class, 20 Long .class, 21 Float .class, 22 Double .class, 23 Class .class, 24 String .class, 25 }; 26 dontExpand = 27 new java.util.HashSet (java.util.Arrays.asList(primitiveLike)); 28 } 29 30 Type theType; 31 String rawName; 32 String compilerVersion; 33 Date timestamp; 34 TypeDumper(String rawName, Type t, String compilerVersion, 35 Long timestamp) { 36 theType = t; 37 this.rawName = rawName; 38 this.compilerVersion = compilerVersion; 39 this.timestamp = new Date (timestamp.longValue()); 40 } 41 42 public static TypeDumper load(String name, TypeSystem ts) 43 throws ClassNotFoundException , NoSuchFieldException , 44 java.io.IOException , SecurityException 45 { 46 Class c = Class.forName(name); 47 try { 48 Field jlcVersion = c.getDeclaredField("jlc$CompilerVersion"); 49 Field jlcTimestamp = c.getDeclaredField("jlc$SourceLastModified"); 50 Field jlcType = c.getDeclaredField("jlc$ClassType"); 51 String t = (String )jlcType.get(null); 52 TypeEncoder te = new TypeEncoder(ts); 53 return new TypeDumper(name, 54 te.decode(t), 55 (String )jlcVersion.get(null), 56 (Long )jlcTimestamp.get(null)); 57 } catch (IllegalAccessException exn) { 58 throw new SecurityException ("illegal access: "+exn.getMessage()); 59 } 60 } 61 62 public void dump(CodeWriter w) { 63 Map cache = new java.util.HashMap (); 64 cache.put(theType, theType); 65 w.write("Type "+rawName+ " {"); 66 w.allowBreak(2); 67 w.begin(0); 68 w.write("Compiled with polyglot version "+compilerVersion+". "); 69 w.allowBreak(0); 70 w.write("Last modified: "+timestamp.toString()+". "); 71 w.allowBreak(0); 72 w.write(theType.toString()); 73 w.allowBreak(4); 74 w.write("<"+ 75 theType.getClass().toString()+">"); 76 w.allowBreak(0); 77 dumpObject(w, theType, cache); 78 w.allowBreak(0); 79 w.end(); 80 w.allowBreak(0); 81 w.write("}"); 82 w.newline(0); 83 } 84 85 protected void dumpObject(CodeWriter w, Object obj, Map cache) { 86 w.write(" fields {"); 87 w.allowBreak(2); 88 w.begin(0); 89 try { 90 Field [] declaredFields = 91 obj.getClass().getDeclaredFields(); 92 java.lang.reflect.AccessibleObject.setAccessible(declaredFields, 93 true); 94 for (int i = 0; i < declaredFields.length; i++) { 95 if (Modifier.isStatic(declaredFields[i].getModifiers())) 96 continue; 97 w.begin(4); 98 w.write(declaredFields[i].getName()+": "); 99 w.allowBreak(0); 100 try { 101 Object o = declaredFields[i].get(obj); 102 if (o != null) { 103 Class rtType = o.getClass(); 104 w.write("<"+rtType.toString()+">:"); 105 w.allowBreak(0); 106 w.write(o.toString()); 107 w.allowBreak(4); 108 if (!Object .class.equals(rtType) && 109 !dontDump(rtType) && 110 !rtType.isArray() && 111 !(cache.containsKey(o) && 112 cache.get(o) == o)) { 113 cache.put(o, o); 114 dumpObject(w, o, cache); 115 } 116 } else { 117 w.write("null"); 118 } 119 } catch (IllegalAccessException exn) { 120 w.write("##["+exn.getMessage()+"]"); 121 } 122 w.end(); 123 w.allowBreak(0); 124 } 125 } catch (SecurityException exn) { 126 } finally { 127 w.end(); 128 w.allowBreak(0); 129 w.write("}"); 130 } 131 } 132 133 static boolean dontDump(Class c) { 134 return dontExpand.contains(c); 135 } 136 137 } 138 139 | Popular Tags |