Browse Source

Fix for ordering problem when using generic abstract aspects. Fix for crappy code (of mine) in ResolvedType.discover... - see pr112105 comment #10

tags/V1_5_0RC1
aclement 18 years ago
parent
commit
720a6d9d5c

+ 11
- 2
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java View File

@@ -47,6 +47,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
@@ -251,8 +252,16 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
// Look at the supertype first
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COLLECTING_ITDS_AND_DECLARES, sourceType.sourceName);
ReferenceBinding superType = sourceType.superclass();
if (yetToProcess.contains(superType) && superType instanceof SourceTypeBinding) {
collectAllITDsAndDeclares((SourceTypeBinding)superType, yetToProcess);
if (superType instanceof SourceTypeBinding) {
if (yetToProcess.contains(superType)) {
collectAllITDsAndDeclares((SourceTypeBinding)superType, yetToProcess);
}
} else if (superType instanceof ParameterizedTypeBinding) {
// If its a PTB we need to pull the SourceTypeBinding out of it.
ParameterizedTypeBinding ptb = (ParameterizedTypeBinding)superType;
if (ptb.type instanceof SourceTypeBinding && yetToProcess.contains(ptb.type)) {
collectAllITDsAndDeclares((SourceTypeBinding)ptb.type, yetToProcess);
}
}
buildInterTypeAndPerClause(sourceType.scope);
addCrosscuttingStructures(sourceType.scope);

+ 2
- 1
tests/java5/generics/genericaspects/BlobContainment.aj View File

@@ -1,6 +1,5 @@
public aspect BlobContainment extends ParentChildRelationship<Blob,Blob> {


public static void main(String []argv) {
Blob a = new Blob();
Blob b = new Blob();
@@ -17,12 +16,14 @@ public aspect BlobContainment extends ParentChildRelationship<Blob,Blob> {

// now query the layout

/*
if (!e.getParent().equals(b))
throw new RuntimeException("why is E not parent of B? "+e.getParent());
if (!d.getParent().equals(a))
throw new RuntimeException("why is A not parent of D? "+d.getParent());
if (a.getChildren().size()!=3)
throw new RuntimeException("A should have 3 children, not:"+a.getChildren().size());
*/
}

}

+ 72
- 34
tests/java5/generics/genericaspects/ParentChildRelationship.aj View File

@@ -1,57 +1,99 @@
import java.util.*;
import org.aspectj.lang.annotation.*;

abstract aspect ParentChildRelationship<Parent,Child> {

interface ParentHasChildren<C>{}
interface ChildHasParent<P>{}

declare parents: Parent implements ParentHasChildren<Child>;
declare parents: Child implements ChildHasParent<Parent>;

public List<E> ParentHasChildren<E>.children = new ArrayList<E>();
public P ChildHasParent<P>.parent;

public List<D> ParentHasChildren<D>.getChildren() {
return Collections.unmodifiableList(children);
}

public P ChildHasParent<P>.getParent() {
return parent;
}

public void ChildHasParent<R>.setParent(R parent) {
this.parent = parent;
ParentHasChildren phc = (ParentHasChildren)parent;
if (phc.getChildren().contains(this))
phc.addChild(this);
}

public void ParentHasChildren<X>.addChild(X child) {
if (((ChildHasParent)child).parent != null) {
((ParentHasChildren)((ChildHasParent)child).parent).removeChild(child);
} else {
((ChildHasParent)child).setParent((ParentHasChildren)this);
}
children.add(child);
}

public void ParentHasChildren<Y>.removeChild(Y child) {
if (children.remove(child)) {
((ChildHasParent)child).parent = null;
}
}

}
/*
abstract aspect ParentChildRelationship<Parent,Child> {

/** interface implemented by parents */
// interface implemented by parents
interface ParentHasChildren<C>{
// List<C> getChildren();
// void addChild(C child);
// void removeChild(C child);
List<C> getChildren();
void addChild(C child);
void removeChild(C child);
}

/** interface implemented by children */
// interface implemented by children
interface ChildHasParent<P>{
// P getParent();
// void setParent(P parent);
P getParent();
void setParent(P parent);
}

/** ensure the parent type implements ParentHasChildren<child type> */
// ensure the parent type implements ParentHasChildren<child type>
declare parents: Parent implements ParentHasChildren<Child>;

/** ensure the child type implements ChildHasParent<parent type> */
// ensure the child type implements ChildHasParent<parent type>
declare parents: Child implements ChildHasParent<Parent>;

// Inter-type declarations made on the *generic* interface types to provide
// default implementations.

/** list of children maintained by parent */
// list of children maintained by parent
public List<E> ParentHasChildren<E>.children = new ArrayList<E>();

/** reference to parent maintained by child */
// reference to parent maintained by child
public P ChildHasParent<P>.parent;

/** Default implementation of getChildren for the generic type ParentHasChildren */
// Default implementation of getChildren for the generic
// type ParentHasChildren
public List<D> ParentHasChildren<D>.getChildren() {
return Collections.unmodifiableList(children);
}

/** Default implementation of getParent for the generic type ChildHasParent */
// Default implementation of getParent for the generic
// type ChildHasParent
public P ChildHasParent<P>.getParent() {
return parent;
}

/**
* Default implementation of setParent for the generic type ChildHasParent.
* Ensures that this child is added to the children of the parent too.
*/
// Default implementation of setParent for the generic type ChildHasParent.
// Ensures that this child is added to the children of the parent too.
public void ChildHasParent<R>.setParent(R parent) {
((ParentHasChildren)parent).addChild(this);
}

/**
* Default implementation of addChild, ensures that parent of child is
* also updated.
*/
// Default implementation of addChild, ensures that parent of child is
// also updated.
public void ParentHasChildren<X>.addChild(X child) {
if (((ChildHasParent)child).parent != null) {
((ParentHasChildren)((ChildHasParent)child).parent).removeChild(child);
@@ -60,27 +102,23 @@ abstract aspect ParentChildRelationship<Parent,Child> {
((ChildHasParent)child).parent = (ParentHasChildren)this;
}

/**
* Default implementation of removeChild, ensures that parent of
* child is also updated.
*/
// Default implementation of removeChild, ensures that parent of
// child is also updated.
public void ParentHasChildren<Y>.removeChild(Y child) {
if (children.remove(child)) {
((ChildHasParent)child).parent = null;
}
}
/**
* Matches at an addChild join point for the parent type P and child type C
*/

// Matches at an addChild join point for the parent type P and child type C
@SuppressAjWarnings
public pointcut addingChild(Parent p, Child c) :
execution(* Parent.addChild(Child)) && this(p) && args(c);
/**
* Matches at a removeChild join point for the parent type P and child type C
*/
@SuppressAjWarnings
public pointcut removingChild(Parent p, Child c) :
execution(* Parent.removeChild(Child)) && this(p) && args(c);
// Matches at a removeChild join point for the parent type P and child type C
@SuppressAjWarnings
public pointcut removingChild(Parent p, Child c) :
execution(* Parent.removeChild(Child)) && this(p) && args(c);

}
*/

+ 76
- 0
tests/java5/generics/genericaspects/TheBigOne.java View File

@@ -0,0 +1,76 @@
import java.util.*;
import org.aspectj.lang.annotation.*;

class Blob {}

public aspect TheBigOne extends ParentChildRelationship<Blob,Blob> {

public static void main(String []argv) {
Blob a = new Blob();
Blob b = new Blob();
Blob c = new Blob();
Blob d = new Blob();
Blob e = new Blob();

// arrange as follows: A contains B,C,D and B contains E

a.addChild(b);
a.addChild(c);
a.addChild(d);
b.addChild(e);

// now query the layout

if (!e.getParent().equals(b))
throw new RuntimeException("why is E not parent of B? "+e.getParent());
if (!d.getParent().equals(a))
throw new RuntimeException("why is A not parent of D? "+d.getParent());
if (a.getChildren().size()!=3)
throw new RuntimeException("A should have 3 children, not:"+a.getChildren().size());
}

}


abstract aspect ParentChildRelationship<Parent,Child> {

interface ParentHasChildren<C>{}
interface ChildHasParent<P>{}

declare parents: Parent implements ParentHasChildren<Child>;
declare parents: Child implements ChildHasParent<Parent>;

public List<E> ParentHasChildren<E>.children = new ArrayList<E>();
public P ChildHasParent<P>.parent;

public List<D> ParentHasChildren<D>.getChildren() {
return Collections.unmodifiableList(children);
}

public P ChildHasParent<P>.getParent() {
return parent;
}

public void ChildHasParent<R>.setParent(R parent) {
this.parent = parent;
ParentHasChildren phc = (ParentHasChildren)parent;
if (phc.getChildren().contains(this))
phc.addChild(this);
}

public void ParentHasChildren<X>.addChild(X child) {
if (((ChildHasParent)child).parent != null) {
((ParentHasChildren)((ChildHasParent)child).parent).removeChild(child);
} else {
((ChildHasParent)child).setParent((ParentHasChildren)this);
}
children.add(child);
}

public void ParentHasChildren<Y>.removeChild(Y child) {
if (children.remove(child)) {
((ChildHasParent)child).parent = null;
}
}

}

+ 2
- 6
tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java View File

@@ -170,10 +170,6 @@ public class GenericsTests extends XMLBasedAjcTestCase {
* TODO exotic class/interface bounds ('? extends List<String>','? super anything')
* TODO signature attributes for generic ITDs (public only?)
*
*
* strangeness:
*
* adding declare precedence into the itds/binaryweaving A2.aj, A3.aj causes a bizarre classfile inconsistent message
*/
public static Test suite() {
@@ -221,8 +217,8 @@ public class GenericsTests extends XMLBasedAjcTestCase {
public void testPR96220_GenericAspects2() {runTest("generic aspects - 2");}
public void testPR96220_GenericAspects3() {runTest("generic aspects - 3");}
public void testGenericAspects4() {runTest("generic aspects - 4");}
// TODO FREAKYGENERICASPECTPROBLEM why does everything have to be in one source file?
// public void testGenericAspects5() {runTest("generic aspects - 5 (ajdk)");}
public void testGenericAspects5() {runTest("generic aspects - 5 (ajdk)");} // in separate files
public void testGenericAspects6() {runTest("generic aspects - 6 (ajdk)");} // all in one file
public void testTypeVariablesInDeclareWarning() { runTest("generic aspect with declare warning using type vars");}
public void testTypeVariablesInExecutionAdvice() { runTest("generic aspect with execution advice using type vars");}
public void testTypeVariablesInAnonymousPointcut() { runTest("generic aspect with anonymous pointcut");}

+ 6
- 0
tests/src/org/aspectj/systemtest/ajc150/ajc150.xml View File

@@ -3081,6 +3081,12 @@
<run class="BlobContainment"/>
</ajc-test>
<!-- same as above but all types in one file -->
<ajc-test dir="java5/generics/genericaspects" title="generic aspects - 6 (ajdk)">
<compile files="TheBigOne.java" options="-1.5"/>
<run class="TheBigOne"/>
</ajc-test>
<!-- end of generic aspects -->
<!-- generic ITDs -->

+ 2
- 2
weaver/src/org/aspectj/weaver/ResolvedType.java View File

@@ -1288,10 +1288,10 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
for (int i = 0; i < superIs.length; i++) {
ResolvedType superI = superIs[i];
if (superI.genericTypeEquals(lookingFor)) return superI;
ResolvedType checkTheSuperI = discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
ResolvedType checkTheSuperI = superI.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
if (checkTheSuperI!=null) return checkTheSuperI;
}
return discoverActualOccurrenceOfTypeInHierarchy(superT);
return superT.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
}

/**

Loading…
Cancel
Save