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.

ConcreteCflowPointcut.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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 v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.patterns;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. import org.aspectj.bridge.ISourceLocation;
  17. import org.aspectj.bridge.Message;
  18. import org.aspectj.util.FuzzyBoolean;
  19. import org.aspectj.weaver.CompressingDataOutputStream;
  20. import org.aspectj.weaver.IntMap;
  21. import org.aspectj.weaver.Member;
  22. import org.aspectj.weaver.MemberImpl;
  23. import org.aspectj.weaver.NameMangler;
  24. import org.aspectj.weaver.ResolvedType;
  25. import org.aspectj.weaver.Shadow;
  26. import org.aspectj.weaver.UnresolvedType;
  27. import org.aspectj.weaver.WeaverMessages;
  28. import org.aspectj.weaver.World;
  29. import org.aspectj.weaver.ast.Expr;
  30. import org.aspectj.weaver.ast.Test;
  31. public class ConcreteCflowPointcut extends Pointcut {
  32. private final Member cflowField;
  33. List<Slot> slots; // exposed for testing
  34. boolean usesCounter;
  35. ResolvedType aspect;
  36. // Can either use a counter or a stack to implement cflow.
  37. public ConcreteCflowPointcut(ResolvedType aspect, Member cflowField, List<Slot> slots, boolean usesCounter) {
  38. this.aspect = aspect;
  39. this.cflowField = cflowField;
  40. this.slots = slots;
  41. this.usesCounter = usesCounter;
  42. this.pointcutKind = CFLOW;
  43. }
  44. public int couldMatchKinds() {
  45. return Shadow.ALL_SHADOW_KINDS_BITS;
  46. }
  47. public FuzzyBoolean fastMatch(FastMatchInfo type) {
  48. return FuzzyBoolean.MAYBE;
  49. }
  50. protected FuzzyBoolean matchInternal(Shadow shadow) {
  51. // ??? this is not maximally efficient
  52. // Check we'll be able to do the residue!
  53. // this bit is for pr145693 - we cannot match at all if one of the types is missing, we will be unable
  54. // to create the residue
  55. if (slots != null) {
  56. for (Slot slot: slots) {
  57. ResolvedType rt = slot.formalType;
  58. if (rt.isMissing()) {
  59. ISourceLocation[] locs = new ISourceLocation[] { getSourceLocation() };
  60. Message m = new Message(WeaverMessages.format(WeaverMessages.MISSING_TYPE_PREVENTS_MATCH, rt.getName()), "",
  61. Message.WARNING, shadow.getSourceLocation(), null, locs);
  62. rt.getWorld().getMessageHandler().handleMessage(m);
  63. return FuzzyBoolean.NO;
  64. }
  65. }
  66. }
  67. return FuzzyBoolean.MAYBE;
  68. }
  69. // used by weaver when validating bindings
  70. public int[] getUsedFormalSlots() {
  71. if (slots == null) {
  72. return new int[0];
  73. }
  74. int[] indices = new int[slots.size()];
  75. for (int i = 0; i < indices.length; i++) {
  76. indices[i] = slots.get(i).formalIndex;
  77. }
  78. return indices;
  79. }
  80. public void write(CompressingDataOutputStream s) throws IOException {
  81. throw new RuntimeException("unimplemented");
  82. }
  83. public void resolveBindings(IScope scope, Bindings bindings) {
  84. throw new RuntimeException("unimplemented");
  85. }
  86. public Pointcut parameterizeWith(Map<String,UnresolvedType> typeVariableMap, World w) {
  87. throw new RuntimeException("unimplemented");
  88. }
  89. public boolean equals(Object other) {
  90. if (!(other instanceof ConcreteCflowPointcut)) {
  91. return false;
  92. }
  93. ConcreteCflowPointcut o = (ConcreteCflowPointcut) other;
  94. return o.cflowField.equals(this.cflowField);
  95. }
  96. public int hashCode() {
  97. int result = 17;
  98. result = 37 * result + cflowField.hashCode();
  99. return result;
  100. }
  101. public String toString() {
  102. return "concretecflow(" + cflowField + ")";
  103. }
  104. protected Test findResidueInternal(Shadow shadow, ExposedState state) {
  105. // System.out.println("find residue: " + this);
  106. if (usesCounter) {
  107. return Test.makeFieldGetCall(cflowField, cflowCounterIsValidMethod, Expr.NONE);
  108. } else {
  109. if (slots != null) { // null for cflows managed by counters
  110. for (Slot slot: slots) {
  111. // System.out.println("slot: " + slot.formalIndex);
  112. state.set(slot.formalIndex,
  113. aspect.getWorld().getWeavingSupport().makeCflowAccessVar(slot.formalType, cflowField, slot.arrayIndex));
  114. }
  115. }
  116. return Test.makeFieldGetCall(cflowField, cflowStackIsValidMethod, Expr.NONE);
  117. }
  118. }
  119. private static final Member cflowStackIsValidMethod = MemberImpl.method(NameMangler.CFLOW_STACK_UNRESOLVEDTYPE, 0,
  120. UnresolvedType.BOOLEAN, "isValid", UnresolvedType.NONE);
  121. private static final Member cflowCounterIsValidMethod = MemberImpl.method(NameMangler.CFLOW_COUNTER_UNRESOLVEDTYPE, 0,
  122. UnresolvedType.BOOLEAN, "isValid", UnresolvedType.NONE);
  123. public Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) {
  124. throw new RuntimeException("unimplemented");
  125. }
  126. public Object accept(PatternNodeVisitor visitor, Object data) {
  127. return visitor.visit(this, data);
  128. }
  129. public static class Slot {
  130. int formalIndex;
  131. ResolvedType formalType;
  132. int arrayIndex;
  133. public Slot(int formalIndex, ResolvedType formalType, int arrayIndex) {
  134. this.formalIndex = formalIndex;
  135. this.formalType = formalType;
  136. this.arrayIndex = arrayIndex;
  137. }
  138. public boolean equals(Object other) {
  139. if (!(other instanceof Slot)) {
  140. return false;
  141. }
  142. Slot o = (Slot) other;
  143. return o.formalIndex == this.formalIndex && o.arrayIndex == this.arrayIndex && o.formalType.equals(this.formalType);
  144. }
  145. public int hashCode() {
  146. int result = 19;
  147. result = 37 * result + formalIndex;
  148. result = 37 * result + arrayIndex;
  149. result = 37 * result + formalType.hashCode();
  150. return result;
  151. }
  152. public String toString() {
  153. return "Slot(" + formalIndex + ", " + formalType + ", " + arrayIndex + ")";
  154. }
  155. }
  156. }