1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 15 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 16 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 17 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 18 import org.eclipse.jdt.internal.compiler.impl.Constant; 19 20 public class FieldBinding extends VariableBinding { 21 public ReferenceBinding declaringClass; 22 protected FieldBinding() { 23 super(null, null, 0, null); 24 } 26 public FieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant) { 27 super(name, type, modifiers, constant); 28 this.declaringClass = declaringClass; 29 } 30 public FieldBinding(FieldDeclaration field, TypeBinding type, int modifiers, ReferenceBinding declaringClass) { 31 this(field.name, type, modifiers, declaringClass, null); 32 field.binding = this; } 34 public FieldBinding(FieldBinding initialFieldBinding, ReferenceBinding declaringClass) { 36 super(initialFieldBinding.name, initialFieldBinding.type, initialFieldBinding.modifiers, initialFieldBinding.constant()); 37 this.declaringClass = declaringClass; 38 this.id = initialFieldBinding.id; 39 setAnnotations(initialFieldBinding.getAnnotations()); 40 } 41 44 45 public final int kind() { 46 return FIELD; 47 } 48 50 51 public final boolean canBeSeenBy(PackageBinding invocationPackage) { 52 if (isPublic()) return true; 53 if (isPrivate()) return false; 54 55 return invocationPackage == declaringClass.getPackage(); 57 } 58 64 65 public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) { 66 if (isPublic()) return true; 67 68 SourceTypeBinding invocationType = scope.enclosingSourceType(); 69 if (invocationType == declaringClass && invocationType == receiverType) return true; 70 71 if (invocationType == null) return !isPrivate() && scope.getCurrentPackage() == declaringClass.fPackage; 73 74 if (isProtected()) { 75 if (invocationType == declaringClass) return true; 81 if (invocationType.fPackage == declaringClass.fPackage) return true; 82 83 ReferenceBinding currentType = invocationType; 84 int depth = 0; 85 ReferenceBinding receiverErasure = (ReferenceBinding)receiverType.erasure(); 86 ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure(); 87 do { 88 if (currentType.findSuperTypeWithSameErasure(declaringErasure) != null) { 89 if (invocationSite.isSuperAccess()) 90 return true; 91 if (receiverType instanceof ArrayBinding) 93 return false; 94 if (isStatic()) { 95 if (depth > 0) invocationSite.setDepth(depth); 96 return true; } 98 if (currentType == receiverErasure || receiverErasure.findSuperTypeWithSameErasure(currentType) != null) { 99 if (depth > 0) invocationSite.setDepth(depth); 100 return true; 101 } 102 } 103 depth++; 104 currentType = currentType.enclosingType(); 105 } while (currentType != null); 106 return false; 107 } 108 109 if (isPrivate()) { 110 receiverCheck: { 113 if (receiverType != declaringClass) { 114 if (receiverType.isTypeVariable() && ((TypeVariableBinding) receiverType).isErasureBoundTo(declaringClass.erasure())) 116 break receiverCheck; 117 return false; 118 } 119 } 120 121 if (invocationType != declaringClass) { 122 ReferenceBinding outerInvocationType = invocationType; 123 ReferenceBinding temp = outerInvocationType.enclosingType(); 124 while (temp != null) { 125 outerInvocationType = temp; 126 temp = temp.enclosingType(); 127 } 128 129 ReferenceBinding outerDeclaringClass = (ReferenceBinding) declaringClass.erasure(); 130 temp = outerDeclaringClass.enclosingType(); 131 while (temp != null) { 132 outerDeclaringClass = temp; 133 temp = temp.enclosingType(); 134 } 135 if (outerInvocationType != outerDeclaringClass) return false; 136 } 137 return true; 138 } 139 140 PackageBinding declaringPackage = declaringClass.fPackage; 142 if (invocationType.fPackage != declaringPackage) return false; 143 144 if (receiverType instanceof ArrayBinding) 146 return false; 147 ReferenceBinding currentType = (ReferenceBinding) receiverType; 148 do { 149 if (declaringClass == currentType) return true; 150 PackageBinding currentPackage = currentType.fPackage; 151 if (currentPackage != null && currentPackage != declaringPackage) return false; 153 } while ((currentType = currentType.superclass()) != null); 154 return false; 155 } 156 160 public char[] computeUniqueKey(boolean isLeaf) { 161 char[] declaringKey = 163 this.declaringClass == null 164 ? CharOperation.NO_CHAR 165 : this.declaringClass.computeUniqueKey(false); 166 int declaringLength = declaringKey.length; 167 168 int nameLength = this.name.length; 170 171 char[] returnTypeKey = this.type == null ? new char[] {'V'} : this.type.computeUniqueKey(false); 173 int returnTypeLength = returnTypeKey.length; 174 175 char[] uniqueKey = new char[declaringLength + 1 + nameLength + 1 + returnTypeLength]; 176 int index = 0; 177 System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength); 178 index += declaringLength; 179 uniqueKey[index++] = '.'; 180 System.arraycopy(this.name, 0, uniqueKey, index, nameLength); 181 index += nameLength; 182 uniqueKey[index++] = ')'; 183 System.arraycopy(returnTypeKey, 0, uniqueKey, index, returnTypeLength); 184 return uniqueKey; 185 } 186 187 public Constant constant() { 188 Constant fieldConstant = this.constant; 189 if (fieldConstant == null) { 190 if (this.isFinal()) { 191 FieldBinding originalField = this.original(); 196 if (originalField.declaringClass instanceof SourceTypeBinding) { 197 SourceTypeBinding sourceType = (SourceTypeBinding) originalField.declaringClass; 198 if (sourceType.scope != null) { 199 TypeDeclaration typeDecl = sourceType.scope.referenceContext; 200 FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField); 201 fieldDecl.resolve(originalField.isStatic() ? typeDecl.staticInitializerScope 203 : typeDecl.initializerScope); 204 fieldConstant = originalField.constant(); 205 } else { 206 fieldConstant = Constant.NotAConstant; } 208 } else { 209 fieldConstant = Constant.NotAConstant; } 211 } else { 212 fieldConstant = Constant.NotAConstant; 213 } 214 this.constant = fieldConstant; 215 } 216 return fieldConstant; 217 } 218 221 public char[] genericSignature() { 222 if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) return null; 223 return this.type.genericTypeSignature(); 224 } 225 226 public final int getAccessFlags() { 227 return modifiers & ExtraCompilerModifiers.AccJustFlag; 228 } 229 230 235 public long getAnnotationTagBits() { 236 FieldBinding originalField = this.original(); 237 if ((originalField.tagBits & TagBits.AnnotationResolved) == 0 && originalField.declaringClass instanceof SourceTypeBinding) { 238 ClassScope scope = ((SourceTypeBinding) originalField.declaringClass).scope; 239 if (scope == null) { this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved); 241 return 0; 242 } 243 TypeDeclaration typeDecl = scope.referenceContext; 244 FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField); 245 if (fieldDecl != null) { 246 MethodScope initializationScope = isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope; 247 FieldBinding previousField = initializationScope.initializedField; 248 int previousFieldID = initializationScope.lastVisibleFieldID; 249 try { 250 initializationScope.initializedField = originalField; 251 initializationScope.lastVisibleFieldID = originalField.id; 252 ASTNode.resolveAnnotations(initializationScope, fieldDecl.annotations, originalField); 253 } finally { 254 initializationScope.initializedField = previousField; 255 initializationScope.lastVisibleFieldID = previousFieldID; 256 } 257 } 258 } 259 return originalField.tagBits; 260 } 261 262 public AnnotationBinding[] getAnnotations() { 263 FieldBinding originalField = this.original(); 264 ReferenceBinding declaringClassBinding = originalField.declaringClass; 265 if (declaringClassBinding == null) { 266 return Binding.NO_ANNOTATIONS; 267 } 268 return declaringClassBinding.retrieveAnnotations(originalField); 269 } 270 271 273 274 public final boolean isDefault() { 275 return !isPublic() && !isProtected() && !isPrivate(); 276 } 277 279 280 public final boolean isDeprecated() { 281 return (modifiers & ClassFileConstants.AccDeprecated) != 0; 282 } 283 285 286 public final boolean isPrivate() { 287 return (modifiers & ClassFileConstants.AccPrivate) != 0; 288 } 289 291 292 public final boolean isUsed() { 293 return (modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0; 294 } 295 297 298 public final boolean isProtected() { 299 return (modifiers & ClassFileConstants.AccProtected) != 0; 300 } 301 303 304 public final boolean isPublic() { 305 return (modifiers & ClassFileConstants.AccPublic) != 0; 306 } 307 309 310 public final boolean isStatic() { 311 return (modifiers & ClassFileConstants.AccStatic) != 0; 312 } 313 315 316 public final boolean isSynthetic() { 317 return (modifiers & ClassFileConstants.AccSynthetic) != 0; 318 } 319 321 322 public final boolean isTransient() { 323 return (modifiers & ClassFileConstants.AccTransient) != 0; 324 } 325 327 328 public final boolean isViewedAsDeprecated() { 329 return (modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0; 330 } 331 333 334 public final boolean isVolatile() { 335 return (modifiers & ClassFileConstants.AccVolatile) != 0; 336 } 337 340 public FieldBinding original() { 341 return this; 342 } 343 public void setAnnotations(AnnotationBinding[] annotations) { 344 this.declaringClass.storeAnnotations(this, annotations); 345 } 346 public FieldDeclaration sourceField() { 347 SourceTypeBinding sourceType; 348 try { 349 sourceType = (SourceTypeBinding) declaringClass; 350 } catch (ClassCastException e) { 351 return null; 352 } 353 354 FieldDeclaration[] fields = sourceType.scope.referenceContext.fields; 355 if (fields != null) { 356 for (int i = fields.length; --i >= 0;) 357 if (this == fields[i].binding) 358 return fields[i]; 359 } 360 return null; 361 } 362 } 363 | Popular Tags |