summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2005-08-04 16:11:03 +0000
committeraclement <aclement>2005-08-04 16:11:03 +0000
commit900a3e81d5b09c55e4044451f311f0566c025ec6 (patch)
tree6c1f9e5e84d9edb9fb8f8728a8a701555b10db75 /weaver
parenta26f850c10f1790682ff9d1f13a4f8d5253f5e71 (diff)
downloadaspectj-900a3e81d5b09c55e4044451f311f0566c025ec6.tar.gz
aspectj-900a3e81d5b09c55e4044451f311f0566c025ec6.zip
genericitds: lots of new support for recursive type variables and ITD ctors.
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/BoundedReferenceType.java22
-rw-r--r--weaver/src/org/aspectj/weaver/JoinPointSignature.java17
-rw-r--r--weaver/src/org/aspectj/weaver/MemberImpl.java12
-rw-r--r--weaver/src/org/aspectj/weaver/ResolvedMember.java7
-rw-r--r--weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java35
-rw-r--r--weaver/src/org/aspectj/weaver/TypeFactory.java9
-rw-r--r--weaver/src/org/aspectj/weaver/TypeVariable.java6
-rw-r--r--weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java33
-rw-r--r--weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java4
-rw-r--r--weaver/src/org/aspectj/weaver/World.java28
10 files changed, 138 insertions, 35 deletions
diff --git a/weaver/src/org/aspectj/weaver/BoundedReferenceType.java b/weaver/src/org/aspectj/weaver/BoundedReferenceType.java
index dfb8efc30..48ec7f927 100644
--- a/weaver/src/org/aspectj/weaver/BoundedReferenceType.java
+++ b/weaver/src/org/aspectj/weaver/BoundedReferenceType.java
@@ -19,17 +19,23 @@ import org.aspectj.weaver.patterns.PerClause;
/**
* A BoundedReferenceType is the result of a generics wildcard expression
* ? extends String, ? super Foo etc..
+ *
* The "signature" for a bounded reference type follows the generic signature
- * specification in section 4.4 of JVM spec: *,+,- plus signature strings
+ * specification in section 4.4 of JVM spec: *,+,- plus signature strings.
+ *
+ * The bound may be a type variable (e.g. ? super T)
*/
public class BoundedReferenceType extends ReferenceType {
+
protected ReferenceType[] additionalInterfaceBounds = new ReferenceType[0];
+
protected boolean isExtends = true;
- protected boolean isSuper = false;
+ protected boolean isSuper = false;
public BoundedReferenceType(ReferenceType aBound, boolean isExtends, World world) {
super((isExtends ? "+" : "-") + aBound.signature,world);
- this.isExtends = isExtends; this.isSuper=!isExtends;
+ this.isExtends = isExtends;
+ this.isSuper = !isExtends;
if (isExtends) {
setUpperBound(aBound);
} else {
@@ -38,7 +44,7 @@ public class BoundedReferenceType extends ReferenceType {
}
setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)getUpperBound()));
}
-
+
public BoundedReferenceType(ReferenceType aBound, boolean isExtends, World world, ReferenceType[] additionalInterfaces) {
this(aBound,isExtends,world);
this.additionalInterfaceBounds = additionalInterfaces;
@@ -51,20 +57,22 @@ public class BoundedReferenceType extends ReferenceType {
/**
* only for use when resolving GenericsWildcardTypeX or a TypeVariableReferenceType
*/
- BoundedReferenceType(String sig, World world) {
+ protected BoundedReferenceType(String sig, World world) {
super(sig,world);
setUpperBound(world.resolve(UnresolvedType.OBJECT));
setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)getUpperBound()));
}
- public ReferenceType[] getInterfaceBounds() { return additionalInterfaceBounds; }
+ public ReferenceType[] getInterfaceBounds() {
+ return additionalInterfaceBounds;
+ }
public boolean hasLowerBound() {
return getLowerBound() != null;
}
public boolean isExtends() { return isExtends; }
- public boolean isSuper() { return isSuper; }
+ public boolean isSuper() { return isSuper; }
// override to include additional interface bounds...
public ResolvedType[] getDeclaredInterfaces() {
diff --git a/weaver/src/org/aspectj/weaver/JoinPointSignature.java b/weaver/src/org/aspectj/weaver/JoinPointSignature.java
index 12f66fca1..9fefcdf23 100644
--- a/weaver/src/org/aspectj/weaver/JoinPointSignature.java
+++ b/weaver/src/org/aspectj/weaver/JoinPointSignature.java
@@ -17,6 +17,7 @@ import java.util.Collection;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute;
+import org.aspectj.weaver.Member.Kind;
/**
* @author colyer
@@ -351,4 +352,20 @@ public class JoinPointSignature implements ResolvedMember {
return buf.toString();
}
+ public void resetName(String newName) {
+ realMember.resetName(newName);
+ }
+
+ public void resetKind(Kind newKind) {
+ realMember.resetKind(newKind);
+ }
+
+ public void resetModifiers(int newModifiers) {
+ realMember.resetModifiers(newModifiers);
+ }
+
+ public void resetReturnTypeToObjectArray() {
+ realMember.resetReturnTypeToObjectArray();
+ }
+
}
diff --git a/weaver/src/org/aspectj/weaver/MemberImpl.java b/weaver/src/org/aspectj/weaver/MemberImpl.java
index cf2a16548..96a4478b2 100644
--- a/weaver/src/org/aspectj/weaver/MemberImpl.java
+++ b/weaver/src/org/aspectj/weaver/MemberImpl.java
@@ -21,14 +21,14 @@ import java.util.Iterator;
import java.util.List;
-public class MemberImpl implements Comparable, AnnotatedElement, Member {
+public class MemberImpl implements Comparable, AnnotatedElement,Member {
- private final Kind kind;
+ protected Kind kind;
protected UnresolvedType declaringType;
- protected final int modifiers; // protected because ResolvedMember uses it
- private final UnresolvedType returnType;
- private final String name;
- private final UnresolvedType[] parameterTypes;
+ protected int modifiers;
+ protected UnresolvedType returnType;
+ protected String name;
+ protected UnresolvedType[] parameterTypes;
private final String signature;
private final String declaredSignature; // TODO asc Is this redundant? Is it needed for generics?
private String paramSignature;
diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java
index 6fd6c0a7c..17b1e2930 100644
--- a/weaver/src/org/aspectj/weaver/ResolvedMember.java
+++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java
@@ -17,6 +17,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.Member.Kind;
public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDeclaringElement {
@@ -135,5 +136,9 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
* variable to match any other type variable regardless of bounds.
*/
public boolean matches(ResolvedMember aCandidateMatch);
-
+
+ public void resetName(String newName);
+ public void resetKind(Kind newKind);
+ public void resetModifiers(int newModifiers);
+ public void resetReturnTypeToObjectArray();
} \ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
index de94d3c55..1acebd584 100644
--- a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
+++ b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Set;
import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.Member.Kind;
/**
* This is the declared member, i.e. it will always correspond to an
@@ -266,7 +267,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
public boolean hasAnnotation(UnresolvedType ofType) {
- // The ctors don't allow annotations to be specified ... yet - but
+ // The ctors don't allow annotations to be specified ... yet - but
// that doesn't mean it is an error to call this method.
// Normally the weaver will be working with subtypes of
// this type - BcelField/BcelMethod
@@ -372,7 +373,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
public ResolvedMember resolve(World world) {
- // FIXME asc guard with a check on resolution having happened !
+ // make sure all the pieces of a resolvedmember really are resolved
if (annotationTypes!=null) {
Set r = new HashSet();
for (Iterator iter = annotationTypes.iterator(); iter.hasNext();) {
@@ -383,7 +384,20 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
declaringType = declaringType.resolve(world);
if (declaringType.isRawType()) declaringType = ((ReferenceType)declaringType).getGenericType();
- return this;
+ if (typeVariables!=null && typeVariables.length>0) {
+ for (int i = 0; i < typeVariables.length; i++) {
+ UnresolvedType array_element = typeVariables[i];
+ typeVariables[i] = typeVariables[i].resolve(world);
+ }
+ }
+ if (parameterTypes!=null && parameterTypes.length>0) {
+ for (int i = 0; i < parameterTypes.length; i++) {
+ UnresolvedType array_element = parameterTypes[i];
+ parameterTypes[i] = parameterTypes[i].resolve(world);
+ }
+ }
+
+ returnType = returnType.resolve(world);return this;
}
public ISourceContext getSourceContext(World world) {
@@ -587,7 +601,20 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
private ResolvedMember myErasure = null;
private boolean calculatedMyErasure = false;
-
+
+
+ /**
+ * For ITDs, we use the default factory methods to build a resolved member, then alter a couple of characteristics
+ * using this method - this is safe.
+ */
+ public void resetName(String newName) {this.name = newName;}
+ public void resetKind(Kind newKind) {this.kind=newKind; }
+ public void resetModifiers(int newModifiers) {this.modifiers=newModifiers;}
+
+ public void resetReturnTypeToObjectArray() {
+ returnType = UnresolvedType.OBJECTARRAY;
+ }
+
/**
* Returns a copy of this member but with the declaring type swapped.
* Copy only needs to be shallow.
diff --git a/weaver/src/org/aspectj/weaver/TypeFactory.java b/weaver/src/org/aspectj/weaver/TypeFactory.java
index e81d63238..465747b4d 100644
--- a/weaver/src/org/aspectj/weaver/TypeFactory.java
+++ b/weaver/src/org/aspectj/weaver/TypeFactory.java
@@ -38,7 +38,7 @@ public class TypeFactory {
ResolvedType baseType = aBaseType;
if (!aBaseType.isGenericType()) {
// try and find the generic type...
- if (someTypeParameters != null) {
+ if (someTypeParameters != null && someTypeParameters.length>0) {
if (!aBaseType.isRawType()) throw new IllegalStateException("Expecting raw type");
baseType = baseType.getGenericType();
if (baseType == null) throw new IllegalStateException("Raw type does not have generic type set");
@@ -50,6 +50,13 @@ public class TypeFactory {
return (ReferenceType) pType.resolve(inAWorld);
}
+ /**
+ * Create an *unresolved* parameterized version of a generic type.
+ */
+ public static UnresolvedType createUnresolvedParameterizedType(String sig,String erasuresig,UnresolvedType[] arguments) {
+ return new UnresolvedType(sig,erasuresig,arguments);
+ }
+
public static ReferenceType createRawType(
ResolvedType aBaseType,
World inAWorld
diff --git a/weaver/src/org/aspectj/weaver/TypeVariable.java b/weaver/src/org/aspectj/weaver/TypeVariable.java
index 66f9a2a0f..35623d7bd 100644
--- a/weaver/src/org/aspectj/weaver/TypeVariable.java
+++ b/weaver/src/org/aspectj/weaver/TypeVariable.java
@@ -25,6 +25,9 @@ public class TypeVariable {
*/
private boolean isResolved = false;
+
+ private boolean beingResolved = false;
+
/**
* the name of the type variable as recorded in the generic signature
*/
@@ -93,6 +96,8 @@ public class TypeVariable {
* resolve all the bounds of this type variable
*/
public void resolve(World inSomeWorld) {
+ if (beingResolved) { return; } // avoid spiral of death
+ beingResolved = true;
if (isResolved) return;
upperBound = upperBound.resolve(inSomeWorld);
@@ -103,6 +108,7 @@ public class TypeVariable {
}
isResolved = true;
+ beingResolved = false;
}
/**
diff --git a/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java b/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java
index c77e36cd7..9c47db1aa 100644
--- a/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java
+++ b/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java
@@ -23,18 +23,29 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
World aWorld) {
super(aTypeVariable.getUpperBound().getSignature(),aWorld);
this.typeVariable = aTypeVariable;
- this.isExtends = false;
- this.isSuper = false;
- setUpperBound(aTypeVariable.getUpperBound());
- setLowerBound(aTypeVariable.getLowerBound());
- UnresolvedType[] ifBounds = aTypeVariable.getAdditionalInterfaceBounds();
- if (ifBounds.length > 0) {
- this.additionalInterfaceBounds = new ReferenceType[ifBounds.length];
+ this.isExtends = false;
+ this.isSuper = false;
+ setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)aTypeVariable.getUpperBound()));
+ }
+
+ public UnresolvedType getUpperBound() {
+ if (typeVariable==null) return super.getUpperBound();
+ return typeVariable.getUpperBound();
+ }
+
+ public UnresolvedType getLowerBound() {
+ return typeVariable.getLowerBound();
+ }
+
+ public ReferenceType[] getAdditionalBounds() {
+ if (additionalInterfaceBounds ==null && typeVariable.getAdditionalInterfaceBounds()!=null) {
+ UnresolvedType [] ifBounds = typeVariable.getAdditionalInterfaceBounds();
+ additionalInterfaceBounds = new ReferenceType[ifBounds.length];
for (int i = 0; i < ifBounds.length; i++) {
- this.additionalInterfaceBounds[i] = (ReferenceType) ifBounds[i];
+ additionalInterfaceBounds[i] = (ReferenceType) ifBounds[i];
}
}
- setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)aTypeVariable.getUpperBound()));
+ return additionalInterfaceBounds;
}
public TypeVariable getTypeVariable() {
@@ -45,6 +56,10 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
return true;
}
+// public ResolvedType resolve(World world) {
+ // return super.resolve(world);
+ //}
+
/**
* return the signature for a *REFERENCE* to a type variable, which is simply:
* Tname;
diff --git a/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java b/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java
index 667c10c43..cf8494ea4 100644
--- a/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java
+++ b/weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java
@@ -37,7 +37,9 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
}
public ResolvedType resolve(World world) {
- if (typeVariable == null) return ResolvedType.MISSING;
+ if (typeVariable == null) {
+ throw new BCException("Cannot resolve this type variable reference, the type variable has not been set!");
+ }
typeVariable.resolve(world);
return new TypeVariableReferenceType(typeVariable,world);
}
diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java
index 13c0e4889..053a3c10d 100644
--- a/weaver/src/org/aspectj/weaver/World.java
+++ b/weaver/src/org/aspectj/weaver/World.java
@@ -249,7 +249,7 @@ public abstract class World implements Dump.INode {
/**
* Resolve to a ReferenceType - simple, raw, parameterized, or generic.
- * Raw, parmeterized, and generic versions of a type share a delegate.
+ * Raw, parameterized, and generic versions of a type share a delegate.
*/
private final ResolvedType resolveToReferenceType(UnresolvedType ty) {
if (ty.isParameterizedType()) {
@@ -309,6 +309,17 @@ public abstract class World implements Dump.INode {
// raw type from a source type, it won't if its been created just through
// being referenced, e.g. java.util.List
ResolvedType genericType = rawType.getGenericType();
+
+ // There is a special case to consider here (testGenericsBang_pr95993 highlights it)
+ // You may have an unresolvedType for a parameterized type but it
+ // is backed by a simple type rather than a generic type. This occurs for
+ // inner types of generic types that inherit their enclosing types
+ // type variables.
+ if (rawType.isSimpleType() && anUnresolvedType.typeParameters.length==0) {
+ rawType.world = this;
+ return rawType;
+ }
+
if (genericType != null) {
genericType.world = this;
return genericType;
@@ -324,18 +335,23 @@ public abstract class World implements Dump.INode {
}
}
- // we have a generic wildcard with either extends or super, resolves to a
- // BoundedReferenceType
+ /**
+ * Go from an unresolved generic wildcard (represented by UnresolvedType) to a resolved version (BoundedReferenceType).
+ */
private ReferenceType resolveGenericWildcardFor(UnresolvedType aType) {
BoundedReferenceType ret = null;
+ // FIXME asc isExtends? isGenericWildcardExtends? I dont like having two
+ // FIXME asc doesnt take account of additional interface bounds (e.g. ? super R & Serializable - can you do that?)
if (aType.isGenericWildcardExtends()) {
- ReferenceType upperBound = (ReferenceType) resolve(aType.getUpperBound());
+ ReferenceType upperBound = (ReferenceType)resolve(aType.getUpperBound());
ret = new BoundedReferenceType(upperBound,true,this);
- } else {
+ } else {
ReferenceType lowerBound = (ReferenceType) resolve(aType.getLowerBound());
ret = new BoundedReferenceType(lowerBound,false,this);
}
- typeMap.put(aType.getSignature(),ret);
+ // FIXME asc verify: I don't think these go in the typemap, it makes it potentially impossible to differentiate different uses of 'T',
+ // for example '? super T' where T is representing different things in two places would have the same sig (-TT;)
+ // typeMap.put(aType.getSignature(),ret);
return ret;
}