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;
// 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);
public aspect BlobContainment extends ParentChildRelationship<Blob,Blob> {
-
public static void main(String []argv) {
Blob a = new Blob();
Blob b = new 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());
+*/
}
}
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);
((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);
}
+*/
--- /dev/null
+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;
+ }
+ }
+
+}
* 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() {
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");}
<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 -->
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);
}
/**