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.ast.FieldDeclaration;
 
  14 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
 
  16 public class FieldBinding extends VariableBinding {
 
  17         public ReferenceBinding declaringClass;
 
  18 protected FieldBinding() {
 
  20 public FieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant) {
 
  21         this.modifiers = modifiers;
 
  24         this.declaringClass = declaringClass;
 
  25         this.constant = constant;
 
  27         // propagate the deprecated modifier
 
  28         if (this.declaringClass != null)
 
  29                 if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated())
 
  30                         this.modifiers |= AccDeprecatedImplicitly;
 
  32 public FieldBinding(FieldDeclaration field, TypeBinding type, ReferenceBinding declaringClass) {
 
  33         this(field.name, type, field.modifiers, declaringClass, null);
 
  37 // special API used to change field declaring class for runtime visibility check
 
  38 public FieldBinding(FieldBinding initialFieldBinding, ReferenceBinding declaringClass) {
 
  39         this.modifiers = initialFieldBinding.modifiers;
 
  40         this.type = initialFieldBinding.type;
 
  41         this.name = initialFieldBinding.name;
 
  42         this.declaringClass = declaringClass;
 
  43         this.constant = initialFieldBinding.constant;
 
  44         this.id = initialFieldBinding.id;
 
  47 * Answer the receiver's binding type from Binding.BindingID.
 
  50 public final int bindingType() {
 
  53 /* Answer true if the receiver is visible to the type provided by the scope.
 
  54 * InvocationSite implements isSuperAccess() to provide additional information
 
  55 * if the receiver is protected.
 
  57 * NOTE: Cannot invoke this method with a compilation unit scope.
 
  60 public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
 
  61         if (isPublic()) return true;
 
  63         SourceTypeBinding invocationType = scope.enclosingSourceType();
 
  64         if (invocationType == declaringClass && invocationType == receiverType) return true;
 
  67                 // answer true if the invocationType is the declaringClass or they are in the same package
 
  68                 // OR the invocationType is a subclass of the declaringClass
 
  69                 //    AND the receiverType is the invocationType or its subclass
 
  70                 //    OR the method is a static method accessed directly through a type
 
  71                 //    OR previous assertions are true for one of the enclosing type
 
  72                 if (invocationType == declaringClass) return true;
 
  73                 if (invocationType.fPackage == declaringClass.fPackage) return true;
 
  75                 ReferenceBinding currentType = invocationType;
 
  78                         if (declaringClass.isSuperclassOf(currentType)) {
 
  79                                 if (invocationSite.isSuperAccess()){
 
  82                                 // receiverType can be an array binding in one case... see if you can change it
 
  83                                 if (receiverType instanceof ArrayBinding){
 
  87                                         return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
 
  89                                 if (currentType == receiverType || currentType.isSuperclassOf((ReferenceBinding) receiverType)){
 
  90                                         if (depth > 0) invocationSite.setDepth(depth);
 
  95                         currentType = currentType.enclosingType();
 
  96                 } while (currentType != null);
 
 101                 // answer true if the receiverType is the declaringClass
 
 102                 // AND the invocationType and the declaringClass have a common enclosingType
 
 103                 if (receiverType != declaringClass) return false;
 
 105                 if (invocationType != declaringClass) {
 
 106                         ReferenceBinding outerInvocationType = invocationType;
 
 107                         ReferenceBinding temp = outerInvocationType.enclosingType();
 
 108                         while (temp != null) {
 
 109                                 outerInvocationType = temp;
 
 110                                 temp = temp.enclosingType();
 
 113                         ReferenceBinding outerDeclaringClass = declaringClass;
 
 114                         temp = outerDeclaringClass.enclosingType();
 
 115                         while (temp != null) {
 
 116                                 outerDeclaringClass = temp;
 
 117                                 temp = temp.enclosingType();
 
 119                         if (outerInvocationType != outerDeclaringClass) return false;
 
 125         if (invocationType.fPackage != declaringClass.fPackage) return false;
 
 127         // receiverType can be an array binding in one case... see if you can change it
 
 128         if (receiverType instanceof ArrayBinding)
 
 130         ReferenceBinding type = (ReferenceBinding) receiverType;
 
 131         PackageBinding declaringPackage = declaringClass.fPackage;
 
 133                 if (declaringClass == type) return true;
 
 134                 if (declaringPackage != type.fPackage) return false;
 
 135         } while ((type = type.superclass()) != null);
 
 138 public final int getAccessFlags() {
 
 139         return modifiers & AccJustFlag;
 
 141 /* Answer true if the receiver has default visibility
 
 144 public final boolean isDefault() {
 
 145         return !isPublic() && !isProtected() && !isPrivate();
 
 147 /* Answer true if the receiver is a deprecated field
 
 150 public final boolean isDeprecated() {
 
 151         return (modifiers & AccDeprecated) != 0;
 
 153 /* Answer true if the receiver has private visibility
 
 156 public final boolean isPrivate() {
 
 157         return (modifiers & AccPrivate) != 0;
 
 159 /* Answer true if the receiver has protected visibility
 
 162 public final boolean isProtected() {
 
 163         return (modifiers & AccProtected) != 0;
 
 165 /* Answer true if the receiver has public visibility
 
 168 public final boolean isPublic() {
 
 169         return (modifiers & AccPublic) != 0;
 
 171 /* Answer true if the receiver is a static field
 
 174 public final boolean isStatic() {
 
 175         return (modifiers & AccStatic) != 0;
 
 177 /* Answer true if the receiver is not defined in the source of the declaringClass
 
 180 public final boolean isSynthetic() {
 
 181         return (modifiers & AccSynthetic) != 0;
 
 183 /* Answer true if the receiver is a transient field
 
 186 public final boolean isTransient() {
 
 187         return (modifiers & AccTransient) != 0;
 
 189 /* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types)
 
 192 public final boolean isViewedAsDeprecated() {
 
 193         return (modifiers & AccDeprecated) != 0 ||
 
 194                 (modifiers & AccDeprecatedImplicitly) != 0;
 
 196 /* Answer true if the receiver is a volatile field
 
 199 public final boolean isVolatile() {
 
 200         return (modifiers & AccVolatile) != 0;