bed0f21047c5a43439442a1cee6f7ef6100ce35b
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / FieldBinding.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.lookup;
12
13 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
14 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
15
16 public class FieldBinding extends VariableBinding {
17         public ReferenceBinding declaringClass;
18 protected FieldBinding() {
19 }
20 public FieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant) {
21         this.modifiers = modifiers;
22         this.type = type;
23         this.name = name;
24         this.declaringClass = declaringClass;
25         this.constant = constant;
26
27         // propagate the deprecated modifier
28         if (this.declaringClass != null)
29                 if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated())
30                         this.modifiers |= AccDeprecatedImplicitly;
31 }
32 public FieldBinding(FieldDeclaration field, TypeBinding type, ReferenceBinding declaringClass) {
33         this(field.name, type, field.modifiers, declaringClass, null);
34
35         field.binding = this;
36 }
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;
45 }
46 /* API
47 * Answer the receiver's binding type from Binding.BindingID.
48 */
49
50 public final int bindingType() {
51         return FIELD;
52 }
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.
56 *
57 * NOTE: Cannot invoke this method with a compilation unit scope.
58 */
59
60 public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
61         if (isPublic()) return true;
62
63         SourceTypeBinding invocationType = scope.enclosingSourceType();
64         if (invocationType == declaringClass && invocationType == receiverType) return true;
65
66         if (isProtected()) {
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;
74                 
75                 ReferenceBinding currentType = invocationType;
76                 int depth = 0;
77                 do {
78                         if (declaringClass.isSuperclassOf(currentType)) {
79                                 if (invocationSite.isSuperAccess()){
80                                         return true;
81                                 }
82                                 // receiverType can be an array binding in one case... see if you can change it
83                                 if (receiverType instanceof ArrayBinding){
84                                         return false;
85                                 }
86                                 if (isStatic()){
87                                         return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
88                                 }
89                                 if (currentType == receiverType || currentType.isSuperclassOf((ReferenceBinding) receiverType)){
90                                         if (depth > 0) invocationSite.setDepth(depth);
91                                         return true;
92                                 }
93                         }
94                         depth++;
95                         currentType = currentType.enclosingType();
96                 } while (currentType != null);
97                 return false;
98         }
99
100         if (isPrivate()) {
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;
104
105                 if (invocationType != declaringClass) {
106                         ReferenceBinding outerInvocationType = invocationType;
107                         ReferenceBinding temp = outerInvocationType.enclosingType();
108                         while (temp != null) {
109                                 outerInvocationType = temp;
110                                 temp = temp.enclosingType();
111                         }
112
113                         ReferenceBinding outerDeclaringClass = declaringClass;
114                         temp = outerDeclaringClass.enclosingType();
115                         while (temp != null) {
116                                 outerDeclaringClass = temp;
117                                 temp = temp.enclosingType();
118                         }
119                         if (outerInvocationType != outerDeclaringClass) return false;
120                 }
121                 return true;
122         }
123
124         // isDefault()
125         if (invocationType.fPackage != declaringClass.fPackage) return false;
126
127         // receiverType can be an array binding in one case... see if you can change it
128         if (receiverType instanceof ArrayBinding)
129                 return false;
130         ReferenceBinding type = (ReferenceBinding) receiverType;
131         PackageBinding declaringPackage = declaringClass.fPackage;
132         do {
133                 if (declaringClass == type) return true;
134                 if (declaringPackage != type.fPackage) return false;
135         } while ((type = type.superclass()) != null);
136         return false;
137 }
138 public final int getAccessFlags() {
139         return modifiers & AccJustFlag;
140 }
141 /* Answer true if the receiver has default visibility
142 */
143
144 public final boolean isDefault() {
145         return !isPublic() && !isProtected() && !isPrivate();
146 }
147 /* Answer true if the receiver is a deprecated field
148 */
149
150 public final boolean isDeprecated() {
151         return (modifiers & AccDeprecated) != 0;
152 }
153 /* Answer true if the receiver has private visibility
154 */
155
156 public final boolean isPrivate() {
157         return (modifiers & AccPrivate) != 0;
158 }
159 /* Answer true if the receiver has protected visibility
160 */
161
162 public final boolean isProtected() {
163         return (modifiers & AccProtected) != 0;
164 }
165 /* Answer true if the receiver has public visibility
166 */
167
168 public final boolean isPublic() {
169         return (modifiers & AccPublic) != 0;
170 }
171 /* Answer true if the receiver is a static field
172 */
173
174 public final boolean isStatic() {
175         return (modifiers & AccStatic) != 0;
176 }
177 /* Answer true if the receiver is not defined in the source of the declaringClass
178 */
179
180 public final boolean isSynthetic() {
181         return (modifiers & AccSynthetic) != 0;
182 }
183 /* Answer true if the receiver is a transient field
184 */
185
186 public final boolean isTransient() {
187         return (modifiers & AccTransient) != 0;
188 }
189 /* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types)
190 */
191
192 public final boolean isViewedAsDeprecated() {
193         return (modifiers & AccDeprecated) != 0 ||
194                 (modifiers & AccDeprecatedImplicitly) != 0;
195 }
196 /* Answer true if the receiver is a volatile field
197 */
198
199 public final boolean isVolatile() {
200         return (modifiers & AccVolatile) != 0;
201 }
202 }