added -J option to preserve unmodified files in preexisting jarfile
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / lookup / ReferenceBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-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.env.IDependent;
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
27 abstract public class ReferenceBinding extends TypeBinding implements IDependent {
28         public char[][] compoundName;
29         public char[] sourceName;
30         public int modifiers;
31         public PackageBinding fPackage;
32
33         char[] fileName;
34         char[] constantPoolName;
35         char[] signature;
36
37 public FieldBinding[] availableFields() {
38         return fields();
39 }
40
41 public MethodBinding[] availableMethods() {
42         return methods();
43 }       
44 /* Answer true if the receiver can be instantiated
45 */
46
47 public boolean canBeInstantiated() {
48         return (this.modifiers & (AccAbstract | AccInterface | AccEnum | AccAnnotation)) == 0;
49 }
50 /* Answer true if the receiver is visible to the invocationPackage.
51 */
52
53 public final boolean canBeSeenBy(PackageBinding invocationPackage) {
54         if (isPublic()) return true;
55         if (isPrivate()) return false;
56
57         // isProtected() or isDefault()
58         return invocationPackage == fPackage;
59 }
60 /* Answer true if the receiver is visible to the receiverType and the invocationType.
61 */
62
63 public final boolean canBeSeenBy(ReferenceBinding receiverType, SourceTypeBinding invocationType) {
64         if (isPublic()) return true;
65
66         if (invocationType == this && invocationType == receiverType) return true;
67
68         if (isProtected()) {
69
70                 // answer true if the invocationType is the declaringClass or they are in the same package
71                 // OR the invocationType is a subclass of the declaringClass
72                 //    AND the invocationType is the invocationType or its subclass
73                 //    OR the type is a static method accessed directly through a type
74                 //    OR previous assertions are true for one of the enclosing type
75                 if (invocationType == this) return true;
76                 if (invocationType.fPackage == fPackage) return true;
77
78                 ReferenceBinding currentType = invocationType;
79                 ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one
80                 if (declaringClass == null) return false; // could be null if incorrect top-level protected type
81                 //int depth = 0;
82                 do {
83                         if (declaringClass == invocationType) return true;
84                         if (declaringClass.isSuperclassOf(currentType)) return true;
85                         //depth++;
86                         currentType = currentType.enclosingType();
87                 } while (currentType != null);
88                 return false;
89         }
90
91         if (isPrivate()) {
92                 // answer true if the receiverType is the receiver or its enclosingType
93                 // AND the invocationType and the receiver have a common enclosingType
94                 receiverCheck: {
95                         if (!(receiverType == this || receiverType == enclosingType())) {
96                                 // special tolerance for type variable direct bounds
97                                 if (receiverType.isTypeVariable()) {
98                                         TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType;
99                                         if (typeVariable.isErasureBoundTo(this.erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure())) {
100                                                 break receiverCheck;
101                                         }
102                                 }
103                                 return false;
104                         }
105                 }
106                 
107                 
108                 if (invocationType != this) {
109                         ReferenceBinding outerInvocationType = invocationType;
110                         ReferenceBinding temp = outerInvocationType.enclosingType();
111                         while (temp != null) {
112                                 outerInvocationType = temp;
113                                 temp = temp.enclosingType();
114                         }
115
116                         ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.erasure();
117                         temp = outerDeclaringClass.enclosingType();
118                         while (temp != null) {
119                                 outerDeclaringClass = temp;
120                                 temp = temp.enclosingType();
121                         }
122                         if (outerInvocationType != outerDeclaringClass) return false;
123                 }
124                 return true;
125         }
126
127         // isDefault()
128         if (invocationType.fPackage != fPackage) return false;
129
130         ReferenceBinding type = receiverType;
131         ReferenceBinding declaringClass = enclosingType() == null ? this : enclosingType();
132         do {
133                 if (declaringClass == type) return true;
134                 if (fPackage != type.fPackage) return false;
135         } while ((type = type.superclass()) != null);
136         return false;
137 }
138 /* 
139  * Answer true if the receiver is visible to the type provided by the scope.
140  */
141
142 public final boolean canBeSeenBy(Scope scope) {
143         
144         if (isPublic()) return true;
145
146         if (scope.kind == Scope.COMPILATION_UNIT_SCOPE){
147                 return this.canBeSeenBy(((CompilationUnitScope)scope).fPackage);
148         }
149         
150         SourceTypeBinding invocationType = scope.enclosingSourceType();
151         if (invocationType == this) return true;
152
153         if (isProtected()) {
154                 // answer true if the invocationType is the declaringClass or they are in the same package
155                 // OR the invocationType is a subclass of the declaringClass
156                 //    AND the invocationType is the invocationType or its subclass
157                 //    OR the type is a static method accessed directly through a type
158                 //    OR previous assertions are true for one of the enclosing type
159                 if (invocationType.fPackage == fPackage) return true;
160
161                 ReferenceBinding currentType = invocationType;
162                 ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one
163                 if (declaringClass == null) return false; // could be null if incorrect top-level protected type
164                 // int depth = 0;
165                 do {
166                         if (declaringClass == invocationType) return true;
167                         if (declaringClass.isSuperclassOf(currentType)) return true;
168                         // depth++;
169                         currentType = currentType.enclosingType();
170                 } while (currentType != null);
171                 return false;
172         }
173         if (isPrivate()) {
174                 // answer true if the receiver and the invocationType have a common enclosingType
175                 // already know they are not the identical type
176                 ReferenceBinding outerInvocationType = invocationType;
177                 ReferenceBinding temp = outerInvocationType.enclosingType();
178                 while (temp != null) {
179                         outerInvocationType = temp;
180                         temp = temp.enclosingType();
181                 }
182
183                 ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.erasure();
184                 temp = outerDeclaringClass.enclosingType();
185                 while (temp != null) {
186                         outerDeclaringClass = temp;
187                         temp = temp.enclosingType();
188                 }
189                 return outerInvocationType == outerDeclaringClass;
190         }
191
192         // isDefault()
193         return invocationType.fPackage == fPackage;
194 }
195 public void computeId() {
196         
197         switch (compoundName.length) {
198
199                 case 3 :
200                         if (!CharOperation.equals(JAVA, compoundName[0]))
201                                 return;
202                 
203                         // remaining types MUST be in java.*.*
204                         if (!CharOperation.equals(LANG, compoundName[1])) {
205                                 if (CharOperation.equals(JAVA_IO_PRINTSTREAM, compoundName))
206                                         id = T_JavaIoPrintStream;
207                                 else if (CharOperation.equals(JAVA_UTIL_ITERATOR, compoundName))
208                                         id = T_JavaUtilIterator;
209                                 else if (CharOperation.equals(JAVA_IO_SERIALIZABLE, compoundName))
210                                     id = T_JavaIoSerializable;
211                                 return;
212                         }
213                 
214                         // remaining types MUST be in java.lang.*
215                         char[] typeName = compoundName[2];
216                         if (typeName.length == 0) return; // just to be safe
217                         switch (typeName[0]) {
218                                 case 'A' :
219                                         if (CharOperation.equals(typeName, JAVA_LANG_ASSERTIONERROR[2]))
220                                                 id = T_JavaLangAssertionError;
221                                         return;
222                                 case 'B' :
223                                         if (CharOperation.equals(typeName, JAVA_LANG_BOOLEAN[2]))
224                                                 id = T_JavaLangBoolean;
225                                         else if (CharOperation.equals(typeName, JAVA_LANG_BYTE[2]))
226                                                 id = T_JavaLangByte;
227                                         return;
228                                 case 'C' :
229                                         if (CharOperation.equals(typeName, JAVA_LANG_CHARACTER[2]))
230                                                 id = T_JavaLangCharacter;
231                                         else if (CharOperation.equals(typeName, JAVA_LANG_CLASS[2]))
232                                                 id = T_JavaLangClass;
233                                         else if (CharOperation.equals(typeName, JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2]))
234                                                 id = T_JavaLangClassNotFoundException;
235                                         else if (CharOperation.equals(typeName, JAVA_LANG_CLONEABLE[2]))
236                                             id = T_JavaLangCloneable;
237                                         return;
238                                 case 'D' :
239                                         if (CharOperation.equals(typeName, JAVA_LANG_DOUBLE[2]))
240                                                 id = T_JavaLangDouble;
241                                         else if (CharOperation.equals(typeName, JAVA_LANG_DEPRECATED[2]))
242                                                 id = T_JavaLangDeprecated;
243                                         return;
244                                 case 'E' :
245                                         if (CharOperation.equals(typeName, JAVA_LANG_ERROR[2]))
246                                                 id = T_JavaLangError;
247                                         else if (CharOperation.equals(typeName, JAVA_LANG_EXCEPTION[2]))
248                                                 id = T_JavaLangException;
249                                         else if (CharOperation.equals(typeName, JAVA_LANG_ENUM[2]))
250                                                 id = T_JavaLangEnum;
251                                         return;
252                                 case 'F' :
253                                         if (CharOperation.equals(typeName, JAVA_LANG_FLOAT[2]))
254                                                 id = T_JavaLangFloat;
255                                         return;
256                                 case 'I' :
257                                         if (CharOperation.equals(typeName, JAVA_LANG_INTEGER[2]))
258                                                 id = T_JavaLangInteger;
259                                         else if (CharOperation.equals(typeName, JAVA_LANG_ITERABLE[2]))
260                                                 id = T_JavaLangIterable;
261                                         else if (CharOperation.equals(typeName, JAVA_LANG_ILLEGALARGUMENTEXCEPTION[2]))
262                                                 id = T_JavaLangIllegalArgumentException;
263                                         return;
264                                 case 'L' :
265                                         if (CharOperation.equals(typeName, JAVA_LANG_LONG[2]))
266                                                 id = T_JavaLangLong;
267                                         return;
268                                 case 'N' :
269                                         if (CharOperation.equals(typeName, JAVA_LANG_NOCLASSDEFERROR[2]))
270                                                 id = T_JavaLangNoClassDefError;
271                                         return;
272                                 case 'O' :
273                                         if (CharOperation.equals(typeName, JAVA_LANG_OBJECT[2]))
274                                                 id = T_JavaLangObject;
275                                         else if (CharOperation.equals(typeName, JAVA_LANG_OVERRIDE[2]))
276                                                 id = T_JavaLangOverride;
277                                         return;
278                                 case 'S' :
279                                         if (CharOperation.equals(typeName, JAVA_LANG_STRING[2]))
280                                                 id = T_JavaLangString;
281                                         else if (CharOperation.equals(typeName, JAVA_LANG_STRINGBUFFER[2]))
282                                                 id = T_JavaLangStringBuffer;
283                                         else if (CharOperation.equals(typeName, JAVA_LANG_STRINGBUILDER[2])) 
284                                                 id = T_JavaLangStringBuilder;
285                                         else if (CharOperation.equals(typeName, JAVA_LANG_SYSTEM[2]))
286                                                 id = T_JavaLangSystem;
287                                         else if (CharOperation.equals(typeName, JAVA_LANG_SHORT[2]))
288                                                 id = T_JavaLangShort;
289                                         else if (CharOperation.equals(typeName, JAVA_LANG_SUPPRESSWARNINGS[2]))
290                                                 id = T_JavaLangSuppressWarnings;
291                                         return;
292                                 case 'T' :
293                                         if (CharOperation.equals(typeName, JAVA_LANG_THROWABLE[2]))
294                                                 id = T_JavaLangThrowable;
295                                         return;
296                                 case 'V' :
297                                         if (CharOperation.equals(typeName, JAVA_LANG_VOID[2]))
298                                                 id = T_JavaLangVoid;
299                                         return;
300                         }
301                 break;
302                         
303                 case 4:
304                         if (!CharOperation.equals(JAVA, compoundName[0]))
305                                 return;
306                         if (!CharOperation.equals(LANG, compoundName[1]))
307                                 return;
308                         char[] packageName = compoundName[2];
309                         if (packageName.length == 0) return; // just to be safe                 
310                         typeName = compoundName[3];
311                         if (typeName.length == 0) return; // just to be safe                    
312                         if (CharOperation.equals(packageName, REFLECT)) {
313                                 if (CharOperation.equals(typeName, JAVA_LANG_REFLECT_CONSTRUCTOR[3]))
314                                         id = T_JavaLangReflectConstructor;
315                                 return;
316                         } else if (CharOperation.equals(packageName, ANNOTATION)) {
317                                 switch (typeName[0]) {
318                                         case 'A' :                      
319                                                 if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_ANNOTATION[3]))
320                                                         id = T_JavaLangAnnotationAnnotation;
321                                                 return;
322                                         case 'D' :
323                                                 if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_DOCUMENTED[3]))
324                                                         id = T_JavaLangAnnotationDocumented;
325                                                 return;
326                                         case 'E' :
327                                                 if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_ELEMENTTYPE[3]))
328                                                         id = T_JavaLangAnnotationElementType;
329                                                 return;
330                                         case 'I' :
331                                                 if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_INHERITED[3]))
332                                                         id = T_JavaLangAnnotationInherited;
333                                                 return;
334                                         case 'R' :
335                                                 if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_RETENTION[3]))
336                                                         id = T_JavaLangAnnotationRetention;
337                                                 else if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_RETENTIONPOLICY[3]))
338                                                         id = T_JavaLangAnnotationRetentionPolicy;
339                                                 return;
340                                         case 'T' :
341                                                 if (CharOperation.equals(typeName, JAVA_LANG_ANNOTATION_TARGET[3]))
342                                                         id = T_JavaLangAnnotationTarget;
343                                                 return;
344                                 }                               
345                         }
346                         break;
347         }
348 }
349 /* Answer the receiver's constant pool name.
350 *
351 * NOTE: This method should only be used during/after code gen.
352 */
353
354 public char[] constantPoolName() /* java/lang/Object */ {
355         if (constantPoolName != null)   return constantPoolName;
356         return constantPoolName = CharOperation.concatWith(compoundName, '/');
357 }
358 public String debugName() {
359         return (compoundName != null) ? new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$
360 }
361 public final int depth() {
362         int depth = 0;
363         ReferenceBinding current = this;
364         while ((current = current.enclosingType()) != null)
365                 depth++;
366         return depth;
367 }
368 public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
369         ReferenceBinding current = this;
370         while (relativeDepth-- > 0 && current != null)
371                 current = current.enclosingType();
372         return current;
373 }
374 public int fieldCount() {
375         return fields().length;
376 }
377 public FieldBinding[] fields() {
378         return NoFields;
379 }
380 /**
381  * Find supertype which erases to a given well-known type, or null if not found
382  * (using id avoids triggering the load of well-known type: 73740)
383  * NOTE: only works for erasures of well-known types, as random other types may share
384  * same id though being distincts.
385  *
386  */
387 public ReferenceBinding findSuperTypeErasingTo(int erasureId, boolean erasureIsClass) {
388
389     if (erasure().id == erasureId) return this;
390     ReferenceBinding currentType = this;
391     // iterate superclass to avoid recording interfaces if searched supertype is class
392     if (erasureIsClass) {
393                 while ((currentType = currentType.superclass()) != null) { 
394                         if (currentType.erasure().id == erasureId) return currentType;
395                 }    
396                 return null;
397     }
398         ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
399         int lastPosition = -1;
400         do {
401                 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
402                 if (itsInterfaces != NoSuperInterfaces) {
403                         if (++lastPosition == interfacesToVisit.length)
404                                 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
405                         interfacesToVisit[lastPosition] = itsInterfaces;
406                 }
407         } while ((currentType = currentType.superclass()) != null);
408                         
409         for (int i = 0; i <= lastPosition; i++) {
410                 ReferenceBinding[] interfaces = interfacesToVisit[i];
411                 for (int j = 0, length = interfaces.length; j < length; j++) {
412                         if ((currentType = interfaces[j]).erasure().id == erasureId)
413                                 return currentType;
414
415                         ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
416                         if (itsInterfaces != NoSuperInterfaces) {
417                                 if (++lastPosition == interfacesToVisit.length)
418                                         System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
419                                 interfacesToVisit[lastPosition] = itsInterfaces;
420                         }
421                 }
422         }
423         return null;
424 }
425 /**
426  * Find supertype which erases to a given type, or null if not found
427  */
428 public ReferenceBinding findSuperTypeErasingTo(ReferenceBinding erasure) {
429
430     if (erasure() == erasure) return this;
431     ReferenceBinding currentType = this;
432     if (erasure.isClass()) {
433                 while ((currentType = currentType.superclass()) != null) {
434                         if (currentType.erasure() == erasure) return currentType;
435                 }
436                 return null;
437     }
438         ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
439         int lastPosition = -1;
440         do {
441                 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
442                 if (itsInterfaces != NoSuperInterfaces) {
443                         if (++lastPosition == interfacesToVisit.length)
444                                 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
445                         interfacesToVisit[lastPosition] = itsInterfaces;
446                 }
447         } while ((currentType = currentType.superclass()) != null);
448                         
449         for (int i = 0; i <= lastPosition; i++) {
450                 ReferenceBinding[] interfaces = interfacesToVisit[i];
451                 for (int j = 0, length = interfaces.length; j < length; j++) {
452                         if ((currentType = interfaces[j]).erasure() == erasure)
453                                 return currentType;
454
455                         ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
456                         if (itsInterfaces != NoSuperInterfaces) {
457                                 if (++lastPosition == interfacesToVisit.length)
458                                         System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
459                                 interfacesToVisit[lastPosition] = itsInterfaces;
460                         }
461                 }
462         }
463         return null;
464 }
465
466 public final int getAccessFlags() {
467         return modifiers & AccJustFlag;
468 }
469 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
470         return null;
471 }
472 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) {
473         return getExactMethod(selector, argumentTypes, null);
474 }
475 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
476         return null;
477 }
478 public FieldBinding getField(char[] fieldName, boolean needResolve) {
479         return null;
480 }
481 /**
482  * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
483  */
484 public char[] getFileName() {
485         return fileName;
486 }
487 public ReferenceBinding getMemberType(char[] typeName) {
488         ReferenceBinding[] memberTypes = memberTypes();
489         for (int i = memberTypes.length; --i >= 0;)
490                 if (CharOperation.equals(memberTypes[i].sourceName, typeName))
491                         return memberTypes[i];
492         return null;
493 }
494 public MethodBinding[] getMethods(char[] selector) {
495         return NoMethods;
496 }
497 public PackageBinding getPackage() {
498         return fPackage;
499 }
500 public boolean hasMemberTypes() {
501     return false;
502 }
503 public TypeVariableBinding getTypeVariable(char[] variableName) {
504         TypeVariableBinding[] typeVariables = typeVariables();
505         for (int i = typeVariables.length; --i >= 0;)
506                 if (CharOperation.equals(typeVariables[i].sourceName, variableName))
507                         return typeVariables[i];
508         return null;
509 }
510 public int hashCode() {
511         // ensure ReferenceBindings hash to the same posiiton as UnresolvedReferenceBindings so they can be replaced without rehashing
512         // ALL ReferenceBindings are unique when created so equals() is the same as ==
513         return (this.compoundName == null || this.compoundName.length == 0)
514                 ? super.hashCode()
515                 : CharOperation.hashCode(this.compoundName[this.compoundName.length - 1]);
516 }
517
518 public final boolean hasRestrictedAccess() {
519         return (modifiers & AccRestrictedAccess) != 0;
520 }
521
522 /* Answer true if the receiver implements anInterface or is identical to anInterface.
523 * If searchHierarchy is true, then also search the receiver's superclasses.
524 *
525 * NOTE: Assume that anInterface is an interface.
526 */
527 public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
528         if (this == anInterface)
529                 return true;
530
531         ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
532         int lastPosition = -1;
533         ReferenceBinding currentType = this;
534         do {
535                 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
536                 if (itsInterfaces != NoSuperInterfaces) {
537                         if (++lastPosition == interfacesToVisit.length)
538                                 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
539                         interfacesToVisit[lastPosition] = itsInterfaces;
540                 }
541         } while (searchHierarchy && (currentType = currentType.superclass()) != null);
542                         
543         for (int i = 0; i <= lastPosition; i++) {
544                 ReferenceBinding[] interfaces = interfacesToVisit[i];
545                 for (int j = 0, length = interfaces.length; j < length; j++) {
546                         if ((currentType = interfaces[j]).isEquivalentTo(anInterface))
547                                 return true;
548
549                         ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
550                         if (itsInterfaces != NoSuperInterfaces) {
551                                 if (++lastPosition == interfacesToVisit.length)
552                                         System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
553                                 interfacesToVisit[lastPosition] = itsInterfaces;
554                         }
555                 }
556         }
557         return false;
558 }
559 // Internal method... assume its only sent to classes NOT interfaces
560
561 boolean implementsMethod(MethodBinding method) {
562         ReferenceBinding type = this;
563         while (type != null) {
564                 MethodBinding[] methods = type.getMethods(method.selector);
565                 for (int i = methods.length; --i >= 0;)
566                         if (methods[i].areParametersEqual(method))
567                                 return true;
568                 type = type.superclass();
569         }
570         return false;
571 }
572 /* Answer true if the receiver is an abstract type
573 */
574
575 public final boolean isAbstract() {
576         return (modifiers & AccAbstract) != 0;
577 }
578 public boolean isAnnotationType() {
579         return (modifiers & AccAnnotation) != 0;
580 }
581 public final boolean isAnonymousType() {
582         return (tagBits & IsAnonymousType) != 0;
583 }
584 public final boolean isBinaryBinding() {
585         return (tagBits & IsBinaryBinding) != 0;
586 }
587 public boolean isClass() {
588         return (modifiers & (AccInterface | AccAnnotation | AccEnum)) == 0;
589 }
590 /*
591  * Returns true if the type hierarchy is being connected
592  */
593 public boolean isHierarchyBeingConnected() {
594         return (this.tagBits & EndHierarchyCheck) == 0 && (this.tagBits & BeginHierarchyCheck) != 0;
595 }
596 /* Answer true if the receiver type can be assigned to the argument type (right)
597 */
598 public boolean isCompatibleWith(TypeBinding otherType) {
599     
600         if (otherType == this)
601                 return true;
602         if (otherType.id == T_JavaLangObject)
603                 return true;
604         if (!(otherType instanceof ReferenceBinding))
605                 return false;
606         ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
607         if (this.isEquivalentTo(otherReferenceType)) return true;
608         if (otherReferenceType.isWildcard()) {
609                 return false; // should have passed equivalence check above if wildcard
610         }
611         if (otherReferenceType.isInterface())
612                 return implementsInterface(otherReferenceType, true);
613         if (isInterface())  // Explicit conversion from an interface to a class is not allowed
614                 return false;
615         return otherReferenceType.isSuperclassOf(this);
616 }
617
618 /* Answer true if the receiver has default visibility
619 */
620 public final boolean isDefault() {
621         return (modifiers & (AccPublic | AccProtected | AccPrivate)) == 0;
622 }
623
624 /* Answer true if the receiver is a deprecated type
625 */
626 public final boolean isDeprecated() {
627         return (modifiers & AccDeprecated) != 0;
628 }
629 public boolean isEnum() {
630         return (modifiers & AccEnum) != 0;
631 }
632 /* Answer true if the receiver is final and cannot be subclassed
633 */
634 public final boolean isFinal() {
635         return (modifiers & AccFinal) != 0;
636 }
637 public boolean isInterface() {
638         // only consider strict interfaces
639         return (modifiers & (AccInterface | AccAnnotation)) == AccInterface;
640 }
641
642 /* Answer true if the receiver has private visibility
643 */
644 public final boolean isPrivate() {
645         return (modifiers & AccPrivate) != 0;
646 }
647 /* Answer true if the receiver has private visibility and is used locally
648 */
649
650 public final boolean isPrivateUsed() {
651         return (modifiers & AccPrivateUsed) != 0;
652 }
653 /* Answer true if the receiver has protected visibility
654 */
655
656 public final boolean isProtected() {
657         return (modifiers & AccProtected) != 0;
658 }
659 /* Answer true if the receiver has public visibility
660 */
661
662 public final boolean isPublic() {
663         return (modifiers & AccPublic) != 0;
664 }
665 /* Answer true if the receiver is a static member type (or toplevel)
666  */
667
668 public final boolean isStatic() {
669         return (modifiers & (AccStatic | AccInterface)) != 0 ||
670                     (tagBits & IsNestedType) == 0;
671 }
672 /* Answer true if all float operations must adher to IEEE 754 float/double rules
673 */
674
675 public final boolean isStrictfp() {
676         return (modifiers & AccStrictfp) != 0;
677 }
678 /* Answer true if the receiver is in the superclass hierarchy of aType
679 *
680 * NOTE: Object.isSuperclassOf(Object) -> false
681 */
682
683 public boolean isSuperclassOf(ReferenceBinding otherType) {
684         while ((otherType = otherType.superclass()) != null) {
685                 if (otherType.isEquivalentTo(this)) return true;
686         }
687         return false;
688 }
689
690 /* Answer true if the receiver is deprecated (or any of its enclosing types)
691 */
692
693 public final boolean isViewedAsDeprecated() {
694         return (modifiers & AccDeprecated) != 0 ||
695                 (modifiers & AccDeprecatedImplicitly) != 0;
696 }
697 public ReferenceBinding[] memberTypes() {
698         return NoMemberTypes;
699 }
700
701 /**
702  * Meant to be invoked on compatible types, to figure if unchecked conversion is necessary
703  */
704 public boolean needsUncheckedConversion(TypeBinding targetType) {
705         if (this == targetType) return false;
706         if (!this.isPartOfRawType()) return false;
707         if (!(targetType instanceof ReferenceBinding)) 
708                 return false;
709         TypeBinding compatible = this.findSuperTypeErasingTo((ReferenceBinding)targetType.erasure());
710         if (compatible == null) 
711                 return false;
712         do {
713                 if (compatible.isRawType() && (targetType.isBoundParameterizedType() || targetType.isGenericType())) {
714                         return true;
715                 }
716         } while ((compatible = compatible.enclosingType()) != null && (targetType = targetType.enclosingType()) != null);
717         return false;
718 }
719
720 public MethodBinding[] methods() {
721         return NoMethods;
722 }
723 /**
724 * Answer the source name for the type.
725 * In the case of member types, as the qualified name from its top level type.
726 * For example, for a member type N defined inside M & A: "A.M.N".
727 */
728
729 public char[] qualifiedSourceName() {
730         if (isMemberType())
731                 return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
732         return sourceName();
733 }
734
735 public char[] readableName() /*java.lang.Object,  p.X<T> */ {
736     char[] readableName;
737         if (isMemberType()) {
738                 readableName = CharOperation.concat(enclosingType().readableName(), sourceName, '.');
739         } else {
740                 readableName = CharOperation.concatWith(compoundName, '.');
741         }
742         TypeVariableBinding[] typeVars;
743         if ((typeVars = this.typeVariables()) != NoTypeVariables) {
744             StringBuffer nameBuffer = new StringBuffer(10);
745             nameBuffer.append(readableName).append('<');
746             for (int i = 0, length = typeVars.length; i < length; i++) {
747                 if (i > 0) nameBuffer.append(',');
748                 nameBuffer.append(typeVars[i].readableName());
749             }
750             nameBuffer.append('>');
751                 int nameLength = nameBuffer.length();
752                 readableName = new char[nameLength];
753                 nameBuffer.getChars(0, nameLength, readableName, 0);  
754         }
755         return readableName;
756 }
757
758 public char[] shortReadableName() /*Object*/ {
759     char[] shortReadableName;
760         if (isMemberType()) {
761                 shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
762         } else {
763                 shortReadableName = this.sourceName;
764         }
765         TypeVariableBinding[] typeVars;
766         if ((typeVars = this.typeVariables()) != NoTypeVariables) {
767             StringBuffer nameBuffer = new StringBuffer(10);
768             nameBuffer.append(shortReadableName).append('<');
769             for (int i = 0, length = typeVars.length; i < length; i++) {
770                 if (i > 0) nameBuffer.append(',');
771                 nameBuffer.append(typeVars[i].shortReadableName());
772             }
773             nameBuffer.append('>');
774                 int nameLength = nameBuffer.length();
775                 shortReadableName = new char[nameLength];
776                 nameBuffer.getChars(0, nameLength, shortReadableName, 0);           
777         }
778         return shortReadableName;
779 }
780
781 /* Answer the receiver's signature.
782 *
783 * NOTE: This method should only be used during/after code gen.
784 */
785
786 public char[] signature() /* Ljava/lang/Object; */ {
787         if (signature != null)
788                 return signature;
789
790         return signature = CharOperation.concat('L', constantPoolName(), ';');
791 }
792 public char[] sourceName() {
793         return sourceName;
794 }
795
796 public ReferenceBinding superclass() {
797         return null;
798 }
799 public ReferenceBinding[] superInterfaces() {
800         return NoSuperInterfaces;
801 }
802 public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
803         if (isStatic()) return null;
804
805         ReferenceBinding enclosingType = enclosingType();
806         if (enclosingType == null)
807                 return null;
808         return new ReferenceBinding[] {enclosingType};
809 }
810 public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
811         return null;            // is null if no enclosing instances are required
812 }
813
814 MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
815         return methods();
816 }
817 }