From 68e9bc60f98ece8557eb6499326644a956d2dcf9 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Wed, 23 Jan 2019 13:02:59 -0800 Subject: mavenized bridge module --- bridge/.classpath | 9 - bridge/.cvsignore | 5 - bridge/.isJava5 | 1 - bridge/.project | 18 - bridge/build.xml | 6 - bridge/pom.xml | 25 + .../java/org/aspectj/bridge/AbortException.java | 228 ++++ .../main/java/org/aspectj/bridge/Constants.java | 22 + .../org/aspectj/bridge/CountingMessageHandler.java | 157 +++ .../src/main/java/org/aspectj/bridge/ICommand.java | 39 + .../java/org/aspectj/bridge/ILifecycleAware.java | 35 + .../src/main/java/org/aspectj/bridge/IMessage.java | 150 +++ .../java/org/aspectj/bridge/IMessageContext.java | 16 + .../java/org/aspectj/bridge/IMessageHandler.java | 89 ++ .../java/org/aspectj/bridge/IMessageHolder.java | 66 ++ .../java/org/aspectj/bridge/IProgressListener.java | 40 + .../java/org/aspectj/bridge/ISourceLocation.java | 72 ++ .../src/main/java/org/aspectj/bridge/Message.java | 190 ++++ .../java/org/aspectj/bridge/MessageHandler.java | 265 +++++ .../main/java/org/aspectj/bridge/MessageUtil.java | 1116 ++++++++++++++++++++ .../java/org/aspectj/bridge/MessageWriter.java | 84 ++ .../java/org/aspectj/bridge/ReflectionFactory.java | 103 ++ .../java/org/aspectj/bridge/SourceLocation.java | 199 ++++ .../src/main/java/org/aspectj/bridge/Version.java | 89 ++ .../main/java/org/aspectj/bridge/WeaveMessage.java | 117 ++ .../context/CompilationAndWeavingContext.java | 260 +++++ .../aspectj/bridge/context/ContextFormatter.java | 21 + .../org/aspectj/bridge/context/ContextToken.java | 20 + .../bridge/context/PinpointingMessageHandler.java | 115 ++ bridge/src/org/aspectj/bridge/AbortException.java | 228 ---- bridge/src/org/aspectj/bridge/Constants.java | 22 - .../org/aspectj/bridge/CountingMessageHandler.java | 157 --- bridge/src/org/aspectj/bridge/ICommand.java | 39 - bridge/src/org/aspectj/bridge/ILifecycleAware.java | 35 - bridge/src/org/aspectj/bridge/IMessage.java | 150 --- bridge/src/org/aspectj/bridge/IMessageContext.java | 16 - bridge/src/org/aspectj/bridge/IMessageHandler.java | 89 -- bridge/src/org/aspectj/bridge/IMessageHolder.java | 66 -- .../src/org/aspectj/bridge/IProgressListener.java | 40 - bridge/src/org/aspectj/bridge/ISourceLocation.java | 72 -- bridge/src/org/aspectj/bridge/Message.java | 190 ---- bridge/src/org/aspectj/bridge/MessageHandler.java | 265 ----- bridge/src/org/aspectj/bridge/MessageUtil.java | 1116 -------------------- bridge/src/org/aspectj/bridge/MessageWriter.java | 84 -- .../src/org/aspectj/bridge/ReflectionFactory.java | 103 -- bridge/src/org/aspectj/bridge/SourceLocation.java | 199 ---- bridge/src/org/aspectj/bridge/Version.java | 89 -- bridge/src/org/aspectj/bridge/WeaveMessage.java | 117 -- .../context/CompilationAndWeavingContext.java | 260 ----- .../aspectj/bridge/context/ContextFormatter.java | 21 - .../org/aspectj/bridge/context/ContextToken.java | 20 - .../bridge/context/PinpointingMessageHandler.java | 115 -- .../aspectj/bridge/CountingMessageHandlerTest.java | 82 ++ .../test/java/org/aspectj/bridge/MessageTest.java | 321 ++++++ .../test/java/org/aspectj/bridge/VersionTest.java | 60 ++ .../context/CompilationAndWeavingContextTest.java | 67 ++ .../org/aspectj/bridge/BridgeModuleTests.java | 35 - bridge/testsrc/org/aspectj/bridge/BridgeTests.java | 35 - .../aspectj/bridge/CountingMessageHandlerTest.java | 82 -- bridge/testsrc/org/aspectj/bridge/MessageTest.java | 321 ------ bridge/testsrc/org/aspectj/bridge/VersionTest.java | 60 -- .../context/CompilationAndWeavingContextTest.java | 67 -- 62 files changed, 4048 insertions(+), 4132 deletions(-) delete mode 100644 bridge/.classpath delete mode 100644 bridge/.cvsignore delete mode 100644 bridge/.isJava5 delete mode 100644 bridge/.project delete mode 100644 bridge/build.xml create mode 100644 bridge/pom.xml create mode 100644 bridge/src/main/java/org/aspectj/bridge/AbortException.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/Constants.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/CountingMessageHandler.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/ICommand.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/ILifecycleAware.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/IMessage.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/IMessageContext.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/IMessageHandler.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/IMessageHolder.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/IProgressListener.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/ISourceLocation.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/Message.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/MessageHandler.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/MessageUtil.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/MessageWriter.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/ReflectionFactory.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/SourceLocation.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/Version.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/context/CompilationAndWeavingContext.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/context/ContextFormatter.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/context/ContextToken.java create mode 100644 bridge/src/main/java/org/aspectj/bridge/context/PinpointingMessageHandler.java delete mode 100644 bridge/src/org/aspectj/bridge/AbortException.java delete mode 100644 bridge/src/org/aspectj/bridge/Constants.java delete mode 100644 bridge/src/org/aspectj/bridge/CountingMessageHandler.java delete mode 100644 bridge/src/org/aspectj/bridge/ICommand.java delete mode 100644 bridge/src/org/aspectj/bridge/ILifecycleAware.java delete mode 100644 bridge/src/org/aspectj/bridge/IMessage.java delete mode 100644 bridge/src/org/aspectj/bridge/IMessageContext.java delete mode 100644 bridge/src/org/aspectj/bridge/IMessageHandler.java delete mode 100644 bridge/src/org/aspectj/bridge/IMessageHolder.java delete mode 100644 bridge/src/org/aspectj/bridge/IProgressListener.java delete mode 100644 bridge/src/org/aspectj/bridge/ISourceLocation.java delete mode 100644 bridge/src/org/aspectj/bridge/Message.java delete mode 100644 bridge/src/org/aspectj/bridge/MessageHandler.java delete mode 100644 bridge/src/org/aspectj/bridge/MessageUtil.java delete mode 100644 bridge/src/org/aspectj/bridge/MessageWriter.java delete mode 100644 bridge/src/org/aspectj/bridge/ReflectionFactory.java delete mode 100644 bridge/src/org/aspectj/bridge/SourceLocation.java delete mode 100644 bridge/src/org/aspectj/bridge/Version.java delete mode 100644 bridge/src/org/aspectj/bridge/WeaveMessage.java delete mode 100644 bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java delete mode 100644 bridge/src/org/aspectj/bridge/context/ContextFormatter.java delete mode 100644 bridge/src/org/aspectj/bridge/context/ContextToken.java delete mode 100644 bridge/src/org/aspectj/bridge/context/PinpointingMessageHandler.java create mode 100644 bridge/src/test/java/org/aspectj/bridge/CountingMessageHandlerTest.java create mode 100644 bridge/src/test/java/org/aspectj/bridge/MessageTest.java create mode 100644 bridge/src/test/java/org/aspectj/bridge/VersionTest.java create mode 100644 bridge/src/test/java/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java delete mode 100644 bridge/testsrc/org/aspectj/bridge/BridgeModuleTests.java delete mode 100644 bridge/testsrc/org/aspectj/bridge/BridgeTests.java delete mode 100644 bridge/testsrc/org/aspectj/bridge/CountingMessageHandlerTest.java delete mode 100644 bridge/testsrc/org/aspectj/bridge/MessageTest.java delete mode 100644 bridge/testsrc/org/aspectj/bridge/VersionTest.java delete mode 100644 bridge/testsrc/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java diff --git a/bridge/.classpath b/bridge/.classpath deleted file mode 100644 index 6544d226b..000000000 --- a/bridge/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/bridge/.cvsignore b/bridge/.cvsignore deleted file mode 100644 index 8bdf2ac1e..000000000 --- a/bridge/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -bin -ant.properties -bridge.mf.txt - -bintest diff --git a/bridge/.isJava5 b/bridge/.isJava5 deleted file mode 100644 index 136d06384..000000000 --- a/bridge/.isJava5 +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/bridge/.project b/bridge/.project deleted file mode 100644 index 91c755134..000000000 --- a/bridge/.project +++ /dev/null @@ -1,18 +0,0 @@ - - - bridge - - - util - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/bridge/build.xml b/bridge/build.xml deleted file mode 100644 index 349b0aa8c..000000000 --- a/bridge/build.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/bridge/pom.xml b/bridge/pom.xml new file mode 100644 index 000000000..03ddca049 --- /dev/null +++ b/bridge/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + + + org.aspectj + aspectj-parent + 1.9.3.BUILD-SNAPSHOT + .. + + + bridge + jar + bridge + + + + org.aspectj + util + ${project.version} + + + + diff --git a/bridge/src/main/java/org/aspectj/bridge/AbortException.java b/bridge/src/main/java/org/aspectj/bridge/AbortException.java new file mode 100644 index 000000000..acde7cd28 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/AbortException.java @@ -0,0 +1,228 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.util.ArrayList; + +/** + * Signal that a process was aborted before completion. This may contain a structured IMessage which indicates why the process was + * aborted (e.g., the underlying exception). For processes using try/catch to complete a method abruptly but complete the process + * normally (e.g., a test failure causes the test to abort but the reporting and testing continues normally), use the static methods + * to borrow and return a "porter" to avoid the expense of constructing a stack trace each time. A porter stack trace is invalid, + * and it should only be used to convey a message. E.g., to print the stack of the AbortException and any contained message: + * + *
+ * catch (AbortException ae) {
+ *     IMessage m = ae.getMessage();
+ *     if (!ae.isPorter()) ae.printStackTrace(System.err);
+ *     Throwable thrown = ae.getThrown();
+ *     if (null != thrown) thrown.printStackTrace(System.err);
+ * }
+ * 
+ * + * @author PARC + * @author Andy Clement + */ +public class AbortException extends RuntimeException { // XXX move porters out, handle proxy better + + private static final long serialVersionUID = -7211791639898586417L; + + private boolean isSilent = false; + + /** used when message text is null */ + public static final String NO_MESSAGE_TEXT = "AbortException (no message)"; + + private static final ArrayList porters = new ArrayList(); + + /** + * Get a porter exception from the pool. Porter exceptions do not have valid stack traces. They are used only to avoid + * generating stack traces when using throw/catch to abruptly complete but continue. + */ + public static AbortException borrowPorter(IMessage message) { + AbortException result; + synchronized (porters) { + if (porters.size() > 0) { + result = porters.get(0); + } else { + result = new AbortException(); + result.setIsSilent(false); + } + } + result.setIMessage(message); + result.isPorter = true; + return result; + } + + /** + * Return (or add) a porter exception to the pool. + */ + public static void returnPorter(AbortException porter) { + synchronized (porters) { + if (porters.contains(porter)) { + throw new IllegalStateException("already have " + porter); + } else { + porters.add(porter); + } + } + } + + /** @return NO_MESSAGE_TEXT or message.getMessage() if not null */ + private static String extractMessage(IMessage message) { + if (null == message) { + return NO_MESSAGE_TEXT; + } else { + String m = message.getMessage(); + if (null == m) { + return NO_MESSAGE_TEXT; + } else { + return m; + } + } + } + + /** structured message abort */ + protected IMessage message; + + /** true if this is a porter exception - only used to hold message */ + protected boolean isPorter; + + /** abort with default String message */ + public AbortException() { + this("ABORT"); + isSilent = true; + } + + /** abort with message */ + public AbortException(String s) { + super(null != s ? s : NO_MESSAGE_TEXT); + this.message = null; + } + + /** abort with structured message */ + public AbortException(IMessage message) { + super(extractMessage(message)); + this.message = message; + } + + /** @return IMessage structured message, if set */ + public IMessage getIMessage() { + return message; + } + + /** + * The stack trace of a porter is invalid; it is only used to carry a message (which may itself have a wrapped exception). + * + * @return true if this exception is only to carry exception + */ + public boolean isPorter() { + return isPorter; + } + + /** @return Throwable at bottom of IMessage chain, if any */ + public Throwable getThrown() { + Throwable result = null; + IMessage m = getIMessage(); + if (null != m) { + result = m.getThrown(); + if (result instanceof AbortException) { + return ((AbortException) result).getThrown(); + } + } + return result; + } + + private void setIMessage(IMessage message) { + this.message = message; + } + + // ----------- proxy attempts + /** + * Get message for this AbortException, either associated explicitly as message or implicitly as IMessage message or its thrown + * message. + * + * @see java.lang.Throwable#getMessage() + */ + public String getMessage() { + String message = super.getMessage(); + if ((null == message) || (NO_MESSAGE_TEXT == message)) { + IMessage m = getIMessage(); + if (null != m) { + message = m.getMessage(); + if (null == message) { + Throwable thrown = m.getThrown(); + if (null != thrown) { + message = thrown.getMessage(); + } + } + } + if (null == message) { + message = NO_MESSAGE_TEXT; // better than nothing + } + } + return message; + } + + /** + * @see java.lang.Throwable#printStackTrace() + */ + public void printStackTrace() { + printStackTrace(System.out); + } + + /** + * Print the stack trace of any enclosed thrown or this otherwise. + * + * @see java.lang.Throwable#printStackTrace(PrintStream) + */ + public void printStackTrace(PrintStream s) { + IMessage m = getIMessage(); + Throwable thrown = (null == m ? null : m.getThrown()); + if (!isPorter() || (null == thrown)) { + s.println("Message: " + m); + super.printStackTrace(s); + } else { + thrown.printStackTrace(s); + } + } + + /** + * Print the stack trace of any enclosed thrown or this otherwise. + * + * @see java.lang.Throwable#printStackTrace(PrintWriter) + */ + public void printStackTrace(PrintWriter s) { + IMessage m = getIMessage(); + Throwable thrown = (null == m ? null : m.getThrown()); + if (null == thrown) { // Always print + if (isPorter()) { + s.println("(Warning porter AbortException without thrown)"); + } + s.println("Message: " + m); + super.printStackTrace(s); + } else { + thrown.printStackTrace(s); + } + } + + public boolean isSilent() { + return isSilent; + } + + public void setIsSilent(boolean isSilent) { + this.isSilent = isSilent; + } + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/Constants.java b/bridge/src/main/java/org/aspectj/bridge/Constants.java new file mode 100644 index 000000000..31f239678 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/Constants.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * 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: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.bridge; + +public class Constants { + + /* Default resource names for user and generate aop.xml file */ + public final static String AOP_USER_XML = "META-INF/aop.xml"; + public final static String AOP_AJC_XML = "META-INF/aop-ajc.xml"; + + /* Resource name for OSGi */ + public final static String AOP_OSGI_XML = "org/aspectj/aop.xml"; + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/CountingMessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/CountingMessageHandler.java new file mode 100644 index 000000000..4ce550876 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/CountingMessageHandler.java @@ -0,0 +1,157 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.util.Enumeration; +import java.util.Hashtable; + +import org.aspectj.util.LangUtil; + +/** + * Wrap an IMessageHandler to count messages handled. Messages being ignored by the delegate IMessageHandler are not counted. + */ +public class CountingMessageHandler implements IMessageHandler { + + public final IMessageHandler delegate; + public final CountingMessageHandler proxy; + private final Hashtable counters; + + public static CountingMessageHandler makeCountingMessageHandler(IMessageHandler handler) { + if (handler instanceof CountingMessageHandler) { + return (CountingMessageHandler) handler; + } else { + return new CountingMessageHandler(handler); + } + } + + public CountingMessageHandler(IMessageHandler delegate) { + LangUtil.throwIaxIfNull(delegate, "delegate"); + this.delegate = delegate; + this.counters = new Hashtable(); + proxy = (delegate instanceof CountingMessageHandler ? (CountingMessageHandler) delegate : null); + } + + /** @return delegate.handleMessage(IMessage) */ + public boolean handleMessage(IMessage message) throws AbortException { + if (null != proxy) { + return proxy.handleMessage(message); + } + if (null != message) { + IMessage.Kind kind = message.getKind(); + if (!isIgnoring(kind)) { + increment(kind); + } + } + return delegate.handleMessage(message); + } + + /** @return delegate.isIgnoring(IMessage.Kind) */ + public boolean isIgnoring(IMessage.Kind kind) { + return delegate.isIgnoring(kind); + } + + /** + * Delegate + * + * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) + * @param kind + */ + public void dontIgnore(IMessage.Kind kind) { + delegate.dontIgnore(kind); + } + + /** + * Delegate + * + * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind) + * @param kind + */ + public void ignore(IMessage.Kind kind) { + delegate.ignore(kind); + } + + /** @return delegate.toString() */ + public String toString() { + return delegate.toString(); + } + + /** + * Return count of messages seen through this interface. + * + * @param kind the IMessage.Kind of the messages to count (if null, count all) + * @param orGreater if true, then count this kind and any considered greater by the ordering of IMessage.Kind.COMPARATOR + * @return number of messages of this kind (optionally or greater) + * @see IMessage.Kind.COMPARATOR + */ + public int numMessages(IMessage.Kind kind, boolean orGreater) { + if (null != proxy) { + return proxy.numMessages(kind, orGreater); + } + int result = 0; + if (null == kind) { + for (Enumeration enu = counters.elements(); enu.hasMoreElements();) { + result += (enu.nextElement()).count; + } + } else if (!orGreater) { + result = numMessages(kind); + } else { + for (IMessage.Kind k : IMessage.KINDS) { + if (kind.isSameOrLessThan(k)) { + result += numMessages(k); + } + } + } + return result; + } + + /** + * @return true if 0 is less than numMessages(IMessage.ERROR, true) + */ + public boolean hasErrors() { + return (0 < numMessages(IMessage.ERROR, true)); + } + + private int numMessages(IMessage.Kind kind) { + if (null != proxy) { + return proxy.numMessages(kind); + } + IntHolder counter = counters.get(kind); + return (null == counter ? 0 : counter.count); + } + + private void increment(IMessage.Kind kind) { + if (null != proxy) { + throw new IllegalStateException("not called when proxying"); + } + + IntHolder counter = counters.get(kind); + if (null == counter) { + counter = new IntHolder(); + counters.put(kind, counter); + } + counter.count++; + } + + private static class IntHolder { + int count; + } + + public void reset() { + if (proxy != null) { + proxy.reset(); + } + counters.clear(); + } + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/ICommand.java b/bridge/src/main/java/org/aspectj/bridge/ICommand.java new file mode 100644 index 000000000..b77d58e59 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/ICommand.java @@ -0,0 +1,39 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.bridge; + + +/** + * Command wrapper with collecting parameter for messages. + */ +public interface ICommand { + /** + * Run command with the given options. + * @param args the String[] options for the command + * @param handler the IMessageHandler for all output from + * the command + * @return true if the command completed successfully + */ + boolean runCommand(String[] args, IMessageHandler handler); + + /** + * Rerun the command. + * + * @param handler the IMessageHandler for all output from the command + * + * @return true if the command completed successfully + */ + boolean repeatCommand(IMessageHandler handler); +} diff --git a/bridge/src/main/java/org/aspectj/bridge/ILifecycleAware.java b/bridge/src/main/java/org/aspectj/bridge/ILifecycleAware.java new file mode 100644 index 000000000..c5ac9b149 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/ILifecycleAware.java @@ -0,0 +1,35 @@ +/* ******************************************************************* + * 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: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.bridge; + +/** + * Interface that can be implemented by MessageHandlers that need to + * perform some additional processing when a build is starting and + * when it has finished. + * + * @author Adrian Colyer + * @since 1.5.1 + */ +public interface ILifecycleAware { + + /** + * called when a build starts + */ + void buildStarting(boolean isIncremental); + + /** + * called when a batch build finishes + * + */ + void buildFinished(boolean wasIncremental); + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessage.java b/bridge/src/main/java/org/aspectj/bridge/IMessage.java new file mode 100644 index 000000000..a32a631e6 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/IMessage.java @@ -0,0 +1,150 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Wrap message with any associated throwable or source location. + */ +public interface IMessage { + /** no messages */ + public static final IMessage[] RA_IMessage = new IMessage[0]; + + // int values must sync with KINDS order below + public static final Kind WEAVEINFO = new Kind("weaveinfo", 5); + public static final Kind INFO = new Kind("info", 10); + public static final Kind DEBUG = new Kind("debug", 20); + public static final Kind TASKTAG = new Kind("task", 25); // represents a 'TODO' from eclipse - producted by the compiler and + // consumed by AJDT + public static final Kind WARNING = new Kind("warning", 30); + public static final Kind ERROR = new Kind("error", 40); + public static final Kind FAIL = new Kind("fail", 50); + public static final Kind ABORT = new Kind("abort", 60); + // XXX prefer another Kind to act as selector for "any", + // but can't prohibit creating messages with it. + // public static final Kind ANY = new Kind("any-selector", 0); + + /** + * list of Kind in precedence order. 0 is less than IMessage.Kind.COMPARATOR.compareTo(KINDS.get(i), KINDS.get(i + 1)) + */ + public static final List KINDS = Collections.unmodifiableList(Arrays.asList(new Kind[] { WEAVEINFO, INFO, DEBUG, TASKTAG, + WARNING, ERROR, FAIL, ABORT })); + + /** @return non-null String with simple message */ + String getMessage(); + + /** @return the kind of this message */ + Kind getKind(); + + /** @return true if this is an error */ + boolean isError(); + + /** @return true if this is a warning */ + boolean isWarning(); + + /** @return true if this is an internal debug message */ + boolean isDebug(); + + /** @return true if this is information for the user */ + boolean isInfo(); + + /** @return true if the process is aborting */ + boolean isAbort(); // XXX ambiguous + + /** @return true if this is a task tag message */ + boolean isTaskTag(); + + /** @return true if something failed */ + boolean isFailed(); + + /** Caller can verify if this message came about because of a DEOW */ + boolean getDeclared(); + + /** Return the ID of the message where applicable, see IProblem for list of valid IDs */ + int getID(); + + /** Return the start position of the problem (inclusive), or -1 if unknown. */ + int getSourceStart(); + + /** Return the end position of the problem (inclusive), or -1 if unknown. */ + int getSourceEnd(); + + /** @return Throwable associated with this message, or null if none */ + Throwable getThrown(); + + /** @return source location associated with this message, or null if none */ + ISourceLocation getSourceLocation(); + + public static final class Kind implements Comparable { + public static final Comparator COMPARATOR = new Comparator() { + public int compare(IMessage.Kind one, IMessage.Kind two) { + if (null == one) { + return (null == two ? 0 : -1); + } else if (null == two) { + return 1; + } else if (one == two) { + return 0; + } else { + return (one.precedence - two.precedence); + } + } + }; + + /** + * @param kind the Kind floor + * @return false if kind is null or this has less precedence than kind, true otherwise. + */ + public boolean isSameOrLessThan(Kind kind) { + return (0 >= COMPARATOR.compare(this, kind)); + } + + public int compareTo(IMessage.Kind other) { + return COMPARATOR.compare(this, other); + } + + private final int precedence; + private final String name; + + private Kind(String name, int precedence) { + this.name = name; + this.precedence = precedence; + } + + public String toString() { + return name; + } + } + + /** + * @return Detailed information about the message. For example, for declare error/warning messages this returns information + * about the corresponding join point's static part. + */ + public String getDetails(); + + /** + * @return List of ISourceLocation instances that indicate additional source locations relevent to this message as + * specified by the message creator. The list should not include the primary source location associated with the message + * which can be obtained from getSourceLocation(). + *

+ * An example of using extra locations would be in a warning message that + * flags all shadow locations that will go unmatched due to a pointcut definition + * being based on a subtype of a defining type. + * @see AspectJ bug 41952 + */ + public List getExtraSourceLocations(); +} diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessageContext.java b/bridge/src/main/java/org/aspectj/bridge/IMessageContext.java new file mode 100644 index 000000000..2f5512a1d --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/IMessageContext.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * 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: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.bridge; + +public interface IMessageContext { + + public String getContextId (); +} diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/IMessageHandler.java new file mode 100644 index 000000000..6dcdfeafb --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/IMessageHandler.java @@ -0,0 +1,89 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.bridge; + +import java.io.PrintWriter; + +/** + * Handle messages, logging and/or aborting as appropriate. + * Implementations define which messages are logged and whether + * the handler aborts the process. + * For messages that are costly to construct, clients may query + * {@link #isIgnoring(IMessage.Kind)} + * to avoid construction if the message will be ignored. + * Clients passing messages to an IMessageHandler should not + * interfere with aborts by catching AbortException unless + * otherwise required by their logic or the message handler. + */ +public interface IMessageHandler { + /** print all to System.err and throw AbortException on failure or abort messages */ + public static final IMessageHandler SYSTEM_ERR = + new MessageWriter(new PrintWriter(System.err, true), true); + + /** print all to System.out but do not throw AbortException on failure or abort messages */ + public static final IMessageHandler SYSTEM_OUT = + new MessageWriter(new PrintWriter(System.out, true), false); + + /** Throw exceptions for anything with ERROR or greater severity */ + public static final IMessageHandler THROW = + new IMessageHandler() { + public boolean handleMessage(IMessage message) { + if (message.getKind().compareTo(IMessage.ERROR) >= 0) { + throw new AbortException(message); + } else { + return SYSTEM_OUT.handleMessage(message); + } + } + public boolean isIgnoring(IMessage.Kind kind) { + return false; + } + public void dontIgnore(IMessage.Kind kind) { + + } + public void ignore(IMessage.Kind kind) { + } + }; + + /** + * Handle message, by reporting and/or throwing an AbortException. + * @param message the IMessage to handle - never null + * @return true if this message was handled by this handler + * @throws IllegalArgumentException if message is null + * @throws AbortException depending on handler logic. + */ + boolean handleMessage(IMessage message) throws AbortException; + + /** + * Signal clients whether this will ignore messages of a given type. + * Clients may use this to avoid constructing or sending certain messages. + * @return true if this handler is ignoring all messages of this type + */ + boolean isIgnoring(IMessage.Kind kind); + + /** + * Allow fine grained configuration after initialization. Minaly used in LTW. Most of the + * implementation can have this method be a no-op. + * + * @param kind + */ + void dontIgnore(IMessage.Kind kind); + + /** + * Allow fine grained configuration after initialization. + * + * @param kind + */ + void ignore(IMessage.Kind kind); +} diff --git a/bridge/src/main/java/org/aspectj/bridge/IMessageHolder.java b/bridge/src/main/java/org/aspectj/bridge/IMessageHolder.java new file mode 100644 index 000000000..fdf2a6779 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/IMessageHolder.java @@ -0,0 +1,66 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.util.List; + +/** + * Hold and query a collection of messages. + */ +public interface IMessageHolder extends IMessageHandler { // XXX do not extend - mix instead + // XXX go to LT EQ GT GE LE rather than simple orGreater + /** value for orGreater parameter */ + public static final boolean ORGREATER = true; + + /** value for orGreater parameter */ + public static final boolean EQUAL = false; + + /** + * Tell whether this holder has any message of this kind (optionally or greater). + * + * @param kind the IMessage.Kind to check for - accept any if null + * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR + * @return true if this holder has any message of this kind, or if orGreater and any message has a greater kind, as determined + * by IMessage.Kind.COMPARATOR + */ + boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater); + + /** + * Count the messages currently held by this holder. Pass null to get all kinds. + * + * @param kind the IMessage.Kind expected, or null for all messages + * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR + * @return number of IMessage held (now) by this holder + */ + int numMessages(IMessage.Kind kind, boolean orGreater); + + /** + * Get all messages or those of a specific kind. Pass null to get all kinds. + * + * @param kind the IMessage.Kind expected, or null for all messages + * @param orGreater if true, also get any greater than the target kind as determined by IMessage.Kind.COMPARATOR + * @return IMessage[] of messages of the right kind, or IMessage.NONE + */ + IMessage[] getMessages(IMessage.Kind kind, boolean orGreater); + + /** @return unmodifiable List view of underlying collection of IMessage */ + List getUnmodifiableListView(); + + /** + * Clear any messages. + * + * @throws UnsupportedOperationException if message list is read-only + */ + void clearMessages() throws UnsupportedOperationException; +} diff --git a/bridge/src/main/java/org/aspectj/bridge/IProgressListener.java b/bridge/src/main/java/org/aspectj/bridge/IProgressListener.java new file mode 100644 index 000000000..4326f7263 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/IProgressListener.java @@ -0,0 +1,40 @@ +/* ******************************************************************* + * Copyright (c) 2003 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.bridge; + +/** + * Used to give progress information typically to IDEs + */ +public interface IProgressListener { + /** + * @param text the current phase of processing + */ + public void setText(String text); + + /** + * @param percentDone how much work is completed so far + */ + public void setProgress(double percentDone); + + /** + * @param cancelRequested true if the caller wants the current compilation to stop asap + */ + public void setCancelledRequested(boolean cancelRequested); + + /** + * @return true if the consumer of the progress info would like the compileation to stop + */ + public boolean isCancelledRequested(); + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/ISourceLocation.java b/bridge/src/main/java/org/aspectj/bridge/ISourceLocation.java new file mode 100644 index 000000000..7ad9423c2 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/ISourceLocation.java @@ -0,0 +1,72 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.io.File; + +/** + * Represent source location as a starting line/column and ending line in a source file. Implementations should be immutable. XXX + * why? + * + * @see org.aspectj.lang.reflect.SourceLocation + * @see org.aspectj.compiler.base.parser.SourceInfo + * @see org.aspectj.tools.ide.SourceLine + * @see org.aspectj.testing.harness.ErrorLine + */ +public interface ISourceLocation extends java.io.Serializable { + static final int MAX_LINE = Integer.MAX_VALUE / 2; + static final int MAX_COLUMN = MAX_LINE; + + /** non-null but empty (nonexisting) File constant */ + static final File NO_FILE = new File("ISourceLocation.NO_FILE"); + + /** signal that column is not known */ + static final int NO_COLUMN = Integer.MIN_VALUE + 1; + + /** non-null but empty constant source location */ + static final ISourceLocation EMPTY = new SourceLocation(NO_FILE, 0, 0, 0); + + /** + * @return File source or NO_FILE if the implementation requires a non-null result or null otherwise + */ + File getSourceFile(); + + /** @return 0..MAX_LINE */ + int getLine(); + + /** + * @return int 0..MAX_COLUMN actual column or 0 if column input was ISourceLocation.NO_COLUMN + */ + int getColumn(); + + /** + * @return offset into file + */ + int getOffset(); + + /** @return getLine()..MAX_LINE */ + int getEndLine(); + + /** @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/main/java/org/aspectj/bridge/Message.java b/bridge/src/main/java/org/aspectj/bridge/Message.java new file mode 100644 index 000000000..a4f17072b --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/Message.java @@ -0,0 +1,190 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Implement messages. This implementation is immutable if ISourceLocation is immutable. + */ +public class Message implements IMessage { + private final String message; + private final IMessage.Kind kind; + private final Throwable thrown; + private final ISourceLocation sourceLocation; + private final String details; + private final List extraSourceLocations; + private final boolean declared; // Is it a DEOW ? + private final int id; + private final int sourceStart, sourceEnd; + + /** + * Create a (compiler) error or warning message + * + * @param message the String used as the underlying message + * @param location the ISourceLocation, if any, associated with this message + * @param isError if true, use IMessage.ERROR; else use IMessage.WARNING + */ + public Message(String message, ISourceLocation location, boolean isError) { + this(message, (isError ? IMessage.ERROR : IMessage.WARNING), null, location); + } + + public Message(String message, ISourceLocation location, boolean isError, ISourceLocation[] extraSourceLocations) { + this(message, "", (isError ? IMessage.ERROR : IMessage.WARNING), location, null, + (extraSourceLocations.length > 0 ? extraSourceLocations : null)); + } + + /** + * Create a message, handling null values for message and kind if thrown is not null. + * + * @param message the String used as the underlying message + * @param kind the IMessage.Kind of message - not null + * @param thrown the Throwable, if any, associated with this message + * @param sourceLocation the ISourceLocation, if any, associated with this message + * @param details descriptive information about the message + * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown + * is null. + */ + public Message(String message, String details, IMessage.Kind kind, ISourceLocation sourceLocation, Throwable thrown, + ISourceLocation[] extraSourceLocations) { + this(message, details, kind, sourceLocation, thrown, extraSourceLocations, false, 0, -1, -1); + } + + public Message(String message, String details, IMessage.Kind kind, ISourceLocation sLoc, Throwable thrown, + ISourceLocation[] otherLocs, boolean declared, int id, int sourcestart, int sourceend) { + this.details = details; + this.id = id; + this.sourceStart = sourcestart; + this.sourceEnd = sourceend; + this.message = ((message != null) ? message : ((thrown == null) ? null : thrown.getMessage())); + this.kind = kind; + this.sourceLocation = sLoc; + this.thrown = thrown; + if (otherLocs != null) { + this.extraSourceLocations = Collections.unmodifiableList(Arrays.asList(otherLocs)); + } else { + this.extraSourceLocations = Collections.emptyList(); + } + if (null == this.kind) { + throw new IllegalArgumentException("null kind"); + } + if (null == this.message) { + throw new IllegalArgumentException("null message"); + } + this.declared = declared; + } + + /** + * Create a message, handling null values for message and kind if thrown is not null. + * + * @param message the String used as the underlying message + * @param kind the IMessage.Kind of message - not null + * @param thrown the Throwable, if any, associated with this message + * @param sourceLocation the ISourceLocation, if any, associated with this message + * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown + * is null. + */ + public Message(String message, IMessage.Kind kind, Throwable thrown, ISourceLocation sourceLocation) { + this(message, "", kind, sourceLocation, thrown, null); + } + + /** @return the kind of this message */ + public IMessage.Kind getKind() { + return kind; + } + + /** @return true if kind == IMessage.ERROR */ + public boolean isError() { + return kind == IMessage.ERROR; + } + + /** @return true if kind == IMessage.WARNING */ + public boolean isWarning() { + return kind == IMessage.WARNING; + } + + /** @return true if kind == IMessage.DEBUG */ + public boolean isDebug() { + return kind == IMessage.DEBUG; + } + + public boolean isTaskTag() { + return kind == IMessage.TASKTAG; + } + + /** + * @return true if kind == IMessage.INFO + */ + public boolean isInfo() { + return kind == IMessage.INFO; + } + + /** @return true if kind == IMessage.ABORT */ + public boolean isAbort() { + return kind == IMessage.ABORT; + } + + /** Caller can verify if this message came about because of a DEOW */ + public boolean getDeclared() { + return declared; + } + + /** + * @return true if kind == IMessage.FAIL + */ + public boolean isFailed() { + return kind == IMessage.FAIL; + } + + /** @return non-null String with simple message */ + final public String getMessage() { + return message; + } + + /** @return Throwable associated with this message, or null if none */ + final public Throwable getThrown() { + return thrown; + } + + /** @return ISourceLocation associated with this message, or null if none */ + final public ISourceLocation getSourceLocation() { + return sourceLocation; + } + + public String toString() { + return MessageUtil.renderMessage(this, false); + } + + public String getDetails() { + return details; + } + + public List getExtraSourceLocations() { + return extraSourceLocations; + } + + public int getID() { + return id; + } + + public int getSourceStart() { + return sourceStart; + } + + public int getSourceEnd() { + return sourceEnd; + } +} diff --git a/bridge/src/main/java/org/aspectj/bridge/MessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/MessageHandler.java new file mode 100644 index 000000000..6fd8539cc --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/MessageHandler.java @@ -0,0 +1,265 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * This handler accumulates messages. To control messages accumulated, clients can ignore messages of a given kind, or install a + * listener/interceptor. The interceptor handles all messages (even null) first, and can halt further processing/accumlation by + * returning true. Clients can obtain messages accumulated using the get... methods. XXX this does not permit messages to be + * removed. + * + * @author PARC + * @author Andy Clement + */ +public class MessageHandler implements IMessageHolder { + + /** messages accumulated */ + protected final ArrayList messages; + /** kinds of messages to be ignored */ + protected final ArrayList ignoring; + /** result of handleMessage(..) for messages not accumulated (ignored) */ + protected boolean handleMessageResult; + /** listener which can halt processing by returning true */ + protected IMessageHandler interceptor; + + /** + * same as MessageHandler(false) + */ + public MessageHandler() { + this(false); + } + + /** + * @param accumulateOnly the result of handleMessage (i.e., if true, then only accumulate messages - stop processing + */ + public MessageHandler(boolean accumulateOnly) { + messages = new ArrayList(); + ignoring = new ArrayList(); + init(accumulateOnly); + ignore(IMessage.WEAVEINFO); // Off by default, need to explicitly be enabled (see -showWeaveInfo) + } + + /** + * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor. Assume that this should return false + * from handleMessage(..). + */ + public void init() { + init(false); + } + + /** + * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor. + * + * @param accumulateOnly boolean value returned from handleMessage after accumulating in list + */ + public void init(boolean accumulateOnly) { + handleMessageResult = accumulateOnly; + if (0 < messages.size()) { + messages.clear(); + } + if (0 < ignoring.size()) { + boolean ignoringWeaveMessages = isIgnoring(IMessage.WEAVEINFO); + ignoring.clear(); + if (ignoringWeaveMessages) { + ignore(IMessage.WEAVEINFO); + } + } + if (null != interceptor) { + interceptor = null; + } + } + + /** + * Clear the messages without changing other behavior. + */ + public void clearMessages() { + if (0 < messages.size()) { + messages.clear(); + } + } + + // ---------------------- IMessageHandler implementation + /** + * This implementation accumulates message. If an interceptor is installed and returns true (message handled), then processing + * halts and the message is not accumulated. + * + * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage) + * @return true on interception or the constructor value otherwise + */ + public boolean handleMessage(IMessage message) { + if ((null != interceptor) && (interceptor.handleMessage(message))) { + return true; + } + if (null == message) { + throw new IllegalArgumentException("null message"); + } + if (!ignoring.contains(message.getKind())) { + messages.add(message); + } + return handleMessageResult; + } + + /** + * @return true if this kind has been flagged to be ignored. + * @see #ignore(IMessage.Kind) + * @see org.aspectj.bridge.IMessageHandler#isIgnoring(Kind) + */ + public boolean isIgnoring(IMessage.Kind kind) { + return ((null != kind) && (ignoring.contains(kind))); + } + + // ---------------------- end of IMessageHandler implementation + + /** + * Set a message kind to be ignored from now on + */ + public void ignore(IMessage.Kind kind) { // XXX sync + if ((null != kind) && (!ignoring.contains(kind))) { + ignoring.add(kind); + } + } + + /** + * Remove a message kind from the list of those ignored from now on. + */ + public void dontIgnore(IMessage.Kind kind) { + if (null != kind) { + ignoring.remove(kind); + } + } + + /** + * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean) + */ + public boolean hasAnyMessage(final IMessage.Kind kind, final boolean orGreater) { + if (null == kind) { + return (0 < messages.size()); + } + if (!orGreater) { + for (IMessage m : messages) { + if (kind == m.getKind()) { + return true; + } + } + } else { + for (IMessage m : messages) { + if (kind.isSameOrLessThan(m.getKind())) { + return true; + } + } + } + return false; + } + + /** + * @return number of messages accumulated of a given kind + */ + public int numMessages(IMessage.Kind kind, final boolean orGreater) { + if (null == kind) { + return messages.size(); + } + int result = 0; + if (!orGreater) { + for (IMessage m : messages) { + if (kind == m.getKind()) { + result++; + } + } + } else { + for (IMessage m : messages) { + if (kind.isSameOrLessThan(m.getKind())) { + result++; + } + } + } + return result; + } + + /** + * @see org.aspectj.bridge.IMessageHolder#getUnmodifiableListView() + */ + public List getUnmodifiableListView() { + return Collections.unmodifiableList(messages); + } + + /** + * Get all messages or those of a specific kind. Pass null to get all kinds. + * + * @param kind the IMessage.Kind expected, or null for all messages + * @return IMessage[] of messages of the right kind + */ + public IMessage[] getMessages(IMessage.Kind kind, final boolean orGreater) { + if (null == kind) { + return messages.toArray(IMessage.RA_IMessage); + } + ArrayList result = new ArrayList(); + if (!orGreater) { + for (IMessage m : messages) { + if (kind == m.getKind()) { + result.add(m); + } + } + } else { + for (IMessage m : messages) { + if (kind.isSameOrLessThan(m.getKind())) { + result.add(m); + } + } + } + if (0 == result.size()) { + return IMessage.RA_IMessage; + } + return result.toArray(IMessage.RA_IMessage); + } + + /** + * @return array of error messages, or IMessage.NONE + */ + public IMessage[] getErrors() { + return getMessages(IMessage.ERROR, false); + } + + /** + * @return array of warning messages, or IMessage.NONE + */ + public IMessage[] getWarnings() { + return getMessages(IMessage.WARNING, false); + } + + /** + * Set the interceptor which gets any message before we process it. + * + * @param interceptor the IMessageHandler passed the message. Pass null to remove the old interceptor. + */ + public void setInterceptor(IMessageHandler interceptor) { + this.interceptor = interceptor; + } + + /** + * @return String containing list of messages + */ + public String toString() { + if (0 == messages.size()) { + return "MessageHandler: no messages"; + } else { + return "MessageHandler: " + messages; + } + + } + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/MessageUtil.java b/bridge/src/main/java/org/aspectj/bridge/MessageUtil.java new file mode 100644 index 000000000..6d85ea6f9 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/MessageUtil.java @@ -0,0 +1,1116 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.util.LangUtil; + +/** + * Convenience API's for constructing, printing, and sending messages. + */ +public class MessageUtil { + + // ------ some constant, content-less messages + // no variants for "info" or "debug", which should always have content + public static final IMessage ABORT_NOTHING_TO_RUN = new Message("aborting - nothing to run", IMessage.ABORT, null, null); + + public static final IMessage FAIL_INCOMPLETE = new Message("run not completed", IMessage.FAIL, null, null); + + public static final IMessage ABORT_NOMESSAGE = new Message("", IMessage.ABORT, null, null); + + public static final IMessage FAIL_NOMESSAGE = new Message("", IMessage.FAIL, null, null); + + public static final IMessage ERROR_NOMESSAGE = new Message("", IMessage.ERROR, null, null); + + public static final IMessage WARNING_NOMESSAGE = new Message("", IMessage.WARNING, null, null); + + /** handle abort message (ignored if handler is null) */ + public static boolean abort(IMessageHandler handler, String message) { + return ((null != handler) && handler.handleMessage(abort(message))); + } + + /** create and handle exception message (ignored if handler is null) */ + public static boolean abort(IMessageHandler handler, String message, Throwable t) { + if (handler != null) { + return handler.handleMessage(abort(message, t)); + } + return false; + } + + /** create and handle fail message (ignored if handler is null) */ + public static boolean fail(IMessageHandler handler, String message) { + return ((null != handler) && handler.handleMessage(fail(message))); + } + + // /** create and handle fail message from reader (ignored if handler is null) */ + // public static boolean fail(IMessageHandler handler, String message, LineReader reader) { + // return ((null != handler) + // && handler.handleMessage(fail(message, reader))); + // } + + /** create and handle fail message (ignored if handler is null) */ + public static boolean fail(IMessageHandler handler, String message, Throwable thrown) { + return ((null != handler) && handler.handleMessage(fail(message, thrown))); + } + + /** create and handle error message (ignored if handler is null) */ + public static boolean error(IMessageHandler handler, String message) { + return ((null != handler) && handler.handleMessage(error(message))); + } + + /** create and handle warn message (ignored if handler is null) */ + public static boolean warn(IMessageHandler handler, String message) { + return ((null != handler) && handler.handleMessage(warn(message))); + } + + /** create and handle debug message (ignored if handler is null) */ + public static boolean debug(IMessageHandler handler, String message) { + return ((null != handler) && handler.handleMessage(debug(message))); + } + + /** create and handle info message (ignored if handler is null) */ + public static boolean info(IMessageHandler handler, String message) { + return ((null != handler) && handler.handleMessage(info(message))); + } + + /** @return ABORT_NOMESSAGE if message is empty or IMessage otherwise */ + // + public static IMessage abort(String message) { + if (LangUtil.isEmpty(message)) { + return ABORT_NOMESSAGE; + } else { + return new Message(message, IMessage.ABORT, null, null); + } + } + + /** + * @return abort IMessage with thrown and message o ABORT_NOMESSAGE if both are empty/null + */ + // + public static IMessage abort(String message, Throwable thrown) { + if (!LangUtil.isEmpty(message)) { + return new Message(message, IMessage.ABORT, thrown, null); + } else if (null == thrown) { + return ABORT_NOMESSAGE; + } else { + return new Message(thrown.getMessage(), IMessage.ABORT, thrown, null); + } + } + + /** @return FAIL_NOMESSAGE if message is empty or IMessage otherwise */ + public static IMessage fail(String message) { + if (LangUtil.isEmpty(message)) { + return FAIL_NOMESSAGE; + } else { + return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY); + + // return fail(message, (LineReader) null); + } + } + + /** + * Create fail message. If message is empty but thrown is not, use thrown.getMessage() as the message. If message is empty and + * thrown is null, return FAIL_NOMESSAGE. + * + * @return FAIL_NOMESSAGE if thrown is null and message is empty or IMessage FAIL with message and thrown otherwise + */ + public static IMessage fail(String message, Throwable thrown) { + if (LangUtil.isEmpty(message)) { + if (null == thrown) { + return FAIL_NOMESSAGE; + } else { + return new Message(thrown.getMessage(), IMessage.FAIL, thrown, null); + } + } else { + return new Message(message, IMessage.FAIL, thrown, null); + } + } + + /** + * @return IMessage with IMessage.Kind FAIL and message as text and soure location from reader + */ + // public static IMessage fail(String message) {//, LineReader reader) { + // ISourceLocation loc = null; + // if (null == reader) { + // loc = ISourceLocation.EMPTY; + // } else { + // int line = reader.getLineNumber(); + // if (0 < line) { + // line = 0; + // } + // loc = new SourceLocation(reader.getFile(), line, line, 0); + // } + // return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY); + // } + + /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */ + // + public static IMessage error(String message, ISourceLocation location) { + if (LangUtil.isEmpty(message)) { + return ERROR_NOMESSAGE; + } else { + return new Message(message, IMessage.ERROR, null, location); + } + } + + /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */ + // + public static IMessage warn(String message, ISourceLocation location) { + if (LangUtil.isEmpty(message)) { + return WARNING_NOMESSAGE; + } else { + return new Message(message, IMessage.WARNING, null, location); + } + } + + /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */ + // + public static IMessage error(String message) { + if (LangUtil.isEmpty(message)) { + return ERROR_NOMESSAGE; + } else { + return new Message(message, IMessage.ERROR, null, null); + } + } + + /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */ + // + public static IMessage warn(String message) { + if (LangUtil.isEmpty(message)) { + return WARNING_NOMESSAGE; + } else { + return new Message(message, IMessage.WARNING, null, null); + } + } + + /** @return IMessage.DEBUG message with message content */ + public static IMessage debug(String message) { + return new Message(message, IMessage.DEBUG, null, null); + } + + /** @return IMessage.INFO message with message content */ + public static IMessage info(String message) { + return new Message(message, IMessage.INFO, null, null); + } + + // /** @return ISourceLocation with the current File/line of the reader */ + // public static ISourceLocation makeSourceLocation(LineReader reader) { + // LangUtil.throwIaxIfNull(reader, "reader"); + // + // int line = reader.getLineNumber(); + // if (0 < line) { + // line = 0; + // } + // return new SourceLocation(reader.getFile(), line, line, 0); + // } + + // ------------------------ printing messages + /** + * Print total counts message to the print stream, starting each on a new line + * + * @param messageHolder + * @param out + */ + public static void printMessageCounts(PrintStream out, IMessageHolder messageHolder) { + if ((null == out) || (null == messageHolder)) { + return; + } + printMessageCounts(out, messageHolder, ""); + } + + public static void printMessageCounts(PrintStream out, IMessageHolder holder, String prefix) { + out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder)); + } + + /** + * Print all message to the print stream, starting each on a new line + * + * @param messageHolder + * @param out + * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) + */ + public static void print(PrintStream out, IMessageHolder messageHolder) { + print(out, messageHolder, (String) null, (IMessageRenderer) null, (IMessageHandler) null); + } + + /** + * Print all message to the print stream, starting each on a new line, with a prefix. + * + * @param messageHolder + * @param out + * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) + */ + public static void print(PrintStream out, IMessageHolder holder, String prefix) { + print(out, holder, prefix, (IMessageRenderer) null, (IMessageHandler) null); + } + + /** + * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. + * + * @param messageHolder + * @param out + * @param renderer IMessageRender to render result - use MESSAGE_LINE if null + * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) + */ + public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer) { + print(out, holder, prefix, renderer, (IMessageHandler) null); + } + + /** + * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. The first line + * renders a summary: {prefix}MessageHolder: {summary} Each message line has the following form: + * + *

+	 * {prefix}[{kind} {index}]: {rendering}
+	 * 
+ * + * (where "{index}" (length 3) is the position within the set of like-kinded messages, ignoring selector omissions. Renderers + * are free to render multi-line output. + * + * @param out the PrintStream sink - return silently if null + * @param messageHolder the IMessageHolder with the messages to print + * @param renderer IMessageRender to render result - use MESSAGE_ALL if null + * @param selector IMessageHandler to select messages to render - if null, do all non-null + */ + public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer, + IMessageHandler selector) { + print(out, holder, prefix, renderer, selector, true); + } + + public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer, + IMessageHandler selector, boolean printSummary) { + if ((null == out) || (null == holder)) { + return; + } + if (null == renderer) { + renderer = MESSAGE_ALL; + } + if (null == selector) { + selector = PICK_ALL; + } + if (printSummary) { + out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder)); + } + for (IMessage.Kind kind : IMessage.KINDS) { + if (!selector.isIgnoring(kind)) { + IMessage[] messages = holder.getMessages(kind, IMessageHolder.EQUAL); + for (int i = 0; i < messages.length; i++) { + if (selector.handleMessage(messages[i])) { + String label = (null == prefix ? "" : prefix + "[" + kind + " " + LangUtil.toSizedString(i, 3) + "]: "); + out.println(label + renderer.renderToString(messages[i])); + } + } + } + } + } + + public static String toShortString(IMessage message) { + if (null == message) { + return "null"; + } + String m = message.getMessage(); + Throwable t = message.getThrown(); + + return (message.getKind() + (null == m ? "" : ": " + m) + (null == t ? "" : ": " + LangUtil.unqualifiedClassName(t))); + } + + /** @return int number of message of this kind (optionally or greater) in list */ + public static int numMessages(List messages, Kind kind, boolean orGreater) { + if (LangUtil.isEmpty(messages)) { + return 0; + } + IMessageHandler selector = makeSelector(kind, orGreater, null); + IMessage[] result = visitMessages(messages, selector, true, false); + return result.length; + } + + /** + * Select all messages in holder except those of the same kind (optionally or greater). If kind is null, then all messages are + * rejected, so an empty list is returned. + * + * @return unmodifiable list of specified IMessage + */ + public static IMessage[] getMessagesExcept(IMessageHolder holder, final IMessage.Kind kind, final boolean orGreater) { + if ((null == holder) || (null == kind)) { + return new IMessage[0]; + } + + IMessageHandler selector = new IMessageHandler() { + public boolean handleMessage(IMessage message) { + IMessage.Kind test = message.getKind(); + return (!(orGreater ? kind.isSameOrLessThan(test) : kind == test)); + } + + public boolean isIgnoring(Kind kind) { + return false; + } + + public void dontIgnore(IMessage.Kind kind) { + + } + + public void ignore(Kind kind) { + } + }; + return visitMessages(holder, selector, true, false); + } + + /** @return unmodifiable list of IMessage complying with parameters */ + public static List getMessages(IMessageHolder holder, IMessage.Kind kind, boolean orGreater, String infix) { + if (null == holder) { + return Collections.emptyList(); + } + if ((null == kind) && LangUtil.isEmpty(infix)) { + return holder.getUnmodifiableListView(); + } + IMessageHandler selector = makeSelector(kind, orGreater, infix); + IMessage[] messages = visitMessages(holder, selector, true, false); + if (LangUtil.isEmpty(messages)) { + return Collections.emptyList(); + } + return Collections.unmodifiableList(Arrays.asList(messages)); + } + + /** + * Extract messages of type kind from the input list. + * + * @param messages if null, return EMPTY_LIST + * @param kind if null, return messages + * @see MessageHandler#getMessages(Kind) + */ + public static List getMessages(List messages, IMessage.Kind kind) { + if (null == messages) { + return Collections.emptyList(); + } + if (null == kind) { + return messages; + } + ArrayList result = new ArrayList(); + for (IMessage message : messages) { + if (kind == message.getKind()) { + result.add(message); + } + } + if (0 == result.size()) { + return Collections.emptyList(); + } + return result; + } + + /** + * Map to the kind of messages associated with this string key. + * + * @param kind the String representing the kind of message (IMessage.Kind.toString()) + * @return Kind the associated IMessage.Kind, or null if not found + */ + public static IMessage.Kind getKind(String kind) { + if (null != kind) { + kind = kind.toLowerCase(); + for (IMessage.Kind k : IMessage.KINDS) { + if (kind.equals(k.toString())) { + return k; + } + } + } + return null; + } + + /** + * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor + */ + public static IMessage[] visitMessages(IMessageHolder holder, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) { + if (null == holder) { + return IMessage.RA_IMessage; + } else { + return visitMessages(holder.getUnmodifiableListView(), visitor, accumulate, abortOnFail); + } + } + + /** + * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor + */ + public static IMessage[] visitMessages(IMessage[] messages, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) { + if (LangUtil.isEmpty(messages)) { + return IMessage.RA_IMessage; + } else { + return visitMessages(Arrays.asList(messages), visitor, accumulate, abortOnFail); + } + } + + /** + * Run visitor over a collection of messages, optionally accumulating those accepted by the visitor + * + * @param messages if null or empty, return IMessage.RA_IMessage + * @param visitor run visitor.handleMessage(message) on each message - if null and messages not empty, IllegalArgumentException + * @param accumulate if true, then return accepted IMessage[] + * @param abortOnFail if true and visitor returns false, stop visiting + * @return IMessage.RA_IMessage if collection is empty, if not accumulate, or if visitor accepted no IMessage, or IMessage[] of + * accepted messages otherwise + * @throws IllegalArgumentException if any in collection are not instanceof IMessage + */ + public static IMessage[] visitMessages(Collection messages, IMessageHandler visitor, final boolean accumulate, + final boolean abortOnFail) { + if (LangUtil.isEmpty(messages)) { + return IMessage.RA_IMessage; + } + LangUtil.throwIaxIfNull(visitor, "visitor"); + ArrayList result = (accumulate ? new ArrayList() : null); + for (IMessage m : messages) { + if (visitor.handleMessage(m)) { + if (accumulate) { + result.add(m); + } + } else if (abortOnFail) { + break; + } + } + if (!accumulate || (0 == result.size())) { + return IMessage.RA_IMessage; + } else { + return result.toArray(IMessage.RA_IMessage); + } + } + + /** + * Make an IMessageHandler that handles IMessage if they have the right kind (or greater) and contain some infix String. + * + * @param kind the IMessage.Kind required of the message + * @param orGreater if true, also accept messages with greater kinds, as defined by IMessage.Kind.COMPARATOR + * @param infix the String text to require in the message - may be null or empty to accept any message with the specified kind. + * @return IMessageHandler selector that works to param specs + */ + public static IMessageHandler makeSelector(IMessage.Kind kind, boolean orGreater, String infix) { + if (!orGreater && LangUtil.isEmpty(infix)) { + if (kind == IMessage.ABORT) { + return PICK_ABORT; + } else if (kind == IMessage.DEBUG) { + return PICK_DEBUG; + } else if (kind == IMessage.DEBUG) { + return PICK_DEBUG; + } else if (kind == IMessage.ERROR) { + return PICK_ERROR; + } else if (kind == IMessage.FAIL) { + return PICK_FAIL; + } else if (kind == IMessage.INFO) { + return PICK_INFO; + } else if (kind == IMessage.WARNING) { + return PICK_WARNING; + } + } + return new KindSelector(kind, orGreater, infix); + } + + // ------------------ visitors to select messages + public static final IMessageHandler PICK_ALL = new KindSelector((IMessage.Kind) null); + public static final IMessageHandler PICK_ABORT = new KindSelector(IMessage.ABORT); + public static final IMessageHandler PICK_DEBUG = new KindSelector(IMessage.DEBUG); + public static final IMessageHandler PICK_ERROR = new KindSelector(IMessage.ERROR); + public static final IMessageHandler PICK_FAIL = new KindSelector(IMessage.FAIL); + public static final IMessageHandler PICK_INFO = new KindSelector(IMessage.INFO); + public static final IMessageHandler PICK_WARNING = new KindSelector(IMessage.WARNING); + public static final IMessageHandler PICK_ABORT_PLUS = new KindSelector(IMessage.ABORT, true); + public static final IMessageHandler PICK_DEBUG_PLUS = new KindSelector(IMessage.DEBUG, true); + public static final IMessageHandler PICK_ERROR_PLUS = new KindSelector(IMessage.ERROR, true); + public static final IMessageHandler PICK_FAIL_PLUS = new KindSelector(IMessage.FAIL, true); + public static final IMessageHandler PICK_INFO_PLUS = new KindSelector(IMessage.INFO, true); + public static final IMessageHandler PICK_WARNING_PLUS = new KindSelector(IMessage.WARNING, true); + + /** implementation for PICK_... constants */ + private static class KindSelector implements IMessageHandler { + final IMessage.Kind sought; + final boolean floor; + final String infix; + + KindSelector(IMessage.Kind sought) { + this(sought, false); + } + + KindSelector(IMessage.Kind sought, boolean floor) { + this(sought, floor, null); + } + + KindSelector(IMessage.Kind sought, boolean floor, String infix) { + this.sought = sought; + this.floor = floor; + this.infix = (LangUtil.isEmpty(infix) ? null : infix); + } + + /** + * @return false if this message is null, of true if we seek any kind (null) or if this has the exact kind we seek and this + * has any text sought + */ + public boolean handleMessage(IMessage message) { + return ((null != message) && !isIgnoring(message.getKind()) && textIn(message)); + } + + /** @return true if handleMessage would return false for a message of this kind */ + public boolean isIgnoring(IMessage.Kind kind) { + if (!floor) { + return ((null != sought) && (sought != kind)); + } else if (null == sought) { + return false; + } else { + return (0 < IMessage.Kind.COMPARATOR.compare(sought, kind)); + } + } + + public void dontIgnore(IMessage.Kind kind) { + + } + + private boolean textIn(IMessage message) { + if (null == infix) { + return true; + } + String text = message.getMessage(); + return (text.indexOf(infix) != -1); + } + + public void ignore(Kind kind) { + } + } + + // ------------------ components to render messages + /** parameterize rendering behavior for messages */ + public static interface IMessageRenderer { + String renderToString(IMessage message); + } + + /** render message more verbosely if it is worse */ + public static final IMessageRenderer MESSAGE_SCALED = new IMessageRenderer() { + public String toString() { + return "MESSAGE_SCALED"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + IMessage.Kind kind = message.getKind(); + int level = 3; + if ((kind == IMessage.ABORT) || (kind == IMessage.FAIL)) { + level = 1; + } else if ((kind == IMessage.ERROR) || (kind == IMessage.WARNING)) { + level = 2; + } else { + level = 3; + } + String result = null; + switch (level) { + case (1): + result = MESSAGE_TOSTRING.renderToString(message); + break; + case (2): + result = MESSAGE_LINE.renderToString(message); + break; + case (3): + result = MESSAGE_SHORT.renderToString(message); + break; + } + Throwable thrown = message.getThrown(); + if (null != thrown) { + if (level == 3) { + result += "Thrown: \n" + LangUtil.renderExceptionShort(thrown); + } else { + result += "Thrown: \n" + LangUtil.renderException(thrown); + } + } + + return result; + } + }; + + /** render message as label, i.e., less than 33 char */ + public static final IMessageRenderer MESSAGE_LABEL = new IMessageRenderer() { + public String toString() { + return "MESSAGE_LABEL"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + return renderMessageLine(message, 5, 5, 32); + } + }; + + /** render message as label, i.e., less than 33 char, with no source location */ + public static final IMessageRenderer MESSAGE_LABEL_NOLOC = new IMessageRenderer() { + public String toString() { + return "MESSAGE_LABEL_NOLOC"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + return renderMessageLine(message, 10, 0, 32); + } + }; + + /** render message as line, i.e., less than 75 char, no internal line sep */ + public static final IMessageRenderer MESSAGE_LINE = new IMessageRenderer() { + public String toString() { + return "MESSAGE_LINE"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + return renderMessageLine(message, 8, 2, 74); + } + }; + + /** + * render message as line, i.e., less than 75 char, no internal line sep, trying to trim text as needed to end with a full + * source location + */ + public static final IMessageRenderer MESSAGE_LINE_FORCE_LOC = new IMessageRenderer() { + public String toString() { + return "MESSAGE_LINE_FORCE_LOC"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + return renderMessageLine(message, 2, 40, 74); + } + }; + + /** render message without restriction, up to 10K, including throwable */ + public static final IMessageRenderer MESSAGE_ALL = new IMessageRenderer() { + public String toString() { + return "MESSAGE_ALL"; + } + + public String renderToString(IMessage message) { + return renderMessage(message); + } + }; + + // /** render message without restriction, up to 10K, including (but eliding) throwable */ + // public static final IMessageRenderer MESSAGE_ALL_ELIDED= new IMessageRenderer() { + // public String toString() { return "MESSAGE_ALL_ELIDED"; } + // public String renderToString(IMessage message) { + // return renderMessage(message, true); + // } + // }; + + /** render message without restriction, except any Throwable thrown */ + public static final IMessageRenderer MESSAGE_MOST = new IMessageRenderer() { + public String toString() { + return "MESSAGE_MOST"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + return renderMessageLine(message, 1, 1, 10000); + } + }; + + /** + * render message as wide line, i.e., less than 256 char, no internal line sep, except any Throwable thrown + */ + public static final IMessageRenderer MESSAGE_WIDELINE = new IMessageRenderer() { + public String toString() { + return "MESSAGE_WIDELINE"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + return renderMessageLine(message, 8, 2, 255); // XXX revert to 256 + } + }; + /** render message using its toString() or "((IMessage) null)" */ + public static final IMessageRenderer MESSAGE_TOSTRING = new IMessageRenderer() { + public String toString() { + return "MESSAGE_TOSTRING"; + } + + public String renderToString(IMessage message) { + if (null == message) { + return "((IMessage) null)"; + } + return message.toString(); + } + }; + + /** render message using toShortString(IMessage)" */ + public static final IMessageRenderer MESSAGE_SHORT = new IMessageRenderer() { + public String toString() { + return "MESSAGE_SHORT"; + } + + public String renderToString(IMessage message) { + return toShortString(message); + } + }; + + /** + * This renders IMessage as String, ignoring empty elements and eliding any thrown stack traces. + * + * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace) + * @see renderSourceLocation(ISourceLocation loc) + */ + public static String renderMessage(IMessage message) { + return renderMessage(message, true); + } + + /** + * This renders IMessage as String, ignoring empty elements and eliding any thrown. + * + * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace) + * @see renderSourceLocation(ISourceLocation loc) + */ + public static String renderMessage(IMessage message, boolean elide) { + if (null == message) { + return "((IMessage) null)"; + } + + ISourceLocation loc = message.getSourceLocation(); + String locString = (null == loc ? "" : " at " + loc); + + String result = message.getKind() + locString + " " + message.getMessage(); + + Throwable thrown = message.getThrown(); + if (thrown != null) { + result += " -- " + LangUtil.renderExceptionShort(thrown); + result += "\n" + LangUtil.renderException(thrown, elide); + } + + if (message.getExtraSourceLocations().isEmpty()) { + return result; + } else { + return addExtraSourceLocations(message, result); + } + } + + public static String addExtraSourceLocations(IMessage message, String baseMessage) { + StringWriter buf = new StringWriter(); + PrintWriter writer = new PrintWriter(buf); + writer.println(baseMessage); + for (Iterator iter = message.getExtraSourceLocations().iterator(); iter.hasNext();) { + ISourceLocation element = iter.next(); + if (element != null) { + writer.print("\tsee also: " + element.toString()); + if (iter.hasNext()) { + writer.println(); + } + } + } + try { + buf.close(); + } catch (IOException ioe) { + } + return buf.getBuffer().toString(); + } + + /** + * Render ISourceLocation to String, ignoring empty elements (null or ISourceLocation.NO_FILE or ISourceLocation.NO_COLUMN + * (though implementations may return 0 from getColumn() when passed NO_COLUMN as input)). + * + * @return "((ISourceLocation) null)" if null or String rendering + * + *
+	 * {file:}line{:column}
+	 * 
+ * + */ + public static String renderSourceLocation(ISourceLocation loc) { + if (null == loc) { + return "((ISourceLocation) null)"; + } + StringBuffer sb = new StringBuffer(); + + File sourceFile = loc.getSourceFile(); + if (sourceFile != ISourceLocation.NO_FILE) { + sb.append(sourceFile.getPath()); + sb.append(":"); + } + int line = loc.getLine(); + sb.append("" + line); + + int column = loc.getColumn(); + if (column != ISourceLocation.NO_COLUMN) { + sb.append(":" + column); + } + + return sb.toString(); + } + + /** + * Render message in a line. IMessage.Kind is always printed, then any unqualified exception class, then the remainder of text + * and location according to their relative scale, all to fit in max characters or less. This does not render thrown except for + * the unqualified class name + * + * @param max the number of characters - forced to 32..10000 + * @param textScale relative proportion to spend on message and/or exception message, relative to source location - if 0, + * message is suppressed + * @param locScale relative proportion to spend on source location suppressed if 0 + * @return "((IMessage) null)" or message per spec + */ + public static String renderMessageLine(IMessage message, int textScale, int locScale, int max) { + + if (null == message) { + return "((IMessage) null)"; + } + if (max < 32) { + max = 32; + } else if (max > 10000) { + max = 10000; + } + if (0 > textScale) { + textScale = -textScale; + } + if (0 > locScale) { + locScale = -locScale; + } + + String text = message.getMessage(); + Throwable thrown = message.getThrown(); + ISourceLocation sl = message.getSourceLocation(); + IMessage.Kind kind = message.getKind(); + StringBuffer result = new StringBuffer(); + result.append(kind.toString()); + result.append(": "); + if (null != thrown) { + result.append(LangUtil.unqualifiedClassName(thrown) + " "); + if ((null == text) || ("".equals(text))) { + text = thrown.getMessage(); + } + } + + if (0 == textScale) { + text = ""; + } else if ((null != text) && (null != thrown)) { + // decide between message and exception text? + String s = thrown.getMessage(); + if ((null != s) && (0 < s.length())) { + text += " - " + s; + } + } + String loc = ""; + if ((0 != locScale) && (null != sl)) { + File f = sl.getSourceFile(); + if (f == ISourceLocation.NO_FILE) { + f = null; + } + if (null != f) { + loc = f.getName(); + } + int line = sl.getLine(); + int col = sl.getColumn(); + int end = sl.getEndLine(); + if ((0 == line) && (0 == col) && (0 == end)) { + // ignore numbers if default + } else { + loc += ":" + line + (col == 0 ? "" : ":" + col); + if (line != end) { // XXX consider suppressing nonstandard... + loc += ":" + end; + } + } + if (!LangUtil.isEmpty(loc)) { + loc = "@[" + loc; // matching "]" added below after clipping + } + } + + // now budget between text and loc + float totalScale = locScale + textScale; + float remainder = max - result.length() - 4; + if ((remainder > 0) && (0 < totalScale)) { + int textSize = (int) (remainder * textScale / totalScale); + int locSize = (int) (remainder * locScale / totalScale); + // adjust for underutilization + int extra = locSize - loc.length(); + if (0 < extra) { + locSize = loc.length(); + textSize += extra; + } + extra = textSize - text.length(); + if (0 < extra) { + textSize = text.length(); + if (locSize < loc.length()) { + locSize += extra; + } + } + if (locSize > loc.length()) { + locSize = loc.length(); + } + if (textSize > text.length()) { + textSize = text.length(); + } + if (0 < textSize) { + result.append(text.substring(0, textSize)); + } + if (0 < locSize) { + if (0 < textSize) { + result.append(" "); + } + result.append(loc.substring(0, locSize) + "]"); + } + } + return result.toString(); + } + + /** @return String of the form "{(# {type}) }.." for message kinds, skipping 0 */ + public static String renderCounts(IMessageHolder holder) { + if (0 == holder.numMessages(null, false)) { + return "(0 messages)"; + } + StringBuffer sb = new StringBuffer(); + for (IMessage.Kind kind : IMessage.KINDS) { + int num = holder.numMessages(kind, false); + if (0 < num) { + sb.append(" (" + num + " " + kind + ") "); + } + } + return sb.toString(); + } + + /** + * Factory for handler adapted to PrintStream XXX weak - only handles println(String) + * + * @param handler the IMessageHandler sink for the messages generated + * @param kind the IMessage.Kind of message to create + * @param overage the OuputStream for text not captured by the handler (if null, System.out used) + * @throws IllegalArgumentException if kind or handler is null + */ + public static PrintStream handlerPrintStream(final IMessageHandler handler, final IMessage.Kind kind, + final OutputStream overage, final String prefix) { + LangUtil.throwIaxIfNull(handler, "handler"); + LangUtil.throwIaxIfNull(kind, "kind"); + class HandlerPrintStream extends PrintStream { + HandlerPrintStream() { + super(null == overage ? System.out : overage); + } + + public void println() { + println(""); + } + + public void println(Object o) { + println(null == o ? "null" : o.toString()); + } + + public void println(String input) { + String textMessage = (null == prefix ? input : prefix + input); + IMessage m = new Message(textMessage, kind, null, null); + handler.handleMessage(m); + } + } + return new HandlerPrintStream(); + } + + /** utility class */ + private MessageUtil() { + } + + /** + * Handle all messages in the second handler using the first + * + * @param handler the IMessageHandler sink for all messages in source + * @param holder the IMessageHolder source for all messages to handle + * @param fastFail if true, stop on first failure + * @return false if any sink.handleMessage(..) failed + */ + public static boolean handleAll(IMessageHandler sink, IMessageHolder source, boolean fastFail) { + return handleAll(sink, source, null, true, fastFail); + } + + /** + * Handle messages in the second handler using the first + * + * @param handler the IMessageHandler sink for all messages in source + * @param holder the IMessageHolder source for all messages to handle + * @param kind the IMessage.Kind to select, if not null + * @param orGreater if true, also accept greater kinds + * @param fastFail if true, stop on first failure + * @return false if any sink.handleMessage(..) failed + */ + public static boolean handleAll(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater, + boolean fastFail) { + LangUtil.throwIaxIfNull(sink, "sink"); + LangUtil.throwIaxIfNull(source, "source"); + return handleAll(sink, source.getMessages(kind, orGreater), fastFail); + } + + /** + * Handle messages in the second handler using the first if they are NOT of this kind (optionally, or greater). If you pass null + * as the kind, then all messages are ignored and this returns true. + * + * @param handler the IMessageHandler sink for all messages in source + * @param holder the IMessageHolder source for all messages to handle + * @param kind the IMessage.Kind to reject, if not null + * @param orGreater if true, also reject greater kinds + * @param fastFail if true, stop on first failure + * @return false if any sink.handleMessage(..) failed + */ + public static boolean handleAllExcept(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater, + boolean fastFail) { + LangUtil.throwIaxIfNull(sink, "sink"); + LangUtil.throwIaxIfNull(source, "source"); + if (null == kind) { + return true; + } + IMessage[] messages = getMessagesExcept(source, kind, orGreater); + return handleAll(sink, messages, fastFail); + } + + /** + * Handle messages in the sink. + * + * @param handler the IMessageHandler sink for all messages in source + * @param sources the IMessage[] messages to handle + * @param fastFail if true, stop on first failure + * @return false if any sink.handleMessage(..) failed + * @throws IllegalArgumentException if sink is null + */ + public static boolean handleAll(IMessageHandler sink, IMessage[] sources, boolean fastFail) { + LangUtil.throwIaxIfNull(sink, "sink"); + if (LangUtil.isEmpty(sources)) { + return true; + } + boolean result = true; + for (int i = 0; i < sources.length; i++) { + if (!sink.handleMessage(sources[i])) { + if (fastFail) { + return false; + } + if (result) { + result = false; + } + } + } + return result; + } +} diff --git a/bridge/src/main/java/org/aspectj/bridge/MessageWriter.java b/bridge/src/main/java/org/aspectj/bridge/MessageWriter.java new file mode 100644 index 000000000..3fbeb91b0 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/MessageWriter.java @@ -0,0 +1,84 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.io.PrintWriter; + +/** + * An IMessageHandler implementation that writes all to a PrintWriter. + * Clients may set this up to throw AbortException for FAIL or ERROR messages. + * Subclasses may control whether messages are printed and how they + * are rendered by overriding render(IMessage). + */ +public class MessageWriter implements IMessageHandler { + + protected PrintWriter writer; + protected boolean abortOnFailure; + public MessageWriter(PrintWriter writer, boolean abortOnFailure) { + this.writer = (null != writer ? writer : new PrintWriter(System.out)); + this.abortOnFailure = abortOnFailure; + } + + /** + * Handle message by printing and + * (if abortOnFailure) throwing an AbortException if + * the messages is a failure or an abort (but not for errors). + * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage) + */ + public boolean handleMessage(IMessage message) throws AbortException { + if ((null != message) && !isIgnoring(message.getKind())) { + String result = render(message); + if (null != result) { + writer.println(result); + writer.flush(); + if (abortOnFailure + && (message.isFailed() || message.isAbort())) { + throw new AbortException(message); + } + } + } + return true; + } + + /** + * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) + */ + public boolean isIgnoring(IMessage.Kind kind) { + // XXX share MessageHandler implementation in superclass + return false; + } + + /** + * No-op + * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) + * @param kind + */ + public void dontIgnore(IMessage.Kind kind) { + + } + + /** + * No-op + * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind) + * @param kind + */ + public void ignore(IMessage.Kind kind) { + } + + /** @return null to not print, or message rendering (including newlines) */ + protected String render(IMessage message) { + return message.toString(); + } + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/ReflectionFactory.java b/bridge/src/main/java/org/aspectj/bridge/ReflectionFactory.java new file mode 100644 index 000000000..8eb65b3a0 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/ReflectionFactory.java @@ -0,0 +1,103 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.lang.reflect.Constructor; +import java.util.Arrays; + +/** + * + */ +public class ReflectionFactory { // XXX lease, pool + public static final String OLD_AJC = "bridge.tools.impl.OldAjc"; + public static final String ECLIPSE = "org.aspectj.ajdt.ajc.AjdtCommand"; + + private static final Object[] NONE = new Object[0]; + + /** + * Produce a compiler as an ICommand. + * + * @param cname the fully-qualified class name of the command to create by reflection (assuming a public no-argument + * constructor). + * @return ICommand compiler or null + */ + public static ICommand makeCommand(String cname, IMessageHandler errorSink) { + return (ICommand) make(ICommand.class, cname, NONE, errorSink); + } + + /** + * Make an object of type c by reflectively loading the class cname and creating an instance using args (if any), signalling + * errors (if any) to any errorSink. + */ + private static Object make(Class c, String cname, Object[] args, IMessageHandler errorSink) { + final boolean makeErrors = (null != errorSink); + Object result = null; + try { + final Class cfn = Class.forName(cname); + String error = null; + if (args == NONE) { + result = cfn.newInstance(); + } else { + Class[] types = getTypes(args); + Constructor constructor = cfn.getConstructor(types); + if (null != constructor) { + result = constructor.newInstance(args); + } else { + if (makeErrors) { + error = "no constructor for " + c + " using " + Arrays.asList(types); + } + } + } + if (null != result) { + if (!c.isAssignableFrom(result.getClass())) { + if (makeErrors) { + error = "expecting type " + c + " got " + result.getClass(); + } + result = null; + } + } + if (null != error) { + IMessage mssg = new Message(error, IMessage.FAIL, null, null); + errorSink.handleMessage(mssg); + } + } catch (Throwable t) { + if (makeErrors) { + String mssg = "ReflectionFactory unable to load " + cname + " as " + c.getName(); + IMessage m = new Message(mssg, IMessage.FAIL, t, null); + errorSink.handleMessage(m); + } + } + return result; + } + + /** + * @return Class[] with types of args or matching null elements + */ + private static Class[] getTypes(Object[] args) { + if ((null == args) || (0 < args.length)) { + return new Class[0]; + } else { + Class[] result = new Class[args.length]; + for (int i = 0; i < result.length; i++) { + if (null != args[i]) { + result[i] = args[i].getClass(); + } + } + return result; + } + } + + private ReflectionFactory() { + } +} diff --git a/bridge/src/main/java/org/aspectj/bridge/SourceLocation.java b/bridge/src/main/java/org/aspectj/bridge/SourceLocation.java new file mode 100644 index 000000000..739dd52ab --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/SourceLocation.java @@ -0,0 +1,199 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.io.File; + +import org.aspectj.util.LangUtil; + +/** + * Immutable source location. This guarantees that the source file is not null and that the numeric values are positive and line <= + * endLine. + * + * @see org.aspectj.lang.reflect.SourceLocation + * @see org.aspectj.compiler.base.parser.SourceInfo + * @see org.aspectj.tools.ide.SourceLine + * @see org.aspectj.testing.harness.ErrorLine + */ +public class SourceLocation implements ISourceLocation { + + private static final long serialVersionUID = -5434765814401009794L; + + private transient int cachedHashcode = -1; + + /** used when SourceLocation is not available */ + public static final ISourceLocation UNKNOWN = new SourceLocation(ISourceLocation.NO_FILE, 0, 0, 0); + + private final File sourceFile; + private final int startLine; + private final int column; + private final int endLine; + private int offset; + private final String context; + private boolean noColumn; + private String sourceFileName; + + /** @throws IllegalArgumentException if the input would not be a valid line */ + public static final void validLine(int line) { + if (line < 0) { + throw new IllegalArgumentException("negative line: " + line); + } else if (line > ISourceLocation.MAX_LINE) { + throw new IllegalArgumentException("line too large: " + line); + } + } + + /** @throws IllegalArgumentException if the input would not be a valid column */ + public static final void validColumn(int column) { + if (column < 0) { + throw new IllegalArgumentException("negative column: " + column); + } else if (column > ISourceLocation.MAX_COLUMN) { + throw new IllegalArgumentException("column too large: " + column); + } + } + + /** + * Same as SourceLocation(file, line, line, 0), except that column is not rendered during toString() + */ + public SourceLocation(File file, int line) { + this(file, line, line, NO_COLUMN); + } + + /** same as SourceLocation(file, line, endLine, ISourceLocation.NO_COLUMN) */ + public SourceLocation(File file, int line, int endLine) { + this(file, line, endLine, ISourceLocation.NO_COLUMN); + } + + /** + * @param file File of the source; if null, use ISourceLocation.NO_FILE, not null + * @param line int starting line of the location - positive number + * @param endLine int ending line of the location - <= starting line + * @param column int character position of starting location - positive number + */ + public SourceLocation(File file, int line, int endLine, int column) { + this(file, line, endLine, column, (String) null); + } + + public SourceLocation(File file, int line, int endLine, int column, String context) { + if (column == NO_COLUMN) { + column = 0; + noColumn = true; + } + if (null == file) { + file = ISourceLocation.NO_FILE; + } + validLine(line); + validLine(endLine); + LangUtil.throwIaxIfFalse(line <= endLine, line + " > " + endLine); + LangUtil.throwIaxIfFalse(column >= 0, "negative column: " + column); + this.sourceFile = file; + this.startLine = line; + this.column = column; + this.endLine = endLine; + 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; + } + + public int getLine() { + return startLine; + } + + /** + * @return int actual column or 0 if not available per constructor treatment of ISourceLocation.NO_COLUMN + */ + public int getColumn() { + return column; + } + + public int getEndLine() { + return endLine; + } + + /** @return null String or application-specific context */ + public String getContext() { + return context; + } + + /** @return String {context\n}{file:}line{:column} */ + public String toString() { + StringBuffer sb = new StringBuffer(); + if (null != context) { + sb.append(context); + sb.append(LangUtil.EOL); + } + if (sourceFile != ISourceLocation.NO_FILE) { + sb.append(sourceFile.getPath()); + } + if (startLine > 0) { + sb.append(":"); + sb.append(startLine); // "" + startLine + "-" + endLine); + } + if (!noColumn) { + sb.append(":" + column); + } + if (offset >= 0) { + sb.append("::" + offset); + } + return sb.toString(); + } + + // XXX Ctors for this type should know about an offset, rather than + // it being set through these methods - but there are just too many + // ctors at the moment! It needs sorting out. + public int getOffset() { + return offset; + } + + public void setOffset(int i) { + cachedHashcode = -1; + offset = i; + } + + public String getSourceFileName() { + return sourceFileName; + } + + public boolean equals(Object obj) { + if (!(obj instanceof SourceLocation)) { + return false; + } + SourceLocation o = (SourceLocation) obj; + return startLine == o.startLine && column == o.column && endLine == o.endLine && offset == o.offset + && (sourceFile == null ? o.sourceFile == null : sourceFile.equals(o.sourceFile)) + && (context == null ? o.context == null : context.equals(o.context)) && noColumn == o.noColumn + && (sourceFileName == null ? o.sourceFileName == null : sourceFileName.equals(o.sourceFileName)); + } + + public int hashCode() { + if (cachedHashcode == -1) { + cachedHashcode = (sourceFile == null ? 0 : sourceFile.hashCode()); + cachedHashcode = cachedHashcode * 37 + startLine; + cachedHashcode = cachedHashcode * 37 + column; + cachedHashcode = cachedHashcode * 37 + endLine; + cachedHashcode = cachedHashcode * 37 + offset; + cachedHashcode = cachedHashcode * 37 + (context == null ? 0 : context.hashCode()); + cachedHashcode = cachedHashcode * 37 + (noColumn ? 0 : 1); + cachedHashcode = cachedHashcode * 37 + (sourceFileName == null ? 0 : sourceFileName.hashCode()); + } + return cachedHashcode; + } + +} diff --git a/bridge/src/main/java/org/aspectj/bridge/Version.java b/bridge/src/main/java/org/aspectj/bridge/Version.java new file mode 100644 index 000000000..367efaf73 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/Version.java @@ -0,0 +1,89 @@ +/* ******************************************************************** + * Copyright (c) 1998-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * *******************************************************************/ + +package org.aspectj.bridge; + +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** release-specific version information */ +public class Version { + + // generated from build/lib/BridgeVersion.java + + /** default version value for development version */ + public static final String DEVELOPMENT = "DEVELOPMENT"; + // VersionUptodate.java depends on this value + + /** default time value for development version */ + public static final long NOTIME = 0L; + + /** set by build script */ + public static final String text = "DEVELOPMENT"; + // VersionUptodate.java scans for "static final String text = " + + /** + * Time text set by build script using SIMPLE_DATE_FORMAT. + * (if DEVELOPMENT version, invalid) + */ + public static final String time_text = "Tuesday Jan 15, 2019 at 00:53:54 GMT"; + + /** + * time in seconds-since-... format, used by programmatic clients. + * (if DEVELOPMENT version, NOTIME) + */ + private static long time = -1; // -1 == uninitialized + + /** format used by build script to set time_text */ + public static final String SIMPLE_DATE_FORMAT = "EEEE MMM d, yyyy 'at' HH:mm:ss z"; + + public static long getTime() { + if (time==-1) { + long foundTime = NOTIME; + // if not DEVELOPMENT version, read time text using format used to set time + try { + SimpleDateFormat format = new SimpleDateFormat(SIMPLE_DATE_FORMAT); + ParsePosition pos = new ParsePosition(0); + Date date = format.parse(time_text, pos); + if (date!=null) foundTime = date.getTime(); + } catch (Throwable t) { + } + time = foundTime; + } + return time; + } + + /** + * Test whether the version is as specified by any first argument. + * Emit text to System.err on failure + * @param args String[] with first argument equal to Version.text + * @see Version#text + */ + public static void main(String[] args) { + if ((null != args) && (0 < args.length)) { + if (!Version.text.equals(args[0])) { + System.err.println("version expected: \"" + + args[0] + + "\" actual=\"" + + Version.text + + "\""); + } + } + } +} + + + + + diff --git a/bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java b/bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java new file mode 100644 index 000000000..2c697a811 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/WeaveMessage.java @@ -0,0 +1,117 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * 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 30-May-2004 + * ******************************************************************/ + +package org.aspectj.bridge; + +public class WeaveMessage extends Message { + + // Kinds of weaving message we can produce + + public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS = new WeaveMessageKind(1, + "Extending interface set for type '%1' (%2) to include '%3' (%4)"); + + public static WeaveMessageKind WEAVEMESSAGE_ITD = new WeaveMessageKind(2, "Type '%1' (%2) has intertyped %3 from '%4' (%5)"); + + // %7 is information like "[with runtime test]" + public static WeaveMessageKind WEAVEMESSAGE_ADVISES = new WeaveMessageKind(3, + "Join point '%1' in Type '%2' (%3) advised by %4 advice from '%5' (%6)%7"); + + public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSEXTENDS = new WeaveMessageKind(4, + "Setting superclass of type '%1' (%2) to '%3' (%4)"); + + public static WeaveMessageKind WEAVEMESSAGE_SOFTENS = new WeaveMessageKind(5, + "Softening exceptions in type '%1' (%2) as defined by aspect '%3' (%4)"); + + public static WeaveMessageKind WEAVEMESSAGE_ANNOTATES = new WeaveMessageKind(6, + "'%1' (%2) is annotated with %3 %4 annotation from '%5' (%6)"); + + public static WeaveMessageKind WEAVEMESSAGE_MIXIN = new WeaveMessageKind(7, "Mixing interface '%1' (%2) into type '%3' (%4)"); + + public static WeaveMessageKind WEAVEMESSAGE_REMOVES_ANNOTATION = new WeaveMessageKind(6, + "'%1' (%2) has had %3 %4 annotation removed by '%5' (%6)"); + + private String affectedtypename; + private String aspectname; + + // private ctor - use the static factory method + private WeaveMessage(String message, String affectedtypename, String aspectname) { + super(message, IMessage.WEAVEINFO, null, null); + this.affectedtypename = affectedtypename; + this.aspectname = aspectname; + } + + /** + * Static helper method for constructing weaving messages. + * + * @param kind what kind of message (e.g. declare parents) + * @param inserts inserts for the message (inserts are marked %n in the message) + * @return new weaving message + */ + public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts) { + StringBuffer str = new StringBuffer(kind.getMessage()); + int pos = -1; + while ((pos = new String(str).indexOf("%")) != -1) { + int n = Character.getNumericValue(str.charAt(pos + 1)); + str.replace(pos, pos + 2, inserts[n - 1]); + } + return new WeaveMessage(str.toString(), null, null); + } + + /** + * Static helper method for constructing weaving messages. + * + * @param kind what kind of message (e.g. declare parents) + * @param inserts inserts for the message (inserts are marked %n in the message) + * @param affectedtypename the type which is being advised/declaredUpon + * @param aspectname the aspect that defined the advice or declares + * @return new weaving message + */ + public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts, String affectedtypename, + String aspectname) { + StringBuffer str = new StringBuffer(kind.getMessage()); + int pos = -1; + while ((pos = new String(str).indexOf("%")) != -1) { + int n = Character.getNumericValue(str.charAt(pos + 1)); + str.replace(pos, pos + 2, inserts[n - 1]); + } + return new WeaveMessage(str.toString(), affectedtypename, aspectname); + } + + /** + * @return Returns the aspectname. + */ + public String getAspectname() { + return aspectname; + } + + /** + * @return Returns the affectedtypename. + */ + public String getAffectedtypename() { + return affectedtypename; + } + + public static class WeaveMessageKind { + + // private int id; + private String message; + + public WeaveMessageKind(int id, String message) { + // this.id = id; + this.message = message; + } + + public String getMessage() { + return message; + } + } +} diff --git a/bridge/src/main/java/org/aspectj/bridge/context/CompilationAndWeavingContext.java b/bridge/src/main/java/org/aspectj/bridge/context/CompilationAndWeavingContext.java new file mode 100644 index 000000000..28a414acd --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/context/CompilationAndWeavingContext.java @@ -0,0 +1,260 @@ +/* ******************************************************************* + * Copyright (c) 2005-2012 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: + * Adrian Colyer Initial implementation + * Andy Clement various fixes + * Trask Stanalker #373195 + * ******************************************************************/ +package org.aspectj.bridge.context; + +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +/** + * This class is responsible for tracking progress through the various phases of compilation and weaving. + * When an exception occurs (or a message is issued, if desired), you can ask this class for a + * "stack trace" that gives information about what the compiler was doing at the time. + * The trace will say something like: + * "when matching pointcut xyz when matching shadow sss when weaving type ABC when weaving shadow mungers" + */ +public class CompilationAndWeavingContext { + + private static int nextTokenId = 1; + + // unique constants for the different phases that can be registered + + // "FRONT END" + public static final int BATCH_BUILD = 0; + public static final int INCREMENTAL_BUILD = 1; + public static final int PROCESSING_COMPILATION_UNIT = 2; + public static final int RESOLVING_COMPILATION_UNIT = 3; + public static final int ANALYSING_COMPILATION_UNIT = 4; + public static final int GENERATING_UNWOVEN_CODE_FOR_COMPILATION_UNIT = 5; + public static final int COMPLETING_TYPE_BINDINGS = 6; + public static final int PROCESSING_DECLARE_PARENTS = 7; + public static final int CHECK_AND_SET_IMPORTS = 8; + public static final int CONNECTING_TYPE_HIERARCHY = 9; + public static final int BUILDING_FIELDS_AND_METHODS = 10; + public static final int COLLECTING_ITDS_AND_DECLARES = 11; + public static final int PROCESSING_DECLARE_ANNOTATIONS = 12; + public static final int WEAVING_INTERTYPE_DECLARATIONS = 13; + public static final int RESOLVING_POINTCUT_DECLARATIONS = 14; + public static final int ADDING_DECLARE_WARNINGS_AND_ERRORS = 15; + public static final int VALIDATING_AT_ASPECTJ_ANNOTATIONS = 16; + public static final int ACCESS_FOR_INLINE = 17; + public static final int ADDING_AT_ASPECTJ_ANNOTATIONS = 18; + public static final int FIXING_SUPER_CALLS_IN_ITDS = 19; + public static final int FIXING_SUPER_CALLS = 20; + public static final int OPTIMIZING_THIS_JOIN_POINT_CALLS = 21; + + // "BACK END" + + public static final int WEAVING = 22; + public static final int PROCESSING_REWEAVABLE_STATE = 23; + public static final int PROCESSING_TYPE_MUNGERS = 24; + public static final int WEAVING_ASPECTS = 25; + public static final int WEAVING_CLASSES = 26; + public static final int WEAVING_TYPE = 27; + public static final int MATCHING_SHADOW = 28; + public static final int IMPLEMENTING_ON_SHADOW = 29; + public static final int MATCHING_POINTCUT = 30; + public static final int MUNGING_WITH = 31; + public static final int PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY = 32; + + // phase names + public static final String[] PHASE_NAMES = new String[] { "batch building", "incrementally building", + "processing compilation unit", "resolving types defined in compilation unit", + "analysing types defined in compilation unit", "generating unwoven code for type defined in compilation unit", + "completing type bindings", "processing declare parents", "checking and setting imports", "connecting type hierarchy", + "building fields and methods", "collecting itds and declares", "processing declare annotations", + "weaving intertype declarations", "resolving pointcut declarations", "adding declare warning and errors", + "validating @AspectJ annotations", "creating accessors for inlining", "adding @AspectJ annotations", + "fixing super calls in ITDs in interface context", "fixing super calls in ITDs", + "optimizing thisJoinPoint calls", + + // BACK END + + "weaving", "processing reweavable state", "processing type mungers", "weaving aspects", "weaving classes", + "weaving type", "matching shadow", "implementing on shadow", "matching pointcut", "type munging with", + "type munging for @AspectJ aspectOf" }; + + // context stacks, one per thread + private static ThreadLocal> contextMap = new ThreadLocal>(); + + // single thread mode stack + private static Stack contextStack = new Stack(); + + // formatters, by phase id + private static Map formatterMap = new HashMap(); + + private static ContextFormatter defaultFormatter = new DefaultFormatter(); + + private static boolean multiThreaded = true; + + /** + * this is a static service + */ + private CompilationAndWeavingContext() { + } + + public static void reset() { + if (!multiThreaded) { + contextMap.remove(); + contextStack.clear(); + formatterMap.clear(); + nextTokenId = 1; + } else { + contextMap.remove(); + // TODO what about formatterMap? + // TODO what about nextTokenId? + } + } + + public static void setMultiThreaded(boolean mt) { + multiThreaded = mt; + } + + public static void registerFormatter(int phaseId, ContextFormatter aFormatter) { + formatterMap.put(new Integer(phaseId), aFormatter); + } + + /** + * Returns a string description of what the compiler/weaver is currently doing + */ + public static String getCurrentContext() { + Stack contextStack = getContextStack(); + Stack explanationStack = new Stack(); + for (ContextStackEntry entry : contextStack) { + Object data = entry.getData(); + if (data != null) { + explanationStack.push(getFormatter(entry).formatEntry(entry.phaseId, data)); + } + } + StringBuffer sb = new StringBuffer(); + while (!explanationStack.isEmpty()) { + sb.append("when "); + sb.append(explanationStack.pop().toString()); + sb.append("\n"); + } + return sb.toString(); + } + + public static ContextToken enteringPhase(int phaseId, Object data) { + Stack contextStack = getContextStack(); + ContextTokenImpl nextToken = nextToken(); + contextStack.push(new ContextStackEntry(nextToken, phaseId, new WeakReference(data))); + return nextToken; + } + + /** + * Exit a phase, all stack entries from the one with the given token down will be removed. + */ + public static void leavingPhase(ContextToken aToken) { + Stack contextStack = getContextStack(); + while (!contextStack.isEmpty()) { + ContextStackEntry entry = contextStack.pop(); + if (entry.contextToken == aToken) { + break; + } + } + } + + /** + * Forget about the context for the current thread + */ + public static void resetForThread() { + if (!multiThreaded) { + return; + } + contextMap.remove(); + } + + private static Stack getContextStack() { + if (!multiThreaded) { + return contextStack; + } else { + Stack contextStack = contextMap.get(); + if (contextStack == null) { + contextStack = new Stack(); + contextMap.set(contextStack); + } + return contextStack; + } + } + + private static ContextTokenImpl nextToken() { + return new ContextTokenImpl(nextTokenId++); + } + + private static ContextFormatter getFormatter(ContextStackEntry entry) { + Integer key = new Integer(entry.phaseId); + if (formatterMap.containsKey(key)) { + return formatterMap.get(key); + } else { + return defaultFormatter; + } + } + + private static class ContextTokenImpl implements ContextToken { + public int tokenId; + + public ContextTokenImpl(int id) { + this.tokenId = id; + } + } + + // dumb data structure + private static class ContextStackEntry { + public ContextTokenImpl contextToken; + public int phaseId; + private WeakReference dataRef; + + public ContextStackEntry(ContextTokenImpl ct, int phase, WeakReference data) { + this.contextToken = ct; + this.phaseId = phase; + this.dataRef = data; + } + + public Object getData() { + return dataRef.get(); + } + + public String toString() { + Object data = getData(); + if (data == null) { + return "referenced context entry has gone out of scope"; + } else { + return CompilationAndWeavingContext.getFormatter(this).formatEntry(phaseId, data); + } + } + } + + private static class DefaultFormatter implements ContextFormatter { + + public String formatEntry(int phaseId, Object data) { + StringBuffer sb = new StringBuffer(); + sb.append(PHASE_NAMES[phaseId]); + sb.append(" "); + if (data instanceof char[]) { + sb.append(new String((char[]) data)); + } else { + try { + sb.append(data.toString()); + } catch (RuntimeException ex) { + // don't lose vital info because of bad toString + sb.append("** broken toString in data object **"); + } + } + return sb.toString(); + } + + } +} diff --git a/bridge/src/main/java/org/aspectj/bridge/context/ContextFormatter.java b/bridge/src/main/java/org/aspectj/bridge/context/ContextFormatter.java new file mode 100644 index 000000000..9f1b591d7 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/context/ContextFormatter.java @@ -0,0 +1,21 @@ +/* ******************************************************************* + * Copyright (c) 2005 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: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.bridge.context; + +/** + * @author colyer + * Implementors of this interface know how to turn the "Object" data and phase id + * associated with a context stack entry into a meaningful string. + */ +public interface ContextFormatter { + String formatEntry(int phaseId, Object data); +} diff --git a/bridge/src/main/java/org/aspectj/bridge/context/ContextToken.java b/bridge/src/main/java/org/aspectj/bridge/context/ContextToken.java new file mode 100644 index 000000000..2415fa72e --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/context/ContextToken.java @@ -0,0 +1,20 @@ +/* ******************************************************************* + * Copyright (c) 2005 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: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.bridge.context; + +/** + * When an entry is added to the CompilationAndWeavingContext stack, + * a ContextToken is returned. + * When leaving a compilation or weaving phase, this token must be supplied. + * The token details are opaque to clients + */ +public interface ContextToken {} diff --git a/bridge/src/main/java/org/aspectj/bridge/context/PinpointingMessageHandler.java b/bridge/src/main/java/org/aspectj/bridge/context/PinpointingMessageHandler.java new file mode 100644 index 000000000..c54ff6789 --- /dev/null +++ b/bridge/src/main/java/org/aspectj/bridge/context/PinpointingMessageHandler.java @@ -0,0 +1,115 @@ +/* ******************************************************************* + * Copyright (c) 2005 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: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.bridge.context; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.IMessage.Kind; + +/** + * @author colyer + * Facade for an IMessageHandler + * Extends message with details of exactly what the compiler / weaver was doing at the + * time. Use the -Xdev:Pinpoint option to turn this facility on. + */ +public class PinpointingMessageHandler implements IMessageHandler { + + private IMessageHandler delegate; + + public PinpointingMessageHandler(IMessageHandler delegate) { + this.delegate = delegate; + } + + /* (non-Javadoc) + * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage) + */ + public boolean handleMessage(IMessage message) throws AbortException { + if (!isIgnoring(message.getKind())) { + MessageIssued ex = new MessageIssued(); + ex.fillInStackTrace(); + StringWriter sw = new StringWriter(); + ex.printStackTrace(new PrintWriter(sw)); + StringBuffer sb = new StringBuffer(); + sb.append(CompilationAndWeavingContext.getCurrentContext()); + sb.append(sw.toString()); + IMessage pinpointedMessage = new PinpointedMessage(message,sb.toString()); + return delegate.handleMessage(pinpointedMessage); + } else { + return delegate.handleMessage(message); + } + } + + /* (non-Javadoc) + * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) + */ + public boolean isIgnoring(Kind kind) { + return delegate.isIgnoring(kind); + } + + /* (non-Javadoc) + * @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind) + */ + public void dontIgnore(Kind kind) { + delegate.dontIgnore(kind); + } + + + /* (non-Javadoc) + * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind) + */ + public void ignore(Kind kind) { + delegate.ignore(kind); + } + + private static class PinpointedMessage implements IMessage { + + private IMessage delegate; + private String message; + + public PinpointedMessage(IMessage delegate, String pinpoint) { + this.delegate = delegate; + this.message = delegate.getMessage() + "\n" + pinpoint; + } + + public String getMessage() { return this.message; } + public Kind getKind() { return delegate.getKind();} + public boolean isError() { return delegate.isError(); } + public boolean isWarning() { return delegate.isWarning();} + public boolean isDebug() { return delegate.isDebug();} + public boolean isInfo() { return delegate.isInfo();} + public boolean isAbort() { return delegate.isAbort();} + public boolean isTaskTag() { return delegate.isTaskTag();} + public boolean isFailed() { return delegate.isFailed();} + public boolean getDeclared() { return delegate.getDeclared(); } + public int getID() { return delegate.getID();} + public int getSourceStart() { return delegate.getSourceStart();} + public int getSourceEnd() { return delegate.getSourceEnd();} + public Throwable getThrown() { return delegate.getThrown();} + public ISourceLocation getSourceLocation() { return delegate.getSourceLocation();} + public String getDetails() { return delegate.getDetails();} + public List getExtraSourceLocations() { return delegate.getExtraSourceLocations();} + } + + private static class MessageIssued extends RuntimeException { + private static final long serialVersionUID = 1L; + + public String getMessage() { + return "message issued..."; + } + } +} diff --git a/bridge/src/org/aspectj/bridge/AbortException.java b/bridge/src/org/aspectj/bridge/AbortException.java deleted file mode 100644 index acde7cd28..000000000 --- a/bridge/src/org/aspectj/bridge/AbortException.java +++ /dev/null @@ -1,228 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.io.PrintStream; -import java.io.PrintWriter; -import java.util.ArrayList; - -/** - * Signal that a process was aborted before completion. This may contain a structured IMessage which indicates why the process was - * aborted (e.g., the underlying exception). For processes using try/catch to complete a method abruptly but complete the process - * normally (e.g., a test failure causes the test to abort but the reporting and testing continues normally), use the static methods - * to borrow and return a "porter" to avoid the expense of constructing a stack trace each time. A porter stack trace is invalid, - * and it should only be used to convey a message. E.g., to print the stack of the AbortException and any contained message: - * - *
- * catch (AbortException ae) {
- *     IMessage m = ae.getMessage();
- *     if (!ae.isPorter()) ae.printStackTrace(System.err);
- *     Throwable thrown = ae.getThrown();
- *     if (null != thrown) thrown.printStackTrace(System.err);
- * }
- * 
- * - * @author PARC - * @author Andy Clement - */ -public class AbortException extends RuntimeException { // XXX move porters out, handle proxy better - - private static final long serialVersionUID = -7211791639898586417L; - - private boolean isSilent = false; - - /** used when message text is null */ - public static final String NO_MESSAGE_TEXT = "AbortException (no message)"; - - private static final ArrayList porters = new ArrayList(); - - /** - * Get a porter exception from the pool. Porter exceptions do not have valid stack traces. They are used only to avoid - * generating stack traces when using throw/catch to abruptly complete but continue. - */ - public static AbortException borrowPorter(IMessage message) { - AbortException result; - synchronized (porters) { - if (porters.size() > 0) { - result = porters.get(0); - } else { - result = new AbortException(); - result.setIsSilent(false); - } - } - result.setIMessage(message); - result.isPorter = true; - return result; - } - - /** - * Return (or add) a porter exception to the pool. - */ - public static void returnPorter(AbortException porter) { - synchronized (porters) { - if (porters.contains(porter)) { - throw new IllegalStateException("already have " + porter); - } else { - porters.add(porter); - } - } - } - - /** @return NO_MESSAGE_TEXT or message.getMessage() if not null */ - private static String extractMessage(IMessage message) { - if (null == message) { - return NO_MESSAGE_TEXT; - } else { - String m = message.getMessage(); - if (null == m) { - return NO_MESSAGE_TEXT; - } else { - return m; - } - } - } - - /** structured message abort */ - protected IMessage message; - - /** true if this is a porter exception - only used to hold message */ - protected boolean isPorter; - - /** abort with default String message */ - public AbortException() { - this("ABORT"); - isSilent = true; - } - - /** abort with message */ - public AbortException(String s) { - super(null != s ? s : NO_MESSAGE_TEXT); - this.message = null; - } - - /** abort with structured message */ - public AbortException(IMessage message) { - super(extractMessage(message)); - this.message = message; - } - - /** @return IMessage structured message, if set */ - public IMessage getIMessage() { - return message; - } - - /** - * The stack trace of a porter is invalid; it is only used to carry a message (which may itself have a wrapped exception). - * - * @return true if this exception is only to carry exception - */ - public boolean isPorter() { - return isPorter; - } - - /** @return Throwable at bottom of IMessage chain, if any */ - public Throwable getThrown() { - Throwable result = null; - IMessage m = getIMessage(); - if (null != m) { - result = m.getThrown(); - if (result instanceof AbortException) { - return ((AbortException) result).getThrown(); - } - } - return result; - } - - private void setIMessage(IMessage message) { - this.message = message; - } - - // ----------- proxy attempts - /** - * Get message for this AbortException, either associated explicitly as message or implicitly as IMessage message or its thrown - * message. - * - * @see java.lang.Throwable#getMessage() - */ - public String getMessage() { - String message = super.getMessage(); - if ((null == message) || (NO_MESSAGE_TEXT == message)) { - IMessage m = getIMessage(); - if (null != m) { - message = m.getMessage(); - if (null == message) { - Throwable thrown = m.getThrown(); - if (null != thrown) { - message = thrown.getMessage(); - } - } - } - if (null == message) { - message = NO_MESSAGE_TEXT; // better than nothing - } - } - return message; - } - - /** - * @see java.lang.Throwable#printStackTrace() - */ - public void printStackTrace() { - printStackTrace(System.out); - } - - /** - * Print the stack trace of any enclosed thrown or this otherwise. - * - * @see java.lang.Throwable#printStackTrace(PrintStream) - */ - public void printStackTrace(PrintStream s) { - IMessage m = getIMessage(); - Throwable thrown = (null == m ? null : m.getThrown()); - if (!isPorter() || (null == thrown)) { - s.println("Message: " + m); - super.printStackTrace(s); - } else { - thrown.printStackTrace(s); - } - } - - /** - * Print the stack trace of any enclosed thrown or this otherwise. - * - * @see java.lang.Throwable#printStackTrace(PrintWriter) - */ - public void printStackTrace(PrintWriter s) { - IMessage m = getIMessage(); - Throwable thrown = (null == m ? null : m.getThrown()); - if (null == thrown) { // Always print - if (isPorter()) { - s.println("(Warning porter AbortException without thrown)"); - } - s.println("Message: " + m); - super.printStackTrace(s); - } else { - thrown.printStackTrace(s); - } - } - - public boolean isSilent() { - return isSilent; - } - - public void setIsSilent(boolean isSilent) { - this.isSilent = isSilent; - } - -} diff --git a/bridge/src/org/aspectj/bridge/Constants.java b/bridge/src/org/aspectj/bridge/Constants.java deleted file mode 100644 index 31f239678..000000000 --- a/bridge/src/org/aspectj/bridge/Constants.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * 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: - * Matthew Webster - initial implementation - *******************************************************************************/ -package org.aspectj.bridge; - -public class Constants { - - /* Default resource names for user and generate aop.xml file */ - public final static String AOP_USER_XML = "META-INF/aop.xml"; - public final static String AOP_AJC_XML = "META-INF/aop-ajc.xml"; - - /* Resource name for OSGi */ - public final static String AOP_OSGI_XML = "org/aspectj/aop.xml"; - -} diff --git a/bridge/src/org/aspectj/bridge/CountingMessageHandler.java b/bridge/src/org/aspectj/bridge/CountingMessageHandler.java deleted file mode 100644 index 4ce550876..000000000 --- a/bridge/src/org/aspectj/bridge/CountingMessageHandler.java +++ /dev/null @@ -1,157 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.util.Enumeration; -import java.util.Hashtable; - -import org.aspectj.util.LangUtil; - -/** - * Wrap an IMessageHandler to count messages handled. Messages being ignored by the delegate IMessageHandler are not counted. - */ -public class CountingMessageHandler implements IMessageHandler { - - public final IMessageHandler delegate; - public final CountingMessageHandler proxy; - private final Hashtable counters; - - public static CountingMessageHandler makeCountingMessageHandler(IMessageHandler handler) { - if (handler instanceof CountingMessageHandler) { - return (CountingMessageHandler) handler; - } else { - return new CountingMessageHandler(handler); - } - } - - public CountingMessageHandler(IMessageHandler delegate) { - LangUtil.throwIaxIfNull(delegate, "delegate"); - this.delegate = delegate; - this.counters = new Hashtable(); - proxy = (delegate instanceof CountingMessageHandler ? (CountingMessageHandler) delegate : null); - } - - /** @return delegate.handleMessage(IMessage) */ - public boolean handleMessage(IMessage message) throws AbortException { - if (null != proxy) { - return proxy.handleMessage(message); - } - if (null != message) { - IMessage.Kind kind = message.getKind(); - if (!isIgnoring(kind)) { - increment(kind); - } - } - return delegate.handleMessage(message); - } - - /** @return delegate.isIgnoring(IMessage.Kind) */ - public boolean isIgnoring(IMessage.Kind kind) { - return delegate.isIgnoring(kind); - } - - /** - * Delegate - * - * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) - * @param kind - */ - public void dontIgnore(IMessage.Kind kind) { - delegate.dontIgnore(kind); - } - - /** - * Delegate - * - * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind) - * @param kind - */ - public void ignore(IMessage.Kind kind) { - delegate.ignore(kind); - } - - /** @return delegate.toString() */ - public String toString() { - return delegate.toString(); - } - - /** - * Return count of messages seen through this interface. - * - * @param kind the IMessage.Kind of the messages to count (if null, count all) - * @param orGreater if true, then count this kind and any considered greater by the ordering of IMessage.Kind.COMPARATOR - * @return number of messages of this kind (optionally or greater) - * @see IMessage.Kind.COMPARATOR - */ - public int numMessages(IMessage.Kind kind, boolean orGreater) { - if (null != proxy) { - return proxy.numMessages(kind, orGreater); - } - int result = 0; - if (null == kind) { - for (Enumeration enu = counters.elements(); enu.hasMoreElements();) { - result += (enu.nextElement()).count; - } - } else if (!orGreater) { - result = numMessages(kind); - } else { - for (IMessage.Kind k : IMessage.KINDS) { - if (kind.isSameOrLessThan(k)) { - result += numMessages(k); - } - } - } - return result; - } - - /** - * @return true if 0 is less than numMessages(IMessage.ERROR, true) - */ - public boolean hasErrors() { - return (0 < numMessages(IMessage.ERROR, true)); - } - - private int numMessages(IMessage.Kind kind) { - if (null != proxy) { - return proxy.numMessages(kind); - } - IntHolder counter = counters.get(kind); - return (null == counter ? 0 : counter.count); - } - - private void increment(IMessage.Kind kind) { - if (null != proxy) { - throw new IllegalStateException("not called when proxying"); - } - - IntHolder counter = counters.get(kind); - if (null == counter) { - counter = new IntHolder(); - counters.put(kind, counter); - } - counter.count++; - } - - private static class IntHolder { - int count; - } - - public void reset() { - if (proxy != null) { - proxy.reset(); - } - counters.clear(); - } - -} diff --git a/bridge/src/org/aspectj/bridge/ICommand.java b/bridge/src/org/aspectj/bridge/ICommand.java deleted file mode 100644 index b77d58e59..000000000 --- a/bridge/src/org/aspectj/bridge/ICommand.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.bridge; - - -/** - * Command wrapper with collecting parameter for messages. - */ -public interface ICommand { - /** - * Run command with the given options. - * @param args the String[] options for the command - * @param handler the IMessageHandler for all output from - * the command - * @return true if the command completed successfully - */ - boolean runCommand(String[] args, IMessageHandler handler); - - /** - * Rerun the command. - * - * @param handler the IMessageHandler for all output from the command - * - * @return true if the command completed successfully - */ - boolean repeatCommand(IMessageHandler handler); -} diff --git a/bridge/src/org/aspectj/bridge/ILifecycleAware.java b/bridge/src/org/aspectj/bridge/ILifecycleAware.java deleted file mode 100644 index c5ac9b149..000000000 --- a/bridge/src/org/aspectj/bridge/ILifecycleAware.java +++ /dev/null @@ -1,35 +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: - * Adrian Colyer Initial implementation - * ******************************************************************/ -package org.aspectj.bridge; - -/** - * Interface that can be implemented by MessageHandlers that need to - * perform some additional processing when a build is starting and - * when it has finished. - * - * @author Adrian Colyer - * @since 1.5.1 - */ -public interface ILifecycleAware { - - /** - * called when a build starts - */ - void buildStarting(boolean isIncremental); - - /** - * called when a batch build finishes - * - */ - void buildFinished(boolean wasIncremental); - -} diff --git a/bridge/src/org/aspectj/bridge/IMessage.java b/bridge/src/org/aspectj/bridge/IMessage.java deleted file mode 100644 index a32a631e6..000000000 --- a/bridge/src/org/aspectj/bridge/IMessage.java +++ /dev/null @@ -1,150 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -/** - * Wrap message with any associated throwable or source location. - */ -public interface IMessage { - /** no messages */ - public static final IMessage[] RA_IMessage = new IMessage[0]; - - // int values must sync with KINDS order below - public static final Kind WEAVEINFO = new Kind("weaveinfo", 5); - public static final Kind INFO = new Kind("info", 10); - public static final Kind DEBUG = new Kind("debug", 20); - public static final Kind TASKTAG = new Kind("task", 25); // represents a 'TODO' from eclipse - producted by the compiler and - // consumed by AJDT - public static final Kind WARNING = new Kind("warning", 30); - public static final Kind ERROR = new Kind("error", 40); - public static final Kind FAIL = new Kind("fail", 50); - public static final Kind ABORT = new Kind("abort", 60); - // XXX prefer another Kind to act as selector for "any", - // but can't prohibit creating messages with it. - // public static final Kind ANY = new Kind("any-selector", 0); - - /** - * list of Kind in precedence order. 0 is less than IMessage.Kind.COMPARATOR.compareTo(KINDS.get(i), KINDS.get(i + 1)) - */ - public static final List KINDS = Collections.unmodifiableList(Arrays.asList(new Kind[] { WEAVEINFO, INFO, DEBUG, TASKTAG, - WARNING, ERROR, FAIL, ABORT })); - - /** @return non-null String with simple message */ - String getMessage(); - - /** @return the kind of this message */ - Kind getKind(); - - /** @return true if this is an error */ - boolean isError(); - - /** @return true if this is a warning */ - boolean isWarning(); - - /** @return true if this is an internal debug message */ - boolean isDebug(); - - /** @return true if this is information for the user */ - boolean isInfo(); - - /** @return true if the process is aborting */ - boolean isAbort(); // XXX ambiguous - - /** @return true if this is a task tag message */ - boolean isTaskTag(); - - /** @return true if something failed */ - boolean isFailed(); - - /** Caller can verify if this message came about because of a DEOW */ - boolean getDeclared(); - - /** Return the ID of the message where applicable, see IProblem for list of valid IDs */ - int getID(); - - /** Return the start position of the problem (inclusive), or -1 if unknown. */ - int getSourceStart(); - - /** Return the end position of the problem (inclusive), or -1 if unknown. */ - int getSourceEnd(); - - /** @return Throwable associated with this message, or null if none */ - Throwable getThrown(); - - /** @return source location associated with this message, or null if none */ - ISourceLocation getSourceLocation(); - - public static final class Kind implements Comparable { - public static final Comparator COMPARATOR = new Comparator() { - public int compare(IMessage.Kind one, IMessage.Kind two) { - if (null == one) { - return (null == two ? 0 : -1); - } else if (null == two) { - return 1; - } else if (one == two) { - return 0; - } else { - return (one.precedence - two.precedence); - } - } - }; - - /** - * @param kind the Kind floor - * @return false if kind is null or this has less precedence than kind, true otherwise. - */ - public boolean isSameOrLessThan(Kind kind) { - return (0 >= COMPARATOR.compare(this, kind)); - } - - public int compareTo(IMessage.Kind other) { - return COMPARATOR.compare(this, other); - } - - private final int precedence; - private final String name; - - private Kind(String name, int precedence) { - this.name = name; - this.precedence = precedence; - } - - public String toString() { - return name; - } - } - - /** - * @return Detailed information about the message. For example, for declare error/warning messages this returns information - * about the corresponding join point's static part. - */ - public String getDetails(); - - /** - * @return List of ISourceLocation instances that indicate additional source locations relevent to this message as - * specified by the message creator. The list should not include the primary source location associated with the message - * which can be obtained from getSourceLocation(). - *

- * An example of using extra locations would be in a warning message that - * flags all shadow locations that will go unmatched due to a pointcut definition - * being based on a subtype of a defining type. - * @see AspectJ bug 41952 - */ - public List getExtraSourceLocations(); -} diff --git a/bridge/src/org/aspectj/bridge/IMessageContext.java b/bridge/src/org/aspectj/bridge/IMessageContext.java deleted file mode 100644 index 2f5512a1d..000000000 --- a/bridge/src/org/aspectj/bridge/IMessageContext.java +++ /dev/null @@ -1,16 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation and others. - * 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: - * Matthew Webster - initial implementation - *******************************************************************************/ -package org.aspectj.bridge; - -public interface IMessageContext { - - public String getContextId (); -} diff --git a/bridge/src/org/aspectj/bridge/IMessageHandler.java b/bridge/src/org/aspectj/bridge/IMessageHandler.java deleted file mode 100644 index 6dcdfeafb..000000000 --- a/bridge/src/org/aspectj/bridge/IMessageHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.bridge; - -import java.io.PrintWriter; - -/** - * Handle messages, logging and/or aborting as appropriate. - * Implementations define which messages are logged and whether - * the handler aborts the process. - * For messages that are costly to construct, clients may query - * {@link #isIgnoring(IMessage.Kind)} - * to avoid construction if the message will be ignored. - * Clients passing messages to an IMessageHandler should not - * interfere with aborts by catching AbortException unless - * otherwise required by their logic or the message handler. - */ -public interface IMessageHandler { - /** print all to System.err and throw AbortException on failure or abort messages */ - public static final IMessageHandler SYSTEM_ERR = - new MessageWriter(new PrintWriter(System.err, true), true); - - /** print all to System.out but do not throw AbortException on failure or abort messages */ - public static final IMessageHandler SYSTEM_OUT = - new MessageWriter(new PrintWriter(System.out, true), false); - - /** Throw exceptions for anything with ERROR or greater severity */ - public static final IMessageHandler THROW = - new IMessageHandler() { - public boolean handleMessage(IMessage message) { - if (message.getKind().compareTo(IMessage.ERROR) >= 0) { - throw new AbortException(message); - } else { - return SYSTEM_OUT.handleMessage(message); - } - } - public boolean isIgnoring(IMessage.Kind kind) { - return false; - } - public void dontIgnore(IMessage.Kind kind) { - - } - public void ignore(IMessage.Kind kind) { - } - }; - - /** - * Handle message, by reporting and/or throwing an AbortException. - * @param message the IMessage to handle - never null - * @return true if this message was handled by this handler - * @throws IllegalArgumentException if message is null - * @throws AbortException depending on handler logic. - */ - boolean handleMessage(IMessage message) throws AbortException; - - /** - * Signal clients whether this will ignore messages of a given type. - * Clients may use this to avoid constructing or sending certain messages. - * @return true if this handler is ignoring all messages of this type - */ - boolean isIgnoring(IMessage.Kind kind); - - /** - * Allow fine grained configuration after initialization. Minaly used in LTW. Most of the - * implementation can have this method be a no-op. - * - * @param kind - */ - void dontIgnore(IMessage.Kind kind); - - /** - * Allow fine grained configuration after initialization. - * - * @param kind - */ - void ignore(IMessage.Kind kind); -} diff --git a/bridge/src/org/aspectj/bridge/IMessageHolder.java b/bridge/src/org/aspectj/bridge/IMessageHolder.java deleted file mode 100644 index fdf2a6779..000000000 --- a/bridge/src/org/aspectj/bridge/IMessageHolder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.util.List; - -/** - * Hold and query a collection of messages. - */ -public interface IMessageHolder extends IMessageHandler { // XXX do not extend - mix instead - // XXX go to LT EQ GT GE LE rather than simple orGreater - /** value for orGreater parameter */ - public static final boolean ORGREATER = true; - - /** value for orGreater parameter */ - public static final boolean EQUAL = false; - - /** - * Tell whether this holder has any message of this kind (optionally or greater). - * - * @param kind the IMessage.Kind to check for - accept any if null - * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR - * @return true if this holder has any message of this kind, or if orGreater and any message has a greater kind, as determined - * by IMessage.Kind.COMPARATOR - */ - boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater); - - /** - * Count the messages currently held by this holder. Pass null to get all kinds. - * - * @param kind the IMessage.Kind expected, or null for all messages - * @param orGreater if true, also any greater than the target kind as determined by IMessage.Kind.COMPARATOR - * @return number of IMessage held (now) by this holder - */ - int numMessages(IMessage.Kind kind, boolean orGreater); - - /** - * Get all messages or those of a specific kind. Pass null to get all kinds. - * - * @param kind the IMessage.Kind expected, or null for all messages - * @param orGreater if true, also get any greater than the target kind as determined by IMessage.Kind.COMPARATOR - * @return IMessage[] of messages of the right kind, or IMessage.NONE - */ - IMessage[] getMessages(IMessage.Kind kind, boolean orGreater); - - /** @return unmodifiable List view of underlying collection of IMessage */ - List getUnmodifiableListView(); - - /** - * Clear any messages. - * - * @throws UnsupportedOperationException if message list is read-only - */ - void clearMessages() throws UnsupportedOperationException; -} diff --git a/bridge/src/org/aspectj/bridge/IProgressListener.java b/bridge/src/org/aspectj/bridge/IProgressListener.java deleted file mode 100644 index 4326f7263..000000000 --- a/bridge/src/org/aspectj/bridge/IProgressListener.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.bridge; - -/** - * Used to give progress information typically to IDEs - */ -public interface IProgressListener { - /** - * @param text the current phase of processing - */ - public void setText(String text); - - /** - * @param percentDone how much work is completed so far - */ - public void setProgress(double percentDone); - - /** - * @param cancelRequested true if the caller wants the current compilation to stop asap - */ - public void setCancelledRequested(boolean cancelRequested); - - /** - * @return true if the consumer of the progress info would like the compileation to stop - */ - public boolean isCancelledRequested(); - -} diff --git a/bridge/src/org/aspectj/bridge/ISourceLocation.java b/bridge/src/org/aspectj/bridge/ISourceLocation.java deleted file mode 100644 index 7ad9423c2..000000000 --- a/bridge/src/org/aspectj/bridge/ISourceLocation.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.io.File; - -/** - * Represent source location as a starting line/column and ending line in a source file. Implementations should be immutable. XXX - * why? - * - * @see org.aspectj.lang.reflect.SourceLocation - * @see org.aspectj.compiler.base.parser.SourceInfo - * @see org.aspectj.tools.ide.SourceLine - * @see org.aspectj.testing.harness.ErrorLine - */ -public interface ISourceLocation extends java.io.Serializable { - static final int MAX_LINE = Integer.MAX_VALUE / 2; - static final int MAX_COLUMN = MAX_LINE; - - /** non-null but empty (nonexisting) File constant */ - static final File NO_FILE = new File("ISourceLocation.NO_FILE"); - - /** signal that column is not known */ - static final int NO_COLUMN = Integer.MIN_VALUE + 1; - - /** non-null but empty constant source location */ - static final ISourceLocation EMPTY = new SourceLocation(NO_FILE, 0, 0, 0); - - /** - * @return File source or NO_FILE if the implementation requires a non-null result or null otherwise - */ - File getSourceFile(); - - /** @return 0..MAX_LINE */ - int getLine(); - - /** - * @return int 0..MAX_COLUMN actual column or 0 if column input was ISourceLocation.NO_COLUMN - */ - int getColumn(); - - /** - * @return offset into file - */ - int getOffset(); - - /** @return getLine()..MAX_LINE */ - int getEndLine(); - - /** @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/Message.java b/bridge/src/org/aspectj/bridge/Message.java deleted file mode 100644 index a4f17072b..000000000 --- a/bridge/src/org/aspectj/bridge/Message.java +++ /dev/null @@ -1,190 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * Implement messages. This implementation is immutable if ISourceLocation is immutable. - */ -public class Message implements IMessage { - private final String message; - private final IMessage.Kind kind; - private final Throwable thrown; - private final ISourceLocation sourceLocation; - private final String details; - private final List extraSourceLocations; - private final boolean declared; // Is it a DEOW ? - private final int id; - private final int sourceStart, sourceEnd; - - /** - * Create a (compiler) error or warning message - * - * @param message the String used as the underlying message - * @param location the ISourceLocation, if any, associated with this message - * @param isError if true, use IMessage.ERROR; else use IMessage.WARNING - */ - public Message(String message, ISourceLocation location, boolean isError) { - this(message, (isError ? IMessage.ERROR : IMessage.WARNING), null, location); - } - - public Message(String message, ISourceLocation location, boolean isError, ISourceLocation[] extraSourceLocations) { - this(message, "", (isError ? IMessage.ERROR : IMessage.WARNING), location, null, - (extraSourceLocations.length > 0 ? extraSourceLocations : null)); - } - - /** - * Create a message, handling null values for message and kind if thrown is not null. - * - * @param message the String used as the underlying message - * @param kind the IMessage.Kind of message - not null - * @param thrown the Throwable, if any, associated with this message - * @param sourceLocation the ISourceLocation, if any, associated with this message - * @param details descriptive information about the message - * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown - * is null. - */ - public Message(String message, String details, IMessage.Kind kind, ISourceLocation sourceLocation, Throwable thrown, - ISourceLocation[] extraSourceLocations) { - this(message, details, kind, sourceLocation, thrown, extraSourceLocations, false, 0, -1, -1); - } - - public Message(String message, String details, IMessage.Kind kind, ISourceLocation sLoc, Throwable thrown, - ISourceLocation[] otherLocs, boolean declared, int id, int sourcestart, int sourceend) { - this.details = details; - this.id = id; - this.sourceStart = sourcestart; - this.sourceEnd = sourceend; - this.message = ((message != null) ? message : ((thrown == null) ? null : thrown.getMessage())); - this.kind = kind; - this.sourceLocation = sLoc; - this.thrown = thrown; - if (otherLocs != null) { - this.extraSourceLocations = Collections.unmodifiableList(Arrays.asList(otherLocs)); - } else { - this.extraSourceLocations = Collections.emptyList(); - } - if (null == this.kind) { - throw new IllegalArgumentException("null kind"); - } - if (null == this.message) { - throw new IllegalArgumentException("null message"); - } - this.declared = declared; - } - - /** - * Create a message, handling null values for message and kind if thrown is not null. - * - * @param message the String used as the underlying message - * @param kind the IMessage.Kind of message - not null - * @param thrown the Throwable, if any, associated with this message - * @param sourceLocation the ISourceLocation, if any, associated with this message - * @throws IllegalArgumentException if message is null and thrown is null or has a null message, or if kind is null and thrown - * is null. - */ - public Message(String message, IMessage.Kind kind, Throwable thrown, ISourceLocation sourceLocation) { - this(message, "", kind, sourceLocation, thrown, null); - } - - /** @return the kind of this message */ - public IMessage.Kind getKind() { - return kind; - } - - /** @return true if kind == IMessage.ERROR */ - public boolean isError() { - return kind == IMessage.ERROR; - } - - /** @return true if kind == IMessage.WARNING */ - public boolean isWarning() { - return kind == IMessage.WARNING; - } - - /** @return true if kind == IMessage.DEBUG */ - public boolean isDebug() { - return kind == IMessage.DEBUG; - } - - public boolean isTaskTag() { - return kind == IMessage.TASKTAG; - } - - /** - * @return true if kind == IMessage.INFO - */ - public boolean isInfo() { - return kind == IMessage.INFO; - } - - /** @return true if kind == IMessage.ABORT */ - public boolean isAbort() { - return kind == IMessage.ABORT; - } - - /** Caller can verify if this message came about because of a DEOW */ - public boolean getDeclared() { - return declared; - } - - /** - * @return true if kind == IMessage.FAIL - */ - public boolean isFailed() { - return kind == IMessage.FAIL; - } - - /** @return non-null String with simple message */ - final public String getMessage() { - return message; - } - - /** @return Throwable associated with this message, or null if none */ - final public Throwable getThrown() { - return thrown; - } - - /** @return ISourceLocation associated with this message, or null if none */ - final public ISourceLocation getSourceLocation() { - return sourceLocation; - } - - public String toString() { - return MessageUtil.renderMessage(this, false); - } - - public String getDetails() { - return details; - } - - public List getExtraSourceLocations() { - return extraSourceLocations; - } - - public int getID() { - return id; - } - - public int getSourceStart() { - return sourceStart; - } - - public int getSourceEnd() { - return sourceEnd; - } -} diff --git a/bridge/src/org/aspectj/bridge/MessageHandler.java b/bridge/src/org/aspectj/bridge/MessageHandler.java deleted file mode 100644 index 6fd8539cc..000000000 --- a/bridge/src/org/aspectj/bridge/MessageHandler.java +++ /dev/null @@ -1,265 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * This handler accumulates messages. To control messages accumulated, clients can ignore messages of a given kind, or install a - * listener/interceptor. The interceptor handles all messages (even null) first, and can halt further processing/accumlation by - * returning true. Clients can obtain messages accumulated using the get... methods. XXX this does not permit messages to be - * removed. - * - * @author PARC - * @author Andy Clement - */ -public class MessageHandler implements IMessageHolder { - - /** messages accumulated */ - protected final ArrayList messages; - /** kinds of messages to be ignored */ - protected final ArrayList ignoring; - /** result of handleMessage(..) for messages not accumulated (ignored) */ - protected boolean handleMessageResult; - /** listener which can halt processing by returning true */ - protected IMessageHandler interceptor; - - /** - * same as MessageHandler(false) - */ - public MessageHandler() { - this(false); - } - - /** - * @param accumulateOnly the result of handleMessage (i.e., if true, then only accumulate messages - stop processing - */ - public MessageHandler(boolean accumulateOnly) { - messages = new ArrayList(); - ignoring = new ArrayList(); - init(accumulateOnly); - ignore(IMessage.WEAVEINFO); // Off by default, need to explicitly be enabled (see -showWeaveInfo) - } - - /** - * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor. Assume that this should return false - * from handleMessage(..). - */ - public void init() { - init(false); - } - - /** - * Initialize this, removing any messages accumulated, kinds being ignored, or interceptor. - * - * @param accumulateOnly boolean value returned from handleMessage after accumulating in list - */ - public void init(boolean accumulateOnly) { - handleMessageResult = accumulateOnly; - if (0 < messages.size()) { - messages.clear(); - } - if (0 < ignoring.size()) { - boolean ignoringWeaveMessages = isIgnoring(IMessage.WEAVEINFO); - ignoring.clear(); - if (ignoringWeaveMessages) { - ignore(IMessage.WEAVEINFO); - } - } - if (null != interceptor) { - interceptor = null; - } - } - - /** - * Clear the messages without changing other behavior. - */ - public void clearMessages() { - if (0 < messages.size()) { - messages.clear(); - } - } - - // ---------------------- IMessageHandler implementation - /** - * This implementation accumulates message. If an interceptor is installed and returns true (message handled), then processing - * halts and the message is not accumulated. - * - * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage) - * @return true on interception or the constructor value otherwise - */ - public boolean handleMessage(IMessage message) { - if ((null != interceptor) && (interceptor.handleMessage(message))) { - return true; - } - if (null == message) { - throw new IllegalArgumentException("null message"); - } - if (!ignoring.contains(message.getKind())) { - messages.add(message); - } - return handleMessageResult; - } - - /** - * @return true if this kind has been flagged to be ignored. - * @see #ignore(IMessage.Kind) - * @see org.aspectj.bridge.IMessageHandler#isIgnoring(Kind) - */ - public boolean isIgnoring(IMessage.Kind kind) { - return ((null != kind) && (ignoring.contains(kind))); - } - - // ---------------------- end of IMessageHandler implementation - - /** - * Set a message kind to be ignored from now on - */ - public void ignore(IMessage.Kind kind) { // XXX sync - if ((null != kind) && (!ignoring.contains(kind))) { - ignoring.add(kind); - } - } - - /** - * Remove a message kind from the list of those ignored from now on. - */ - public void dontIgnore(IMessage.Kind kind) { - if (null != kind) { - ignoring.remove(kind); - } - } - - /** - * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean) - */ - public boolean hasAnyMessage(final IMessage.Kind kind, final boolean orGreater) { - if (null == kind) { - return (0 < messages.size()); - } - if (!orGreater) { - for (IMessage m : messages) { - if (kind == m.getKind()) { - return true; - } - } - } else { - for (IMessage m : messages) { - if (kind.isSameOrLessThan(m.getKind())) { - return true; - } - } - } - return false; - } - - /** - * @return number of messages accumulated of a given kind - */ - public int numMessages(IMessage.Kind kind, final boolean orGreater) { - if (null == kind) { - return messages.size(); - } - int result = 0; - if (!orGreater) { - for (IMessage m : messages) { - if (kind == m.getKind()) { - result++; - } - } - } else { - for (IMessage m : messages) { - if (kind.isSameOrLessThan(m.getKind())) { - result++; - } - } - } - return result; - } - - /** - * @see org.aspectj.bridge.IMessageHolder#getUnmodifiableListView() - */ - public List getUnmodifiableListView() { - return Collections.unmodifiableList(messages); - } - - /** - * Get all messages or those of a specific kind. Pass null to get all kinds. - * - * @param kind the IMessage.Kind expected, or null for all messages - * @return IMessage[] of messages of the right kind - */ - public IMessage[] getMessages(IMessage.Kind kind, final boolean orGreater) { - if (null == kind) { - return messages.toArray(IMessage.RA_IMessage); - } - ArrayList result = new ArrayList(); - if (!orGreater) { - for (IMessage m : messages) { - if (kind == m.getKind()) { - result.add(m); - } - } - } else { - for (IMessage m : messages) { - if (kind.isSameOrLessThan(m.getKind())) { - result.add(m); - } - } - } - if (0 == result.size()) { - return IMessage.RA_IMessage; - } - return result.toArray(IMessage.RA_IMessage); - } - - /** - * @return array of error messages, or IMessage.NONE - */ - public IMessage[] getErrors() { - return getMessages(IMessage.ERROR, false); - } - - /** - * @return array of warning messages, or IMessage.NONE - */ - public IMessage[] getWarnings() { - return getMessages(IMessage.WARNING, false); - } - - /** - * Set the interceptor which gets any message before we process it. - * - * @param interceptor the IMessageHandler passed the message. Pass null to remove the old interceptor. - */ - public void setInterceptor(IMessageHandler interceptor) { - this.interceptor = interceptor; - } - - /** - * @return String containing list of messages - */ - public String toString() { - if (0 == messages.size()) { - return "MessageHandler: no messages"; - } else { - return "MessageHandler: " + messages; - } - - } - -} diff --git a/bridge/src/org/aspectj/bridge/MessageUtil.java b/bridge/src/org/aspectj/bridge/MessageUtil.java deleted file mode 100644 index 6d85ea6f9..000000000 --- a/bridge/src/org/aspectj/bridge/MessageUtil.java +++ /dev/null @@ -1,1116 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.bridge.IMessage.Kind; -import org.aspectj.util.LangUtil; - -/** - * Convenience API's for constructing, printing, and sending messages. - */ -public class MessageUtil { - - // ------ some constant, content-less messages - // no variants for "info" or "debug", which should always have content - public static final IMessage ABORT_NOTHING_TO_RUN = new Message("aborting - nothing to run", IMessage.ABORT, null, null); - - public static final IMessage FAIL_INCOMPLETE = new Message("run not completed", IMessage.FAIL, null, null); - - public static final IMessage ABORT_NOMESSAGE = new Message("", IMessage.ABORT, null, null); - - public static final IMessage FAIL_NOMESSAGE = new Message("", IMessage.FAIL, null, null); - - public static final IMessage ERROR_NOMESSAGE = new Message("", IMessage.ERROR, null, null); - - public static final IMessage WARNING_NOMESSAGE = new Message("", IMessage.WARNING, null, null); - - /** handle abort message (ignored if handler is null) */ - public static boolean abort(IMessageHandler handler, String message) { - return ((null != handler) && handler.handleMessage(abort(message))); - } - - /** create and handle exception message (ignored if handler is null) */ - public static boolean abort(IMessageHandler handler, String message, Throwable t) { - if (handler != null) { - return handler.handleMessage(abort(message, t)); - } - return false; - } - - /** create and handle fail message (ignored if handler is null) */ - public static boolean fail(IMessageHandler handler, String message) { - return ((null != handler) && handler.handleMessage(fail(message))); - } - - // /** create and handle fail message from reader (ignored if handler is null) */ - // public static boolean fail(IMessageHandler handler, String message, LineReader reader) { - // return ((null != handler) - // && handler.handleMessage(fail(message, reader))); - // } - - /** create and handle fail message (ignored if handler is null) */ - public static boolean fail(IMessageHandler handler, String message, Throwable thrown) { - return ((null != handler) && handler.handleMessage(fail(message, thrown))); - } - - /** create and handle error message (ignored if handler is null) */ - public static boolean error(IMessageHandler handler, String message) { - return ((null != handler) && handler.handleMessage(error(message))); - } - - /** create and handle warn message (ignored if handler is null) */ - public static boolean warn(IMessageHandler handler, String message) { - return ((null != handler) && handler.handleMessage(warn(message))); - } - - /** create and handle debug message (ignored if handler is null) */ - public static boolean debug(IMessageHandler handler, String message) { - return ((null != handler) && handler.handleMessage(debug(message))); - } - - /** create and handle info message (ignored if handler is null) */ - public static boolean info(IMessageHandler handler, String message) { - return ((null != handler) && handler.handleMessage(info(message))); - } - - /** @return ABORT_NOMESSAGE if message is empty or IMessage otherwise */ - // - public static IMessage abort(String message) { - if (LangUtil.isEmpty(message)) { - return ABORT_NOMESSAGE; - } else { - return new Message(message, IMessage.ABORT, null, null); - } - } - - /** - * @return abort IMessage with thrown and message o ABORT_NOMESSAGE if both are empty/null - */ - // - public static IMessage abort(String message, Throwable thrown) { - if (!LangUtil.isEmpty(message)) { - return new Message(message, IMessage.ABORT, thrown, null); - } else if (null == thrown) { - return ABORT_NOMESSAGE; - } else { - return new Message(thrown.getMessage(), IMessage.ABORT, thrown, null); - } - } - - /** @return FAIL_NOMESSAGE if message is empty or IMessage otherwise */ - public static IMessage fail(String message) { - if (LangUtil.isEmpty(message)) { - return FAIL_NOMESSAGE; - } else { - return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY); - - // return fail(message, (LineReader) null); - } - } - - /** - * Create fail message. If message is empty but thrown is not, use thrown.getMessage() as the message. If message is empty and - * thrown is null, return FAIL_NOMESSAGE. - * - * @return FAIL_NOMESSAGE if thrown is null and message is empty or IMessage FAIL with message and thrown otherwise - */ - public static IMessage fail(String message, Throwable thrown) { - if (LangUtil.isEmpty(message)) { - if (null == thrown) { - return FAIL_NOMESSAGE; - } else { - return new Message(thrown.getMessage(), IMessage.FAIL, thrown, null); - } - } else { - return new Message(message, IMessage.FAIL, thrown, null); - } - } - - /** - * @return IMessage with IMessage.Kind FAIL and message as text and soure location from reader - */ - // public static IMessage fail(String message) {//, LineReader reader) { - // ISourceLocation loc = null; - // if (null == reader) { - // loc = ISourceLocation.EMPTY; - // } else { - // int line = reader.getLineNumber(); - // if (0 < line) { - // line = 0; - // } - // loc = new SourceLocation(reader.getFile(), line, line, 0); - // } - // return new Message(message, IMessage.FAIL, null, ISourceLocation.EMPTY); - // } - - /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */ - // - public static IMessage error(String message, ISourceLocation location) { - if (LangUtil.isEmpty(message)) { - return ERROR_NOMESSAGE; - } else { - return new Message(message, IMessage.ERROR, null, location); - } - } - - /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */ - // - public static IMessage warn(String message, ISourceLocation location) { - if (LangUtil.isEmpty(message)) { - return WARNING_NOMESSAGE; - } else { - return new Message(message, IMessage.WARNING, null, location); - } - } - - /** @return ERROR_NOMESSAGE if message is empty or IMessage otherwise */ - // - public static IMessage error(String message) { - if (LangUtil.isEmpty(message)) { - return ERROR_NOMESSAGE; - } else { - return new Message(message, IMessage.ERROR, null, null); - } - } - - /** @return WARNING_NOMESSAGE if message is empty or IMessage otherwise */ - // - public static IMessage warn(String message) { - if (LangUtil.isEmpty(message)) { - return WARNING_NOMESSAGE; - } else { - return new Message(message, IMessage.WARNING, null, null); - } - } - - /** @return IMessage.DEBUG message with message content */ - public static IMessage debug(String message) { - return new Message(message, IMessage.DEBUG, null, null); - } - - /** @return IMessage.INFO message with message content */ - public static IMessage info(String message) { - return new Message(message, IMessage.INFO, null, null); - } - - // /** @return ISourceLocation with the current File/line of the reader */ - // public static ISourceLocation makeSourceLocation(LineReader reader) { - // LangUtil.throwIaxIfNull(reader, "reader"); - // - // int line = reader.getLineNumber(); - // if (0 < line) { - // line = 0; - // } - // return new SourceLocation(reader.getFile(), line, line, 0); - // } - - // ------------------------ printing messages - /** - * Print total counts message to the print stream, starting each on a new line - * - * @param messageHolder - * @param out - */ - public static void printMessageCounts(PrintStream out, IMessageHolder messageHolder) { - if ((null == out) || (null == messageHolder)) { - return; - } - printMessageCounts(out, messageHolder, ""); - } - - public static void printMessageCounts(PrintStream out, IMessageHolder holder, String prefix) { - out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder)); - } - - /** - * Print all message to the print stream, starting each on a new line - * - * @param messageHolder - * @param out - * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) - */ - public static void print(PrintStream out, IMessageHolder messageHolder) { - print(out, messageHolder, (String) null, (IMessageRenderer) null, (IMessageHandler) null); - } - - /** - * Print all message to the print stream, starting each on a new line, with a prefix. - * - * @param messageHolder - * @param out - * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) - */ - public static void print(PrintStream out, IMessageHolder holder, String prefix) { - print(out, holder, prefix, (IMessageRenderer) null, (IMessageHandler) null); - } - - /** - * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. - * - * @param messageHolder - * @param out - * @param renderer IMessageRender to render result - use MESSAGE_LINE if null - * @see #print(PrintStream, String, IMessageHolder, IMessageRenderer, IMessageHandler) - */ - public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer) { - print(out, holder, prefix, renderer, (IMessageHandler) null); - } - - /** - * Print all message to the print stream, starting each on a new line, with a prefix and using a renderer. The first line - * renders a summary: {prefix}MessageHolder: {summary} Each message line has the following form: - * - *

-	 * {prefix}[{kind} {index}]: {rendering}
-	 * 
- * - * (where "{index}" (length 3) is the position within the set of like-kinded messages, ignoring selector omissions. Renderers - * are free to render multi-line output. - * - * @param out the PrintStream sink - return silently if null - * @param messageHolder the IMessageHolder with the messages to print - * @param renderer IMessageRender to render result - use MESSAGE_ALL if null - * @param selector IMessageHandler to select messages to render - if null, do all non-null - */ - public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer, - IMessageHandler selector) { - print(out, holder, prefix, renderer, selector, true); - } - - public static void print(PrintStream out, IMessageHolder holder, String prefix, IMessageRenderer renderer, - IMessageHandler selector, boolean printSummary) { - if ((null == out) || (null == holder)) { - return; - } - if (null == renderer) { - renderer = MESSAGE_ALL; - } - if (null == selector) { - selector = PICK_ALL; - } - if (printSummary) { - out.println(prefix + "MessageHolder: " + MessageUtil.renderCounts(holder)); - } - for (IMessage.Kind kind : IMessage.KINDS) { - if (!selector.isIgnoring(kind)) { - IMessage[] messages = holder.getMessages(kind, IMessageHolder.EQUAL); - for (int i = 0; i < messages.length; i++) { - if (selector.handleMessage(messages[i])) { - String label = (null == prefix ? "" : prefix + "[" + kind + " " + LangUtil.toSizedString(i, 3) + "]: "); - out.println(label + renderer.renderToString(messages[i])); - } - } - } - } - } - - public static String toShortString(IMessage message) { - if (null == message) { - return "null"; - } - String m = message.getMessage(); - Throwable t = message.getThrown(); - - return (message.getKind() + (null == m ? "" : ": " + m) + (null == t ? "" : ": " + LangUtil.unqualifiedClassName(t))); - } - - /** @return int number of message of this kind (optionally or greater) in list */ - public static int numMessages(List messages, Kind kind, boolean orGreater) { - if (LangUtil.isEmpty(messages)) { - return 0; - } - IMessageHandler selector = makeSelector(kind, orGreater, null); - IMessage[] result = visitMessages(messages, selector, true, false); - return result.length; - } - - /** - * Select all messages in holder except those of the same kind (optionally or greater). If kind is null, then all messages are - * rejected, so an empty list is returned. - * - * @return unmodifiable list of specified IMessage - */ - public static IMessage[] getMessagesExcept(IMessageHolder holder, final IMessage.Kind kind, final boolean orGreater) { - if ((null == holder) || (null == kind)) { - return new IMessage[0]; - } - - IMessageHandler selector = new IMessageHandler() { - public boolean handleMessage(IMessage message) { - IMessage.Kind test = message.getKind(); - return (!(orGreater ? kind.isSameOrLessThan(test) : kind == test)); - } - - public boolean isIgnoring(Kind kind) { - return false; - } - - public void dontIgnore(IMessage.Kind kind) { - - } - - public void ignore(Kind kind) { - } - }; - return visitMessages(holder, selector, true, false); - } - - /** @return unmodifiable list of IMessage complying with parameters */ - public static List getMessages(IMessageHolder holder, IMessage.Kind kind, boolean orGreater, String infix) { - if (null == holder) { - return Collections.emptyList(); - } - if ((null == kind) && LangUtil.isEmpty(infix)) { - return holder.getUnmodifiableListView(); - } - IMessageHandler selector = makeSelector(kind, orGreater, infix); - IMessage[] messages = visitMessages(holder, selector, true, false); - if (LangUtil.isEmpty(messages)) { - return Collections.emptyList(); - } - return Collections.unmodifiableList(Arrays.asList(messages)); - } - - /** - * Extract messages of type kind from the input list. - * - * @param messages if null, return EMPTY_LIST - * @param kind if null, return messages - * @see MessageHandler#getMessages(Kind) - */ - public static List getMessages(List messages, IMessage.Kind kind) { - if (null == messages) { - return Collections.emptyList(); - } - if (null == kind) { - return messages; - } - ArrayList result = new ArrayList(); - for (IMessage message : messages) { - if (kind == message.getKind()) { - result.add(message); - } - } - if (0 == result.size()) { - return Collections.emptyList(); - } - return result; - } - - /** - * Map to the kind of messages associated with this string key. - * - * @param kind the String representing the kind of message (IMessage.Kind.toString()) - * @return Kind the associated IMessage.Kind, or null if not found - */ - public static IMessage.Kind getKind(String kind) { - if (null != kind) { - kind = kind.toLowerCase(); - for (IMessage.Kind k : IMessage.KINDS) { - if (kind.equals(k.toString())) { - return k; - } - } - } - return null; - } - - /** - * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor - */ - public static IMessage[] visitMessages(IMessageHolder holder, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) { - if (null == holder) { - return IMessage.RA_IMessage; - } else { - return visitMessages(holder.getUnmodifiableListView(), visitor, accumulate, abortOnFail); - } - } - - /** - * Run visitor over the set of messages in holder, optionally accumulating those accepted by the visitor - */ - public static IMessage[] visitMessages(IMessage[] messages, IMessageHandler visitor, boolean accumulate, boolean abortOnFail) { - if (LangUtil.isEmpty(messages)) { - return IMessage.RA_IMessage; - } else { - return visitMessages(Arrays.asList(messages), visitor, accumulate, abortOnFail); - } - } - - /** - * Run visitor over a collection of messages, optionally accumulating those accepted by the visitor - * - * @param messages if null or empty, return IMessage.RA_IMessage - * @param visitor run visitor.handleMessage(message) on each message - if null and messages not empty, IllegalArgumentException - * @param accumulate if true, then return accepted IMessage[] - * @param abortOnFail if true and visitor returns false, stop visiting - * @return IMessage.RA_IMessage if collection is empty, if not accumulate, or if visitor accepted no IMessage, or IMessage[] of - * accepted messages otherwise - * @throws IllegalArgumentException if any in collection are not instanceof IMessage - */ - public static IMessage[] visitMessages(Collection messages, IMessageHandler visitor, final boolean accumulate, - final boolean abortOnFail) { - if (LangUtil.isEmpty(messages)) { - return IMessage.RA_IMessage; - } - LangUtil.throwIaxIfNull(visitor, "visitor"); - ArrayList result = (accumulate ? new ArrayList() : null); - for (IMessage m : messages) { - if (visitor.handleMessage(m)) { - if (accumulate) { - result.add(m); - } - } else if (abortOnFail) { - break; - } - } - if (!accumulate || (0 == result.size())) { - return IMessage.RA_IMessage; - } else { - return result.toArray(IMessage.RA_IMessage); - } - } - - /** - * Make an IMessageHandler that handles IMessage if they have the right kind (or greater) and contain some infix String. - * - * @param kind the IMessage.Kind required of the message - * @param orGreater if true, also accept messages with greater kinds, as defined by IMessage.Kind.COMPARATOR - * @param infix the String text to require in the message - may be null or empty to accept any message with the specified kind. - * @return IMessageHandler selector that works to param specs - */ - public static IMessageHandler makeSelector(IMessage.Kind kind, boolean orGreater, String infix) { - if (!orGreater && LangUtil.isEmpty(infix)) { - if (kind == IMessage.ABORT) { - return PICK_ABORT; - } else if (kind == IMessage.DEBUG) { - return PICK_DEBUG; - } else if (kind == IMessage.DEBUG) { - return PICK_DEBUG; - } else if (kind == IMessage.ERROR) { - return PICK_ERROR; - } else if (kind == IMessage.FAIL) { - return PICK_FAIL; - } else if (kind == IMessage.INFO) { - return PICK_INFO; - } else if (kind == IMessage.WARNING) { - return PICK_WARNING; - } - } - return new KindSelector(kind, orGreater, infix); - } - - // ------------------ visitors to select messages - public static final IMessageHandler PICK_ALL = new KindSelector((IMessage.Kind) null); - public static final IMessageHandler PICK_ABORT = new KindSelector(IMessage.ABORT); - public static final IMessageHandler PICK_DEBUG = new KindSelector(IMessage.DEBUG); - public static final IMessageHandler PICK_ERROR = new KindSelector(IMessage.ERROR); - public static final IMessageHandler PICK_FAIL = new KindSelector(IMessage.FAIL); - public static final IMessageHandler PICK_INFO = new KindSelector(IMessage.INFO); - public static final IMessageHandler PICK_WARNING = new KindSelector(IMessage.WARNING); - public static final IMessageHandler PICK_ABORT_PLUS = new KindSelector(IMessage.ABORT, true); - public static final IMessageHandler PICK_DEBUG_PLUS = new KindSelector(IMessage.DEBUG, true); - public static final IMessageHandler PICK_ERROR_PLUS = new KindSelector(IMessage.ERROR, true); - public static final IMessageHandler PICK_FAIL_PLUS = new KindSelector(IMessage.FAIL, true); - public static final IMessageHandler PICK_INFO_PLUS = new KindSelector(IMessage.INFO, true); - public static final IMessageHandler PICK_WARNING_PLUS = new KindSelector(IMessage.WARNING, true); - - /** implementation for PICK_... constants */ - private static class KindSelector implements IMessageHandler { - final IMessage.Kind sought; - final boolean floor; - final String infix; - - KindSelector(IMessage.Kind sought) { - this(sought, false); - } - - KindSelector(IMessage.Kind sought, boolean floor) { - this(sought, floor, null); - } - - KindSelector(IMessage.Kind sought, boolean floor, String infix) { - this.sought = sought; - this.floor = floor; - this.infix = (LangUtil.isEmpty(infix) ? null : infix); - } - - /** - * @return false if this message is null, of true if we seek any kind (null) or if this has the exact kind we seek and this - * has any text sought - */ - public boolean handleMessage(IMessage message) { - return ((null != message) && !isIgnoring(message.getKind()) && textIn(message)); - } - - /** @return true if handleMessage would return false for a message of this kind */ - public boolean isIgnoring(IMessage.Kind kind) { - if (!floor) { - return ((null != sought) && (sought != kind)); - } else if (null == sought) { - return false; - } else { - return (0 < IMessage.Kind.COMPARATOR.compare(sought, kind)); - } - } - - public void dontIgnore(IMessage.Kind kind) { - - } - - private boolean textIn(IMessage message) { - if (null == infix) { - return true; - } - String text = message.getMessage(); - return (text.indexOf(infix) != -1); - } - - public void ignore(Kind kind) { - } - } - - // ------------------ components to render messages - /** parameterize rendering behavior for messages */ - public static interface IMessageRenderer { - String renderToString(IMessage message); - } - - /** render message more verbosely if it is worse */ - public static final IMessageRenderer MESSAGE_SCALED = new IMessageRenderer() { - public String toString() { - return "MESSAGE_SCALED"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - IMessage.Kind kind = message.getKind(); - int level = 3; - if ((kind == IMessage.ABORT) || (kind == IMessage.FAIL)) { - level = 1; - } else if ((kind == IMessage.ERROR) || (kind == IMessage.WARNING)) { - level = 2; - } else { - level = 3; - } - String result = null; - switch (level) { - case (1): - result = MESSAGE_TOSTRING.renderToString(message); - break; - case (2): - result = MESSAGE_LINE.renderToString(message); - break; - case (3): - result = MESSAGE_SHORT.renderToString(message); - break; - } - Throwable thrown = message.getThrown(); - if (null != thrown) { - if (level == 3) { - result += "Thrown: \n" + LangUtil.renderExceptionShort(thrown); - } else { - result += "Thrown: \n" + LangUtil.renderException(thrown); - } - } - - return result; - } - }; - - /** render message as label, i.e., less than 33 char */ - public static final IMessageRenderer MESSAGE_LABEL = new IMessageRenderer() { - public String toString() { - return "MESSAGE_LABEL"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - return renderMessageLine(message, 5, 5, 32); - } - }; - - /** render message as label, i.e., less than 33 char, with no source location */ - public static final IMessageRenderer MESSAGE_LABEL_NOLOC = new IMessageRenderer() { - public String toString() { - return "MESSAGE_LABEL_NOLOC"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - return renderMessageLine(message, 10, 0, 32); - } - }; - - /** render message as line, i.e., less than 75 char, no internal line sep */ - public static final IMessageRenderer MESSAGE_LINE = new IMessageRenderer() { - public String toString() { - return "MESSAGE_LINE"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - return renderMessageLine(message, 8, 2, 74); - } - }; - - /** - * render message as line, i.e., less than 75 char, no internal line sep, trying to trim text as needed to end with a full - * source location - */ - public static final IMessageRenderer MESSAGE_LINE_FORCE_LOC = new IMessageRenderer() { - public String toString() { - return "MESSAGE_LINE_FORCE_LOC"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - return renderMessageLine(message, 2, 40, 74); - } - }; - - /** render message without restriction, up to 10K, including throwable */ - public static final IMessageRenderer MESSAGE_ALL = new IMessageRenderer() { - public String toString() { - return "MESSAGE_ALL"; - } - - public String renderToString(IMessage message) { - return renderMessage(message); - } - }; - - // /** render message without restriction, up to 10K, including (but eliding) throwable */ - // public static final IMessageRenderer MESSAGE_ALL_ELIDED= new IMessageRenderer() { - // public String toString() { return "MESSAGE_ALL_ELIDED"; } - // public String renderToString(IMessage message) { - // return renderMessage(message, true); - // } - // }; - - /** render message without restriction, except any Throwable thrown */ - public static final IMessageRenderer MESSAGE_MOST = new IMessageRenderer() { - public String toString() { - return "MESSAGE_MOST"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - return renderMessageLine(message, 1, 1, 10000); - } - }; - - /** - * render message as wide line, i.e., less than 256 char, no internal line sep, except any Throwable thrown - */ - public static final IMessageRenderer MESSAGE_WIDELINE = new IMessageRenderer() { - public String toString() { - return "MESSAGE_WIDELINE"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - return renderMessageLine(message, 8, 2, 255); // XXX revert to 256 - } - }; - /** render message using its toString() or "((IMessage) null)" */ - public static final IMessageRenderer MESSAGE_TOSTRING = new IMessageRenderer() { - public String toString() { - return "MESSAGE_TOSTRING"; - } - - public String renderToString(IMessage message) { - if (null == message) { - return "((IMessage) null)"; - } - return message.toString(); - } - }; - - /** render message using toShortString(IMessage)" */ - public static final IMessageRenderer MESSAGE_SHORT = new IMessageRenderer() { - public String toString() { - return "MESSAGE_SHORT"; - } - - public String renderToString(IMessage message) { - return toShortString(message); - } - }; - - /** - * This renders IMessage as String, ignoring empty elements and eliding any thrown stack traces. - * - * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace) - * @see renderSourceLocation(ISourceLocation loc) - */ - public static String renderMessage(IMessage message) { - return renderMessage(message, true); - } - - /** - * This renders IMessage as String, ignoring empty elements and eliding any thrown. - * - * @return "((IMessage) null)" if null or String rendering otherwise, including everything (esp. throwable stack trace) - * @see renderSourceLocation(ISourceLocation loc) - */ - public static String renderMessage(IMessage message, boolean elide) { - if (null == message) { - return "((IMessage) null)"; - } - - ISourceLocation loc = message.getSourceLocation(); - String locString = (null == loc ? "" : " at " + loc); - - String result = message.getKind() + locString + " " + message.getMessage(); - - Throwable thrown = message.getThrown(); - if (thrown != null) { - result += " -- " + LangUtil.renderExceptionShort(thrown); - result += "\n" + LangUtil.renderException(thrown, elide); - } - - if (message.getExtraSourceLocations().isEmpty()) { - return result; - } else { - return addExtraSourceLocations(message, result); - } - } - - public static String addExtraSourceLocations(IMessage message, String baseMessage) { - StringWriter buf = new StringWriter(); - PrintWriter writer = new PrintWriter(buf); - writer.println(baseMessage); - for (Iterator iter = message.getExtraSourceLocations().iterator(); iter.hasNext();) { - ISourceLocation element = iter.next(); - if (element != null) { - writer.print("\tsee also: " + element.toString()); - if (iter.hasNext()) { - writer.println(); - } - } - } - try { - buf.close(); - } catch (IOException ioe) { - } - return buf.getBuffer().toString(); - } - - /** - * Render ISourceLocation to String, ignoring empty elements (null or ISourceLocation.NO_FILE or ISourceLocation.NO_COLUMN - * (though implementations may return 0 from getColumn() when passed NO_COLUMN as input)). - * - * @return "((ISourceLocation) null)" if null or String rendering - * - *
-	 * {file:}line{:column}
-	 * 
- * - */ - public static String renderSourceLocation(ISourceLocation loc) { - if (null == loc) { - return "((ISourceLocation) null)"; - } - StringBuffer sb = new StringBuffer(); - - File sourceFile = loc.getSourceFile(); - if (sourceFile != ISourceLocation.NO_FILE) { - sb.append(sourceFile.getPath()); - sb.append(":"); - } - int line = loc.getLine(); - sb.append("" + line); - - int column = loc.getColumn(); - if (column != ISourceLocation.NO_COLUMN) { - sb.append(":" + column); - } - - return sb.toString(); - } - - /** - * Render message in a line. IMessage.Kind is always printed, then any unqualified exception class, then the remainder of text - * and location according to their relative scale, all to fit in max characters or less. This does not render thrown except for - * the unqualified class name - * - * @param max the number of characters - forced to 32..10000 - * @param textScale relative proportion to spend on message and/or exception message, relative to source location - if 0, - * message is suppressed - * @param locScale relative proportion to spend on source location suppressed if 0 - * @return "((IMessage) null)" or message per spec - */ - public static String renderMessageLine(IMessage message, int textScale, int locScale, int max) { - - if (null == message) { - return "((IMessage) null)"; - } - if (max < 32) { - max = 32; - } else if (max > 10000) { - max = 10000; - } - if (0 > textScale) { - textScale = -textScale; - } - if (0 > locScale) { - locScale = -locScale; - } - - String text = message.getMessage(); - Throwable thrown = message.getThrown(); - ISourceLocation sl = message.getSourceLocation(); - IMessage.Kind kind = message.getKind(); - StringBuffer result = new StringBuffer(); - result.append(kind.toString()); - result.append(": "); - if (null != thrown) { - result.append(LangUtil.unqualifiedClassName(thrown) + " "); - if ((null == text) || ("".equals(text))) { - text = thrown.getMessage(); - } - } - - if (0 == textScale) { - text = ""; - } else if ((null != text) && (null != thrown)) { - // decide between message and exception text? - String s = thrown.getMessage(); - if ((null != s) && (0 < s.length())) { - text += " - " + s; - } - } - String loc = ""; - if ((0 != locScale) && (null != sl)) { - File f = sl.getSourceFile(); - if (f == ISourceLocation.NO_FILE) { - f = null; - } - if (null != f) { - loc = f.getName(); - } - int line = sl.getLine(); - int col = sl.getColumn(); - int end = sl.getEndLine(); - if ((0 == line) && (0 == col) && (0 == end)) { - // ignore numbers if default - } else { - loc += ":" + line + (col == 0 ? "" : ":" + col); - if (line != end) { // XXX consider suppressing nonstandard... - loc += ":" + end; - } - } - if (!LangUtil.isEmpty(loc)) { - loc = "@[" + loc; // matching "]" added below after clipping - } - } - - // now budget between text and loc - float totalScale = locScale + textScale; - float remainder = max - result.length() - 4; - if ((remainder > 0) && (0 < totalScale)) { - int textSize = (int) (remainder * textScale / totalScale); - int locSize = (int) (remainder * locScale / totalScale); - // adjust for underutilization - int extra = locSize - loc.length(); - if (0 < extra) { - locSize = loc.length(); - textSize += extra; - } - extra = textSize - text.length(); - if (0 < extra) { - textSize = text.length(); - if (locSize < loc.length()) { - locSize += extra; - } - } - if (locSize > loc.length()) { - locSize = loc.length(); - } - if (textSize > text.length()) { - textSize = text.length(); - } - if (0 < textSize) { - result.append(text.substring(0, textSize)); - } - if (0 < locSize) { - if (0 < textSize) { - result.append(" "); - } - result.append(loc.substring(0, locSize) + "]"); - } - } - return result.toString(); - } - - /** @return String of the form "{(# {type}) }.." for message kinds, skipping 0 */ - public static String renderCounts(IMessageHolder holder) { - if (0 == holder.numMessages(null, false)) { - return "(0 messages)"; - } - StringBuffer sb = new StringBuffer(); - for (IMessage.Kind kind : IMessage.KINDS) { - int num = holder.numMessages(kind, false); - if (0 < num) { - sb.append(" (" + num + " " + kind + ") "); - } - } - return sb.toString(); - } - - /** - * Factory for handler adapted to PrintStream XXX weak - only handles println(String) - * - * @param handler the IMessageHandler sink for the messages generated - * @param kind the IMessage.Kind of message to create - * @param overage the OuputStream for text not captured by the handler (if null, System.out used) - * @throws IllegalArgumentException if kind or handler is null - */ - public static PrintStream handlerPrintStream(final IMessageHandler handler, final IMessage.Kind kind, - final OutputStream overage, final String prefix) { - LangUtil.throwIaxIfNull(handler, "handler"); - LangUtil.throwIaxIfNull(kind, "kind"); - class HandlerPrintStream extends PrintStream { - HandlerPrintStream() { - super(null == overage ? System.out : overage); - } - - public void println() { - println(""); - } - - public void println(Object o) { - println(null == o ? "null" : o.toString()); - } - - public void println(String input) { - String textMessage = (null == prefix ? input : prefix + input); - IMessage m = new Message(textMessage, kind, null, null); - handler.handleMessage(m); - } - } - return new HandlerPrintStream(); - } - - /** utility class */ - private MessageUtil() { - } - - /** - * Handle all messages in the second handler using the first - * - * @param handler the IMessageHandler sink for all messages in source - * @param holder the IMessageHolder source for all messages to handle - * @param fastFail if true, stop on first failure - * @return false if any sink.handleMessage(..) failed - */ - public static boolean handleAll(IMessageHandler sink, IMessageHolder source, boolean fastFail) { - return handleAll(sink, source, null, true, fastFail); - } - - /** - * Handle messages in the second handler using the first - * - * @param handler the IMessageHandler sink for all messages in source - * @param holder the IMessageHolder source for all messages to handle - * @param kind the IMessage.Kind to select, if not null - * @param orGreater if true, also accept greater kinds - * @param fastFail if true, stop on first failure - * @return false if any sink.handleMessage(..) failed - */ - public static boolean handleAll(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater, - boolean fastFail) { - LangUtil.throwIaxIfNull(sink, "sink"); - LangUtil.throwIaxIfNull(source, "source"); - return handleAll(sink, source.getMessages(kind, orGreater), fastFail); - } - - /** - * Handle messages in the second handler using the first if they are NOT of this kind (optionally, or greater). If you pass null - * as the kind, then all messages are ignored and this returns true. - * - * @param handler the IMessageHandler sink for all messages in source - * @param holder the IMessageHolder source for all messages to handle - * @param kind the IMessage.Kind to reject, if not null - * @param orGreater if true, also reject greater kinds - * @param fastFail if true, stop on first failure - * @return false if any sink.handleMessage(..) failed - */ - public static boolean handleAllExcept(IMessageHandler sink, IMessageHolder source, IMessage.Kind kind, boolean orGreater, - boolean fastFail) { - LangUtil.throwIaxIfNull(sink, "sink"); - LangUtil.throwIaxIfNull(source, "source"); - if (null == kind) { - return true; - } - IMessage[] messages = getMessagesExcept(source, kind, orGreater); - return handleAll(sink, messages, fastFail); - } - - /** - * Handle messages in the sink. - * - * @param handler the IMessageHandler sink for all messages in source - * @param sources the IMessage[] messages to handle - * @param fastFail if true, stop on first failure - * @return false if any sink.handleMessage(..) failed - * @throws IllegalArgumentException if sink is null - */ - public static boolean handleAll(IMessageHandler sink, IMessage[] sources, boolean fastFail) { - LangUtil.throwIaxIfNull(sink, "sink"); - if (LangUtil.isEmpty(sources)) { - return true; - } - boolean result = true; - for (int i = 0; i < sources.length; i++) { - if (!sink.handleMessage(sources[i])) { - if (fastFail) { - return false; - } - if (result) { - result = false; - } - } - } - return result; - } -} diff --git a/bridge/src/org/aspectj/bridge/MessageWriter.java b/bridge/src/org/aspectj/bridge/MessageWriter.java deleted file mode 100644 index 3fbeb91b0..000000000 --- a/bridge/src/org/aspectj/bridge/MessageWriter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.io.PrintWriter; - -/** - * An IMessageHandler implementation that writes all to a PrintWriter. - * Clients may set this up to throw AbortException for FAIL or ERROR messages. - * Subclasses may control whether messages are printed and how they - * are rendered by overriding render(IMessage). - */ -public class MessageWriter implements IMessageHandler { - - protected PrintWriter writer; - protected boolean abortOnFailure; - public MessageWriter(PrintWriter writer, boolean abortOnFailure) { - this.writer = (null != writer ? writer : new PrintWriter(System.out)); - this.abortOnFailure = abortOnFailure; - } - - /** - * Handle message by printing and - * (if abortOnFailure) throwing an AbortException if - * the messages is a failure or an abort (but not for errors). - * @see org.aspectj.bridge.IMessageHandler#handleMessage(IMessage) - */ - public boolean handleMessage(IMessage message) throws AbortException { - if ((null != message) && !isIgnoring(message.getKind())) { - String result = render(message); - if (null != result) { - writer.println(result); - writer.flush(); - if (abortOnFailure - && (message.isFailed() || message.isAbort())) { - throw new AbortException(message); - } - } - } - return true; - } - - /** - * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) - */ - public boolean isIgnoring(IMessage.Kind kind) { - // XXX share MessageHandler implementation in superclass - return false; - } - - /** - * No-op - * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) - * @param kind - */ - public void dontIgnore(IMessage.Kind kind) { - - } - - /** - * No-op - * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind) - * @param kind - */ - public void ignore(IMessage.Kind kind) { - } - - /** @return null to not print, or message rendering (including newlines) */ - protected String render(IMessage message) { - return message.toString(); - } - -} diff --git a/bridge/src/org/aspectj/bridge/ReflectionFactory.java b/bridge/src/org/aspectj/bridge/ReflectionFactory.java deleted file mode 100644 index 8eb65b3a0..000000000 --- a/bridge/src/org/aspectj/bridge/ReflectionFactory.java +++ /dev/null @@ -1,103 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.lang.reflect.Constructor; -import java.util.Arrays; - -/** - * - */ -public class ReflectionFactory { // XXX lease, pool - public static final String OLD_AJC = "bridge.tools.impl.OldAjc"; - public static final String ECLIPSE = "org.aspectj.ajdt.ajc.AjdtCommand"; - - private static final Object[] NONE = new Object[0]; - - /** - * Produce a compiler as an ICommand. - * - * @param cname the fully-qualified class name of the command to create by reflection (assuming a public no-argument - * constructor). - * @return ICommand compiler or null - */ - public static ICommand makeCommand(String cname, IMessageHandler errorSink) { - return (ICommand) make(ICommand.class, cname, NONE, errorSink); - } - - /** - * Make an object of type c by reflectively loading the class cname and creating an instance using args (if any), signalling - * errors (if any) to any errorSink. - */ - private static Object make(Class c, String cname, Object[] args, IMessageHandler errorSink) { - final boolean makeErrors = (null != errorSink); - Object result = null; - try { - final Class cfn = Class.forName(cname); - String error = null; - if (args == NONE) { - result = cfn.newInstance(); - } else { - Class[] types = getTypes(args); - Constructor constructor = cfn.getConstructor(types); - if (null != constructor) { - result = constructor.newInstance(args); - } else { - if (makeErrors) { - error = "no constructor for " + c + " using " + Arrays.asList(types); - } - } - } - if (null != result) { - if (!c.isAssignableFrom(result.getClass())) { - if (makeErrors) { - error = "expecting type " + c + " got " + result.getClass(); - } - result = null; - } - } - if (null != error) { - IMessage mssg = new Message(error, IMessage.FAIL, null, null); - errorSink.handleMessage(mssg); - } - } catch (Throwable t) { - if (makeErrors) { - String mssg = "ReflectionFactory unable to load " + cname + " as " + c.getName(); - IMessage m = new Message(mssg, IMessage.FAIL, t, null); - errorSink.handleMessage(m); - } - } - return result; - } - - /** - * @return Class[] with types of args or matching null elements - */ - private static Class[] getTypes(Object[] args) { - if ((null == args) || (0 < args.length)) { - return new Class[0]; - } else { - Class[] result = new Class[args.length]; - for (int i = 0; i < result.length; i++) { - if (null != args[i]) { - result[i] = args[i].getClass(); - } - } - return result; - } - } - - private ReflectionFactory() { - } -} diff --git a/bridge/src/org/aspectj/bridge/SourceLocation.java b/bridge/src/org/aspectj/bridge/SourceLocation.java deleted file mode 100644 index 739dd52ab..000000000 --- a/bridge/src/org/aspectj/bridge/SourceLocation.java +++ /dev/null @@ -1,199 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.io.File; - -import org.aspectj.util.LangUtil; - -/** - * Immutable source location. This guarantees that the source file is not null and that the numeric values are positive and line <= - * endLine. - * - * @see org.aspectj.lang.reflect.SourceLocation - * @see org.aspectj.compiler.base.parser.SourceInfo - * @see org.aspectj.tools.ide.SourceLine - * @see org.aspectj.testing.harness.ErrorLine - */ -public class SourceLocation implements ISourceLocation { - - private static final long serialVersionUID = -5434765814401009794L; - - private transient int cachedHashcode = -1; - - /** used when SourceLocation is not available */ - public static final ISourceLocation UNKNOWN = new SourceLocation(ISourceLocation.NO_FILE, 0, 0, 0); - - private final File sourceFile; - private final int startLine; - private final int column; - private final int endLine; - private int offset; - private final String context; - private boolean noColumn; - private String sourceFileName; - - /** @throws IllegalArgumentException if the input would not be a valid line */ - public static final void validLine(int line) { - if (line < 0) { - throw new IllegalArgumentException("negative line: " + line); - } else if (line > ISourceLocation.MAX_LINE) { - throw new IllegalArgumentException("line too large: " + line); - } - } - - /** @throws IllegalArgumentException if the input would not be a valid column */ - public static final void validColumn(int column) { - if (column < 0) { - throw new IllegalArgumentException("negative column: " + column); - } else if (column > ISourceLocation.MAX_COLUMN) { - throw new IllegalArgumentException("column too large: " + column); - } - } - - /** - * Same as SourceLocation(file, line, line, 0), except that column is not rendered during toString() - */ - public SourceLocation(File file, int line) { - this(file, line, line, NO_COLUMN); - } - - /** same as SourceLocation(file, line, endLine, ISourceLocation.NO_COLUMN) */ - public SourceLocation(File file, int line, int endLine) { - this(file, line, endLine, ISourceLocation.NO_COLUMN); - } - - /** - * @param file File of the source; if null, use ISourceLocation.NO_FILE, not null - * @param line int starting line of the location - positive number - * @param endLine int ending line of the location - <= starting line - * @param column int character position of starting location - positive number - */ - public SourceLocation(File file, int line, int endLine, int column) { - this(file, line, endLine, column, (String) null); - } - - public SourceLocation(File file, int line, int endLine, int column, String context) { - if (column == NO_COLUMN) { - column = 0; - noColumn = true; - } - if (null == file) { - file = ISourceLocation.NO_FILE; - } - validLine(line); - validLine(endLine); - LangUtil.throwIaxIfFalse(line <= endLine, line + " > " + endLine); - LangUtil.throwIaxIfFalse(column >= 0, "negative column: " + column); - this.sourceFile = file; - this.startLine = line; - this.column = column; - this.endLine = endLine; - 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; - } - - public int getLine() { - return startLine; - } - - /** - * @return int actual column or 0 if not available per constructor treatment of ISourceLocation.NO_COLUMN - */ - public int getColumn() { - return column; - } - - public int getEndLine() { - return endLine; - } - - /** @return null String or application-specific context */ - public String getContext() { - return context; - } - - /** @return String {context\n}{file:}line{:column} */ - public String toString() { - StringBuffer sb = new StringBuffer(); - if (null != context) { - sb.append(context); - sb.append(LangUtil.EOL); - } - if (sourceFile != ISourceLocation.NO_FILE) { - sb.append(sourceFile.getPath()); - } - if (startLine > 0) { - sb.append(":"); - sb.append(startLine); // "" + startLine + "-" + endLine); - } - if (!noColumn) { - sb.append(":" + column); - } - if (offset >= 0) { - sb.append("::" + offset); - } - return sb.toString(); - } - - // XXX Ctors for this type should know about an offset, rather than - // it being set through these methods - but there are just too many - // ctors at the moment! It needs sorting out. - public int getOffset() { - return offset; - } - - public void setOffset(int i) { - cachedHashcode = -1; - offset = i; - } - - public String getSourceFileName() { - return sourceFileName; - } - - public boolean equals(Object obj) { - if (!(obj instanceof SourceLocation)) { - return false; - } - SourceLocation o = (SourceLocation) obj; - return startLine == o.startLine && column == o.column && endLine == o.endLine && offset == o.offset - && (sourceFile == null ? o.sourceFile == null : sourceFile.equals(o.sourceFile)) - && (context == null ? o.context == null : context.equals(o.context)) && noColumn == o.noColumn - && (sourceFileName == null ? o.sourceFileName == null : sourceFileName.equals(o.sourceFileName)); - } - - public int hashCode() { - if (cachedHashcode == -1) { - cachedHashcode = (sourceFile == null ? 0 : sourceFile.hashCode()); - cachedHashcode = cachedHashcode * 37 + startLine; - cachedHashcode = cachedHashcode * 37 + column; - cachedHashcode = cachedHashcode * 37 + endLine; - cachedHashcode = cachedHashcode * 37 + offset; - cachedHashcode = cachedHashcode * 37 + (context == null ? 0 : context.hashCode()); - cachedHashcode = cachedHashcode * 37 + (noColumn ? 0 : 1); - cachedHashcode = cachedHashcode * 37 + (sourceFileName == null ? 0 : sourceFileName.hashCode()); - } - return cachedHashcode; - } - -} diff --git a/bridge/src/org/aspectj/bridge/Version.java b/bridge/src/org/aspectj/bridge/Version.java deleted file mode 100644 index 835127c75..000000000 --- a/bridge/src/org/aspectj/bridge/Version.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ******************************************************************** - * Copyright (c) 1998-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * *******************************************************************/ - -package org.aspectj.bridge; - -import java.text.ParsePosition; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** release-specific version information */ -public class Version { - - // generated from build/lib/BridgeVersion.java - - /** default version value for development version */ - public static final String DEVELOPMENT = "DEVELOPMENT"; - // VersionUptodate.java depends on this value - - /** default time value for development version */ - public static final long NOTIME = 0L; - - /** set by build script */ - public static final String text = "DEVELOPMENT"; - // VersionUptodate.java scans for "static final String text = " - - /** - * Time text set by build script using SIMPLE_DATE_FORMAT. - * (if DEVELOPMENT version, invalid) - */ - public static final String time_text = "Friday Nov 18, 2016 at 16:34:52 GMT"; - - /** - * time in seconds-since-... format, used by programmatic clients. - * (if DEVELOPMENT version, NOTIME) - */ - private static long time = -1; // -1 == uninitialized - - /** format used by build script to set time_text */ - public static final String SIMPLE_DATE_FORMAT = "EEEE MMM d, yyyy 'at' HH:mm:ss z"; - - public static long getTime() { - if (time==-1) { - long foundTime = NOTIME; - // if not DEVELOPMENT version, read time text using format used to set time - try { - SimpleDateFormat format = new SimpleDateFormat(SIMPLE_DATE_FORMAT); - ParsePosition pos = new ParsePosition(0); - Date date = format.parse(time_text, pos); - if (date!=null) foundTime = date.getTime(); - } catch (Throwable t) { - } - time = foundTime; - } - return time; - } - - /** - * Test whether the version is as specified by any first argument. - * Emit text to System.err on failure - * @param args String[] with first argument equal to Version.text - * @see Version#text - */ - public static void main(String[] args) { - if ((null != args) && (0 < args.length)) { - if (!Version.text.equals(args[0])) { - System.err.println("version expected: \"" - + args[0] - + "\" actual=\"" - + Version.text - + "\""); - } - } - } -} - - - - - diff --git a/bridge/src/org/aspectj/bridge/WeaveMessage.java b/bridge/src/org/aspectj/bridge/WeaveMessage.java deleted file mode 100644 index 2c697a811..000000000 --- a/bridge/src/org/aspectj/bridge/WeaveMessage.java +++ /dev/null @@ -1,117 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * 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 30-May-2004 - * ******************************************************************/ - -package org.aspectj.bridge; - -public class WeaveMessage extends Message { - - // Kinds of weaving message we can produce - - public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS = new WeaveMessageKind(1, - "Extending interface set for type '%1' (%2) to include '%3' (%4)"); - - public static WeaveMessageKind WEAVEMESSAGE_ITD = new WeaveMessageKind(2, "Type '%1' (%2) has intertyped %3 from '%4' (%5)"); - - // %7 is information like "[with runtime test]" - public static WeaveMessageKind WEAVEMESSAGE_ADVISES = new WeaveMessageKind(3, - "Join point '%1' in Type '%2' (%3) advised by %4 advice from '%5' (%6)%7"); - - public static WeaveMessageKind WEAVEMESSAGE_DECLAREPARENTSEXTENDS = new WeaveMessageKind(4, - "Setting superclass of type '%1' (%2) to '%3' (%4)"); - - public static WeaveMessageKind WEAVEMESSAGE_SOFTENS = new WeaveMessageKind(5, - "Softening exceptions in type '%1' (%2) as defined by aspect '%3' (%4)"); - - public static WeaveMessageKind WEAVEMESSAGE_ANNOTATES = new WeaveMessageKind(6, - "'%1' (%2) is annotated with %3 %4 annotation from '%5' (%6)"); - - public static WeaveMessageKind WEAVEMESSAGE_MIXIN = new WeaveMessageKind(7, "Mixing interface '%1' (%2) into type '%3' (%4)"); - - public static WeaveMessageKind WEAVEMESSAGE_REMOVES_ANNOTATION = new WeaveMessageKind(6, - "'%1' (%2) has had %3 %4 annotation removed by '%5' (%6)"); - - private String affectedtypename; - private String aspectname; - - // private ctor - use the static factory method - private WeaveMessage(String message, String affectedtypename, String aspectname) { - super(message, IMessage.WEAVEINFO, null, null); - this.affectedtypename = affectedtypename; - this.aspectname = aspectname; - } - - /** - * Static helper method for constructing weaving messages. - * - * @param kind what kind of message (e.g. declare parents) - * @param inserts inserts for the message (inserts are marked %n in the message) - * @return new weaving message - */ - public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts) { - StringBuffer str = new StringBuffer(kind.getMessage()); - int pos = -1; - while ((pos = new String(str).indexOf("%")) != -1) { - int n = Character.getNumericValue(str.charAt(pos + 1)); - str.replace(pos, pos + 2, inserts[n - 1]); - } - return new WeaveMessage(str.toString(), null, null); - } - - /** - * Static helper method for constructing weaving messages. - * - * @param kind what kind of message (e.g. declare parents) - * @param inserts inserts for the message (inserts are marked %n in the message) - * @param affectedtypename the type which is being advised/declaredUpon - * @param aspectname the aspect that defined the advice or declares - * @return new weaving message - */ - public static WeaveMessage constructWeavingMessage(WeaveMessageKind kind, String[] inserts, String affectedtypename, - String aspectname) { - StringBuffer str = new StringBuffer(kind.getMessage()); - int pos = -1; - while ((pos = new String(str).indexOf("%")) != -1) { - int n = Character.getNumericValue(str.charAt(pos + 1)); - str.replace(pos, pos + 2, inserts[n - 1]); - } - return new WeaveMessage(str.toString(), affectedtypename, aspectname); - } - - /** - * @return Returns the aspectname. - */ - public String getAspectname() { - return aspectname; - } - - /** - * @return Returns the affectedtypename. - */ - public String getAffectedtypename() { - return affectedtypename; - } - - public static class WeaveMessageKind { - - // private int id; - private String message; - - public WeaveMessageKind(int id, String message) { - // this.id = id; - this.message = message; - } - - public String getMessage() { - return message; - } - } -} diff --git a/bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java b/bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java deleted file mode 100644 index 28a414acd..000000000 --- a/bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java +++ /dev/null @@ -1,260 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005-2012 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: - * Adrian Colyer Initial implementation - * Andy Clement various fixes - * Trask Stanalker #373195 - * ******************************************************************/ -package org.aspectj.bridge.context; - -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; - -/** - * This class is responsible for tracking progress through the various phases of compilation and weaving. - * When an exception occurs (or a message is issued, if desired), you can ask this class for a - * "stack trace" that gives information about what the compiler was doing at the time. - * The trace will say something like: - * "when matching pointcut xyz when matching shadow sss when weaving type ABC when weaving shadow mungers" - */ -public class CompilationAndWeavingContext { - - private static int nextTokenId = 1; - - // unique constants for the different phases that can be registered - - // "FRONT END" - public static final int BATCH_BUILD = 0; - public static final int INCREMENTAL_BUILD = 1; - public static final int PROCESSING_COMPILATION_UNIT = 2; - public static final int RESOLVING_COMPILATION_UNIT = 3; - public static final int ANALYSING_COMPILATION_UNIT = 4; - public static final int GENERATING_UNWOVEN_CODE_FOR_COMPILATION_UNIT = 5; - public static final int COMPLETING_TYPE_BINDINGS = 6; - public static final int PROCESSING_DECLARE_PARENTS = 7; - public static final int CHECK_AND_SET_IMPORTS = 8; - public static final int CONNECTING_TYPE_HIERARCHY = 9; - public static final int BUILDING_FIELDS_AND_METHODS = 10; - public static final int COLLECTING_ITDS_AND_DECLARES = 11; - public static final int PROCESSING_DECLARE_ANNOTATIONS = 12; - public static final int WEAVING_INTERTYPE_DECLARATIONS = 13; - public static final int RESOLVING_POINTCUT_DECLARATIONS = 14; - public static final int ADDING_DECLARE_WARNINGS_AND_ERRORS = 15; - public static final int VALIDATING_AT_ASPECTJ_ANNOTATIONS = 16; - public static final int ACCESS_FOR_INLINE = 17; - public static final int ADDING_AT_ASPECTJ_ANNOTATIONS = 18; - public static final int FIXING_SUPER_CALLS_IN_ITDS = 19; - public static final int FIXING_SUPER_CALLS = 20; - public static final int OPTIMIZING_THIS_JOIN_POINT_CALLS = 21; - - // "BACK END" - - public static final int WEAVING = 22; - public static final int PROCESSING_REWEAVABLE_STATE = 23; - public static final int PROCESSING_TYPE_MUNGERS = 24; - public static final int WEAVING_ASPECTS = 25; - public static final int WEAVING_CLASSES = 26; - public static final int WEAVING_TYPE = 27; - public static final int MATCHING_SHADOW = 28; - public static final int IMPLEMENTING_ON_SHADOW = 29; - public static final int MATCHING_POINTCUT = 30; - public static final int MUNGING_WITH = 31; - public static final int PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY = 32; - - // phase names - public static final String[] PHASE_NAMES = new String[] { "batch building", "incrementally building", - "processing compilation unit", "resolving types defined in compilation unit", - "analysing types defined in compilation unit", "generating unwoven code for type defined in compilation unit", - "completing type bindings", "processing declare parents", "checking and setting imports", "connecting type hierarchy", - "building fields and methods", "collecting itds and declares", "processing declare annotations", - "weaving intertype declarations", "resolving pointcut declarations", "adding declare warning and errors", - "validating @AspectJ annotations", "creating accessors for inlining", "adding @AspectJ annotations", - "fixing super calls in ITDs in interface context", "fixing super calls in ITDs", - "optimizing thisJoinPoint calls", - - // BACK END - - "weaving", "processing reweavable state", "processing type mungers", "weaving aspects", "weaving classes", - "weaving type", "matching shadow", "implementing on shadow", "matching pointcut", "type munging with", - "type munging for @AspectJ aspectOf" }; - - // context stacks, one per thread - private static ThreadLocal> contextMap = new ThreadLocal>(); - - // single thread mode stack - private static Stack contextStack = new Stack(); - - // formatters, by phase id - private static Map formatterMap = new HashMap(); - - private static ContextFormatter defaultFormatter = new DefaultFormatter(); - - private static boolean multiThreaded = true; - - /** - * this is a static service - */ - private CompilationAndWeavingContext() { - } - - public static void reset() { - if (!multiThreaded) { - contextMap.remove(); - contextStack.clear(); - formatterMap.clear(); - nextTokenId = 1; - } else { - contextMap.remove(); - // TODO what about formatterMap? - // TODO what about nextTokenId? - } - } - - public static void setMultiThreaded(boolean mt) { - multiThreaded = mt; - } - - public static void registerFormatter(int phaseId, ContextFormatter aFormatter) { - formatterMap.put(new Integer(phaseId), aFormatter); - } - - /** - * Returns a string description of what the compiler/weaver is currently doing - */ - public static String getCurrentContext() { - Stack contextStack = getContextStack(); - Stack explanationStack = new Stack(); - for (ContextStackEntry entry : contextStack) { - Object data = entry.getData(); - if (data != null) { - explanationStack.push(getFormatter(entry).formatEntry(entry.phaseId, data)); - } - } - StringBuffer sb = new StringBuffer(); - while (!explanationStack.isEmpty()) { - sb.append("when "); - sb.append(explanationStack.pop().toString()); - sb.append("\n"); - } - return sb.toString(); - } - - public static ContextToken enteringPhase(int phaseId, Object data) { - Stack contextStack = getContextStack(); - ContextTokenImpl nextToken = nextToken(); - contextStack.push(new ContextStackEntry(nextToken, phaseId, new WeakReference(data))); - return nextToken; - } - - /** - * Exit a phase, all stack entries from the one with the given token down will be removed. - */ - public static void leavingPhase(ContextToken aToken) { - Stack contextStack = getContextStack(); - while (!contextStack.isEmpty()) { - ContextStackEntry entry = contextStack.pop(); - if (entry.contextToken == aToken) { - break; - } - } - } - - /** - * Forget about the context for the current thread - */ - public static void resetForThread() { - if (!multiThreaded) { - return; - } - contextMap.remove(); - } - - private static Stack getContextStack() { - if (!multiThreaded) { - return contextStack; - } else { - Stack contextStack = contextMap.get(); - if (contextStack == null) { - contextStack = new Stack(); - contextMap.set(contextStack); - } - return contextStack; - } - } - - private static ContextTokenImpl nextToken() { - return new ContextTokenImpl(nextTokenId++); - } - - private static ContextFormatter getFormatter(ContextStackEntry entry) { - Integer key = new Integer(entry.phaseId); - if (formatterMap.containsKey(key)) { - return formatterMap.get(key); - } else { - return defaultFormatter; - } - } - - private static class ContextTokenImpl implements ContextToken { - public int tokenId; - - public ContextTokenImpl(int id) { - this.tokenId = id; - } - } - - // dumb data structure - private static class ContextStackEntry { - public ContextTokenImpl contextToken; - public int phaseId; - private WeakReference dataRef; - - public ContextStackEntry(ContextTokenImpl ct, int phase, WeakReference data) { - this.contextToken = ct; - this.phaseId = phase; - this.dataRef = data; - } - - public Object getData() { - return dataRef.get(); - } - - public String toString() { - Object data = getData(); - if (data == null) { - return "referenced context entry has gone out of scope"; - } else { - return CompilationAndWeavingContext.getFormatter(this).formatEntry(phaseId, data); - } - } - } - - private static class DefaultFormatter implements ContextFormatter { - - public String formatEntry(int phaseId, Object data) { - StringBuffer sb = new StringBuffer(); - sb.append(PHASE_NAMES[phaseId]); - sb.append(" "); - if (data instanceof char[]) { - sb.append(new String((char[]) data)); - } else { - try { - sb.append(data.toString()); - } catch (RuntimeException ex) { - // don't lose vital info because of bad toString - sb.append("** broken toString in data object **"); - } - } - return sb.toString(); - } - - } -} diff --git a/bridge/src/org/aspectj/bridge/context/ContextFormatter.java b/bridge/src/org/aspectj/bridge/context/ContextFormatter.java deleted file mode 100644 index 9f1b591d7..000000000 --- a/bridge/src/org/aspectj/bridge/context/ContextFormatter.java +++ /dev/null @@ -1,21 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 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: - * Adrian Colyer Initial implementation - * ******************************************************************/ -package org.aspectj.bridge.context; - -/** - * @author colyer - * Implementors of this interface know how to turn the "Object" data and phase id - * associated with a context stack entry into a meaningful string. - */ -public interface ContextFormatter { - String formatEntry(int phaseId, Object data); -} diff --git a/bridge/src/org/aspectj/bridge/context/ContextToken.java b/bridge/src/org/aspectj/bridge/context/ContextToken.java deleted file mode 100644 index 2415fa72e..000000000 --- a/bridge/src/org/aspectj/bridge/context/ContextToken.java +++ /dev/null @@ -1,20 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 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: - * Adrian Colyer Initial implementation - * ******************************************************************/ -package org.aspectj.bridge.context; - -/** - * When an entry is added to the CompilationAndWeavingContext stack, - * a ContextToken is returned. - * When leaving a compilation or weaving phase, this token must be supplied. - * The token details are opaque to clients - */ -public interface ContextToken {} diff --git a/bridge/src/org/aspectj/bridge/context/PinpointingMessageHandler.java b/bridge/src/org/aspectj/bridge/context/PinpointingMessageHandler.java deleted file mode 100644 index c54ff6789..000000000 --- a/bridge/src/org/aspectj/bridge/context/PinpointingMessageHandler.java +++ /dev/null @@ -1,115 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 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: - * Adrian Colyer Initial implementation - * ******************************************************************/ -package org.aspectj.bridge.context; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.List; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.IMessage.Kind; - -/** - * @author colyer - * Facade for an IMessageHandler - * Extends message with details of exactly what the compiler / weaver was doing at the - * time. Use the -Xdev:Pinpoint option to turn this facility on. - */ -public class PinpointingMessageHandler implements IMessageHandler { - - private IMessageHandler delegate; - - public PinpointingMessageHandler(IMessageHandler delegate) { - this.delegate = delegate; - } - - /* (non-Javadoc) - * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage) - */ - public boolean handleMessage(IMessage message) throws AbortException { - if (!isIgnoring(message.getKind())) { - MessageIssued ex = new MessageIssued(); - ex.fillInStackTrace(); - StringWriter sw = new StringWriter(); - ex.printStackTrace(new PrintWriter(sw)); - StringBuffer sb = new StringBuffer(); - sb.append(CompilationAndWeavingContext.getCurrentContext()); - sb.append(sw.toString()); - IMessage pinpointedMessage = new PinpointedMessage(message,sb.toString()); - return delegate.handleMessage(pinpointedMessage); - } else { - return delegate.handleMessage(message); - } - } - - /* (non-Javadoc) - * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) - */ - public boolean isIgnoring(Kind kind) { - return delegate.isIgnoring(kind); - } - - /* (non-Javadoc) - * @see org.aspectj.bridge.IMessageHandler#dontIgnore(org.aspectj.bridge.IMessage.Kind) - */ - public void dontIgnore(Kind kind) { - delegate.dontIgnore(kind); - } - - - /* (non-Javadoc) - * @see org.aspectj.bridge.IMessageHandler#ignore(org.aspectj.bridge.IMessage.Kind) - */ - public void ignore(Kind kind) { - delegate.ignore(kind); - } - - private static class PinpointedMessage implements IMessage { - - private IMessage delegate; - private String message; - - public PinpointedMessage(IMessage delegate, String pinpoint) { - this.delegate = delegate; - this.message = delegate.getMessage() + "\n" + pinpoint; - } - - public String getMessage() { return this.message; } - public Kind getKind() { return delegate.getKind();} - public boolean isError() { return delegate.isError(); } - public boolean isWarning() { return delegate.isWarning();} - public boolean isDebug() { return delegate.isDebug();} - public boolean isInfo() { return delegate.isInfo();} - public boolean isAbort() { return delegate.isAbort();} - public boolean isTaskTag() { return delegate.isTaskTag();} - public boolean isFailed() { return delegate.isFailed();} - public boolean getDeclared() { return delegate.getDeclared(); } - public int getID() { return delegate.getID();} - public int getSourceStart() { return delegate.getSourceStart();} - public int getSourceEnd() { return delegate.getSourceEnd();} - public Throwable getThrown() { return delegate.getThrown();} - public ISourceLocation getSourceLocation() { return delegate.getSourceLocation();} - public String getDetails() { return delegate.getDetails();} - public List getExtraSourceLocations() { return delegate.getExtraSourceLocations();} - } - - private static class MessageIssued extends RuntimeException { - private static final long serialVersionUID = 1L; - - public String getMessage() { - return "message issued..."; - } - } -} diff --git a/bridge/src/test/java/org/aspectj/bridge/CountingMessageHandlerTest.java b/bridge/src/test/java/org/aspectj/bridge/CountingMessageHandlerTest.java new file mode 100644 index 000000000..dc357a8b1 --- /dev/null +++ b/bridge/src/test/java/org/aspectj/bridge/CountingMessageHandlerTest.java @@ -0,0 +1,82 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + + +import junit.framework.TestCase; +import junit.textui.TestRunner; + +/** + * + */ +public class CountingMessageHandlerTest extends TestCase { + + private static final String ME + = "org.aspectj.bridge.CountingMessageHandlerTest"; // XXX + + /** @param args ignored */ + public static void main(String[] args) { + TestRunner.main(new String[] {ME}); + } + + /** + * Constructor for MessageTest. + * @param name + */ + public CountingMessageHandlerTest(String name) { + super(name); + } + + public void testSimpleWrapping() { + MessageHandler m = new MessageHandler(); + CountingMessageHandler me = new CountingMessageHandler(m); + checkCountingMessageHandler(me); + } + + public void testCounterWrapping() { + MessageHandler m = new MessageHandler(); + CountingMessageHandler first = new CountingMessageHandler(m); + CountingMessageHandler me = new CountingMessageHandler(first); + checkCountingMessageHandler(me); + } + + void checkCountingMessageHandler(CountingMessageHandler me) { + MessageUtil.warn(me, "warn 1"); + assertTrue(!me.hasErrors()); + assertEquals(0 , me.numMessages(IMessage.ERROR, false)); + assertEquals(1 , me.numMessages(IMessage.WARNING, false)); + assertEquals(0 , me.numMessages(IMessage.INFO, false)); + assertEquals(0 , me.numMessages(IMessage.ERROR, true)); + assertEquals(1 , me.numMessages(IMessage.WARNING, true)); + assertEquals(1 , me.numMessages(IMessage.INFO, true)); + + MessageUtil.info(me, "info 1"); + assertTrue(!me.hasErrors()); + assertEquals(0 , me.numMessages(IMessage.ERROR, false)); + assertEquals(1 , me.numMessages(IMessage.WARNING, false)); + assertEquals(1 , me.numMessages(IMessage.INFO, false)); + assertEquals(0 , me.numMessages(IMessage.ERROR, true)); + assertEquals(1 , me.numMessages(IMessage.WARNING, true)); + assertEquals(2 , me.numMessages(IMessage.INFO, true)); + + MessageUtil.error(me, "error 1"); + assertTrue(me.hasErrors()); + assertEquals(1 , me.numMessages(IMessage.ERROR, false)); + assertEquals(1 , me.numMessages(IMessage.WARNING, false)); + assertEquals(1 , me.numMessages(IMessage.INFO, false)); + assertEquals(1 , me.numMessages(IMessage.ERROR, true)); + assertEquals(2 , me.numMessages(IMessage.WARNING, true)); + assertEquals(3 , me.numMessages(IMessage.INFO, true)); + } +} diff --git a/bridge/src/test/java/org/aspectj/bridge/MessageTest.java b/bridge/src/test/java/org/aspectj/bridge/MessageTest.java new file mode 100644 index 000000000..be30c48ba --- /dev/null +++ b/bridge/src/test/java/org/aspectj/bridge/MessageTest.java @@ -0,0 +1,321 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.io.File; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; +import junit.textui.TestRunner; + +/** + * + */ +public class MessageTest extends TestCase { + + private static final String ME + = "org.aspectj.bridge.MessageTest"; // XXX + + /** @param args ignored */ + public static void main(String[] args) { + TestRunner.main(new String[] {ME}); + } + + /** + * Constructor for MessageTest. + * @param name + */ + public MessageTest(String name) { + super(name); + } + + void checkListOrder(List list, Comparator c) { // XXX util + assertNotNull(list); + assertNotNull(c); + ListIterator it = list.listIterator(); + T last = null; + T current = null; + while (it.hasNext()) { + current = it.next(); + if (null != last) { + int i = c.compare(last, current); + if (i > 0) { + assertTrue( last + " > " + current + " (" + i + ")", false); + } + } + last = current; + } + } + + public void testKindOrder() { + // first briefly validate the checker + checkListOrder(Arrays.asList(new String[] { "a", "b", "C" }), + String.CASE_INSENSITIVE_ORDER); + checkListOrder(IMessage.KINDS, IMessage.Kind.COMPARATOR); + } + + public void testKind_isSameOrLessThan() { + IMessage.Kind last; + IMessage.Kind next = null; + for (Iterator iter = IMessage.KINDS.iterator(); iter.hasNext();) { + last = next; + next = iter.next(); + if (null == last) { + continue; + } + String label = "last: " + last + " next: " + next; + assertTrue(label, !next.isSameOrLessThan(null)); + assertTrue(label, !next.isSameOrLessThan(last)); + assertTrue(label, last.isSameOrLessThan(next)); + assertTrue(label, next.isSameOrLessThan(next)); + } + } + + public void testMessageHandler() { + boolean handleMessageResult = true; + checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult); + handleMessageResult = false; + checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult); + } + + public void checkEmptyMessageHolder( + IMessageHolder h, + final boolean handleMessageResult) { + // { INFO, DEBUG, WARNING, ERROR, FAIL, ABORT })); + assertNotNull(h); + assertTrue(!h.hasAnyMessage(null, true)); + assertTrue(!h.hasAnyMessage(null, false)); + assertTrue(!h.hasAnyMessage(IMessage.INFO, true)); + assertTrue(!h.hasAnyMessage(IMessage.INFO, false)); + + assertTrue(handleMessageResult == h.handleMessage(make("error 1", IMessage.ERROR))); + assertTrue(handleMessageResult == h.handleMessage(make("error 2", IMessage.ERROR))); + assertTrue(handleMessageResult == h.handleMessage(make("fail 1", IMessage.FAIL))); + assertTrue(handleMessageResult == h.handleMessage(make("fail 2", IMessage.FAIL))); + assertTrue(handleMessageResult == h.handleMessage(make("debug 1", IMessage.DEBUG))); + assertTrue(handleMessageResult == h.handleMessage(make("debug 2", IMessage.DEBUG))); + + assertTrue(h.hasAnyMessage(null, true)); + assertTrue(h.hasAnyMessage(null, false)); + assertTrue(h.hasAnyMessage(IMessage.ERROR, true)); + assertTrue(h.hasAnyMessage(IMessage.ERROR, false)); + assertTrue(h.hasAnyMessage(IMessage.FAIL, true)); + assertTrue(h.hasAnyMessage(IMessage.FAIL, false)); + assertTrue(h.hasAnyMessage(IMessage.DEBUG, true)); + assertTrue(h.hasAnyMessage(IMessage.DEBUG, false)); + + assertTrue(!h.hasAnyMessage(IMessage.INFO, IMessageHolder.EQUAL)); + assertTrue(!h.hasAnyMessage(IMessage.WARNING, IMessageHolder.EQUAL)); + assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.EQUAL)); + assertTrue(h.hasAnyMessage(IMessage.INFO, IMessageHolder.ORGREATER)); + assertTrue(h.hasAnyMessage(IMessage.WARNING, IMessageHolder.ORGREATER)); + assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.ORGREATER)); + + assertTrue(0 == h.numMessages(IMessage.INFO, IMessageHolder.EQUAL)); + assertTrue(0 == h.numMessages(IMessage.WARNING, IMessageHolder.EQUAL)); + assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.EQUAL)); + + assertTrue(6 == h.numMessages(null, IMessageHolder.ORGREATER)); + assertTrue(6 == h.numMessages(null, IMessageHolder.EQUAL)); + assertTrue(6 == h.numMessages(IMessage.INFO, IMessageHolder.ORGREATER)); + assertTrue(6 == h.numMessages(IMessage.DEBUG, IMessageHolder.ORGREATER)); + assertTrue(4 == h.numMessages(IMessage.WARNING, IMessageHolder.ORGREATER)); + assertTrue(4 == h.numMessages(IMessage.ERROR, IMessageHolder.ORGREATER)); + assertTrue(2 == h.numMessages(IMessage.FAIL, IMessageHolder.ORGREATER)); + assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.ORGREATER)); + + } + + public void testMessage() { + String input = "input"; + Throwable thrown = null; + ISourceLocation sl = null; + Class exClass = null; + String descriptor = "Message"; // for make(...) + IMessage.Kind kind = IMessage.INFO; + + // -- kind variants + roundTrip(input, kind, thrown, sl, descriptor, exClass); + kind = IMessage.WARNING; + roundTrip(input, kind, thrown, sl, descriptor, exClass); + kind = IMessage.ERROR; + roundTrip(input, kind, thrown, sl, descriptor, exClass); + kind = IMessage.DEBUG; + roundTrip(input, kind, thrown, sl, descriptor, exClass); + kind = IMessage.FAIL; + roundTrip(input, kind, thrown, sl, descriptor, exClass); + + // -- throwable + kind = IMessage.FAIL; + thrown = new AbortException(); + input = null; + roundTrip(input, kind, thrown, sl, descriptor, exClass); + + // -- source location + kind = IMessage.WARNING; + thrown = null; + input = "type not found"; + File f = new File("some/file.java"); // XXX unchecked + sl = new SourceLocation(f, 0, 0, 0); + roundTrip(input, kind, thrown, sl, descriptor, exClass); + sl = new SourceLocation(f, 1, 1, 0); + roundTrip(input, kind, thrown, sl, descriptor, exClass); + + // -- input error tests - null kind, null input (factory-dependent) + kind = null; + exClass = IllegalArgumentException.class; + roundTrip(input, kind, thrown, sl, descriptor, exClass); + input = null; + kind = IMessage.INFO; + roundTrip(input, kind, thrown, sl, descriptor, exClass); + } + + protected IMessage make(String message, IMessage.Kind kind) { + return new Message(message, kind, null, null); + } + + /** make a Message per descriptor and input */ + protected IMessage make(String input, IMessage.Kind kind, + Throwable thrown, ISourceLocation sourceLocation, + String descriptor) { // XXX ignored for now + return new Message(input, kind, thrown, sourceLocation); + } + + /** + * Simple round-trip on the message + */ + protected void roundTrip(String input, IMessage.Kind kind, + Throwable thrown, ISourceLocation sourceLocation, + String descriptor, Class exClass) { + try { + IMessage m = make(input, kind, thrown, sourceLocation, descriptor); + if ((null == input) && (null != thrown)) { + input = thrown.getMessage(); + } + roundTripCheck(m, input, kind, thrown, sourceLocation); + } catch (AssertionFailedError x) { + throw x; + } catch (Throwable t) { + assertTrue(null != exClass); + assertTrue(exClass.isAssignableFrom(t.getClass())); + } + } + + protected void roundTripCheck(IMessage message, String input, IMessage.Kind kind, + Throwable thrown, ISourceLocation sourceLocation) { + IMessage m = message; + assertTrue("not null", null != m); + assertEquals(input, m.getMessage()); + assertTrue(""+kind, kind == m.getKind()); + assertTrue(""+thrown, equals(thrown, m.getThrown())); + assertTrue(""+sourceLocation, + equals(sourceLocation, m.getSourceLocation())); + String err = new KindTest().testKindSet(message, kind); + if (null != err) { + assertTrue(err, false); + } + } + + protected static boolean equals(Object one, Object two) { + if (null == one) { + return (null == two); + } else if (null == two) { + return false; + } else { + return one.equals(two); + } + } +} + +/** test correlation between message and enclosed kind */ +class KindTest { + /** order tracked in checkKindMethods() */ + static final IMessage.Kind[] KINDS = new IMessage.Kind[] + { IMessage.ABORT, IMessage.DEBUG, IMessage.ERROR, + IMessage.INFO, IMessage.WARNING, IMessage.FAIL }; + + static final List KINDLIST = Arrays.asList(KINDS); + + /** used to clear instance BitSet */ + static final BitSet UNSET = new BitSet(KINDS.length); + + + final BitSet expected = new BitSet(KINDS.length); + IMessage.Kind kind = IMessage.INFO; + + /** @return error if failed */ + public String testKindSet(IMessage m, IMessage.Kind newKind) { + IMessage.Kind oldKind = this.kind; + String result = setKind(newKind); + if (null == result) { + result = checkKindSet(m, newKind); + } + if (null == result) { + result = checkExpectedKind(m); + } + return (null != result? result : setKind(oldKind)); + } + + /** @return error if failed */ + private String setKind(IMessage.Kind kind) { + this.kind = kind; + int index = KINDLIST.indexOf(kind); + if (-1 == index) { + return "unknown kind: " + kind; + } + expected.and(UNSET); + expected.set(index); + return null; + } + + /** @return error if failed */ + String checkExpectedKind(IMessage m) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < KINDS.length; i++) { + if (expected.get(i) != checkKindMethods(m, i)) { + String s = "expected " + expected.get(i) + + " for is{Method} for " + KINDS[i]; + result.append(s + "\n"); + } + } + return (0 < result.length() ? result.toString() : null); + } + + String checkKindSet(IMessage m, IMessage.Kind kind) { + if (kind != m.getKind()) { + return "expected kind " + kind + " got " + m.getKind(); + } + return null; + } + + /** @return true if index matches isFoo() reporting */ + boolean checkKindMethods(IMessage m, int index) { + switch (index) { + case (0) : return m.isAbort(); + case (1) : return m.isDebug(); + case (2) : return m.isError(); + case (3) : return m.isInfo(); + case (4) : return m.isWarning(); + case (5) : return m.isFailed(); + default : throw new IllegalArgumentException("index=" + index); + + } + } +} diff --git a/bridge/src/test/java/org/aspectj/bridge/VersionTest.java b/bridge/src/test/java/org/aspectj/bridge/VersionTest.java new file mode 100644 index 000000000..cee4c8450 --- /dev/null +++ b/bridge/src/test/java/org/aspectj/bridge/VersionTest.java @@ -0,0 +1,60 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +package org.aspectj.bridge; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.aspectj.util.LangUtil; + +import junit.framework.TestCase; +import junit.textui.TestRunner; + +/** + * + */ +public class VersionTest extends TestCase { + + private static final String ME = "org.aspectj.bridge.VersionTest"; + + /** @param args ignored */ + public static void main(String[] args) { + TestRunner.main(new String[] { ME }); + } + + /** + * Constructor for MessageTest. + * + * @param name + */ + public VersionTest(String name) { + super(name); + } + + public void testVersion() { + if (LangUtil.is11VMOrGreater()) { + return; + } + if (Version.time_text.equals("")) { + return; // dev build, we can only test this on the build server. + } + Date date = new Date(Version.getTime()); + SimpleDateFormat format = new SimpleDateFormat(Version.SIMPLE_DATE_FORMAT, Locale.getDefault()); + format.setTimeZone(TimeZone.getTimeZone("GMT")); + String timeString = format.format(date); + assertEquals(Version.time_text, timeString); + } +} diff --git a/bridge/src/test/java/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java b/bridge/src/test/java/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java new file mode 100644 index 000000000..825a52b61 --- /dev/null +++ b/bridge/src/test/java/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java @@ -0,0 +1,67 @@ +/* ******************************************************************* + * Copyright (c) 2005 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: + * Adrian Colyer Initial implementation + * ******************************************************************/ +package org.aspectj.bridge.context; + +import junit.framework.TestCase; + +/** + * @author colyer + * + */ +public class CompilationAndWeavingContextTest extends TestCase { + + public void testEnteringPhase() { + CompilationAndWeavingContext.enteringPhase(1,"XYZ"); + assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); + } + + public void testDoubleEntry() { + CompilationAndWeavingContext.enteringPhase(1,"XYZ"); + CompilationAndWeavingContext.enteringPhase(2, "ABC"); + assertEquals("when mucking about with ABC\nwhen fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); + } + + public void testEntryEntryExit() { + CompilationAndWeavingContext.enteringPhase(1,"XYZ"); + ContextToken ct = CompilationAndWeavingContext.enteringPhase(2, "ABC"); + CompilationAndWeavingContext.leavingPhase(ct); + assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); + } + + public void testEntryExitTop() { + ContextToken ct = CompilationAndWeavingContext.enteringPhase(1,"XYZ"); + CompilationAndWeavingContext.enteringPhase(2, "ABC"); + CompilationAndWeavingContext.leavingPhase(ct); + assertEquals("",CompilationAndWeavingContext.getCurrentContext()); + } + + + protected void setUp() throws Exception { + CompilationAndWeavingContext.reset(); + CompilationAndWeavingContext.registerFormatter(1, new MyContextFormatter("fiddling ")); + CompilationAndWeavingContext.registerFormatter(2, new MyContextFormatter("mucking about with ")); + } + + private static class MyContextFormatter implements ContextFormatter { + + private String prefix; + + public MyContextFormatter(String prefix) { + this.prefix = prefix; + } + + public String formatEntry(int phaseId, Object data) { + return prefix + data.toString(); + } + + } +} diff --git a/bridge/testsrc/org/aspectj/bridge/BridgeModuleTests.java b/bridge/testsrc/org/aspectj/bridge/BridgeModuleTests.java deleted file mode 100644 index 5811f987d..000000000 --- a/bridge/testsrc/org/aspectj/bridge/BridgeModuleTests.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.aspectj.bridge; -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -// default package - -import org.aspectj.bridge.context.CompilationAndWeavingContextTest; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public class BridgeModuleTests extends TestCase { - - public static Test suite() { - TestSuite suite = new TestSuite(BridgeModuleTests.class.getName()); - suite.addTest(org.aspectj.bridge.BridgeTests.suite()); - suite.addTestSuite(CompilationAndWeavingContextTest.class); - return suite; - } - - public BridgeModuleTests(String name) { super(name); } - -} diff --git a/bridge/testsrc/org/aspectj/bridge/BridgeTests.java b/bridge/testsrc/org/aspectj/bridge/BridgeTests.java deleted file mode 100644 index 5d0b1d0f8..000000000 --- a/bridge/testsrc/org/aspectj/bridge/BridgeTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.bridge; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public class BridgeTests extends TestCase { - - public static Test suite() { - TestSuite suite = new TestSuite(BridgeTests.class.getName()); - //$JUnit-BEGIN$ - suite.addTestSuite(CountingMessageHandlerTest.class); - suite.addTestSuite(MessageTest.class); - suite.addTestSuite(VersionTest.class); - //$JUnit-END$ - return suite; - } - - public BridgeTests(String name) { super(name); } - -} diff --git a/bridge/testsrc/org/aspectj/bridge/CountingMessageHandlerTest.java b/bridge/testsrc/org/aspectj/bridge/CountingMessageHandlerTest.java deleted file mode 100644 index dc357a8b1..000000000 --- a/bridge/testsrc/org/aspectj/bridge/CountingMessageHandlerTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - - -import junit.framework.TestCase; -import junit.textui.TestRunner; - -/** - * - */ -public class CountingMessageHandlerTest extends TestCase { - - private static final String ME - = "org.aspectj.bridge.CountingMessageHandlerTest"; // XXX - - /** @param args ignored */ - public static void main(String[] args) { - TestRunner.main(new String[] {ME}); - } - - /** - * Constructor for MessageTest. - * @param name - */ - public CountingMessageHandlerTest(String name) { - super(name); - } - - public void testSimpleWrapping() { - MessageHandler m = new MessageHandler(); - CountingMessageHandler me = new CountingMessageHandler(m); - checkCountingMessageHandler(me); - } - - public void testCounterWrapping() { - MessageHandler m = new MessageHandler(); - CountingMessageHandler first = new CountingMessageHandler(m); - CountingMessageHandler me = new CountingMessageHandler(first); - checkCountingMessageHandler(me); - } - - void checkCountingMessageHandler(CountingMessageHandler me) { - MessageUtil.warn(me, "warn 1"); - assertTrue(!me.hasErrors()); - assertEquals(0 , me.numMessages(IMessage.ERROR, false)); - assertEquals(1 , me.numMessages(IMessage.WARNING, false)); - assertEquals(0 , me.numMessages(IMessage.INFO, false)); - assertEquals(0 , me.numMessages(IMessage.ERROR, true)); - assertEquals(1 , me.numMessages(IMessage.WARNING, true)); - assertEquals(1 , me.numMessages(IMessage.INFO, true)); - - MessageUtil.info(me, "info 1"); - assertTrue(!me.hasErrors()); - assertEquals(0 , me.numMessages(IMessage.ERROR, false)); - assertEquals(1 , me.numMessages(IMessage.WARNING, false)); - assertEquals(1 , me.numMessages(IMessage.INFO, false)); - assertEquals(0 , me.numMessages(IMessage.ERROR, true)); - assertEquals(1 , me.numMessages(IMessage.WARNING, true)); - assertEquals(2 , me.numMessages(IMessage.INFO, true)); - - MessageUtil.error(me, "error 1"); - assertTrue(me.hasErrors()); - assertEquals(1 , me.numMessages(IMessage.ERROR, false)); - assertEquals(1 , me.numMessages(IMessage.WARNING, false)); - assertEquals(1 , me.numMessages(IMessage.INFO, false)); - assertEquals(1 , me.numMessages(IMessage.ERROR, true)); - assertEquals(2 , me.numMessages(IMessage.WARNING, true)); - assertEquals(3 , me.numMessages(IMessage.INFO, true)); - } -} diff --git a/bridge/testsrc/org/aspectj/bridge/MessageTest.java b/bridge/testsrc/org/aspectj/bridge/MessageTest.java deleted file mode 100644 index be30c48ba..000000000 --- a/bridge/testsrc/org/aspectj/bridge/MessageTest.java +++ /dev/null @@ -1,321 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.io.File; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; -import junit.textui.TestRunner; - -/** - * - */ -public class MessageTest extends TestCase { - - private static final String ME - = "org.aspectj.bridge.MessageTest"; // XXX - - /** @param args ignored */ - public static void main(String[] args) { - TestRunner.main(new String[] {ME}); - } - - /** - * Constructor for MessageTest. - * @param name - */ - public MessageTest(String name) { - super(name); - } - - void checkListOrder(List list, Comparator c) { // XXX util - assertNotNull(list); - assertNotNull(c); - ListIterator it = list.listIterator(); - T last = null; - T current = null; - while (it.hasNext()) { - current = it.next(); - if (null != last) { - int i = c.compare(last, current); - if (i > 0) { - assertTrue( last + " > " + current + " (" + i + ")", false); - } - } - last = current; - } - } - - public void testKindOrder() { - // first briefly validate the checker - checkListOrder(Arrays.asList(new String[] { "a", "b", "C" }), - String.CASE_INSENSITIVE_ORDER); - checkListOrder(IMessage.KINDS, IMessage.Kind.COMPARATOR); - } - - public void testKind_isSameOrLessThan() { - IMessage.Kind last; - IMessage.Kind next = null; - for (Iterator iter = IMessage.KINDS.iterator(); iter.hasNext();) { - last = next; - next = iter.next(); - if (null == last) { - continue; - } - String label = "last: " + last + " next: " + next; - assertTrue(label, !next.isSameOrLessThan(null)); - assertTrue(label, !next.isSameOrLessThan(last)); - assertTrue(label, last.isSameOrLessThan(next)); - assertTrue(label, next.isSameOrLessThan(next)); - } - } - - public void testMessageHandler() { - boolean handleMessageResult = true; - checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult); - handleMessageResult = false; - checkEmptyMessageHolder(new MessageHandler(handleMessageResult), handleMessageResult); - } - - public void checkEmptyMessageHolder( - IMessageHolder h, - final boolean handleMessageResult) { - // { INFO, DEBUG, WARNING, ERROR, FAIL, ABORT })); - assertNotNull(h); - assertTrue(!h.hasAnyMessage(null, true)); - assertTrue(!h.hasAnyMessage(null, false)); - assertTrue(!h.hasAnyMessage(IMessage.INFO, true)); - assertTrue(!h.hasAnyMessage(IMessage.INFO, false)); - - assertTrue(handleMessageResult == h.handleMessage(make("error 1", IMessage.ERROR))); - assertTrue(handleMessageResult == h.handleMessage(make("error 2", IMessage.ERROR))); - assertTrue(handleMessageResult == h.handleMessage(make("fail 1", IMessage.FAIL))); - assertTrue(handleMessageResult == h.handleMessage(make("fail 2", IMessage.FAIL))); - assertTrue(handleMessageResult == h.handleMessage(make("debug 1", IMessage.DEBUG))); - assertTrue(handleMessageResult == h.handleMessage(make("debug 2", IMessage.DEBUG))); - - assertTrue(h.hasAnyMessage(null, true)); - assertTrue(h.hasAnyMessage(null, false)); - assertTrue(h.hasAnyMessage(IMessage.ERROR, true)); - assertTrue(h.hasAnyMessage(IMessage.ERROR, false)); - assertTrue(h.hasAnyMessage(IMessage.FAIL, true)); - assertTrue(h.hasAnyMessage(IMessage.FAIL, false)); - assertTrue(h.hasAnyMessage(IMessage.DEBUG, true)); - assertTrue(h.hasAnyMessage(IMessage.DEBUG, false)); - - assertTrue(!h.hasAnyMessage(IMessage.INFO, IMessageHolder.EQUAL)); - assertTrue(!h.hasAnyMessage(IMessage.WARNING, IMessageHolder.EQUAL)); - assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.EQUAL)); - assertTrue(h.hasAnyMessage(IMessage.INFO, IMessageHolder.ORGREATER)); - assertTrue(h.hasAnyMessage(IMessage.WARNING, IMessageHolder.ORGREATER)); - assertTrue(!h.hasAnyMessage(IMessage.ABORT, IMessageHolder.ORGREATER)); - - assertTrue(0 == h.numMessages(IMessage.INFO, IMessageHolder.EQUAL)); - assertTrue(0 == h.numMessages(IMessage.WARNING, IMessageHolder.EQUAL)); - assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.EQUAL)); - - assertTrue(6 == h.numMessages(null, IMessageHolder.ORGREATER)); - assertTrue(6 == h.numMessages(null, IMessageHolder.EQUAL)); - assertTrue(6 == h.numMessages(IMessage.INFO, IMessageHolder.ORGREATER)); - assertTrue(6 == h.numMessages(IMessage.DEBUG, IMessageHolder.ORGREATER)); - assertTrue(4 == h.numMessages(IMessage.WARNING, IMessageHolder.ORGREATER)); - assertTrue(4 == h.numMessages(IMessage.ERROR, IMessageHolder.ORGREATER)); - assertTrue(2 == h.numMessages(IMessage.FAIL, IMessageHolder.ORGREATER)); - assertTrue(0 == h.numMessages(IMessage.ABORT, IMessageHolder.ORGREATER)); - - } - - public void testMessage() { - String input = "input"; - Throwable thrown = null; - ISourceLocation sl = null; - Class exClass = null; - String descriptor = "Message"; // for make(...) - IMessage.Kind kind = IMessage.INFO; - - // -- kind variants - roundTrip(input, kind, thrown, sl, descriptor, exClass); - kind = IMessage.WARNING; - roundTrip(input, kind, thrown, sl, descriptor, exClass); - kind = IMessage.ERROR; - roundTrip(input, kind, thrown, sl, descriptor, exClass); - kind = IMessage.DEBUG; - roundTrip(input, kind, thrown, sl, descriptor, exClass); - kind = IMessage.FAIL; - roundTrip(input, kind, thrown, sl, descriptor, exClass); - - // -- throwable - kind = IMessage.FAIL; - thrown = new AbortException(); - input = null; - roundTrip(input, kind, thrown, sl, descriptor, exClass); - - // -- source location - kind = IMessage.WARNING; - thrown = null; - input = "type not found"; - File f = new File("some/file.java"); // XXX unchecked - sl = new SourceLocation(f, 0, 0, 0); - roundTrip(input, kind, thrown, sl, descriptor, exClass); - sl = new SourceLocation(f, 1, 1, 0); - roundTrip(input, kind, thrown, sl, descriptor, exClass); - - // -- input error tests - null kind, null input (factory-dependent) - kind = null; - exClass = IllegalArgumentException.class; - roundTrip(input, kind, thrown, sl, descriptor, exClass); - input = null; - kind = IMessage.INFO; - roundTrip(input, kind, thrown, sl, descriptor, exClass); - } - - protected IMessage make(String message, IMessage.Kind kind) { - return new Message(message, kind, null, null); - } - - /** make a Message per descriptor and input */ - protected IMessage make(String input, IMessage.Kind kind, - Throwable thrown, ISourceLocation sourceLocation, - String descriptor) { // XXX ignored for now - return new Message(input, kind, thrown, sourceLocation); - } - - /** - * Simple round-trip on the message - */ - protected void roundTrip(String input, IMessage.Kind kind, - Throwable thrown, ISourceLocation sourceLocation, - String descriptor, Class exClass) { - try { - IMessage m = make(input, kind, thrown, sourceLocation, descriptor); - if ((null == input) && (null != thrown)) { - input = thrown.getMessage(); - } - roundTripCheck(m, input, kind, thrown, sourceLocation); - } catch (AssertionFailedError x) { - throw x; - } catch (Throwable t) { - assertTrue(null != exClass); - assertTrue(exClass.isAssignableFrom(t.getClass())); - } - } - - protected void roundTripCheck(IMessage message, String input, IMessage.Kind kind, - Throwable thrown, ISourceLocation sourceLocation) { - IMessage m = message; - assertTrue("not null", null != m); - assertEquals(input, m.getMessage()); - assertTrue(""+kind, kind == m.getKind()); - assertTrue(""+thrown, equals(thrown, m.getThrown())); - assertTrue(""+sourceLocation, - equals(sourceLocation, m.getSourceLocation())); - String err = new KindTest().testKindSet(message, kind); - if (null != err) { - assertTrue(err, false); - } - } - - protected static boolean equals(Object one, Object two) { - if (null == one) { - return (null == two); - } else if (null == two) { - return false; - } else { - return one.equals(two); - } - } -} - -/** test correlation between message and enclosed kind */ -class KindTest { - /** order tracked in checkKindMethods() */ - static final IMessage.Kind[] KINDS = new IMessage.Kind[] - { IMessage.ABORT, IMessage.DEBUG, IMessage.ERROR, - IMessage.INFO, IMessage.WARNING, IMessage.FAIL }; - - static final List KINDLIST = Arrays.asList(KINDS); - - /** used to clear instance BitSet */ - static final BitSet UNSET = new BitSet(KINDS.length); - - - final BitSet expected = new BitSet(KINDS.length); - IMessage.Kind kind = IMessage.INFO; - - /** @return error if failed */ - public String testKindSet(IMessage m, IMessage.Kind newKind) { - IMessage.Kind oldKind = this.kind; - String result = setKind(newKind); - if (null == result) { - result = checkKindSet(m, newKind); - } - if (null == result) { - result = checkExpectedKind(m); - } - return (null != result? result : setKind(oldKind)); - } - - /** @return error if failed */ - private String setKind(IMessage.Kind kind) { - this.kind = kind; - int index = KINDLIST.indexOf(kind); - if (-1 == index) { - return "unknown kind: " + kind; - } - expected.and(UNSET); - expected.set(index); - return null; - } - - /** @return error if failed */ - String checkExpectedKind(IMessage m) { - StringBuffer result = new StringBuffer(); - for (int i = 0; i < KINDS.length; i++) { - if (expected.get(i) != checkKindMethods(m, i)) { - String s = "expected " + expected.get(i) - + " for is{Method} for " + KINDS[i]; - result.append(s + "\n"); - } - } - return (0 < result.length() ? result.toString() : null); - } - - String checkKindSet(IMessage m, IMessage.Kind kind) { - if (kind != m.getKind()) { - return "expected kind " + kind + " got " + m.getKind(); - } - return null; - } - - /** @return true if index matches isFoo() reporting */ - boolean checkKindMethods(IMessage m, int index) { - switch (index) { - case (0) : return m.isAbort(); - case (1) : return m.isDebug(); - case (2) : return m.isError(); - case (3) : return m.isInfo(); - case (4) : return m.isWarning(); - case (5) : return m.isFailed(); - default : throw new IllegalArgumentException("index=" + index); - - } - } -} diff --git a/bridge/testsrc/org/aspectj/bridge/VersionTest.java b/bridge/testsrc/org/aspectj/bridge/VersionTest.java deleted file mode 100644 index cee4c8450..000000000 --- a/bridge/testsrc/org/aspectj/bridge/VersionTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.bridge; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; - -import org.aspectj.util.LangUtil; - -import junit.framework.TestCase; -import junit.textui.TestRunner; - -/** - * - */ -public class VersionTest extends TestCase { - - private static final String ME = "org.aspectj.bridge.VersionTest"; - - /** @param args ignored */ - public static void main(String[] args) { - TestRunner.main(new String[] { ME }); - } - - /** - * Constructor for MessageTest. - * - * @param name - */ - public VersionTest(String name) { - super(name); - } - - public void testVersion() { - if (LangUtil.is11VMOrGreater()) { - return; - } - if (Version.time_text.equals("")) { - return; // dev build, we can only test this on the build server. - } - Date date = new Date(Version.getTime()); - SimpleDateFormat format = new SimpleDateFormat(Version.SIMPLE_DATE_FORMAT, Locale.getDefault()); - format.setTimeZone(TimeZone.getTimeZone("GMT")); - String timeString = format.format(date); - assertEquals(Version.time_text, timeString); - } -} diff --git a/bridge/testsrc/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java b/bridge/testsrc/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java deleted file mode 100644 index 825a52b61..000000000 --- a/bridge/testsrc/org/aspectj/bridge/context/CompilationAndWeavingContextTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 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: - * Adrian Colyer Initial implementation - * ******************************************************************/ -package org.aspectj.bridge.context; - -import junit.framework.TestCase; - -/** - * @author colyer - * - */ -public class CompilationAndWeavingContextTest extends TestCase { - - public void testEnteringPhase() { - CompilationAndWeavingContext.enteringPhase(1,"XYZ"); - assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); - } - - public void testDoubleEntry() { - CompilationAndWeavingContext.enteringPhase(1,"XYZ"); - CompilationAndWeavingContext.enteringPhase(2, "ABC"); - assertEquals("when mucking about with ABC\nwhen fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); - } - - public void testEntryEntryExit() { - CompilationAndWeavingContext.enteringPhase(1,"XYZ"); - ContextToken ct = CompilationAndWeavingContext.enteringPhase(2, "ABC"); - CompilationAndWeavingContext.leavingPhase(ct); - assertEquals("when fiddling XYZ\n",CompilationAndWeavingContext.getCurrentContext()); - } - - public void testEntryExitTop() { - ContextToken ct = CompilationAndWeavingContext.enteringPhase(1,"XYZ"); - CompilationAndWeavingContext.enteringPhase(2, "ABC"); - CompilationAndWeavingContext.leavingPhase(ct); - assertEquals("",CompilationAndWeavingContext.getCurrentContext()); - } - - - protected void setUp() throws Exception { - CompilationAndWeavingContext.reset(); - CompilationAndWeavingContext.registerFormatter(1, new MyContextFormatter("fiddling ")); - CompilationAndWeavingContext.registerFormatter(2, new MyContextFormatter("mucking about with ")); - } - - private static class MyContextFormatter implements ContextFormatter { - - private String prefix; - - public MyContextFormatter(String prefix) { - this.prefix = prefix; - } - - public String formatEntry(int phaseId, Object data) { - return prefix + data.toString(); - } - - } -} -- cgit v1.2.3