Browse Source

442425: fix error on attempted annotation style decp

tags/V1_8_3
Andy Clement 9 years ago
parent
commit
d929114a66

+ 10
- 0
tests/bugs183/442425/EntityController.java View File

@@ -0,0 +1,10 @@
package de.scrum_master.app;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface EntityController {}

+ 16
- 0
tests/bugs183/442425/EntityControllerAspect.java View File

@@ -0,0 +1,16 @@
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;
/*
@DeclareMixin("@EntityController *")
private IEntityController createEntityControllerInstance() {
return new EntityMongoController();
}
*/
}

+ 8
- 0
tests/bugs183/442425/EntityMongoController.java View File

@@ -0,0 +1,8 @@
package de.scrum_master.app;

public class EntityMongoController<T> implements IEntityController<T> {
private T entity;

public void setEntity(T entity) { this.entity = entity; }
public T getEntity() { return entity; }
}

+ 6
- 0
tests/bugs183/442425/IEntityController.java View File

@@ -0,0 +1,6 @@
package de.scrum_master.app;

public interface IEntityController<T> {
void setEntity(T entity);
T getEntity();
}

+ 37
- 0
tests/bugs183/442425/MyAnnotatedController.java View File

@@ -0,0 +1,37 @@
package de.scrum_master.app;

import java.lang.reflect.Method;

@EntityController
public class MyAnnotatedController<T> {
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();

// 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());

// 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());
}
}


BIN
tests/bugs183/442425/de/scrum_master/app/EntityController.class View File


BIN
tests/bugs183/442425/de/scrum_master/app/EntityControllerAspect.class View File


BIN
tests/bugs183/442425/de/scrum_master/app/EntityMongoController.class View File


BIN
tests/bugs183/442425/de/scrum_master/app/IEntityController.class View File


BIN
tests/bugs183/442425/de/scrum_master/app/MyAnnotatedController.class View File


+ 39
- 0
tests/src/org/aspectj/systemtest/ajc183/Ajc183Tests.java View File

@@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2014 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://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andy Clement - initial API and implementation
*******************************************************************************/
package org.aspectj.systemtest.ajc183;

import java.io.File;

import junit.framework.Test;

import org.aspectj.testing.XMLBasedAjcTestCase;

/**
* @author Andy Clement
*/
public class Ajc183Tests extends org.aspectj.testing.XMLBasedAjcTestCase {

public void testAnnoStyleDecp_442425() {
runTest("anno style decp");
}

// ---

public static Test suite() {
return XMLBasedAjcTestCase.loadSuite(Ajc183Tests.class);
}

@Override
protected File getSpecFile() {
return getClassResource("ajc183.xml");
}

}

+ 27
- 0
tests/src/org/aspectj/systemtest/ajc183/AllTestsAspectJ183.java View File

@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2014 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://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andy Clement - initial API and implementation
*******************************************************************************/
package org.aspectj.systemtest.ajc183;

import junit.framework.Test;
import junit.framework.TestSuite;
import org.aspectj.systemtest.apt.AptTests;

public class AllTestsAspectJ183 {

public static Test suite() {
TestSuite suite = new TestSuite("AspectJ 1.8.3 tests");
// $JUnit-BEGIN$
suite.addTest(Ajc183Tests.suite());
suite.addTest(AptTests.suite());
// $JUnit-END$
return suite;
}
}

+ 25
- 0
tests/src/org/aspectj/systemtest/ajc183/ajc183.xml View File

@@ -0,0 +1,25 @@
<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>

<suite>

<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&lt;String&gt; to IEntityController&lt;String&gt;"/>
<message kind="error" line="30" text="Cannot infer type arguments for MyAnnotatedController&lt;&gt;"/>
</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>
-->
</ajc-test>
</suite>

+ 10
- 16
weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java View File

@@ -726,6 +726,9 @@ public class AtAjAttributes {
TypePattern typePattern = parseTypePattern(decpPattern, struct);
ResolvedType fieldType = UnresolvedType.forSignature(struct.field.getSignature()).resolve(
struct.enclosingType.getWorld());
if (fieldType.isParameterizedOrRawType()) {
fieldType = fieldType.getGenericType();
}
if (fieldType.isInterface()) {
TypePattern parent = parseTypePattern(fieldType.getName(), struct);
FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
@@ -772,9 +775,7 @@ public class AtAjAttributes {
hasNoCtorOrANoArgOne = false;

if (resolvedMember.getParameterTypes().length == 0) {
if (defaultVisibilityImpl) { // default
// visibility
// implementation
if (defaultVisibilityImpl) { // default visibility implementation
if (resolvedMember.isPublic() || resolvedMember.isDefault()) {
hasNoCtorOrANoArgOne = true;
} else {
@@ -819,11 +820,6 @@ public class AtAjAttributes {
Iterator<ResolvedMember> methodIterator = fieldType.getMethodsIncludingIntertypeDeclarations(false, true);
while (methodIterator.hasNext()) {
ResolvedMember method = methodIterator.next();

// ResolvedMember[] methods = fieldType.getMethodsWithoutIterator(true, false, false).toArray(
// new ResolvedMember[0]);
// for (int i = 0; i < methods.length; i++) {
// ResolvedMember method = methods[i];
if (method.isAbstract()) {
// moved to be detected at weave time if the target
// doesnt implement the methods
@@ -849,22 +845,19 @@ public class AtAjAttributes {
// So here we create a modified method with an
// alternative declaring type so that we lookup
// the right field. See pr164016.
MethodDelegateTypeMunger mdtm = new MethodDelegateTypeMunger(method, struct.enclosingType,
defaultImplClassName, typePattern);
MethodDelegateTypeMunger mdtm = new MethodDelegateTypeMunger(method, struct.enclosingType, defaultImplClassName, typePattern);
mdtm.setFieldType(fieldType);
mdtm.setSourceLocation(struct.enclosingType.getSourceLocation());
struct.ajAttributes.add(new AjAttribute.TypeMunger(mdtm));
}
}
// successfull so far, we thus need a bcel type munger to
// have
// successful so far, we thus need a bcel type munger to have
// a field hosting the mixin in the target type
if (hasAtLeastOneMethod && defaultImplClassName != null) {
ResolvedMember fieldHost = AjcMemberMaker.itdAtDeclareParentsField(null, fieldType, struct.enclosingType);
struct.ajAttributes.add(new AjAttribute.TypeMunger(new MethodDelegateTypeMunger.FieldHostTypeMunger(
fieldHost, struct.enclosingType, typePattern)));
}

return true;
} else {
reportError("@DeclareParents: can only be used on a field whose type is an interface", struct);
@@ -915,7 +908,6 @@ public class AtAjAttributes {
// No annotation found
return false;
}

Method annotatedMethod = struct.method;
World world = struct.enclosingType.getWorld();
NameValuePair declareMixinPatternNameValuePair = getAnnotationElement(declareMixinAnnotation, VALUE);
@@ -926,7 +918,9 @@ public class AtAjAttributes {

// Return value of the annotated method is the interface or class that the mixin delegate should have
ResolvedType methodReturnType = UnresolvedType.forSignature(annotatedMethod.getReturnType().getSignature()).resolve(world);

if (methodReturnType.isParameterizedOrRawType()) {
methodReturnType = methodReturnType.getGenericType();
}
if (methodReturnType.isPrimitiveType()) {
reportError(getMethodForMessage(struct) + ": factory methods for a mixin cannot return void or a primitive type",
struct);
@@ -942,7 +936,7 @@ public class AtAjAttributes {
// supplied as a list in the 'Class[] interfaces' value in the annotation value
// supplied as just the interface return value of the annotated method
// supplied as just the class return value of the annotated method
NameValuePair interfaceListSpecified = getAnnotationElement(declareMixinAnnotation, "interfaces");
NameValuePair interfaceListSpecified = getAnnotationElement(declareMixinAnnotation, "interfaces");

List<TypePattern> newParents = new ArrayList<TypePattern>(1);
List<ResolvedType> newInterfaceTypes = new ArrayList<ResolvedType>(1);

Loading…
Cancel
Save