diff options
author | avasseur <avasseur> | 2005-04-07 16:08:38 +0000 |
---|---|---|
committer | avasseur <avasseur> | 2005-04-07 16:08:38 +0000 |
commit | 7bd354830663965177f74b1057e2006d684dcd7c (patch) | |
tree | 2e352ef5fdd9e663d1b8eb804df75cb57524d48d | |
parent | b830696a0a306bcb8a1252d339f0423b27b2ad36 (diff) | |
download | aspectj-7bd354830663965177f74b1057e2006d684dcd7c.tar.gz aspectj-7bd354830663965177f74b1057e2006d684dcd7c.zip |
added LTW: modules loadtime and loadtime5
fix some build issues - some more left in deps handling
refactored IMessageHandler to support dontIgnore()
43 files changed, 1483 insertions, 53 deletions
diff --git a/aspectj5rt/build.xml b/aspectj5rt/build.xml index d90399216..054730025 100644 --- a/aspectj5rt/build.xml +++ b/aspectj5rt/build.xml @@ -18,9 +18,9 @@ <target name="compile" if="jdk15" depends="init, runtime.compile"> <!-- FIXME: we override compile due to use of java5-src instead of src.. and source/target attrs --> - <mkdir dir="${basedir}/bin"/> - <javac debug="on" destdir="${basedir}/bin" source="1.5" target="1.5"> - <src path="${basedir}/java5-src"/> + <mkdir dir="../aspectj5rt/bin"/> + <javac debug="on" destdir="../aspectj5rt/bin" source="1.5" target="1.5"> + <src path="../aspectj5rt/java5-src"/> <classpath refid="aspectj5rt.src.path"/> </javac> </target> diff --git a/bridge/src/org/aspectj/bridge/CountingMessageHandler.java b/bridge/src/org/aspectj/bridge/CountingMessageHandler.java index 3cdd7d482..d7ea4b9b9 100644 --- a/bridge/src/org/aspectj/bridge/CountingMessageHandler.java +++ b/bridge/src/org/aspectj/bridge/CountingMessageHandler.java @@ -140,4 +140,12 @@ public class CountingMessageHandler implements IMessageHandler { if (proxy != null) proxy.reset(); counters.clear(); } + + /** + * Not supported + * @param kind + */ + public void dontIgnore(IMessage.Kind kind) { + ; + } } diff --git a/bridge/src/org/aspectj/bridge/IMessageHandler.java b/bridge/src/org/aspectj/bridge/IMessageHandler.java index 76b76ec0b..03a584f7e 100644 --- a/bridge/src/org/aspectj/bridge/IMessageHandler.java +++ b/bridge/src/org/aspectj/bridge/IMessageHandler.java @@ -49,6 +49,9 @@ public interface IMessageHandler { public boolean isIgnoring(IMessage.Kind kind) { return false; } + public void dontIgnore(IMessage.Kind kind) { + ; + } }; /** @@ -66,4 +69,11 @@ public interface IMessageHandler { * @return true if this handler is ignoring all messages of this type */ boolean isIgnoring(IMessage.Kind kind); + + /** + * Allow fine grained configuration. This implementation does not ignore anything. + * @param kind + */ + void dontIgnore(IMessage.Kind kind); + } diff --git a/bridge/src/org/aspectj/bridge/MessageUtil.java b/bridge/src/org/aspectj/bridge/MessageUtil.java index 79250943e..436514a8c 100644 --- a/bridge/src/org/aspectj/bridge/MessageUtil.java +++ b/bridge/src/org/aspectj/bridge/MessageUtil.java @@ -358,6 +358,9 @@ public class MessageUtil { public boolean isIgnoring(Kind kind) { return false; } + public void dontIgnore(IMessage.Kind kind) { + ; + } }; return visitMessages(holder, selector, true, false); } @@ -584,6 +587,10 @@ public class MessageUtil { String text = message.getMessage(); return ((null != message) && (-1 != text.indexOf(infix))); } + + public void dontIgnore(IMessage.Kind kind) { + ; + } } // ------------------ components to render messages diff --git a/bridge/src/org/aspectj/bridge/MessageWriter.java b/bridge/src/org/aspectj/bridge/MessageWriter.java index 467002c3b..8e0e4d12f 100644 --- a/bridge/src/org/aspectj/bridge/MessageWriter.java +++ b/bridge/src/org/aspectj/bridge/MessageWriter.java @@ -52,7 +52,7 @@ public class MessageWriter implements IMessageHandler { } /** - * @see org.aspectj.bridge.IMessageHandler#isIgnoring(Kind) + * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) */ public boolean isIgnoring(IMessage.Kind kind) { // XXX share MessageHandler implementation in superclass @@ -64,4 +64,12 @@ public class MessageWriter implements IMessageHandler { return message.toString(); } + /** + * Override to allow fine grained configuration. This implementation does not ignore anything. + * @param kind + */ + public void dontIgnore(IMessage.Kind kind) { + ; + } + } diff --git a/build-common.xml b/build-common.xml index 02cac59a9..cad3a2e6b 100644 --- a/build-common.xml +++ b/build-common.xml @@ -72,7 +72,7 @@ <sequential> <echo message="compile ... @{project}"/> <mkdir dir="../@{project}/${build.dir}"/> - <javac debug="on" destdir="../@{project}/${build.dir}" source="1.2" target="1.1"> + <javac debug="on" destdir="../@{project}/${build.dir}" source="1.3" target="1.3"> <src path="../@{project}/${src.dir}"/> <classpath refid="@{path}"/> </javac> @@ -85,7 +85,7 @@ <sequential> <echo message="test:compile ... @{project}"/> <mkdir dir="../@{project}/${test.build.dir}"/> - <javac debug="on" destdir="../@{project}/${test.build.dir}" source="1.2" target="1.1"> + <javac debug="on" destdir="../@{project}/${test.build.dir}" source="1.3" target="1.3"> <src path="../@{project}/${test.src.dir}"/> <classpath refid="@{path}"/> <classpath path="../@{project}/${build.dir}"/> @@ -99,7 +99,7 @@ <attribute name="suite"/> <sequential> <!-- showoutput="on" --> - <junit showoutput="on" fork="on" haltonfailure="on" haltonerror="on" printsummary="on"> + <junit showoutput="on" fork="on" haltonfailure="on" haltonerror="on" printsummary="on" dir="../@{project}"> <classpath> <pathelement path="../@{project}/${build.dir}"/> <pathelement path="../@{project}/${test.build.dir}"/> @@ -23,7 +23,9 @@ testing-drivers/build.xml, ajdoc/build.xml, ajbrowser/build.xml, - tests/build.xml"/> + tests/build.xml, + loadtime/build.xml, + loadtime5/build.xml"/> </subant> </sequential> </macrodef> @@ -62,7 +64,9 @@ ajde/build.xml, taskdefs/build.xml, ajdoc/build.xml, - ajbrowser/build.xml"/> + ajbrowser/build.xml, + loadtime/build.xml, + loadtime5/build.xml"/> <!-- TODO av org.aspectj.lib --> </subant> <!-- FIXME av bcel-builder --> diff --git a/loadtime/build.xml b/loadtime/build.xml new file mode 100644 index 000000000..0ca5895ee --- /dev/null +++ b/loadtime/build.xml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<project name="loadtime" default="all" basedir="."> + + <import file="../build-common.xml"/> + <import file="../asm/build.xml"/> + <import file="../bridge/build.xml"/> + <import file="../util/build.xml"/> + <import file="../weaver/build.xml"/> + + + <path id="loadtime.test.src.path"> + <fileset dir="${basedir}/../lib"> + <include name="junit/*.jar"/> + </fileset> + <path refid="loadtime.src.path"/> + </path> + + <path id="loadtime.src.path"> + <pathelement path="../asm/bin"/> + <pathelement path="../bridge/bin"/> + <pathelement path="../util/bin"/> + <pathelement path="../weaver/bin"/> + <fileset dir="${basedir}/../lib"> + <include name="bcel/*.jar"/> + </fileset> + </path> + + <target name="compile" depends="init, + asm.compile, + bridge.compile, + util.compile, + weaver.compile"> + <srccompile project="loadtime" path="loadtime.src.path"/> + </target> + + <target name="test:compile" depends="compile"> + </target> + + <target name="test" depends="test:compile"> + </target> + + <target name="jar" depends="compile"> + <delete file="${build.ajdir}/jars/loadtime.jar"/> + <jar destfile="${build.ajdir}/jars/loadtime.jar"> + <fileset dir="bin"> + <include name="**/*"/> + </fileset> + </jar> + </target> + +</project> + diff --git a/loadtime/src/aspectj_1_5_0.dtd b/loadtime/src/aspectj_1_5_0.dtd new file mode 100644 index 000000000..2802dc879 --- /dev/null +++ b/loadtime/src/aspectj_1_5_0.dtd @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--***************************************************************************************************************************** + AspectJ 5 DTD + +To use this DTD, start your defintion file with + <!DOCTYPE aspectj PUBLIC + "-//AspectJ//DTD 1.5.0//EN" + "http://.../dtd/aspectj_1_5_0.dtd"> + +You can also use the "aliasing DTD" that matchs always the latest release of AspectJ +<!DOCTYPE aspectj PUBLIC + "-//AspectJ//DTD//EN" + "http://.../dtd/aspectj.dtd"> + +To not use this DTD, start your definition file with + <?xml version="1.0"?> + +******************************************************************************************************************************--> + + +<!--***************************************************************************************************************************** +aspectj +********************************************************************************************************************************* +[aspectj] defines the root element +******************************************************************************************************************************--> +<!ELEMENT aspectj ( + weaver?, + aspects? +)> +<!--***************************************************************************************************************************** +weaver +********************************************************************************************************************************* +[weaver] defines the weaver configuration +@options defines a command like line of option + When multiple aspectj DD are found, the options are simply toggled + TODO: Note: the scope of the options can be ClassLoader aware but should be assumed JVM wide +******************************************************************************************************************************--> +<!ELEMENT weaver ( + (include | exclude)* +)> +<!ATTLIST weaver + options CDATA #IMPLIED +> +<!--***************************************************************************************************************************** +include +********************************************************************************************************************************* +[include] narrows the scope of the weaver +A class must be matched by ALL the include elements to be exposed to the weaver +@within defines a type pattern + (it is not a startWith) +******************************************************************************************************************************--> +<!ELEMENT include EMPTY> +<!ATTLIST include + within CDATA #REQUIRED +> +<!--***************************************************************************************************************************** +exclude +********************************************************************************************************************************* +[exclude] narrows the scope of the weaver +A class must be matched by NONE of the exclude elements to be exposed to the weaver +@within defines a type pattern + (it is not a startWith) + TODO should it be called @from: "<exclude from=..> instead of <exclude within=..> + TODO: AND must be written that way and not with the "&&" symbol. Thus NOT and OR exists as well. +******************************************************************************************************************************--> +<!ELEMENT exclude EMPTY> +<!ATTLIST exclude + within CDATA #REQUIRED +> +<!--***************************************************************************************************************************** +aspects +********************************************************************************************************************************* +[aspects] defines a set of aspects +TODO we were about to use include but it is already used for weaver scope with "within" which is not relevant +for aspects. I (AV) decided to use only aspect and provide include= thru name, and exclude= as exclude. +see sample. +******************************************************************************************************************************--> +<!ELEMENT aspects ( + (aspect | exclude | concrete-aspect)* +)> +<!--***************************************************************************************************************************** +aspect +TODO: did not used include since already used in weaver/include@within and @within does not makes sense +********************************************************************************************************************************* +[aspect] defines an aspect to include + @name FQN of the aspect, nested class must use $ +******************************************************************************************************************************--> +<!ELEMENT aspect EMPTY> +<!ATTLIST aspect + name CDATA #REQUIRED +> +<!--***************************************************************************************************************************** +exclude +********************************************************************************************************************************* +[exclude] defines a set of aspect to exclude + @within within pattern (even from other systems / parent classloader) +SAME AS FOR weaver/exclude +******************************************************************************************************************************--> +<!--***************************************************************************************************************************** +concrete-aspect +********************************************************************************************************************************* +[concrete-aspect] defines a concrete aspect from an abstract one + @name FQN of the concrete aspect (use $ for nested class) [will be jit generated] + @extends FQN of the abstract aspect (use $ for nested class) +******************************************************************************************************************************--> +<!ELEMENT concrete-aspect ( + pointcut+ +)> +<!ATTLIST concrete-aspect + name CDATA #REQUIRED + extends CDATA #REQUIRED +> +<!--***************************************************************************************************************************** +pointcut +********************************************************************************************************************************* +[pointcut] defines a concrete pointcut within a concrete aspect from an abstract one + @name name of the abstract pointcut (method name, unique in aspect class hierarchy) + @expression pointcut expression + Note: for argument binding, the bounded arguments must be present and bounded: + <pointcut name="myAdvice(int i)" expression="... AND args(i)"/> + TODO: AND must be written that way and not with the "&&" symbol. Thus NOT and OR exists as well. +******************************************************************************************************************************--> +<!ELEMENT pointcut EMPTY> +<!ATTLIST pointcut + name CDATA #REQUIRED + expression CDATA #REQUIRED +> diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java new file mode 100644 index 000000000..20b03d28b --- /dev/null +++ b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package org.aspectj.weaver.loadtime; + +import org.aspectj.asm.IRelationship; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.Message; +import org.aspectj.weaver.ICrossReferenceHandler; +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWeaver; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.loadtime.definition.Definition; +import org.aspectj.weaver.loadtime.definition.DocumentParser; +import org.aspectj.weaver.tools.GeneratedClassHandler; +import org.aspectj.weaver.tools.WeavingAdaptor; + +import java.io.File; +import java.io.FileOutputStream; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * Adapter between the generic class pre processor interface and the AspectJ weaver + * Load time weaving consistency relies on Bcel.setRepository + * + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class Aj implements ClassPreProcessor { + + /** + * Initialization + */ + public void initialize() { + ; + } + + /** + * Weave + * + * @param className + * @param bytes + * @param loader + * @return + */ + public byte[] preProcess(String className, byte[] bytes, ClassLoader loader) { + //System.out.println("Aj.preProcess " + className + " @ " + loader + " " + Thread.currentThread()); + //TODO av needs to spec and doc that + //TODO av should skip org.aspectj as well unless done somewhere else + if (loader == null + || className == null) { + // skip boot loader or null classes (hibernate) + return bytes; + } + + try { + byte[] weaved = WeaverContainer.getWeaver(loader).weaveClass(className, bytes); + //TODO av make dump optionnal and configurable + __dump(className, weaved); + return weaved; + } catch (Throwable t) { + t.printStackTrace(); + return bytes; + } + } + + /** + * Cache of weaver + * There is one weaver per classloader + */ + static class WeaverContainer { + + private static Map weavingAdaptors = new WeakHashMap(); + + static WeavingAdaptor getWeaver(ClassLoader loader) { + synchronized (weavingAdaptors) { + WeavingAdaptor weavingAdaptor = (WeavingAdaptor) weavingAdaptors.get(loader); + if (weavingAdaptor == null) { + weavingAdaptor = new ClassLoaderWeavingAdaptor(loader); + weavingAdaptors.put(loader, weavingAdaptor); + } + return weavingAdaptor; + } + } + } + + /** + * Adaptor with the AspectJ WeavingAdaptor + */ + static class ClassLoaderWeavingAdaptor extends WeavingAdaptor { + + public ClassLoaderWeavingAdaptor(final ClassLoader loader) { + super(null);// at this stage we don't have yet a generatedClassHandler to define to the VM the closures + this.generatedClassHandler = new GeneratedClassHandler() { + /** + * Callback when we need to define a Closure in the JVM + * + * @param name + * @param bytes + */ + public void acceptClass(String name, byte[] bytes) { + //TODO av make dump configurable + try { + __dump(name, bytes); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + defineClass(loader, name, bytes);// could be done lazily using the hook + } + }; + + bcelWorld = new BcelWorld( + loader, messageHandler, new ICrossReferenceHandler() { + public void addCrossReference(ISourceLocation from, ISourceLocation to, IRelationship.Kind kind, boolean runtimeTest) { + ;// for tools only + } + } + ); + +// //TODO this AJ code will call +// //org.aspectj.apache.bcel.Repository.setRepository(this); +// //ie set some static things +// //==> bogus as Bcel is expected to be +// org.aspectj.apache.bcel.Repository.setRepository(new ClassLoaderRepository(loader)); + + weaver = new BcelWeaver(bcelWorld); + + // register the definitions + registerDefinitions(weaver, loader); + + // after adding aspects + weaver.prepareForWeave(); + } + } + + private static void defineClass(ClassLoader loader, String name, byte[] bytes) { + try { + //TODO av protection domain, and optimize + Method defineClass = ClassLoader.class.getDeclaredMethod( + "defineClass", new Class[]{ + String.class, bytes.getClass(), int.class, int.class + } + ); + defineClass.setAccessible(true); + defineClass.invoke( + loader, new Object[]{ + name, + bytes, + new Integer(0), + new Integer(bytes.length) + } + ); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + /** + * Dump the given bytcode in _dump/... + * + * @param name + * @param b + * @throws Throwable + */ + private static void __dump(String name, byte[] b) throws Throwable { + String className = name.replace('.', '/'); + final File dir; + if (className.indexOf('/') > 0) { + dir = new File("_dump" + File.separator + className.substring(0, className.lastIndexOf('/'))); + } else { + dir = new File("_dump"); + } + dir.mkdirs(); + String fileName = "_dump" + File.separator + className + ".class"; + FileOutputStream os = new FileOutputStream(fileName); + os.write(b); + os.close(); + } + + /** + * Load and cache the aop.xml/properties according to the classloader visibility rules + * + * @param weaver + * @param loader + */ + private static void registerDefinitions(final BcelWeaver weaver, final ClassLoader loader) { + try { + //TODO av underoptimized: we will parse each XML once per CL that see it + Enumeration xmls = loader.getResources("/META-INF/aop.xml"); + List definitions = new ArrayList(); + + //TODO av dev mode needed ? TBD -Daj5.def=... + if (loader != null && loader != ClassLoader.getSystemClassLoader().getParent()) { + String file = System.getProperty("aj5.def", null); + if (file != null) { + definitions.add(DocumentParser.parse((new File(file)).toURL())); + } + } + + while (xmls.hasMoreElements()) { + URL xml = (URL) xmls.nextElement(); + definitions.add(DocumentParser.parse(xml)); + } + registerOptions(weaver, loader, definitions); + registerAspects(weaver, loader, definitions); + registerFilters(weaver, loader, definitions); + } catch (Exception e) { + weaver.getWorld().getMessageHandler().handleMessage( + new Message("Register definition failed", IMessage.FAIL, e, null) + ); + } + } + + /** + * Configure the weaver according to the option directives + * TODO av - don't know if it is that good to reuse, since we only allow a small subset of options in LTW + * + * @param weaver + * @param loader + * @param definitions + */ + private static void registerOptions(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { + StringBuffer allOptions = new StringBuffer(); + for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { + Definition definition = (Definition) iterator.next(); + allOptions.append(definition.getWeaverOptions()).append(' '); + } + + Options.WeaverOption weaverOption = Options.parse(allOptions.toString(), loader); + + // configure the weaver and world + // AV - code duplicates AspectJBuilder.initWorldAndWeaver() + World world = weaver.getWorld(); + world.setMessageHandler(weaverOption.messageHandler); + world.setXlazyTjp(weaverOption.lazyTjp); + weaver.setReweavableMode(weaverOption.reWeavable, false); + world.setXnoInline(weaverOption.noInline); + world.setBehaveInJava5Way(weaverOption.java5); + //TODO proceedOnError option + } + + /** + * Register the aspect, following include / exclude rules + * + * @param weaver + * @param loader + * @param definitions + */ + private static void registerAspects(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { + //TODO: the exclude aspect allow to exclude aspect defined upper in the CL hierarchy - is it what we want ?? + // if not, review the getResource so that we track which resource is defined by which CL + + //it aspectClassNames + //exclude if in any of the exclude list + for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { + Definition definition = (Definition) iterator.next(); + for (Iterator aspects = definition.getAspectClassNames().iterator(); aspects.hasNext();) { + String aspectClassName = (String) aspects.next(); + if (!Definition.isAspectExcluded(aspectClassName, definitions)) { + weaver.addLibraryAspect(aspectClassName); + } + } + } + + //it concreteAspects + //exclude if in any of the exclude list + //TODO + } + + /** + * Register the include / exclude filters + * + * @param weaver + * @param loader + * @param definitions + */ + private static void registerFilters(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { + //TODO + ; + } +} diff --git a/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java b/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java new file mode 100644 index 000000000..0473cb75c --- /dev/null +++ b/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package org.aspectj.weaver.loadtime; + +/** + * Generic class pre processor interface that allows to separate the AspectJ 5 load time weaving + * from Java 5 JVMTI interfaces for further use on Java 1.3 / 1.4 + * + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public interface ClassPreProcessor { + + /** + * Post constructor initialization, usually empty + */ + void initialize(); + + /** + * Weave + * + * @param className + * @param bytes + * @param classLoader + * @return + */ + byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader); +}
\ No newline at end of file diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Options.java b/loadtime/src/org/aspectj/weaver/loadtime/Options.java new file mode 100644 index 000000000..d87f7460f --- /dev/null +++ b/loadtime/src/org/aspectj/weaver/loadtime/Options.java @@ -0,0 +1,161 @@ +/************************************************************************************** + * Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved. * + * http://aspectwerkz.codehaus.org * + * ---------------------------------------------------------------------------------- * + * The software in this package is published under the terms of the LGPL license * + * a copy of which has been included with this distribution in the license.txt file. * + **************************************************************************************/ +package org.aspectj.weaver.loadtime; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.Message; +import org.aspectj.util.LangUtil; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * A class that hanldes LTW options. + * Note: AV - I choosed to not reuse AjCompilerOptions and alike since those implies too many dependancies on + * jdt and ajdt modules. + * + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class Options { + + private static class DefaultMessageHandler implements IMessageHandler { + + boolean isVerbose = false; + boolean showWeaveInfo = false; + boolean showWarn = true; + + public boolean handleMessage(IMessage message) throws AbortException { + return SYSTEM_OUT.handleMessage(message); + } + + public boolean isIgnoring(IMessage.Kind kind) { + if (kind.equals(IMessage.WEAVEINFO)) { + return !showWeaveInfo; + } + if (kind.isSameOrLessThan(IMessage.INFO)) { + return !isVerbose; + } + return !showWarn; + } + + public void dontIgnore(IMessage.Kind kind) { + if (kind.equals(IMessage.WEAVEINFO)) { + showWeaveInfo = true; + } else if (kind.equals(IMessage.DEBUG)) { + isVerbose = true; + } else if (kind.equals(IMessage.WARNING)) { + showWarn = false; + } + } + } + + private final static String OPTION_15 = "-1.5"; + private final static String OPTION_lazyTjp = "-XlazyTjp"; + private final static String OPTION_noWarn = "-nowarn"; + private final static String OPTION_noWarnNone = "-warn:none"; + private final static String OPTION_proceedOnError = "-proceedOnError"; + private final static String OPTION_verbose = "-verbose"; + private final static String OPTION_reweavable = "-Xreweavable"; + private final static String OPTION_noinline = "-Xnoinline"; + private final static String OPTION_showWeaveInfo = "-showWeaveInfo"; + private final static String OPTIONVALUED_messageHolder = "-XmessageHolderClass:";//TODO rename to Handler + + //FIXME dump option - dump what - dump before/after ? + + public static WeaverOption parse(String options, ClassLoader laoder) { + // the first option wins + List flags = LangUtil.anySplit(options, " "); + Collections.reverse(flags); + + WeaverOption weaverOption = new WeaverOption(); + weaverOption.messageHandler = new DefaultMessageHandler();//default + + + // do a first round on the message handler since it will report the options themselves + for (Iterator iterator = flags.iterator(); iterator.hasNext();) { + String arg = (String) iterator.next(); + if (arg.startsWith(OPTIONVALUED_messageHolder)) { + if (arg.length() > OPTIONVALUED_messageHolder.length()) { + String handlerClass = arg.substring(OPTIONVALUED_messageHolder.length()).trim(); + try { + Class handler = Class.forName(handlerClass, false, laoder); + weaverOption.messageHandler = ((IMessageHandler) handler.newInstance()); + } catch (Throwable t) { + weaverOption.messageHandler.handleMessage( + new Message( + "Cannot instantiate message handler " + handlerClass, + IMessage.ERROR, + t, + null + ) + ); + } + } + } + } + + // configure the other options + for (Iterator iterator = flags.iterator(); iterator.hasNext();) { + String arg = (String) iterator.next(); + if (arg.equals(OPTION_15)) { + weaverOption.java5 = true; + } else if (arg.equalsIgnoreCase(OPTION_lazyTjp)) { + weaverOption.lazyTjp = true; + } else if (arg.equalsIgnoreCase(OPTION_noinline)) { + weaverOption.noInline = true; + } else if (arg.equalsIgnoreCase(OPTION_noWarn) || arg.equalsIgnoreCase(OPTION_noWarnNone)) { + weaverOption.noWarn = true; + } else if (arg.equalsIgnoreCase(OPTION_proceedOnError)) { + weaverOption.proceedOnError = true; + } else if (arg.equalsIgnoreCase(OPTION_reweavable)) { + weaverOption.reWeavable = true; + } else if (arg.equalsIgnoreCase(OPTION_showWeaveInfo)) { + weaverOption.showWeaveInfo = true; + } else if (arg.equalsIgnoreCase(OPTION_verbose)) { + weaverOption.verbose = true; + } else { + weaverOption.messageHandler.handleMessage( + new Message( + "Cannot configure weaver with option " + arg + ": unknown option", + IMessage.WARNING, + null, + null + ) + ); + } + } + + // refine message handler configuration + if (weaverOption.noWarn) { + weaverOption.messageHandler.dontIgnore(IMessage.WARNING); + } + if (weaverOption.verbose) { + weaverOption.messageHandler.dontIgnore(IMessage.DEBUG); + } + if (weaverOption.showWeaveInfo) { + weaverOption.messageHandler.dontIgnore(IMessage.WEAVEINFO); + } + + return weaverOption; + } + + public static class WeaverOption { + boolean java5; + boolean lazyTjp; + boolean noWarn; + boolean proceedOnError; + boolean verbose; + boolean reWeavable; + boolean noInline; + boolean showWeaveInfo; + IMessageHandler messageHandler; + } +} diff --git a/loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java b/loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java new file mode 100644 index 000000000..b4b6cee47 --- /dev/null +++ b/loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package org.aspectj.weaver.loadtime.definition; + +import java.util.List; +import java.util.ArrayList; + +/** + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class Definition { + + private StringBuffer m_weaverOptions; + + private List m_includePatterns; + + private List m_excludePatterns; + + private List m_aspectClassNames; + + private List m_aspectExcludePatterns; + + private List m_concreteAspects; + + public Definition() { + m_weaverOptions = new StringBuffer(); + m_includePatterns = new ArrayList(0); + m_excludePatterns = new ArrayList(0); + m_aspectClassNames = new ArrayList(); + m_aspectExcludePatterns = new ArrayList(0); + m_concreteAspects = new ArrayList(0); + } + + public String getWeaverOptions() { + return m_weaverOptions.toString(); + } + + public List getIncludePatterns() { + return m_includePatterns; + } + + public List getExcludePatterns() { + return m_excludePatterns; + } + + public List getAspectClassNames() { + return m_aspectClassNames; + } + + public List getAspectExcludePatterns() { + return m_aspectExcludePatterns; + } + + public List getConcreteAspects() { + return m_concreteAspects; + } + + public static class ConcreteAspect { + String name; + String extend; + List pointcuts; + + public ConcreteAspect(String name, String extend) { + this.name = name; + this.extend = extend; + this.pointcuts = new ArrayList(); + } + } + + public static class Pointcut { + String name; + String expression; + public Pointcut(String name, String expression) { + this.name = name; + this.expression = expression; + } + } + + public static boolean isAspectExcluded(String aspectClassName, List definitions) { + //TODO + return false; + } + + public void appendWeaverOptions(String option) { + m_weaverOptions.append(option.trim()).append(' '); + } + +} diff --git a/loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java b/loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java new file mode 100644 index 000000000..9d83b54b0 --- /dev/null +++ b/loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package org.aspectj.weaver.loadtime.definition; + +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.InputSource; +import org.xml.sax.Attributes; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.XMLReaderFactory; +import org.aspectj.weaver.loadtime.definition.Definition; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; +import java.net.URL; +import java.io.IOException; +import java.io.InputStream; +import java.io.File; + +/** + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class DocumentParser extends DefaultHandler { + + /** + * The current DTD public id. The matching dtd will be searched as a resource. + */ + private final static String DTD_PUBLIC_ID = "-//AspectJ//DTD 1.5.0//EN"; + + /** + * The DTD alias, for better user experience. + */ + private final static String DTD_PUBLIC_ID_ALIAS = "-//AspectJ//DTD//EN"; + + /** + * A handler to the DTD stream so that we are only using one file descriptor + */ + private final static InputStream DTD_STREAM = DocumentParser.class.getResourceAsStream("/aspectj_1_5_0.dtd"); + + private final static String ASPECTJ_ELEMENT = "aspectj"; + private final static String WEAVER_ELEMENT = "weaver"; + private final static String OPTIONS_ATTRIBUTE = "options"; + private final static String ASPECTS_ELEMENT = "aspects"; + private final static String ASPECT_ELEMENT = "aspect"; + private final static String CONCRETE_ASPECT_ELEMENT = "concrete-aspect"; + private final static String NAME_ATTRIBUTE = "name"; + private final static String EXTEND_ATTRIBUTE = "extends"; + private final static String POINTCUT_ELEMENT = "pointcut"; + private final static String EXPRESSION_ATTRIBUTE = "expression"; + + + private final Definition m_definition; + + private boolean m_inAspectJ; + + private Definition.ConcreteAspect m_lastConcreteAspect; + + private DocumentParser() { + m_definition = new Definition(); + } + + public static Definition parse(final URL url) throws Exception { + InputStream in = null; + try { + DocumentParser parser = new DocumentParser(); + + XMLReader xmlReader = XMLReaderFactory.createXMLReader(); + xmlReader.setEntityResolver(parser); + xmlReader.setContentHandler(parser); + //TODO use a locator for error location reporting ? + + try { + if (xmlReader.getFeature("http://xml.org/sax/features/validation")) { + xmlReader.setFeature("http://xml.org/sax/features/validation", false); + } +// xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); +// xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + } + catch (SAXNotRecognizedException e) { + ;//fine, the parser don't do validation + } + + in = url.openStream(); + xmlReader.parse(new InputSource(in)); + return parser.m_definition; + } finally { + try {in.close();} catch (Throwable t) {;} + } + } + + public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException { + if (publicId.equals(DTD_PUBLIC_ID) || publicId.equals(DTD_PUBLIC_ID_ALIAS)) { + InputStream in = DTD_STREAM; + if (in == null) { +// System.err.println("AspectJ - WARN - could not open DTD"); + return null; + } else { + return new InputSource(in); + } + } else { +// System.err.println( +// "AspectJ - WARN - deprecated DTD " +// + publicId +// + " - consider upgrading to " +// + DTD_PUBLIC_ID +// ); + return null;//new InputSource(); + } + } + + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (ASPECT_ELEMENT.equals(qName)) { + String name = attributes.getValue(NAME_ATTRIBUTE); + if (!isNull(name)) { + m_definition.getAspectClassNames().add(name); + } + } else if (WEAVER_ELEMENT.equals(qName)) { + String options = attributes.getValue(OPTIONS_ATTRIBUTE); + if (!isNull(options)) { + m_definition.appendWeaverOptions(options); + } + } else if (CONCRETE_ASPECT_ELEMENT.equals(qName)) { + String name = attributes.getValue(NAME_ATTRIBUTE); + String extend = attributes.getValue(EXTEND_ATTRIBUTE); + if (!isNull(name) && !isNull(extend)) { + m_lastConcreteAspect = new Definition.ConcreteAspect(name, extend); + m_definition.getConcreteAspects().add(m_lastConcreteAspect); + } + } else if (POINTCUT_ELEMENT.equals(qName) && m_lastConcreteAspect != null) { + String name = attributes.getValue(NAME_ATTRIBUTE); + String expression = attributes.getValue(EXPRESSION_ATTRIBUTE); + if (!isNull(name) && !isNull(expression)) { + m_lastConcreteAspect.pointcuts.add(new Definition.Pointcut(name, replaceXmlAnd(expression))); + } + } else if (ASPECTJ_ELEMENT.equals(qName)) { + if (m_inAspectJ) { + throw new SAXException("Found nested <aspectj> element"); + } + m_inAspectJ = true; + } else if (ASPECTS_ELEMENT.equals(qName)) { + ;//nothing to do + } else { + throw new SAXException("Unknown element while parsing <aspectj> element: " + qName); + } + //TODO include / exclude + super.startElement(uri, localName, qName, attributes); + } + + public void endElement(String uri, String localName, String qName) throws SAXException { + if (CONCRETE_ASPECT_ELEMENT.equals(qName)) { + m_lastConcreteAspect = null; + } else if (ASPECTJ_ELEMENT.equals(qName)) { + m_inAspectJ = false; + } + super.endElement(uri, localName, qName); + } + + public void warning(SAXParseException e) throws SAXException { + super.warning(e); + } + + public void error(SAXParseException e) throws SAXException { + super.error(e); + } + + public void fatalError(SAXParseException e) throws SAXException { + super.fatalError(e); + } + + + + private static String replaceXmlAnd(String expression) { + //TODO av do we need to handle "..)AND" or "AND(.." ? + //FIXME av Java 1.4 code - if KO, use some Strings util + return expression.replaceAll(" AND ", " && "); + } + + public static void main(String args[]) throws Throwable { + Definition def = parse(new File(args[0]).toURL()); + System.out.println(def); + } + + private boolean isNull(String s) { + return (s == null || s.length() <= 0); + } + +} diff --git a/loadtime5/build.xml b/loadtime5/build.xml new file mode 100644 index 000000000..c35162cdc --- /dev/null +++ b/loadtime5/build.xml @@ -0,0 +1,84 @@ +<?xml version="1.0"?> +<project name="loadtime5" default="all" basedir="."> + + <import file="../build-common.xml"/> + <import file="../asm/build.xml"/> + <import file="../bridge/build.xml"/> + <import file="../loadtime/build.xml"/> + <import file="../weaver/build.xml"/> + <import file="../util/build.xml"/> + <import file="../runtime/build.xml/"/> + <import file="../aspectj5rt/build.xml"/> + + + + <path id="loadtime5.test.src.path"> + <fileset dir="${basedir}/../lib"> + <include name="junit/*.jar"/> + </fileset> + <path refid="loadtime5.src.path"/> + <pathelement path="../runtime/bin"/> + <pathelement path="../aspectj5rt/bin"/> + <pathelement path="../util/bin"/> + </path> + + <path id="loadtime5.src.path"> + <pathelement path="../asm/bin"/> + <pathelement path="../bridge/bin"/> + <pathelement path="../loadtime/bin"/> + <pathelement path="../weaver/bin"/> + <fileset dir="${basedir}/../lib"> + <include name="bcel/*.jar"/> + </fileset> + </path> + + <target name="compile" depends="init, + asm.compile, + bridge.compile, + loadtime.compile, + weaver.compile" if="jdk15"> + <!-- FIXME: we override compile due to use of 1.5 --> + <mkdir dir="${basedir}/bin"/> + <javac debug="on" destdir="${basedir}/bin" source="1.5" target="1.5"> + <src path="${basedir}/src"/> + <classpath refid="loadtime5.src.path"/> + </javac> + </target> + + <target name="test:compile" depends="compile" if="jdk15"> + <!-- FIXME sucky deps --> + <antcall target="runtime.compile"/> + <antcall target="aspectj5rt.compile"/> + <!-- FIXME: we override compile due to use of 1.5 --> + <mkdir dir="${basedir}/bintest"/> + <javac debug="on" destdir="${basedir}/bintest" source="1.5" target="1.5"> + <src path="${basedir}/testsrc"/> + <classpath refid="loadtime5.test.src.path"/> + </javac> + </target> + + <target name="test" depends="test:compile, jar" if="jdk15"> + <!-- FIXME sucky deps --> + <antcall target="util.compile"/> + + <java fork="true" classname="org.aspectj.weaver.loadtime5.test.AllTests"> + <jvmarg line="-javaagent:${build.ajdir}/jars/loadtime5.jar -Daj5.def=../loadtime5/testsrc/aop.xml"/> + <classpath refid="loadtime5.test.src.path"/> + <classpath> + <pathelement path="${basedir}/bintest"/> + </classpath> + </java> + </target> + + <target name="jar" depends="compile"> + <delete file="${build.ajdir}/jars/loadtime5.jar"/> + <copy file="loadtime5.mf.txt" todir="${build.ajdir}/temp" filtering="yes"/> + <jar destfile="${build.ajdir}/jars/loadtime5.jar" manifest="${build.ajdir}/temp/loadtime5.mf.txt"> + <fileset dir="bin"> + <include name="**/*"/> + </fileset> + </jar> + </target> + +</project> + diff --git a/loadtime5/loadtime5.mf.txt b/loadtime5/loadtime5.mf.txt new file mode 100644 index 000000000..fa19c87cc --- /dev/null +++ b/loadtime5/loadtime5.mf.txt @@ -0,0 +1,2 @@ +Premain-Class: org.aspectj.weaver.loadtime.Agent +Can-Redefine-Classes: true diff --git a/loadtime5/src/org/aspectj/weaver/loadtime/Agent.java b/loadtime5/src/org/aspectj/weaver/loadtime/Agent.java new file mode 100644 index 000000000..1444a1d12 --- /dev/null +++ b/loadtime5/src/org/aspectj/weaver/loadtime/Agent.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package org.aspectj.weaver.loadtime; + +import java.lang.instrument.Instrumentation; +import java.lang.instrument.ClassFileTransformer; + +/** + * Java 1.5 preMain agent to hook in the class pre processor + * Can be used with -javaagent:aspectjweaver.jar + * + * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a> + */ +public class Agent { + + /** + * The instrumentation instance + */ + private static Instrumentation s_instrumentation; + + /** + * The ClassFileTransformer wrapping the weaver + */ + private static ClassFileTransformer s_transformer = new ClassPreProcessorAgentAdapter(); + + /** + * JSR-163 preMain Agent entry method + * + * @param options + * @param instrumentation + */ + public static void premain(String options, Instrumentation instrumentation) { + s_instrumentation = instrumentation; + s_instrumentation.addTransformer(s_transformer); + } + + /** + * Returns the Instrumentation system level instance + */ + public static Instrumentation getInstrumentation() { + if (s_instrumentation == null) { + throw new UnsupportedOperationException("Java 5 was not started with preMain -javaagent for AspectJ"); + } + return s_instrumentation; + } + +} diff --git a/loadtime5/src/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java b/loadtime5/src/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java new file mode 100644 index 000000000..a8b915aca --- /dev/null +++ b/loadtime5/src/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package org.aspectj.weaver.loadtime; + +import org.aspectj.weaver.loadtime.Aj; +import org.aspectj.weaver.loadtime.ClassPreProcessor; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; + +/** + * Java 1.5 adapter for class pre processor + * + * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a> + */ +public class ClassPreProcessorAgentAdapter implements ClassFileTransformer { + + /** + * Concrete preprocessor. + */ + private static ClassPreProcessor s_preProcessor; + + static { + try { + s_preProcessor = new Aj(); + s_preProcessor.initialize(); + } catch (Exception e) { + throw new ExceptionInInitializerError("could not initialize JSR163 preprocessor due to: " + e.toString()); + } + } + + /** + * Weaving delegation + * + * @param loader the defining class loader + * @param className the name of class beeing loaded + * @param classBeingRedefined when hotswap is called + * @param protectionDomain + * @param bytes the bytecode before weaving + * @return the weaved bytecode + */ + public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, + ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { + if (classBeingRedefined == null) { + return s_preProcessor.preProcess(className, bytes, loader); + } else { + //FIXME av for now we skip hotswap. We should think more about that + new Exception("AspectJ5 does not weave hotswapped class (" + className + ")").printStackTrace(); + return bytes; + } + } + +} diff --git a/loadtime5/testsrc/aop.xml b/loadtime5/testsrc/aop.xml new file mode 100644 index 000000000..75266141d --- /dev/null +++ b/loadtime5/testsrc/aop.xml @@ -0,0 +1,11 @@ +<!-- FIXME fails when DTD here and call from Ant--> +<!--<!DOCTYPE aspectj PUBLIC--> +<!-- "-//AspectJ//DTD//EN"--> +<!-- "http://www.aspectj.org/dtd/aspectj_1_5_0.dtd">--> +<aspectj> + <weaver options="-showWeaveInfo"/> + <aspects> + <!-- see here nested class with ".", "$" is accepted as well --> + <aspect name="test.loadtime5.AtAspectJTest.TestAspect"/> + </aspects> +</aspectj> diff --git a/loadtime5/testsrc/org/aspectj/weaver/loadtime5/test/AllTests.java b/loadtime5/testsrc/org/aspectj/weaver/loadtime5/test/AllTests.java new file mode 100644 index 000000000..88ecc8c2e --- /dev/null +++ b/loadtime5/testsrc/org/aspectj/weaver/loadtime5/test/AllTests.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package org.aspectj.weaver.loadtime5.test; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import test.loadtime5.AtAspectJTest; + +/** + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class AllTests extends TestCase { + public static Test suite() { + TestSuite suite = new TestSuite("All tests"); + + suite.addTestSuite(AtAspectJTest.class); + +// suite.addTestSuite(SingletonAspectBindingsTest.class); +// suite.addTestSuite(CflowTest.class); +// suite.addTestSuite(PointcutReferenceTest.class); +// suite.addTestSuite(AfterXTest.class); +// +// //FIXME AV - fix the pc grammar to support if for @AJ aspects +// System.err.println("(AllTests: IfPointcutTest fails)"); +// //suite.addTestSuite(IfPointcutTest.class); +// +// suite.addTestSuite(XXJoinPointTest.class); +// suite.addTestSuite(PrecedenceTest.class); +// suite.addTestSuite(BindingTest.class); +// +// suite.addTestSuite(PerClauseTest.class); + + return suite; + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + +} diff --git a/loadtime5/testsrc/test/loadtime5/AtAspectJTest.java b/loadtime5/testsrc/test/loadtime5/AtAspectJTest.java new file mode 100644 index 000000000..6f34aa2c4 --- /dev/null +++ b/loadtime5/testsrc/test/loadtime5/AtAspectJTest.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) Jonas Bon�r, Alexandre Vasseur + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + *******************************************************************************/ +package test.loadtime5; + +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import junit.framework.TestCase; +import junit.textui.TestRunner; + +/** + * Test various advice and JoinPoint + binding, without pc ref + * + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class AtAspectJTest extends TestCase { + + static StringBuffer s_log = new StringBuffer(); + static void log(String s) { + s_log.append(s).append(" "); + } + + public static void main(String[] args) { + TestRunner.run(AtAspectJTest.class); + } + + public static junit.framework.Test suite() { + return new junit.framework.TestSuite(AtAspectJTest.class); + } + + public void hello() { + log("hello"); + } + + public void hello(String s) { + log("hello-"); + log(s); + } + + public void testExecutionWithThisBinding() { + s_log = new StringBuffer(); + AtAspectJTest me = new AtAspectJTest(); + me.hello(); + // see here advice precedence as in source code order + //TODO check around relative order + // see fix in BcelWeaver sorting shadowMungerList + //assertEquals("around2_ around_ before hello after _around _around2 ", s_log.toString()); + assertEquals("around_ around2_ before hello _around2 _around after ", s_log.toString()); + } + + public void testExecutionWithArgBinding() { + s_log = new StringBuffer(); + AtAspectJTest me = new AtAspectJTest(); + me.hello("x"); + assertEquals("before- x hello- x ", s_log.toString()); + } + + + @Aspect + public static class TestAspect { + + static int s = 0; + + static { + s++; + } + + public TestAspect() { + // assert clinit has run when singleton aspectOf reaches that + assertTrue(s>0); + } + + //public static TestAspect aspectOf() {return null;} + + @Around("execution(* test.loadtime5.AtAspectJTest.hello())") + public void aaround(ProceedingJoinPoint jp) { + log("around_"); + try { + jp.proceed(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + log("_around"); + } + + @Around("execution(* test.loadtime5.AtAspectJTest.hello()) && this(t)") + public void around2(ProceedingJoinPoint jp, Object t) { + log("around2_"); + assertEquals(AtAspectJTest.class.getName(), t.getClass().getName()); + try { + jp.proceed(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + log("_around2"); + } + + @Before("execution(* test.loadtime5.AtAspectJTest.hello())") + public void before(JoinPoint.StaticPart sjp) { + log("before"); + assertEquals("hello", sjp.getSignature().getName()); + } + + @After("execution(* test.loadtime5.AtAspectJTest.hello())") + public void after(JoinPoint.StaticPart sjp) { + log("after"); + assertEquals("execution(public void test.loadtime5.AtAspectJTest.hello())", sjp.toLongString()); + } + + //TODO see String alias, see before advice name clash - all that works + // 1/ String is in java.lang.* - see SimpleScope.javalangPrefix array + // 2/ the advice is register thru its Bcel Method mirror + @Before("execution(* test.loadtime5.AtAspectJTest.hello(String)) && args(s)") + public void before(String s, JoinPoint.StaticPart sjp) { + log("before-"); + log(s); + assertEquals("hello", sjp.getSignature().getName()); + } + + } +} diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverMessageHandler.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverMessageHandler.java index a7c9bc056..22cdcb774 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverMessageHandler.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverMessageHandler.java @@ -120,7 +120,11 @@ public class WeaverMessageHandler implements IMessageHandler { public boolean isIgnoring(Kind kind) { return sink.isIgnoring(kind); } - + + public void dontIgnore(IMessage.Kind kind) { + ; + } + private int getStartPos(ISourceLocation sLoc,CompilationResult result) { int pos = 0; if (sLoc == null) return 0; diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java index 12ca5f606..b5c864019 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java @@ -411,28 +411,7 @@ public class AjBuildConfig { public void setLintMode(String lintMode) { this.lintMode = lintMode; - String lintValue = null; - if (AJLINT_IGNORE.equals(lintMode)) { - lintValue = AjCompilerOptions.IGNORE; - } else if (AJLINT_WARN.equals(lintMode)) { - lintValue = AjCompilerOptions.WARNING; - } else if (AJLINT_ERROR.equals(lintMode)) { - lintValue = AjCompilerOptions.ERROR; - } - - if (lintValue != null) { - Map lintOptions = new HashMap(); - lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportUnresolvableMember,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportShadowNotInStructure,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField,lintValue); - lintOptions.put(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion,lintValue); - options.set(lintOptions); - } + options.setLintMode(lintMode); } public boolean isNoWeave() { diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java index 8553ed9df..8b8587fe5 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java @@ -14,6 +14,7 @@ package org.aspectj.ajdt.internal.core.builder; import java.util.Map; +import java.util.HashMap; import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; @@ -122,7 +123,33 @@ public class AjCompilerOptions extends CompilerOptions { return map; } - + + public void setLintMode(String lintMode) { + String lintValue = null; + if (AjBuildConfig.AJLINT_IGNORE.equals(lintMode)) { + lintValue = AjCompilerOptions.IGNORE; + } else if (AjBuildConfig.AJLINT_WARN.equals(lintMode)) { + lintValue = AjCompilerOptions.WARNING; + } else if (AjBuildConfig.AJLINT_ERROR.equals(lintMode)) { + lintValue = AjCompilerOptions.ERROR; + } + + if (lintValue != null) { + Map lintOptions = new HashMap(); + lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportUnresolvableMember,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportShadowNotInStructure,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField,lintValue); + lintOptions.put(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion,lintValue); + set(lintOptions); + } + } + + /* (non-Javadoc) * @see org.eclipse.jdt.internal.compiler.impl.CompilerOptions#set(java.util.Map) */ diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java index b91aed439..04f09230c 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java @@ -228,7 +228,11 @@ public class AspectJBuilder extends JavaBuilder implements ICompilerAdapterFacto if (kind == IMessage.DEBUG || kind == IMessage.INFO) return true; return false; } - + + public void dontIgnore(IMessage.Kind kind) { + ; + } + } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java index 0cfa6103f..96ffd66cf 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java @@ -455,7 +455,11 @@ public class Main { } return false; } - + + public void dontIgnore(IMessage.Kind kind) { + ; + } + /** * Render message differently. * If abort, then prefix stack trace with feedback request. diff --git a/testing-client/testsrc/org/aspectj/testing/TesterTest.java b/testing-client/testsrc/org/aspectj/testing/TesterTest.java index 5acce235d..4ed67cac4 100644 --- a/testing-client/testsrc/org/aspectj/testing/TesterTest.java +++ b/testing-client/testsrc/org/aspectj/testing/TesterTest.java @@ -202,7 +202,11 @@ public class TesterTest extends TestCase { public boolean isIgnoring(IMessage.Kind kind) { return false; } - + + public void dontIgnore(IMessage.Kind kind) { + ; + } + public boolean handleMessage(IMessage message) { (message.isFailed() ? failures : passes).add(message); return true; diff --git a/testing-util/build.xml b/testing-util/build.xml index 9b15730c8..82d2e12ea 100644 --- a/testing-util/build.xml +++ b/testing-util/build.xml @@ -4,11 +4,17 @@ <import file="../build-common.xml"/> <import file="../bridge/build.xml"/> <import file="../util/build.xml"/> + <import file="../runtime/build.xml"/> + <path id="testing-util.test.src.path"> <fileset dir="${basedir}/../lib"> <include name="junit/*.jar"/> + <include name="bcel/*.jar"/> </fileset> + <!-- depends on weaver to use Dissasemble feature on LazyClassGen to test comparison of .class file --> + <pathelement path="../weaver/bin"/> + <pathelement path="../runtime/bin"/> <path refid="testing-util.src.path"/> </path> @@ -30,8 +36,10 @@ <testcompile project="testing-util" path="testing-util.test.src.path"/> </target> - <!-- FIXME: seems to depend on weaver, seems to emit warnings --> - <target name="test" depends="test:compile"> + <target name="test" depends="test:compile, + runtime.compile"> + <!-- depends on weaver to access .class dissassemble utility hence circular --> + <subant antfile="build.xml" target="test:compile" buildpath="../weaver" /> <testrun project="testing-util" path="testing-util.test.src.path" suite="TestingUtilModuleTests"/> </target> diff --git a/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/TestCompareClassFile$1.class b/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/TestCompareClassFile$1.class Binary files differnew file mode 100644 index 000000000..fcb5452c3 --- /dev/null +++ b/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/TestCompareClassFile$1.class diff --git a/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/TestCompareClassFile.class b/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/TestCompareClassFile.class Binary files differnew file mode 100644 index 000000000..5768f483e --- /dev/null +++ b/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/TestCompareClassFile.class diff --git a/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/readme.txt b/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/readme.txt new file mode 100644 index 000000000..e1db1af30 --- /dev/null +++ b/testing-util/testdata/testCompareClassFiles/org/aspectj/testingutil/readme.txt @@ -0,0 +1 @@ +AV - should be added to CVS since I have renamed old files diff --git a/testing-util/testsrc/org/aspectj/testingutil/TestUtilTest.java b/testing-util/testsrc/org/aspectj/testingutil/TestUtilTest.java index ec56260f9..00fb0f385 100644 --- a/testing-util/testsrc/org/aspectj/testingutil/TestUtilTest.java +++ b/testing-util/testsrc/org/aspectj/testingutil/TestUtilTest.java @@ -34,7 +34,7 @@ public class TestUtilTest extends TestCase { public void testFileCompareNonClass() throws IOException { MessageHandler holder = new MessageHandler(); - File thisFile = new File(UtilTests.TESTING_UTIL_PATH + "/testsrc/org/aspectj/testing/util/TestUtilTest.java"); + File thisFile = new File(UtilTests.TESTING_UTIL_PATH + "/testsrc/org/aspectj/testingutil/TestUtilTest.java"); //File thisFile = new File("src/testing-util.lst"); assertTrue(TestUtil.sameFiles(holder, thisFile, thisFile)); @@ -100,7 +100,7 @@ public class TestUtilTest extends TestCase { } MessageHandler holder = new MessageHandler(); File classBase = new File(UtilTests.TESTING_UTIL_PATH + "/testdata/testCompareClassFiles"); - String path = "org/aspectj/testing/util/TestCompareClassFile.class"; + String path = "org/aspectj/testingutil/TestCompareClassFile.class"; File classFile = new File(classBase, path); try { diff --git a/testing/src/org/aspectj/testing/run/RunStatus.java b/testing/src/org/aspectj/testing/run/RunStatus.java index ce3bff73a..10288298b 100644 --- a/testing/src/org/aspectj/testing/run/RunStatus.java +++ b/testing/src/org/aspectj/testing/run/RunStatus.java @@ -277,7 +277,11 @@ public class RunStatus implements IRunStatus { public boolean isIgnoring(IMessage.Kind kind) { return messageHolder.isIgnoring(kind); } - + + public void dontIgnore(IMessage.Kind kind) { + ; + } + /** * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean) */ diff --git a/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java b/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java index 18df66869..6fb341dd8 100644 --- a/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java +++ b/testing/testsrc/org/aspectj/testing/taskdefs/AjcTaskCompileCommandTest.java @@ -134,6 +134,10 @@ public class AjcTaskCompileCommandTest extends TestCase { public boolean isIgnoring(IMessage.Kind kind) { return false; } + + public void dontIgnore(IMessage.Kind kind) { + ; + } }); String[] parms = (String[]) args.toArray(new String[0]); boolean result = command.runCommand(parms, handler); diff --git a/tests/build.xml b/tests/build.xml index 39b605826..85c8a0b23 100644 --- a/tests/build.xml +++ b/tests/build.xml @@ -79,6 +79,7 @@ <testrun project="tests" path="tests.test.src.path" suite="org.aspectj.systemtest.AllTests"/> </target> + <!-- run a single test with "ant -Dtest=org.aspectj.systemtest.AllTests15 atest" --> <target name="atest" depends="test:compile, runtime.compile, weaver.compile"> diff --git a/tests/java5/ataspectj/ataspectj/IfPointcutTest.java b/tests/java5/ataspectj/ataspectj/IfPointcutTest.java index f6b9cb0ba..66693ec4a 100644 --- a/tests/java5/ataspectj/ataspectj/IfPointcutTest.java +++ b/tests/java5/ataspectj/ataspectj/IfPointcutTest.java @@ -52,10 +52,12 @@ public class IfPointcutTest extends TestCase { return (i>=0); } - @Pointcut("args(i) && if(i>0)") + //FIXME av if pcd support + //@Pointcut("args(i) && if(i>0)") void ifPc(int i) {} - @Before("execution(* ataspectj.IfPointcutTest.hello(int)) && ifPc(i)") + //FIXME av if pcd support + //@Before("execution(* ataspectj.IfPointcutTest.hello(int)) && ifPc(i)") void before(int i) { System.out.println("IfPointcutTest$TestAspect.before"); } diff --git a/tests/java5/ataspectj/ataspectj/PrecedenceTest.java b/tests/java5/ataspectj/ataspectj/PrecedenceTest.java index 9d86934de..8f4573e37 100644 --- a/tests/java5/ataspectj/ataspectj/PrecedenceTest.java +++ b/tests/java5/ataspectj/ataspectj/PrecedenceTest.java @@ -39,7 +39,7 @@ public class PrecedenceTest extends TestCase { public void testPrecedence() { s_log = new StringBuffer(); hello(); - assertEquals("TestAspect_3 TestAspect_2 TestAspect_1 hello", s_log.toString()); + assertEquals("TestAspect_3 TestAspect_2 TestAspect_1 hello ", s_log.toString()); } diff --git a/tests/src/org/aspectj/systemtest/AllTests15.java b/tests/src/org/aspectj/systemtest/AllTests15.java index 647bd722a..94876e896 100644 --- a/tests/src/org/aspectj/systemtest/AllTests15.java +++ b/tests/src/org/aspectj/systemtest/AllTests15.java @@ -14,7 +14,7 @@ public class AllTests15 { TestSuite suite = new TestSuite("AspectJ System Test Suite - JDK 1.5"); //$JUnit-BEGIN$ suite.addTest(AllTests14.suite()); - suite.addTestSuite(AllTestsAspectJ150_NeedJava15.class); + suite.addTest(AllTestsAspectJ150_NeedJava15.suite()); //$JUnit-END$ return suite; } diff --git a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java index 0cae15ed9..cb825c300 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java +++ b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java @@ -12,6 +12,7 @@ package org.aspectj.systemtest.ajc150; import junit.framework.Test; import junit.framework.TestSuite; +import junit.framework.TestCase; import org.aspectj.systemtest.ajc150.ataspectj.AtAjc150Tests; /** @@ -27,7 +28,7 @@ public class AllTestsAspectJ150_NeedJava15 { suite.addTestSuite(Annotations.class); suite.addTestSuite(AnnotationBinding.class); - //ATAJ tests + //ATAeJ tests suite.addTest(AtAjc150Tests.suite()); //$JUnit-END$ diff --git a/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java b/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java index d8aefbe50..388287253 100644 --- a/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java +++ b/weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java @@ -87,8 +87,9 @@ public class Aj5Attributes { ISourceContext context; IMessageHandler handler; - public AjAttributeStruct(ResolvedTypeX type) { + public AjAttributeStruct(ResolvedTypeX type, ISourceContext sourceContext) { enclosingType = type; + context = sourceContext; } } @@ -107,8 +108,8 @@ public class Aj5Attributes { Method method; - public AjAttributeMethodStruct(Method method, ResolvedTypeX type) { - super(type); + public AjAttributeMethodStruct(Method method, ResolvedTypeX type, ISourceContext sourceContext) { + super(type, sourceContext); this.method = method; } @@ -140,7 +141,7 @@ public class Aj5Attributes { * @return list of AjAttributes */ public static List readAj5ClassAttributes(JavaClass javaClass, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) { - AjAttributeStruct struct = new AjAttributeStruct(type); + AjAttributeStruct struct = new AjAttributeStruct(type, context); Attribute[] attributes = javaClass.getAttributes(); for (int i = 0; i < attributes.length; i++) { Attribute attribute = attributes[i]; @@ -158,7 +159,8 @@ public class Aj5Attributes { //TODO can that be too slow ? for (int m = 0; m < javaClass.getMethods().length; m++) { Method method = javaClass.getMethods()[m]; - AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, type); + //TODO optimize, this method struct will gets recreated for advice extraction + AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, type, context); Attribute[] mattributes = method.getAttributes(); for (int i = 0; i < mattributes.length; i++) { @@ -184,7 +186,7 @@ public class Aj5Attributes { * @return list of AjAttributes */ public static List readAj5MethodAttributes(Method method, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) { - AjAttributeMethodStruct struct = new AjAttributeMethodStruct(method, type); + AjAttributeMethodStruct struct = new AjAttributeMethodStruct(method, type, context); Attribute[] attributes = method.getAttributes(); for (int i = 0; i < attributes.length; i++) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index f0c6edb9a..58df6fbac 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -36,7 +36,10 @@ import org.aspectj.weaver.ataspectj.Aj5Attributes; final class BcelMethod extends ResolvedMember { - private Method method; + Method method; + public int foo() { + return method.getLineNumberTable().getLineNumberTable()[0].getLineNumber();//getSourceLine(0); + } private boolean isAjSynthetic; private ShadowMunger associatedShadowMunger; private AjAttribute.EffectiveSignatureAttribute effectiveSignature; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index d0985bbf4..d4468ac15 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -66,6 +66,7 @@ import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.WeaverMetrics; import org.aspectj.weaver.WeaverStateInfo; import org.aspectj.weaver.AjcMemberMaker; +import org.aspectj.weaver.World; import org.aspectj.weaver.patterns.AndPointcut; import org.aspectj.weaver.patterns.BindingAnnotationTypePattern; import org.aspectj.weaver.patterns.BindingTypePattern; @@ -1282,4 +1283,8 @@ public class BcelWeaver implements IWeaver { public boolean isReweavable() { return inReweavableMode; } + + public World getWorld() { + return world; + } } diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java index e7fdbdca9..0163affe1 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java @@ -99,6 +99,10 @@ public class AnnotationPatternMatchingTestCase extends TestCase { return false; } public boolean isIgnoring(Kind kind) {return false;} + + public void dontIgnore(IMessage.Kind kind) { + ; + } } public void testReferenceToNonAnnotationType() { |