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 BytecodeSignatures 026 * @declaredat /home/jesper/git/extendj/java5/frontend/BytecodeSignatures.jrag:33 027 */ 028 public class Signatures extends java.lang.Object { 029 030 // simple parser framework 031 String data; 032 033 034 int pos; 035 036 037 public Signatures(String s) { 038 data = s; 039 pos = 0; 040 } 041 042 043 044 public boolean next(String s) { 045 for (int i = 0; i < s.length(); i++) { 046 if (data.charAt(pos + i) != s.charAt(i)) { 047 return false; 048 } 049 } 050 return true; 051 } 052 053 054 055 public void eat(String s) { 056 for (int i = 0; i < s.length(); i++) { 057 if (data.charAt(pos + i) != s.charAt(i)) { 058 error(s); 059 } 060 } 061 pos += s.length(); 062 } 063 064 065 066 public void error(String s) { 067 throw new Error("Expected " + s + " but found " + data.substring(pos)); 068 } 069 070 071 072 public String identifier() { 073 int i = pos; 074 while (Character.isJavaIdentifierPart(data.charAt(i))) { 075 i++; 076 } 077 String result = data.substring(pos, i); 078 pos = i; 079 return result; 080 } 081 082 083 084 public boolean eof() { 085 return pos == data.length(); 086 } 087 088 089 090 // 4.4.4 Signatures 091 092 public static class ClassSignature extends Signatures { 093 public ClassSignature(String s) { 094 super(s); 095 classSignature(); 096 } 097 void classSignature() { 098 if (next("<")) { 099 formalTypeParameters(); 100 } 101 superclassSignature = parseSuperclassSignature(); 102 while (!eof()) { 103 superinterfaceSignature.add(parseSuperinterfaceSignature()); 104 } 105 } 106 107 public boolean hasFormalTypeParameters() { return typeParameters != null; } 108 public List typeParameters() { return typeParameters; } 109 110 public boolean hasSuperclassSignature() { return superclassSignature != null; } 111 public Access superclassSignature() { return superclassSignature; } 112 protected Access superclassSignature; 113 114 public boolean hasSuperinterfaceSignature() { return superinterfaceSignature.getNumChildNoTransform() != 0; } 115 public List superinterfaceSignature() { return superinterfaceSignature; } 116 protected List superinterfaceSignature = new List(); 117 118 Access parseSuperclassSignature() { 119 return classTypeSignature(); 120 } 121 122 Access parseSuperinterfaceSignature() { 123 return classTypeSignature(); 124 } 125 } 126 127 128 129 public static class FieldSignature extends Signatures { 130 public FieldSignature(String s) { 131 super(s); 132 fieldTypeAccess = fieldTypeSignature(); 133 } 134 Access fieldTypeAccess() { 135 return fieldTypeAccess; 136 } 137 private Access fieldTypeAccess; 138 } 139 140 141 142 public static class MethodSignature extends Signatures { 143 public MethodSignature(String s) { 144 super(s); 145 methodTypeSignature(); 146 } 147 void methodTypeSignature() { 148 if (next("<")) { 149 formalTypeParameters(); 150 } 151 eat("("); 152 while (!next(")")) { 153 parameterTypes.add(typeSignature()); 154 } 155 eat(")"); 156 returnType = parseReturnType(); 157 while (!eof()) { 158 exceptionList.add(throwsSignature()); 159 } 160 } 161 Access parseReturnType() { 162 if (next("V")) { 163 eat("V"); 164 return new PrimitiveTypeAccess("void"); 165 } else { 166 return typeSignature(); 167 } 168 } 169 170 Access throwsSignature() { 171 eat("^"); 172 if (next("L")) { 173 return classTypeSignature(); 174 } else { 175 return typeVariableSignature(); 176 } 177 } 178 179 public boolean hasFormalTypeParameters() { return typeParameters != null; } 180 public List typeParameters() { return typeParameters; } 181 182 public Collection parameterTypes() { return parameterTypes; } 183 protected Collection parameterTypes = new ArrayList(); 184 185 public List exceptionList() { return exceptionList; } 186 public boolean hasExceptionList() { return exceptionList.getNumChildNoTransform() != 0; } 187 protected List exceptionList = new List(); 188 189 protected Access returnType = null; 190 public boolean hasReturnType() { return returnType != null; } 191 public Access returnType() { return returnType; } 192 } 193 194 195 196 protected List typeParameters; 197 198 199 200 void formalTypeParameters() { 201 eat("<"); 202 typeParameters = new List(); 203 do { 204 typeParameters.add(formalTypeParameter()); 205 } while (!next(">")); 206 eat(">"); 207 } 208 209 210 211 TypeVariable formalTypeParameter() { 212 String id = identifier(); 213 List bounds = new List(); 214 Access classBound = classBound(); 215 if (classBound != null) { 216 bounds.add(classBound); 217 } 218 while (next(":")) { 219 bounds.add(interfaceBound()); 220 } 221 if (bounds.getNumChildNoTransform() == 0) { 222 bounds.add(new TypeAccess("java.lang", "Object")); 223 } 224 return new TypeVariable(new Modifiers(new List()), id, new List(), bounds); 225 } 226 227 228 229 Access classBound() { 230 eat(":"); 231 if (nextIsFieldTypeSignature()) { 232 return fieldTypeSignature(); 233 } else { 234 return null; 235 //return new TypeAccess("java.lang", "Object"); 236 } 237 } 238 239 240 241 Access interfaceBound() { 242 eat(":"); 243 return fieldTypeSignature(); 244 } 245 246 247 248 249 Access fieldTypeSignature() { 250 if (next("L")) { 251 return classTypeSignature(); 252 } else if (next("[")) { 253 return arrayTypeSignature(); 254 } else if (next("T")) { 255 return typeVariableSignature(); 256 } else { 257 error("L or [ or T"); 258 } 259 return null; // error never returns 260 } 261 262 263 boolean nextIsFieldTypeSignature() { 264 return next("L") || next("[") || next("T"); 265 } 266 267 268 269 Access classTypeSignature() { 270 eat("L"); 271 // Package and Type Name 272 StringBuilder packageName = new StringBuilder(); 273 String typeName = identifier(); 274 while (next("/")) { 275 eat("/"); 276 if (packageName.length() != 0) { 277 packageName.append("."); 278 } 279 packageName.append(typeName); 280 typeName = identifier(); 281 } 282 Access a = typeName.indexOf('$') == -1 ? 283 new TypeAccess(packageName.toString(), typeName) : 284 new BytecodeTypeAccess(packageName.toString(), typeName); 285 if (next("<")) { // type arguments of top level type 286 a = new ParTypeAccess(a, typeArguments()); 287 } 288 while (next(".")) { // inner classes 289 a = a.qualifiesAccess(classTypeSignatureSuffix()); 290 } 291 eat(";"); 292 return a; 293 } 294 295 296 297 Access classTypeSignatureSuffix() { 298 eat("."); 299 String id = identifier(); 300 Access a = id.indexOf('$') == -1 ? 301 new TypeAccess(id) : new BytecodeTypeAccess("", id); 302 if (next("<")) { 303 a = new ParTypeAccess(a, typeArguments()); 304 } 305 return a; 306 } 307 308 309 310 Access typeVariableSignature() { 311 eat("T"); 312 String id = identifier(); 313 eat(";"); 314 return new TypeAccess(id); 315 } 316 317 318 319 List typeArguments() { 320 eat("<"); 321 List list = new List(); 322 do { 323 list.add(typeArgument()); 324 } while (!next(">")); 325 eat(">"); 326 return list; 327 } 328 329 330 331 Access typeArgument() { 332 if (next("*")) { 333 eat("*"); 334 return new Wildcard(); 335 } else if (next("+")) { 336 eat("+"); 337 return new WildcardExtends(fieldTypeSignature()); 338 } else if (next("-")) { 339 eat("-"); 340 return new WildcardSuper(fieldTypeSignature()); 341 } else { 342 return fieldTypeSignature(); 343 } 344 } 345 346 347 348 Access arrayTypeSignature() { 349 eat("["); 350 return new ArrayTypeAccess(typeSignature()); 351 } 352 353 354 355 Access typeSignature() { 356 if (nextIsFieldTypeSignature()) { 357 return fieldTypeSignature(); 358 } else { 359 return baseType(); 360 } 361 } 362 363 364 365 Access baseType() { 366 if (next("B")) { 367 eat("B"); return new PrimitiveTypeAccess("byte"); 368 } else if (next("C")) { 369 eat("C"); return new PrimitiveTypeAccess("char"); 370 } else if (next("D")) { 371 eat("D"); return new PrimitiveTypeAccess("double"); 372 } else if (next("F")) { 373 eat("F"); return new PrimitiveTypeAccess("float"); 374 } else if (next("I")) { 375 eat("I"); return new PrimitiveTypeAccess("int"); 376 } else if (next("J")) { 377 eat("J"); return new PrimitiveTypeAccess("long"); 378 } else if (next("S")) { 379 eat("S"); return new PrimitiveTypeAccess("short"); 380 } else if (next("Z")) { 381 eat("Z"); return new PrimitiveTypeAccess("boolean"); 382 } 383 error("baseType"); 384 return null; // error never returns 385 } 386 387 388 }