@@ -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. | |||
* <p/> | |||
* 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 <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||
*/ | |||
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> T aspectOf(Class<T> 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> T aspectOf(Class<T> 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> T aspectOf(Class<T> 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; | |||
} | |||
} |
@@ -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;} | |||
} | |||
@@ -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 |
@@ -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; |
@@ -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 <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||
*/ | |||
//@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() { | |||
} | |||
} | |||
@@ -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; | |||
} | |||
@@ -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(* *(..))") |
@@ -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() {} | |||
@@ -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; | |||
} |
@@ -0,0 +1,5 @@ | |||
package moodytest; | |||
public class AnnotationMoodyImplementor { | |||
} |
@@ -0,0 +1,5 @@ | |||
package moodytest; | |||
public enum Mood { | |||
HAPPY, SAD, CONFUSED | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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");} |
@@ -98,7 +98,10 @@ | |||
<run class="Pr114054"/> | |||
</ajc-test> | |||
<ajc-test dir="bugs150" pr="121385" title="mixing styles"> | |||
<compile files="pr121385.aj" options="-1.5"/> | |||
</ajc-test> | |||
<ajc-test dir="java5/decps" title="decps - 1"> | |||
<compile files="Basic1.java" options="-1.5"/> | |||
<run class="Basic1"/> | |||
@@ -122,7 +125,7 @@ | |||
<ajc-test dir="java5/decps" title="decps - 2b"> | |||
<compile files="Basic2b.java" options="-1.5 -showWeaveInfo"> | |||
<message kind="weave" text="Join point 'method-execution(void X$IImpl.m2())' in Type 'X$IImpl' (Basic2b.java:18) advised by before advice from 'X' (Basic2b.java:27)"/> | |||
<message kind="weave" text="Join point 'method-execution(void X$IIimpl.m2())' in Type 'X$IIimpl' (Basic2b.java:18) advised by before advice from 'X' (Basic2b.java:27)"/> | |||
<message kind="weave" text="Extending interface set for type 'Basic2b' (Basic2b.java) to include 'X$I' (Basic2b.java)"/> | |||
<message kind="weave" text="Join point 'method-execution(void Basic2b.main(java.lang.String[]))' in Type 'Basic2b' (Basic2b.java:4) advised by before advice from 'X' (Basic2b.java:27)"/> | |||
</compile> | |||
@@ -152,18 +155,18 @@ | |||
<message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m2()')"/> | |||
<message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m3()')"/> | |||
<message kind="weave" text="Type 'Basic3b' (Basic3b.java) has intertyped method from 'X' (Basic3b.java:'void X$I.m4()')"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:7) advised by before advice from 'X' (Basic3b.java:36)"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m3())' in Type 'Basic3b' (Basic3b.java:8) advised by before advice from 'X' (Basic3b.java:36)"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:9) advised by before advice from 'X' (Basic3b.java:36)"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m4())' in Type 'Basic3b' (Basic3b.java:10) advised by before advice from 'X' (Basic3b.java:36)"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:7) advised by before advice from 'X' (Basic3b.java:35)"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m3())' in Type 'Basic3b' (Basic3b.java:8) advised by before advice from 'X' (Basic3b.java:35)"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m2())' in Type 'Basic3b' (Basic3b.java:9) advised by before advice from 'X' (Basic3b.java:35)"/> | |||
<message kind="weave" text="Join point 'method-call(void X$I.m4())' in Type 'Basic3b' (Basic3b.java:10) advised by before advice from 'X' (Basic3b.java:35)"/> | |||
</compile> | |||
<run class="Basic3b"/> | |||
</ajc-test> | |||
<ajc-test dir="java5/decps" title="decps - 3c"> | |||
<compile files="Basic3c.java" options="-1.5"> | |||
<message kind="error" text="@DeclareParents: defaultImpl="X$IImpl" has no public no-arg constructor"/> | |||
</compile> | |||
<run class="Basic3c"/> | |||
</ajc-test> | |||
@@ -133,4 +133,8 @@ public class AtAjSyntaxTests extends XMLBasedAjcTestCase { | |||
runTest("AbstractAspectNPE"); | |||
} | |||
public void testAbstractInherited() { | |||
runTest("AbstractInherited"); | |||
} | |||
} |
@@ -173,4 +173,12 @@ | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/ataspectj" title="AbstractInherited"> | |||
<compile files="ataspectj/bugs/AbstractInherited.java" | |||
options="-1.5 -showWeaveInfo"> | |||
<message kind="weave" text="Join point "/> | |||
</compile> | |||
</ajc-test> | |||
</suite> |
@@ -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 |
@@ -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() { |
@@ -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("<init>")) { | |||
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( |
@@ -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( |
@@ -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 { |