From: acolyer Date: Mon, 19 Dec 2005 16:44:11 +0000 (+0000) Subject: more @DeclareParents fixes merged from HEAD X-Git-Tag: V1_5_0_final~6 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4fca33486ef4bafa1f633a59436d02ef53b29d23;p=aspectj.git more @DeclareParents fixes merged from HEAD --- diff --git a/aspectj5rt/java5-src/org/aspectj/lang/Aspects.java b/aspectj5rt/java5-src/org/aspectj/lang/Aspects.java new file mode 100644 index 000000000..e82320c2e --- /dev/null +++ b/aspectj5rt/java5-src/org/aspectj/lang/Aspects.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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: + * initial implementation Alexandre Vasseur + * generic signature update Adrian Colyer + *******************************************************************************/ +package org.aspectj.lang; + + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.InvocationTargetException; + +/** + * Handles generic aspectOf method when those are not available in the aspects but added later on + * thru load time weaving. + *

+ * Aspects.aspectOf(..) is doing reflective calls to the aspect aspectOf, so for better performance + * consider using ajc compilation of the aspects and using them as a binary dependancies in your project. + * + * @author Alexandre Vasseur + */ +public class Aspects { + + private final static Class[] EMPTY_CLASS_ARRAY = new Class[0]; + private final static Class[] PEROBJECT_CLASS_ARRAY = new Class[]{Object.class}; + private final static Class[] PERTYPEWITHIN_CLASS_ARRAY = new Class[]{Class.class}; + private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0]; + private final static String ASPECTOF = "aspectOf"; + private final static String HASASPECT = "hasAspect"; + + /** + * Returns the singleton aspect or the percflow / percflowbelow associated with the current thread + * + * @param aspectClass + * @return + * @throws NoAspectBoundException if no such aspect + */ + public static T aspectOf(Class aspectClass) throws NoAspectBoundException { + try { + return (T) getSingletonOrThreadAspectOf(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY); + } catch (InvocationTargetException e) { + //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs + throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause()); + } catch (Exception e) { + throw new NoAspectBoundException(aspectClass.getName(), e); + } + } + + /** + * Returns the perthis / pertarget aspect + * @param aspectClass + * @param perObject + * @return + * @throws NoAspectBoundException if no such aspect, or no aspect bound + */ + public static T aspectOf(Class aspectClass, Object perObject) throws NoAspectBoundException { + try { + return (T) getPerObjectAspectOf(aspectClass).invoke(null, new Object[]{perObject}); + } catch (InvocationTargetException e) { + //FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs + throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause()); + } catch (Exception e) { + throw new NoAspectBoundException(aspectClass.getName(), e); + } + } + + /** + * Returns the pertypewithin aspect + * @param aspectClass + * @param perTypeWithin class + * @return + * @throws NoAspectBoundException if no such aspect, or no aspect bound + */ + public static T aspectOf(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException { + try { + return (T) getPerTypeWithinAspectOf(aspectClass).invoke(null, new Object[]{perTypeWithin}); + } catch (InvocationTargetException e) { +// FIXME asc Highly temporary change to see what the build makes of it - dont use 1.4 APIs + throw new NoAspectBoundException(aspectClass.getName(), e);//e.getCause()); + } catch (Exception e) { + throw new NoAspectBoundException(aspectClass.getName(), e); + } + } + + /** + * Returns true if singleton aspect or percflow / percflowbelow aspect is bound + * + * @param aspectClass + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass) throws NoAspectBoundException { + try { + return ((Boolean)getSingletonOrThreadHasAspect(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY)).booleanValue(); + } catch (Exception e) { + return false; + } + } + + /** + * Returns true if the perthis / pertarget aspect is bound + * @param aspectClass + * @param perObject + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass, Object perObject) throws NoAspectBoundException { + try { + return ((Boolean)getPerObjectHasAspect(aspectClass).invoke(null, new Object[]{perObject})).booleanValue(); + } catch (Exception e) { + return false; + } + } + + /** + * Returns true if the pertypewithin aspect is bound + * @param aspectClass + * @param perTypeWithin class + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException { + try { + return ((Boolean)getPerTypeWithinHasAspect(aspectClass).invoke(null, new Object[]{perTypeWithin})).booleanValue(); + } catch (Exception e) { + return false; + } + } + + // -- aspectOf + + private static Method getSingletonOrThreadAspectOf(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(ASPECTOF, EMPTY_CLASS_ARRAY); + return checkAspectOf(method, aspectClass); + } + + private static Method getPerObjectAspectOf(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(ASPECTOF, PEROBJECT_CLASS_ARRAY); + return checkAspectOf(method, aspectClass); + } + + private static Method getPerTypeWithinAspectOf(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(ASPECTOF, PERTYPEWITHIN_CLASS_ARRAY); + return checkAspectOf(method, aspectClass); + } + + private static Method checkAspectOf(Method method, Class aspectClass) throws NoSuchMethodException { + method.setAccessible(true); + if (!method.isAccessible() + || !Modifier.isPublic(method.getModifiers()) + || !Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException(aspectClass.getName() + ".aspectOf(..) is not accessible public static"); + } + return method; + } + + // -- hasAspect + + private static Method getSingletonOrThreadHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, EMPTY_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method getPerObjectHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, PEROBJECT_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method getPerTypeWithinHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, PERTYPEWITHIN_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method checkHasAspect(Method method, Class aspectClass) throws NoSuchMethodException { + method.setAccessible(true); + if (!method.isAccessible() + || !Modifier.isPublic(method.getModifiers()) + || !Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException(aspectClass.getName() + ".hasAspect(..) is not accessible public static"); + } + return method; + } +} diff --git a/lib/aspectj/lib/aspectjrt.jar b/lib/aspectj/lib/aspectjrt.jar index 297c989ac..bca216381 100644 Binary files a/lib/aspectj/lib/aspectjrt.jar and b/lib/aspectj/lib/aspectjrt.jar differ diff --git a/lib/test/aspectjrt.jar b/lib/test/aspectjrt.jar index 297c989ac..bca216381 100644 Binary files a/lib/test/aspectjrt.jar and b/lib/test/aspectjrt.jar differ diff --git a/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsReweavableTest.java b/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsReweavableTest.java index fad0d8488..1636328ab 100644 --- a/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsReweavableTest.java +++ b/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsReweavableTest.java @@ -26,7 +26,7 @@ public class DeclareParentsImplementsReweavableTest extends TestCase { static interface I1 { int do1(); } - static class Imp1 implements I1 { + public static class Imp1 implements I1 { public int do1() {return 1;} } diff --git a/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsTest.java b/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsTest.java index b4cc9ed4e..8ce1e1915 100644 --- a/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsTest.java +++ b/tests/java5/ataspectj/ataspectj/DeclareParentsImplementsTest.java @@ -41,6 +41,9 @@ public class DeclareParentsImplementsTest extends TestCase { } static class Implementation implements Introduced { + public Implementation(int i) {} + public Implementation() {} + public void intro() { log("intro-"+field1); // we cannot copy the raw bytecode as there might be super.* calls, and other OO stuff diff --git a/tests/java5/ataspectj/ataspectj/DeclareParentsInterfaceTest.java b/tests/java5/ataspectj/ataspectj/DeclareParentsInterfaceTest.java index 2823251e5..d21fc7b7d 100644 --- a/tests/java5/ataspectj/ataspectj/DeclareParentsInterfaceTest.java +++ b/tests/java5/ataspectj/ataspectj/DeclareParentsInterfaceTest.java @@ -14,7 +14,6 @@ package ataspectj; import junit.framework.TestCase; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.annotation.DeclareImplements; import org.aspectj.lang.annotation.DeclareParents; import java.util.Arrays; diff --git a/tests/java5/ataspectj/ataspectj/bugs/AbstractInherited.java b/tests/java5/ataspectj/ataspectj/bugs/AbstractInherited.java new file mode 100644 index 000000000..397c1ad18 --- /dev/null +++ b/tests/java5/ataspectj/ataspectj/bugs/AbstractInherited.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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: + * Alexandre Vasseur initial implementation + *******************************************************************************/ +package ataspectj.bugs; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Around; + +/** + * @author Alexandre Vasseur + */ +//@Aspect +public abstract aspect AbstractInherited { + + //@Around("execution(* foo(..))") + //public Object around() { + // return null; + //} + + void around(): execution(* foo(..)) { + } + +} + +@Aspect +class Sub extends AbstractInherited { +} + +class C { + void foo() { + } +} + + diff --git a/tests/java5/ataspectj/ataspectj/bugs/AspectOfWhenAspectNotInIncludeTest.java b/tests/java5/ataspectj/ataspectj/bugs/AspectOfWhenAspectNotInIncludeTest.java index 5d4437eef..0703215f3 100644 --- a/tests/java5/ataspectj/ataspectj/bugs/AspectOfWhenAspectNotInIncludeTest.java +++ b/tests/java5/ataspectj/ataspectj/bugs/AspectOfWhenAspectNotInIncludeTest.java @@ -15,9 +15,9 @@ import junit.framework.TestCase; import junit.framework.Test; import junit.framework.TestSuite; import ataspectj.TestHelper; +import org.aspectj.lang.annotation.DeclareParents; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.DeclareImplements; import org.aspectj.lang.Aspects; import java.io.Serializable; @@ -36,7 +36,7 @@ public class AspectOfWhenAspectNotInIncludeTest extends TestCase { @Aspect static class TestAspectForAspect { - @DeclareImplements("ataspectj.bugs.AspectOfWhenAspectNotInIncludeTest.TestAspect") + @DeclareParents("ataspectj.bugs.AspectOfWhenAspectNotInIncludeTest.TestAspect") Serializable shouldNotHappenDueToInclude; } diff --git a/tests/java5/decps/Basic2b.java b/tests/java5/decps/Basic2b.java index 03c88f80d..b92b4421e 100644 --- a/tests/java5/decps/Basic2b.java +++ b/tests/java5/decps/Basic2b.java @@ -14,13 +14,13 @@ public class Basic2b { interface I { } - static class IImpl implements I { + public static class IIimpl implements I { public void m2() { } } - @DeclareParents(value="Basic2b",defaultImpl=X.IImpl.class) - private I simplefield;; + @DeclareParents(value="Basic2b",defaultImpl=X.IIimpl.class) + private I simplefield; @Before("execution(* *(..))") diff --git a/tests/java5/decps/Basic3b.java b/tests/java5/decps/Basic3b.java index 1d4ecfe5a..cfbd582c7 100644 --- a/tests/java5/decps/Basic3b.java +++ b/tests/java5/decps/Basic3b.java @@ -16,22 +16,21 @@ public class Basic3b { @Aspect class X { interface I { - public void m2(); - public void m3(); - public void m4(); + public void m2(); + public void m3(); + public void m4(); } - static class IImpl implements I { + public static class IIimpl implements I { public void m2() { } public void m3() { } public void m4() { } } - @DeclareParents(value="Basic3b",defaultImpl=IImpl.class) + @DeclareParents(value="Basic3b",defaultImpl=X.IIimpl.class) private I simplefield; - @Before("call(* *(..))") public void advice1() {} diff --git a/tests/multiIncremental/pr121384/base/moodytest/AnnotationMoodIndicator.java b/tests/multiIncremental/pr121384/base/moodytest/AnnotationMoodIndicator.java new file mode 100644 index 000000000..6872077e9 --- /dev/null +++ b/tests/multiIncremental/pr121384/base/moodytest/AnnotationMoodIndicator.java @@ -0,0 +1,22 @@ +package moodytest; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.DeclareParents; + +@Aspect +public class AnnotationMoodIndicator { + public interface Moody { + Mood getMood(); + void setMood(Mood mood); + } + + public static class MoodyImpl implements Moody { + Mood mood = Mood.HAPPY; + + public Mood getMood() { return mood; } + public void setMood(Mood mood) { this.mood = mood; } + } + + @DeclareParents(value="moodytest.AnnotationMoodyImplementor",defaultImpl=MoodyImpl.class) + private Moody introduced; +} diff --git a/tests/multiIncremental/pr121384/base/moodytest/AnnotationMoodyImplementor.java b/tests/multiIncremental/pr121384/base/moodytest/AnnotationMoodyImplementor.java new file mode 100644 index 000000000..7cab32f5c --- /dev/null +++ b/tests/multiIncremental/pr121384/base/moodytest/AnnotationMoodyImplementor.java @@ -0,0 +1,5 @@ +package moodytest; + +public class AnnotationMoodyImplementor { + +} diff --git a/tests/multiIncremental/pr121384/base/moodytest/Mood.java b/tests/multiIncremental/pr121384/base/moodytest/Mood.java new file mode 100644 index 000000000..6fca1bebb --- /dev/null +++ b/tests/multiIncremental/pr121384/base/moodytest/Mood.java @@ -0,0 +1,5 @@ +package moodytest; + +public enum Mood { + HAPPY, SAD, CONFUSED +} diff --git a/tests/multiIncremental/pr121384/inc1/moodytest/AnnotationMoodTester.java b/tests/multiIncremental/pr121384/inc1/moodytest/AnnotationMoodTester.java new file mode 100644 index 000000000..332bf8585 --- /dev/null +++ b/tests/multiIncremental/pr121384/inc1/moodytest/AnnotationMoodTester.java @@ -0,0 +1,29 @@ +package moodytest; + +import moodytest.AnnotationMoodyImplementor; +import moodytest.Mood; +import junit.framework.TestCase; + +public class AnnotationMoodTester extends TestCase { + AnnotationMoodyImplementor ami0 = null; + AnnotationMoodyImplementor ami1 = null; + + public AnnotationMoodTester(String name) { super(name); } + + protected void setUp() throws Exception { + ami0 = new AnnotationMoodyImplementor(); + ami1 = new AnnotationMoodyImplementor(); + } + + public void testHappyDefault() { + assertEquals("ami0 should be happy!", Mood.HAPPY, ami0.getMood()); + } + + public void testOneConfused() { + ami0.setMood(Mood.CONFUSED); + assertEquals("ami0 should now be confused", Mood.CONFUSED, + ami0.getMood()); + assertEquals("ami1 should still be happy", Mood.HAPPY, + ami1.getMood()); + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/Ajc150Tests.java b/tests/src/org/aspectj/systemtest/ajc150/Ajc150Tests.java index 75bb203f3..def43d636 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/Ajc150Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/Ajc150Tests.java @@ -41,13 +41,14 @@ public class Ajc150Tests extends org.aspectj.testing.XMLBasedAjcTestCase { protected File getSpecFile() { return new File("../tests/src/org/aspectj/systemtest/ajc150/ajc150.xml"); } - public void testDecps1() { runTest("decps - 1");} - public void testDecps1b() { runTest("decps - 1b");} - public void testDecps2() { runTest("decps - 2");} - public void testDecps2b() { runTest("decps - 2b");} - public void testDecps3() { runTest("decps - 3");} - public void testDecps3b() { runTest("decps - 3b");} - public void testDecps3c() { runTest("decps - 3c");} + + public void testDecps1() { runTest("decps - 1"); } + public void testDecps1b() { runTest("decps - 1b"); } + public void testDecps2() { runTest("decps - 2"); } + public void testDecps2b() { runTest("decps - 2b"); } + public void testDecps3() { runTest("decps - 3"); } + public void testDecps3b() { runTest("decps - 3b"); } + public void testDecps3c() { runTest("decps - 3c"); } public void testVarargsNPE_pr120826() { runTest("varargs NPE");} public void testNamedPointcutPertarget_pr120521() { runTest("named pointcut not resolved in pertarget pointcut");} diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index 7115d779e..56cf37dc8 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -98,7 +98,10 @@ - + + + + @@ -122,7 +125,7 @@ - + @@ -152,18 +155,18 @@ - - - - + + + + + - diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java index c462cdea8..4a8635081 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java @@ -133,4 +133,8 @@ public class AtAjSyntaxTests extends XMLBasedAjcTestCase { runTest("AbstractAspectNPE"); } + public void testAbstractInherited() { + runTest("AbstractInherited"); + } + } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml index 015d8c1dc..09b3c6d78 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml @@ -173,4 +173,12 @@ + + + + + + + \ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java b/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java index e45ded8a9..9e864b089 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java @@ -431,6 +431,7 @@ public class AjdeInteractionTestbed extends TestCase { System.getProperty("sun.boot.class.path") + File.pathSeparator + "../runtime/bin" + File.pathSeparator + System.getProperty("aspectjrt.path") + + File.pathSeparator + "../lib/junit/junit.jar" + File.pathSeparator+".."+File.separator+"lib" + File.separator+"test"+File.separator+"aspectjrt.jar"; // look at dependant projects diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java index b010f7b60..ebd34910c 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java @@ -364,6 +364,19 @@ public class MultiProjectIncrementalTests extends AjdeInteractionTestbed { build("PR115251"); checkWasntFullBuild(); } + + public void testPr121384() { +// AjdeInteractionTestbed.VERBOSE=true; +// AsmManager.setReporting("c:/foo.txt",true,true,true,false); + MyBuildOptionsAdapter.setNonStandardOptions("-showWeaveInfo"); + configureBuildStructureModel(true); + initialiseProject("pr121384"); + build("pr121384"); + checkWasFullBuild(); + alter("pr121384","inc1"); + build("pr121384"); + checkWasntFullBuild(); + } /* public void testPr111779() { diff --git a/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java b/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java index 9297f1d16..e49374dab 100644 --- a/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java +++ b/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java @@ -17,7 +17,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; -import java.lang.reflect.Modifier; import org.aspectj.apache.bcel.Constants; import org.aspectj.apache.bcel.classfile.Attribute; @@ -29,10 +28,10 @@ import org.aspectj.apache.bcel.classfile.LocalVariable; import org.aspectj.apache.bcel.classfile.LocalVariableTable; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.apache.bcel.classfile.annotation.Annotation; +import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations; -import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; import org.aspectj.apache.bcel.generic.Type; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessageHandler; @@ -52,9 +51,6 @@ import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeaverMessages; -import org.aspectj.weaver.NewFieldTypeMunger; -import org.aspectj.weaver.ResolvedMemberImpl; -import org.aspectj.weaver.Member; import org.aspectj.weaver.patterns.AndPointcut; import org.aspectj.weaver.patterns.DeclareErrorOrWarning; import org.aspectj.weaver.patterns.DeclareParents; @@ -671,16 +667,18 @@ public class AtAjAttributes { if (fieldType.isInterface()) { TypePattern parent = new ExactTypePattern(UnresolvedType.forSignature(struct.field.getSignature()), false, false); parent.resolve(struct.enclosingType.getWorld()); - //TODO kick ISourceLocation sl = struct.bField.getSourceLocation(); ?? // first add the declare implements like List parents = new ArrayList(1); parents.add(parent); + DeclareParents dp = new DeclareParents( + typePattern, + parents, + false + ); + //TODO kick ISourceLocation sl = struct.bField.getSourceLocation(); ?? + dp.setLocation(struct.context,0,0); // not ideal... struct.ajAttributes.add( new AjAttribute.DeclareAttribute( - new DeclareParents( - typePattern, - parents, - false - ) + dp ) ); @@ -693,8 +691,34 @@ public class AtAjAttributes { defaultImplClassName = UnresolvedType.forSignature(defaultImpl.getClassString()).getName(); if (defaultImplClassName.equals("org.aspectj.lang.annotation.DeclareParents")) { defaultImplClassName = null; + } else { + // check public no arg ctor + ResolvedType impl = struct.enclosingType.getWorld().resolve( + defaultImplClassName, + false + ); + ResolvedMember[] mm = impl.getDeclaredMethods(); + boolean hasNoCtorOrANoArgOne = true; + for (int i = 0; i < mm.length; i++) { + ResolvedMember resolvedMember = mm[i]; + if (resolvedMember.getName().equals("")) { + hasNoCtorOrANoArgOne = false; + if (resolvedMember.getParameterTypes().length == 0 + && resolvedMember.isPublic()) { + hasNoCtorOrANoArgOne = true; + } + } + if (hasNoCtorOrANoArgOne) { + break; + } + } + if (!hasNoCtorOrANoArgOne) { + reportError("@DeclareParents: defaultImpl=\"" + + defaultImplClassName + + "\" has no public no-arg constructor", struct); + } } - //TODO check public no arg ctor + } // then iterate on field interface hierarchy (not object) @@ -709,7 +733,7 @@ public class AtAjAttributes { return false; } hasAtLeastOneMethod = true; - + struct.ajAttributes.add( new AjAttribute.TypeMunger( new MethodDelegateTypeMunger( diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java index e6f0d88c8..5d6a5fcb6 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java @@ -454,11 +454,14 @@ public class BcelAdvice extends Advice { } } else if (hasExtraParameter()) { previousIsClosure = false; - extraVar.appendLoadAndConvert( - il, - fact, - getExtraParameterType().resolve(world)); - } else { + //extra var can be null here (@Aj aspect extends abstract code style, advice in code style) + if (extraVar != null) { + extraVar.appendLoadAndConvert( + il, + fact, + getExtraParameterType().resolve(world)); + } + } else { previousIsClosure = false; getConcreteAspect().getWorld().getMessageHandler().handleMessage( new Message( diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 46332675a..0497f109a 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -21,6 +21,7 @@ import java.util.Set; import org.aspectj.apache.bcel.Constants; import org.aspectj.apache.bcel.classfile.annotation.Annotation; +import org.aspectj.apache.bcel.generic.BranchInstruction; import org.aspectj.apache.bcel.generic.ConstantPoolGen; import org.aspectj.apache.bcel.generic.FieldGen; import org.aspectj.apache.bcel.generic.INVOKESPECIAL; @@ -29,7 +30,6 @@ import org.aspectj.apache.bcel.generic.InstructionFactory; import org.aspectj.apache.bcel.generic.InstructionHandle; import org.aspectj.apache.bcel.generic.InstructionList; import org.aspectj.apache.bcel.generic.Type; -import org.aspectj.apache.bcel.generic.BranchInstruction; import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; @@ -64,7 +64,6 @@ import org.aspectj.weaver.WeaverStateInfo; import org.aspectj.weaver.World; import org.aspectj.weaver.patterns.DeclareAnnotation; import org.aspectj.weaver.patterns.Pointcut; -import org.aspectj.lang.Signature; //XXX addLazyMethodGen is probably bad everywhere public class BcelTypeMunger extends ConcreteTypeMunger {