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.

DeclarePrecedence.java 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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.IMessage;
  17. import org.aspectj.weaver.CompressingDataOutputStream;
  18. import org.aspectj.weaver.ISourceContext;
  19. import org.aspectj.weaver.ResolvedType;
  20. import org.aspectj.weaver.VersionedDataInputStream;
  21. import org.aspectj.weaver.WeaverMessages;
  22. import org.aspectj.weaver.World;
  23. public class DeclarePrecedence extends Declare {
  24. private TypePatternList patterns;
  25. private IScope scope = null; // non-null means it has not yet been resolved (used by annotation style lazy resolution)
  26. public DeclarePrecedence(List patterns) {
  27. this(new TypePatternList(patterns));
  28. }
  29. private DeclarePrecedence(TypePatternList patterns) {
  30. this.patterns = patterns;
  31. }
  32. public Object accept(PatternNodeVisitor visitor, Object data) {
  33. return visitor.visit(this, data);
  34. }
  35. public Object traverse(PatternNodeVisitor visitor, Object data) {
  36. Object ret = accept(visitor, data);
  37. if (this.patterns != null)
  38. this.patterns.traverse(visitor, ret);
  39. return ret;
  40. }
  41. public Declare parameterizeWith(Map typeVariableBindingMap, World w) {
  42. DeclarePrecedence ret = new DeclarePrecedence(this.patterns.parameterizeWith(typeVariableBindingMap, w));
  43. ret.copyLocationFrom(this);
  44. return ret;
  45. }
  46. public String toString() {
  47. StringBuilder buf = new StringBuilder();
  48. buf.append("declare precedence: ");
  49. buf.append(patterns);
  50. buf.append(";");
  51. return buf.toString();
  52. }
  53. public boolean equals(Object other) {
  54. if (!(other instanceof DeclarePrecedence)) {
  55. return false;
  56. }
  57. DeclarePrecedence o = (DeclarePrecedence) other;
  58. return o.patterns.equals(patterns);
  59. }
  60. public int hashCode() {
  61. return patterns.hashCode();
  62. }
  63. public void write(CompressingDataOutputStream s) throws IOException {
  64. s.writeByte(Declare.DOMINATES);
  65. patterns.write(s);
  66. writeLocation(s);
  67. }
  68. public static Declare read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  69. Declare ret = new DeclarePrecedence(TypePatternList.read(s, context));
  70. ret.readLocation(context, s);
  71. return ret;
  72. }
  73. public void setScopeForResolution(IScope scope) {
  74. this.scope = scope;
  75. }
  76. public void ensureResolved() { // Lazy resolution - due to pr256779
  77. if (scope != null) {
  78. try {
  79. resolve(scope);
  80. } finally {
  81. scope = null;
  82. }
  83. }
  84. }
  85. public void resolve(IScope scope) {
  86. patterns = patterns.resolveBindings(scope, Bindings.NONE, false, false);
  87. boolean seenStar = false;
  88. for (int i = 0; i < patterns.size(); i++) {
  89. TypePattern pi = patterns.get(i);
  90. if (pi.isStar()) {
  91. if (seenStar) {
  92. scope.getWorld().showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.TWO_STARS_IN_PRECEDENCE),
  93. pi.getSourceLocation(), null);
  94. }
  95. seenStar = true;
  96. continue;
  97. }
  98. ResolvedType exactType = pi.getExactType().resolve(scope.getWorld());
  99. if (exactType.isMissing()) {
  100. continue;
  101. }
  102. // Cannot do a dec prec specifying a non-aspect types unless suffixed with a '+'
  103. if (!exactType.isAspect() && !exactType.isAnnotationStyleAspect() && !pi.isIncludeSubtypes()
  104. && !exactType.isTypeVariableReference()) {
  105. scope.getWorld().showMessage(IMessage.ERROR,
  106. WeaverMessages.format(WeaverMessages.CLASSES_IN_PRECEDENCE, exactType.getName()), pi.getSourceLocation(),
  107. null);
  108. }
  109. for (int j = 0; j < patterns.size(); j++) {
  110. if (j == i) {
  111. continue;
  112. }
  113. TypePattern pj = patterns.get(j);
  114. if (pj.isStar()) {
  115. continue;
  116. }
  117. if (pj.matchesStatically(exactType)) {
  118. scope.getWorld().showMessage(IMessage.ERROR,
  119. WeaverMessages.format(WeaverMessages.TWO_PATTERN_MATCHES_IN_PRECEDENCE, exactType.getName()),
  120. pi.getSourceLocation(), pj.getSourceLocation());
  121. }
  122. }
  123. }
  124. }
  125. public TypePatternList getPatterns() {
  126. ensureResolved();
  127. return patterns;
  128. }
  129. private int matchingIndex(ResolvedType a) {
  130. ensureResolved();
  131. int knownMatch = -1;
  132. int starMatch = -1;
  133. for (int i = 0, len = patterns.size(); i < len; i++) {
  134. TypePattern p = patterns.get(i);
  135. if (p.isStar()) {
  136. starMatch = i;
  137. } else if (p.matchesStatically(a)) {
  138. if (knownMatch != -1) {
  139. a.getWorld().showMessage(IMessage.ERROR,
  140. WeaverMessages.format(WeaverMessages.MULTIPLE_MATCHES_IN_PRECEDENCE, a, patterns.get(knownMatch), p),
  141. patterns.get(knownMatch).getSourceLocation(), p.getSourceLocation());
  142. return -1;
  143. } else {
  144. knownMatch = i;
  145. }
  146. }
  147. }
  148. if (knownMatch == -1) {
  149. return starMatch;
  150. } else {
  151. return knownMatch;
  152. }
  153. }
  154. public int compare(ResolvedType aspect1, ResolvedType aspect2) {
  155. ensureResolved();
  156. int index1 = matchingIndex(aspect1);
  157. int index2 = matchingIndex(aspect2);
  158. // System.out.println("a1: " + aspect1 + ", " + aspect2 + " = " + index1 + ", " + index2);
  159. if (index1 == -1 || index2 == -1) {
  160. return 0;
  161. }
  162. if (index1 == index2) {
  163. return 0;
  164. } else if (index1 > index2) {
  165. return -1;
  166. } else {
  167. return +1;
  168. }
  169. }
  170. public boolean isAdviceLike() {
  171. return false;
  172. }
  173. public String getNameSuffix() {
  174. return "precedence";
  175. }
  176. }