From f5035234ee878003515413fee5e7e6bfa7a2228d Mon Sep 17 00:00:00 2001 From: aclement Date: Mon, 23 Aug 2004 13:40:31 +0000 Subject: [PATCH] Matthews enhancement fix for Bugzilla Bug 72154 "Support for simple dump file" + Andy using it to capture 'cant find type' issues. --- .../src/org/aspectj/ajdt/ajc/AjdtCommand.java | 12 +- .../org/aspectj/ajdt/ajc/BuildArgParser.java | 4 +- .../internal/core/builder/AjBuildManager.java | 2 + .../src/org/aspectj/tools/ajc/Main.java | 2 + .../testdata/DumpTestCase/src/Aspect.aj | 6 + .../testdata/DumpTestCase/src/DeclareError.aj | 6 + .../DumpTestCase/src/DeclareWarning.aj | 5 + .../testdata/DumpTestCase/src/HelloWorld.java | 6 + .../testdata/DumpTestCase/src/Pointcuts.aj | 5 + .../compiler/batch/AjdtBatchTests.java | 1 + .../compiler/batch/CompilerDumpTestCase.java | 102 +++++ weaver/src/org/aspectj/weaver/Dump.java | 378 ++++++++++++++++++ weaver/src/org/aspectj/weaver/World.java | 49 ++- .../org/aspectj/weaver/BcweaverTests.java | 1 + .../org/aspectj/weaver/DumpTestCase.java | 152 +++++++ 15 files changed, 711 insertions(+), 20 deletions(-) create mode 100644 org.aspectj.ajdt.core/testdata/DumpTestCase/src/Aspect.aj create mode 100644 org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareError.aj create mode 100644 org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareWarning.aj create mode 100644 org.aspectj.ajdt.core/testdata/DumpTestCase/src/HelloWorld.java create mode 100644 org.aspectj.ajdt.core/testdata/DumpTestCase/src/Pointcuts.aj create mode 100644 org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompilerDumpTestCase.java create mode 100644 weaver/src/org/aspectj/weaver/Dump.java create mode 100644 weaver/testsrc/org/aspectj/weaver/DumpTestCase.java diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java index 080192767..714596084 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/AjdtCommand.java @@ -15,6 +15,7 @@ package org.aspectj.ajdt.ajc; import org.aspectj.ajdt.internal.core.builder.*; import org.aspectj.bridge.*; +import org.aspectj.weaver.Dump; import org.eclipse.jdt.internal.core.builder.MissingSourceFileException; /** @@ -105,10 +106,12 @@ public class AjdtCommand implements ICommand { return false; } //System.err.println("errs: " + counter.hasErrors()); - return ((repeat - ? buildManager.incrementalBuild(config, handler) - : buildManager.batchBuild(config, handler)) - && !counter.hasErrors()); + boolean result = ((repeat + ? buildManager.incrementalBuild(config, handler) + : buildManager.batchBuild(config, handler)) + && !counter.hasErrors()); + Dump.dumpOnExit(); + return result; } catch (AbortException ae) { if (ae.isSilent()) { throw ae; @@ -119,6 +122,7 @@ public class AjdtCommand implements ICommand { MessageUtil.error(handler, t.getMessage()); } catch (Throwable t) { MessageUtil.abort(handler, ABORT_MESSAGE, t); + Dump.dumpWithException(t); } return false; } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java index 72b7d6b8a..c8888e8a5 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java @@ -20,6 +20,7 @@ import java.util.*; import org.aspectj.ajdt.internal.core.builder.*; import org.aspectj.bridge.*; import org.aspectj.util.*; +import org.aspectj.weaver.Dump; import org.aspectj.weaver.WeaverMessages; import org.eclipse.jdt.core.compiler.InvalidInputException; import org.eclipse.jdt.internal.compiler.batch.Main; @@ -107,7 +108,8 @@ public class BuildArgParser extends Main { * @return AjBuildConfig per args, * which will be invalid unless there are no handler errors. */ - public AjBuildConfig populateBuildConfig(AjBuildConfig buildConfig, String[] args, boolean setClasspath, File configFile) { + public AjBuildConfig populateBuildConfig(AjBuildConfig buildConfig, String[] args, boolean setClasspath, File configFile) { + Dump.saveCommandLine(args); buildConfig.setConfigFile(configFile); try { // sets filenames to be non-null in order to make sure that file paramters are ignored diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java index deabe0638..2161ee47e 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java @@ -30,6 +30,7 @@ import org.aspectj.asm.*; import org.aspectj.asm.internal.ProgramElement; import org.aspectj.bridge.*; import org.aspectj.util.FileUtil; +import org.aspectj.weaver.Dump; import org.aspectj.weaver.World; import org.aspectj.weaver.bcel.*; import org.eclipse.core.runtime.OperationCanceledException; @@ -648,6 +649,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc } List cps = buildConfig.getFullClasspath(); + Dump.saveFullClasspath(cps); String[] classpaths = new String[cps.size()]; for (int i=0; i < cps.size(); i++) { classpaths[i] = (String)cps.get(i); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java index fa790ae7c..0cfa6103f 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java @@ -32,6 +32,7 @@ import org.aspectj.bridge.ReflectionFactory; import org.aspectj.bridge.Version; import org.aspectj.util.FileUtil; import org.aspectj.util.LangUtil; +import org.aspectj.weaver.Dump; /** * Programmatic and command-line interface to AspectJ compiler. @@ -268,6 +269,7 @@ public class Main { * @param holder the MessageHandler sink for messages. */ public void run(String[] args, IMessageHolder holder) { + Dump.saveMessageHolder(holder); if (LangUtil.isEmpty(args)) { args = new String[] { "-?" }; } else if (controller.running()) { diff --git a/org.aspectj.ajdt.core/testdata/DumpTestCase/src/Aspect.aj b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/Aspect.aj new file mode 100644 index 000000000..94b3bf683 --- /dev/null +++ b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/Aspect.aj @@ -0,0 +1,6 @@ +public aspect Aspect { + + after () returning : Pointcuts.main () && within(HelloWorld) { + System.out.println(thisJoinPoint); + } +} diff --git a/org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareError.aj b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareError.aj new file mode 100644 index 000000000..7a1fad261 --- /dev/null +++ b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareError.aj @@ -0,0 +1,6 @@ +public aspect DeclareError { + + declare error : Pointcuts.main() && within(HelloWorld) : + "main()"; + +} diff --git a/org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareWarning.aj b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareWarning.aj new file mode 100644 index 000000000..7ba2b1f51 --- /dev/null +++ b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/DeclareWarning.aj @@ -0,0 +1,5 @@ +public aspect DeclareWarning { + + declare warning : Pointcuts.main() && within(HelloWorld) : + "main()"; +} diff --git a/org.aspectj.ajdt.core/testdata/DumpTestCase/src/HelloWorld.java b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/HelloWorld.java new file mode 100644 index 000000000..37732b8d5 --- /dev/null +++ b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/HelloWorld.java @@ -0,0 +1,6 @@ +public class HelloWorld { + + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/org.aspectj.ajdt.core/testdata/DumpTestCase/src/Pointcuts.aj b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/Pointcuts.aj new file mode 100644 index 000000000..5b589abfd --- /dev/null +++ b/org.aspectj.ajdt.core/testdata/DumpTestCase/src/Pointcuts.aj @@ -0,0 +1,5 @@ +public class Pointcuts { + + public pointcut main () : + execution(void main(String[])); +} diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java index 5dcc167df..d89573909 100644 --- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/AjdtBatchTests.java @@ -31,6 +31,7 @@ public class AjdtBatchTests extends TestCase { suite.addTestSuite(MultipleCompileTestCase.class); suite.addTestSuite(JavadocTest.class); suite.addTestSuite(PartiallyExposedHierarchyTestCase.class); + suite.addTestSuite(CompilerDumpTestCase.class); // XXX suite.addTestSuite(VerifyWeaveTestCase.class); //suite.addTestSuite(WorkingCommandTestCase.class); //$JUnit-END$ diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompilerDumpTestCase.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompilerDumpTestCase.java new file mode 100644 index 000000000..6a1b7cfa9 --- /dev/null +++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/CompilerDumpTestCase.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.ajdt.internal.compiler.batch; + +import java.io.File; + +import org.aspectj.bridge.IMessage; +import org.aspectj.tools.ajc.AjcTestCase; +import org.aspectj.tools.ajc.CompilationResult; +import org.aspectj.weaver.Dump; + +import junit.framework.TestCase; + +public class CompilerDumpTestCase extends AjcTestCase { + + public static final String PROJECT_DIR = "DumpTestCase"; + + private File baseDir; + private File dumpFile; + private IMessage.Kind savedDumpCondition; + + protected void setUp() throws Exception { + super.setUp(); + + baseDir = new File("../org.aspectj.ajdt.core/testdata",PROJECT_DIR); + dumpFile = null; + savedDumpCondition = Dump.getDumpOnExit(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + + if (dumpFile != null && dumpFile.exists()) { + boolean deleted = dumpFile.delete(); + assertTrue("Dump file '" + dumpFile.getPath() + "' could not be deleted",deleted); + } + Dump.setDumpOnExit(savedDumpCondition); + } + + /** + * Aim: Dump after successful compile to ensure it contains the command + * line information. + * + * Inputs to the compiler: + * HelloWorld.java Pointcuts.aj Aspect.aj + * + * Expected result = Compile succeeds. + */ + public void testDump () { + String[] args = new String[] { "src/HelloWorld.java", "src/Pointcuts.aj", "src/Aspect.aj" }; + CompilationResult result = ajc(baseDir,args); + assertNoMessages(result); + String fileName = Dump.dump("DumpTestCase.testDump()"); + dumpFile = new File(fileName); + org.aspectj.weaver.DumpTestCase.assertContents(dumpFile,"Command Line","HelloWorld.java"); + } + + /** + * Aim: Dump after successful compile to ensure it contains warning + * messages. + * + * Inputs to the compiler: + * HelloWorld.java Pointcuts.aj Aspect.aj DeclareWarning.aj + * + * Expected result = Compile succeeds. + */ + public void testDumpWithWarnings () { + String[] args = new String[] { "src/HelloWorld.java", "src/Pointcuts.aj", "src/DeclareWarning.aj" }; + CompilationResult result = ajc(baseDir,args); + String fileName = Dump.dump("DumpTestCase.testDumpWithWarnings()"); + dumpFile = new File(fileName); + org.aspectj.weaver.DumpTestCase.assertContents(dumpFile,"Compiler Messages","warning"); + } + + /** + * Aim: Dump due to errors. + * + * Inputs to the compiler: + * HelloWorld.java Pointcuts.aj Aspect.aj DeclareError.aj + * + * Expected result = Compile fails and dump file created. + */ + public void testWithErrors () { + Dump.setDumpOnExit(IMessage.ERROR); + String previousFileName = Dump.getLastDumpFileName(); + String[] args = new String[] { "src/HelloWorld.java", "src/Pointcuts.aj", "src/DeclareError.aj" }; + CompilationResult result = ajc(baseDir,args); + String fileName = Dump.getLastDumpFileName(); + assertTrue("Dump file should be created",!fileName.equals(previousFileName)); + dumpFile = new File(fileName); + org.aspectj.weaver.DumpTestCase.assertContents(dumpFile,"Compiler Messages","error"); + } + +} diff --git a/weaver/src/org/aspectj/weaver/Dump.java b/weaver/src/org/aspectj/weaver/Dump.java new file mode 100644 index 000000000..76b06e6a6 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/Dump.java @@ -0,0 +1,378 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Matthew Webster + * ******************************************************************/ +package org.aspectj.weaver; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHolder; +import org.aspectj.bridge.Version; + +/** + * @author websterm + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class Dump { + + /* Format for unique filename based on date & time */ + private static final String FILENAME_PREFIX = "ajcore"; + private static final DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); + private static final DateFormat timeFormat = new SimpleDateFormat("HHmmss.SSS"); + private static final String FILENAME_SUFFIX = "txt"; + + public static final String UNKNOWN_FILENAME = "Unknown"; + public static final String DUMP_EXCLUDED = "Excluded"; + public static final String NULL_OR_EMPTY = "Empty"; + + private static Class exceptionClass; + private static IMessage.Kind conditionKind = IMessage.ABORT; + + private String reason; + private String fileName; + private PrintStream print; + + private static String[] savedCommandLine; + private static List savedFullClasspath; + private static IMessageHolder savedMessageHolder; + + private static Map nodes = new HashMap(); + private static String lastDumpFileName = UNKNOWN_FILENAME; + + /* + * Dump methods + */ + public static String dump (String reason) { + String fileName = UNKNOWN_FILENAME; + Dump dump = null; + try { + dump = new Dump(reason); + fileName = dump.getFileName(); + dump.dumpDefault(); + } + finally { + if (dump != null) dump.close(); + } + return fileName; + } + + public static String dumpWithException (Throwable th) { + String fileName = UNKNOWN_FILENAME; + Dump dump = null; + try { + dump = new Dump(th.getClass().getName()); + fileName = dump.getFileName(); + dump.dumpException(th); + } + finally { + if (dump != null) dump.close(); + } + return fileName; + } + + public static String dumpOnExit () { + if (!shouldDumpOnExit()) return DUMP_EXCLUDED; + + String fileName = UNKNOWN_FILENAME; + Dump dump = null; + try { + dump = new Dump(conditionKind.toString()); + fileName = dump.getFileName(); + dump.dumpDefault(); + } + finally { + if (dump != null) dump.close(); + } + return fileName; + } + + private static boolean shouldDumpOnExit () { + return (savedMessageHolder == null) || savedMessageHolder.hasAnyMessage(conditionKind,true); + } + + /* + * Dump configuration + */ + public static void setDumpOnException (boolean b) { + if (b) { + exceptionClass = java.lang.Throwable.class; + } + else { + exceptionClass = null; + } + } + + public static boolean getDumpOnException () { + return (exceptionClass != null); + } + + public static boolean setDumpOnExit (IMessage.Kind condition) { + conditionKind = condition; + return true; + } + + public static boolean setDumpOnExit (String condition) { + for (Iterator i = IMessage.KINDS.iterator(); i.hasNext();) { + IMessage.Kind kind = (IMessage.Kind)i.next(); + if (kind.toString().equals(condition)) { + return setDumpOnExit(kind); + } + } + return false; + } + + public static IMessage.Kind getDumpOnExit () { + return conditionKind; + } + + public static String getLastDumpFileName () { + return lastDumpFileName; + } + + /* + * Dump registration + */ + public static void saveCommandLine (String[] args) { + savedCommandLine = new String[args.length]; + System.arraycopy(args,0,savedCommandLine,0,args.length); + } + + public static void saveFullClasspath (List list) { + savedFullClasspath = list; + } + + public static void saveMessageHolder (IMessageHolder holder) { + savedMessageHolder = holder; + } + + public static void registerNode (Class module, INode newNode) { + nodes.put(module,newNode); + } + + /* + * Dump methods + */ + private Dump (String reason) { + this.reason = reason; + + openDump(); + dumpAspectJProperties(); + dumpDumpConfiguration(); + } + + public String getFileName() { + return fileName; + } + + private void dumpDefault () { + dumpSytemProperties(); + dumpCommandLine(); + dumpFullClasspath(); + dumpCompilerMessages(); + + /* + * Dump registered nodes + */ + IVisitor dumpVisitor = new IVisitor() { + + public void visitString (String s) { + println(s); + } + + public void visitList (List list) { + println(list); + } + }; + for (Iterator i = nodes.keySet().iterator(); i.hasNext();) { + Class module = (Class)i.next(); + println("---- " + module.getName() + " ----"); + INode dumpNode = (INode)nodes.get(module); + try { + dumpNode.accept(dumpVisitor); + } + catch (Exception ex) { + println(ex.toString()); + } + } + } + + private void dumpException (Throwable th) { + println("---- Exception Information ---"); + println(th); + dumpDefault(); + } + + private void dumpAspectJProperties () { + println("---- AspectJ Properties ---"); + println("AspectJ Compiler " + Version.text + " built on " + Version.time_text); + } + + private void dumpDumpConfiguration () { + println("---- Dump Properties ---"); + println("Dump file: " + fileName); + println("Dump reason: " + reason); + println("Dump on exception: " + (exceptionClass != null)); + println("Dump at exit condition: " + conditionKind); + } + + private void dumpFullClasspath () { + println("---- Full Classpath ---"); + if (savedFullClasspath != null && savedFullClasspath.size() > 0) { + for (Iterator iter = savedFullClasspath.iterator(); iter.hasNext(); ) { + String fileName = (String)iter.next(); + File file = new File(fileName); + println(file); + } + } + else { + println(NULL_OR_EMPTY); + } + } + + private void dumpSytemProperties () { + println("---- System Properties ---"); + Properties props = System.getProperties(); + println(props); + } + + private void dumpCommandLine () { + println("---- Command Line ---"); + println(savedCommandLine); + } + + private void dumpCompilerMessages () { + println("---- Compiler Messages ---"); + if (savedMessageHolder != null) for (Iterator i = savedMessageHolder.getUnmodifiableListView().iterator(); i.hasNext(); ) { + IMessage message = (IMessage)i.next(); + println(message.toString()); + } + else { + println(NULL_OR_EMPTY); + } + } + + /* + * Dump output + */ + private void openDump () { + if (print != null) return; + + Date now = new Date(); + fileName = FILENAME_PREFIX + "." + + dateFormat.format(now) + "." + + timeFormat.format(now) + "." + + FILENAME_SUFFIX; + try { + print = new PrintStream(new FileOutputStream(fileName),true); + System.out.println("Dumping to " + fileName); + } + catch (FileNotFoundException ex) { + print = System.err; + System.out.println("Dumping to stderr"); + fileName = UNKNOWN_FILENAME; + } + + lastDumpFileName = fileName; + } + + public void close () { + print.close(); + } + + private void println (String s) { + print.println(s); + } + + private void println (Object[] array) { + if (array == null) { + println(NULL_OR_EMPTY); + return; + } + + for (int i = 0; i < array.length; i++) { + print.println(array[i]); + } + } + + private void println (Properties props) { + Iterator iter = props.keySet().iterator(); + while (iter.hasNext()) { + String key = (String)iter.next(); + String value = props.getProperty(key); + print.println(key + "=" + value); + } + } + + private void println (Throwable th) { + th.printStackTrace(print); + } + + private void println (File file) { + print.print(file.getAbsolutePath()); + if (!file.exists()) { + println("(missing)"); + } + else if (file.isDirectory()) { + int count = file.listFiles().length; + println("(" + count + " entries)"); + } + else { + println("(" + file.length() + " bytes)"); + } + } + + private void println (List list) { + if (list == null || list.isEmpty()) println(NULL_OR_EMPTY); + else for (Iterator i = list.iterator(); i.hasNext();) { + Object o = i.next(); + if (o instanceof Exception) { + println((Exception)o); + } else { + println(i.next().toString()); + } + } + } + + static { + String exceptionName = System.getProperty("org.aspectj.weaver.Dump.exception","true"); + if (!exceptionName.equals("false")) setDumpOnException(true); + + String conditionName = System.getProperty("org.aspectj.weaver.Dump.condition","true"); + setDumpOnExit(conditionName); + } + + public interface INode { + + public void accept (IVisitor visior); + + } + + public interface IVisitor { + + public void visitString (String s); + public void visitList (List list); + } +} diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 071af0678..468a6ba8c 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -13,9 +13,11 @@ package org.aspectj.weaver; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.WeakHashMap; @@ -30,7 +32,7 @@ import org.aspectj.bridge.IMessage.Kind; import org.aspectj.weaver.patterns.DeclarePrecedence; import org.aspectj.weaver.patterns.Pointcut; -public abstract class World { +public abstract class World implements Dump.INode { protected IMessageHandler messageHandler = IMessageHandler.SYSTEM_ERR; protected ICrossReferenceHandler xrefHandler = null; @@ -44,9 +46,12 @@ public abstract class World { protected boolean XnoInline; protected boolean XlazyTjp; + + private List dumpState_cantFindTypeExceptions = null; protected World() { super(); + Dump.registerNode(this.getClass(),this); typeMap.put("B", ResolvedTypeX.BYTE); typeMap.put("S", ResolvedTypeX.SHORT); typeMap.put("I", ResolvedTypeX.INT); @@ -57,6 +62,18 @@ public abstract class World { typeMap.put("Z", ResolvedTypeX.BOOLEAN); typeMap.put("V", ResolvedTypeX.VOID); } + + public void accept (Dump.IVisitor visitor) { + visitor.visitString("Shadow mungers:"); + visitor.visitList(crosscuttingMembersSet.getShadowMungers()); + visitor.visitString("Type mungers:"); + visitor.visitList(crosscuttingMembersSet.getTypeMungers()); + if (dumpState_cantFindTypeExceptions!=null) { + visitor.visitString("Cant find type problems:"); + visitor.visitList(dumpState_cantFindTypeExceptions); + dumpState_cantFindTypeExceptions = null; + } + } public ResolvedTypeX[] resolve(TypeX[] types) { int len = types.length; @@ -110,10 +127,12 @@ public abstract class World { } else { ret = resolveObjectType(ty); if (!allowMissing && ret == ResolvedTypeX.MISSING) { - //Thread.currentThread().dumpStack(); MessageUtil.error(messageHandler, WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); - // + " on classpath " + classPath); + if (dumpState_cantFindTypeExceptions==null) { + dumpState_cantFindTypeExceptions = new ArrayList(); + } + dumpState_cantFindTypeExceptions.add(new RuntimeException("Can't find type "+ty.getName())); } } //System.out.println("ret: " + ret); @@ -223,18 +242,18 @@ public abstract class World { // ---- empty world - public static final World EMPTY = new World() { - public List getShadowMungers() { return Collections.EMPTY_LIST; } - public ResolvedTypeX.ConcreteName resolveObjectType(ResolvedTypeX.Name ty) { - return null; - } - public Advice concreteAdvice(AjAttribute.AdviceAttribute attribute, Pointcut p, Member m) { - throw new RuntimeException("unimplemented"); - } - public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedTypeX aspectType) { - throw new RuntimeException("unimplemented"); - } - }; +// public static final World EMPTY = new World() { +// public List getShadowMungers() { return Collections.EMPTY_LIST; } +// public ResolvedTypeX.ConcreteName resolveObjectType(ResolvedTypeX.Name ty) { +// return null; +// } +// public Advice concreteAdvice(AjAttribute.AdviceAttribute attribute, Pointcut p, Member m) { +// throw new RuntimeException("unimplemented"); +// } +// public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedTypeX aspectType) { +// throw new RuntimeException("unimplemented"); +// } +// }; public abstract Advice concreteAdvice( diff --git a/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java b/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java index ac1587b54..94cb7ddac 100644 --- a/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java +++ b/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java @@ -54,6 +54,7 @@ public class BcweaverTests extends TestCase { suite.addTestSuite(TypeXTestCase.class); suite.addTestSuite(WeavingURLClassLoaderTest.class); suite.addTestSuite(WeaverMessagesTestCase.class); + suite.addTestSuite(DumpTestCase.class); //$JUnit-END$ return suite; } diff --git a/weaver/testsrc/org/aspectj/weaver/DumpTestCase.java b/weaver/testsrc/org/aspectj/weaver/DumpTestCase.java new file mode 100644 index 000000000..4354fa907 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/DumpTestCase.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Matthew Webster + *******************************************************************************/ +package org.aspectj.weaver; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.sql.Savepoint; + +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHolder; +import org.aspectj.bridge.Message; +import org.aspectj.bridge.MessageHandler; +import org.aspectj.util.FileUtil; + +import sun.security.krb5.internal.crypto.d; + +import junit.framework.TestCase; + +/** + * @author websterm + * + * Test Dump facility. Ensure it can be configured and files contain expected contents. Testcase + * returns Dump configuration to orginal state. + */ +public class DumpTestCase extends TestCase { + + private File dumpFile; + private IMessage.Kind savedDumpCondition; + + public DumpTestCase(String name) { + super(name); + } + + protected void setUp() throws Exception { + super.setUp(); + + dumpFile = null; + savedDumpCondition = Dump.getDumpOnExit(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + + if (dumpFile != null && dumpFile.exists()) { + boolean deleted = dumpFile.delete(); + assertTrue("Dump file '" + dumpFile.getPath() + "' could not be deleted",deleted); + } + Dump.setDumpOnExit(savedDumpCondition); + } + + public void testSetDumpOnException () { + Dump.setDumpOnException(true); + assertTrue("DumpOnException should be true",Dump.getDumpOnException()); + } + + public void testSetDumpOnExit () { + assertTrue("Should be able to set condition 'error'",Dump.setDumpOnExit("error")); + assertTrue("Should be able to set condition 'warning'",Dump.setDumpOnExit("warning")); + assertFalse("Should not be able to set condition 'junk'",Dump.setDumpOnExit("junk")); + } + + public void testDump () { + String fileName = Dump.dump("testDump()"); + dumpFile = new File(fileName); + assertTrue("Dump file '" + fileName + "' should exist",dumpFile.exists()); + } + + public void testDumpWithException () { + String message = "testDumpWithException()"; + String fileName = recursiveCall(message,100); + dumpFile = new File(fileName); + assertContents(dumpFile,"Exception Information",message); + } + + public void testDumpOnExit () { + Dump.setDumpOnExit("abort"); + Dump.saveMessageHolder(null); + String fileName = Dump.dumpOnExit(); + dumpFile = new File(fileName); + assertTrue("Dump file '" + fileName + "' should exist",dumpFile.exists()); + } + + public void testDumpOnExitExcluded () { + Dump.setDumpOnExit("abort"); + IMessageHolder holder = new MessageHandler(); + Dump.saveMessageHolder(holder); + holder.handleMessage(new Message("testDumpOnExitExcluded()",IMessage.ERROR,null,null)); + String fileName = Dump.dumpOnExit(); + dumpFile = new File(fileName); + assertEquals("Dump '" + fileName + "' should be excluded",Dump.DUMP_EXCLUDED,fileName); + } + + public void testDumpOnExitIncluded () { + Dump.setDumpOnExit("error"); + IMessageHolder holder = new MessageHandler(); + Dump.saveMessageHolder(holder); + IMessage error = new Message("testDumpOnExitIncluded()",IMessage.ERROR,null,null); + holder.handleMessage(error); + String fileName = Dump.dumpOnExit(); + dumpFile = new File(fileName); + assertContents(dumpFile,"Compiler Messages",error.getMessage()); + } + + /* Ensure dump file exists and contains certain contents under a given heading */ + public static void assertContents (File dumpFile, String heading, String contents) { + assertTrue("Dump file '" + dumpFile.getPath() + "' should exist",dumpFile.exists()); + assertTrue("Dump file '" + dumpFile.getPath()+ "' should contain '" + contents + "'",fileContains(dumpFile,heading,contents)); + } + + private static boolean fileContains (File dumpFile, String heading, String contents) { + boolean result = false; + + try { + BufferedReader reader = new BufferedReader(new FileReader(dumpFile)); + String currentHeading = ""; + String record; + while ((null != (record = reader.readLine())) && (result == false)) { + if (record.startsWith("----")) currentHeading = record; + else if ((record.indexOf(contents) != -1) && currentHeading.indexOf(heading) != -1) result = true; + } + reader.close(); + } + catch (IOException ex) { + fail(ex.toString()); + } + + return result; + } + + /* Generate a big stack trace */ + private String recursiveCall (String message, int depth) { + if (depth == 0) { + Throwable th = new RuntimeException(message); + return Dump.dumpWithException(th); + } + else { + return recursiveCall(message,--depth); + } + } + +} -- 2.39.5