@@ -663,7 +663,13 @@ public class AjTypeImpl<T> implements AjType<T> { | |||
if (!f.getType().isInterface()) continue; | |||
if (!Modifier.isPublic(f.getModifiers()) || !Modifier.isStatic(f.getModifiers())) continue; | |||
if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) { | |||
for (Method itdM : f.getType().getDeclaredMethods()) { | |||
Class itdSource = f.getType(); | |||
try { | |||
itdSource = f.get(null).getClass(); | |||
} catch (IllegalAccessException ex) { | |||
// | |||
} | |||
for (Method itdM : itdSource.getDeclaredMethods()) { | |||
if (!Modifier.isPublic(itdM.getModifiers()) && publicOnly) continue; | |||
InterTypeMethodDeclaration itdm = new InterTypeMethodDeclarationImpl( | |||
this, AjTypeSystem.getAjType(f.getType()), itdM | |||
@@ -676,9 +682,30 @@ public class AjTypeImpl<T> implements AjType<T> { | |||
} | |||
private void addAnnotationStyleITDFields(List<InterTypeFieldDeclaration> toList, boolean publicOnly) { | |||
return; | |||
//AV: I think it is meaningless | |||
//@AJ decp is interface driven ie no field | |||
// AMC: private fields in the mixin type should show as ITDs private to the aspect... | |||
if (isAspect()) { | |||
for (Field f : clazz.getDeclaredFields()) { | |||
if (!f.getType().isInterface()) continue; | |||
if (!Modifier.isPublic(f.getModifiers()) || !Modifier.isStatic(f.getModifiers())) continue; | |||
if (f.isAnnotationPresent(org.aspectj.lang.annotation.DeclareParents.class)) { | |||
Class itdSource = f.getType(); | |||
try { | |||
itdSource = f.get(null).getClass(); | |||
} catch (IllegalAccessException ex) { | |||
// | |||
} | |||
for (Field itdF : itdSource.getDeclaredFields()) { | |||
if (!Modifier.isPublic(itdF.getModifiers()) && publicOnly) continue; | |||
InterTypeFieldDeclaration itdf = new InterTypeFieldDeclarationImpl( | |||
this, AjTypeSystem.getAjType(f.getType()), itdF | |||
); | |||
toList.add(itdf); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
/* (non-Javadoc) |
@@ -0,0 +1,21 @@ | |||
import org.aspectj.lang.annotation.*; | |||
public aspect AtAspectJDeclareParents { | |||
@DeclareParents("C") | |||
public static I mixin = new Impl(); | |||
} | |||
class C {} | |||
interface I{} | |||
class Impl implements I { | |||
private int x; | |||
public int getX() { return this.x; } | |||
public void setX(int x) { this.x = x; } | |||
} |
@@ -0,0 +1,30 @@ | |||
public aspect InterTypeDeclarations { | |||
private int I.x = 5; | |||
int I.y = 6; | |||
public int I.z = 7; | |||
private int I.getX() { return this.x; } | |||
int I.getY() { return this.y; } | |||
public int I.getZ() { return this.z; } | |||
private int C.x = 5; | |||
int C.y = 6; | |||
public int C.z = 7; | |||
private int C.getX() { return this.x; } | |||
int C.getY() { return this.y; } | |||
public int C.getZ() { return this.z; } | |||
private C.new(int x) { super(); this.x = x;} | |||
C.new(int x, int y) { this(x); this.y = y; } | |||
public C.new(int x, int y, int z) { this(x,y); this.z = z; } | |||
} | |||
interface I {} | |||
class C {} |
@@ -0,0 +1,132 @@ | |||
import org.aspectj.lang.reflect.*; | |||
import java.util.*; | |||
import java.lang.reflect.*; | |||
public class ReflectOnAtAspectJDeclareParents { | |||
public static void main(String[] args) { | |||
new ReflectOnAtAspectJDeclareParents().runTests(); | |||
} | |||
public void runTests() { | |||
AjType<AtAspectJDeclareParents> ajType = AjTypeSystem.getAjType(AtAspectJDeclareParents.class); | |||
testDeclareParents(ajType); | |||
testDeclaredInterTypeMethods(ajType); | |||
testInterTypeMethods(ajType); | |||
testDeclaredInterTypeFields(ajType); | |||
testInterTypeFields(ajType); | |||
} | |||
private void testDeclareParents(AjType<AtAspectJDeclareParents> ajType) { | |||
DeclareParents[] dps = ajType.getDeclareParents(); | |||
assertEquals(1,dps.length,"number of declare parents"); | |||
System.out.println(dps[0]); | |||
} | |||
private void testDeclaredInterTypeMethods(AjType<AtAspectJDeclareParents> ajType) { | |||
InterTypeMethodDeclaration[] itdms = ajType.getDeclaredITDMethods(); | |||
assertEquals(2,itdms.length,"number of declared ITD methods"); | |||
Set s = new TreeSet(new Comparator<InterTypeMethodDeclaration>() { | |||
public int compare(InterTypeMethodDeclaration m1, InterTypeMethodDeclaration m2) { | |||
if (m1 == m2) return 0; | |||
int vis = (m1.getModifiers() - m2.getModifiers()); | |||
if (vis != 0) return vis; | |||
int name = (m1.getName().compareTo(m2.getName())); | |||
if (name != 0) return name; | |||
try { | |||
return ( | |||
m1.getTargetType().getJavaClass().getName().compareTo( | |||
m2.getTargetType().getJavaClass().getName()) | |||
); | |||
} catch (ClassNotFoundException ex) { | |||
throw new RuntimeException(ex); | |||
} | |||
} | |||
}); | |||
for (InterTypeMethodDeclaration itdm : itdms) { s.add(itdm); } | |||
for (Object o : s) { System.out.println(o); } | |||
try { | |||
InterTypeMethodDeclaration shouldFind = ajType.getDeclaredITDMethod("getX",AjTypeSystem.getAjType(I.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchMethodException ex) { | |||
throw new RuntimeException("getITDMethod failed"); | |||
} | |||
try { | |||
ajType.getDeclaredITDMethod("getP",AjTypeSystem.getAjType(I.class)); | |||
throw new RuntimeException("failed to fail in getting ITDMethod"); | |||
} catch (NoSuchMethodException ex) { | |||
// good! | |||
} | |||
} | |||
private void testInterTypeMethods(AjType<AtAspectJDeclareParents> ajType) { | |||
InterTypeMethodDeclaration[] itdms = ajType.getITDMethods(); | |||
assertEquals(2,itdms.length,"number of ITD methods"); | |||
Set s = new TreeSet(new Comparator<InterTypeMethodDeclaration>() { | |||
public int compare(InterTypeMethodDeclaration m1, InterTypeMethodDeclaration m2) { | |||
if (m1 == m2) return 0; | |||
int vis = (m1.getModifiers() - m2.getModifiers()); | |||
if (vis != 0) return vis; | |||
int name = (m1.getName().compareTo(m2.getName())); | |||
if (name != 0) return name; | |||
try { | |||
return ( | |||
m1.getTargetType().getJavaClass().getName().compareTo( | |||
m2.getTargetType().getJavaClass().getName()) | |||
); | |||
} catch (ClassNotFoundException ex) { | |||
throw new RuntimeException(ex); | |||
} | |||
} | |||
}); | |||
for (InterTypeMethodDeclaration itdm : itdms) { s.add(itdm); } | |||
for (Object o : s) { System.out.println(o); } | |||
try { | |||
InterTypeMethodDeclaration shouldFind = ajType.getITDMethod("getX",AjTypeSystem.getAjType(I.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchMethodException ex) { | |||
throw new RuntimeException("getITDMethod failed"); | |||
} | |||
try { | |||
ajType.getITDMethod("getX",AjTypeSystem.getAjType(C.class)); | |||
throw new RuntimeException("failed to fail in getting ITDMethod"); | |||
} catch (NoSuchMethodException ex) { | |||
// good! | |||
} | |||
} | |||
private void testDeclaredInterTypeFields(AjType<AtAspectJDeclareParents> ajType) { | |||
InterTypeFieldDeclaration[] itdfs = ajType.getDeclaredITDFields(); | |||
assertEquals(1,itdfs.length,"number of declared ITD fields"); | |||
System.out.println(itdfs[0]); | |||
try { | |||
InterTypeFieldDeclaration shouldFind = ajType.getDeclaredITDField("x",AjTypeSystem.getAjType(I.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchFieldException ex) { | |||
throw new RuntimeException("getITDField failed"); | |||
} | |||
try { | |||
ajType.getDeclaredITDField("p",AjTypeSystem.getAjType(C.class)); | |||
throw new RuntimeException("failed to fail in getting ITDField"); | |||
} catch (NoSuchFieldException ex) { | |||
// good! | |||
} | |||
} | |||
private void testInterTypeFields(AjType<AtAspectJDeclareParents> ajType) { | |||
InterTypeFieldDeclaration[] itdfs = ajType.getITDFields(); | |||
assertEquals(0,itdfs.length,"number of declared ITD fields"); | |||
} | |||
private void assertEquals(int x, int y, String msg) { | |||
if (x != y) { | |||
throw new RuntimeException(msg + " expecting '" + x + "' but was '" + y + "'"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,232 @@ | |||
import org.aspectj.lang.reflect.*; | |||
import java.util.*; | |||
import java.lang.reflect.*; | |||
public class ReflectOnCodeStyleITDs { | |||
public static void main(String[] args) { | |||
new ReflectOnCodeStyleITDs().runTests(); | |||
} | |||
public void runTests() { | |||
AjType<InterTypeDeclarations> ajType = AjTypeSystem.getAjType(InterTypeDeclarations.class); | |||
testDeclaredInterTypeConstructors(ajType); | |||
testInterTypeConstructors(ajType); | |||
testDeclaredInterTypeMethods(ajType); | |||
testInterTypeMethods(ajType); | |||
testDeclaredInterTypeFields(ajType); | |||
testInterTypeFields(ajType); | |||
} | |||
private void testDeclaredInterTypeConstructors(AjType<InterTypeDeclarations> ajType) { | |||
InterTypeConstructorDeclaration[] itdcs = ajType.getDeclaredITDConstructors(); | |||
assertEquals(3,itdcs.length,"number of declared ITD constructors"); | |||
InterTypeConstructorDeclaration publicITDC = null; | |||
InterTypeConstructorDeclaration defaultITDC = null; | |||
InterTypeConstructorDeclaration privateITDC = null; | |||
for(InterTypeConstructorDeclaration itdc : itdcs) { | |||
if (Modifier.isPublic(itdc.getModifiers())) { | |||
publicITDC = itdc; | |||
} else if (Modifier.isPrivate(itdc.getModifiers())) { | |||
privateITDC = itdc; | |||
} else { | |||
defaultITDC = itdc; | |||
} | |||
} | |||
System.out.println(publicITDC); | |||
System.out.println(defaultITDC); | |||
System.out.println(privateITDC); | |||
try { | |||
InterTypeConstructorDeclaration shouldFind = ajType.getDeclaredITDConstructor(AjTypeSystem.getAjType(C.class), AjTypeSystem.getAjType(int.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchMethodException ex) { | |||
throw new RuntimeException("getDeclaredITDConstructor failed"); | |||
} | |||
try { | |||
ajType.getDeclaredITDConstructor(AjTypeSystem.getAjType(I.class), AjTypeSystem.getAjType(int.class)); | |||
throw new RuntimeException("failed to fail in getting DeclaredITDConstructor #1"); | |||
} catch (NoSuchMethodException ex) { | |||
// good! | |||
} | |||
try { | |||
ajType.getDeclaredITDConstructor(AjTypeSystem.getAjType(C.class), AjTypeSystem.getAjType(String.class)); | |||
throw new RuntimeException("failed to fail in getting DeclaredITDConstructor #2"); | |||
} catch (NoSuchMethodException ex) { | |||
// good! | |||
} | |||
} | |||
private void testInterTypeConstructors(AjType<InterTypeDeclarations> ajType) { | |||
InterTypeConstructorDeclaration[] itdcs = ajType.getITDConstructors(); | |||
assertEquals(1,itdcs.length,"number of ITD constructors"); | |||
System.out.println(itdcs[0]); | |||
AjType<?> intClass = AjTypeSystem.getAjType(int.class); | |||
try { | |||
InterTypeConstructorDeclaration shouldFind = ajType.getITDConstructor(AjTypeSystem.getAjType(C.class), intClass, intClass, intClass); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchMethodException ex) { | |||
throw new RuntimeException("getITDConstructor failed"); | |||
} | |||
try { | |||
ajType.getITDConstructor(AjTypeSystem.getAjType(C.class), AjTypeSystem.getAjType(int.class)); | |||
throw new RuntimeException("failed to fail in getting ITDConstructor"); | |||
} catch (NoSuchMethodException ex) { | |||
// good! | |||
} | |||
} | |||
private void testDeclaredInterTypeMethods(AjType<InterTypeDeclarations> ajType) { | |||
InterTypeMethodDeclaration[] itdms = ajType.getDeclaredITDMethods(); | |||
assertEquals(6,itdms.length,"number of declared ITD methods"); | |||
Set s = new TreeSet(new Comparator<InterTypeMethodDeclaration>() { | |||
public int compare(InterTypeMethodDeclaration m1, InterTypeMethodDeclaration m2) { | |||
if (m1 == m2) return 0; | |||
int vis = (m1.getModifiers() - m2.getModifiers()); | |||
if (vis != 0) return vis; | |||
int name = (m1.getName().compareTo(m2.getName())); | |||
if (name != 0) return name; | |||
try { | |||
return ( | |||
m1.getTargetType().getJavaClass().getName().compareTo( | |||
m2.getTargetType().getJavaClass().getName()) | |||
); | |||
} catch (ClassNotFoundException ex) { | |||
throw new RuntimeException(ex); | |||
} | |||
} | |||
}); | |||
for (InterTypeMethodDeclaration itdm : itdms) { s.add(itdm); } | |||
for (Object o : s) { System.out.println(o); } | |||
try { | |||
InterTypeMethodDeclaration shouldFind = ajType.getDeclaredITDMethod("getX",AjTypeSystem.getAjType(C.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchMethodException ex) { | |||
throw new RuntimeException("getITDMethod failed"); | |||
} | |||
try { | |||
ajType.getDeclaredITDMethod("getP",AjTypeSystem.getAjType(C.class)); | |||
throw new RuntimeException("failed to fail in getting ITDMethod"); | |||
} catch (NoSuchMethodException ex) { | |||
// good! | |||
} | |||
} | |||
private void testInterTypeMethods(AjType<InterTypeDeclarations> ajType) { | |||
InterTypeMethodDeclaration[] itdms = ajType.getITDMethods(); | |||
assertEquals(2,itdms.length,"number of ITD methods"); | |||
Set s = new TreeSet(new Comparator<InterTypeMethodDeclaration>() { | |||
public int compare(InterTypeMethodDeclaration m1, InterTypeMethodDeclaration m2) { | |||
if (m1 == m2) return 0; | |||
int vis = (m1.getModifiers() - m2.getModifiers()); | |||
if (vis != 0) return vis; | |||
int name = (m1.getName().compareTo(m2.getName())); | |||
if (name != 0) return name; | |||
try { | |||
return ( | |||
m1.getTargetType().getJavaClass().getName().compareTo( | |||
m2.getTargetType().getJavaClass().getName()) | |||
); | |||
} catch (ClassNotFoundException ex) { | |||
throw new RuntimeException(ex); | |||
} | |||
} | |||
}); | |||
for (InterTypeMethodDeclaration itdm : itdms) { s.add(itdm); } | |||
for (Object o : s) { System.out.println(o); } | |||
try { | |||
InterTypeMethodDeclaration shouldFind = ajType.getITDMethod("getZ",AjTypeSystem.getAjType(C.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchMethodException ex) { | |||
throw new RuntimeException("getITDMethod failed"); | |||
} | |||
try { | |||
ajType.getITDMethod("getX",AjTypeSystem.getAjType(C.class)); | |||
throw new RuntimeException("failed to fail in getting ITDMethod"); | |||
} catch (NoSuchMethodException ex) { | |||
// good! | |||
} | |||
} | |||
private void testDeclaredInterTypeFields(AjType<InterTypeDeclarations> ajType) { | |||
InterTypeFieldDeclaration[] itdfs = ajType.getDeclaredITDFields(); | |||
assertEquals(6,itdfs.length,"number of declared ITD fields"); | |||
Set s = new TreeSet(new Comparator<InterTypeFieldDeclaration>() { | |||
public int compare(InterTypeFieldDeclaration m1, InterTypeFieldDeclaration m2) { | |||
if (m1 == m2) return 0; | |||
int vis = (m1.getModifiers() - m2.getModifiers()); | |||
if (vis != 0) return vis; | |||
int name = (m1.getName().compareTo(m2.getName())); | |||
if (name != 0) return name; | |||
try { | |||
return ( | |||
m1.getTargetType().getJavaClass().getName().compareTo( | |||
m2.getTargetType().getJavaClass().getName()) | |||
); | |||
} catch (ClassNotFoundException ex) { | |||
throw new RuntimeException(ex); | |||
} | |||
} | |||
}); | |||
for (InterTypeFieldDeclaration itdf : itdfs) { s.add(itdf); } | |||
for (Object o : s) { System.out.println(o); } | |||
try { | |||
InterTypeFieldDeclaration shouldFind = ajType.getDeclaredITDField("x",AjTypeSystem.getAjType(C.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchFieldException ex) { | |||
throw new RuntimeException("getITDField failed"); | |||
} | |||
try { | |||
ajType.getDeclaredITDField("p",AjTypeSystem.getAjType(C.class)); | |||
throw new RuntimeException("failed to fail in getting ITDField"); | |||
} catch (NoSuchFieldException ex) { | |||
// good! | |||
} | |||
} | |||
private void testInterTypeFields(AjType<InterTypeDeclarations> ajType) { | |||
InterTypeFieldDeclaration[] itdfs = ajType.getITDFields(); | |||
assertEquals(2,itdfs.length,"number of declared ITD fields"); | |||
Set s = new TreeSet(new Comparator<InterTypeFieldDeclaration>() { | |||
public int compare(InterTypeFieldDeclaration m1, InterTypeFieldDeclaration m2) { | |||
if (m1 == m2) return 0; | |||
int vis = (m1.getModifiers() - m2.getModifiers()); | |||
if (vis != 0) return vis; | |||
int name = (m1.getName().compareTo(m2.getName())); | |||
if (name != 0) return name; | |||
try { | |||
return ( | |||
m1.getTargetType().getJavaClass().getName().compareTo( | |||
m2.getTargetType().getJavaClass().getName()) | |||
); | |||
} catch (ClassNotFoundException ex) { | |||
throw new RuntimeException(ex); | |||
} | |||
} | |||
}); | |||
for (InterTypeFieldDeclaration itdf : itdfs) { s.add(itdf); } | |||
for (Object o : s) { System.out.println(o); } | |||
try { | |||
InterTypeFieldDeclaration shouldFind = ajType.getITDField("z",AjTypeSystem.getAjType(C.class)); | |||
System.out.println(shouldFind); | |||
} catch (NoSuchFieldException ex) { | |||
throw new RuntimeException("getITDField failed"); | |||
} | |||
try { | |||
ajType.getITDField("x",AjTypeSystem.getAjType(C.class)); | |||
throw new RuntimeException("failed to fail in getting ITDField"); | |||
} catch (NoSuchFieldException ex) { | |||
// good! | |||
} | |||
} | |||
private void assertEquals(int x, int y, String msg) { | |||
if (x != y) { | |||
throw new RuntimeException(msg + " expecting '" + x + "' but was '" + y + "'"); | |||
} | |||
} | |||
} |
@@ -839,6 +839,14 @@ public class Ajc150Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
runTest("IllegalAccessError with around advice on interface method call using LTW and -XnoInline"); | |||
} | |||
public void testReflectOnCodeStyleITDs() { | |||
runTest("reflection on itds"); | |||
} | |||
public void testReflectOnAtAspectJDecP() { | |||
runTest("reflection on @DeclareParents"); | |||
} | |||
// helper methods..... | |||
public SyntheticRepository createRepos(File cpentry) { |
@@ -225,7 +225,57 @@ | |||
<compile files="PointcutLibrary.aj,ReflectOnAjcCompiledPointcuts.java" options="-1.5"></compile> | |||
<run class="ReflectOnAjcCompiledPointcuts" classpath="../lib/bcel/bcel.jar"/> | |||
</ajc-test> | |||
<ajc-test dir="java5/reflection" title="reflection on itds"> | |||
<compile files="InterTypeDeclarations.aj,ReflectOnCodeStyleITDs.java" options="-1.5"></compile> | |||
<run class="ReflectOnCodeStyleITDs" classpath="../lib/bcel/bcel.jar"> | |||
<stdout> | |||
<line text="public C.new(int, int, int)"/> | |||
<line text="C.new(int, int)"/> | |||
<line text="private C.new(int)"/> | |||
<line text="private C.new(int)"/> | |||
<line text="public C.new(int, int, int)"/> | |||
<line text="public C.new(int, int, int)"/> | |||
<line text="int C.getY()"/> | |||
<line text="int I.getY()"/> | |||
<line text="public int C.getZ()"/> | |||
<line text="public int I.getZ()"/> | |||
<line text="private int C.getX()"/> | |||
<line text="private int I.getX()"/> | |||
<line text="private int C.getX()"/> | |||
<line text="public int C.getZ()"/> | |||
<line text="public int I.getZ()"/> | |||
<line text="public int C.getZ()"/> | |||
<line text="int C.y"/> | |||
<line text="int I.y"/> | |||
<line text="public int C.z"/> | |||
<line text="public int I.z"/> | |||
<line text="private int C.x"/> | |||
<line text="private int I.x"/> | |||
<line text="private int C.x"/> | |||
<line text="public int C.z"/> | |||
<line text="public int I.z"/> | |||
<line text="public int C.z"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="java5/reflection" title="reflection on @DeclareParents"> | |||
<compile files="AtAspectJDeclareParents.aj,ReflectOnAtAspectJDeclareParents.java" options="-1.5"></compile> | |||
<run class="ReflectOnAtAspectJDeclareParents" classpath="../lib/bcel/bcel.jar"> | |||
<stdout> | |||
<line text="declare parents : C implements I"/> | |||
<line text="public int I.getX()"/> | |||
<line text="public void I.setX(int)"/> | |||
<line text="public int I.getX()"/> | |||
<line text="public int I.getX()"/> | |||
<line text="public void I.setX(int)"/> | |||
<line text="public int I.getX()"/> | |||
<line text="private int I.x"/> | |||
<line text="private int I.x"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="compatibility/case1" title="generating code for a 1.2.1 runtime - 1"> | |||
<compile files="Simple.java" options="-Xajruntimetarget:1.2"/> |