Applying pteague's patch (re #685)
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / FieldBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 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 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
19         protected FieldBinding() {
20         }
21
22         public FieldBinding(char[] name, TypeBinding type, int modifiers,
23                         ReferenceBinding declaringClass, Constant constant) {
24                 this.modifiers = modifiers;
25                 this.type = type;
26                 this.name = name;
27                 this.declaringClass = declaringClass;
28                 this.constant = constant;
29
30                 // propagate the deprecated modifier
31                 if (this.declaringClass != null)
32                         if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated())
33                                 this.modifiers |= AccDeprecatedImplicitly;
34         }
35
36         public FieldBinding(FieldDeclaration field, TypeBinding type,
37                         ReferenceBinding declaringClass) {
38                 this(field.name, type, field.modifiers, declaringClass, null);
39
40                 field.binding = this;
41         }
42
43         // special API used to change field declaring class for runtime visibility
44         // check
45         public FieldBinding(FieldBinding initialFieldBinding,
46                         ReferenceBinding declaringClass) {
47                 this.modifiers = initialFieldBinding.modifiers;
48                 this.type = initialFieldBinding.type;
49                 this.name = initialFieldBinding.name;
50                 this.declaringClass = declaringClass;
51                 this.constant = initialFieldBinding.constant;
52                 this.id = initialFieldBinding.id;
53         }
54
55         /*
56          * API Answer the receiver's binding type from Binding.BindingID.
57          */
58
59         public final int bindingType() {
60                 return FIELD;
61         }
62
63         /*
64          * Answer true if the receiver is visible to the type provided by the scope.
65          * InvocationSite implements isSuperAccess() to provide additional
66          * information if the receiver is protected.
67          * 
68          * NOTE: Cannot invoke this method with a compilation unit scope.
69          */
70
71         public final boolean canBeSeenBy(TypeBinding receiverType,
72                         InvocationSite invocationSite, Scope scope) {
73                 if (isPublic())
74                         return true;
75
76                 SourceTypeBinding invocationType = scope.enclosingSourceType();
77                 if (invocationType == declaringClass && invocationType == receiverType)
78                         return true;
79
80                 if (isProtected()) {
81                         // answer true if the invocationType is the declaringClass or they
82                         // are in the same package
83                         // OR the invocationType is a subclass of the declaringClass
84                         // AND the receiverType is the invocationType or its subclass
85                         // OR the method is a static method accessed directly through a type
86                         // OR previous assertions are true for one of the enclosing type
87                         if (invocationType == declaringClass)
88                                 return true;
89                         if (invocationType.fPackage == declaringClass.fPackage)
90                                 return true;
91
92                         ReferenceBinding currentType = invocationType;
93                         int depth = 0;
94                         do {
95                                 if (declaringClass.isSuperclassOf(currentType)) {
96                                         if (invocationSite.isSuperAccess()) {
97                                                 return true;
98                                         }
99                                         // receiverType can be an array binding in one case... see
100                                         // if you can change it
101                                         if (receiverType instanceof ArrayBinding) {
102                                                 return false;
103                                         }
104                                         if (isStatic()) {
105                                                 return true; // see 1FMEPDL - return
106                                                                                 // invocationSite.isTypeAccess();
107                                         }
108                                         if (currentType == receiverType
109                                                         || currentType
110                                                                         .isSuperclassOf((ReferenceBinding) receiverType)) {
111                                                 if (depth > 0)
112                                                         invocationSite.setDepth(depth);
113                                                 return true;
114                                         }
115                                 }
116                                 depth++;
117                                 currentType = currentType.enclosingType();
118                         } while (currentType != null);
119                         return false;
120                 }
121
122                 if (isPrivate()) {
123                         // answer true if the receiverType is the declaringClass
124                         // AND the invocationType and the declaringClass have a common
125                         // enclosingType
126                         if (receiverType != declaringClass)
127                                 return false;
128
129                         if (invocationType != declaringClass) {
130                                 ReferenceBinding outerInvocationType = invocationType;
131                                 ReferenceBinding temp = outerInvocationType.enclosingType();
132                                 while (temp != null) {
133                                         outerInvocationType = temp;
134                                         temp = temp.enclosingType();
135                                 }
136
137                                 ReferenceBinding outerDeclaringClass = declaringClass;
138                                 temp = outerDeclaringClass.enclosingType();
139                                 while (temp != null) {
140                                         outerDeclaringClass = temp;
141                                         temp = temp.enclosingType();
142                                 }
143                                 if (outerInvocationType != outerDeclaringClass)
144                                         return false;
145                         }
146                         return true;
147                 }
148
149                 // isDefault()
150                 if (invocationType.fPackage != declaringClass.fPackage)
151                         return false;
152
153                 // receiverType can be an array binding in one case... see if you can
154                 // change it
155                 if (receiverType instanceof ArrayBinding)
156                         return false;
157                 ReferenceBinding type = (ReferenceBinding) receiverType;
158                 PackageBinding declaringPackage = declaringClass.fPackage;
159                 do {
160                         if (declaringClass == type)
161                                 return true;
162                         if (declaringPackage != type.fPackage)
163                                 return false;
164                 } while ((type = type.superclass()) != null);
165                 return false;
166         }
167
168         public final int getAccessFlags() {
169                 return modifiers & AccJustFlag;
170         }
171
172         /*
173          * Answer true if the receiver has default visibility
174          */
175
176         public final boolean isDefault() {
177                 return !isPublic() && !isProtected() && !isPrivate();
178         }
179
180         /*
181          * Answer true if the receiver is a deprecated field
182          */
183
184         public final boolean isDeprecated() {
185                 return (modifiers & AccDeprecated) != 0;
186         }
187
188         /*
189          * Answer true if the receiver has private visibility
190          */
191
192         public final boolean isPrivate() {
193                 return (modifiers & AccPrivate) != 0;
194         }
195
196         /*
197          * Answer true if the receiver has private visibility and is used locally
198          */
199
200         public final boolean isPrivateUsed() {
201                 return (modifiers & AccPrivateUsed) != 0;
202         }
203
204         /*
205          * Answer true if the receiver has protected visibility
206          */
207
208         public final boolean isProtected() {
209                 return (modifiers & AccProtected) != 0;
210         }
211
212         /*
213          * Answer true if the receiver has public visibility
214          */
215
216         public final boolean isPublic() {
217                 return (modifiers & AccPublic) != 0;
218         }
219
220         /*
221          * Answer true if the receiver is a static field
222          */
223
224         public final boolean isStatic() {
225                 return (modifiers & AccStatic) != 0;
226         }
227
228         /*
229          * Answer true if the receiver is not defined in the source of the
230          * declaringClass
231          */
232
233         // public final boolean isSynthetic() {
234         // return (modifiers & AccSynthetic) != 0;
235         // }
236         /*
237          * Answer true if the receiver is a transient field
238          */
239
240         // public final boolean isTransient() {
241         // return (modifiers & AccTransient) != 0;
242         // }
243         /*
244          * Answer true if the receiver's declaring type is deprecated (or any of its
245          * enclosing types)
246          */
247
248         public final boolean isViewedAsDeprecated() {
249                 return (modifiers & AccDeprecated) != 0
250                                 || (modifiers & AccDeprecatedImplicitly) != 0;
251         }
252         /*
253          * Answer true if the receiver is a volatile field
254          */
255
256         // public final boolean isVolatile() {
257         // return (modifiers & AccVolatile) != 0;
258         // }
259 }