KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > lookup > WildcardBinding


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.lookup;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
15 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
17 /*
18  * A wildcard acts as an argument for parameterized types, allowing to
19  * abstract parameterized types, e.g. List<String> is not compatible with List<Object>,
20  * but compatible with List<?>.
21  */

22 public class WildcardBinding extends ReferenceBinding {
23
24     ReferenceBinding genericType;
25     int rank;
26     public TypeBinding bound; // when unbound denotes the corresponding type variable (so as to retrieve its bound lazily)
27
public TypeBinding[] otherBounds; // only positionned by lub computations (if so, #bound is also set) and associated to EXTENDS mode
28
char[] genericSignature;
29     public int boundKind;
30     ReferenceBinding superclass;
31     ReferenceBinding[] superInterfaces;
32     TypeVariableBinding typeVariable; // corresponding variable
33
LookupEnvironment environment;
34     
35     /**
36      * When unbound, the bound denotes the corresponding type variable (so as to retrieve its bound lazily)
37      */

38     public WildcardBinding(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind, LookupEnvironment environment) {
39         this.genericType = genericType;
40         this.rank = rank;
41         this.boundKind = boundKind;
42         this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat wildcard as public
43
this.environment = environment;
44         initialize(genericType, bound, otherBounds);
45
46         if (genericType instanceof UnresolvedReferenceBinding)
47             ((UnresolvedReferenceBinding) genericType).addWrapper(this, environment);
48         if (bound instanceof UnresolvedReferenceBinding)
49             ((UnresolvedReferenceBinding) bound).addWrapper(this, environment);
50         this.tagBits |= TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
51
}
52
53     public int kind() {
54         return WILDCARD_TYPE;
55     }
56         
57     /**
58      * Returns true if the argument type satisfies the wildcard bound(s)
59      */

60     public boolean boundCheck(TypeBinding argumentType) {
61         switch (this.boundKind) {
62             case Wildcard.UNBOUND :
63                 return true;
64             case Wildcard.EXTENDS :
65                 if (argumentType.isCompatibleWith(this.bound)) return true;
66                 // check other bounds (lub scenario)
67
for (int i = 0, length = this.otherBounds == null ? 0 : this.otherBounds.length; i < length; i++) {
68                     if (argumentType.isCompatibleWith(this.otherBounds[i])) return true;
69                 }
70                 return false;
71             default: // SUPER
72
// ? super Exception ok for: IOException, since it would be ok for (Exception)ioException
73
return argumentType.isCompatibleWith(this.bound);
74         }
75     }
76     /**
77      * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#canBeInstantiated()
78      */

79     public boolean canBeInstantiated() {
80         // cannot be asked per construction
81
return false;
82     }
83     
84     /**
85      * Collect the substitutes into a map for certain type variables inside the receiver type
86      * e.g. Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
87      * Constraints:
88      * A << F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
89      * A = F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
90      * A >> F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
91      */

92     public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
93
94         if ((this.tagBits & TagBits.HasTypeVariable) == 0) return;
95         if (actualType == TypeBinding.NULL) return;
96     
97         if (actualType.isCapture()) {
98             CaptureBinding capture = (CaptureBinding) actualType;
99             actualType = capture.wildcard;
100         }
101         
102         switch (constraint) {
103             case TypeConstants.CONSTRAINT_EXTENDS : // A << F
104
switch (this.boundKind) {
105                     case Wildcard.UNBOUND: // F={?}
106
// if (otherType.isWildcard()) {
107
// WildcardBinding otherWildcard = (WildcardBinding) otherType;
108
// switch(otherWildcard.kind) {
109
// case Wildcard.UNBOUND: // A={?} << F={?} --> 0
110
// break;
111
// case Wildcard.EXTENDS: // A={? extends V} << F={?} ---> 0
112
// break;
113
// case Wildcard.SUPER: // A={? super V} << F={?} ---> 0
114
// break;
115
// }
116
// } else { // A=V << F={?} ---> 0
117
// }
118
break;
119                     case Wildcard.EXTENDS: // F={? extends U}
120
if (actualType.isWildcard()) {
121                             WildcardBinding actualWildcard = (WildcardBinding) actualType;
122                             switch(actualWildcard.boundKind) {
123                                 case Wildcard.UNBOUND: // A={?} << F={? extends U} --> 0
124
break;
125                                 case Wildcard.EXTENDS: // A={? extends V} << F={? extends U} ---> V << U
126
this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
127                                     for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
128                                         this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
129                                     }
130                                     break;
131                                 case Wildcard.SUPER: // A={? super V} << F={? extends U} ---> 0
132
break;
133                             }
134                         } else { // A=V << F={? extends U} ---> V << U
135
this.bound.collectSubstitutes(scope, actualType, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
136                         }
137                         break;
138                     case Wildcard.SUPER: // F={? super U}
139
if (actualType.isWildcard()) {
140                             WildcardBinding actualWildcard = (WildcardBinding) actualType;
141                             switch(actualWildcard.boundKind) {
142                                 case Wildcard.UNBOUND: // A={?} << F={? super U} --> 0
143
break;
144                                 case Wildcard.EXTENDS: // A={? extends V} << F={? super U} ---> 0
145
break;
146                                 case Wildcard.SUPER: // A={? super V} << F={? super U} ---> 0
147
this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
148                                     for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
149                                         this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_SUPER);
150                                     }
151                                     break;
152                             }
153                         } else { // A=V << F={? super U} ---> V >> U
154
this.bound.collectSubstitutes(scope, actualType, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
155                         }
156                         break;
157                 }
158                 break;
159             case TypeConstants.CONSTRAINT_EQUAL : // A == F
160
switch (this.boundKind) {
161                     case Wildcard.UNBOUND: // F={?}
162
// if (otherType.isWildcard()) {
163
// WildcardBinding otherWildcard = (WildcardBinding) otherType;
164
// switch(otherWildcard.kind) {
165
// case Wildcard.UNBOUND: // A={?} == F={?} --> 0
166
// break;
167
// case Wildcard.EXTENDS: // A={? extends V} == F={?} ---> 0
168
// break;
169
// case Wildcard.SUPER: // A={? super V} == F={?} ---> 0
170
// break;
171
// }
172
// } else { // A=V == F={?} ---> 0
173
// }
174
break;
175                     case Wildcard.EXTENDS: // F={? extends U}
176
if (actualType.isWildcard()) {
177                             WildcardBinding actualWildcard = (WildcardBinding) actualType;
178                             switch(actualWildcard.boundKind) {
179                                 case Wildcard.UNBOUND: // A={?} == F={? extends U} --> 0
180
break;
181                                 case Wildcard.EXTENDS: // A={? extends V} == F={? extends U} ---> V == U
182
this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
183                                     for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
184                                         this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
185                                     }
186                                     break;
187                                 case Wildcard.SUPER: // A={? super V} == F={? extends U} ---> 0
188
break;
189                             }
190                         } else { // A=V == F={? extends U} ---> 0
191
}
192                         break;
193                     case Wildcard.SUPER: // F={? super U}
194
if (actualType.isWildcard()) {
195                             WildcardBinding actualWildcard = (WildcardBinding) actualType;
196                             switch(actualWildcard.boundKind) {
197                                 case Wildcard.UNBOUND: // A={?} == F={? super U} --> 0
198
break;
199                                 case Wildcard.EXTENDS: // A={? extends V} == F={? super U} ---> 0
200
break;
201                                 case Wildcard.SUPER: // A={? super V} == F={? super U} ---> 0
202
this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
203                                     for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
204                                         this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
205                                     }
206                                     break;
207                             }
208                         } else { // A=V == F={? super U} ---> 0
209
}
210                         break;
211                 }
212                 break;
213             case TypeConstants.CONSTRAINT_SUPER : // A >> F
214
switch (this.boundKind) {
215                     case Wildcard.UNBOUND: // F={?}
216
// if (otherType.isWildcard()) {
217
// WildcardBinding otherWildcard = (WildcardBinding) otherType;
218
// switch(otherWildcard.kind) {
219
// case Wildcard.UNBOUND: // A={?} >> F={?} --> 0
220
// break;
221
// case Wildcard.EXTENDS: // A={? extends V} >> F={?} ---> 0
222
// break;
223
// case Wildcard.SUPER: // A={? super V} >> F={?} ---> 0
224
// break;
225
// }
226
// } else { // A=V >> F={?} ---> 0
227
// }
228
break;
229                     case Wildcard.EXTENDS: // F={? extends U}
230
if (actualType.isWildcard()) {
231                             WildcardBinding actualWildcard = (WildcardBinding) actualType;
232                             switch(actualWildcard.boundKind) {
233                                 case Wildcard.UNBOUND: // A={?} >> F={? extends U} --> 0
234
break;
235                                 case Wildcard.EXTENDS: // A={? extends V} >> F={? extends U} ---> V >> U
236
this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
237                                     for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
238                                         this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_SUPER);
239                                     }
240                                     break;
241                                 case Wildcard.SUPER: // A={? super V} >> F={? extends U} ---> 0
242
break;
243                             }
244                         } else { // A=V == F={? extends U} ---> 0
245
}
246                         break;
247                     case Wildcard.SUPER: // F={? super U}
248
if (actualType.isWildcard()) {
249                             WildcardBinding actualWildcard = (WildcardBinding) actualType;
250                             switch(actualWildcard.boundKind) {
251                                 case Wildcard.UNBOUND: // A={?} >> F={? super U} --> 0
252
break;
253                                 case Wildcard.EXTENDS: // A={? extends V} >> F={? super U} ---> 0
254
break;
255                                 case Wildcard.SUPER: // A={? super V} >> F={? super U} ---> V >> U
256
this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
257                                     for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
258                                         this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_SUPER);
259                                     }
260                                     break;
261                             }
262                         } else { // A=V >> F={? super U} ---> 0
263
}
264                         break;
265                 }
266                 break;
267         }
268     }
269     
270     /*
271      * genericTypeKey *|+|- [boundKey]
272      * p.X<T> { X<?> ... } --> Lp/X<TT;>;*
273      */

274     public char[] computeUniqueKey(boolean isLeaf) {
275         char[] genericTypeKey = this.genericType.computeUniqueKey(false/*not a leaf*/);
276         char[] wildCardKey;
277         switch (this.boundKind) {
278             case Wildcard.UNBOUND :
279                 wildCardKey = TypeConstants.WILDCARD_STAR;
280                 break;
281             case Wildcard.EXTENDS :
282                 wildCardKey = CharOperation.concat(TypeConstants.WILDCARD_PLUS, this.bound.computeUniqueKey(false/*not a leaf*/));
283                 break;
284             default: // SUPER
285
wildCardKey = CharOperation.concat(TypeConstants.WILDCARD_MINUS, this.bound.computeUniqueKey(false/*not a leaf*/));
286                 break;
287         }
288         return CharOperation.concat(genericTypeKey, wildCardKey);
289        }
290     
291     /**
292      * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#constantPoolName()
293      */

294     public char[] constantPoolName() {
295         return this.erasure().constantPoolName();
296     }
297     
298     /**
299      * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
300      */

301     public String JavaDoc debugName() {
302         return toString();
303     }
304     
305     /* (non-Javadoc)
306      * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
307      */

308     public TypeBinding erasure() {
309         if (this.otherBounds == null) {
310             if (this.boundKind == Wildcard.EXTENDS)
311                 return this.bound.erasure();
312             return typeVariable().erasure();
313         }
314         // intersection type
315
return this.bound.id == TypeIds.T_JavaLangObject
316             ? this.otherBounds[0].erasure() // use first explicit bound to improve stackmap
317
: this.bound.erasure();
318     }
319
320     /* (non-Javadoc)
321      * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#signature()
322      */

323     public char[] genericTypeSignature() {
324         if (this.genericSignature == null) {
325             switch (this.boundKind) {
326                 case Wildcard.UNBOUND :
327                     this.genericSignature = TypeConstants.WILDCARD_STAR;
328                     break;
329                 case Wildcard.EXTENDS :
330                     this.genericSignature = CharOperation.concat(TypeConstants.WILDCARD_PLUS, this.bound.genericTypeSignature());
331                     break;
332                 default: // SUPER
333
this.genericSignature = CharOperation.concat(TypeConstants.WILDCARD_MINUS, this.bound.genericTypeSignature());
334             }
335         }
336         return this.genericSignature;
337     }
338     
339     public int hashCode() {
340         return this.genericType.hashCode();
341     }
342
343     void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
344         this.genericType = someGenericType;
345         this.bound = someBound;
346         this.otherBounds = someOtherBounds;
347         if (someGenericType != null) {
348             this.fPackage = someGenericType.getPackage();
349         }
350         if (someBound != null) {
351             this.tagBits |= someBound.tagBits & TagBits.HasTypeVariable;
352         }
353     }
354
355     /**
356      * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#isSuperclassOf(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)
357      */

358     public boolean isSuperclassOf(ReferenceBinding otherType) {
359         if (this.boundKind == Wildcard.SUPER) {
360             if (this.bound instanceof ReferenceBinding) {
361                 return ((ReferenceBinding) this.bound).isSuperclassOf(otherType);
362             } else { // array bound
363
return otherType.id == TypeIds.T_JavaLangObject;
364             }
365         }
366         return false;
367     }
368     
369     /**
370      * Returns true if the current type denotes an intersection type: Number & Comparable<?>
371      */

372     public boolean isIntersectionType() {
373         return this.otherBounds != null;
374     }
375     
376     /**
377      * Returns true if the type is a wildcard
378      */

379     public boolean isUnboundWildcard() {
380         return this.boundKind == Wildcard.UNBOUND;
381     }
382     
383     /**
384      * Returns true if the type is a wildcard
385      */

386     public boolean isWildcard() {
387         return true;
388     }
389
390     /* (non-Javadoc)
391      * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
392      */

393     public char[] readableName() {
394         switch (this.boundKind) {
395             case Wildcard.UNBOUND :
396                 return TypeConstants.WILDCARD_NAME;
397             case Wildcard.EXTENDS :
398                 if (this.otherBounds == null)
399                     return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.readableName());
400                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(10);
401                 buffer.append(this.bound.readableName());
402                 for (int i = 0, length = this.otherBounds.length; i < length; i++) {
403                     buffer.append('&').append(this.otherBounds[i].readableName());
404                 }
405                 int length;
406                 char[] result = new char[length = buffer.length()];
407                 buffer.getChars(0, length, result, 0);
408                 return result;
409             default: // SUPER
410
return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.readableName());
411         }
412     }
413     
414     ReferenceBinding resolve() {
415         if ((this.tagBits & TagBits.HasUnresolvedTypeVariables) == 0)
416             return this;
417
418         this.tagBits &= ~TagBits.HasUnresolvedTypeVariables;
419         BinaryTypeBinding.resolveType(this.genericType, this.environment, null, 0);
420         switch(this.boundKind) {
421             case Wildcard.EXTENDS :
422             case Wildcard.SUPER :
423                 BinaryTypeBinding.resolveType(this.bound, this.environment, null, 0);
424                 break;
425             case Wildcard.UNBOUND :
426         }
427         return this;
428     }
429     
430     /* (non-Javadoc)
431      * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
432      */

433     public char[] shortReadableName() {
434         switch (this.boundKind) {
435             case Wildcard.UNBOUND :
436                 return TypeConstants.WILDCARD_NAME;
437             case Wildcard.EXTENDS :
438                 if (this.otherBounds == null)
439                     return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.shortReadableName());
440                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(10);
441                 buffer.append(this.bound.shortReadableName());
442                 for (int i = 0, length = this.otherBounds.length; i < length; i++) {
443                     buffer.append('&').append(this.otherBounds[i].shortReadableName());
444                 }
445                 int length;
446                 char[] result = new char[length = buffer.length()];
447                 buffer.getChars(0, length, result, 0);
448                 return result;
449             default: // SUPER
450
return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.shortReadableName());
451         }
452     }
453     
454     /**
455      * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#signature()
456      */

457     public char[] signature() {
458         // should not be called directly on a wildcard; signature should only be asked on
459
// original methods or type erasures (which cannot denote wildcards at first level)
460
if (this.signature == null) {
461             switch (this.boundKind) {
462                 case Wildcard.EXTENDS :
463                     return this.bound.signature();
464                 default: // SUPER | UNBOUND
465
return this.typeVariable().signature();
466             }
467         }
468         return this.signature;
469     }
470     
471     /* (non-Javadoc)
472      * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#sourceName()
473      */

474     public char[] sourceName() {
475         switch (this.boundKind) {
476             case Wildcard.UNBOUND :
477                 return TypeConstants.WILDCARD_NAME;
478             case Wildcard.EXTENDS :
479                 return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.sourceName());
480             default: // SUPER
481
return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.sourceName());
482         }
483     }
484
485     /* (non-Javadoc)
486      * @see org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding#superclass()
487      */

488     public ReferenceBinding superclass() {
489         if (this.superclass == null) {
490             TypeBinding superType = null;
491             if (this.boundKind == Wildcard.EXTENDS && !this.bound.isInterface()) {
492                 superType = this.bound;
493             } else {
494                 TypeVariableBinding variable = this.typeVariable();
495                 if (variable != null) superType = variable.firstBound;
496             }
497             this.superclass = superType instanceof ReferenceBinding && !superType.isInterface()
498                 ? (ReferenceBinding) superType
499                 : environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
500         }
501
502         return this.superclass;
503     }
504   /*
505     public ReferenceBinding superclass2() {
506         if (this.superclass == null) {
507             TypeBinding superType = (this.boundKind == Wildcard.EXTENDS && !this.bound.isInterface())
508                 ? this.bound
509                 : null;
510             this.superclass = superType instanceof ReferenceBinding && !superType.isInterface()
511                 ? (ReferenceBinding) superType
512                 : environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
513             
514 // TypeBinding superType = null;
515 // if (this.boundKind == Wildcard.EXTENDS && !this.bound.isInterface()) {
516 // superType = this.bound;
517 // } else {
518 // TypeVariableBinding variable = this.typeVariable();
519 // if (variable != null) superType = variable.firstBound;
520 // }
521 // this.superclass = superType instanceof ReferenceBinding && !superType.isInterface()
522 // ? (ReferenceBinding) superType
523 // : environment.getType(TypeConstants.JAVA_LANG_OBJECT);
524         }
525         return this.superclass;
526     }
527 */

528     /* (non-Javadoc)
529      * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#superInterfaces()
530      */

531     public ReferenceBinding[] superInterfaces() {
532         if (this.superInterfaces == null) {
533             if (this.typeVariable() != null) {
534                 this.superInterfaces = this.typeVariable.superInterfaces();
535             } else {
536                 this.superInterfaces = Binding.NO_SUPERINTERFACES;
537             }
538             if (this.boundKind == Wildcard.EXTENDS) {
539                 if (this.bound.isInterface()) {
540                     // augment super interfaces with the wildcard bound
541
int length = this.superInterfaces.length;
542                     System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new ReferenceBinding[length+1], 1, length);
543                     this.superInterfaces[0] = (ReferenceBinding) this.bound; // make bound first
544
}
545                 if (this.otherBounds != null) {
546                     // augment super interfaces with the wildcard otherBounds (interfaces per construction)
547
int length = this.superInterfaces.length;
548                     int otherLength = this.otherBounds.length;
549                     System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new ReferenceBinding[length+otherLength], 0, length);
550                     for (int i = 0; i < otherLength; i++) {
551                         this.superInterfaces[length+i] = (ReferenceBinding) this.otherBounds[i];
552                     }
553                 }
554             }
555         }
556         return this.superInterfaces;
557     }
558
559     public ReferenceBinding[] superInterfaces2() {
560         if (this.superInterfaces == null) {
561             if (this.boundKind == Wildcard.EXTENDS) {
562                 if (this.bound.isInterface()) {
563                     if (this.otherBounds != null) {
564                         // augment super interfaces with the wildcard otherBounds (interfaces per construction)
565
int otherLength = this.otherBounds.length;
566                         System.arraycopy(this.otherBounds, 0, this.superInterfaces = new ReferenceBinding[otherLength+1], 1, otherLength);
567                         this.superInterfaces[0] = (ReferenceBinding) this.bound;
568                     } else {
569                         this.superInterfaces = new ReferenceBinding[] { (ReferenceBinding) this.bound };
570                     }
571                 } else if (this.otherBounds != null) {
572                     int otherLength = this.otherBounds.length;
573                     System.arraycopy(this.otherBounds, 0, this.superInterfaces = new ReferenceBinding[otherLength], 0, otherLength);
574                 } else {
575                     this.superInterfaces = Binding.NO_SUPERINTERFACES;
576                 }
577             } else {
578                 this.superInterfaces = Binding.NO_SUPERINTERFACES;
579             }
580         }
581         return this.superInterfaces;
582     }
583
584     public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
585         boolean affected = false;
586         if (this.genericType == unresolvedType) {
587             this.genericType = resolvedType; // no raw conversion
588
affected = true;
589         } else if (this.bound == unresolvedType) {
590             this.bound = env.convertUnresolvedBinaryToRawType(resolvedType);
591             affected = true;
592         }
593         if (affected)
594             initialize(this.genericType, this.bound, this.otherBounds);
595     }
596
597     /**
598      * @see java.lang.Object#toString()
599      */

600     public String JavaDoc toString() {
601         switch (this.boundKind) {
602             case Wildcard.UNBOUND :
603                 return new String JavaDoc(TypeConstants.WILDCARD_NAME);
604             case Wildcard.EXTENDS :
605                 if (this.otherBounds == null)
606                     return new String JavaDoc(CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.debugName().toCharArray()));
607                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(this.bound.debugName());
608                 for (int i = 0, length = this.otherBounds.length; i < length; i++) {
609                     buffer.append('&').append(this.otherBounds[i].debugName());
610                 }
611                 return buffer.toString();
612             default: // SUPER
613
return new String JavaDoc(CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.debugName().toCharArray()));
614         }
615     }
616     /**
617      * Returns associated type variable, or null in case of inconsistency
618      */

619     public TypeVariableBinding typeVariable() {
620         if (this.typeVariable == null) {
621             TypeVariableBinding[] typeVariables = this.genericType.typeVariables();
622             if (this.rank < typeVariables.length)
623                 this.typeVariable = typeVariables[this.rank];
624         }
625         return this.typeVariable;
626     }
627 }
628
Popular Tags