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    }