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 TypeDescriptor extends java.lang.Object {
017    
018        private BytecodeParser p;
019    
020    
021        private String descriptor;
022    
023    
024        public TypeDescriptor(BytecodeParser parser, String descriptor) {
025          p = parser;
026          this.descriptor = descriptor;
027        }
028    
029    
030    
031        public boolean isBoolean() {
032          return descriptor.charAt(0) == 'Z';
033        }
034    
035    
036    
037        public Access type() {
038          return type(descriptor);
039        }
040    
041    
042    
043        public Access type(String s) {
044          char c = s.charAt(0);
045          switch (c) {
046            case 'B':
047              return new PrimitiveTypeAccess("byte");
048            case 'C':
049              return new PrimitiveTypeAccess("char");
050            case 'D':
051              return new PrimitiveTypeAccess("double");
052            case 'F':
053              return new PrimitiveTypeAccess("float");
054            case 'I':
055              return new PrimitiveTypeAccess("int");
056            case 'J':
057              return new PrimitiveTypeAccess("long");
058            case 'S':
059              return new PrimitiveTypeAccess("short");
060            case 'Z':
061              return new PrimitiveTypeAccess("boolean");
062            case 'L':
063              return this.p.fromClassName(s.substring(1, s.length() - 1));
064            case '[':
065              return new ArrayTypeAccess(type(s.substring(1)));
066            case 'V':
067              return new PrimitiveTypeAccess("void");
068            default:
069              this.p.println("Error: unknown type in TypeDescriptor");
070              throw new Error("Error: unknown Type in TypeDescriptor: " + s);
071          }
072          //return null;
073        }
074    
075    
076    
077        public List parameterList() {
078          List list = new List();
079          String s = descriptor;
080          while(!s.equals("")) {
081            s = typeList(s, list);
082          }
083          return list;
084        }
085    
086    
087        public List parameterListSkipFirst() {
088          List list = new List();
089          String s = descriptor;
090          if(!s.equals(""))
091            s = typeList(s, new List()); // skip first
092          while(!s.equals("")) {
093            s = typeList(s, list);
094          }
095          return list;
096        }
097    
098    
099    
100        public String typeList(String s, List l) {
101          char c = s.charAt(0);
102          switch (c) {
103            case 'B':
104              l.add(new ParameterDeclaration(new Modifiers(), 
105                    new PrimitiveTypeAccess("byte"), "p" + l.getNumChildNoTransform()));
106              return s.substring(1);
107            case 'C':
108              l.add(new ParameterDeclaration(new Modifiers(), 
109                    new PrimitiveTypeAccess("char"), "p" + l.getNumChildNoTransform()));
110              return s.substring(1);
111            case 'D':
112              l.add(new ParameterDeclaration(new Modifiers(), 
113                    new PrimitiveTypeAccess("double"), "p" + l.getNumChildNoTransform()));
114              return s.substring(1);
115            case 'F':
116              l.add(new ParameterDeclaration(new Modifiers(), 
117                    new PrimitiveTypeAccess("float"), "p" + l.getNumChildNoTransform()));
118              return s.substring(1);
119            case 'I':
120              l.add(new ParameterDeclaration(new Modifiers(), 
121                    new PrimitiveTypeAccess("int"), "p" + l.getNumChildNoTransform()));
122              return s.substring(1);
123            case 'J':
124              l.add(new ParameterDeclaration(new Modifiers(), 
125                    new PrimitiveTypeAccess("long"), "p" + l.getNumChildNoTransform()));
126              return s.substring(1);
127            case 'S':
128              l.add(new ParameterDeclaration(new Modifiers(), 
129                    new PrimitiveTypeAccess("short"), "p" + l.getNumChildNoTransform()));
130              return s.substring(1);
131            case 'Z':
132              l.add(new ParameterDeclaration(new Modifiers(), 
133                    new PrimitiveTypeAccess("boolean"), "p" + l.getNumChildNoTransform()));
134              return s.substring(1);
135            case 'L':
136              int pos = s.indexOf(';');
137              String s1 = s.substring(1, pos);
138              String s2 = s.substring(pos+1, s.length());
139              l.add(new ParameterDeclaration(new Modifiers(),
140                    this.p.fromClassName(s1),
141                    "p" + l.getNumChildNoTransform()));
142              return s2;
143            case '[':
144              int i = 1;
145              while(s.charAt(i) == '[') i++;
146              ArrayTypeAccess bottom = new ArrayTypeAccess(new ParseName("")); // dummy name is replaced later
147              ArrayTypeAccess top = bottom;
148              for(int j = 0; j < i - 1; j++)
149                top = new ArrayTypeAccess(top);
150              l.add(new ParameterDeclaration(new Modifiers(), top, "p" + l.getNumChild()));
151              return arrayTypeList(s.substring(i), bottom);
152            default:
153              this.p.println("Error: unknown Type \"" + c + "\" in TypeDescriptor");
154              throw new Error("Error: unknown Type in TypeDescriptor: " + s);
155          }
156          //return "";
157    
158        }
159    
160    
161    
162        public String arrayTypeList(String s, ArrayTypeAccess typeAccess) {
163          char c = s.charAt(0);
164          switch (c) {
165            case 'B':
166              typeAccess.setAccess(new PrimitiveTypeAccess("byte"));
167              return s.substring(1);
168            case 'C':
169              typeAccess.setAccess(new PrimitiveTypeAccess("char"));
170              return s.substring(1);
171            case 'D':
172              typeAccess.setAccess(new PrimitiveTypeAccess("double"));
173              return s.substring(1);
174            case 'F':
175              typeAccess.setAccess(new PrimitiveTypeAccess("float"));
176              return s.substring(1);
177            case 'I':
178              typeAccess.setAccess(new PrimitiveTypeAccess("int"));
179              return s.substring(1);
180            case 'J':
181              typeAccess.setAccess(new PrimitiveTypeAccess("long"));
182              return s.substring(1);
183            case 'S':
184              typeAccess.setAccess(new PrimitiveTypeAccess("short"));
185              return s.substring(1);
186            case 'Z':
187              typeAccess.setAccess(new PrimitiveTypeAccess("boolean"));
188              return s.substring(1);
189            case 'L':
190              //String[] strings = s.substring(1).split("\\;", 2);
191              //typeAccess.setAccess(this.p.fromClassName(strings[0]));
192              //return strings[1];
193              int pos = s.indexOf(';');
194              String s1 = s.substring(1, pos);
195              String s2 = s.substring(pos+1, s.length());
196              typeAccess.setAccess(this.p.fromClassName(s1));
197              return s2;
198            default:
199              this.p.println("Error: unknown Type in TypeDescriptor");
200              throw new Error("Error: unknown Type in TypeDescriptor: " + s);
201          }
202          //return null;
203        }
204    
205    
206    }