This test was always inactive and did not add any value other than during development. No it runs, passes and documents the status quo of - what was fixed (regression for AJC 1.8.2 core dump fixed in 1.8.3), - the current limitations of @DeclareParents and @DeclareMixin regarding generic interfaces. Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>tags/V1_9_20
@@ -1,5 +1,3 @@ | |||
package de.scrum_master.app; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
@@ -7,4 +5,4 @@ import java.lang.annotation.Target; | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.TYPE) | |||
public @interface EntityController {} | |||
public @interface EntityController { } |
@@ -1,16 +1,15 @@ | |||
package de.scrum_master.app; | |||
import org.aspectj.lang.annotation.Aspect; | |||
import org.aspectj.lang.annotation.*; | |||
@Aspect | |||
public class EntityControllerAspect { | |||
@DeclareParents(value = "@EntityController *", defaultImpl = EntityMongoController.class) | |||
private IEntityController iEntityController; | |||
@DeclareParents(value = "@EntityController *", defaultImpl = EntityMongoController.class) | |||
private IEntityController iEntityController; | |||
/* | |||
@DeclareMixin("@EntityController *") | |||
private IEntityController createEntityControllerInstance() { | |||
return new EntityMongoController(); | |||
} | |||
@DeclareMixin("@EntityController *") | |||
private IEntityController createEntityControllerInstance() { | |||
return new EntityMongoController(); | |||
} | |||
*/ | |||
} |
@@ -1,8 +1,7 @@ | |||
package de.scrum_master.app; | |||
public class EntityMongoController<T> implements IEntityController<T> { | |||
private T entity; | |||
private T entity; | |||
public void setEntity(T entity) { this.entity = entity; } | |||
public void setEntity(T entity) { this.entity = entity; } | |||
public T getEntity() { return entity; } | |||
public T getEntity() { return entity; } | |||
} |
@@ -1,6 +1,5 @@ | |||
package de.scrum_master.app; | |||
public interface IEntityController<T> { | |||
void setEntity(T entity); | |||
T getEntity(); | |||
void setEntity(T entity); | |||
T getEntity(); | |||
} |
@@ -1,37 +1,44 @@ | |||
package de.scrum_master.app; | |||
import java.lang.reflect.Method; | |||
@EntityController | |||
public class MyAnnotatedController<T> { | |||
public void doSomething() { | |||
System.out.println("Doing something"); | |||
} | |||
public void doSomething() { | |||
System.out.println("Doing something"); | |||
} | |||
public static void main(String[] args) { | |||
// Use class type directly so as to call its method | |||
MyAnnotatedController<String> annotatedTextController = new MyAnnotatedController<>(); | |||
annotatedTextController.doSomething(); | |||
public static void main(String[] args) { | |||
// Use class type directly so as to call its method | |||
MyAnnotatedController<String> annotatedTextController = new MyAnnotatedController<>(); | |||
annotatedTextController.doSomething(); | |||
// Print all declared methods (should also show interface methods introduced via ITD) | |||
for (Method method : annotatedTextController.getClass().getDeclaredMethods()) { | |||
if (!method.getName().startsWith("ajc$")) | |||
System.out.println(method); | |||
} | |||
// Print all declared methods (should also show interface methods introduced via ITD) | |||
for (Method method : annotatedTextController.getClass().getDeclaredMethods()) { | |||
if (!method.getName().startsWith("ajc$")) | |||
System.out.println(method); | |||
} | |||
// Prove that class type is compatible with interface type | |||
//IEntityController<String> entityTextController = annotatedTextController; | |||
//entityTextController.setEntity("foo"); | |||
// Would not work here because generic interface type is type-safe: | |||
// entityNumberController.setEntity(123); | |||
//System.out.println("Entity value = " + entityTextController.getEntity()); | |||
// Prove that class type is compatible with interface type | |||
// | |||
// NOTE: As explained in https://bugs.eclipse.org/bugs/show_bug.cgi?id=442425#c2, @DeclareParents will add the | |||
// raw form of the parent to the target class, not the generic one. Therefore, the additional cast is necessary. | |||
// Otherwise, AJC would throw: | |||
// Type mismatch: cannot convert from MyAnnotatedController<String> to IEntityController<String> | |||
IEntityController<String> entityTextController = (IEntityController<String>) annotatedTextController; | |||
entityTextController.setEntity("foo"); | |||
// Would not work here because generic interface type is type-safe: | |||
// entityNumberController.setEntity(123); | |||
System.out.println("Entity value = " + entityTextController.getEntity()); | |||
// Create another object and directly assign it to interface type | |||
//IEntityController<Integer> entityNumberController = new MyAnnotatedController<>(); | |||
//entityNumberController.setEntity(123); | |||
// Would not work here because generic interface type is type-safe: | |||
// entityNumberController.setEntity("foo"); | |||
//System.out.println("Entity value = " + entityNumberController.getEntity()); | |||
} | |||
// Create another object and directly assign it to interface type. | |||
// | |||
// NOTE: As explained in https://bugs.eclipse.org/bugs/show_bug.cgi?id=442425#c2, @DeclareParents will add the | |||
// raw form of the parent to the target class, not the generic one. Therefore, the additional cast is necessary. | |||
// Otherwise, AJC would throw: | |||
// Cannot infer type arguments for MyAnnotatedController<> | |||
IEntityController<Integer> entityNumberController = (IEntityController<Integer>) new MyAnnotatedController<>(); | |||
entityNumberController.setEntity(123); | |||
// Would not work here because generic interface type is type-safe: | |||
// entityNumberController.setEntity("foo"); | |||
System.out.println("Entity value = " + entityNumberController.getEntity()); | |||
} | |||
} | |||
@@ -78,10 +78,10 @@ public class Ajc183Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
public void testVerifyError_443447() { | |||
runTest("verifyerror"); | |||
} | |||
// | |||
// public void testAnnoStyleDecp_442425() { | |||
// runTest("anno style decp"); | |||
// } | |||
public void testAnnoStyleDecp_442425() { | |||
runTest("anno style decp"); | |||
} | |||
// --- | |||
@@ -156,25 +156,30 @@ | |||
<ajc-test dir="bugs183/442425" title="anno style decp"> | |||
<compile options="-1.8" files="EntityController.java IEntityController.java MyAnnotatedController.java EntityControllerAspect.java EntityMongoController.java"> | |||
<message kind="error" line="23" text="Type mismatch: cannot convert from MyAnnotatedController<String> to IEntityController<String>"/> | |||
<message kind="error" line="30" text="Cannot infer type arguments for MyAnnotatedController<>"/> | |||
<!-- | |||
NOTE: As explained in https://bugs.eclipse.org/bugs/show_bug.cgi?id=442425#c2, @DeclareParents will add the | |||
raw form of the parent to the target class, not the generic one. Therefore, without additional casts AJC would | |||
throw the following two errors: | |||
--> | |||
<!--<message kind="error" line="26" text="Type mismatch: cannot convert from MyAnnotatedController<String> to IEntityController<String>"/>--> | |||
<!--<message kind="error" line="38" text="Cannot infer type arguments for MyAnnotatedController<>"/>--> | |||
</compile> | |||
<!-- | |||
<run class="de.scrum_master.app.MyAnnotatedController"> | |||
<stdout> | |||
<line text="Doing something"/> | |||
<line text="public static void de.scrum_master.app.MyAnnotatedController.main(java.lang.String[])"/> | |||
<line text="public void de.scrum_master.app.MyAnnotatedController.doSomething()"/> | |||
<line text="public java.lang.Object de.scrum_master.app.MyAnnotatedController.getEntity()"/> | |||
<line text="public void de.scrum_master.app.MyAnnotatedController.setEntity(java.lang.Object)"/> | |||
<line text="Entity value = foo"/> | |||
<line text="Entity value = 123"/> | |||
</stdout> | |||
<run class="MyAnnotatedController"> | |||
<stdout ordered="no"> | |||
<line text="Doing something"/> | |||
<line text="public static void MyAnnotatedController.main(java.lang.String[])"/> | |||
<line text="public void MyAnnotatedController.doSomething()"/> | |||
<!-- Object, not generic type --> | |||
<line text="public java.lang.Object MyAnnotatedController.getEntity()"/> | |||
<!-- Object, not generic type --> | |||
<line text="public void MyAnnotatedController.setEntity(java.lang.Object)"/> | |||
<line text="Entity value = foo"/> | |||
<line text="Entity value = 123"/> | |||
</stdout> | |||
</run> | |||
--> | |||
</ajc-test> | |||
<ajc-test dir="bugs183/443477" title="verifyerror"> | |||
<ajc-test dir="bugs183/443477" title="verifyerror"> | |||
<compile options="-1.7" files="Coo.java"/> | |||
<run class="Coo"/> | |||
</ajc-test> |