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 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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 Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * ******************************************************************/
  10. package org.aspectj.weaver.patterns;
  11. import java.io.DataInputStream;
  12. import java.io.DataOutputStream;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import org.aspectj.util.FuzzyBoolean;
  16. import org.aspectj.weaver.ISourceContext;
  17. import org.aspectj.weaver.IntMap;
  18. import org.aspectj.weaver.ResolvedTypeX;
  19. import org.aspectj.weaver.World;
  20. /**
  21. * @author colyer
  22. *
  23. * TODO To change the template for this generated type comment go to
  24. * Window - Preferences - Java - Code Style - Code Templates
  25. */
  26. public class AnnotationPatternList extends PatternNode {
  27. private AnnotationTypePattern[] typePatterns;
  28. int ellipsisCount = 0;
  29. public static final AnnotationPatternList EMPTY =
  30. new AnnotationPatternList(new AnnotationTypePattern[] {});
  31. public static final AnnotationPatternList ANY =
  32. new AnnotationPatternList(new AnnotationTypePattern[] {AnnotationTypePattern.ELLIPSIS});
  33. public AnnotationPatternList() {
  34. typePatterns = new AnnotationTypePattern[0];
  35. ellipsisCount = 0;
  36. }
  37. public AnnotationPatternList(AnnotationTypePattern[] arguments) {
  38. this.typePatterns = arguments;
  39. for (int i=0; i<arguments.length; i++) {
  40. if (arguments[i] == AnnotationTypePattern.ELLIPSIS) ellipsisCount++;
  41. }
  42. }
  43. public AnnotationPatternList(List l) {
  44. this((AnnotationTypePattern[]) l.toArray(new AnnotationTypePattern[l.size()]));
  45. }
  46. protected AnnotationTypePattern[] getAnnotationPatterns() {
  47. return typePatterns;
  48. }
  49. public void resolve(World inWorld) {
  50. for (int i = 0; i < typePatterns.length; i++) {
  51. typePatterns[i].resolve(inWorld);
  52. }
  53. }
  54. public FuzzyBoolean matches(ResolvedTypeX[] someArgs) {
  55. // do some quick length tests first
  56. int numArgsMatchedByEllipsis = (someArgs.length + ellipsisCount) - typePatterns.length;
  57. if (numArgsMatchedByEllipsis < 0) return FuzzyBoolean.NO;
  58. if ((numArgsMatchedByEllipsis > 0) && (ellipsisCount == 0)) {
  59. return FuzzyBoolean.NO;
  60. }
  61. // now work through the args and the patterns, skipping at ellipsis
  62. FuzzyBoolean ret = FuzzyBoolean.YES;
  63. int argsIndex = 0;
  64. for (int i = 0; i < typePatterns.length; i++) {
  65. if (typePatterns[i] == AnnotationTypePattern.ELLIPSIS) {
  66. // match ellipsisMatchCount args
  67. argsIndex += numArgsMatchedByEllipsis;
  68. } else if (typePatterns[i] == AnnotationTypePattern.ANY) {
  69. argsIndex++;
  70. } else {
  71. // match the argument type at argsIndex with the ExactAnnotationTypePattern
  72. // we know it is exact because nothing else is allowed in args
  73. ExactAnnotationTypePattern ap = (ExactAnnotationTypePattern)typePatterns[i];
  74. FuzzyBoolean matches = ap.matches(someArgs[argsIndex]);
  75. if (matches == FuzzyBoolean.NO) {
  76. return FuzzyBoolean.MAYBE; // could still match at runtime
  77. } else {
  78. argsIndex++;
  79. ret = ret.and(matches);
  80. }
  81. }
  82. }
  83. return ret;
  84. }
  85. public int size() { return typePatterns.length; }
  86. public AnnotationTypePattern get(int index) {
  87. return typePatterns[index];
  88. }
  89. public AnnotationPatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding) {
  90. for (int i=0; i<typePatterns.length; i++) {
  91. AnnotationTypePattern p = typePatterns[i];
  92. if (p != null) {
  93. typePatterns[i] = typePatterns[i].resolveBindings(scope, bindings, allowBinding);
  94. }
  95. }
  96. return this;
  97. }
  98. public AnnotationPatternList resolveReferences(IntMap bindings) {
  99. int len = typePatterns.length;
  100. AnnotationTypePattern[] ret = new AnnotationTypePattern[len];
  101. for (int i=0; i < len; i++) {
  102. ret[i] = typePatterns[i].remapAdviceFormals(bindings);
  103. }
  104. return new AnnotationPatternList(ret);
  105. }
  106. public String toString() {
  107. StringBuffer buf = new StringBuffer();
  108. buf.append("(");
  109. for (int i=0, len=typePatterns.length; i < len; i++) {
  110. AnnotationTypePattern type = typePatterns[i];
  111. if (i > 0) buf.append(", ");
  112. if (type == AnnotationTypePattern.ELLIPSIS) {
  113. buf.append("..");
  114. } else {
  115. buf.append(type.toString());
  116. }
  117. }
  118. buf.append(")");
  119. return buf.toString();
  120. }
  121. public boolean equals(Object other) {
  122. if (!(other instanceof AnnotationPatternList)) return false;
  123. AnnotationPatternList o = (AnnotationPatternList)other;
  124. int len = o.typePatterns.length;
  125. if (len != this.typePatterns.length) return false;
  126. for (int i=0; i<len; i++) {
  127. if (!this.typePatterns[i].equals(o.typePatterns[i])) return false;
  128. }
  129. return true;
  130. }
  131. public int hashCode() {
  132. int result = 41;
  133. for (int i = 0, len = typePatterns.length; i < len; i++) {
  134. result = 37*result + typePatterns[i].hashCode();
  135. }
  136. return result;
  137. }
  138. public static AnnotationPatternList read(DataInputStream s, ISourceContext context) throws IOException {
  139. short len = s.readShort();
  140. AnnotationTypePattern[] arguments = new AnnotationTypePattern[len];
  141. for (int i=0; i<len; i++) {
  142. arguments[i] = AnnotationTypePattern.read(s, context);
  143. }
  144. AnnotationPatternList ret = new AnnotationPatternList(arguments);
  145. ret.readLocation(context, s);
  146. return ret;
  147. }
  148. public void write(DataOutputStream s) throws IOException {
  149. s.writeShort(typePatterns.length);
  150. for (int i=0; i<typePatterns.length; i++) {
  151. typePatterns[i].write(s);
  152. }
  153. writeLocation(s);
  154. }
  155. }