--- /dev/null
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class GenericAspectWithAnnotationTypeParameter {
+
+ @AnnOne
+ @AnnTwo
+ public static void main(String[] args) {
+ System.out.println("hello");
+ }
+
+
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface AnnOne {}
+@interface AnnTwo {}
+
+abstract aspect AnnotationMatcher<A extends Annotation> {
+
+ before() : execution(* *(..)) && @annotation(A) {
+ System.out.println("annotation match - no binding");
+ }
+
+ before() : execution(@A * *(..)) {
+ System.out.println("execution with annotation match");
+ }
+
+ before(A anAnnotation) : execution(* *(..)) && @annotation(anAnnotation) {
+ System.out.println("annotation match - binding");
+ }
+}
+
+aspect AnnOneMatcher extends AnnotationMatcher<AnnOne> {}
\ No newline at end of file
--- /dev/null
+abstract aspect AbstractSystemArchitecture {
+
+ public abstract pointcut inMyApplication();
+
+ // more pointcuts below...
+
+}
+
+aspect MySystemArchitecture extends AbstractSystemArchitecture {
+
+ public pointcut inMyApplication() : within(SomeClass);
+
+}
+
+abstract aspect NoDirectlyRunnableClasses<A extends AbstractSystemArchitecture> {
+
+ declare warning : execution(public static void main(String[])) &&
+ A.inMyApplication()
+ : "no directly runnable classes";
+
+}
+
+aspect NoRunnablesInMyApp extends NoDirectlyRunnableClasses<MySystemArchitecture> {
+
+}
+
+
+class SomeClass {
+
+ public static void main(String[] args) { // CW L30
+ System.out.println("hello");
+ }
+
+}
+
+class SomeOtherClass {
+
+ public static void main(String[] args) { // no warning
+ System.out.println("hello");
+ }
+
+}
\ No newline at end of file
runTest("aop.xml aspect inherits abstract method that has concrete implementation in parent");
}
+ public void testGenericAspectsWithAnnotationTypeParameters() {
+ runTest("Generic aspects with annotation type parameters");
+ }
+
+ public void testPointcutInterfaces_pr130869() {
+ runTest("Pointcut interfaces");
+ }
+
/////////////////////////////////////////
public static Test suite() {
return XMLBasedAjcTestCase.loadSuite(Ajc151Tests.class);
protected File getSpecFile() {
return new File("../tests/src/org/aspectj/systemtest/ajc151/ajc151.xml");
}
+
}
\ No newline at end of file
<compile files="pr128237.java" options="-1.5"/>
</ajc-test>
+ <ajc-test dir="bugs151" title="Generic aspects with annotation type parameters">
+ <compile files="GenericAspectWithAnnotationTypeParameter.aj" options="-1.5"/>
+ <run class="GenericAspectWithAnnotationTypeParameter">
+ <stdout>
+ <line text="annotation match - no binding"/>
+ <line text="execution with annotation match"/>
+ <line text="annotation match - binding"/>
+ <line text="hello"/>
+ </stdout>
+ </run>
+ </ajc-test>
+
+ <ajc-test dir="bugs151" title="Pointcut interfaces">
+ <compile files="pr130869.aj" options="-1.5">
+ <message kind="warning" line="30" text="no directly runnable classes"/>
+ </compile>
+ </ajc-test>
+
<!-- New features down here... when they arent big enough to have their own test file -->
<ajc-test dir="features151/ptw" title="exposing withintype">
} else {
searchType = scope.getEnclosingType();
}
+ if (searchType.isTypeVariableReference()) {
+ searchType = ((TypeVariableReference)searchType).getTypeVariable().getUpperBound().resolve(scope.getWorld());
+ }
arguments.resolveBindings(scope, bindings, true, true);
}
if (Modifier.isAbstract(pointcutDef.getModifiers())) {
- if (onType != null) {
+ if (onType != null && !onType.isTypeVariableReference()) {
scope.message(IMessage.ERROR, this,
"can't make static reference to abstract pointcut");
return;
} else if (onType.isGenericType()) {
scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_REFERENCE_POINTCUT_IN_RAW_TYPE),
getSourceLocation()));
- }
+ }
}
for (int i=0,len=arguments.size(); i < len; i++) {
if (searchStart.isMissing()) {
return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
}
- }
+ if (onType.isTypeVariableReference()) {
+ // need to replace on type with the binding for the type variable
+ // in the declaring type
+ if (declaringType.isParameterizedType()) {
+ TypeVariable[] tvs = declaringType.getGenericType().getTypeVariables();
+ String typeVariableName = ((TypeVariableReference)onType).getTypeVariable().getName();
+ for (int i = 0; i < tvs.length; i++) {
+ if (tvs[i].getName().equals(typeVariableName)) {
+ ResolvedType realOnType = declaringType.getTypeParameters()[i].resolve(declaringType.getWorld());
+ onType = realOnType;
+ searchStart = realOnType;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
if (declaringType == null) declaringType = searchStart;
pointcutDec = declaringType.findPointcut(name);
boolean foundMatchingPointcut = (pointcutDec != null && pointcutDec.isPrivate());