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 }