aboutsummaryrefslogtreecommitdiffstats
path: root/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2019-01-23 18:53:51 -0800
committerAndy Clement <aclement@pivotal.io>2019-01-23 18:53:51 -0800
commitafaa961b294eca20fa9d54359c53a1de2d3c41fd (patch)
tree4b756f0f0dc4764cfcaeb200756de79cd4cdf56a /org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java
parent74dcae875f1c89b7e3fa2ffa6b524a3c187a597e (diff)
downloadaspectj-afaa961b294eca20fa9d54359c53a1de2d3c41fd.tar.gz
aspectj-afaa961b294eca20fa9d54359c53a1de2d3c41fd.zip
mavenized org.aspectj.matcher module - wip
Diffstat (limited to 'org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java')
-rw-r--r--org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java281
1 files changed, 281 insertions, 0 deletions
diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java
new file mode 100644
index 000000000..4a765a9e5
--- /dev/null
+++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java
@@ -0,0 +1,281 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * ******************************************************************/
+
+package org.aspectj.weaver;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
+import org.aspectj.weaver.patterns.PerClause;
+import org.aspectj.weaver.patterns.Pointcut;
+
+/**
+ * Representation of a shadow munger for a declare error or warning declaration.
+ *
+ * @author Andy Clement
+ */
+public class Checker extends ShadowMunger {
+
+ private boolean isError; // if not error then it is a warning
+ private String message;
+ private volatile int hashCode = -1;
+
+ @SuppressWarnings("unused")
+ private Checker() {
+ }
+
+ /**
+ * Create a Checker for a declare error or declare warning.
+ *
+ * @param deow the declare error or declare warning for which to create the checker munger
+ */
+ public Checker(DeclareErrorOrWarning deow) {
+ super(deow.getPointcut(), deow.getStart(), deow.getEnd(), deow.getSourceContext(), ShadowMungerDeow);
+ this.message = deow.getMessage();
+ this.isError = deow.isError();
+ }
+
+ /**
+ * Only used when filling in a parameterized Checker
+ */
+ private Checker(Pointcut pointcut, int start, int end, ISourceContext context, String message, boolean isError) {
+ super(pointcut, start, end, context, ShadowMungerDeow);
+ this.message = message;
+ this.isError = isError;
+ }
+
+ public boolean isError() {
+ return isError;
+ }
+
+ public String getMessage(Shadow shadow) {
+ return format(this.message, shadow);
+ }
+
+ @Override
+ public void specializeOn(Shadow shadow) {
+ throw new IllegalStateException("Cannot call specializeOn(...) for a Checker");
+ }
+
+ @Override
+ public boolean implementOn(Shadow shadow) {
+ throw new IllegalStateException("Cannot call implementOn(...) for a Checker");
+ }
+
+ /**
+ * Determine if the Checker matches at a shadow. If it does then we can immediately report the message. Currently, there can
+ * never be a non-statically determinable match.
+ *
+ * @param shadow the shadow which to match against
+ * @param world the world through which to access message handlers
+ */
+ @Override
+ public boolean match(Shadow shadow, World world) {
+ if (super.match(shadow, world)) {
+ world.reportCheckerMatch(this, shadow);
+ }
+ return false;
+ }
+
+ // implementation for PartialOrder.PartialComparable
+ public int compareTo(Object other) {
+ return 0;
+ }
+
+ @Override
+ public boolean mustCheckExceptions() {
+ return true;
+ }
+
+ @Override
+ public Collection<ResolvedType> getThrownExceptions() {
+ return Collections.emptyList();
+ }
+
+ // FIXME this perhaps ought to take account of the other fields in advice (use super.equals?)
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Checker)) {
+ return false;
+ }
+ Checker o = (Checker) other;
+ return o.isError == isError && ((o.pointcut == null) ? (pointcut == null) : o.pointcut.equals(pointcut));
+ }
+
+ @Override
+ public int hashCode() {
+ if (hashCode == -1) {
+ int result = 17;
+ result = 37 * result + (isError ? 1 : 0);
+ result = 37 * result + ((pointcut == null) ? 0 : pointcut.hashCode());
+ hashCode = result;
+ }
+ return hashCode;
+ }
+
+ /**
+ * Parameterize the Checker by parameterizing the pointcut
+ */
+ @Override
+ public ShadowMunger parameterizeWith(ResolvedType declaringType, Map<String, UnresolvedType> typeVariableMap) {
+ Checker ret = new Checker(this.pointcut.parameterizeWith(typeVariableMap, declaringType.getWorld()), this.start, this.end,
+ this.sourceContext, this.message, this.isError);
+ return ret;
+ }
+
+ /**
+ * Concretize this Checker by concretizing the pointcut
+ */
+ @Override
+ public ShadowMunger concretize(ResolvedType theAspect, World world, PerClause clause) {
+ this.pointcut = this.pointcut.concretize(theAspect, getDeclaringType(), 0, this);
+ this.hashCode = -1;
+ return this;
+ }
+
+ @Override
+ public ResolvedType getConcreteAspect() {
+ return getDeclaringType();
+ }
+
+ // public void write(DataOutputStream stream) throws IOException {
+ // super.write(stream);
+ // stream.writeBoolean(isError);
+ // stream.writeUTF(message);
+ // }
+ //
+ // public static Checker read(DataInputStream stream, World world) throws IOException {
+ // Checker checker = new Checker();
+ // checker.isError = stream.readBoolean();
+ // checker.message = stream.readUTF();
+ // return checker;
+ // }
+
+ // Return the next non-escaped (with a '\') open curly
+ private int nextCurly(String string, int pos) {
+ do {
+ int curlyIndex = string.indexOf('{', pos);
+ if (curlyIndex == -1) {
+ return -1;
+ }
+ if (curlyIndex == 0) {
+ return 0;
+ }
+ if (string.charAt(curlyIndex - 1) != '\\') {
+ return curlyIndex;
+ }
+ pos = curlyIndex + 1;
+ } while (pos < string.length());
+ return -1;
+ }
+
+ private String format(String msg, Shadow shadow) {
+ int pos = 0;
+ int curlyIndex = nextCurly(msg, 0);
+ if (curlyIndex == -1) {
+ // was there an escaped one?
+ if (msg.indexOf('{') != -1) {
+ return msg.replace("\\{", "{");
+ } else {
+ return msg;
+ }
+ }
+ StringBuffer ret = new StringBuffer();
+ while (curlyIndex >= 0) {
+ if (curlyIndex > 0) {
+ ret.append(msg.substring(pos, curlyIndex).replace("\\{", "{"));
+ }
+ int endCurly = msg.indexOf('}', curlyIndex);
+ if (endCurly == -1) {
+ // wasn't closed properly - ignore it
+ ret.append('{');
+ pos = curlyIndex + 1;
+ } else {
+ ret.append(getValue(msg.substring(curlyIndex + 1, endCurly), shadow));
+ }
+ pos = endCurly + 1;
+ curlyIndex = nextCurly(msg, pos);
+ }
+ ret.append(msg.substring(pos, msg.length()));
+ return ret.toString();
+ }
+
+ /**
+ * @param buf the buffer in which to insert the substitution
+ * @param shadow shadow from which to draw context info
+ * @param c the substitution character
+ */
+ private String getValue(String key, Shadow shadow) {
+ if (key.equalsIgnoreCase("joinpoint")) {
+ return shadow.toString();
+ } else if (key.equalsIgnoreCase("joinpoint.kind")) {
+ return shadow.getKind().getName();
+ } else if (key.equalsIgnoreCase("joinpoint.enclosingclass")) {
+ return shadow.getEnclosingType().getName();
+ } else if (key.equalsIgnoreCase("joinpoint.enclosingmember.name")) {
+ Member member = shadow.getEnclosingCodeSignature();
+ if (member==null) {
+ return "";
+ } else {
+ return member.getName();
+ }
+ } else if (key.equalsIgnoreCase("joinpoint.enclosingmember")) {
+ Member member = shadow.getEnclosingCodeSignature();
+ if (member==null) {
+ return "";
+ } else {
+ return member.toString();
+ }
+ } else if (key.equalsIgnoreCase("joinpoint.signature")) {
+ return shadow.getSignature().toString();
+ } else if (key.equalsIgnoreCase("joinpoint.signature.declaringtype")) {
+ return shadow.getSignature().getDeclaringType().toString();
+ } else if (key.equalsIgnoreCase("joinpoint.signature.name")) {
+ return shadow.getSignature().getName();
+ } else if (key.equalsIgnoreCase("joinpoint.sourcelocation.sourcefile")) {
+ ISourceLocation loc = shadow.getSourceLocation();
+ if ((loc != null) && (loc.getSourceFile() != null)) {
+ return loc.getSourceFile().toString();
+ } else {
+ return "UNKNOWN";
+ }
+ } else if (key.equalsIgnoreCase("joinpoint.sourcelocation.line")) {
+ ISourceLocation loc = shadow.getSourceLocation();
+ if (loc != null) {
+ return Integer.toString(loc.getLine());
+ } else {
+ return "-1";
+ }
+ } else if (key.equalsIgnoreCase("advice.aspecttype")) {
+ return getDeclaringType().getName();
+ } else if (key.equalsIgnoreCase("advice.sourcelocation.line")) {
+ ISourceLocation loc = getSourceLocation();
+ if ((loc != null) && (loc.getSourceFile() != null)) {
+ return Integer.toString(loc.getLine());
+ } else {
+ return "-1";
+ }
+ } else if (key.equalsIgnoreCase("advice.sourcelocation.sourcefile")) {
+ ISourceLocation loc = getSourceLocation();
+ if ((loc != null) && (loc.getSourceFile() != null)) {
+ return loc.getSourceFile().toString();
+ } else {
+ return "UNKNOWN";
+ }
+ } else {
+ return "UNKNOWN_KEY{" + key + "}";
+ }
+ }
+}