You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FieldBinding.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. * Palo Alto Research Center, Incorporated - AspectJ adaptation
  11. ******************************************************************************/
  12. package org.eclipse.jdt.internal.compiler.lookup;
  13. import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
  14. import org.eclipse.jdt.internal.compiler.impl.Constant;
  15. /**
  16. * AspectJ added hooks for inter-type field bindings as well as
  17. * proto-hooks for allowing privileged access
  18. */
  19. public class FieldBinding extends VariableBinding {
  20. public ReferenceBinding declaringClass;
  21. protected FieldBinding() {
  22. }
  23. public FieldBinding(char[] name, TypeBinding type, int modifiers, 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. // propagate the deprecated modifier
  30. if (this.declaringClass != null)
  31. if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated())
  32. this.modifiers |= AccDeprecatedImplicitly;
  33. }
  34. public FieldBinding(FieldDeclaration field, TypeBinding type, ReferenceBinding declaringClass) {
  35. this(field.name, type, field.modifiers, declaringClass, null);
  36. field.binding = this;
  37. }
  38. // special API used to change field declaring class for runtime visibility check
  39. public FieldBinding(FieldBinding initialFieldBinding, ReferenceBinding declaringClass) {
  40. this.modifiers = initialFieldBinding.modifiers;
  41. this.type = initialFieldBinding.type;
  42. this.name = initialFieldBinding.name;
  43. this.declaringClass = declaringClass;
  44. this.constant = initialFieldBinding.constant;
  45. this.id = initialFieldBinding.id;
  46. }
  47. /* API
  48. * Answer the receiver's binding type from Binding.BindingID.
  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. // made non-final for AspectJ
  60. public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
  61. if (isPublic()) return true;
  62. SourceTypeBinding invocationType = scope.invocationType();
  63. if (invocationType == declaringClass && invocationType == receiverType) return true;
  64. // if (invocationType.isPrivileged) {
  65. // System.out.println("privileged access to: " + this);
  66. // return true;
  67. // }
  68. if (isProtected()) {
  69. // answer true if the invocationType is the declaringClass or they are in the same package
  70. // OR the invocationType is a subclass of the declaringClass
  71. // AND the receiverType is the invocationType or its subclass
  72. // OR the method is a static method accessed directly through a type
  73. // OR previous assertions are true for one of the enclosing type
  74. if (invocationType == declaringClass) return true;
  75. if (invocationType.fPackage == declaringClass.fPackage) return true;
  76. ReferenceBinding currentType = invocationType;
  77. int depth = 0;
  78. do {
  79. if (declaringClass.isSuperclassOf(currentType)) {
  80. if (invocationSite.isSuperAccess()){
  81. return true;
  82. }
  83. // receiverType can be an array binding in one case... see if you can change it
  84. if (receiverType instanceof ArrayBinding){
  85. return false;
  86. }
  87. if (isStatic()){
  88. return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
  89. }
  90. if (currentType == receiverType || currentType.isSuperclassOf((ReferenceBinding) receiverType)){
  91. if (depth > 0) invocationSite.setDepth(depth);
  92. return true;
  93. }
  94. }
  95. depth++;
  96. currentType = currentType.enclosingType();
  97. } while (currentType != null);
  98. return false;
  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. if (invocationType != declaringClass) {
  105. ReferenceBinding outerInvocationType = invocationType;
  106. ReferenceBinding temp = outerInvocationType.enclosingType();
  107. while (temp != null) {
  108. outerInvocationType = temp;
  109. temp = temp.enclosingType();
  110. }
  111. ReferenceBinding outerDeclaringClass = declaringClass;
  112. temp = outerDeclaringClass.enclosingType();
  113. while (temp != null) {
  114. outerDeclaringClass = temp;
  115. temp = temp.enclosingType();
  116. }
  117. if (outerInvocationType != outerDeclaringClass) return false;
  118. }
  119. return true;
  120. }
  121. // isDefault()
  122. if (invocationType.fPackage != declaringClass.fPackage) return false;
  123. // receiverType can be an array binding in one case... see if you can change it
  124. if (receiverType instanceof ArrayBinding)
  125. return false;
  126. ReferenceBinding type = (ReferenceBinding) receiverType;
  127. PackageBinding declaringPackage = declaringClass.fPackage;
  128. do {
  129. if (declaringClass == type) return true;
  130. if (declaringPackage != type.fPackage) return false;
  131. } while ((type = type.superclass()) != null);
  132. return false;
  133. }
  134. public final int getAccessFlags() {
  135. return modifiers & AccJustFlag;
  136. }
  137. /* Answer true if the receiver has default visibility
  138. */
  139. public final boolean isDefault() {
  140. return !isPublic() && !isProtected() && !isPrivate();
  141. }
  142. /* Answer true if the receiver is a deprecated field
  143. */
  144. public final boolean isDeprecated() {
  145. return (modifiers & AccDeprecated) != 0;
  146. }
  147. /* Answer true if the receiver has private visibility
  148. */
  149. public final boolean isPrivate() {
  150. return (modifiers & AccPrivate) != 0;
  151. }
  152. /* Answer true if the receiver has protected visibility
  153. */
  154. public final boolean isProtected() {
  155. return (modifiers & AccProtected) != 0;
  156. }
  157. /* Answer true if the receiver has public visibility
  158. */
  159. public final boolean isPublic() {
  160. return (modifiers & AccPublic) != 0;
  161. }
  162. /* Answer true if the receiver is a static field
  163. */
  164. public final boolean isStatic() {
  165. return (modifiers & AccStatic) != 0;
  166. }
  167. /* Answer true if the receiver is not defined in the source of the declaringClass
  168. */
  169. public final boolean isSynthetic() {
  170. return (modifiers & AccSynthetic) != 0;
  171. }
  172. /* Answer true if the receiver is a transient field
  173. */
  174. public final boolean isTransient() {
  175. return (modifiers & AccTransient) != 0;
  176. }
  177. /* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types)
  178. */
  179. public final boolean isViewedAsDeprecated() {
  180. return (modifiers & AccDeprecated) != 0 ||
  181. (modifiers & AccDeprecatedImplicitly) != 0;
  182. }
  183. /* Answer true if the receiver is a volatile field
  184. */
  185. public final boolean isVolatile() {
  186. return (modifiers & AccVolatile) != 0;
  187. }
  188. public boolean alwaysNeedsAccessMethod(boolean isReadAccess) { return false; }
  189. public SyntheticAccessMethodBinding getAccessMethod(boolean isReadAccess) {
  190. throw new RuntimeException("unimplemented");
  191. }
  192. public FieldBinding getFieldBindingForLookup() { return this; }
  193. }