Browse Source

fix for 142466

tags/V1_5_2rc1
aclement 18 years ago
parent
commit
69e24e90d4

+ 63
- 21
loadtime/src/org/aspectj/weaver/loadtime/ConcreteAspectCodeGen.java View File

@@ -38,9 +38,12 @@ import org.aspectj.weaver.patterns.PerSingleton;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* Generates bytecode for concrete-aspect
@@ -159,27 +162,35 @@ public class ConcreteAspectCodeGen {

// must have all abstractions defined
List elligibleAbstractions = new ArrayList();
Iterator methods = m_parent.getMethods();
while (methods.hasNext()) {
ResolvedMember method = (ResolvedMember) methods.next();
if (method.isAbstract()) {
if ("()V".equals(method.getSignature())) {
String n = method.getName();
if (n.startsWith("ajc$pointcut")) { // Allow for the abstract pointcut being from a code style aspect compiled with -1.5 (see test for 128744)
n = n.substring(14);
n = n.substring(0,n.indexOf("$"));
elligibleAbstractions.add(n);
} else {
// Only interested in abstract methods that take no parameters and are marked @Pointcut
if (hasPointcutAnnotation(method))
elligibleAbstractions.add(method.getName());
}
} else {
reportError("Abstract method '" + method.getName() + "' cannot be concretized as a pointcut (illegal signature, must have no arguments, must return void): " + stringify());
return false;
}
Collection abstractMethods = getOutstandingAbstractMethods(m_parent);
for (Iterator iter = abstractMethods.iterator(); iter.hasNext();) {
ResolvedMember method = (ResolvedMember) iter.next();
if ("()V".equals(method.getSignature())) {
String n = method.getName();
if (n.startsWith("ajc$pointcut")) { // Allow for the abstract pointcut being from a code style aspect compiled with -1.5 (see test for 128744)
n = n.substring(14);
n = n.substring(0,n.indexOf("$"));
elligibleAbstractions.add(n);
} else if (hasPointcutAnnotation(method)) {
elligibleAbstractions.add(method.getName());
} else {
// error, an outstanding abstract method that can't be concretized in XML
reportError("Abstract method '" + method.toString() + "' cannot be concretized in XML: " + stringify());
return false;
}
} else {
if (method.getName().startsWith("ajc$pointcut") || hasPointcutAnnotation(method)) {
// it may be a pointcut but it doesn't meet the requirements for XML concretization
reportError("Abstract method '" + method.toString() + "' cannot be concretized as a pointcut (illegal signature, must have no arguments, must return void): " + stringify());
return false;
} else {
// error, an outstanding abstract method that can't be concretized in XML
reportError("Abstract method '" + method.toString() + "' cannot be concretized in XML: " + stringify());
return false;
}
}
}
}
List pointcutNames = new ArrayList();
for (Iterator it = m_concreteAspect.pointcuts.iterator(); it.hasNext();) {
Definition.Pointcut abstractPc = (Definition.Pointcut) it.next();
@@ -198,7 +209,38 @@ public class ConcreteAspectCodeGen {
return m_isValid;
}

/**
private Collection getOutstandingAbstractMethods(ResolvedType type) {
Map collector = new HashMap();
// let's get to the top of the hierarchy and then walk down ... recording abstract methods then removing
// them if they get defined further down the hierarchy
getOutstandingAbstractMethodsHelper(type,collector);
return collector.values();
}
// We are trying to determine abstract methods left over at the bottom of a hierarchy that have not been
// concretized.
private void getOutstandingAbstractMethodsHelper(ResolvedType type,Map collector) {
if (type==null) return;
// Get to the top
if (type!=null && !type.equals(ResolvedType.OBJECT)) {
if (type.getSuperclass()!=null)
getOutstandingAbstractMethodsHelper(type.getSuperclass(),collector);
}
ResolvedMember[] rms = type.getDeclaredMethods();
if (rms!=null) {
for (int i = 0; i < rms.length; i++) {
ResolvedMember member = rms[i];
String key = member.getName()+member.getSignature();
if (member.isAbstract()) {
collector.put(key,member);
} else {
collector.remove(key);
}
}
}
}

/**
* Rebuild the XML snip that defines this concrete aspect, for log error purpose
*
* @return string repr.

+ 31
- 0
tests/bugs152/pr142466/AbstractMethods.aj View File

@@ -0,0 +1,31 @@
import org.aspectj.lang.annotation.*;


@Aspect
public abstract class AbstractMethods {

@Pointcut
protected abstract void tracingScope();

@Before("tracingScope()")
public void doit() {
test();
System.out.println("advice running");
}
protected abstract void test();
}

/*
public abstract aspect AbstractMethods {

protected abstract pointcut tracingScope ();
before () : tracingScope () {
test();
System.out.println("advice running");
}
protected abstract void test ();
// protected void test () {}
}
*/

+ 6
- 0
tests/bugs152/pr142466/AtAspectTestConcreteMethods.java View File

@@ -0,0 +1,6 @@
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AtAspectTestConcreteMethods extends ConcreteMethods {

}

+ 8
- 0
tests/bugs152/pr142466/ConcreteMethods.aj View File

@@ -0,0 +1,8 @@


public abstract aspect ConcreteMethods extends AbstractMethods {

protected void test () {}
public abstract void foo(int i) ;

}

+ 11
- 0
tests/bugs152/pr142466/HelloWorld.java View File

@@ -0,0 +1,11 @@
public class HelloWorld {

public static void main(String[] args) {
new HelloWorld().println();
}

public void println() {
System.out.print("Hello World!");
}

}

+ 10
- 0
tests/bugs152/pr142466/aop-tracing.xml View File

@@ -0,0 +1,10 @@
<aspectj>
<aspects>
<concrete-aspect name="TraceHelloWorld" extends="ConcreteMethods">
<pointcut name="tracingScope" expression="within(HelloWorld) AND call(* println(..))"/>
</concrete-aspect>
</aspects>
<weaver options=""/>
</aspectj>


+ 31
- 0
tests/bugs152/pr142466/case2/AbstractMethods.aj View File

@@ -0,0 +1,31 @@
import org.aspectj.lang.annotation.*;


@Aspect
public abstract class AbstractMethods {

@Pointcut
protected abstract void tracingScope();

@Before("tracingScope()")
public void doit() {
test();
System.out.println("advice running");
}
protected abstract void test();
}

/*
public abstract aspect AbstractMethods {

protected abstract pointcut tracingScope ();
before () : tracingScope () {
test();
System.out.println("advice running");
}
protected abstract void test ();
// protected void test () {}
}
*/

+ 6
- 0
tests/bugs152/pr142466/case2/AtAspectTestConcreteMethods.java View File

@@ -0,0 +1,6 @@
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AtAspectTestConcreteMethods extends ConcreteMethods {

}

+ 7
- 0
tests/bugs152/pr142466/case2/ConcreteMethods.aj View File

@@ -0,0 +1,7 @@


public abstract aspect ConcreteMethods extends AbstractMethods {

// protected void test () {}

}

+ 11
- 0
tests/bugs152/pr142466/case2/HelloWorld.java View File

@@ -0,0 +1,11 @@
public class HelloWorld {

public static void main(String[] args) {
new HelloWorld().println();
}

public void println() {
System.out.print("Hello World!");
}

}

+ 10
- 0
tests/bugs152/pr142466/case2/aop-tracing.xml View File

@@ -0,0 +1,10 @@
<aspectj>
<aspects>
<concrete-aspect name="TraceHelloWorld" extends="ConcreteMethods">
<pointcut name="tracingScope" expression="within(HelloWorld) AND call(* println(..))"/>
</concrete-aspect>
</aspects>
<weaver options=""/>
</aspectj>


+ 2
- 0
tests/src/org/aspectj/systemtest/ajc152/Ajc152Tests.java View File

@@ -17,6 +17,8 @@ import org.aspectj.testing.XMLBasedAjcTestCase;

public class Ajc152Tests extends org.aspectj.testing.XMLBasedAjcTestCase {

public void testConcretizingAbstractMethods_pr142466() { runTest("aop.xml aspect inheriting but not concretizing abstract method");}
public void testConcretizingAbstractMethods_pr142466_2() { runTest("aop.xml aspect inheriting but not concretizing abstract method - 2");}
public void testComplexGenericDecl_pr137568() { runTest("complicated generics declaration");}
public void testItdOnInnerTypeOfGenericType_pr132349() { runTest("ITD on inner type of generic type");}
public void testItdOnInnerTypeOfGenericType_pr132349_2() { runTest("ITD on inner type of generic type - 2");}

+ 27
- 0
tests/src/org/aspectj/systemtest/ajc152/ajc152.xml View File

@@ -287,6 +287,33 @@
</run>
</ajc-test>
<ajc-test dir="bugs152/pr142466" title="aop.xml aspect inheriting but not concretizing abstract method">
<compile files="HelloWorld.java"/>
<compile files="AbstractMethods.aj, ConcreteMethods.aj" options="-1.5"/>
<run class="HelloWorld" ltw="aop-tracing.xml">
<stderr>
<line text="error Abstract method 'void ConcreteMethods.foo(int)' cannot be concretized in XML:"/>
<line text="warning register definition failed"/>
</stderr>
<stdout>
<line text="Hello World!"/>
</stdout>
</run>
</ajc-test>
<ajc-test dir="bugs152/pr142466/case2" title="aop.xml aspect inheriting but not concretizing abstract method - 2">
<compile files="HelloWorld.java"/>
<compile files="AbstractMethods.aj, ConcreteMethods.aj" options="-1.5"/>
<run class="HelloWorld" ltw="aop-tracing.xml">
<stderr>
<line text="error Abstract method 'void AbstractMethods.test()' cannot be concretized in XML"/>
<line text="warning register definition failed"/>
</stderr>
<stdout>
<line text="Hello World!"/>
</stdout>
</run>
</ajc-test>

<ajc-test dir="bugs152/pr138223" pr="138223" title="Double at annotation matching (no binding)">
<compile files="DoubleAnnotationMatching.aj" options="-1.5">

Loading…
Cancel
Save