
1 // 2 // Copyright (c) 2006, Brian Frank and Andy Frank 3 // Licensed under the Academic Free License version 3.0 4 // 5 // History: 6 // 26 Dec 05 Brian Frank Creation 7 // 19 Aug 06 Brian Frank Ported from Java to Fan 8 // 9 10 ** 11 ** FPrinter is used to pretty print fcode 12 ** 13 class FPrinter : FConst 14 { 15 16 ////////////////////////////////////////////////////////////////////////// 17 // Constructor 18 ////////////////////////////////////////////////////////////////////////// 19 20 new make(FPod pod, OutStream out := Sys.out) 21 { 22 this.pod = pod 23 this.out = out 24 } 25 26 ////////////////////////////////////////////////////////////////////////// 27 // Dump 28 ////////////////////////////////////////////////////////////////////////// 29 30 Void all() 31 { 32 tables 33 ftypes 34 out.flush 35 } 36 37 ////////////////////////////////////////////////////////////////////////// 38 // Const Tables 39 ////////////////////////////////////////////////////////////////////////// 40 41 Void tables() 42 { 43 printLine("##### Tables #####"); 44 table("--- names ---", pod.names) 45 table("--- typeRefs ---", pod.typeRefs) 46 table("--- fieldRefs ---", pod.fieldRefs) 47 table("--- methodRefs ---", pod.methodRefs) 48 table("--- ints ---", pod.ints) 49 table("--- floats ---", pod.floats) 50 table("--- strs ---", pod.strs) 51 table("--- durations ---", pod.durations) 52 table("--- uris ---", pod.uris) 53 out.flush 54 } 55 56 Void table(Str title, FTable table) 57 { 58 printLine(title) 59 table.table.each |Obj obj, Int index| 60 { 61 m := obj.type.method("format", false) 62 s := m != null ? m.call([obj, pod]) : obj.toStr 63 printLine(" [$index] $s") 64 } 65 } 66 67 ////////////////////////////////////////////////////////////////////////// 68 // Types 69 ////////////////////////////////////////////////////////////////////////// 70 71 Void ftypes() 72 { 73 printLine("##### Types #####") 74 pod.ftypes.each |FType t| { ftype(t) } 75 out.flush 76 } 77 78 Void ftype(FType t) 79 { 80 printLine("--" + typeRef(t.self) + " : " + typeRef(t.fbase) + "--") 81 if (!t.fmixins.isEmpty) 82 { 83 printLine(" mixin " + t.fmixins.join(", ") |Int m->Str| { return typeRef(m) }); 84 } 85 attrs(t.fattrs) 86 printLine 87 t.ffields.each |FField f| { field(f) } 88 t.fmethods.each |FMethod m| { method(m) } 89 out.flush 90 } 91 92 Void slot(FSlot s) 93 { 94 if (s is FField) 95 field((FField)s) 96 else 97 method((FMethod)s) 98 out.flush 99 } 100 101 Void field(FField f) 102 { 103 printLine(" " + name(f.nameIndex) + " -> " + typeRef(f.typeRef) + " [" + flags(f.flags) + "]") 104 attrs(f.fattrs) 105 printLine 106 } 107 108 Void method(FMethod m) 109 { 110 print(" " + name(m.nameIndex) + " (") 111 print(m.fparams.join(", ") |FMethodVar p->Str| { return typeRef(p.typeRef) + " " + name(p.nameIndex) }) 112 print(") -> " + typeRef(m.ret)) 113 if (m.ret != m.inheritedRet) print(" {" + typeRef(m.inheritedRet) + "}") 114 printLine(" [" + flags(m.flags) + "]") 115 m.vars.each |FMethodVar v, Int reg| 116 { 117 role := v.isParam ? "Param" : "Local" 118 if (m.flags & FConst.Static == 0) reg++ 119 printLine(" [" + role + " " + reg + "] " + pod.n(v.nameIndex) + " -> " + typeRef(v.typeRef)) 120 if (v.def != null) code(v.def) 121 } 122 if (m.code != null) 123 { 124 printLine(" [Code]") 125 code(m.code) 126 } 127 attrs(m.fattrs) 128 printLine 129 } 130 131 Void code(Buf code) 132 { 133 if (!showCode) return; 134 out.flush 135 codePrinter := FCodePrinter.make(pod, out) 136 codePrinter.showIndex = showIndex 137 codePrinter.code(code) 138 } 139 140 ////////////////////////////////////////////////////////////////////////// 141 // Attributes 142 ////////////////////////////////////////////////////////////////////////// 143 144 Void attrs(FAttr[] attrs) 145 { 146 if (attrs == null) return 147 attrs.each |FAttr a| { attr(a) } 148 } 149 150 Void attr(FAttr attr) 151 { 152 name := name(attr.name) 153 if (name == LineNumbersAttr && !showLines) return 154 printLine(" [$name] size=$attr.data.size") 155 if (name == SourceFileAttr) sourceFileAttr(attr) 156 if (name == ErrTableAttr) errTableAttr(attr) 157 if (name == LineNumberAttr) lineNumberAttr(attr) 158 if (name == LineNumbersAttr) lineNumbersAttr(attr) 159 if (name == FacetsAttr) facetsAttr(attr) 160 } 161 162 Void sourceFileAttr(FAttr attr) 163 { 164 printLine(" $attr.utf") 165 } 166 167 Void lineNumberAttr(FAttr attr) 168 { 169 printLine(" $attr.u2") 170 } 171 172 Void facetsAttr(FAttr attr) 173 { 174 buf := attr.data 175 buf.seek(0) 176 buf.readU2.times |,| 177 { 178 name := name(buf.readU2) 179 val := buf.readUtf 180 printLine(" $name=$val") 181 } 182 } 183 184 Void errTableAttr(FAttr attr) 185 { 186 buf := attr.data 187 buf.seek(0) 188 buf.readU2.times |,| 189 { 190 start := buf.readU2 191 end := buf.readU2 192 handler := buf.readU2 193 tr := buf.readU2 194 printLine(" $start to $end -> $handler " + typeRef(tr)) 195 } 196 } 197 198 Void lineNumbersAttr(FAttr attr) 199 { 200 buf := attr.data 201 buf.seek(0) 202 buf.readU2.times |,| 203 { 204 pc := buf.readU2 205 line := buf.readU2 206 printLine(" $pc: $line") 207 } 208 } 209 210 ////////////////////////////////////////////////////////////////////////// 211 // Dump Utils 212 ////////////////////////////////////////////////////////////////////////// 213 214 Str typeRef(Int i) 215 { 216 if (i == 65535) return "null" 217 return pod.typeRefStr(i) + index(i) 218 } 219 220 Str name(Int i) 221 { 222 return pod.n(i) + index(i) 223 } 224 225 Str flags(Int flags) 226 { 227 s := StrBuf.make 228 if (flags & FConst.Abstract != 0) s.add("abstract ") 229 if (flags & FConst.Const != 0) s.add("const ") 230 if (flags & FConst.Ctor != 0) s.add("ctor ") 231 if (flags & FConst.Enum != 0) s.add("enum ") 232 if (flags & FConst.Final != 0) s.add("final ") 233 if (flags & FConst.Getter != 0) s.add("getter ") 234 if (flags & FConst.Internal != 0) s.add("internal ") 235 if (flags & FConst.Mixin != 0) s.add("mixin ") 236 if (flags & FConst.Native != 0) s.add("native ") 237 if (flags & FConst.Override != 0) s.add("override ") 238 if (flags & FConst.Private != 0) s.add("private ") 239 if (flags & FConst.Protected != 0) s.add("protected ") 240 if (flags & FConst.Public != 0) s.add("public ") 241 if (flags & FConst.Setter != 0) s.add("setter ") 242 if (flags & FConst.Static != 0) s.add("static ") 243 if (flags & FConst.Storage != 0) s.add("storage ") 244 if (flags & FConst.Synthetic != 0) s.add("synthetic ") 245 if (flags & FConst.Virtual != 0) s.add("virtual ") 246 return s.toStr[0..-2] 247 } 248 249 Str index(Int index) 250 { 251 if (showIndex) return "[" + index + "]" 252 return "" 253 } 254 255 ////////////////////////////////////////////////////////////////////////// 256 // Print 257 ////////////////////////////////////////////////////////////////////////// 258 259 FPrinter print(Obj obj) { out.print(obj); return this } 260 FPrinter printLine(Obj obj := "") { out.printLine(obj); return this } 261 262 ////////////////////////////////////////////////////////////////////////// 263 // Fields 264 ////////////////////////////////////////////////////////////////////////// 265 266 FPod pod 267 OutStream out 268 Bool showIndex := false 269 Bool showCode := true 270 Bool showLines := false 271 272 }