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