170 public LocationInfo pushInner() { 171 return pushLocation((byte)1, (short)0); 172 } 173 174 public LocationInfo pushWildcard() { 175 return pushLocation((byte) 2, (short) 0); 176 } 177 178 public LocationInfo pushTypeArg(short index) { 179 return pushLocation((byte) 3, index); 180 } 181 182 public LocationInfo pushLocation(byte tag, short index) { 183 int newDepth = this.depth + 1; 184 Location[] res = new Location[newDepth]; 185 System.arraycopy(this.locations, 0, res, 0, depth); 186 res[newDepth - 1] = new Location(tag, (short)(index & 0xFF)); 187 return new LocationInfo(newDepth, res); 188 } 189 190 public TypeAnnotation[] filter(TypeAnnotation[] ta) { 191 ArrayList<TypeAnnotation> l = new ArrayList<>(ta.length); 192 for (TypeAnnotation t : ta) { 193 if (isSameLocationInfo(t.getLocationInfo())) 194 l.add(t); 195 } 196 return l.toArray(new TypeAnnotation[0]); 197 } 198 199 boolean isSameLocationInfo(LocationInfo other) { 200 if (depth != other.depth) 201 return false; 202 for (int i = 0; i < depth; i++) 203 if (!locations[i].isSameLocation(other.locations[i])) 204 return false; 205 return true; 206 } 207 208 public static final class Location { 209 public final byte tag; | 170 public LocationInfo pushInner() { 171 return pushLocation((byte)1, (short)0); 172 } 173 174 public LocationInfo pushWildcard() { 175 return pushLocation((byte) 2, (short) 0); 176 } 177 178 public LocationInfo pushTypeArg(short index) { 179 return pushLocation((byte) 3, index); 180 } 181 182 public LocationInfo pushLocation(byte tag, short index) { 183 int newDepth = this.depth + 1; 184 Location[] res = new Location[newDepth]; 185 System.arraycopy(this.locations, 0, res, 0, depth); 186 res[newDepth - 1] = new Location(tag, (short)(index & 0xFF)); 187 return new LocationInfo(newDepth, res); 188 } 189 190 public LocationInfo popLocation(byte tag) { 191 if (locations[depth-1].tag != tag) 192 throw new IllegalStateException("Tags not matching"); 193 return popLocation(); 194 } 195 196 public LocationInfo popLocation() { 197 int newDepth = this.depth - 1; 198 Location[] res = new Location[newDepth]; 199 System.arraycopy(this.locations, 0, res, 0, newDepth); 200 return new LocationInfo(newDepth, res); 201 } 202 203 /** Pop a series of locations matching {@code tag}. Stop poping as soon as a non-matching tag is found. */ 204 public LocationInfo popAllLocations(byte tag) { 205 LocationInfo l = this; 206 while(l.depth > 0 && l.locations[l.depth - 1].tag == tag) { 207 l = l.popLocation(); 208 } 209 return l; 210 } 211 212 public TypeAnnotation[] filter(TypeAnnotation[] ta) { 213 ArrayList<TypeAnnotation> l = new ArrayList<>(ta.length); 214 for (TypeAnnotation t : ta) { 215 if (isSameLocationInfo(t.getLocationInfo())) 216 l.add(t); 217 } 218 return l.toArray(new TypeAnnotation[0]); 219 } 220 221 boolean isSameLocationInfo(LocationInfo other) { 222 if (depth != other.depth) 223 return false; 224 for (int i = 0; i < depth; i++) 225 if (!locations[i].isSameLocation(other.locations[i])) 226 return false; 227 return true; 228 } 229 230 public static final class Location { 231 public final byte tag; |