1 /*******************************************************************************
 
   2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
 
   3  * All rights reserved. This program and the accompanying materials 
 
   4  * are made available under the terms of the Common Public License v0.5 
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v05.html
 
   9  *     IBM Corporation - initial API and implementation
 
  10  ******************************************************************************/
 
  11 package net.sourceforge.phpdt.internal.compiler.lookup;
 
  13 import net.sourceforge.phpdt.internal.compiler.env.IDependent;
 
  14 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
 
  17 Not all fields defined by this type (& its subclasses) are initialized when it is created.
 
  18 Some are initialized only when needed.
 
  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.
 
  24 null is NOT a valid value for a non-public field... it just means the field is not initialized.
 
  27 abstract public class ReferenceBinding extends TypeBinding implements IDependent {
 
  28         public char[][] compoundName;
 
  29         public char[] sourceName;
 
  31         public PackageBinding fPackage;
 
  34         char[] constantPoolName;
 
  37 public FieldBinding[] availableFields() {
 
  41 public MethodBinding[] availableMethods() {
 
  44 /* Answer true if the receiver can be instantiated
 
  47 public boolean canBeInstantiated() {
 
  48         return !(isAbstract() || isInterface());
 
  50 /* Answer true if the receiver is visible to the invocationPackage.
 
  53 public final boolean canBeSeenBy(PackageBinding invocationPackage) {
 
  54         if (isPublic()) return true;
 
  55         if (isPrivate()) return false;
 
  57         // isProtected() or isDefault()
 
  58         return invocationPackage == fPackage;
 
  60 /* Answer true if the receiver is visible to the receiverType and the invocationType.
 
  63 public final boolean canBeSeenBy(ReferenceBinding receiverType, SourceTypeBinding invocationType) {
 
  64         if (isPublic()) return true;
 
  66         if (invocationType == this && invocationType == receiverType) return true;
 
  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;
 
  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
 
  83                         if (declaringClass == invocationType) return true;
 
  84                         if (declaringClass.isSuperclassOf(currentType)) return true;
 
  86                         currentType = currentType.enclosingType();
 
  87                 } while (currentType != null);
 
  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;
 
  96                 if (invocationType != this) {
 
  97                         ReferenceBinding outerInvocationType = invocationType;
 
  98                         ReferenceBinding temp = outerInvocationType.enclosingType();
 
  99                         while (temp != null) {
 
 100                                 outerInvocationType = temp;
 
 101                                 temp = temp.enclosingType();
 
 104                         ReferenceBinding outerDeclaringClass = this;
 
 105                         temp = outerDeclaringClass.enclosingType();
 
 106                         while (temp != null) {
 
 107                                 outerDeclaringClass = temp;
 
 108                                 temp = temp.enclosingType();
 
 110                         if (outerInvocationType != outerDeclaringClass) return false;
 
 116         if (invocationType.fPackage != fPackage) return false;
 
 118         ReferenceBinding type = receiverType;
 
 119         ReferenceBinding declaringClass = enclosingType() == null ? this : enclosingType();
 
 121                 if (declaringClass == type) return true;
 
 122                 if (fPackage != type.fPackage) return false;
 
 123         } while ((type = type.superclass()) != null);
 
 126 /* Answer true if the receiver is visible to the type provided by the scope.
 
 128 * NOTE: Cannot invoke this method with a compilation unit scope.
 
 131 public final boolean canBeSeenBy(Scope scope) {
 
 132         if (isPublic()) return true;
 
 134         SourceTypeBinding invocationType = scope.enclosingSourceType();
 
 135         if (invocationType == this) return true;
 
 138                 // answer true if the receiver (or its enclosing type) is the superclass 
 
 139                 //      of the invocationType or in the same package
 
 140                 return invocationType.fPackage == fPackage 
 
 141                                 || isSuperclassOf(invocationType)
 
 142                                 || enclosingType().isSuperclassOf(invocationType); // protected types always have an enclosing one
 
 146                 // answer true if the invocationType is the declaringClass or they are in the same package
 
 147                 // OR the invocationType is a subclass of the declaringClass
 
 148                 //    AND the invocationType is the invocationType or its subclass
 
 149                 //    OR the type is a static method accessed directly through a type
 
 150                 //    OR previous assertions are true for one of the enclosing type
 
 151                 if (invocationType.fPackage == fPackage) return true;
 
 153                 ReferenceBinding currentType = invocationType;
 
 154                 ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one
 
 155                 if (declaringClass == null) return false; // could be null if incorrect top-level protected type
 
 158                         if (declaringClass == invocationType) return true;
 
 159                         if (declaringClass.isSuperclassOf(currentType)) return true;
 
 161                         currentType = currentType.enclosingType();
 
 162                 } while (currentType != null);
 
 166                 // answer true if the receiver and the invocationType have a common enclosingType
 
 167                 // already know they are not the identical type
 
 168                 ReferenceBinding outerInvocationType = invocationType;
 
 169                 ReferenceBinding temp = outerInvocationType.enclosingType();
 
 170                 while (temp != null) {
 
 171                         outerInvocationType = temp;
 
 172                         temp = temp.enclosingType();
 
 175                 ReferenceBinding outerDeclaringClass = this;
 
 176                 temp = outerDeclaringClass.enclosingType();
 
 177                 while (temp != null) {
 
 178                         outerDeclaringClass = temp;
 
 179                         temp = temp.enclosingType();
 
 181                 return outerInvocationType == outerDeclaringClass;
 
 185         return invocationType.fPackage == fPackage;
 
 187 public void computeId() {
 
 188         if (compoundName.length != 3) {
 
 189                 if (compoundName.length == 4 && CharOperation.equals(JAVA_LANG_REFLECT_CONSTRUCTOR, compoundName)) {
 
 190                         id = T_JavaLangReflectConstructor;
 
 193                 return;         // all other types are in java.*.*
 
 196         if (!CharOperation.equals(JAVA, compoundName[0]))
 
 197                 return;         // assumes we only look up types in java
 
 199         if (!CharOperation.equals(LANG, compoundName[1])) {
 
 200                 if (CharOperation.equals(JAVA_IO_PRINTSTREAM, compoundName)) {
 
 201                         id = T_JavaIoPrintStream;
 
 204                 return;         // all other types are in java.lang
 
 207         if (CharOperation.equals(JAVA_LANG_OBJECT, compoundName)) {
 
 208                 id = T_JavaLangObject;
 
 211         if (CharOperation.equals(JAVA_LANG_STRING, compoundName)) {
 
 212                 id = T_JavaLangString;
 
 216         // well-known exception types
 
 217         if (CharOperation.equals(JAVA_LANG_THROWABLE, compoundName)) {
 
 218                 id = T_JavaLangThrowable;
 
 221         if (CharOperation.equals(JAVA_LANG_ERROR, compoundName)) {
 
 222                 id = T_JavaLangError;
 
 225         if (CharOperation.equals(JAVA_LANG_EXCEPTION, compoundName)) {
 
 226                 id = T_JavaLangException;
 
 229         if (CharOperation.equals(JAVA_LANG_CLASSNOTFOUNDEXCEPTION, compoundName)) {
 
 230                 id = T_JavaLangClassNotFoundException;
 
 233         if (CharOperation.equals(JAVA_LANG_NOCLASSDEFERROR, compoundName)) {
 
 234                 id = T_JavaLangNoClassDefError;
 
 238         // other well-known types
 
 239         if (CharOperation.equals(JAVA_LANG_CLASS, compoundName)) {
 
 240                 id = T_JavaLangClass;
 
 243         if (CharOperation.equals(JAVA_LANG_STRINGBUFFER, compoundName)) {
 
 244                 id = T_JavaLangStringBuffer;
 
 247         if (CharOperation.equals(JAVA_LANG_SYSTEM, compoundName)) {
 
 248                 id = T_JavaLangSystem;
 
 252         if (CharOperation.equals(JAVA_LANG_INTEGER, compoundName)) {
 
 253                 id = T_JavaLangInteger;
 
 257         if (CharOperation.equals(JAVA_LANG_BYTE, compoundName)) {
 
 262         if (CharOperation.equals(JAVA_LANG_CHARACTER, compoundName)) {
 
 263                 id = T_JavaLangCharacter;
 
 267         if (CharOperation.equals(JAVA_LANG_FLOAT, compoundName)) {
 
 268                 id = T_JavaLangFloat;
 
 272         if (CharOperation.equals(JAVA_LANG_DOUBLE, compoundName)) {
 
 273                 id = T_JavaLangDouble;
 
 277         if (CharOperation.equals(JAVA_LANG_BOOLEAN, compoundName)) {
 
 278                 id = T_JavaLangBoolean;
 
 282         if (CharOperation.equals(JAVA_LANG_SHORT, compoundName)) {
 
 283                 id = T_JavaLangShort;
 
 287         if (CharOperation.equals(JAVA_LANG_LONG, compoundName)) {
 
 292         if (CharOperation.equals(JAVA_LANG_VOID, compoundName)) {
 
 297         if (CharOperation.equals(JAVA_LANG_ASSERTIONERROR, compoundName)) {
 
 298                 id = T_JavaLangAssertionError;
 
 302 /* Answer the receiver's constant pool name.
 
 304 * NOTE: This method should only be used during/after code gen.
 
 307 public char[] constantPoolName() /* java/lang/Object */ {
 
 308         if (constantPoolName != null)   return constantPoolName;
 
 309         return constantPoolName = CharOperation.concatWith(compoundName, '/');
 
 312         return (compoundName != null) ? new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$
 
 314 public final int depth() {
 
 316         ReferenceBinding current = this;
 
 317         while ((current = current.enclosingType()) != null)
 
 321 /* Answer the receiver's enclosing type... null if the receiver is a top level type.
 
 324 public ReferenceBinding enclosingType() {
 
 327 public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
 
 328         ReferenceBinding current = this;
 
 329         while (relativeDepth-- > 0 && current != null)
 
 330                 current = current.enclosingType();
 
 333 public int fieldCount() {
 
 334         return fields().length;
 
 336 public FieldBinding[] fields() {
 
 339 public final int getAccessFlags() {
 
 340         return modifiers & AccJustFlag;
 
 342 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
 
 345 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) {
 
 348 public FieldBinding getField(char[] fieldName) {
 
 352  * Answer the file name which defines the type.
 
 354  * The path part (optional) must be separated from the actual
 
 355  * file proper name by a java.io.File.separator.
 
 357  * The proper file name includes the suffix extension (e.g. ".java")
 
 359  * e.g. "c:/com/ibm/compiler/java/api/Compiler.java" 
 
 362 public char[] getFileName() {
 
 365 public ReferenceBinding getMemberType(char[] typeName) {
 
 366         ReferenceBinding[] memberTypes = memberTypes();
 
 367         for (int i = memberTypes.length; --i >= 0;)
 
 368                 if (CharOperation.equals(memberTypes[i].sourceName, typeName))
 
 369                         return memberTypes[i];
 
 372 public MethodBinding[] getMethods(char[] selector) {
 
 375 public PackageBinding getPackage() {
 
 378 /* Answer true if the receiver implements anInterface or is identical to anInterface.
 
 379 * If searchHierarchy is true, then also search the receiver's superclasses.
 
 381 * NOTE: Assume that anInterface is an interface.
 
 384 public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
 
 385         if (this == anInterface)
 
 388         ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
 
 389         int lastPosition = -1;
 
 390         ReferenceBinding currentType = this;
 
 392                 ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
 
 393                 if (itsInterfaces != NoSuperInterfaces) {
 
 394                         if (++lastPosition == interfacesToVisit.length)
 
 395                                 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
 
 396                         interfacesToVisit[lastPosition] = itsInterfaces;
 
 398         } while (searchHierarchy && (currentType = currentType.superclass()) != null);
 
 400         for (int i = 0; i <= lastPosition; i++) {
 
 401                 ReferenceBinding[] interfaces = interfacesToVisit[i];
 
 402                 for (int j = 0, length = interfaces.length; j < length; j++) {
 
 403                         if ((currentType = interfaces[j]) == anInterface)
 
 406                         ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
 
 407                         if (itsInterfaces != NoSuperInterfaces) {
 
 408                                 if (++lastPosition == interfacesToVisit.length)
 
 409                                         System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
 
 410                                 interfacesToVisit[lastPosition] = itsInterfaces;
 
 416 // Internal method... assume its only sent to classes NOT interfaces
 
 418 boolean implementsMethod(MethodBinding method) {
 
 419         ReferenceBinding type = this;
 
 420         while (type != null) {
 
 421                 MethodBinding[] methods = type.getMethods(method.selector);
 
 422                 for (int i = methods.length; --i >= 0;)
 
 423                         if (methods[i].areParametersEqual(method))
 
 425                 type = type.superclass();
 
 429 /* Answer true if the receiver is an abstract type
 
 432 public final boolean isAbstract() {
 
 433         return (modifiers & AccAbstract) != 0;
 
 435 public final boolean isAnonymousType() {
 
 436         return (tagBits & IsAnonymousType) != 0;
 
 438 public final boolean isBinaryBinding() {
 
 439         return (tagBits & IsBinaryBinding) != 0;
 
 441 public final boolean isClass() {
 
 442         return (modifiers & AccInterface) == 0;
 
 444 /* Answer true if the receiver type can be assigned to the argument type (right)
 
 447 boolean isCompatibleWith(TypeBinding right) {
 
 450         if (right.id == T_Object)
 
 452         if (!(right instanceof ReferenceBinding))
 
 455         ReferenceBinding referenceBinding = (ReferenceBinding) right;
 
 456         if (referenceBinding.isInterface())
 
 457                 return implementsInterface(referenceBinding, true);
 
 458         if (isInterface())  // Explicit conversion from an interface to a class is not allowed
 
 460         return referenceBinding.isSuperclassOf(this);
 
 462 /* Answer true if the receiver has default visibility
 
 465 public final boolean isDefault() {
 
 466         return (modifiers & (AccPublic | AccProtected | AccPrivate)) == 0;
 
 468 /* Answer true if the receiver is a deprecated type
 
 471 public final boolean isDeprecated() {
 
 472         return (modifiers & AccDeprecated) != 0;
 
 474 /* Answer true if the receiver is final and cannot be subclassed
 
 477 public final boolean isFinal() {
 
 478         return (modifiers & AccFinal) != 0;
 
 480 public final boolean isInterface() {
 
 481         return (modifiers & AccInterface) != 0;
 
 483 public final boolean isLocalType() {
 
 484         return (tagBits & IsLocalType) != 0;
 
 486 public final boolean isMemberType() {
 
 487         return (tagBits & IsMemberType) != 0;
 
 489 public final boolean isNestedType() {
 
 490         return (tagBits & IsNestedType) != 0;
 
 492 /* Answer true if the receiver has private visibility
 
 495 public final boolean isPrivate() {
 
 496         return (modifiers & AccPrivate) != 0;
 
 498 /* Answer true if the receiver has protected visibility
 
 501 public final boolean isProtected() {
 
 502         return (modifiers & AccProtected) != 0;
 
 504 /* Answer true if the receiver has public visibility
 
 507 public final boolean isPublic() {
 
 508         return (modifiers & AccPublic) != 0;
 
 510 /* Answer true if the receiver is a static member type (or toplevel)
 
 513 public final boolean isStatic() {
 
 514         return (modifiers & (AccStatic | AccInterface)) != 0 ||
 
 515                     (tagBits & IsNestedType) == 0;
 
 517 /* Answer true if all float operations must adher to IEEE 754 float/double rules
 
 520 public final boolean isStrictfp() {
 
 521         return (modifiers & AccStrictfp) != 0;
 
 523 /* Answer true if the receiver is in the superclass hierarchy of aType
 
 525 * NOTE: Object.isSuperclassOf(Object) -> false
 
 528 public boolean isSuperclassOf(ReferenceBinding type) {
 
 530                 if (this == (type = type.superclass())) return true;
 
 531         } while (type != null);
 
 535 /* Answer true if the receiver is deprecated (or any of its enclosing types)
 
 538 public final boolean isViewedAsDeprecated() {
 
 539         return (modifiers & AccDeprecated) != 0 ||
 
 540                 (modifiers & AccDeprecatedImplicitly) != 0;
 
 542 public ReferenceBinding[] memberTypes() {
 
 543         return NoMemberTypes;
 
 545 public MethodBinding[] methods() {
 
 549 * Answer the source name for the type.
 
 550 * In the case of member types, as the qualified name from its top level type.
 
 551 * For example, for a member type N defined inside M & A: "A.M.N".
 
 554 public char[] qualifiedSourceName() {
 
 555         if (isMemberType()) {
 
 556                 return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
 
 561 public char[] readableName() /*java.lang.Object*/ {
 
 563                 return CharOperation.concat(enclosingType().readableName(), sourceName, '.');
 
 565                 return CharOperation.concatWith(compoundName, '.');
 
 567 /* Answer the receiver's signature.
 
 569 * NOTE: This method should only be used during/after code gen.
 
 572 public char[] signature() /* Ljava/lang/Object; */ {
 
 573         if (signature != null)
 
 576         return signature = CharOperation.concat('L', constantPoolName(), ';');
 
 578 public char[] sourceName() {
 
 581 public ReferenceBinding superclass() {
 
 584 public ReferenceBinding[] superInterfaces() {
 
 585         return NoSuperInterfaces;
 
 587 public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
 
 588         if (isStatic()) return null;
 
 590         ReferenceBinding enclosingType = enclosingType();
 
 591         if (enclosingType == null)
 
 594                 return new ReferenceBinding[] {enclosingType};
 
 596 public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
 
 597         return null;            // is null if no enclosing instances are required