Makefile fixup
[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 !(isAbstract() || isInterface());
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                 if (!(receiverType == this || receiverType == enclosingType())) return false;
95                 
96                 if (invocationType != this) {
97                         ReferenceBinding outerInvocationType = invocationType;
98                         ReferenceBinding temp = outerInvocationType.enclosingType();
99                         while (temp != null) {
100                                 outerInvocationType = temp;
101                                 temp = temp.enclosingType();
102                         }
103
104                         ReferenceBinding outerDeclaringClass = this;
105                         temp = outerDeclaringClass.enclosingType();
106                         while (temp != null) {
107                                 outerDeclaringClass = temp;
108                                 temp = temp.enclosingType();
109                         }
110                         if (outerInvocationType != outerDeclaringClass) return false;
111                 }
112                 return true;
113         }
114
115         // isDefault()
116         if (invocationType.fPackage != fPackage) return false;
117
118         ReferenceBinding type = receiverType;
119         ReferenceBinding declaringClass = enclosingType() == null ? this : enclosingType();
120         do {
121                 if (declaringClass == type) return true;
122                 if (fPackage != type.fPackage) return false;
123         } while ((type = type.superclass()) != null);
124         return false;
125 }
126 /* 
127  * Answer true if the receiver is visible to the type provided by the scope.
128  */
129
130 public final boolean canBeSeenBy(Scope scope) {
131         
132         if (isPublic()) return true;
133
134         if (scope.kind == Scope.COMPILATION_UNIT_SCOPE){
135                 return this.canBeSeenBy(((CompilationUnitScope)scope).fPackage);
136         }
137         
138         SourceTypeBinding invocationType = scope.enclosingSourceType();
139         if (invocationType == this) return true;
140
141         if (isProtected()) {
142                 // answer true if the invocationType is the declaringClass or they are in the same package
143                 // OR the invocationType is a subclass of the declaringClass
144                 //    AND the invocationType is the invocationType or its subclass
145                 //    OR the type is a static method accessed directly through a type
146                 //    OR previous assertions are true for one of the enclosing type
147                 if (invocationType.fPackage == fPackage) return true;
148
149                 ReferenceBinding currentType = invocationType;
150                 ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one
151                 if (declaringClass == null) return false; // could be null if incorrect top-level protected type
152                 // int depth = 0;
153                 do {
154                         if (declaringClass == invocationType) return true;
155                         if (declaringClass.isSuperclassOf(currentType)) return true;
156                         // depth++;
157                         currentType = currentType.enclosingType();
158                 } while (currentType != null);
159                 return false;
160         }
161         if (isPrivate()) {
162                 // answer true if the receiver and the invocationType have a common enclosingType
163                 // already know they are not the identical type
164                 ReferenceBinding outerInvocationType = invocationType;
165                 ReferenceBinding temp = outerInvocationType.enclosingType();
166                 while (temp != null) {
167                         outerInvocationType = temp;
168                         temp = temp.enclosingType();
169                 }
170
171                 ReferenceBinding outerDeclaringClass = this;
172                 temp = outerDeclaringClass.enclosingType();
173                 while (temp != null) {
174                         outerDeclaringClass = temp;
175                         temp = temp.enclosingType();
176                 }
177                 return outerInvocationType == outerDeclaringClass;
178         }
179
180         // isDefault()
181         return invocationType.fPackage == fPackage;
182 }
183 public void computeId() {
184         if (compoundName.length != 3) {
185                 if (compoundName.length == 4 && CharOperation.equals(JAVA_LANG_REFLECT_CONSTRUCTOR, compoundName))
186                         id = T_JavaLangReflectConstructor;
187                 return;
188         }
189
190         if (!CharOperation.equals(JAVA, compoundName[0]))
191                 return;
192
193         // remaining types MUST be in java.*.*
194         if (!CharOperation.equals(LANG, compoundName[1])) {
195                 if (CharOperation.equals(JAVA_IO_PRINTSTREAM, compoundName))
196                         id = T_JavaIoPrintStream;
197                 else if (CharOperation.equals(JAVA_IO_SERIALIZABLE, compoundName))
198                     id = T_JavaIoSerializable;
199                 return;
200         }
201
202         // remaining types MUST be in java.lang.*
203         char[] typeName = compoundName[2];
204         if (typeName.length == 0) return; // just to be safe
205         switch (typeName[0]) {
206                 case 'A' :
207                         if (CharOperation.equals(typeName, JAVA_LANG_ASSERTIONERROR[2]))
208                                 id = T_JavaLangAssertionError;
209                         return;
210                 case 'B' :
211                         if (CharOperation.equals(typeName, JAVA_LANG_BOOLEAN[2]))
212                                 id = T_JavaLangBoolean;
213                         else if (CharOperation.equals(typeName, JAVA_LANG_BYTE[2]))
214                                 id = T_JavaLangByte;
215                         return;
216                 case 'C' :
217                         if (CharOperation.equals(typeName, JAVA_LANG_CHARACTER[2]))
218                                 id = T_JavaLangCharacter;
219                         else if (CharOperation.equals(typeName, JAVA_LANG_CLASS[2]))
220                                 id = T_JavaLangClass;
221                         else if (CharOperation.equals(typeName, JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2]))
222                                 id = T_JavaLangClassNotFoundException;
223                         else if (CharOperation.equals(typeName, JAVA_LANG_CLONEABLE[2]))
224                             id = T_JavaLangCloneable;
225                         return;
226                 case 'D' :
227                         if (CharOperation.equals(typeName, JAVA_LANG_DOUBLE[2]))
228                                 id = T_JavaLangDouble;
229                         return;
230                 case 'E' :
231                         if (CharOperation.equals(typeName, JAVA_LANG_ERROR[2]))
232                                 id = T_JavaLangError;
233                         else if (CharOperation.equals(typeName, JAVA_LANG_EXCEPTION[2]))
234                                 id = T_JavaLangException;
235                         return;
236                 case 'F' :
237                         if (CharOperation.equals(typeName, JAVA_LANG_FLOAT[2]))
238                                 id = T_JavaLangFloat;
239                         return;
240                 case 'I' :
241                         if (CharOperation.equals(typeName, JAVA_LANG_INTEGER[2]))
242                                 id = T_JavaLangInteger;
243                         return;
244                 case 'L' :
245                         if (CharOperation.equals(typeName, JAVA_LANG_LONG[2]))
246                                 id = T_JavaLangLong;
247                         return;
248                 case 'N' :
249                         if (CharOperation.equals(typeName, JAVA_LANG_NOCLASSDEFERROR[2]))
250                                 id = T_JavaLangNoClassDefError;
251                         return;
252                 case 'O' :
253                         if (CharOperation.equals(typeName, JAVA_LANG_OBJECT[2]))
254                                 id = T_JavaLangObject;
255                         return;
256                 case 'S' :
257                         if (CharOperation.equals(typeName, JAVA_LANG_STRING[2]))
258                                 id = T_JavaLangString;
259                         else if (CharOperation.equals(typeName, JAVA_LANG_STRINGBUFFER[2]))
260                                 id = T_JavaLangStringBuffer;
261                         else if (CharOperation.equals(typeName, JAVA_LANG_SYSTEM[2]))
262                                 id = T_JavaLangSystem;
263                         else if (CharOperation.equals(typeName, JAVA_LANG_SHORT[2]))
264                                 id = T_JavaLangShort;
265                         return;
266                 case 'T' :
267                         if (CharOperation.equals(typeName, JAVA_LANG_THROWABLE[2]))
268                                 id = T_JavaLangThrowable;
269                         return;
270                 case 'V' :
271                         if (CharOperation.equals(typeName, JAVA_LANG_VOID[2]))
272                                 id = T_JavaLangVoid;
273                         return;
274         }
275 }
276 /* Answer the receiver's constant pool name.
277 *
278 * NOTE: This method should only be used during/after code gen.
279 */
280
281 public char[] constantPoolName() /* java/lang/Object */ {
282         if (constantPoolName != null)   return constantPoolName;
283         return constantPoolName = CharOperation.concatWith(compoundName, '/');
284 }
285 String debugName() {
286         return (compoundName != null) ? new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$
287 }
288 public final int depth() {
289         int depth = 0;
290         ReferenceBinding current = this;
291         while ((current = current.enclosingType()) != null)
292                 depth++;
293         return depth;
294 }
295 /* Answer the receiver's enclosing type... null if the receiver is a top level type.
296 */
297
298 public ReferenceBinding enclosingType() {
299         return null;
300 }
301 public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
302         ReferenceBinding current = this;
303         while (relativeDepth-- > 0 && current != null)
304                 current = current.enclosingType();
305         return current;
306 }
307 public int fieldCount() {
308         return fields().length;
309 }
310 public FieldBinding[] fields() {
311         return NoFields;
312 }
313 public final int getAccessFlags() {
314         return modifiers & AccJustFlag;
315 }
316 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
317         return null;
318 }
319 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) {
320         return null;
321 }
322 public FieldBinding getField(char[] fieldName, boolean needResolve) {
323         return null;
324 }
325 /**
326  * Answer the file name which defines the type.
327  *
328  * The path part (optional) must be separated from the actual
329  * file proper name by a java.io.File.separator.
330  *
331  * The proper file name includes the suffix extension (e.g. ".java")
332  *
333  * e.g. "c:/com/ibm/compiler/java/api/Compiler.java" 
334  */
335
336 public char[] getFileName() {
337         return fileName;
338 }
339 public ReferenceBinding getMemberType(char[] typeName) {
340         ReferenceBinding[] memberTypes = memberTypes();
341         for (int i = memberTypes.length; --i >= 0;)
342                 if (CharOperation.equals(memberTypes[i].sourceName, typeName))
343                         return memberTypes[i];
344         return null;
345 }
346 public MethodBinding[] getMethods(char[] selector) {
347         return NoMethods;
348 }
349 public PackageBinding getPackage() {
350         return fPackage;
351 }
352 public boolean hasMemberTypes() {
353     return false;
354 }
355 /* Answer true if the receiver implements anInterface or is identical to anInterface.
356 * If searchHierarchy is true, then also search the receiver's superclasses.
357 *
358 * NOTE: Assume that anInterface is an interface.
359 */
360
361 public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
362         if (this == anInterface)
363                 return true;
364
365         ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
366         int lastPosition = -1;
367         ReferenceBinding currentType = this;
368         do {
369                 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
370                 if (itsInterfaces != NoSuperInterfaces) {
371                         if (++lastPosition == interfacesToVisit.length)
372                                 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
373                         interfacesToVisit[lastPosition] = itsInterfaces;
374                 }
375         } while (searchHierarchy && (currentType = currentType.superclass()) != null);
376                         
377         for (int i = 0; i <= lastPosition; i++) {
378                 ReferenceBinding[] interfaces = interfacesToVisit[i];
379                 for (int j = 0, length = interfaces.length; j < length; j++) {
380                         if ((currentType = interfaces[j]) == anInterface)
381                                 return true;
382
383                         ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
384                         if (itsInterfaces != NoSuperInterfaces) {
385                                 if (++lastPosition == interfacesToVisit.length)
386                                         System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
387                                 interfacesToVisit[lastPosition] = itsInterfaces;
388                         }
389                 }
390         }
391         return false;
392 }
393 // Internal method... assume its only sent to classes NOT interfaces
394
395 boolean implementsMethod(MethodBinding method) {
396         ReferenceBinding type = this;
397         while (type != null) {
398                 MethodBinding[] methods = type.getMethods(method.selector);
399                 for (int i = methods.length; --i >= 0;)
400                         if (methods[i].areParametersEqual(method))
401                                 return true;
402                 type = type.superclass();
403         }
404         return false;
405 }
406 /* Answer true if the receiver is an abstract type
407 */
408
409 public final boolean isAbstract() {
410         return (modifiers & AccAbstract) != 0;
411 }
412 public final boolean isAnonymousType() {
413         return (tagBits & IsAnonymousType) != 0;
414 }
415 public final boolean isBinaryBinding() {
416         return (tagBits & IsBinaryBinding) != 0;
417 }
418 public final boolean isClass() {
419         return (modifiers & AccInterface) == 0;
420 }
421 /* Answer true if the receiver type can be assigned to the argument type (right)
422 */
423         
424 public boolean isCompatibleWith(TypeBinding right) {
425         if (right == this)
426                 return true;
427         if (right.id == T_Object)
428                 return true;
429         if (!(right instanceof ReferenceBinding))
430                 return false;
431
432         ReferenceBinding referenceBinding = (ReferenceBinding) right;
433         if (referenceBinding.isInterface())
434                 return implementsInterface(referenceBinding, true);
435         if (isInterface())  // Explicit conversion from an interface to a class is not allowed
436                 return false;
437         return referenceBinding.isSuperclassOf(this);
438 }
439 /* Answer true if the receiver has default visibility
440 */
441
442 public final boolean isDefault() {
443         return (modifiers & (AccPublic | AccProtected | AccPrivate)) == 0;
444 }
445 /* Answer true if the receiver is a deprecated type
446 */
447
448 public final boolean isDeprecated() {
449         return (modifiers & AccDeprecated) != 0;
450 }
451 /* Answer true if the receiver is final and cannot be subclassed
452 */
453
454 public final boolean isFinal() {
455         return (modifiers & AccFinal) != 0;
456 }
457 public final boolean isInterface() {
458         return (modifiers & AccInterface) != 0;
459 }
460 public final boolean isLocalType() {
461         return (tagBits & IsLocalType) != 0;
462 }
463 public final boolean isMemberType() {
464         return (tagBits & IsMemberType) != 0;
465 }
466 public final boolean isNestedType() {
467         return (tagBits & IsNestedType) != 0;
468 }
469 /* Answer true if the receiver has private visibility
470 */
471
472 public final boolean isPrivate() {
473         return (modifiers & AccPrivate) != 0;
474 }
475 /* Answer true if the receiver has private visibility and is used locally
476 */
477
478 public final boolean isPrivateUsed() {
479         return (modifiers & AccPrivateUsed) != 0;
480 }
481 /* Answer true if the receiver has protected visibility
482 */
483
484 public final boolean isProtected() {
485         return (modifiers & AccProtected) != 0;
486 }
487 /* Answer true if the receiver has public visibility
488 */
489
490 public final boolean isPublic() {
491         return (modifiers & AccPublic) != 0;
492 }
493 /* Answer true if the receiver is a static member type (or toplevel)
494  */
495
496 public final boolean isStatic() {
497         return (modifiers & (AccStatic | AccInterface)) != 0 ||
498                     (tagBits & IsNestedType) == 0;
499 }
500 /* Answer true if all float operations must adher to IEEE 754 float/double rules
501 */
502
503 public final boolean isStrictfp() {
504         return (modifiers & AccStrictfp) != 0;
505 }
506 /* Answer true if the receiver is in the superclass hierarchy of aType
507 *
508 * NOTE: Object.isSuperclassOf(Object) -> false
509 */
510
511 public boolean isSuperclassOf(ReferenceBinding type) {
512         do {
513                 if (this == (type = type.superclass())) return true;
514         } while (type != null);
515
516         return false;
517 }
518 /* Answer true if the receiver is deprecated (or any of its enclosing types)
519 */
520
521 public final boolean isViewedAsDeprecated() {
522         return (modifiers & AccDeprecated) != 0 ||
523                 (modifiers & AccDeprecatedImplicitly) != 0;
524 }
525 public ReferenceBinding[] memberTypes() {
526         return NoMemberTypes;
527 }
528 public MethodBinding[] methods() {
529         return NoMethods;
530 }
531 /**
532 * Answer the source name for the type.
533 * In the case of member types, as the qualified name from its top level type.
534 * For example, for a member type N defined inside M & A: "A.M.N".
535 */
536
537 public char[] qualifiedSourceName() {
538         if (isMemberType())
539                 return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
540         return sourceName();
541 }
542
543 public char[] readableName() /*java.lang.Object*/ {
544         if (isMemberType())
545                 return CharOperation.concat(enclosingType().readableName(), sourceName, '.');
546         return CharOperation.concatWith(compoundName, '.');
547 }
548
549 public char[] shortReadableName() /*Object*/ {
550         if (isMemberType())
551                 return CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
552         return sourceName;
553 }
554
555 /* Answer the receiver's signature.
556 *
557 * NOTE: This method should only be used during/after code gen.
558 */
559
560 public char[] signature() /* Ljava/lang/Object; */ {
561         if (signature != null)
562                 return signature;
563
564         return signature = CharOperation.concat('L', constantPoolName(), ';');
565 }
566 public char[] sourceName() {
567         return sourceName;
568 }
569 public ReferenceBinding superclass() {
570         return null;
571 }
572 public ReferenceBinding[] superInterfaces() {
573         return NoSuperInterfaces;
574 }
575 public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
576         if (isStatic()) return null;
577
578         ReferenceBinding enclosingType = enclosingType();
579         if (enclosingType == null)
580                 return null;
581         return new ReferenceBinding[] {enclosingType};
582 }
583 public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
584         return null;            // is null if no enclosing instances are required
585 }
586 MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
587         return methods();
588 }
589 }