diff options
author | Andy Clement <aclement@pivotal.io> | 2019-01-23 18:53:51 -0800 |
---|---|---|
committer | Andy Clement <aclement@pivotal.io> | 2019-01-23 18:53:51 -0800 |
commit | afaa961b294eca20fa9d54359c53a1de2d3c41fd (patch) | |
tree | 4b756f0f0dc4764cfcaeb200756de79cd4cdf56a /org.aspectj.matcher/src/main/java/org/aspectj/weaver/Checker.java | |
parent | 74dcae875f1c89b7e3fa2ffa6b524a3c187a597e (diff) | |
download | aspectj-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.java | 281 |
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 + "}"; + } + } +} |