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.

AnnotationPatternList.java 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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 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. * ******************************************************************/
  10. package org.aspectj.weaver.patterns;
  11. import java.io.IOException;
  12. import java.util.List;
  13. import java.util.Map;
  14. import org.aspectj.util.FuzzyBoolean;
  15. import org.aspectj.weaver.CompressingDataOutputStream;
  16. import org.aspectj.weaver.ISourceContext;
  17. import org.aspectj.weaver.IntMap;
  18. import org.aspectj.weaver.ResolvedType;
  19. import org.aspectj.weaver.UnresolvedType;
  20. import org.aspectj.weaver.VersionedDataInputStream;
  21. import org.aspectj.weaver.World;
  22. /**
  23. * @author Adrian Colyer
  24. */
  25. public class AnnotationPatternList extends PatternNode {
  26. private AnnotationTypePattern[] typePatterns;
  27. int ellipsisCount = 0;
  28. public static final AnnotationPatternList EMPTY = new AnnotationPatternList(AnnotationTypePattern.NONE);
  29. public static final AnnotationPatternList ANY = new AnnotationPatternList(
  30. new AnnotationTypePattern[] { AnnotationTypePattern.ELLIPSIS });
  31. public AnnotationPatternList() {
  32. typePatterns = AnnotationTypePattern.NONE;
  33. ellipsisCount = 0;
  34. }
  35. public AnnotationPatternList(AnnotationTypePattern[] arguments) {
  36. this.typePatterns = arguments;
  37. for (AnnotationTypePattern argument : arguments) {
  38. if (argument == AnnotationTypePattern.ELLIPSIS) {
  39. ellipsisCount++;
  40. }
  41. }
  42. }
  43. public AnnotationPatternList(List<AnnotationTypePattern> l) {
  44. this(l.toArray(AnnotationTypePattern.NONE));
  45. }
  46. protected AnnotationTypePattern[] getAnnotationPatterns() {
  47. return typePatterns;
  48. }
  49. public AnnotationPatternList parameterizeWith(Map<String,UnresolvedType> typeVariableMap, World w) {
  50. AnnotationTypePattern[] parameterizedPatterns = new AnnotationTypePattern[this.typePatterns.length];
  51. for (int i = 0; i < parameterizedPatterns.length; i++) {
  52. parameterizedPatterns[i] = this.typePatterns[i].parameterizeWith(typeVariableMap, w);
  53. }
  54. AnnotationPatternList ret = new AnnotationPatternList(parameterizedPatterns);
  55. ret.copyLocationFrom(this);
  56. return ret;
  57. }
  58. public void resolve(World inWorld) {
  59. for (AnnotationTypePattern typePattern : typePatterns) {
  60. typePattern.resolve(inWorld);
  61. }
  62. }
  63. public FuzzyBoolean matches(ResolvedType[] someArgs) {
  64. // do some quick length tests first
  65. int numArgsMatchedByEllipsis = (someArgs.length + ellipsisCount) - typePatterns.length;
  66. if (numArgsMatchedByEllipsis < 0) {
  67. return FuzzyBoolean.NO;
  68. }
  69. if ((numArgsMatchedByEllipsis > 0) && (ellipsisCount == 0)) {
  70. return FuzzyBoolean.NO;
  71. }
  72. // now work through the args and the patterns, skipping at ellipsis
  73. FuzzyBoolean ret = FuzzyBoolean.YES;
  74. int argsIndex = 0;
  75. for (AnnotationTypePattern typePattern : typePatterns) {
  76. if (typePattern == AnnotationTypePattern.ELLIPSIS) {
  77. // match ellipsisMatchCount args
  78. argsIndex += numArgsMatchedByEllipsis;
  79. } else if (typePattern == AnnotationTypePattern.ANY) {
  80. argsIndex++;
  81. } else {
  82. // match the argument type at argsIndex with the ExactAnnotationTypePattern
  83. // we know it is exact because nothing else is allowed in args
  84. if (someArgs[argsIndex].isPrimitiveType()) {
  85. return FuzzyBoolean.NO; // can never match
  86. }
  87. ExactAnnotationTypePattern ap = (ExactAnnotationTypePattern) typePattern;
  88. FuzzyBoolean matches = ap.matchesRuntimeType(someArgs[argsIndex]);
  89. if (matches == FuzzyBoolean.NO) {
  90. return FuzzyBoolean.MAYBE; // could still match at runtime
  91. } else {
  92. argsIndex++;
  93. ret = ret.and(matches);
  94. }
  95. }
  96. }
  97. return ret;
  98. }
  99. public int size() {
  100. return typePatterns.length;
  101. }
  102. public AnnotationTypePattern get(int index) {
  103. return typePatterns[index];
  104. }
  105. public AnnotationPatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) {
  106. for (int i = 0; i < typePatterns.length; i++) {
  107. AnnotationTypePattern p = typePatterns[i];
  108. if (p != null) {
  109. typePatterns[i] = typePatterns[i].resolveBindings(scope, bindings, allowBinding);
  110. }
  111. }
  112. return this;
  113. }
  114. public AnnotationPatternList resolveReferences(IntMap bindings) {
  115. int len = typePatterns.length;
  116. AnnotationTypePattern[] ret = new AnnotationTypePattern[len];
  117. for (int i = 0; i < len; i++) {
  118. ret[i] = typePatterns[i].remapAdviceFormals(bindings);
  119. }
  120. return new AnnotationPatternList(ret);
  121. }
  122. public String toString() {
  123. StringBuilder buf = new StringBuilder();
  124. buf.append("(");
  125. for (int i = 0, len = typePatterns.length; i < len; i++) {
  126. AnnotationTypePattern type = typePatterns[i];
  127. if (i > 0) {
  128. buf.append(", ");
  129. }
  130. if (type == AnnotationTypePattern.ELLIPSIS) {
  131. buf.append("..");
  132. } else {
  133. String annPatt = type.toString();
  134. buf.append(annPatt.startsWith("@") ? annPatt.substring(1) : annPatt);
  135. }
  136. }
  137. buf.append(")");
  138. return buf.toString();
  139. }
  140. public boolean equals(Object other) {
  141. if (!(other instanceof AnnotationPatternList)) {
  142. return false;
  143. }
  144. AnnotationPatternList o = (AnnotationPatternList) other;
  145. int len = o.typePatterns.length;
  146. if (len != this.typePatterns.length) {
  147. return false;
  148. }
  149. for (int i = 0; i < len; i++) {
  150. if (!this.typePatterns[i].equals(o.typePatterns[i])) {
  151. return false;
  152. }
  153. }
  154. return true;
  155. }
  156. public int hashCode() {
  157. int result = 41;
  158. for (AnnotationTypePattern typePattern : typePatterns) {
  159. result = 37 * result + typePattern.hashCode();
  160. }
  161. return result;
  162. }
  163. public static AnnotationPatternList read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  164. short len = s.readShort();
  165. AnnotationTypePattern[] arguments = new AnnotationTypePattern[len];
  166. for (int i = 0; i < len; i++) {
  167. arguments[i] = AnnotationTypePattern.read(s, context);
  168. }
  169. AnnotationPatternList ret = new AnnotationPatternList(arguments);
  170. ret.readLocation(context, s);
  171. return ret;
  172. }
  173. public void write(CompressingDataOutputStream s) throws IOException {
  174. s.writeShort(typePatterns.length);
  175. for (AnnotationTypePattern typePattern : typePatterns) {
  176. typePattern.write(s);
  177. }
  178. writeLocation(s);
  179. }
  180. public Object accept(PatternNodeVisitor visitor, Object data) {
  181. return visitor.visit(this, data);
  182. }
  183. public Object traverse(PatternNodeVisitor visitor, Object data) {
  184. Object ret = accept(visitor, data);
  185. for (AnnotationTypePattern typePattern : typePatterns) {
  186. typePattern.traverse(visitor, ret);
  187. }
  188. return ret;
  189. }
  190. }