diff options
35 files changed, 653 insertions, 293 deletions
diff --git a/ajde/testdata/WeaveInfoMessagesTest/AspectInPackage.aj b/ajde/testdata/WeaveInfoMessagesTest/AspectInPackage.aj new file mode 100644 index 000000000..74ff94b1a --- /dev/null +++ b/ajde/testdata/WeaveInfoMessagesTest/AspectInPackage.aj @@ -0,0 +1,10 @@ +package pkg; + +public aspect AspectInPackage { + + pointcut p() : execution(* *.*(..)); + + before() : p() { + } + +} diff --git a/ajde/testdata/WeaveInfoMessagesTest/AspectInPackage.jar b/ajde/testdata/WeaveInfoMessagesTest/AspectInPackage.jar Binary files differnew file mode 100644 index 000000000..a9d117f04 --- /dev/null +++ b/ajde/testdata/WeaveInfoMessagesTest/AspectInPackage.jar diff --git a/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.nodebug.txt b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.nodebug.txt index f9bda86e0..eab1c861a 100644 --- a/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.nodebug.txt +++ b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.nodebug.txt @@ -1,13 +1,13 @@ -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) -Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (no debug info available) advised by around advice from 'AspectAdvice' (AspectAdvice.aj:24) [with runtime test] -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (no debug info available) advised by around advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:24(from AspectAdvice.aj)) [with runtime test] +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:20(from AspectAdvice.aj)) diff --git a/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.jar.txt b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.jar.txt new file mode 100644 index 000000000..1c9e788bb --- /dev/null +++ b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.jar.txt @@ -0,0 +1,4 @@ +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) diff --git a/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.txt b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.txt new file mode 100644 index 000000000..d86780069 --- /dev/null +++ b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.txt @@ -0,0 +1,4 @@ +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) diff --git a/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.txt b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.txt index 03d6c4574..9ed2ca073 100644 --- a/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.txt +++ b/ajde/testdata/WeaveInfoMessagesTest/expected/advice.binary.txt @@ -1,13 +1,13 @@ -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) -Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) -Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) -Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by around advice from 'AspectAdvice' (AspectAdvice.aj:24) [with runtime test] -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) -Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by after advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by after advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by around advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:24(from AspectAdvice.aj)) [with runtime test] +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by after advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:20(from AspectAdvice.aj)) diff --git a/ajde/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.nodebug.txt b/ajde/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.nodebug.txt new file mode 100644 index 000000000..2a326c0e3 --- /dev/null +++ b/ajde/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.nodebug.txt @@ -0,0 +1,2 @@ +Softening exceptions in type 'Simple' (no debug info available) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft_nodebug.jar!AspectDeclareSoft.class:4(from AspectDeclareSoft.aj)) +Softening exceptions in type 'Simple' (no debug info available) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft_nodebug.jar!AspectDeclareSoft.class:6(from AspectDeclareSoft.aj)) diff --git a/ajde/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.txt b/ajde/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.txt new file mode 100644 index 000000000..e1f3522dc --- /dev/null +++ b/ajde/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.txt @@ -0,0 +1,2 @@ +Softening exceptions in type 'Simple' (Simple.java:13) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.jar!AspectDeclareSoft.class:4(from AspectDeclareSoft.aj)) +Softening exceptions in type 'Simple' (Simple.java:13) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.jar!AspectDeclareSoft.class:6(from AspectDeclareSoft.aj)) diff --git a/ajde/testdata/WeaveInfoMessagesTest/pkg/AspectInPackage.class b/ajde/testdata/WeaveInfoMessagesTest/pkg/AspectInPackage.class Binary files differnew file mode 100644 index 000000000..cc11cd2ca --- /dev/null +++ b/ajde/testdata/WeaveInfoMessagesTest/pkg/AspectInPackage.class diff --git a/ajde/testsrc/org/aspectj/ajde/ShowWeaveMessagesTestCase.java b/ajde/testsrc/org/aspectj/ajde/ShowWeaveMessagesTestCase.java index 743c54c2a..528654a9b 100644 --- a/ajde/testsrc/org/aspectj/ajde/ShowWeaveMessagesTestCase.java +++ b/ajde/testsrc/org/aspectj/ajde/ShowWeaveMessagesTestCase.java @@ -243,12 +243,35 @@ public class ShowWeaveMessagesTestCase extends AjdeTestCase { aspectpath.add(openFile("AspectDeclareSoft.jar")); ideManager.getProjectProperties().setAspectPath(aspectpath); assertTrue("Build failed", doSynchronousBuild("Empty.lst")); - verifyWeavingMessages("declare.soft",false); + verifyWeavingMessages("declare.soft.binary",true); } + public void testWeaveMessagesBinaryAdviceInPackageFromJar() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryAdviceInPackageFromJar: Simple.jar + AspectInPackage.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + ideManager.getProjectProperties().setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectInPackage.jar")); + ideManager.getProjectProperties().setAspectPath(aspectpath); + assertTrue("Build failed", doSynchronousBuild("Empty.lst")); + /*List l = */ideManager.getCompilationSourceLineTasks(); + verifyWeavingMessages("advice.binary.package.jar",true); + } - - + public void testWeaveMessagesBinaryAdviceInPackage() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryAdviceInPackage: Simple.jar + AspectInPackage.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + ideManager.getProjectProperties().setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("pkg")); + ideManager.getProjectProperties().setAspectPath(aspectpath); + assertTrue("Build failed", doSynchronousBuild("Empty.lst")); + /*List l = */ideManager.getCompilationSourceLineTasks(); + verifyWeavingMessages("advice.binary.package",true); + } + // BINARY WEAVING WHEN WE'VE LOST THE SOURCE POINTERS public void testWeaveMessagesBinaryAdviceNoDebugInfo() { @@ -301,7 +324,7 @@ public class ShowWeaveMessagesTestCase extends AjdeTestCase { aspectpath.add(openFile("AspectDeclareSoft_nodebug.jar")); ideManager.getProjectProperties().setAspectPath(aspectpath); assertTrue("Build failed", doSynchronousBuild("Empty.lst")); - verifyWeavingMessages("declare.soft.nodebug",true); + verifyWeavingMessages("declare.soft.binary.nodebug",true); } diff --git a/asm/src/org/aspectj/asm/AsmManager.java b/asm/src/org/aspectj/asm/AsmManager.java index 08eff87d4..87b5a347a 100644 --- a/asm/src/org/aspectj/asm/AsmManager.java +++ b/asm/src/org/aspectj/asm/AsmManager.java @@ -61,6 +61,7 @@ public class AsmManager { private static boolean dumpModel = false; private static boolean dumpRelationships = false; private static boolean dumpDeltaProcessing = false; + private static IModelFilter modelFilter = null; private static String dumpFilename = ""; private static boolean reporting = false; @@ -88,7 +89,6 @@ public class AsmManager { } public static AsmManager getDefault() { - new RuntimeException("fetching asm").printStackTrace(); return INSTANCE; } @@ -380,10 +380,21 @@ public class AsmManager { dumpFilename = filename; } + public static void setReporting(String filename,boolean dModel,boolean dRels,boolean dDeltaProcessing, + boolean deletefile,IModelFilter aFilter) { + setReporting(filename,dModel,dRels,dDeltaProcessing,deletefile); + modelFilter = aFilter; + } + public static boolean isReporting() { return reporting; } + public static void setDontReport() { + reporting = false; + dumpDeltaProcessing=false; + } + public void reportModelInfo(String reasonForReport) { @@ -422,8 +433,10 @@ public class AsmManager { for (int i =0 ;i<indent;i++) w.write(" "); String loc = ""; if (node!=null) { - if (node.getSourceLocation()!=null) + if (node.getSourceLocation()!=null) { loc = node.getSourceLocation().toString(); + if (modelFilter!=null) loc = modelFilter.processFilelocation(loc); + } } w.write(node+" ["+(node==null?"null":node.getKind().toString())+"] "+loc+"\n"); if (node!=null) @@ -458,9 +471,12 @@ public class AsmManager { List targets = ir.getTargets(); for (Iterator iterator2 = targets.iterator(); iterator2.hasNext(); - ) { + ) { String thid = (String) iterator2.next(); - w.write("Hid:"+(ctr++)+":(targets="+targets.size()+") "+hid+" ("+ir.getName()+") "+thid+"\n"); + StringBuffer sb = new StringBuffer(); + if (modelFilter==null || modelFilter.wantsHandleIds()) sb.append("Hid:"+(ctr++)+":"); + sb.append("(targets="+targets.size()+") "+hid+" ("+ir.getName()+") "+thid+"\n"); + w.write(sb.toString()); } } } diff --git a/asm/src/org/aspectj/asm/IModelFilter.java b/asm/src/org/aspectj/asm/IModelFilter.java new file mode 100644 index 000000000..a901e83a9 --- /dev/null +++ b/asm/src/org/aspectj/asm/IModelFilter.java @@ -0,0 +1,32 @@ +/* ******************************************************************* + * Copyright (c) 2006 Contributors + * 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: + * Andy Clement IBM initial implementation + * ******************************************************************/ +package org.aspectj.asm; + +/** + * When dumping the model out (for debugging/testing), various parts of + * it can be passed through this filter. Currently it is used to ensure + * the source locations we dump out are independent of sandbox directory. + */ +public interface IModelFilter { + /** + * Called when about to dump out an absolute file location, enabling + * it to be altered (eg. c:/temp/ajcsSandbox/foo/ajctemp.12323/<BLAH> + * could become TEST_SANDBOX/<BLAH> + */ + String processFilelocation(String loc); + + /** + * When the relationship map is dumped, lines are prefixed with a handle ID. + * Return true if you want these, false if you dont. + */ + boolean wantsHandleIds(); +} diff --git a/asm/src/org/aspectj/asm/IProgramElement.java b/asm/src/org/aspectj/asm/IProgramElement.java index 6fbc15b09..bc60fdbce 100644 --- a/asm/src/org/aspectj/asm/IProgramElement.java +++ b/asm/src/org/aspectj/asm/IProgramElement.java @@ -28,6 +28,7 @@ public interface IProgramElement extends Serializable { public void setChildren(List children); public void addChild(IProgramElement child); + public boolean removeChild(IProgramElement child); // Extra stuff // Could be just a string but may prove more useful as an object in the long run ... diff --git a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java index e0bb070dd..31aad3f18 100644 --- a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java +++ b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java @@ -259,6 +259,13 @@ public class AspectJElementHierarchy implements IHierarchy { if (lastSlash == -1) { lastSlash = sourceFilePath.lastIndexOf('/'); } + // '!' is used like in URLs "c:/blahblah/X.jar!a/b.class" + int i = sourceFilePath.lastIndexOf('!'); + int j = sourceFilePath.indexOf(".class"); + if (i > lastSlash && i != -1 && j != -1) { + // we are a binary aspect in the default package + lastSlash = i; + } String fileName = sourceFilePath.substring(lastSlash+1); IProgramElement fileNode = new ProgramElement(fileName, IProgramElement.Kind.FILE_JAVA, new SourceLocation(new File(sourceFilePath), 1, 1),0,null,null); //fileNode.setSourceLocation(); diff --git a/bridge/src/org/aspectj/bridge/ISourceLocation.java b/bridge/src/org/aspectj/bridge/ISourceLocation.java index e5c745797..502db15a7 100644 --- a/bridge/src/org/aspectj/bridge/ISourceLocation.java +++ b/bridge/src/org/aspectj/bridge/ISourceLocation.java @@ -64,4 +64,13 @@ public interface ISourceLocation { /** @return String application-specific context for source */ String getContext(); + /** + * In the cases where getSourceFile().getName() returns a class file + * (for example when we have a binary aspect) this should return the + * name of the source file (for example BinaryAspect.aj) + * + * @return the name of the source file + */ + String getSourceFileName(); + } diff --git a/bridge/src/org/aspectj/bridge/SourceLocation.java b/bridge/src/org/aspectj/bridge/SourceLocation.java index bc0c47171..e68a45f89 100644 --- a/bridge/src/org/aspectj/bridge/SourceLocation.java +++ b/bridge/src/org/aspectj/bridge/SourceLocation.java @@ -60,6 +60,7 @@ public class SourceLocation implements ISourceLocation, java.io.Serializable { private int offset; private final String context; private boolean noColumn; + private String sourceFileName; /** * Same as SourceLocation(file, line, line, 0), @@ -103,6 +104,11 @@ public class SourceLocation implements ISourceLocation, java.io.Serializable { this.context = context; } + public SourceLocation(File file, int line, int endLine, int column, String context, String sourceFileName) { + this(file,line,endLine,column,context); + this.sourceFileName = sourceFileName; + } + public File getSourceFile() { return sourceFile; } @@ -156,6 +162,10 @@ public class SourceLocation implements ISourceLocation, java.io.Serializable { public int getOffset() { return offset;} public void setOffset(int i) { offset=i;} + public String getSourceFileName() { + return sourceFileName; + } + } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java index 8e597c0ec..0f80b1380 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java @@ -158,4 +158,8 @@ public class EclipseSourceLocation implements ISourceLocation { getOffset()==o.getOffset() && ((filename==null)?(o.filename==null):o.filename.equals(filename)); } + + public String getSourceFileName() { + return null; + } } diff --git a/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java index dcf663fe8..b91587da7 100644 --- a/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java +++ b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java @@ -107,7 +107,6 @@ public abstract class XMLBasedAjcTestCase extends AjcTestCase { fail("No test '" + title + "' in suite."); } } - ajc.setShouldEmptySandbox(true); boolean run = currentTest.runTest(this); assertTrue("Test not run",run); if (clearTest) { diff --git a/testing/src/org/aspectj/testing/xml/SoftSourceLocation.java b/testing/src/org/aspectj/testing/xml/SoftSourceLocation.java index a9b7f585f..17f5ae673 100644 --- a/testing/src/org/aspectj/testing/xml/SoftSourceLocation.java +++ b/testing/src/org/aspectj/testing/xml/SoftSourceLocation.java @@ -126,4 +126,8 @@ public class SoftSourceLocation implements ISourceLocation { + getSourceFile().getPath() + ":" + getLine() ; } + + public String getSourceFileName() { + return null; + } } diff --git a/tests/src/org/aspectj/systemtest/AllTests.java b/tests/src/org/aspectj/systemtest/AllTests.java index 2a399b1dc..a4aec7d68 100644 --- a/tests/src/org/aspectj/systemtest/AllTests.java +++ b/tests/src/org/aspectj/systemtest/AllTests.java @@ -20,6 +20,7 @@ import org.aspectj.systemtest.incremental.IncrementalTests; import org.aspectj.systemtest.incremental.model.IncrementalModelTests; import org.aspectj.systemtest.incremental.tools.OutputLocationManagerTests; import org.aspectj.systemtest.inpath.InPathTests; +import org.aspectj.systemtest.model.ModelTests; import org.aspectj.systemtest.options.OptionsTests; import org.aspectj.systemtest.pre10x.AjcPre10xTests; import org.aspectj.systemtest.serialVerUID.SUIDTests; @@ -52,6 +53,7 @@ public class AllTests { suite.addTest(SUIDTests.suite()); suite.addTest(XLintTests.suite()); suite.addTest(TracingTests.suite()); + suite.addTest(ModelTests.suite()); //$JUnit-END$ return suite; diff --git a/tests/src/org/aspectj/systemtest/AllTests15.java b/tests/src/org/aspectj/systemtest/AllTests15.java index 09ed48206..e0a372662 100644 --- a/tests/src/org/aspectj/systemtest/AllTests15.java +++ b/tests/src/org/aspectj/systemtest/AllTests15.java @@ -11,6 +11,7 @@ import org.aspectj.systemtest.ajc150.ataspectj.AtAjAnnotationGenTests; import org.aspectj.systemtest.ajc151.AllTestsAspectJ151; import org.aspectj.systemtest.ajc152.AllTestsAspectJ152; import org.aspectj.systemtest.ajc153.AllTestsAspectJ153; +import org.aspectj.systemtest.model.Model5Tests; import org.aspectj.systemtest.incremental.tools.MultiProjectIncrementalTests; import org.aspectj.systemtest.xlint.XLint5Tests; @@ -25,6 +26,7 @@ public class AllTests15 { suite.addTest(AllTestsAspectJ152.suite()); suite.addTest(AllTestsAspectJ153.suite()); suite.addTest(AtAjAnnotationGenTests.suite()); + suite.addTest(Model5Tests.suite()); /* FIXME maw Many of these tests do not depend on Java 5 but they * cannot be executed in Eclipse with 1.3 because of XML issues and * are excluded on the build machine so moving them here loses nothing diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index c8f86b2f5..3de18f230 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -1880,9 +1880,9 @@ <weave classesFiles="AnnotatedType.java,SimpleAnnotation.java,SimpleAnnotation2.java" aspectsFiles="AnnotationAspect02.aj" options="-1.5,-showWeaveInfo"> - <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:3) advised by before advice from 'AnnotationAspect02' (AnnotationAspect02.aj:4)"/> - <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:3) advised by before advice from 'AnnotationAspect02' (AnnotationAspect02.aj:2)"/> - <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:4) advised by before advice from 'AnnotationAspect02' (AnnotationAspect02.aj:4)"/> + <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:3) advised by before advice from 'AnnotationAspect02' (aspects.jar!AnnotationAspect02.class:4(from AnnotationAspect02.aj))"/> + <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:3) advised by before advice from 'AnnotationAspect02' (aspects.jar!AnnotationAspect02.class:2(from AnnotationAspect02.aj))"/> + <message kind="weave" text="Type 'AnnotatedType' (AnnotatedType.java:4) advised by before advice from 'AnnotationAspect02' (aspects.jar!AnnotationAspect02.class:4(from AnnotationAspect02.aj))"/> </weave> </ajc-test> diff --git a/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java b/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java index bf7ae5bce..a47368db7 100644 --- a/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java @@ -219,11 +219,11 @@ public class Ajc152Tests extends org.aspectj.testing.XMLBasedAjcTestCase { // expecting: // sourceOfRelationship main in MyFoo.java // relationship advised by - // target MyBar.aj + // target MyBar.class // // and // - // sourceOfRelationship MyBar.aj + // sourceOfRelationship MyBar.class // relationship advises // target main in MyFoo.java @@ -236,8 +236,8 @@ public class Ajc152Tests extends org.aspectj.testing.XMLBasedAjcTestCase { String sourceOfRelationship = (String) iter.next(); IProgramElement ipe = top.findElementForHandle(sourceOfRelationship); List relationships = asmRelMap.get(ipe); - if (ipe.getName().equals("MyBar.aj")) { - assertEquals("expected MyBar.aj to have one relationships but found " + if (ipe.getName().equals("MyBar.class")) { + assertEquals("expected MyBar.class to have one relationships but found " + relationships.size(),1,relationships.size()); Relationship rel = (Relationship)relationships.get(0); assertEquals("expected relationship to be 'advises' but was " @@ -264,8 +264,8 @@ public class Ajc152Tests extends org.aspectj.testing.XMLBasedAjcTestCase { List targets = rel.getTargets(); assertEquals("expected one target but found " + targets.size(),1,targets.size()); IProgramElement link = top.findElementForHandle((String)targets.get(0)); - assertEquals("expected target 'MyBar.aj' but target " + link.getName(), - "MyBar.aj",link.getName()); + assertEquals("expected target 'MyBar.class' but target " + link.getName(), + "MyBar.class",link.getName()); } else { fail("unexpected element " + ipe.getName() + " in the relationship map"); diff --git a/tests/src/org/aspectj/systemtest/ajc152/AllTestsAspectJ152.java b/tests/src/org/aspectj/systemtest/ajc152/AllTestsAspectJ152.java index 1cf8167f7..05c311f50 100644 --- a/tests/src/org/aspectj/systemtest/ajc152/AllTestsAspectJ152.java +++ b/tests/src/org/aspectj/systemtest/ajc152/AllTestsAspectJ152.java @@ -19,7 +19,6 @@ public class AllTestsAspectJ152 { TestSuite suite = new TestSuite("AspectJ 1.5.2 tests"); //$JUnit-BEGIN$ suite.addTest(Ajc152Tests.suite()); - suite.addTest(CreatingModelForInjarTests.suite()); suite.addTest(SynchronizationTests.suite()); suite.addTest(SynchronizationTransformTests.suite()); //$JUnit-END$ diff --git a/tests/src/org/aspectj/systemtest/ajc152/CreatingModelForInjarTests.java b/tests/src/org/aspectj/systemtest/ajc152/CreatingModelForInjarTests.java deleted file mode 100644 index 845e7b29f..000000000 --- a/tests/src/org/aspectj/systemtest/ajc152/CreatingModelForInjarTests.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************** - * Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html - * - * Contributors: IBM Corporation - initial API and implementation - * Helen Hawkins - initial version - *******************************************************************/ -package org.aspectj.systemtest.ajc152; - -import java.io.File; -import java.util.Iterator; -import java.util.List; - -import junit.framework.Test; - -import org.aspectj.asm.AsmManager; -import org.aspectj.asm.IHierarchy; -import org.aspectj.asm.IProgramElement; -import org.aspectj.asm.IRelationshipMap; -import org.aspectj.testing.XMLBasedAjcTestCase; -//import org.aspectj.weaver.World; - -public class CreatingModelForInjarTests extends org.aspectj.testing.XMLBasedAjcTestCase { - - public void testAdviceAndNamedPCD() { - runTest("advice and deow"); - - // expect: - // - pkg {package} - // - A.aj (binary) {java source file} - // - import declarations {import reference} - // - A {aspect} - // - p {pointcut} - // - before {advice} - - IProgramElement pkgNode = getPkgNode(); - IProgramElement srcFile = checkChild(pkgNode,IProgramElement.Kind.FILE_JAVA,"A.aj (binary)",1); - checkChild(srcFile,IProgramElement.Kind.IMPORT_REFERENCE,"import declarations",-1); - IProgramElement aspectNode = checkChild(srcFile,IProgramElement.Kind.ASPECT,"A",-1); - checkChild(aspectNode,IProgramElement.Kind.POINTCUT,"p",5); - checkChild(aspectNode,IProgramElement.Kind.ADVICE,"before",7); - } - - public void testDeclareWarning() { - runTest("advice and deow"); - - // expect: - // - pkg {package} - // - Deow.aj (binary) {java source file} - // - import declarations {import reference} - // - Deow {aspect} - // - declare warning {declare warning} - - IHierarchy top = AsmManager.getDefault().getHierarchy(); - IProgramElement dwNode = top.findElementForLabel(top.getRoot(), - IProgramElement.Kind.DECLARE_WARNING, - "declare warning: \"There should be n..\""); - assertNotNull("Couldn't find 'declare warning: \"There should be n..\"' " + - "element in the tree",dwNode); - assertEquals("expected 'declare warning: \"There should be n..\"'" + - " to be on line 5 but was on " + dwNode.getSourceLocation().getLine(), - 5, dwNode.getSourceLocation().getLine()); - } - - public void testNumberOfPackageNodes() { - runTest("advice and deow"); - // check that the 'pkg' package node has not been added twice - IProgramElement root = AsmManager.getDefault().getHierarchy().getRoot(); - List l = root.getChildren(); - int numberOfPkgs = 0; - for (Iterator iter = l.iterator(); iter.hasNext();) { - IProgramElement element = (IProgramElement) iter.next(); - if (element.getKind().equals(IProgramElement.Kind.PACKAGE) - && element.getName().equals("pkg")) { - numberOfPkgs++; - } - } - assertEquals("expected one package called 'pkg' but found " + numberOfPkgs,1,numberOfPkgs); - } - - public void testAdviceInRelMap() { - runTest("advice and deow"); - IHierarchy top = AsmManager.getDefault().getHierarchy(); - IProgramElement adviceNode = top.findElementForLabel(top.getRoot(), IProgramElement.Kind.ADVICE,"before(): p.."); - IRelationshipMap relMap = AsmManager.getDefault().getRelationshipMap(); - List adviceRels = relMap.get(adviceNode); - assertFalse("expected before advice to have relationships but did not",adviceRels.isEmpty()); - } - - public void testDeclareWarningInRelMap() { - runTest("advice and deow"); - IHierarchy top = AsmManager.getDefault().getHierarchy(); - IProgramElement dwNode = top.findElementForLabel(top.getRoot(), - IProgramElement.Kind.DECLARE_WARNING, - "declare warning: \"There should be n..\""); - IRelationshipMap relMap = AsmManager.getDefault().getRelationshipMap(); - List dwRels = relMap.get(dwNode); - assertFalse("expected declare warning to have relationships but did not",dwRels.isEmpty()); - } - - public void testAdviceLabelsCorrect() { - runTest("ensure advice label is correct"); - IHierarchy top = AsmManager.getDefault().getHierarchy(); - - IProgramElement node = top.findElementForLabel(top.getRoot(), - IProgramElement.Kind.ADVICE, "before(): execM1().."); - assertNotNull("expected to find ipe with label 'before(): execM1()..'" + - " but didn't", node); - - node = top.findElementForLabel(top.getRoot(), - IProgramElement.Kind.ADVICE, "before(): execM2().."); - assertNotNull("expected to find ipe with label 'before(): execM2()..'" + - " but didn't", node); - - node = top.findElementForLabel(top.getRoot(), - IProgramElement.Kind.ADVICE, "before(): <anonymous pointcut>"); - assertNotNull("expected to find ipe with label 'before(): <anonymous pointcut>'" + - " but didn't", node); - } - - // ensure that filled in hierarchy only has one entry for - // aspect - public void testOnlyOneAspectEntry() { - runTest("ensure advice label is correct"); - - IProgramElement pkgNode = getPkgNode(); - assertEquals("expected one child node but found " + - pkgNode.getChildren().size(), 1, pkgNode.getChildren().size()); - - } - - public void testOnlyOneAspectEntry_inDefaultPackage() { - runTest("aspect in default package"); - // expect there to be two children - 'pack' and - // 'AspectInDefaultPackage.aj (binary)' - IProgramElement defaultPkg = AsmManager.getDefault().getHierarchy().getRoot(); - assertEquals("expected two child node but found " + - defaultPkg.getChildren().size(), 2, defaultPkg.getChildren().size()); - - } - - // --------------------- Helper methods --------------------- - - private IProgramElement getPkgNode() { - IHierarchy top = AsmManager.getDefault().getHierarchy(); - IProgramElement pkgNode = top.findElementForLabel(top.getRoot(), - IProgramElement.Kind.PACKAGE,"pkg"); - assertNotNull("Couldn't find 'pkg' element in the tree",pkgNode); - return pkgNode; - } - - private IProgramElement checkChild(IProgramElement parent, - IProgramElement.Kind childKind, - String childName, - int childLineNumbr) { - List children = parent.getChildren(); - boolean foundChild = false; - for (Iterator iter = children.iterator(); iter.hasNext();) { - IProgramElement element = (IProgramElement) iter.next(); - if (element.getKind().equals(childKind) - && element.getName().equals(childName) ) { - foundChild = true; - if (childLineNumbr != -1) { - assertEquals("expected " + childKind.toString() + childName + - " to be on line " + childLineNumbr + " but was on " + - element.getSourceLocation().getLine(), - childLineNumbr, element.getSourceLocation().getLine()); - } - return element; - } - } - assertTrue("expected " + parent.getName() + " to have child " + childName - + " but it did not", foundChild); - return null; - } - - protected void setUp() throws Exception { - super.setUp(); -// World.createInjarHierarchy = true; - } - - protected void tearDown() throws Exception { - super.tearDown(); -// World.createInjarHierarchy = false; - } - - // /////////////////////////////////////// - public static Test suite() { - return XMLBasedAjcTestCase.loadSuite(CreatingModelForInjarTests.class); - } - - protected File getSpecFile() { - return new File("../tests/src/org/aspectj/systemtest/ajc152/injar.xml"); - } -} diff --git a/tests/src/org/aspectj/systemtest/ajc152/injar.xml b/tests/src/org/aspectj/systemtest/ajc152/injar.xml deleted file mode 100644 index f53dbbaac..000000000 --- a/tests/src/org/aspectj/systemtest/ajc152/injar.xml +++ /dev/null @@ -1,20 +0,0 @@ -<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]> - -<!-- AspectJ v1.5.2 Tests --> -<suite> - - <ajc-test dir="bugs152/pr145963" title="advice and deow"> - <compile files="ClassForAspectPath.java" aspectpath="adviceAndDeow.jar" options="-emacssym"> - <message kind="warning" line="9" text="There should be no printlns"/> - </compile> - </ajc-test> - - <ajc-test dir="bugs152/pr145963" title="ensure advice label is correct"> - <compile files="C.java" aspectpath="adviceLabels.jar" options="-emacssym"/> - </ajc-test> - - <ajc-test dir="bugs152/pr145963" title="aspect in default package"> - <compile files="C.java" aspectpath="aspectInDefaultPackage.jar" options="-emacssym"/> - </ajc-test> - -</suite> diff --git a/tests/src/org/aspectj/systemtest/model/Model5Tests.java b/tests/src/org/aspectj/systemtest/model/Model5Tests.java new file mode 100644 index 000000000..6678256e6 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/model/Model5Tests.java @@ -0,0 +1,42 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version + *******************************************************************/ +package org.aspectj.systemtest.model; + +import java.io.File; + +import junit.framework.Test; + +import org.aspectj.testing.XMLBasedAjcTestCase; + +/** + * Tests the model when there is a requirement on Java5 features. + * @see org.aspectj.systemtest.model.ModelTestCase + */ +public class Model5Tests extends ModelTestCase { + + static { + // Switch this to true for a single iteration if you want to reconstruct the + // 'expected model' files. + regenerate = false; + // Switch this to true if you want to debug the comparison + debugTest = false; + } + + // /////////////////////////////////////// + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(Model5Tests.class); + } + + protected File getSpecFile() { + return new File("../tests/src/org/aspectj/systemtest/model/model.xml"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/model/ModelTestCase.java b/tests/src/org/aspectj/systemtest/model/ModelTestCase.java new file mode 100644 index 000000000..37f873839 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/model/ModelTestCase.java @@ -0,0 +1,208 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version + *******************************************************************/ +package org.aspectj.systemtest.model; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.asm.AsmManager; +import org.aspectj.asm.IElementHandleProvider; +import org.aspectj.asm.IModelFilter; +import org.aspectj.asm.internal.JDTLikeHandleProvider; +import org.aspectj.testing.XMLBasedAjcTestCase; +import org.aspectj.util.FileUtil; + +/** + * This class provides an extension to the XMLBasedAjcTestCase to manage + * testing the model. It assumes the testdata is in ../tests/model/<testid> + * and that the expected model against which to do the comparison is in + * the file ../tests/model/expected/<testid>.txt. One test ensures that both + * the model and the relationship map are as expected for the given testdata. + * + * To write a testcase, create a testdata directory containing the data + * for the test run and a file containing the expected model (this can be + * generated by setting the regenerate flag to true). Add the required + * configuration to model.xml. Finally, create a testcase in either ModelTests + * or Model5Tests (depending on whether the testcase has a requirement + * on Java5) and call runModelTest(<title of test>,<testid>). + */ +public abstract class ModelTestCase extends XMLBasedAjcTestCase { + + protected static boolean regenerate = false; + protected static boolean debugTest = false; + + private final String expectedOutDir = "../tests/model/expected" + File.separator; + private String testid; + + private String modelFilename; + + private IElementHandleProvider handleProvider; + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + // using the JDTLikeHandleProvider because this produces consistent handles + // over different compiles + handleProvider = AsmManager.getDefault().getHandleProvider(); + AsmManager.getDefault().setHandleProvider(new JDTLikeHandleProvider()); + // We are about to create a sandbox for the model output file, don't let the + // following compile wipe it. + ajc.setShouldEmptySandbox(false); + // report all information - model, relationships delta processing + modelFilename = ajc.getSandboxDirectory().getAbsolutePath() + File.separator + "model.txt"; + AsmManager.setReporting(modelFilename, + true,true,true,false,new TestFilter(ajc.getSandboxDirectory().getAbsolutePath())); + } + + static class TestFilter implements IModelFilter { + String sandboxDirectory ; + public TestFilter(String sandboxDirectory) { + this.sandboxDirectory = sandboxDirectory; + } + + public String processFilelocation(String loc) { + if (loc.startsWith(sandboxDirectory)) return "TEST_SANDBOX"+loc.substring(sandboxDirectory.length()); + return loc; + } + + public boolean wantsHandleIds() { + return false; + } + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + super.tearDown(); + AsmManager.getDefault().setHandleProvider(handleProvider); + AsmManager.setDontReport(); + ajc.setShouldEmptySandbox(true); + } + + /** + * Firstly sets the testid which is both the name of the expected output + * file and the name of the testdata directory. It then + * invokes XMLBasedAjcTestCase.runTest(String) with the given + * title and finally verifies that the model file created from this test + * run is the same as the expected output (includes model information, the + * relationship map and various properties about the model) contained + * in ../tests/model/expected/<testid>.txt + */ + protected void runModelTest(String title,String testid) { + this.testid = testid; + runTest(title); + verifyModel(); + } + + private void verifyModel() { + File expectedOutput = new File(expectedOutDir + testid + ".txt"); + if (regenerate) { + // Create the file + saveModel(expectedOutput); + } else { + // Verify the file matches what we have + compareModel(expectedOutput); + } + } + + private void compareModel(File expectedF) { + if (debugTest) System.out.println("comparing with model in file " + expectedF.getAbsolutePath()); + List fileContents = new ArrayList(); + try { + String sandboxDir = ajc.getSandboxDirectory().getAbsolutePath(); + String modelOutput = modelFilename; + // Load the file with the expected output + BufferedReader expect = new BufferedReader(new FileReader(expectedF)); +// String tempDir = expect.readLine(); + String expectedLine = null; + while((expectedLine=expect.readLine())!=null) { + fileContents.add(expectedLine); + } + List expectedFileContents = new ArrayList(); + expectedFileContents.addAll(fileContents); + + // Load the file with the output from this test run + BufferedReader found = new BufferedReader(new FileReader(new File(modelOutput))); + String foundLine = null; + List foundFileContents = new ArrayList(); + while((foundLine=found.readLine())!=null) { +// int i = foundLine.indexOf(sandboxDir); +// if (i == -1) { +// int j = foundLine.indexOf("(targets="); +// if (j == -1) { + foundFileContents.add(foundLine); +// } else { +// foundFileContents.add(foundLine.substring(j)); +// } +// } else { +// String newLine = foundLine.substring(0,i) + tempDir +// + foundLine.substring(i + sandboxDir.length()); +// foundFileContents.add(newLine); +// } + } + + // iterate over what we found + for (Iterator iter = foundFileContents.iterator(); iter.hasNext();) { + String line = (String) iter.next(); + if (debugTest) System.err.println("looking at model entry: " + line); + if (!fileContents.contains(line)) { +// if (!((String)fileContents.get(lineNumber)).equals(line)) { + + if(debugTest) { + System.err.println("couldn't find: " + line); + for (Iterator iterator = fileContents.iterator(); iterator + .hasNext();) { + String element = (String) iterator.next(); + System.err.println("compared with: " + element); + } + } + +// StringBuffer errorData = new StringBuffer(); +// errorData.append("Problem with comparison at line number: "+) + fail("couldn't find model entry '" + line + "' in expected output"); + } else { + fileContents.remove(line); + } + } + + if (debugTest && !fileContents.isEmpty()) { + for (Iterator iter = fileContents.iterator(); iter + .hasNext();) { + String element = (String) iter.next(); + System.err.println("remaining: " + element); + } + } + assertTrue("should have found all expected model output: " + fileContents,fileContents.isEmpty()); + } catch (Exception e) { + fail("Unexpected exception comparing model files:"+e); + } + } + + private void saveModel(File f) { + if (debugTest) System.out.println("Saving model into "+f.getAbsolutePath()); + File modelFile = new File(modelFilename); + try { + FileUtil.copyFile(modelFile, f); + } catch (IOException ioe) { + ioe.printStackTrace(); + fail("Couldn't copy file to "+f.toString()); + } + } + +} diff --git a/tests/src/org/aspectj/systemtest/model/ModelTests.java b/tests/src/org/aspectj/systemtest/model/ModelTests.java new file mode 100644 index 000000000..304321698 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/model/ModelTests.java @@ -0,0 +1,47 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version + *******************************************************************/ +package org.aspectj.systemtest.model; + +import java.io.File; + +import junit.framework.Test; + +import org.aspectj.testing.XMLBasedAjcTestCase; + +/** + * Tests the model when there is no requirement on Java5 features. + * @see org.aspectj.systemtest.model.ModelTestCase + */ +public class ModelTests extends ModelTestCase { + + static { + // Switch this to true for a single iteration if you want to reconstruct the + // 'expected model' files. + regenerate = false; + // Switch this to true if you want to debug the comparison + debugTest = false; + } + + public void testSourceLocationAndJarFile_pr145963() {runModelTest("sourcelocation and jar file","pr145963_1");} + public void testSourceLocationAndClassFile_pr145963() {runModelTest("sourcelocation and class file","pr145963_2");} + public void testAspectInDefaultPackage_pr145963() {runModelTest("aspect in default package", "pr145963_3");} + public void testAspectInJavaFile_pr145963() {runModelTest("aspect in java file", "pr145963_4");} + + ///////////////////////////////////////// + public static Test suite() { + return XMLBasedAjcTestCase.loadSuite(ModelTests.class); + } + + protected File getSpecFile() { + return new File("../tests/src/org/aspectj/systemtest/model/model.xml"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/model/model.xml b/tests/src/org/aspectj/systemtest/model/model.xml new file mode 100644 index 000000000..5a1843e22 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/model/model.xml @@ -0,0 +1,31 @@ +<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]> + +<!-- Model and Hierarchy Tests --> +<suite> + + <ajc-test dir="model/pr145963_1" title="sourcelocation and jar file"> + <compile files="C.java, SourceAspect.aj" aspectpath="simple.jar" options="-emacssym"> + <message kind="warning" line="6" text="There should be no printlns"/> + </compile> + </ajc-test> + + <ajc-test dir="model/pr145963_2" title="sourcelocation and class file"> + <compile files="C.java, SourceAspect.aj" aspectpath="pkg" options="-emacssym"> + <message kind="warning" line="6" text="There should be no printlns"/> + </compile> + </ajc-test> + + <ajc-test dir="model/pr145963_3" title="aspect in default package"> + <compile files="C.java" aspectpath="simple.jar" options="-emacssym"> + <message kind="warning" line="6" text="There should be no printlns"/> + </compile> + </ajc-test> + + <ajc-test dir="model/pr145963_4" title="aspect in java file"> + <compile files="C.java" aspectpath="simple.jar" options="-emacssym"> + <message kind="warning" line="6" text="There should be no printlns"/> + </compile> + </ajc-test> + + +</suite> diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java index 77b03d8b1..ba3bf6bca 100644 --- a/weaver/src/org/aspectj/weaver/Advice.java +++ b/weaver/src/org/aspectj/weaver/Advice.java @@ -434,7 +434,6 @@ public abstract class Advice extends ShadowMunger { public ResolvedType getResolvedDeclaringAspect() { // The aspect which declares this piece of advice // is 'concreteAspect' since 'declaringType' is null - return concreteAspect; + return ((concreteAspect != null) ? concreteAspect : getDeclaringType()); } - } diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index 055267121..e13776568 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -40,6 +40,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P"; private ResolvedType[] resolvedTypeParams; + private String binaryPath; protected World world; @@ -2095,5 +2096,17 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } return myMap; } + + public void setBinaryPath(String binaryPath) { + this.binaryPath = binaryPath; + } + + /** + * Returns the path to the jar or class file from which this + * binary aspect came or null if not a binary aspect + */ + public String getBinaryPath() { + return binaryPath; + } } diff --git a/weaver/src/org/aspectj/weaver/Shadow.java b/weaver/src/org/aspectj/weaver/Shadow.java index 0db4ac5a4..1add44522 100644 --- a/weaver/src/org/aspectj/weaver/Shadow.java +++ b/weaver/src/org/aspectj/weaver/Shadow.java @@ -565,9 +565,24 @@ public abstract class Shadow { int takeFrom = isl.getSourceFile().getPath().lastIndexOf('/'); if (takeFrom == -1) { takeFrom = isl.getSourceFile().getPath().lastIndexOf('\\'); - } + } + int binary = isl.getSourceFile().getPath().lastIndexOf('!'); + if (binary != -1 && binary < takeFrom) { + // we have been woven by a binary aspect + String pathToBinaryLoc = isl.getSourceFile().getPath().substring(0,binary + 1); + if (pathToBinaryLoc.indexOf(".jar") != -1) { + // only want to add the extra info if we're from a jar file + int lastSlash = pathToBinaryLoc.lastIndexOf('/'); + if (lastSlash == -1) { + lastSlash = pathToBinaryLoc.lastIndexOf('\\'); + } + nice.append(pathToBinaryLoc.substring(lastSlash + 1)); + } + } nice.append(isl.getSourceFile().getPath().substring(takeFrom +1)); if (isl.getLine()!=0) nice.append(":").append(isl.getLine()); + // if it's a binary file then also want to give the file name + if (isl.getSourceFileName() != null ) nice.append("(from " + isl.getSourceFileName() + ")"); } return nice.toString(); } diff --git a/weaver/src/org/aspectj/weaver/ShadowMunger.java b/weaver/src/org/aspectj/weaver/ShadowMunger.java index e5e5d0574..a4ac3f8e1 100644 --- a/weaver/src/org/aspectj/weaver/ShadowMunger.java +++ b/weaver/src/org/aspectj/weaver/ShadowMunger.java @@ -13,6 +13,7 @@ package org.aspectj.weaver; +import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -23,6 +24,7 @@ import org.aspectj.asm.AsmManager; import org.aspectj.asm.IProgramElement; import org.aspectj.asm.internal.ProgramElement; import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.SourceLocation; import org.aspectj.util.PartialOrder; import org.aspectj.weaver.bcel.BcelAdvice; import org.aspectj.weaver.patterns.DeclareErrorOrWarning; @@ -48,6 +50,8 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH protected int start, end; protected ISourceContext sourceContext; private ISourceLocation sourceLocation; + private ISourceLocation binarySourceLocation; + private File binaryFile; private String handle = null; private ResolvedType declaringType; // the type that declared this munger. @@ -91,6 +95,12 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH sourceLocation = sourceContext.makeSourceLocation(this); } } + if (isBinary()) { + if (binarySourceLocation == null) { + binarySourceLocation = getBinarySourceLocation(sourceLocation); + } + return binarySourceLocation; + } return sourceLocation; } @@ -156,16 +166,26 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH * Creates the hierarchy for binary aspects */ public void createHierarchy() { + if (!isBinary()) return; + IProgramElement sourceFileNode = AsmManager.getDefault().getHierarchy().findElementForSourceLine(getSourceLocation()); + // the call to findElementForSourceLine(ISourceLocation) returns a file node + // if it can't find a node in the hierarchy for the given sourcelocation. + // Therefore, if this is returned, we know we can't find one and have to + // continue to fault in the model. if (!sourceFileNode.getKind().equals(IProgramElement.Kind.FILE_JAVA)) { return; } - String name = sourceFileNode.getName(); - sourceFileNode.setName(name + " (binary)"); - AsmManager.getDefault().getHandleProvider().createHandleIdentifier(sourceFileNode); ResolvedType aspect = getResolvedDeclaringAspect(); + // create the class file node + IProgramElement classFileNode = new ProgramElement( + sourceFileNode.getName() + " (binary)", + IProgramElement.Kind.CLASS, + getBinarySourceLocation(aspect.getSourceLocation()), + 0,null,null); + // create package ipe if one exists.... IProgramElement root = AsmManager.getDefault().getHierarchy().getRoot(); if (aspect.getPackageName() != null) { @@ -179,42 +199,44 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH IProgramElement.Kind.PACKAGE, new ArrayList()); root.addChild(pkgNode); - pkgNode.addChild(sourceFileNode); + pkgNode.addChild(classFileNode); } else { + // need to add it first otherwise the handle for classFileNode + // may not be generated correctly if it uses information from + // it's parent node + pkgNode.addChild(classFileNode); for (Iterator iter = pkgNode.getChildren().iterator(); iter.hasNext();) { IProgramElement element = (IProgramElement) iter.next(); - if (element.getHandleIdentifier().equals( - sourceFileNode.getHandleIdentifier())) { - // already added the sourcefile so have already + if (!element.equals(classFileNode) && + element.getHandleIdentifier().equals( + classFileNode.getHandleIdentifier())) { + // already added the classfile so have already // added the structure for this aspect + pkgNode.removeChild(classFileNode); return; } } - pkgNode.addChild(sourceFileNode); } } else { + // need to add it first otherwise the handle for classFileNode + // may not be generated correctly if it uses information from + // it's parent node + root.addChild(classFileNode); for (Iterator iter = root.getChildren().iterator(); iter.hasNext();) { IProgramElement element = (IProgramElement) iter.next(); - if (element.getHandleIdentifier().equals( - sourceFileNode.getHandleIdentifier())) { + if (!element.equals(classFileNode) && + element.getHandleIdentifier().equals( + classFileNode.getHandleIdentifier())) { // already added the sourcefile so have already // added the structure for this aspect + root.removeChild(classFileNode); return; } } - root.addChild(sourceFileNode); - } - - // remove the error child from the 'A.aj' node - if (sourceFileNode instanceof ProgramElement) { - IProgramElement errorNode = (IProgramElement) sourceFileNode.getChildren().get(0); - if (errorNode.getKind().equals(IProgramElement.Kind.ERROR)) { - ((ProgramElement)sourceFileNode).removeChild(errorNode); - } } // add and create empty import declaration ipe - sourceFileNode.addChild(new ProgramElement( + classFileNode.addChild(new ProgramElement( "import declarations", IProgramElement.Kind.IMPORT_REFERENCE, null,0,null,null)); @@ -223,10 +245,10 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH IProgramElement aspectNode = new ProgramElement( aspect.getSimpleName(), IProgramElement.Kind.ASPECT, - aspect.getSourceLocation(), + getBinarySourceLocation(aspect.getSourceLocation()), aspect.getModifiers(), null,null); - sourceFileNode.addChild(aspectNode); + classFileNode.addChild(aspectNode); addChildNodes(aspectNode,aspect.getDeclaredPointcuts()); @@ -242,7 +264,7 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH parent.addChild(new ProgramElement( pcd.getName(), IProgramElement.Kind.POINTCUT, - rpcd.getPointcut().getSourceLocation(), + getBinarySourceLocation(rpcd.getPointcut().getSourceLocation()), pcd.getModifiers(), null, Collections.EMPTY_LIST)); @@ -258,8 +280,8 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH IProgramElement deowNode = new ProgramElement( decl.isError() ? "declare error" : "declare warning", decl.isError() ? IProgramElement.Kind.DECLARE_ERROR : IProgramElement.Kind.DECLARE_WARNING, - getSourceLocation(), - this.getDeclaringType().getModifiers(), + getBinarySourceLocation(decl.getSourceLocation()), + decl.getDeclaringType().getModifiers(), null,null); deowNode.setDetails("\"" + AsmRelationshipUtils.genDeclareMessage(decl.getMessage()) + "\""); parent.addChild(deowNode); @@ -268,12 +290,78 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH IProgramElement adviceNode = new ProgramElement( advice.kind.getName(), IProgramElement.Kind.ADVICE, - getSourceLocation(), + getBinarySourceLocation(advice.getSourceLocation()), advice.signature.getModifiers(),null,Collections.EMPTY_LIST); adviceNode.setDetails(AsmRelationshipUtils.genPointcutDetails(advice.getPointcut())); parent.addChild(adviceNode); } } } - + + /** + * Returns the binarySourceLocation for the given sourcelocation. This + * isn't cached because it's used when faulting in the binary nodes + * and is called with ISourceLocations for all advice, pointcuts and deows + * contained within the resolvedDeclaringAspect. + */ + private ISourceLocation getBinarySourceLocation(ISourceLocation sl) { + if (sl == null) return null; + String sourceFileName = null; + if (getResolvedDeclaringAspect() instanceof ReferenceType) { + String s = ((ReferenceType)getResolvedDeclaringAspect()).getDelegate().getSourcefilename(); + int i = s.lastIndexOf('/'); + if (i != -1) { + sourceFileName = s.substring(i+1); + } else { + sourceFileName = s; + } + } + ISourceLocation sLoc = new SourceLocation( + getBinaryFile(), + sl.getLine(), + sl.getEndLine(), + ((sl.getColumn() == 0) ? ISourceLocation.NO_COLUMN : sl.getColumn()), + sl.getContext(), + sourceFileName); + return sLoc; + } + + /** + * Returns the File with pathname to the class file, for example either + * C:\temp\ajcSandbox\workspace\ajcTest16957.tmp\simple.jar!pkg\BinaryAspect.class + * if the class file is in a jar file, or + * C:\temp\ajcSandbox\workspace\ajcTest16957.tmp!pkg\BinaryAspect.class + * if the class file is in a directory + */ + private File getBinaryFile() { + if (binaryFile == null) { + String s = getResolvedDeclaringAspect().getBinaryPath(); + File f = getResolvedDeclaringAspect().getSourceLocation().getSourceFile(); + int i = f.getPath().lastIndexOf('.'); + String path = f.getPath().substring(0,i) + ".class"; + binaryFile = new File(s + "!" + path); + } + return binaryFile; + } + + /** + * Returns whether or not this shadow munger came from + * a binary aspect - keep a record of whether or not we've + * checked if we're binary otherwise we keep caluclating the + * same thing many times + */ + protected boolean isBinary() { + if (!checkedIsBinary) { + ResolvedType rt = getResolvedDeclaringAspect(); + if (rt != null) { + isBinary = ((rt.getBinaryPath() == null) ? false : true); + } + checkedIsBinary = true; + } + return isBinary; + } + + private boolean isBinary; + private boolean checkedIsBinary; + } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 0a13be53d..6a51fd484 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -241,6 +241,7 @@ public class BcelWeaver implements IWeaver { inStream.closeEntry(); ResolvedType type = world.addSourceObjectType(jc).getResolvedTypeX(); + type.setBinaryPath(inFile.getAbsolutePath()); if (type.isAspect()) { addedAspects.add(type); } @@ -272,6 +273,10 @@ public class BcelWeaver implements IWeaver { ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes),name); JavaClass jc = parser.parse(); ResolvedType type = world.addSourceObjectType(jc).getResolvedTypeX(); + String typeName = type.getName().replace('.', File.separatorChar); + int end = name.indexOf(typeName); + String binaryPath = name.substring(0,end-1); + type.setBinaryPath(binaryPath); if (type.isAspect()) { toList.add(type); } |