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.

InterTypeMethodBinding.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.internal.compiler.lookup;
  13. import org.aspectj.ajdt.internal.compiler.ast.InterTypeMethodDeclaration;
  14. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  15. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
  16. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  17. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
  18. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
  19. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
  20. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  21. import org.aspectj.weaver.AjcMemberMaker;
  22. import org.aspectj.weaver.Member;
  23. import org.aspectj.weaver.ResolvedMember;
  24. import org.aspectj.weaver.ResolvedTypeMunger;
  25. import org.aspectj.weaver.UnresolvedType;
  26. /**
  27. * A special method binding representing an ITD that pretends to be a member in some target type for matching purposes.
  28. */
  29. public class InterTypeMethodBinding extends MethodBinding {
  30. /** The target type upon which the ITD is declared */
  31. private ReferenceBinding targetType;
  32. /**
  33. * This is the 'pretend' method that should be the target of any attempt to call the ITD'd method.
  34. */
  35. private MethodBinding syntheticMethod;
  36. public MethodBinding postDispatchMethod;
  37. public AbstractMethodDeclaration sourceMethod;
  38. public InterTypeMethodBinding(EclipseFactory world, ResolvedTypeMunger munger, UnresolvedType withinType,
  39. AbstractMethodDeclaration sourceMethod) {
  40. super();
  41. ResolvedMember signature = munger.getSignature();
  42. MethodBinding mb = world.makeMethodBinding(signature, munger.getTypeVariableAliases());
  43. this.modifiers = mb.modifiers;
  44. this.selector = mb.selector;
  45. this.returnType = mb.returnType;
  46. this.parameters = mb.parameters;
  47. this.thrownExceptions = mb.thrownExceptions;
  48. this.typeVariables = mb.typeVariables;
  49. this.sourceMethod = sourceMethod;
  50. this.targetType = (ReferenceBinding) world.makeTypeBinding(signature.getDeclaringType());
  51. this.declaringClass = (ReferenceBinding) world.makeTypeBinding(withinType);
  52. // Ok, we need to set the typevariable declaring elements
  53. // 1st set:
  54. // If the typevariable is one declared on the source method, then we know we are the declaring element
  55. for (int i = 0; i < typeVariables.length; i++) {
  56. typeVariables[i].declaringElement = this;
  57. }
  58. for (int i = 0; i < typeVariables.length; i++) {
  59. if (typeVariables[i].declaringElement == null)
  60. throw new RuntimeException("Declaring element not set");
  61. }
  62. // typeVariables[0].declaringElement=this;
  63. // if (tVar.getDeclaringElement() instanceof Member) {
  64. // declaringElement = makeMethodBinding((ResolvedMember)tVar.getDeclaringElement());
  65. // } else {
  66. // declaringElement = makeTypeBinding((UnresolvedType)tVar.getDeclaringElement());
  67. // }
  68. if (signature.getKind() == Member.METHOD) {
  69. syntheticMethod = world.makeMethodBinding(AjcMemberMaker.interMethodDispatcher(signature, withinType));
  70. postDispatchMethod = world.makeMethodBinding(AjcMemberMaker.interMethodBody(signature, withinType));
  71. } else {
  72. syntheticMethod = world.makeMethodBinding(AjcMemberMaker.interConstructor(world.getWorld().resolve(
  73. signature.getDeclaringType()), signature, withinType));
  74. postDispatchMethod = syntheticMethod;
  75. }
  76. }
  77. // XXX this is identical to InterTypeFieldBinding
  78. @Override
  79. public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
  80. scope.compilationUnitScope().recordTypeReference(declaringClass);
  81. if (isPublic())
  82. return true;
  83. SourceTypeBinding invocationType = scope.invocationType();
  84. // System.out.println("receiver: " + receiverType + ", " + invocationType);
  85. if (invocationType == declaringClass)
  86. return true;
  87. if (invocationType.privilegedHandler != null) {
  88. // it is a privileged aspect
  89. return true;
  90. }
  91. if (isProtected()) {
  92. throw new RuntimeException("unimplemented");
  93. }
  94. // XXX make sure this walks correctly
  95. if (isPrivate()) {
  96. // Possibly the call is made from an inner type within the privileged aspect
  97. // TODO should check the first outer aspect we come across and stop at that point?
  98. if (invocationType.isNestedType()) {
  99. TypeBinding enclosingType = invocationType.enclosingType();
  100. while (enclosingType != null) {
  101. if ((enclosingType instanceof SourceTypeBinding) && ((SourceTypeBinding)enclosingType).privilegedHandler != null) {
  102. return true;
  103. }
  104. enclosingType = enclosingType.enclosingType();
  105. }
  106. }
  107. // answer true if the receiverType is the declaringClass
  108. // AND the invocationType and the declaringClass have a common enclosingType
  109. // if (receiverType != declaringClass) return false;
  110. if (invocationType != declaringClass) {
  111. ReferenceBinding outerInvocationType = invocationType;
  112. ReferenceBinding temp = outerInvocationType.enclosingType();
  113. while (temp != null) {
  114. outerInvocationType = temp;
  115. temp = temp.enclosingType();
  116. }
  117. ReferenceBinding outerDeclaringClass = declaringClass;
  118. temp = outerDeclaringClass.enclosingType();
  119. while (temp != null) {
  120. outerDeclaringClass = temp;
  121. temp = temp.enclosingType();
  122. }
  123. // System.err.println("outer dec: " +
  124. if (outerInvocationType != outerDeclaringClass)
  125. return false;
  126. }
  127. return true;
  128. }
  129. // isDefault()
  130. if (invocationType.fPackage == declaringClass.fPackage)
  131. return true;
  132. return false;
  133. }
  134. @Override
  135. public boolean isFinal() {
  136. if (sourceMethod == null || !(sourceMethod instanceof InterTypeMethodDeclaration))
  137. return super.isFinal();
  138. return ((InterTypeMethodDeclaration) sourceMethod).isFinal();
  139. }
  140. @Override
  141. public MethodBinding getAccessMethod(boolean staticReference) {
  142. if (staticReference)
  143. return postDispatchMethod;
  144. else
  145. return syntheticMethod;
  146. }
  147. @Override
  148. public boolean alwaysNeedsAccessMethod() {
  149. return true;
  150. }
  151. @Override
  152. public AbstractMethodDeclaration sourceMethod() {
  153. return sourceMethod;
  154. }
  155. public ReferenceBinding getTargetType() {
  156. return targetType;
  157. }
  158. // override method in MethodBinding to ensure correct behaviour in some of JDTs generics checks.
  159. @Override
  160. public ReferenceBinding getOwningClass() {
  161. return targetType;
  162. }
  163. @Override
  164. public String toString() {
  165. return "InterTypeMethodBinding(" + super.toString() + ", " + getTargetType() + ")";
  166. }
  167. }