1313import com .ibm .wala .types .TypeReference ;
1414import com .ibm .wala .util .debug .Assertions ;
1515import java .util .ArrayList ;
16- import java .util .Iterator ;
1716
1817/**
1918 * UNDER CONSTRUCTION.
@@ -81,13 +80,21 @@ public static TypeSignature make(String s) throws IllegalArgumentException {
8180 public abstract boolean isBaseType ();
8281
8382 /**
84- * @param typeSigs TypeSignature*
85- * @return tokenize it
83+ * Split a string of consecutive type signatures (TypeSignature*) into its top-level type
84+ * signatures. The string should start with either {@code (} or {@code <} and have a respective
85+ * matching {@code )} or {@code >}.
86+ *
87+ * @param typeSigs a string of consecutive type signatures
88+ * @return an array of top-level type signatures
8689 */
87- static String [] parseForTypeSignatures (String typeSigs ) throws IllegalArgumentException {
90+ public static String [] parseForTypeSignatures (String typeSigs ) throws IllegalArgumentException {
8891 ArrayList <String > sigs = new ArrayList <>(10 );
92+ char start = typeSigs .charAt (0 );
93+ if (start != '(' && start != '<' ) {
94+ throw new IllegalArgumentException (
95+ "illegal start of TypeSignature " + typeSigs + ", must be '(' or '<'" );
96+ }
8997 if (typeSigs .length () < 2 ) {
90- // TODO: check this?
9198 throw new IllegalArgumentException ("illegal string of TypeSignature " + typeSigs );
9299 }
93100
@@ -124,20 +131,16 @@ static String[] parseForTypeSignatures(String typeSigs) throws IllegalArgumentEx
124131 case TypeReference .ClassTypeCode :
125132 {
126133 int off = i - 1 ;
127- int depth = 0 ;
128- while (typeSigs .charAt (i ++) != ';' || depth > 0 ) {
129- if (typeSigs .charAt (i - 1 ) == '<' ) {
130- depth ++;
131- }
132- if (typeSigs .charAt (i - 1 ) == '>' ) {
133- depth --;
134- }
135- }
134+ i = getEndIndexOfClassType (typeSigs , i );
136135 sigs .add (typeSigs .substring (off , i ));
137136 continue ;
138137 }
139138 case TypeReference .ArrayTypeCode :
140139 {
140+ int arrayStart = i - 1 ;
141+ while (typeSigs .charAt (i ) == TypeReference .ArrayTypeCode ) {
142+ i ++;
143+ }
141144 switch (typeSigs .charAt (i )) {
142145 case TypeReference .BooleanTypeCode :
143146 case TypeReference .ByteTypeCode :
@@ -147,23 +150,14 @@ static String[] parseForTypeSignatures(String typeSigs) throws IllegalArgumentEx
147150 case TypeReference .FloatTypeCode :
148151 case TypeReference .DoubleTypeCode :
149152 case TypeReference .CharTypeCode :
150- sigs .add (typeSigs .substring (i - 1 , i + 1 ));
153+ sigs .add (typeSigs .substring (arrayStart , i + 1 ));
151154 i ++;
152155 break ;
153156 case 'T' :
154157 case TypeReference .ClassTypeCode :
155- int off = i - 1 ;
156- i ++;
157- int depth = 0 ;
158- while (typeSigs .charAt (i ++) != ';' || depth > 0 ) {
159- if (typeSigs .charAt (i - 1 ) == '<' ) {
160- depth ++;
161- }
162- if (typeSigs .charAt (i - 1 ) == '>' ) {
163- depth --;
164- }
165- }
166- sigs .add (typeSigs .substring (off , i ));
158+ i ++; // to skip 'L' or 'T'
159+ i = getEndIndexOfClassType (typeSigs , i );
160+ sigs .add (typeSigs .substring (arrayStart , i ));
167161 break ;
168162 default :
169163 Assertions .UNREACHABLE ("BANG " + typeSigs .charAt (i ));
@@ -178,20 +172,35 @@ static String[] parseForTypeSignatures(String typeSigs) throws IllegalArgumentEx
178172 sigs .add (typeSigs .substring (off , i ));
179173 continue ;
180174 }
175+ case (byte ) '*' : // unbounded wildcard
176+ sigs .add ("*" );
177+ break ;
178+ case (byte ) '-' : // bounded wildcard
179+ case (byte ) '+' : // bounded wildcard
180+ int boundedStart = i - 1 ;
181+ i ++; // to skip 'L'
182+ i = getEndIndexOfClassType (typeSigs , i );
183+ sigs .add (typeSigs .substring (boundedStart , i ));
184+ break ;
181185 case (byte ) ')' : // end of parameter list
182- int size = sigs .size ();
183- if (size == 0 ) {
184- return null ;
185- }
186- Iterator <String > it = sigs .iterator ();
187- String [] result = new String [size ];
188- for (int j = 0 ; j < size ; j ++) {
189- result [j ] = it .next ();
190- }
191- return result ;
186+ case (byte ) '>' : // end of type argument list
187+ return sigs .toArray (new String [sigs .size ()]);
192188 default :
193- assert false : "bad type signature list " + typeSigs ;
189+ throw new IllegalArgumentException ("bad type signature list " + typeSigs );
190+ }
191+ }
192+ }
193+
194+ private static int getEndIndexOfClassType (String typeSigs , int i ) {
195+ int depth = 0 ;
196+ while (typeSigs .charAt (i ++) != ';' || depth > 0 ) {
197+ if (typeSigs .charAt (i - 1 ) == '<' ) {
198+ depth ++;
199+ }
200+ if (typeSigs .charAt (i - 1 ) == '>' ) {
201+ depth --;
194202 }
195203 }
204+ return i ;
196205 }
197206}
0 commit comments