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    }