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.

PointcutEvaluationExpenseComparator.java 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation.
  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. * ******************************************************************/
  10. package org.aspectj.weaver.patterns;
  11. import java.util.Comparator;
  12. import org.aspectj.weaver.Shadow;
  13. public class PointcutEvaluationExpenseComparator implements Comparator<Pointcut> {
  14. private static final int MATCHES_NOTHING = -1;
  15. private static final int WITHIN = 1;
  16. private static final int ATWITHIN = 2;
  17. private static final int STATICINIT = 3;
  18. private static final int ADVICEEXECUTION = 4;
  19. private static final int HANDLER = 5;
  20. private static final int GET_OR_SET = 6;
  21. private static final int WITHINCODE = 7;
  22. private static final int ATWITHINCODE = 8;
  23. private static final int EXE_INIT_PREINIT = 9;
  24. private static final int CALL_WITH_DECLARING_TYPE = 10;
  25. private static final int THIS_OR_TARGET = 11;
  26. private static final int CALL_WITHOUT_DECLARING_TYPE = 12;
  27. private static final int ANNOTATION = 13;
  28. private static final int AT_THIS_OR_TARGET = 14;
  29. private static final int ARGS = 15;
  30. private static final int AT_ARGS = 16;
  31. private static final int CFLOW = 17;
  32. private static final int IF = 18;
  33. private static final int OTHER = 20;
  34. /**
  35. * Compare 2 pointcuts based on an estimate of how expensive they may be to evaluate.
  36. *
  37. * within
  38. *
  39. * {@literal @}within staticinitialization [make sure this has a fast match method] adviceexecution handler get, set withincode
  40. * {@literal @}withincode execution, initialization, preinitialization call
  41. * {@literal @}annotation this, target
  42. * {@literal @}this, {@literal @}target args
  43. * {@literal @}args cflow, cflowbelow if
  44. */
  45. public int compare(Pointcut p1, Pointcut p2) {
  46. // important property for a well-defined comparator
  47. if (p1.equals(p2)) {
  48. return 0;
  49. }
  50. int result = getScore(p1) - getScore(p2);
  51. if (result == 0) {
  52. // they have the same evaluation expense, but are not 'equal'
  53. // sort by hashCode
  54. int p1code = p1.hashCode();
  55. int p2code = p2.hashCode();
  56. if (p1code == p2code) {
  57. return 0;
  58. } else if (p1code < p2code) {
  59. return -1;
  60. } else {
  61. return +1;
  62. }
  63. }
  64. return result;
  65. }
  66. // a higher score means a more expensive evaluation
  67. private int getScore(Pointcut p) {
  68. if (p.couldMatchKinds() == Shadow.NO_SHADOW_KINDS_BITS) {
  69. return MATCHES_NOTHING;
  70. }
  71. if (p instanceof WithinPointcut) {
  72. return WITHIN;
  73. }
  74. if (p instanceof WithinAnnotationPointcut) {
  75. return ATWITHIN;
  76. }
  77. if (p instanceof KindedPointcut) {
  78. KindedPointcut kp = (KindedPointcut) p;
  79. Shadow.Kind kind = kp.getKind();
  80. if (kind == Shadow.AdviceExecution) {
  81. return ADVICEEXECUTION;
  82. } else if ((kind == Shadow.ConstructorCall) || (kind == Shadow.MethodCall)) {
  83. TypePattern declaringTypePattern = kp.getSignature().getDeclaringType();
  84. if (declaringTypePattern instanceof AnyTypePattern) {
  85. return CALL_WITHOUT_DECLARING_TYPE;
  86. } else {
  87. return CALL_WITH_DECLARING_TYPE;
  88. }
  89. } else if ((kind == Shadow.ConstructorExecution) || (kind == Shadow.MethodExecution) || (kind == Shadow.Initialization)
  90. || (kind == Shadow.PreInitialization)) {
  91. return EXE_INIT_PREINIT;
  92. } else if (kind == Shadow.ExceptionHandler) {
  93. return HANDLER;
  94. } else if ((kind == Shadow.FieldGet) || (kind == Shadow.FieldSet)) {
  95. return GET_OR_SET;
  96. } else if (kind == Shadow.StaticInitialization) {
  97. return STATICINIT;
  98. } else {
  99. return OTHER;
  100. }
  101. }
  102. if (p instanceof AnnotationPointcut) {
  103. return ANNOTATION;
  104. }
  105. if (p instanceof ArgsPointcut) {
  106. return ARGS;
  107. }
  108. if (p instanceof ArgsAnnotationPointcut) {
  109. return AT_ARGS;
  110. }
  111. if (p instanceof CflowPointcut || p instanceof ConcreteCflowPointcut) {
  112. return CFLOW;
  113. }
  114. if (p instanceof HandlerPointcut) {
  115. return HANDLER;
  116. }
  117. if (p instanceof IfPointcut) {
  118. return IF;
  119. }
  120. if (p instanceof ThisOrTargetPointcut) {
  121. return THIS_OR_TARGET;
  122. }
  123. if (p instanceof ThisOrTargetAnnotationPointcut) {
  124. return AT_THIS_OR_TARGET;
  125. }
  126. if (p instanceof WithincodePointcut) {
  127. return WITHINCODE;
  128. }
  129. if (p instanceof WithinCodeAnnotationPointcut) {
  130. return ATWITHINCODE;
  131. }
  132. if (p instanceof NotPointcut) {
  133. return getScore(((NotPointcut) p).getNegatedPointcut());
  134. }
  135. if (p instanceof AndPointcut) {
  136. int leftScore = getScore(((AndPointcut) p).getLeft());
  137. int rightScore = getScore(((AndPointcut) p).getRight());
  138. if (leftScore < rightScore) {
  139. return leftScore;
  140. } else {
  141. return rightScore;
  142. }
  143. }
  144. if (p instanceof OrPointcut) {
  145. int leftScore = getScore(((OrPointcut) p).getLeft());
  146. int rightScore = getScore(((OrPointcut) p).getRight());
  147. if (leftScore > rightScore) {
  148. return leftScore;
  149. } else {
  150. return rightScore;
  151. }
  152. }
  153. return OTHER;
  154. }
  155. }