Skip to content

Commit a1a700f

Browse files
committed
Implement source location matching for weave messages in XML tests
WIP (work in progress). Closes #218. Signed-off-by: Alexander Kriegisch <[email protected]>
1 parent 287ec8f commit a1a700f

File tree

8 files changed

+166
-63
lines changed

8 files changed

+166
-63
lines changed

bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,18 @@ public class WeaveMessage extends Message {
3939
public static WeaveMessageKind WEAVEMESSAGE_REMOVES_ANNOTATION = new WeaveMessageKind(6,
4040
"'%1' (%2) has had %3 %4 annotation removed by '%5' (%6)");
4141

42-
private String affectedtypename;
43-
private String aspectname;
42+
private String affectedTypeName;
43+
private String aspectName;
4444

4545
// private ctor - use the static factory method
46-
private WeaveMessage(String message, String affectedtypename, String aspectname) {
47-
super(message, IMessage.WEAVEINFO, null, null);
48-
this.affectedtypename = affectedtypename;
49-
this.aspectname = aspectname;
46+
private WeaveMessage(
47+
String message,
48+
String affectedTypeName, String aspectName,
49+
ISourceLocation affectedTypeLocation, ISourceLocation aspectLocation
50+
) {
51+
super(message, null, IMessage.WEAVEINFO, affectedTypeLocation, null, new ISourceLocation[] { aspectLocation });
52+
this.affectedTypeName = affectedTypeName;
53+
this.aspectName = aspectName;
5054
}
5155

5256
/**
@@ -63,41 +67,46 @@ public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String
6367
int n = Character.getNumericValue(str.charAt(pos + 1));
6468
str.replace(pos, pos + 2, inserts[n - 1]);
6569
}
66-
return new WeaveMessage(str.toString(), null, null);
70+
return new WeaveMessage(str.toString(), null, null, null, null);
6771
}
6872

6973
/**
7074
* Static helper method for constructing weaving messages.
7175
*
7276
* @param kind what kind of message (e.g. declare parents)
7377
* @param inserts inserts for the message (inserts are marked %n in the message)
74-
* @param affectedtypename the type which is being advised/declaredUpon
75-
* @param aspectname the aspect that defined the advice or declares
78+
* @param affectedTypeName the type which is being advised/declaredUpon
79+
* @param aspectName the aspect that defined the advice or declares
80+
* @param affectedTypeLocation the source location of the advised/declaredUpon type
81+
* @param aspectLocation the source location of the declaring/defining advice/declare
7682
* @return new weaving message
7783
*/
78-
public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts, String affectedtypename,
79-
String aspectname) {
84+
public static WeaveMessage constructWeavingMessage(
85+
WeaveMessageKind kind, String[] inserts,
86+
String affectedTypeName, String aspectName,
87+
ISourceLocation affectedTypeLocation, ISourceLocation aspectLocation
88+
) {
8089
StringBuilder str = new StringBuilder(kind.getMessage());
8190
int pos = -1;
8291
while ((pos = new String(str).indexOf("%")) != -1) {
8392
int n = Character.getNumericValue(str.charAt(pos + 1));
8493
str.replace(pos, pos + 2, inserts[n - 1]);
8594
}
86-
return new WeaveMessage(str.toString(), affectedtypename, aspectname);
95+
return new WeaveMessage(str.toString(), affectedTypeName, aspectName, affectedTypeLocation, aspectLocation);
8796
}
8897

8998
/**
9099
* @return Returns the aspectname.
91100
*/
92-
public String getAspectname() {
93-
return aspectname;
101+
public String getAspectName() {
102+
return aspectName;
94103
}
95104

96105
/**
97106
* @return Returns the affectedtypename.
98107
*/
99-
public String getAffectedtypename() {
100-
return affectedtypename;
108+
public String getAffectedTypeName() {
109+
return affectedTypeName;
101110
}
102111

103112
public static class WeaveMessageKind {

org.aspectj.ajdt.core/src/main/java/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@ public int getEndLine() {
108108

109109
public String getContext() {
110110
if (null == context) {
111-
ICompilationUnit compilationUnit = result.compilationUnit;
112-
IProblem[] problems = result.problems;
111+
ICompilationUnit compilationUnit = null;
112+
IProblem[] problems = null;
113+
if (result != null) {
114+
compilationUnit = result.compilationUnit;
115+
problems = result.problems;
116+
}
113117
if ((null == compilationUnit) || (null == problems)
114118
|| (1 != problems.length)) { // ?? which of n>1 problems?
115119
context = NO_CONTEXT;

org.aspectj.ajdt.core/src/test/java/org/aspectj/tools/ajc/AjcTestCase.java

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import org.aspectj.bridge.IMessage;
3535
import org.aspectj.bridge.ISourceLocation;
36+
import org.aspectj.bridge.WeaveMessage;
3637
import org.aspectj.testing.util.TestUtil;
3738
import org.aspectj.util.LangUtil;
3839

@@ -134,8 +135,10 @@ public abstract class AjcTestCase extends TestCase {
134135
*/
135136
public static class Message {
136137
private int line = -1;
138+
private int aspectLine = -1;
137139
private String text;
138140
private String sourceFileName;
141+
private String aspectFileName;
139142
private ISourceLocation[] seeAlsos;
140143
public boolean careAboutOtherMessages = true;
141144

@@ -172,19 +175,28 @@ public Message(int line, String text) {
172175
* </p>
173176
*/
174177
public Message(int line, String srcFile, String text, ISourceLocation[] seeAlso) {
178+
this(line, srcFile, -1, null, text, seeAlso);
179+
}
180+
181+
public Message(int line, String srcFile, int aspectLine, String aspectFile, String text, ISourceLocation[] seeAlso) {
175182
this.line = line;
176183
StringBuilder srcFileName = new StringBuilder();
177184
if (srcFile != null) {
178185
char[] chars = srcFile.toCharArray();
179186
for (char c : chars) {
180-
if ((c == '\\') || (c == '/')) {
181-
srcFileName.append(separator);
182-
} else {
183-
srcFileName.append(c);
184-
}
187+
srcFileName.append((c == '\\' || c == '/') ? separator : c);
185188
}
186189
this.sourceFileName = srcFileName.toString();
187190
}
191+
this.aspectLine = aspectLine;
192+
StringBuilder aspectFileName = new StringBuilder();
193+
if (aspectFile != null) {
194+
char[] chars = aspectFile.toCharArray();
195+
for (char c : chars) {
196+
aspectFileName.append((c == '\\' || c == '/') ? separator : c);
197+
}
198+
this.aspectFileName = aspectFileName.toString();
199+
}
188200
this.text = text;
189201
if (this.text != null && text.startsWith("*")) {
190202
// Don't care what other messages are around
@@ -211,33 +223,41 @@ public Message(String text) {
211223
*/
212224
public boolean matches(IMessage message) {
213225
ISourceLocation loc = message.getSourceLocation();
214-
if ((loc == null) && ((line != -1) || (sourceFileName != null))) {
226+
if ((loc == null) && ((line != -1) || (sourceFileName != null)))
215227
return false;
216-
}
217228
if (line != -1) {
218-
if (loc.getLine() != line) {
229+
if (loc.getLine() != line)
219230
return false;
220-
}
221231
}
222232
if (sourceFileName != null) {
223-
if (!loc.getSourceFile().getPath().endsWith(sourceFileName)) {
233+
if (!loc.getSourceFile().getPath().endsWith(sourceFileName))
224234
return false;
235+
}
236+
if (message instanceof WeaveMessage) {
237+
List<ISourceLocation> extraLocations = message.getExtraSourceLocations();
238+
loc = extraLocations.size() > 0 ? extraLocations.get(0) : null;
239+
if ((loc == null) && ((aspectLine != -1) || (aspectFileName != null)))
240+
return false;
241+
if (aspectLine != -1) {
242+
if (loc.getLine() != aspectLine)
243+
return false;
244+
}
245+
if (aspectFileName != null) {
246+
if (!loc.getSourceFile().getPath().endsWith(aspectFileName))
247+
return false;
225248
}
226249
}
227250
if (text != null) {
228-
if (!message.getMessage().contains(text)) {
251+
if (!message.getMessage().contains(text))
229252
return false;
230-
}
231253
}
232254
if (seeAlsos != null) {
233255
List<ISourceLocation> extraLocations = message.getExtraSourceLocations();
234-
if (extraLocations.size() != seeAlsos.length) {
256+
if (extraLocations.size() != seeAlsos.length)
235257
return false;
236-
}
237258
for (ISourceLocation seeAlso : seeAlsos) {
238-
if (!hasAMatch(extraLocations, seeAlso)) {
259+
if (!hasAMatch(extraLocations, seeAlso))
239260
return false;
240-
}
241261
}
242262
}
243263
return true;

testing/src/test/java/org/aspectj/testing/CompileSpec.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ protected AjcTestCase.MessageSpec buildMessageSpec() {
329329
} else if (kind.equals("abort")) {
330330
fails.add(exMsg.toMessage());
331331
} else if (kind.equals("weave")) {
332-
weaveInfos.add(exMsg.toMessage());
332+
weaveInfos.add(exMsg.toWeaveMessage());
333333
} else if (kind.equals("usage")) {
334334
weaveInfos.add(exMsg.toMessage());
335335
}

testing/src/test/java/org/aspectj/testing/ExpectedMessageSpec.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,18 @@ public class ExpectedMessageSpec {
2323

2424
private String kind = "error";
2525
private int line = -1;
26+
private int aspectLine = -1;
2627
private String text;
2728
private String file;
29+
private String aspectFile;
2830
private String details;
2931

3032
public AjcTestCase.Message toMessage() {
31-
return new AjcTestCase.Message(line,file,text,null);
33+
return new AjcTestCase.Message(line, file, text, null);
34+
}
35+
36+
public AjcTestCase.Message toWeaveMessage() {
37+
return new AjcTestCase.Message(line, file, aspectLine, aspectFile, text, null);
3238
}
3339

3440
/**
@@ -55,6 +61,18 @@ public String getFile() {
5561
public void setFile(String file) {
5662
this.file = file;
5763
}
64+
/**
65+
* @return Returns the aspect file.
66+
*/
67+
public String getAspectFile() {
68+
return aspectFile;
69+
}
70+
/**
71+
* @param aspectFile The aspect file to set.
72+
*/
73+
public void setAspectFile(String aspectFile) {
74+
this.aspectFile = aspectFile;
75+
}
5876
/**
5977
* @return Returns the kind.
6078
*/
@@ -79,6 +97,18 @@ public int getLine() {
7997
public void setLine(int line) {
8098
this.line = line;
8199
}
100+
/**
101+
* @return Returns the asperct line.
102+
*/
103+
public int getAspectLine() {
104+
return aspectLine;
105+
}
106+
/**
107+
* @param aspectLine The aspect line to set.
108+
*/
109+
public void setAspectLine(int aspectLine) {
110+
this.aspectLine = aspectLine;
111+
}
82112
/**
83113
* @return Returns the text.
84114
*/

tests/ajcTestSuite.dtd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,13 @@
6060

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

6872
<!ELEMENT source (#PCDATA)>

weaver/src/main/java/org/aspectj/weaver/bcel/BcelTypeMunger.java

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -193,21 +193,36 @@ public boolean munge(BcelClassWeaver weaver) {
193193
NewParentTypeMunger parentTM = (NewParentTypeMunger) munger;
194194
if (parentTM.isMixin()) {
195195
weaver.getWorld()
196-
.getMessageHandler()
197-
.handleMessage(
198-
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_MIXIN, new String[] {
199-
parentTM.getNewParent().getName(), fName, weaver.getLazyClassGen().getType().getName(),
200-
tName }, weaver.getLazyClassGen().getClassName(), getAspectType().getName()));
201-
} else {
196+
.getMessageHandler()
197+
.handleMessage(
198+
WeaveMessage.constructWeavingMessage(
199+
WeaveMessage.WEAVEMESSAGE_MIXIN,
200+
new String[] {
201+
parentTM.getNewParent().getName(), fName,
202+
weaver.getLazyClassGen().getType().getName(), tName
203+
},
204+
weaver.getLazyClassGen().getClassName(), getAspectType().getName(),
205+
parentTM.getNewParent().getSourceLocation(), weaver.getLazyClassGen().getType().getSourceLocation()
206+
)
207+
);
208+
}
209+
else {
202210
if (parentTM.getNewParent().isInterface()) {
203211
weaver.getWorld()
204-
.getMessageHandler()
205-
.handleMessage(
206-
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,
207-
new String[] { weaver.getLazyClassGen().getType().getName(), tName,
208-
parentTM.getNewParent().getName(), fName }, weaver.getLazyClassGen()
209-
.getClassName(), getAspectType().getName()));
210-
} else {
212+
.getMessageHandler()
213+
.handleMessage(
214+
WeaveMessage.constructWeavingMessage(
215+
WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,
216+
new String[] {
217+
weaver.getLazyClassGen().getType().getName(), tName,
218+
parentTM.getNewParent().getName(), fName
219+
},
220+
weaver.getLazyClassGen().getClassName(), getAspectType().getName(),
221+
parentTM.getNewParent().getSourceLocation(), weaver.getLazyClassGen().getType().getSourceLocation()
222+
)
223+
);
224+
}
225+
else {
211226
weaver.getWorld()
212227
.getMessageHandler()
213228
.handleMessage(
@@ -232,11 +247,18 @@ public boolean munge(BcelClassWeaver weaver) {
232247
fromString = fName;
233248
}
234249
weaver.getWorld()
235-
.getMessageHandler()
236-
.handleMessage(
237-
WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ITD, new String[] {
238-
weaver.getLazyClassGen().getType().getName(), tName, kindString, getAspectType().getName(),
239-
fromString }, weaver.getLazyClassGen().getClassName(), getAspectType().getName()));
250+
.getMessageHandler()
251+
.handleMessage(
252+
WeaveMessage.constructWeavingMessage(
253+
WeaveMessage.WEAVEMESSAGE_ITD,
254+
new String[] {
255+
weaver.getLazyClassGen().getType().getName(), tName,
256+
kindString, getAspectType().getName(), fromString
257+
},
258+
weaver.getLazyClassGen().getClassName(), getAspectType().getName(),
259+
weaver.getLazyClassGen().getType().getSourceLocation(), getAspectType().getSourceLocation()
260+
)
261+
);
240262
}
241263
}
242264

weaver/src/main/java/org/aspectj/weaver/bcel/BcelWorld.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,31 @@ private void reportWeavingMessage(ShadowMunger munger, Shadow shadow) {
190190
String advisingType = advice.getConcreteAspect().getName();
191191
Message msg = null;
192192
if (advice.getKind().equals(AdviceKind.Softener)) {
193-
msg = WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_SOFTENS, new String[] { advisedType,
194-
beautifyLocation(shadow.getSourceLocation()), advisingType, beautifyLocation(munger.getSourceLocation()) },
195-
advisedType, advisingType);
196-
} else {
193+
msg = WeaveMessage.constructWeavingMessage(
194+
WeaveMessage.WEAVEMESSAGE_SOFTENS,
195+
new String[] {
196+
advisedType, beautifyLocation(shadow.getSourceLocation()),
197+
advisingType, beautifyLocation(munger.getSourceLocation())
198+
},
199+
advisedType, advisingType,
200+
shadow.getSourceLocation(), munger.getSourceLocation()
201+
);
202+
}
203+
else {
197204
boolean runtimeTest = advice.hasDynamicTests();
198205
String joinPointDescription = shadow.toString();
199-
msg = WeaveMessage
200-
.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ADVISES,
201-
new String[] { joinPointDescription, advisedType, beautifyLocation(shadow.getSourceLocation()),
202-
description, advisingType, beautifyLocation(munger.getSourceLocation()),
203-
(runtimeTest ? " [with runtime test]" : "") }, advisedType, advisingType);
206+
msg = WeaveMessage.constructWeavingMessage(
207+
WeaveMessage.WEAVEMESSAGE_ADVISES,
208+
new String[] {
209+
joinPointDescription,
210+
advisedType, beautifyLocation(shadow.getSourceLocation()),
211+
description,
212+
advisingType, beautifyLocation(munger.getSourceLocation()),
213+
(runtimeTest ? " [with runtime test]" : "")
214+
},
215+
advisedType, advisingType,
216+
shadow.getSourceLocation(), munger.getSourceLocation()
217+
);
204218
// Boolean.toString(runtimeTest)});
205219
}
206220
getMessageHandler().handleMessage(msg);

0 commit comments

Comments
 (0)