Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

Checker.java 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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;
  13. import java.util.Collection;
  14. import java.util.Collections;
  15. import java.util.Map;
  16. import org.aspectj.bridge.ISourceLocation;
  17. import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
  18. import org.aspectj.weaver.patterns.PerClause;
  19. import org.aspectj.weaver.patterns.Pointcut;
  20. /**
  21. * Representation of a shadow munger for a declare error or warning declaration.
  22. *
  23. * @author Andy Clement
  24. */
  25. public class Checker extends ShadowMunger {
  26. private boolean isError; // if not error then it is a warning
  27. private String message;
  28. private volatile int hashCode = -1;
  29. @SuppressWarnings("unused")
  30. private Checker() {
  31. }
  32. /**
  33. * Create a Checker for a declare error or declare warning.
  34. *
  35. * @param deow the declare error or declare warning for which to create the checker munger
  36. */
  37. public Checker(DeclareErrorOrWarning deow) {
  38. super(deow.getPointcut(), deow.getStart(), deow.getEnd(), deow.getSourceContext(), ShadowMungerDeow);
  39. this.message = deow.getMessage();
  40. this.isError = deow.isError();
  41. }
  42. /**
  43. * Only used when filling in a parameterized Checker
  44. */
  45. private Checker(Pointcut pointcut, int start, int end, ISourceContext context, String message, boolean isError) {
  46. super(pointcut, start, end, context, ShadowMungerDeow);
  47. this.message = message;
  48. this.isError = isError;
  49. }
  50. public boolean isError() {
  51. return isError;
  52. }
  53. public String getMessage(Shadow shadow) {
  54. return format(this.message, shadow);
  55. }
  56. @Override
  57. public void specializeOn(Shadow shadow) {
  58. throw new IllegalStateException("Cannot call specializeOn(...) for a Checker");
  59. }
  60. @Override
  61. public boolean implementOn(Shadow shadow) {
  62. throw new IllegalStateException("Cannot call implementOn(...) for a Checker");
  63. }
  64. /**
  65. * Determine if the Checker matches at a shadow. If it does then we can immediately report the message. Currently, there can
  66. * never be a non-statically determinable match.
  67. *
  68. * @param shadow the shadow which to match against
  69. * @param world the world through which to access message handlers
  70. */
  71. @Override
  72. public boolean match(Shadow shadow, World world) {
  73. if (super.match(shadow, world)) {
  74. world.reportCheckerMatch(this, shadow);
  75. }
  76. return false;
  77. }
  78. // implementation for PartialOrder.PartialComparable
  79. public int compareTo(Object other) {
  80. return 0;
  81. }
  82. @Override
  83. public boolean mustCheckExceptions() {
  84. return true;
  85. }
  86. @Override
  87. public Collection<ResolvedType> getThrownExceptions() {
  88. return Collections.emptyList();
  89. }
  90. // FIXME this perhaps ought to take account of the other fields in advice (use super.equals?)
  91. @Override
  92. public boolean equals(Object other) {
  93. if (!(other instanceof Checker)) {
  94. return false;
  95. }
  96. Checker o = (Checker) other;
  97. return o.isError == isError && ((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut));
  98. }
  99. @Override
  100. public int hashCode() {
  101. if (hashCode == -1) {
  102. int result = 17;
  103. result = 37 * result + (isError ? 1 : 0);
  104. result = 37 * result + ((pointcut == null) ? 0 : pointcut.hashCode());
  105. hashCode = result;
  106. }
  107. return hashCode;
  108. }
  109. /**
  110. * Parameterize the Checker by parameterizing the pointcut
  111. */
  112. @Override
  113. public ShadowMunger parameterizeWith(ResolvedType declaringType, Map<String, UnresolvedType> typeVariableMap) {
  114. Checker ret = new Checker(this.pointcut.parameterizeWith(typeVariableMap, declaringType.getWorld()), this.start, this.end,
  115. this.sourceContext, this.message, this.isError);
  116. return ret;
  117. }
  118. /**
  119. * Concretize this Checker by concretizing the pointcut
  120. */
  121. @Override
  122. public ShadowMunger concretize(ResolvedType theAspect, World world, PerClause clause) {
  123. this.pointcut = this.pointcut.concretize(theAspect, getDeclaringType(), 0, this);
  124. this.hashCode = -1;
  125. return this;
  126. }
  127. @Override
  128. public ResolvedType getConcreteAspect() {
  129. return getDeclaringType();
  130. }
  131. // public void write(DataOutputStream stream) throws IOException {
  132. // super.write(stream);
  133. // stream.writeBoolean(isError);
  134. // stream.writeUTF(message);
  135. // }
  136. //
  137. // public static Checker read(DataInputStream stream, World world) throws IOException {
  138. // Checker checker = new Checker();
  139. // checker.isError = stream.readBoolean();
  140. // checker.message = stream.readUTF();
  141. // return checker;
  142. // }
  143. // Return the next non-escaped (with a '\') open curly
  144. private int nextCurly(String string, int pos) {
  145. do {
  146. int curlyIndex = string.indexOf('{', pos);
  147. if (curlyIndex == -1) {
  148. return -1;
  149. }
  150. if (curlyIndex == 0) {
  151. return 0;
  152. }
  153. if (string.charAt(curlyIndex - 1) != '\\') {
  154. return curlyIndex;
  155. }
  156. pos = curlyIndex + 1;
  157. } while (pos < string.length());
  158. return -1;
  159. }
  160. private String format(String msg, Shadow shadow) {
  161. int pos = 0;
  162. int curlyIndex = nextCurly(msg, 0);
  163. if (curlyIndex == -1) {
  164. // was there an escaped one?
  165. if (msg.indexOf('{') != -1) {
  166. return msg.replace("\\{", "{");
  167. } else {
  168. return msg;
  169. }
  170. }
  171. StringBuilder ret = new StringBuilder();
  172. while (curlyIndex >= 0) {
  173. if (curlyIndex > 0) {
  174. ret.append(msg.substring(pos, curlyIndex).replace("\\{", "{"));
  175. }
  176. int endCurly = msg.indexOf('}', curlyIndex);
  177. if (endCurly == -1) {
  178. // wasn't closed properly - ignore it
  179. ret.append('{');
  180. pos = curlyIndex + 1;
  181. } else {
  182. ret.append(getValue(msg.substring(curlyIndex + 1, endCurly), shadow));
  183. }
  184. pos = endCurly + 1;
  185. curlyIndex = nextCurly(msg, pos);
  186. }
  187. ret.append(msg.substring(pos, msg.length()));
  188. return ret.toString();
  189. }
  190. /**
  191. * @param buf the buffer in which to insert the substitution
  192. * @param shadow shadow from which to draw context info
  193. * @param c the substitution character
  194. */
  195. private String getValue(String key, Shadow shadow) {
  196. if (key.equalsIgnoreCase("joinpoint")) {
  197. return shadow.toString();
  198. } else if (key.equalsIgnoreCase("joinpoint.kind")) {
  199. return shadow.getKind().getName();
  200. } else if (key.equalsIgnoreCase("joinpoint.enclosingclass")) {
  201. return shadow.getEnclosingType().getName();
  202. } else if (key.equalsIgnoreCase("joinpoint.enclosingmember.name")) {
  203. Member member = shadow.getEnclosingCodeSignature();
  204. if (member==null) {
  205. return "";
  206. } else {
  207. return member.getName();
  208. }
  209. } else if (key.equalsIgnoreCase("joinpoint.enclosingmember")) {
  210. Member member = shadow.getEnclosingCodeSignature();
  211. if (member==null) {
  212. return "";
  213. } else {
  214. return member.toString();
  215. }
  216. } else if (key.equalsIgnoreCase("joinpoint.signature")) {
  217. return shadow.getSignature().toString();
  218. } else if (key.equalsIgnoreCase("joinpoint.signature.declaringtype")) {
  219. return shadow.getSignature().getDeclaringType().toString();
  220. } else if (key.equalsIgnoreCase("joinpoint.signature.name")) {
  221. return shadow.getSignature().getName();
  222. } else if (key.equalsIgnoreCase("joinpoint.sourcelocation.sourcefile")) {
  223. ISourceLocation loc = shadow.getSourceLocation();
  224. if ((loc != null) && (loc.getSourceFile() != null)) {
  225. return loc.getSourceFile().toString();
  226. } else {
  227. return "UNKNOWN";
  228. }
  229. } else if (key.equalsIgnoreCase("joinpoint.sourcelocation.line")) {
  230. ISourceLocation loc = shadow.getSourceLocation();
  231. if (loc != null) {
  232. return Integer.toString(loc.getLine());
  233. } else {
  234. return "-1";
  235. }
  236. } else if (key.equalsIgnoreCase("advice.aspecttype")) {
  237. return getDeclaringType().getName();
  238. } else if (key.equalsIgnoreCase("advice.sourcelocation.line")) {
  239. ISourceLocation loc = getSourceLocation();
  240. if ((loc != null) && (loc.getSourceFile() != null)) {
  241. return Integer.toString(loc.getLine());
  242. } else {
  243. return "-1";
  244. }
  245. } else if (key.equalsIgnoreCase("advice.sourcelocation.sourcefile")) {
  246. ISourceLocation loc = getSourceLocation();
  247. if ((loc != null) && (loc.getSourceFile() != null)) {
  248. return loc.getSourceFile().toString();
  249. } else {
  250. return "UNKNOWN";
  251. }
  252. } else {
  253. return "UNKNOWN_KEY{" + key + "}";
  254. }
  255. }
  256. }