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.3KB

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