KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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
16 /*
17  * Not all fields defined by this type (& its subclasses) are initialized when it is created.
18  * Some are initialized only when needed.
19  *
20  * Accessors have been provided for some public fields so all TypeBindings have the same API...
21  * but access public fields directly whenever possible.
22  * Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
23  *
24  * null is NOT a valid value for a non-public field... it just means the field is not initialized.
25  */

26 abstract public class TypeBinding extends Binding {
27     
28     public int id = TypeIds.NoId;
29     public long tagBits = 0; // See values in the interface TagBits below
30

31
32     /** Base type definitions */
33     public final static BaseTypeBinding INT = new BaseTypeBinding(
34             TypeIds.T_int, TypeConstants.INT, new char[] { 'I' });
35
36     public final static BaseTypeBinding BYTE = new BaseTypeBinding(
37             TypeIds.T_byte, TypeConstants.BYTE, new char[] { 'B' });
38
39     public final static BaseTypeBinding SHORT = new BaseTypeBinding(
40             TypeIds.T_short, TypeConstants.SHORT, new char[] { 'S' });
41
42     public final static BaseTypeBinding CHAR = new BaseTypeBinding(
43             TypeIds.T_char, TypeConstants.CHAR, new char[] { 'C' });
44
45     public final static BaseTypeBinding LONG = new BaseTypeBinding(
46             TypeIds.T_long, TypeConstants.LONG, new char[] { 'J' });
47
48     public final static BaseTypeBinding FLOAT = new BaseTypeBinding(
49             TypeIds.T_float, TypeConstants.FLOAT, new char[] { 'F' });
50
51     public final static BaseTypeBinding DOUBLE = new BaseTypeBinding(
52             TypeIds.T_double, TypeConstants.DOUBLE, new char[] { 'D' });
53
54     public final static BaseTypeBinding BOOLEAN = new BaseTypeBinding(
55             TypeIds.T_boolean, TypeConstants.BOOLEAN, new char[] { 'Z' });
56
57     public final static BaseTypeBinding NULL = new BaseTypeBinding(
58             TypeIds.T_null, TypeConstants.NULL, new char[] { 'N' }); //N stands for null even if it is never internally used
59

60     public final static BaseTypeBinding VOID = new BaseTypeBinding(
61             TypeIds.T_void, TypeConstants.VOID, new char[] { 'V' });
62
63 /**
64  * Match a well-known type id to its binding
65  */

66 public static final TypeBinding wellKnownType(Scope scope, int id) {
67     switch (id) {
68     case TypeIds.T_boolean:
69         return TypeBinding.BOOLEAN;
70     case TypeIds.T_byte:
71         return TypeBinding.BYTE;
72     case TypeIds.T_char:
73         return TypeBinding.CHAR;
74     case TypeIds.T_short:
75         return TypeBinding.SHORT;
76     case TypeIds.T_double:
77         return TypeBinding.DOUBLE;
78     case TypeIds.T_float:
79         return TypeBinding.FLOAT;
80     case TypeIds.T_int:
81         return TypeBinding.INT;
82     case TypeIds.T_long:
83         return TypeBinding.LONG;
84     case TypeIds.T_JavaLangObject:
85         return scope.getJavaLangObject();
86     case TypeIds.T_JavaLangString:
87         return scope.getJavaLangString();
88     default:
89         return null;
90     }
91 }
92
93 /* Answer true if the receiver can be instantiated
94  */

95 public boolean canBeInstantiated() {
96     return !isBaseType();
97 }
98
99 /**
100  * Perform capture conversion on a given type (only effective on parameterized type with wildcards)
101  */

102 public TypeBinding capture(Scope scope, int position) {
103     return this;
104 }
105
106 /**
107  * Collect the substitutes into a map for certain type variables inside the receiver type
108  * e.g. Collection<T>.findSubstitute(T, Collection<List<X>>): T --> List<X>
109  * Constraints:
110  * A << F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
111  * A = F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
112  * A >> F corresponds to: F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
113  */

114 public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
115     // no substitute by default
116
}
117
118 /**
119  * Answer the receiver's constant pool name.
120  * NOTE: This method should only be used during/after code gen.
121  * e.g. 'java/lang/Object'
122  */

123 public abstract char[] constantPoolName();
124
125 public String JavaDoc debugName() {
126     return new String JavaDoc(readableName());
127 }
128
129 /*
130  * Answer the receiver's dimensions - 0 for non-array types
131  */

132 public int dimensions() {
133     return 0;
134 }
135
136 /* Answer the receiver's enclosing type... null if the receiver is a top level type.
137  */

138 public ReferenceBinding enclosingType() {
139     return null;
140 }
141
142 public TypeBinding erasure() {
143     return this;
144 }
145
146 /**
147  * Find supertype which erases to a given well-known type, or null if not found
148  * (using id avoids triggering the load of well-known type: 73740)
149  * NOTE: only works for erasures of well-known types, as random other types may share
150  * same id though being distincts.
151  *
152  */

153 public ReferenceBinding findSuperTypeErasingTo(int wellKnownErasureID, boolean erasureIsClass) {
154
155     if (!(this instanceof ReferenceBinding)) return null;
156     ReferenceBinding reference = (ReferenceBinding) this;
157     
158     // do not allow type variables to match with erasures for free
159
if (reference.id == wellKnownErasureID || (!isTypeVariable() && !isIntersectionType() && erasure().id == wellKnownErasureID)) return reference;
160
161     ReferenceBinding currentType = reference;
162     // iterate superclass to avoid recording interfaces if searched supertype is class
163
if (erasureIsClass) {
164         while ((currentType = currentType.superclass()) != null) {
165             if (currentType.id == wellKnownErasureID || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure().id == wellKnownErasureID))
166                 return currentType;
167         }
168         return null;
169     }
170     ReferenceBinding[] interfacesToVisit = null;
171     int nextPosition = 0;
172     do {
173         ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
174         if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
175             if (interfacesToVisit == null) {
176                 interfacesToVisit = itsInterfaces;
177                 nextPosition = interfacesToVisit.length;
178             } else {
179                 int itsLength = itsInterfaces.length;
180                 if (nextPosition + itsLength >= interfacesToVisit.length)
181                     System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
182                 nextInterface : for (int a = 0; a < itsLength; a++) {
183                     ReferenceBinding next = itsInterfaces[a];
184                     for (int b = 0; b < nextPosition; b++)
185                         if (next == interfacesToVisit[b]) continue nextInterface;
186                     interfacesToVisit[nextPosition++] = next;
187                 }
188             }
189         }
190     } while ((currentType = currentType.superclass()) != null);
191             
192     for (int i = 0; i < nextPosition; i++) {
193         currentType = interfacesToVisit[i];
194         if (currentType.id == wellKnownErasureID || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure().id == wellKnownErasureID))
195             return currentType;
196
197         ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
198         if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
199             int itsLength = itsInterfaces.length;
200             if (nextPosition + itsLength >= interfacesToVisit.length)
201                 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
202             nextInterface : for (int a = 0; a < itsLength; a++) {
203                 ReferenceBinding next = itsInterfaces[a];
204                 for (int b = 0; b < nextPosition; b++)
205                     if (next == interfacesToVisit[b]) continue nextInterface;
206                 interfacesToVisit[nextPosition++] = next;
207             }
208         }
209     }
210     return null;
211 }
212
213 /**
214  * Find supertype which erases to a given type, or null if not found
215  */

216 public TypeBinding findSuperTypeWithSameErasure(TypeBinding otherType) {
217     if (this == otherType) return this;
218     if (otherType == null) return null;
219     switch(kind()) {
220         case Binding.ARRAY_TYPE :
221             ArrayBinding arrayType = (ArrayBinding) this;
222             int otherDim = otherType.dimensions();
223             if (arrayType.dimensions != otherDim) {
224                 switch(otherType.id) {
225                     case TypeIds.T_JavaLangObject :
226                     case TypeIds.T_JavaIoSerializable :
227                     case TypeIds.T_JavaLangCloneable :
228                         return otherType;
229                 }
230                 if (otherDim < arrayType.dimensions && otherType.leafComponentType().id == TypeIds.T_JavaLangObject) {
231                     return otherType; // X[][] has Object[] as an implicit supertype
232
}
233                 return null;
234             }
235             if (!(arrayType.leafComponentType instanceof ReferenceBinding)) return null;
236             TypeBinding leafSuperType = arrayType.leafComponentType.findSuperTypeWithSameErasure(otherType.leafComponentType());
237             if (leafSuperType == null) return null;
238             return arrayType.environment().createArrayType(leafSuperType, arrayType.dimensions);
239             
240         case Binding.TYPE_PARAMETER :
241             if (isCapture()) {
242                 CaptureBinding capture = (CaptureBinding) this;
243                 TypeBinding captureBound = capture.firstBound;
244                 if (captureBound instanceof ArrayBinding) {
245                     TypeBinding match = captureBound.findSuperTypeWithSameErasure(otherType);
246                     if (match != null) return match;
247                 }
248             }
249             // fall-through
250
case Binding.TYPE :
251         case Binding.PARAMETERIZED_TYPE :
252         case Binding.GENERIC_TYPE :
253         case Binding.RAW_TYPE :
254         case Binding.WILDCARD_TYPE :
255             // do not allow type variables/intersection types to match with erasures for free
256
if (!otherType.isTypeVariable() && !otherType.isIntersectionType()) otherType = otherType.erasure();
257             if (this == otherType || (!isTypeVariable() && !isIntersectionType() && erasure() == otherType)) return this;
258             
259             ReferenceBinding currentType = (ReferenceBinding)this;
260             if (!otherType.isInterface()) {
261                 while ((currentType = currentType.superclass()) != null) {
262                     if (currentType == otherType || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure() == otherType)) return currentType;
263                 }
264                 return null;
265             }
266             ReferenceBinding[] interfacesToVisit = null;
267             int nextPosition = 0;
268             do {
269                 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
270                 if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
271                     if (interfacesToVisit == null) {
272                         interfacesToVisit = itsInterfaces;
273                         nextPosition = interfacesToVisit.length;
274                     } else {
275                         int itsLength = itsInterfaces.length;
276                         if (nextPosition + itsLength >= interfacesToVisit.length)
277                             System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
278                         nextInterface : for (int a = 0; a < itsLength; a++) {
279                             ReferenceBinding next = itsInterfaces[a];
280                             for (int b = 0; b < nextPosition; b++)
281                                 if (next == interfacesToVisit[b]) continue nextInterface;
282                             interfacesToVisit[nextPosition++] = next;
283                         }
284                     }
285                 }
286             } while ((currentType = currentType.superclass()) != null);
287                     
288             for (int i = 0; i < nextPosition; i++) {
289                 currentType = interfacesToVisit[i];
290                 if (currentType == otherType || (!currentType.isTypeVariable() && !currentType.isIntersectionType() && currentType.erasure() == otherType))
291                     return currentType;
292
293                 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
294                 if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
295                     int itsLength = itsInterfaces.length;
296                     if (nextPosition + itsLength >= interfacesToVisit.length)
297                         System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
298                     nextInterface : for (int a = 0; a < itsLength; a++) {
299                         ReferenceBinding next = itsInterfaces[a];
300                         for (int b = 0; b < nextPosition; b++)
301                             if (next == interfacesToVisit[b]) continue nextInterface;
302                         interfacesToVisit[nextPosition++] = next;
303                     }
304                 }
305             }
306     }
307     return null;
308 }
309
310 /**
311  * Returns the type to use for generic cast, or null if none required
312  */

313 public TypeBinding genericCast(TypeBinding otherType) {
314     if (this == otherType)
315         return null;
316     TypeBinding otherErasure = otherType.erasure();
317     if (otherErasure == this.erasure())
318         return null;
319     return otherErasure;
320 }
321
322 /**
323  * Answer the receiver classfile signature.
324  * Arrays & base types do not distinguish between signature() & constantPoolName().
325  * NOTE: This method should only be used during/after code gen.
326  */

327 public char[] genericTypeSignature() {
328     return signature();
329 }
330
331 public abstract PackageBinding getPackage();
332
333 public boolean isAnnotationType() {
334     return false;
335 }
336
337 public final boolean isAnonymousType() {
338     return (this.tagBits & TagBits.IsAnonymousType) != 0;
339 }
340
341 /* Answer true if the receiver is an array
342  */

343 public final boolean isArrayType() {
344     return (this.tagBits & TagBits.IsArrayType) != 0;
345 }
346
347 /* Answer true if the receiver is a base type
348  */

349 public final boolean isBaseType() {
350     return (this.tagBits & TagBits.IsBaseType) != 0;
351 }
352
353 /**
354  * Returns true if parameterized type AND not of the form List<?>
355  */

356 public boolean isBoundParameterizedType() {
357     return (this.tagBits & TagBits.IsBoundParameterizedType) != 0;
358 }
359
360 /**
361  * Returns true if the type is the capture of some wildcard
362  */

363 public boolean isCapture() {
364     return false;
365 }
366
367 public boolean isClass() {
368     return false;
369 }
370
371 /* Answer true if the receiver type can be assigned to the argument type (right)
372  */

373 public abstract boolean isCompatibleWith(TypeBinding right);
374
375 public boolean isEnum() {
376     return false;
377 }
378
379 /**
380  * Returns true if a type is identical to another one,
381  * or for generic types, true if compared to its raw type.
382  */

383 public boolean isEquivalentTo(TypeBinding otherType) {
384     if (this == otherType)
385         return true;
386     if (otherType == null)
387         return false;
388     if (otherType.isWildcard()) // wildcard
389
return ((WildcardBinding) otherType).boundCheck(this);
390     return false;
391 }
392
393 public boolean isGenericType() {
394     return false;
395 }
396
397 /* Answer true if the receiver's hierarchy has problems (always false for arrays & base types)
398  */

399 public final boolean isHierarchyInconsistent() {
400     return (this.tagBits & TagBits.HierarchyHasProblems) != 0;
401 }
402
403 public boolean isInterface() {
404     return false;
405 }
406
407 /**
408  * Returns true if a type is intersecting with another one,
409  */

410 public boolean isIntersectingWith(TypeBinding otherType) {
411     return this == otherType;
412 }
413
414 /**
415  * Returns true if the current type denotes an intersection type: Number & Comparable<?>
416  */

417 public boolean isIntersectionType() {
418     return false;
419 }
420
421 public final boolean isLocalType() {
422     return (this.tagBits & TagBits.IsLocalType) != 0;
423 }
424
425 public final boolean isMemberType() {
426     return (this.tagBits & TagBits.IsMemberType) != 0;
427 }
428
429 public final boolean isNestedType() {
430     return (this.tagBits & TagBits.IsNestedType) != 0;
431 }
432
433 public final boolean isNumericType() {
434     switch (id) {
435     case TypeIds.T_int:
436     case TypeIds.T_float:
437     case TypeIds.T_double:
438     case TypeIds.T_short:
439     case TypeIds.T_byte:
440     case TypeIds.T_long:
441     case TypeIds.T_char:
442         return true;
443     default:
444         return false;
445     }
446 }
447
448 /**
449  * Returns true if the type is parameterized, e.g. List<String>
450  */

451 public boolean isParameterizedType() {
452     return false;
453 }
454
455 /**
456  * Returns true if the type is parameterized using its own type variables as arguments
457  */

458 public boolean isParameterizedWithOwnVariables() {
459     if (this.kind() != Binding.PARAMETERIZED_TYPE)
460         return false;
461     ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
462     if (paramType.arguments == null)
463         return false;
464     TypeVariableBinding[] variables = this.erasure().typeVariables();
465     for (int i = 0, length = variables.length; i < length; i++) {
466         if (variables[i] != paramType.arguments[i])
467             return false;
468     }
469     ReferenceBinding enclosing = paramType.enclosingType();
470     if (enclosing != null && enclosing.erasure().isGenericType()
471             && !enclosing.isParameterizedWithOwnVariables()) {
472         return false;
473     }
474     return true;
475 }
476
477 /**
478  * Returns true if the two types are statically known to be different at compile-time,
479  * e.g. a type variable is not provably known to be distinct from another type
480  */

481 public boolean isProvablyDistinctFrom(TypeBinding otherType, int depth) {
482     if (this == otherType)
483         return false;
484     if (depth > 1)
485         return true;
486     switch (otherType.kind()) {
487         case Binding.TYPE_PARAMETER:
488         case Binding.WILDCARD_TYPE:
489             return false;
490     }
491     switch (kind()) {
492     case Binding.TYPE_PARAMETER:
493     case Binding.WILDCARD_TYPE:
494         return false;
495
496     case Binding.PARAMETERIZED_TYPE:
497         ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) this;
498         if (parameterizedType.genericType().isProvablyDistinctFrom(otherType.erasure(), depth))
499             return true;
500         switch (otherType.kind()) {
501         case Binding.GENERIC_TYPE:
502         case Binding.RAW_TYPE:
503             return false;
504         case Binding.PARAMETERIZED_TYPE:
505             TypeBinding[] arguments = parameterizedType.arguments;
506             if (arguments == null)
507                 return false;
508             ParameterizedTypeBinding otherParameterizedType = (ParameterizedTypeBinding) otherType;
509             TypeBinding[] otherArguments = otherParameterizedType.arguments;
510             if (otherArguments == null)
511                 return false;
512             for (int i = 0, length = arguments.length; i < length; i++) {
513                 if (arguments[i].isProvablyDistinctFrom(otherArguments[i], depth + 1))
514                     return true;
515             }
516             return false;
517
518         }
519         break;
520
521     case Binding.RAW_TYPE:
522         if (depth > 0) return true;
523         return this.erasure().isProvablyDistinctFrom(otherType.erasure(), 0);
524
525     case Binding.GENERIC_TYPE:
526         if (depth > 0) return true;
527         return this != otherType.erasure();
528     }
529     return this != otherType;
530 }
531
532 public boolean isRawType() {
533     return false;
534 }
535
536 /**
537  * JLS(3) 4.7.
538  * Note: Foo<?>.Bar is also reifiable
539  */

540 public boolean isReifiable() {
541
542     TypeBinding leafType = leafComponentType();
543     if (!(leafType instanceof ReferenceBinding))
544         return true;
545     ReferenceBinding current = (ReferenceBinding) leafType;
546     do {
547         switch (current.kind()) {
548
549         case Binding.TYPE_PARAMETER:
550         case Binding.WILDCARD_TYPE:
551         case Binding.GENERIC_TYPE:
552             return false;
553
554         case Binding.PARAMETERIZED_TYPE:
555             if (current.isBoundParameterizedType())
556                 return false;
557             break;
558
559         case Binding.RAW_TYPE:
560             return true;
561         }
562         if (current.isStatic())
563             return true;
564         if (current.isLocalType()) {
565             NestedTypeBinding nestedType = (NestedTypeBinding) current.erasure();
566             if (nestedType.scope.methodScope().isStatic) return true;
567         }
568     } while ((current = current.enclosingType()) != null);
569     return true;
570 }
571 /**
572  * Returns true if a given type may be thrown
573  */

574 public boolean isThrowable() {
575     return false;
576 }
577
578 // JLS3: 4.5.1.1
579
public boolean isTypeArgumentContainedBy(TypeBinding otherType) {
580     if (this == otherType)
581         return true;
582     switch (otherType.kind()) {
583     // allow wildcard containment
584
case Binding.WILDCARD_TYPE:
585         TypeBinding lowerBound = this;
586         TypeBinding upperBound = this;
587         switch (this.kind()) {
588         case Binding.WILDCARD_TYPE:
589             WildcardBinding wildcard = (WildcardBinding) this;
590             switch (wildcard.boundKind) {
591             case Wildcard.EXTENDS:
592                 if (wildcard.otherBounds != null) // intersection type
593
break;
594                 upperBound = wildcard.bound;
595                 lowerBound = null;
596                 break;
597             case Wildcard.SUPER:
598                 upperBound = wildcard;
599                 lowerBound = wildcard.bound;
600                 break;
601             case Wildcard.UNBOUND:
602                 upperBound = wildcard;
603                 lowerBound = null;
604             }
605             break;
606         case Binding.TYPE_PARAMETER:
607             if (this.isCapture()) {
608                 CaptureBinding capture = (CaptureBinding) this;
609                 if (capture.lowerBound != null)
610                     lowerBound = capture.lowerBound;
611             }
612         }
613         WildcardBinding otherWildcard = (WildcardBinding) otherType;
614         if (otherWildcard.otherBounds != null)
615             return false; // not a true wildcard (intersection type)
616
TypeBinding otherBound = otherWildcard.bound;
617         switch (otherWildcard.boundKind) {
618         case Wildcard.EXTENDS:
619             if (otherBound == this)
620                 return true; // ? extends T <= ? extends ? extends T
621
if (upperBound == null)
622                 return false;
623             TypeBinding match = upperBound.findSuperTypeWithSameErasure(otherBound);
624             if (match != null && (match = match.leafComponentType()).isRawType()) {
625                 return match == otherBound.leafComponentType(); // forbide: Collection <= ? extends Collection<?>
626
// forbide: Collection[] <= ? extends Collection<?>[]
627
}
628             return upperBound.isCompatibleWith(otherBound);
629
630         case Wildcard.SUPER:
631             if (otherBound == this)
632                 return true; // ? super T <= ? super ? super T
633
if (lowerBound == null)
634                 return false;
635             match = otherBound.findSuperTypeWithSameErasure(lowerBound);
636             if (match != null && (match = match.leafComponentType()).isRawType()) {
637                 return match == lowerBound.leafComponentType(); // forbide: Collection <= ? super Collection<?>
638
// forbide: Collection[] <= ? super Collection<?>[]
639
}
640             return otherBound.isCompatibleWith(lowerBound);
641
642         case Wildcard.UNBOUND:
643         default:
644             return true;
645         }
646         // allow List<?> to match List<? extends Object> (and reciprocally)
647
case Binding.PARAMETERIZED_TYPE:
648         if (!this.isParameterizedType())
649             return false;
650         ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
651         ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
652         if (paramType.actualType() != otherParamType.actualType())
653             return false;
654         if (!paramType.isStatic()) { // static member types do not compare their enclosing
655
ReferenceBinding enclosing = enclosingType();
656             if (enclosing != null) {
657                 ReferenceBinding otherEnclosing = otherParamType
658                         .enclosingType();
659                 if (otherEnclosing == null)
660                     return false;
661                 if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
662                     if (enclosing != otherEnclosing)
663                         return false;
664                 } else {
665                     if (!enclosing.isEquivalentTo(otherParamType
666                             .enclosingType()))
667                         return false;
668                 }
669             }
670         }
671         int length = paramType.arguments == null ? 0
672                 : paramType.arguments.length;
673         TypeBinding[] otherArguments = otherParamType.arguments;
674         int otherLength = otherArguments == null ? 0
675                 : otherArguments.length;
676         if (otherLength != length)
677             return false;
678         nextArgument: for (int i = 0; i < length; i++) {
679             TypeBinding argument = paramType.arguments[i];
680             TypeBinding otherArgument = otherArguments[i];
681             if (argument == otherArgument)
682                 continue nextArgument;
683             int kind = argument.kind();
684             if (otherArgument.kind() != kind)
685                 return false;
686             switch (kind) {
687             case Binding.PARAMETERIZED_TYPE:
688                 if (argument.isTypeArgumentContainedBy(otherArgument)) // recurse
689
continue nextArgument;
690                 break;
691             case Binding.WILDCARD_TYPE:
692                 WildcardBinding wildcard = (WildcardBinding) argument;
693                 otherWildcard = (WildcardBinding) otherArgument;
694                 switch (wildcard.boundKind) {
695                 case Wildcard.EXTENDS:
696                     // match "? extends <upperBound>" with "?"
697
if (otherWildcard.boundKind == Wildcard.UNBOUND
698                             && wildcard.bound == wildcard.typeVariable()
699                                     .upperBound())
700                         continue nextArgument;
701                     break;
702                 case Wildcard.SUPER:
703                     break;
704                 case Wildcard.UNBOUND:
705                     // match "?" with "? extends <upperBound>"
706
if (otherWildcard.boundKind == Wildcard.EXTENDS
707                             && otherWildcard.bound == otherWildcard
708                                     .typeVariable().upperBound())
709                         continue nextArgument;
710                     break;
711                 }
712                 break;
713             }
714             return false;
715         }
716         return true;
717     }
718     return false;
719 }
720
721 /**
722  * Returns false if two given types could not intersect as argument types:
723  * List<Throwable> & List<Runnable> --> false
724  * List<? extends Throwable> & List<? extends Runnable> --> true
725  * List<? extends String> & List<? extends Runnable> --> false
726  */

727 public boolean isTypeArgumentIntersecting(TypeBinding otherArgument) {
728     if (this == otherArgument)
729         return true;
730     switch (kind()) {
731
732     // TYPE_PARAM & ANY TYPE
733
case Binding.TYPE_PARAMETER:
734         return true;
735
736     case Binding.WILDCARD_TYPE:
737         switch (otherArgument.kind()) {
738
739         // WILDCARD & TYPE_PARAM
740
case Binding.TYPE_PARAMETER:
741             return true;
742
743             // WILDCARD & WILDCARD
744
case Binding.WILDCARD_TYPE:
745             TypeBinding lowerBound1 = null;
746             TypeBinding upperBound1 = null;
747             WildcardBinding wildcard = (WildcardBinding) this;
748             switch (wildcard.boundKind) {
749             case Wildcard.EXTENDS:
750                 upperBound1 = wildcard.bound;
751                 break;
752             case Wildcard.SUPER:
753                 lowerBound1 = wildcard.bound;
754                 break;
755             case Wildcard.UNBOUND:
756             }
757
758             TypeBinding lowerBound2 = null;
759             TypeBinding upperBound2 = null;
760             WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
761             switch (otherWildcard.boundKind) {
762             case Wildcard.EXTENDS:
763                 upperBound2 = otherWildcard.bound;
764                 break;
765             case Wildcard.SUPER:
766                 lowerBound2 = otherWildcard.bound;
767                 break;
768             case Wildcard.UNBOUND:
769             }
770             if (lowerBound1 != null) {
771                 if (lowerBound2 != null) {
772                     return true; // Object could always be a candidate
773

774                 } else if (upperBound2 != null) {
775                     return lowerBound1.isCompatibleWith(upperBound2);
776                 } else {
777                     return true;
778                 }
779             } else if (upperBound1 != null) {
780                 if (upperBound1.isTypeVariable())
781                     return true;
782                 if (lowerBound2 != null) {
783                     return lowerBound2.isCompatibleWith(upperBound1);
784
785                 } else if (upperBound2 != null) {
786                     if (upperBound1.isInterface()) {
787                         if (upperBound2.isInterface())
788                             return true;
789                         if (upperBound2.isArrayType()
790                                 || ((upperBound2 instanceof ReferenceBinding) && ((ReferenceBinding) upperBound2)
791                                         .isFinal())) {
792                             return upperBound2
793                                     .isCompatibleWith(upperBound1);
794                         }
795                         return true;
796                     } else {
797                         if (upperBound2.isInterface()) {
798                             if (upperBound1.isArrayType()
799                                     || ((upperBound1 instanceof ReferenceBinding) && ((ReferenceBinding) upperBound1)
800                                             .isFinal())) {
801                                 return upperBound1
802                                         .isCompatibleWith(upperBound2);
803                             }
804                         } else {
805                             return upperBound1
806                                     .isCompatibleWith(upperBound2);
807                         }
808                     }
809                     return true;
810                 } else {
811                     return true;
812                 }
813             } else {
814                 return true;
815             }
816
817             // WILDCARD & OTHER TYPE
818
default:
819             wildcard = (WildcardBinding) this;
820             switch (wildcard.boundKind) {
821             case Wildcard.EXTENDS:
822                 return otherArgument.isCompatibleWith(wildcard.bound);
823             case Wildcard.SUPER:
824                 return wildcard.bound.isCompatibleWith(otherArgument);
825             case Wildcard.UNBOUND:
826             default:
827                 return true;
828             }
829         }
830
831     default:
832         switch (otherArgument.kind()) {
833
834         // OTHER TYPE & TYPE_PARAM
835
case Binding.TYPE_PARAMETER:
836             return true;
837
838             // OTHER TYPE & WILDCARD
839
case Binding.WILDCARD_TYPE:
840             WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
841             switch (otherWildcard.boundKind) {
842             case Wildcard.EXTENDS:
843                 return this.isCompatibleWith(otherWildcard.bound);
844             case Wildcard.SUPER:
845                 return otherWildcard.bound.isCompatibleWith(this);
846             case Wildcard.UNBOUND:
847             default:
848                 return true;
849             }
850
851             // OTHER TYPE & OTHER TYPE
852
default:
853             return false;
854         }
855     }
856 }
857
858 /**
859  * Returns true if the type was declared as a type variable
860  */

861 public boolean isTypeVariable() {
862     return false;
863 }
864
865 /**
866  * Returns true if wildcard type of the form '?' (no bound)
867  */

868 public boolean isUnboundWildcard() {
869     return false;
870 }
871
872 /**
873  * Returns true if the type is a subclass of java.lang.Error or java.lang.RuntimeException
874  */

875 public boolean isUncheckedException(boolean includeSupertype) {
876     return false;
877 }
878
879 /**
880  * Returns true if the type is a wildcard
881  */

882 public boolean isWildcard() {
883     return false;
884 }
885
886 /* API
887  * Answer the receiver's binding type from Binding.BindingID.
888  */

889 public int kind() {
890     return Binding.TYPE;
891 }
892
893 public TypeBinding leafComponentType() {
894     return this;
895 }
896
897 /**
898  * Meant to be invoked on compatible types, to figure if unchecked conversion is necessary
899  */

900 public boolean needsUncheckedConversion(TypeBinding targetType) {
901
902     if (this == targetType)
903         return false;
904     targetType = targetType.leafComponentType();
905     if (!(targetType instanceof ReferenceBinding))
906         return false;
907
908     TypeBinding currentType = this.leafComponentType();
909     TypeBinding match = currentType.findSuperTypeWithSameErasure(targetType);
910     if (!(match instanceof ReferenceBinding))
911         return false;
912     ReferenceBinding compatible = (ReferenceBinding) match;
913     while (compatible.isRawType()) {
914         if (targetType.isBoundParameterizedType())
915             return true;
916         if (compatible.isStatic())
917             break;
918         if ((compatible = compatible.enclosingType()) == null)
919             break;
920         if ((targetType = targetType.enclosingType()) == null)
921             break;
922     }
923     return false;
924 }
925
926 /**
927  * Answer the qualified name of the receiver's package separated by periods
928  * or an empty string if its the default package.
929  *
930  * For example, {java.util}.
931  */

932
933 public char[] qualifiedPackageName() {
934     PackageBinding packageBinding = getPackage();
935     return packageBinding == null
936             || packageBinding.compoundName == CharOperation.NO_CHAR_CHAR ? CharOperation.NO_CHAR
937             : packageBinding.readableName();
938 }
939
940 /**
941  * Answer the source name for the type.
942  * In the case of member types, as the qualified name from its top level type.
943  * For example, for a member type N defined inside M & A: "A.M.N".
944  */

945
946 public abstract char[] qualifiedSourceName();
947
948 /**
949  * Answer the receiver classfile signature.
950  * Arrays & base types do not distinguish between signature() & constantPoolName().
951  * NOTE: This method should only be used during/after code gen.
952  */

953 public char[] signature() {
954     return constantPoolName();
955 }
956
957 public abstract char[] sourceName();
958
959 public void swapUnresolved(UnresolvedReferenceBinding unresolvedType,
960         ReferenceBinding resolvedType, LookupEnvironment environment) {
961     // subclasses must override if they wrap another type binding
962
}
963
964 public TypeVariableBinding[] typeVariables() {
965     return Binding.NO_TYPE_VARIABLES;
966 }
967 }
968
Popular Tags