Browse Source

Implement source location matching for weave messages in XML tests

WIP (work in progress).

Closes #218.

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
tags/V1_9_22_1
Alexander Kriegisch 1 year ago
parent
commit
a1a700fc6e

+ 25
- 16
bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java View File

public static WeaveMessageKind WEAVEMESSAGE_REMOVES_ANNOTATION = new WeaveMessageKind(6, public static WeaveMessageKind WEAVEMESSAGE_REMOVES_ANNOTATION = new WeaveMessageKind(6,
"'%1' (%2) has had %3 %4 annotation removed by '%5' (%6)"); "'%1' (%2) has had %3 %4 annotation removed by '%5' (%6)");


private String affectedtypename;
private String aspectname;
private String affectedTypeName;
private String aspectName;


// private ctor - use the static factory method // private ctor - use the static factory method
private WeaveMessage(String message, String affectedtypename, String aspectname) {
super(message, IMessage.WEAVEINFO, null, null);
this.affectedtypename = affectedtypename;
this.aspectname = aspectname;
private WeaveMessage(
String message,
String affectedTypeName, String aspectName,
ISourceLocation affectedTypeLocation, ISourceLocation aspectLocation
) {
super(message, null, IMessage.WEAVEINFO, affectedTypeLocation, null, new ISourceLocation[] { aspectLocation });
this.affectedTypeName = affectedTypeName;
this.aspectName = aspectName;
} }


/** /**
int n = Character.getNumericValue(str.charAt(pos + 1)); int n = Character.getNumericValue(str.charAt(pos + 1));
str.replace(pos, pos + 2, inserts[n - 1]); str.replace(pos, pos + 2, inserts[n - 1]);
} }
return new WeaveMessage(str.toString(), null, null);
return new WeaveMessage(str.toString(), null, null, null, null);
} }


/** /**
* *
* @param kind what kind of message (e.g. declare parents) * @param kind what kind of message (e.g. declare parents)
* @param inserts inserts for the message (inserts are marked %n in the message) * @param inserts inserts for the message (inserts are marked %n in the message)
* @param affectedtypename the type which is being advised/declaredUpon
* @param aspectname the aspect that defined the advice or declares
* @param affectedTypeName the type which is being advised/declaredUpon
* @param aspectName the aspect that defined the advice or declares
* @param affectedTypeLocation the source location of the advised/declaredUpon type
* @param aspectLocation the source location of the declaring/defining advice/declare
* @return new weaving message * @return new weaving message
*/ */
public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts, String affectedtypename,
String aspectname) {
public static WeaveMessage constructWeavingMessage(
WeaveMessageKind kind, String[] inserts,
String affectedTypeName, String aspectName,
ISourceLocation affectedTypeLocation, ISourceLocation aspectLocation
) {
StringBuilder str = new StringBuilder(kind.getMessage()); StringBuilder str = new StringBuilder(kind.getMessage());
int pos = -1; int pos = -1;
while ((pos = new String(str).indexOf("%")) != -1) { while ((pos = new String(str).indexOf("%")) != -1) {
int n = Character.getNumericValue(str.charAt(pos + 1)); int n = Character.getNumericValue(str.charAt(pos + 1));
str.replace(pos, pos + 2, inserts[n - 1]); str.replace(pos, pos + 2, inserts[n - 1]);
} }
return new WeaveMessage(str.toString(), affectedtypename, aspectname);
return new WeaveMessage(str.toString(), affectedTypeName, aspectName, affectedTypeLocation, aspectLocation);
} }


/** /**
* @return Returns the aspectname. * @return Returns the aspectname.
*/ */
public String getAspectname() {
return aspectname;
public String getAspectName() {
return aspectName;
} }


/** /**
* @return Returns the affectedtypename. * @return Returns the affectedtypename.
*/ */
public String getAffectedtypename() {
return affectedtypename;
public String getAffectedTypeName() {
return affectedTypeName;
} }


public static class WeaveMessageKind { public static class WeaveMessageKind {

+ 6
- 2
org.aspectj.ajdt.core/src/main/java/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java View File



public String getContext() { public String getContext() {
if (null == context) { if (null == context) {
ICompilationUnit compilationUnit = result.compilationUnit;
IProblem[] problems = result.problems;
ICompilationUnit compilationUnit = null;
IProblem[] problems = null;
if (result != null) {
compilationUnit = result.compilationUnit;
problems = result.problems;
}
if ((null == compilationUnit) || (null == problems) if ((null == compilationUnit) || (null == problems)
|| (1 != problems.length)) { // ?? which of n>1 problems? || (1 != problems.length)) { // ?? which of n>1 problems?
context = NO_CONTEXT; context = NO_CONTEXT;

+ 36
- 16
org.aspectj.ajdt.core/src/test/java/org/aspectj/tools/ajc/AjcTestCase.java View File



import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.WeaveMessage;
import org.aspectj.testing.util.TestUtil; import org.aspectj.testing.util.TestUtil;
import org.aspectj.util.LangUtil; import org.aspectj.util.LangUtil;


*/ */
public static class Message { public static class Message {
private int line = -1; private int line = -1;
private int aspectLine = -1;
private String text; private String text;
private String sourceFileName; private String sourceFileName;
private String aspectFileName;
private ISourceLocation[] seeAlsos; private ISourceLocation[] seeAlsos;
public boolean careAboutOtherMessages = true; public boolean careAboutOtherMessages = true;


* </p> * </p>
*/ */
public Message(int line, String srcFile, String text, ISourceLocation[] seeAlso) { public Message(int line, String srcFile, String text, ISourceLocation[] seeAlso) {
this(line, srcFile, -1, null, text, seeAlso);
}

public Message(int line, String srcFile, int aspectLine, String aspectFile, String text, ISourceLocation[] seeAlso) {
this.line = line; this.line = line;
StringBuilder srcFileName = new StringBuilder(); StringBuilder srcFileName = new StringBuilder();
if (srcFile != null) { if (srcFile != null) {
char[] chars = srcFile.toCharArray(); char[] chars = srcFile.toCharArray();
for (char c : chars) { for (char c : chars) {
if ((c == '\\') || (c == '/')) {
srcFileName.append(separator);
} else {
srcFileName.append(c);
}
srcFileName.append((c == '\\' || c == '/') ? separator : c);
} }
this.sourceFileName = srcFileName.toString(); this.sourceFileName = srcFileName.toString();
} }
this.aspectLine = aspectLine;
StringBuilder aspectFileName = new StringBuilder();
if (aspectFile != null) {
char[] chars = aspectFile.toCharArray();
for (char c : chars) {
aspectFileName.append((c == '\\' || c == '/') ? separator : c);
}
this.aspectFileName = aspectFileName.toString();
}
this.text = text; this.text = text;
if (this.text != null && text.startsWith("*")) { if (this.text != null && text.startsWith("*")) {
// Don't care what other messages are around // Don't care what other messages are around
*/ */
public boolean matches(IMessage message) { public boolean matches(IMessage message) {
ISourceLocation loc = message.getSourceLocation(); ISourceLocation loc = message.getSourceLocation();
if ((loc == null) && ((line != -1) || (sourceFileName != null))) {
if ((loc == null) && ((line != -1) || (sourceFileName != null)))
return false; return false;
}
if (line != -1) { if (line != -1) {
if (loc.getLine() != line) {
if (loc.getLine() != line)
return false; return false;
}
} }
if (sourceFileName != null) { if (sourceFileName != null) {
if (!loc.getSourceFile().getPath().endsWith(sourceFileName)) {
if (!loc.getSourceFile().getPath().endsWith(sourceFileName))
return false; return false;
}
if (message instanceof WeaveMessage) {
List<ISourceLocation> extraLocations = message.getExtraSourceLocations();
loc = extraLocations.size() > 0 ? extraLocations.get(0) : null;
if ((loc == null) && ((aspectLine != -1) || (aspectFileName != null)))
return false;
if (aspectLine != -1) {
if (loc.getLine() != aspectLine)
return false;
}
if (aspectFileName != null) {
if (!loc.getSourceFile().getPath().endsWith(aspectFileName))
return false;
} }
} }
if (text != null) { if (text != null) {
if (!message.getMessage().contains(text)) {
if (!message.getMessage().contains(text))
return false; return false;
}
} }
if (seeAlsos != null) { if (seeAlsos != null) {
List<ISourceLocation> extraLocations = message.getExtraSourceLocations(); List<ISourceLocation> extraLocations = message.getExtraSourceLocations();
if (extraLocations.size() != seeAlsos.length) {
if (extraLocations.size() != seeAlsos.length)
return false; return false;
}
for (ISourceLocation seeAlso : seeAlsos) { for (ISourceLocation seeAlso : seeAlsos) {
if (!hasAMatch(extraLocations, seeAlso)) {
if (!hasAMatch(extraLocations, seeAlso))
return false; return false;
}
} }
} }
return true; return true;

+ 1
- 1
testing/src/test/java/org/aspectj/testing/CompileSpec.java View File

} else if (kind.equals("abort")) { } else if (kind.equals("abort")) {
fails.add(exMsg.toMessage()); fails.add(exMsg.toMessage());
} else if (kind.equals("weave")) { } else if (kind.equals("weave")) {
weaveInfos.add(exMsg.toMessage());
weaveInfos.add(exMsg.toWeaveMessage());
} else if (kind.equals("usage")) { } else if (kind.equals("usage")) {
weaveInfos.add(exMsg.toMessage()); weaveInfos.add(exMsg.toMessage());
} }

+ 31
- 1
testing/src/test/java/org/aspectj/testing/ExpectedMessageSpec.java View File



private String kind = "error"; private String kind = "error";
private int line = -1; private int line = -1;
private int aspectLine = -1;
private String text; private String text;
private String file; private String file;
private String aspectFile;
private String details; private String details;


public AjcTestCase.Message toMessage() { public AjcTestCase.Message toMessage() {
return new AjcTestCase.Message(line,file,text,null);
return new AjcTestCase.Message(line, file, text, null);
}

public AjcTestCase.Message toWeaveMessage() {
return new AjcTestCase.Message(line, file, aspectLine, aspectFile, text, null);
} }


/** /**
public void setFile(String file) { public void setFile(String file) {
this.file = file; this.file = file;
} }
/**
* @return Returns the aspect file.
*/
public String getAspectFile() {
return aspectFile;
}
/**
* @param aspectFile The aspect file to set.
*/
public void setAspectFile(String aspectFile) {
this.aspectFile = aspectFile;
}
/** /**
* @return Returns the kind. * @return Returns the kind.
*/ */
public void setLine(int line) { public void setLine(int line) {
this.line = line; this.line = line;
} }
/**
* @return Returns the asperct line.
*/
public int getAspectLine() {
return aspectLine;
}
/**
* @param aspectLine The aspect line to set.
*/
public void setAspectLine(int aspectLine) {
this.aspectLine = aspectLine;
}
/** /**
* @return Returns the text. * @return Returns the text.
*/ */

+ 4
- 0
tests/ajcTestSuite.dtd View File



<!ELEMENT message (source*)> <!ELEMENT message (source*)>
<!ATTLIST message kind (abort | fail | error | warning | info | Xlint | weave) #IMPLIED > <!ATTLIST message kind (abort | fail | error | warning | info | Xlint | weave) #IMPLIED >
<!-- Java source code line; in weaving messages it denotes the weaving target, e.g. to where an advice is applied -->
<!ATTLIST message line CDATA #IMPLIED > <!ATTLIST message line CDATA #IMPLIED >
<!-- Aspect source code line; only useful for weaving messages where it denotes the source of what is woven in (e.g. advice) -->
<!ATTLIST message aspectLine CDATA #IMPLIED >
<!ATTLIST message text CDATA #IMPLIED > <!ATTLIST message text CDATA #IMPLIED >
<!ATTLIST message file CDATA #IMPLIED > <!ATTLIST message file CDATA #IMPLIED >
<!ATTLIST message aspectFile CDATA #IMPLIED >
<!ATTLIST message details CDATA #IMPLIED > <!ATTLIST message details CDATA #IMPLIED >


<!ELEMENT source (#PCDATA)> <!ELEMENT source (#PCDATA)>

+ 40
- 18
weaver/src/main/java/org/aspectj/weaver/bcel/BcelTypeMunger.java View File

NewParentTypeMunger parentTM = (NewParentTypeMunger) munger; NewParentTypeMunger parentTM = (NewParentTypeMunger) munger;
if (parentTM.isMixin()) { if (parentTM.isMixin()) {
weaver.getWorld() weaver.getWorld()
.getMessageHandler()
.handleMessage(
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_MIXIN, new String[] {
parentTM.getNewParent().getName(), fName, weaver.getLazyClassGen().getType().getName(),
tName }, weaver.getLazyClassGen().getClassName(), getAspectType().getName()));
} else {
.getMessageHandler()
.handleMessage(
WeaveMessage.constructWeavingMessage(
WeaveMessage.WEAVEMESSAGE_MIXIN,
new String[] {
parentTM.getNewParent().getName(), fName,
weaver.getLazyClassGen().getType().getName(), tName
},
weaver.getLazyClassGen().getClassName(), getAspectType().getName(),
parentTM.getNewParent().getSourceLocation(), weaver.getLazyClassGen().getType().getSourceLocation()
)
);
}
else {
if (parentTM.getNewParent().isInterface()) { if (parentTM.getNewParent().isInterface()) {
weaver.getWorld() weaver.getWorld()
.getMessageHandler()
.handleMessage(
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,
new String[] { weaver.getLazyClassGen().getType().getName(), tName,
parentTM.getNewParent().getName(), fName }, weaver.getLazyClassGen()
.getClassName(), getAspectType().getName()));
} else {
.getMessageHandler()
.handleMessage(
WeaveMessage.constructWeavingMessage(
WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,
new String[] {
weaver.getLazyClassGen().getType().getName(), tName,
parentTM.getNewParent().getName(), fName
},
weaver.getLazyClassGen().getClassName(), getAspectType().getName(),
parentTM.getNewParent().getSourceLocation(), weaver.getLazyClassGen().getType().getSourceLocation()
)
);
}
else {
weaver.getWorld() weaver.getWorld()
.getMessageHandler() .getMessageHandler()
.handleMessage( .handleMessage(
fromString = fName; fromString = fName;
} }
weaver.getWorld() weaver.getWorld()
.getMessageHandler()
.handleMessage(
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ITD, new String[] {
weaver.getLazyClassGen().getType().getName(), tName, kindString, getAspectType().getName(),
fromString }, weaver.getLazyClassGen().getClassName(), getAspectType().getName()));
.getMessageHandler()
.handleMessage(
WeaveMessage.constructWeavingMessage(
WeaveMessage.WEAVEMESSAGE_ITD,
new String[] {
weaver.getLazyClassGen().getType().getName(), tName,
kindString, getAspectType().getName(), fromString
},
weaver.getLazyClassGen().getClassName(), getAspectType().getName(),
weaver.getLazyClassGen().getType().getSourceLocation(), getAspectType().getSourceLocation()
)
);
} }
} }



+ 23
- 9
weaver/src/main/java/org/aspectj/weaver/bcel/BcelWorld.java View File

String advisingType = advice.getConcreteAspect().getName(); String advisingType = advice.getConcreteAspect().getName();
Message msg = null; Message msg = null;
if (advice.getKind().equals(AdviceKind.Softener)) { if (advice.getKind().equals(AdviceKind.Softener)) {
msg = WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_SOFTENS, new String[] { advisedType,
beautifyLocation(shadow.getSourceLocation()), advisingType, beautifyLocation(munger.getSourceLocation()) },
advisedType, advisingType);
} else {
msg = WeaveMessage.constructWeavingMessage(
WeaveMessage.WEAVEMESSAGE_SOFTENS,
new String[] {
advisedType, beautifyLocation(shadow.getSourceLocation()),
advisingType, beautifyLocation(munger.getSourceLocation())
},
advisedType, advisingType,
shadow.getSourceLocation(), munger.getSourceLocation()
);
}
else {
boolean runtimeTest = advice.hasDynamicTests(); boolean runtimeTest = advice.hasDynamicTests();
String joinPointDescription = shadow.toString(); String joinPointDescription = shadow.toString();
msg = WeaveMessage
.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ADVISES,
new String[] { joinPointDescription, advisedType, beautifyLocation(shadow.getSourceLocation()),
description, advisingType, beautifyLocation(munger.getSourceLocation()),
(runtimeTest ? " [with runtime test]" : "") }, advisedType, advisingType);
msg = WeaveMessage.constructWeavingMessage(
WeaveMessage.WEAVEMESSAGE_ADVISES,
new String[] {
joinPointDescription,
advisedType, beautifyLocation(shadow.getSourceLocation()),
description,
advisingType, beautifyLocation(munger.getSourceLocation()),
(runtimeTest ? " [with runtime test]" : "")
},
advisedType, advisingType,
shadow.getSourceLocation(), munger.getSourceLocation()
);
// Boolean.toString(runtimeTest)}); // Boolean.toString(runtimeTest)});
} }
getMessageHandler().handleMessage(msg); getMessageHandler().handleMessage(msg);

Loading…
Cancel
Save