001 package org.extendj.ast; 002 003 import java.util.HashSet; 004 import java.io.File; 005 import java.util.Set; 006 import java.util.Collections; 007 import java.util.Collection; 008 import java.util.ArrayList; 009 import beaver.*; 010 import java.util.*; 011 import java.io.ByteArrayOutputStream; 012 import java.io.PrintStream; 013 import java.lang.reflect.InvocationTargetException; 014 import java.lang.reflect.Method; 015 import org.jastadd.util.*; 016 import java.util.zip.*; 017 import java.io.*; 018 import org.jastadd.util.PrettyPrintable; 019 import org.jastadd.util.PrettyPrinter; 020 import java.io.FileNotFoundException; 021 import java.io.BufferedInputStream; 022 import java.io.DataInputStream; 023 /** 024 * @ast class 025 * @aspect ClassfileParser 026 * @declaredat /home/jesper/git/extendj/java4/frontend/ClassfileParser.jrag:34 027 */ 028 public abstract class AbstractClassfileParser extends java.lang.Object { 029 030 031 public static class ClassfileFormatError extends Error { 032 public ClassfileFormatError(String message) { 033 super(message); 034 } 035 } 036 037 038 039 public static final boolean VERBOSE = false; 040 041 042 043 protected static final int CONSTANT_Class = 7; 044 045 046 protected static final int CONSTANT_FieldRef = 9; 047 048 049 protected static final int CONSTANT_MethodRef = 10; 050 051 052 protected static final int CONSTANT_InterfaceMethodRef = 11; 053 054 055 protected static final int CONSTANT_String = 8; 056 057 058 protected static final int CONSTANT_Integer = 3; 059 060 061 protected static final int CONSTANT_Float = 4; 062 063 064 protected static final int CONSTANT_Long = 5; 065 066 067 protected static final int CONSTANT_Double = 6; 068 069 070 protected static final int CONSTANT_NameAndType = 12; 071 072 073 protected static final int CONSTANT_Utf8 = 1; 074 075 076 077 private DataInputStream is; 078 079 080 081 public final String name; 082 083 084 public CONSTANT_Class_Info classInfo; 085 086 087 public CONSTANT_Info[] constantPool = null; 088 089 090 091 // For Java 5 and later. 092 public boolean isInnerClass = false; 093 094 095 096 public AbstractClassfileParser(InputStream in, String name) { 097 this.is = new DataInputStream(new BufferedInputStream(in)); 098 this.name = name; 099 } 100 101 102 103 public abstract boolean outerClassNameEquals(String name); 104 105 106 107 public final int next() throws IOException { 108 return is.read(); 109 } 110 111 112 113 public final int u1() throws IOException { 114 return is.readUnsignedByte(); 115 } 116 117 118 119 public final int u2() throws IOException { 120 return is.readUnsignedShort(); 121 } 122 123 124 125 public final int u4() throws IOException { 126 return is.readInt(); 127 } 128 129 130 131 public final int readInt() throws IOException { 132 return is.readInt(); 133 } 134 135 136 137 public final float readFloat() throws IOException { 138 return is.readFloat(); 139 } 140 141 142 143 public final long readLong() throws IOException { 144 return is.readLong(); 145 } 146 147 148 149 public final double readDouble() throws IOException { 150 return is.readDouble(); 151 } 152 153 154 155 public final String readUTF() throws IOException { 156 return is.readUTF(); 157 } 158 159 160 161 public final void skip(int length) throws IOException { 162 while (length > 0) { 163 length -= is.skip(length); 164 } 165 } 166 167 168 169 public void error(String msg) throws ClassfileFormatError { 170 throw new ClassfileFormatError(msg); 171 } 172 173 174 175 public final void print(String s) { 176 //System.out.print(s); 177 } 178 179 180 181 public final void println(String s) { 182 print(s + "\n"); 183 } 184 185 186 187 public final void println() { 188 print("\n"); 189 } 190 191 192 193 public final void parseMagic() throws IOException { 194 if (next() != 0xca || next() != 0xfe || next() != 0xba || next() != 0xbe) { 195 error("magic error"); 196 } 197 } 198 199 200 201 public final int parseMinor() throws IOException { 202 return u2(); 203 } 204 205 206 207 public final int parseMajor() throws IOException { 208 return u2(); 209 } 210 211 212 213 public final String parseThisClass() throws IOException { 214 int index = u2(); 215 CONSTANT_Class_Info info = (CONSTANT_Class_Info) constantPool[index]; 216 classInfo = info; 217 return info.simpleName(); 218 } 219 220 221 222 public final Access parseSuperClass() throws IOException { 223 int index = u2(); 224 if (index == 0) { 225 return null; 226 } 227 CONSTANT_Class_Info info = (CONSTANT_Class_Info) constantPool[index]; 228 return info.access(); 229 } 230 231 232 233 public final List parseInterfaces(List list) throws IOException { 234 int count = u2(); 235 for (int i = 0; i < count; i++) { 236 CONSTANT_Class_Info info = (CONSTANT_Class_Info) constantPool[u2()]; 237 list.add(info.access()); 238 } 239 return list; 240 } 241 242 243 244 public void parseFields(TypeDecl typeDecl) throws IOException { 245 int count = u2(); 246 if (VERBOSE) { 247 println("Fields (" + count + "):"); 248 } 249 for (int i = 0; i < count; i++) { 250 if (VERBOSE) { 251 print(" Field nbr " + i + " "); 252 } 253 FieldInfo fieldInfo = new FieldInfo(this); 254 if (!fieldInfo.isSynthetic()) { 255 typeDecl.addBodyDecl(fieldInfo.bodyDecl()); 256 } 257 } 258 } 259 260 261 262 public static Modifiers modifiers(int flags) { 263 Modifiers m = new Modifiers(); 264 if ((flags & 0x0001) != 0) { 265 m.addModifier(new Modifier("public")); 266 } 267 if ((flags & 0x0002) != 0) { 268 m.addModifier(new Modifier("private")); 269 } 270 if ((flags & 0x0004) != 0) { 271 m.addModifier(new Modifier("protected")); 272 } 273 if ((flags & 0x0008) != 0) { 274 m.addModifier(new Modifier("static")); 275 } 276 if ((flags & 0x0010) != 0) { 277 m.addModifier(new Modifier("final")); 278 } 279 if ((flags & 0x0020) != 0) { 280 m.addModifier(new Modifier("synchronized")); 281 } 282 if ((flags & 0x0040) != 0) { 283 m.addModifier(new Modifier("volatile")); 284 } 285 if ((flags & 0x0080) != 0) { 286 m.addModifier(new Modifier("transient")); 287 } 288 if ((flags & 0x0100) != 0) { 289 m.addModifier(new Modifier("native")); 290 } 291 if ((flags & 0x0400) != 0) { 292 m.addModifier(new Modifier("abstract")); 293 } 294 if ((flags & 0x0800) != 0) { 295 m.addModifier(new Modifier("strictfp")); 296 } 297 return m; 298 } 299 300 301 302 private void checkLengthAndNull(int index) { 303 if (index >= constantPool.length) { 304 throw new Error("Trying to access element " + index + " in constant pool of length " + constantPool.length); 305 } 306 if (constantPool[index] == null) { 307 throw new Error("Unexpected null element in constant pool at index " + index); 308 } 309 } 310 311 312 313 public boolean validConstantPoolIndex(int index) { 314 return index < constantPool.length && constantPool[index] != null; 315 } 316 317 318 319 public CONSTANT_Info getCONSTANT_Info(int index) { 320 checkLengthAndNull(index); 321 return constantPool[index]; 322 } 323 324 325 326 public CONSTANT_Utf8_Info getCONSTANT_Utf8_Info(int index) { 327 checkLengthAndNull(index); 328 CONSTANT_Info info = constantPool[index]; 329 if (!(info instanceof CONSTANT_Utf8_Info)) { 330 throw new Error("Expected CONSTANT_Utf8_info at " + index + " in constant pool but found " + info.getClass().getName()); 331 } 332 return (CONSTANT_Utf8_Info) info; 333 } 334 335 336 337 public CONSTANT_Class_Info getCONSTANT_Class_Info(int index) { 338 checkLengthAndNull(index); 339 CONSTANT_Info info = constantPool[index]; 340 if (!(info instanceof CONSTANT_Class_Info)) { 341 throw new Error("Expected CONSTANT_Class_info at " + index + " in constant pool but found " + info.getClass().getName()); 342 } 343 return (CONSTANT_Class_Info) info; 344 } 345 346 347 348 public void parseConstantPool() throws IOException { 349 int count = u2(); 350 if (VERBOSE) { 351 println("constant_pool_count: " + count); 352 } 353 constantPool = new CONSTANT_Info[count + 1]; 354 for (int i = 1; i < count; i++) { 355 parseConstantPoolEntry(i); 356 if (constantPool[i] instanceof CONSTANT_Long_Info 357 || constantPool[i] instanceof CONSTANT_Double_Info) 358 i++; 359 } 360 } 361 362 363 364 protected abstract void parseConstantPoolEntry(int i) throws IOException; 365 366 367 }