diff options
author | acolyer <acolyer> | 2005-07-28 10:55:10 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2005-07-28 10:55:10 +0000 |
commit | 8cb70f37f86030709e51d62e8d1579e418ecc107 (patch) | |
tree | 07e30691bc535d7c05bb06d8228d473ca587aebf | |
parent | de2890a546b560dbb09624953501bf1399f43254 (diff) | |
download | aspectj-8cb70f37f86030709e51d62e8d1579e418ecc107.tar.gz aspectj-8cb70f37f86030709e51d62e8d1579e418ecc107.zip |
eliminates unwanted "genericSignature" attribute, and adds full support for generic wildcard (?, ? extends, ? super)
10 files changed, 130 insertions, 75 deletions
diff --git a/weaver/src/org/aspectj/weaver/BoundedReferenceType.java b/weaver/src/org/aspectj/weaver/BoundedReferenceType.java index 4e4b331e8..a08032082 100644 --- a/weaver/src/org/aspectj/weaver/BoundedReferenceType.java +++ b/weaver/src/org/aspectj/weaver/BoundedReferenceType.java @@ -23,9 +23,7 @@ import org.aspectj.weaver.patterns.PerClause; * specification in section 4.4 of JVM spec: *,+,- plus signature strings */ public class BoundedReferenceType extends ReferenceType { - protected ReferenceType upperBound; protected ReferenceType[] additionalInterfaceBounds = new ReferenceType[0]; - protected ReferenceType lowerBound = null; protected boolean isExtends = true; protected boolean isSuper = false; @@ -33,12 +31,12 @@ public class BoundedReferenceType extends ReferenceType { super((isExtends ? "+" : "-") + aBound.signature,world); this.isExtends = isExtends; this.isSuper=!isExtends; if (isExtends) { - this.upperBound = aBound; + setUpperBound(aBound); } else { - this.lowerBound = aBound; - this.upperBound = (ReferenceType) world.resolve(UnresolvedType.OBJECT); + setLowerBound(aBound); + setUpperBound(world.resolve(UnresolvedType.OBJECT)); } - setDelegate(new ReferenceTypeReferenceTypeDelegate(upperBound)); + setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)getUpperBound())); } public BoundedReferenceType(ReferenceType aBound, boolean isExtends, World world, ReferenceType[] additionalInterfaces) { @@ -51,19 +49,16 @@ public class BoundedReferenceType extends ReferenceType { */ BoundedReferenceType(String sig, World world) { super(sig,world); - this.upperBound = (ReferenceType) world.resolve(UnresolvedType.OBJECT); + setUpperBound(world.resolve(UnresolvedType.OBJECT)); + setDelegate(new ReferenceTypeReferenceTypeDelegate((ReferenceType)getUpperBound())); } - public ReferenceType getUpperBound() { return upperBound; } - public ReferenceType[] getInterfaceBounds() { return additionalInterfaceBounds; } public boolean hasLowerBound() { - return lowerBound != null; + return getLowerBound() != null; } - public ReferenceType getLowerBound() { return lowerBound; } - public boolean isExtends() { return isExtends; } public boolean isSuper() { return isSuper; } @@ -81,6 +76,10 @@ public class BoundedReferenceType extends ReferenceType { } } + public boolean isGenericWildcard() { + return true; + } + protected static class ReferenceTypeReferenceTypeDelegate extends AbstractReferenceTypeDelegate { public ReferenceTypeReferenceTypeDelegate(ReferenceType backing) { diff --git a/weaver/src/org/aspectj/weaver/GenericsWildcardTypeX.java b/weaver/src/org/aspectj/weaver/GenericsWildcardTypeX.java deleted file mode 100644 index 7e8b824bc..000000000 --- a/weaver/src/org/aspectj/weaver/GenericsWildcardTypeX.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer Initial implementation - * ******************************************************************/ -package org.aspectj.weaver; - -/** - * Represents the ? type in a generics signature prior to resolving. - * - */ -public class GenericsWildcardTypeX extends UnresolvedType { - - public static final GenericsWildcardTypeX GENERIC_WILDCARD = - new GenericsWildcardTypeX(); - - private BoundedReferenceType resolved = null; - - private GenericsWildcardTypeX() { - super("Ljava/lang/Object;"); // should be super("?") ? - } - - public ResolvedType resolve(World world) { - if (resolved == null) { - resolved = new BoundedReferenceType("Ljava/lang/Object;",world); - } - return resolved; - } - -} diff --git a/weaver/src/org/aspectj/weaver/ReferenceType.java b/weaver/src/org/aspectj/weaver/ReferenceType.java index 9ee460fce..8ff58c35a 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceType.java +++ b/weaver/src/org/aspectj/weaver/ReferenceType.java @@ -100,7 +100,6 @@ public class ReferenceType extends ResolvedType { */ public ReferenceType(UnresolvedType genericType, World world) { super(genericType.getSignature(),world); - genericSignature=genericType.genericSignature; typeKind=TypeKind.GENERIC; } diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index 001125bb4..e592f59f5 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -37,6 +37,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl private static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0]; public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P"; + private ResolvedType[] resolvedTypeParams; + protected World world; protected ResolvedType(String signature, World world) { @@ -252,6 +254,13 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } } + public ResolvedType[] getResolvedTypeParameters() { + if (resolvedTypeParams == null) { + resolvedTypeParams = world.resolve(typeParameters); + } + return resolvedTypeParams; + } + /** * described in JVM spec 2ed 5.4.3.2 */ diff --git a/weaver/src/org/aspectj/weaver/TypeFactory.java b/weaver/src/org/aspectj/weaver/TypeFactory.java index 844442213..e81d63238 100644 --- a/weaver/src/org/aspectj/weaver/TypeFactory.java +++ b/weaver/src/org/aspectj/weaver/TypeFactory.java @@ -14,6 +14,8 @@ package org.aspectj.weaver; import java.util.ArrayList; import java.util.List; +import org.aspectj.weaver.UnresolvedType.TypeKind; + /** * @author colyer * @@ -77,9 +79,26 @@ public class TypeFactory { String signatureErasure = "L" + signature.substring(1,startOfParams) + ";"; UnresolvedType[] typeParams = createTypeParams(signature.substring(startOfParams +1, endOfParams)); return new UnresolvedType(signature,signatureErasure,typeParams); - } else { - return new UnresolvedType(signature); - } + } else if (signature.equals("?")){ + UnresolvedType ret = UnresolvedType.SOMETHING; + ret.typeKind = TypeKind.WILDCARD; + return ret; + } else if(signature.startsWith("+")) { + // ? extends ... + UnresolvedType bound = UnresolvedType.forSignature(signature.substring(1)); + UnresolvedType ret = new UnresolvedType(signature); + ret.typeKind = TypeKind.WILDCARD; + ret.setUpperBound(bound); + return ret; + } else if (signature.startsWith("-")) { + // ? super ... + UnresolvedType bound = UnresolvedType.forSignature(signature.substring(1)); + UnresolvedType ret = new UnresolvedType(signature); + ret.typeKind = TypeKind.WILDCARD; + ret.setLowerBound(bound); + return ret; + } + return new UnresolvedType(signature); } private static UnresolvedType[] createTypeParams(String typeParameterSpecification) { diff --git a/weaver/src/org/aspectj/weaver/TypeVariable.java b/weaver/src/org/aspectj/weaver/TypeVariable.java index 046d22ba9..66f9a2a0f 100644 --- a/weaver/src/org/aspectj/weaver/TypeVariable.java +++ b/weaver/src/org/aspectj/weaver/TypeVariable.java @@ -116,6 +116,11 @@ public class TypeVariable { return matchingBounds((TypeVariableReferenceType)aCandidateType); } + // wildcard can accept any binding + if (aCandidateType.isGenericWildcard()) { // AMC - need a more robust test! + return true; + } + // otherwise can be bound iff... // aCandidateType is a subtype of upperBound if (!isASubtypeOf(upperBound,aCandidateType)) { @@ -137,9 +142,9 @@ public class TypeVariable { // can match any type in the range of the type variable... // XXX what about interfaces? private boolean matchingBounds(TypeVariableReferenceType tvrt) { - if (tvrt.getUpperBound() != upperBound) return false; - if (tvrt.hasLowerBound() != (lowerBound != null)) return false; - if (tvrt.hasLowerBound() && tvrt.lowerBound != lowerBound) return false; + if (tvrt.getUpperBound() != getUpperBound()) return false; + if (tvrt.hasLowerBound() != (getLowerBound() != null)) return false; + if (tvrt.hasLowerBound() && tvrt.getLowerBound() != getLowerBound()) return false; // either we both have bounds, or neither of us have bounds if ((tvrt.additionalInterfaceBounds != null) != (additionalInterfaceBounds != null)) return false; if (additionalInterfaceBounds != null) { @@ -226,7 +231,7 @@ public class TypeVariable { } return sb.toString(); } - + public void setRank(int rank) { this.rank=rank; } diff --git a/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java b/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java index bb37f3473..c77e36cd7 100644 --- a/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java +++ b/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java @@ -25,8 +25,8 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T this.typeVariable = aTypeVariable; this.isExtends = false; this.isSuper = false; - this.upperBound = (ReferenceType) aTypeVariable.getUpperBound(); - this.lowerBound = (ReferenceType) aTypeVariable.getLowerBound(); + setUpperBound(aTypeVariable.getUpperBound()); + setLowerBound(aTypeVariable.getLowerBound()); UnresolvedType[] ifBounds = aTypeVariable.getAdditionalInterfaceBounds(); if (ifBounds.length > 0) { this.additionalInterfaceBounds = new ReferenceType[ifBounds.length]; diff --git a/weaver/src/org/aspectj/weaver/UnresolvedType.java b/weaver/src/org/aspectj/weaver/UnresolvedType.java index 08df6e765..320d93e5c 100644 --- a/weaver/src/org/aspectj/weaver/UnresolvedType.java +++ b/weaver/src/org/aspectj/weaver/UnresolvedType.java @@ -113,6 +113,7 @@ public class UnresolvedType implements TypeVariableDeclaringElement { public static final UnresolvedType JAVA_LANG_REFLECT_METHOD = forSignature("Ljava/lang/reflect/Method;"); public static final UnresolvedType SUPPRESS_AJ_WARNINGS = forSignature("Lorg/aspectj/lang/annotation/SuppressAjWarnings;"); public static final UnresolvedType AT_TARGET = forSignature("Ljava/lang/annotation/Target;"); + public static final UnresolvedType SOMETHING = new UnresolvedType("?"); // this doesn't belong here and will get moved to ResolvedType later in the refactoring public static final String MISSING_NAME = "@missing@"; @@ -146,6 +147,16 @@ public class UnresolvedType implements TypeVariableDeclaringElement { protected TypeVariable[] typeVariables; /** + * Iff isGenericWildcard, then this is the upper bound type for ? extends Foo + */ + private UnresolvedType upperBound; + + /** + * Iff isGenericWildcard, then this is the lower bound type for ? super Foo + */ + private UnresolvedType lowerBound; + + /** * Determines if this represents a primitive type. A primitive type * is one of nine predefined resolved types. * @@ -168,6 +179,8 @@ public class UnresolvedType implements TypeVariableDeclaringElement { public boolean isParameterizedType() { return typeKind == TypeKind.PARAMETERIZED; } public boolean isTypeVariableReference() { return typeKind == TypeKind.TYPE_VARIABLE; } public boolean isGenericWildcard() { return typeKind == TypeKind.WILDCARD; } + public boolean isGenericWildcardExtends() { return isGenericWildcard() && upperBound != null; } + public boolean isGenericWildcardSuper() { return isGenericWildcard() && lowerBound != null; } // for any reference type, we can get some extra information... public final boolean isArray() { return signature.startsWith("["); } @@ -221,11 +234,7 @@ public class UnresolvedType implements TypeVariableDeclaringElement { // ----------------------------- // old stuff... - - // For a generic type, this is the 'declared' signature - // e.g. for Enum: <E:Ljava/lang/Enum<TE;>;>Ljava/lang/Object;Ljava/lang/Comparable<TE;>;Ljava/io/Serializable; - // note: it doesnt include the name of the type! - protected String genericSignature; + /** * @param signature the bytecode string representation of this Type @@ -312,7 +321,6 @@ public class UnresolvedType implements TypeVariableDeclaringElement { ret.typeKind=TypeKind.GENERIC; ret.typeVariables = tvbs; ret.signatureErasure = sig; - ret.genericSignature = genericSig; return ret; } @@ -331,7 +339,6 @@ public class UnresolvedType implements TypeVariableDeclaringElement { } ret.signatureErasure = sig; ret.signature = ret.signatureErasure; - ret.genericSignature=declaredGenericSig; return ret; } @@ -402,9 +409,9 @@ public class UnresolvedType implements TypeVariableDeclaringElement { case 'V': return ResolvedType.VOID; case 'Z': return ResolvedType.BOOLEAN; case '[': return TypeFactory.createTypeFromSignature(signature); - case '+': return new UnresolvedType(signature); - case '-' : return new UnresolvedType(signature); - case '?' : return GenericsWildcardTypeX.GENERIC_WILDCARD; + case '+': return TypeFactory.createTypeFromSignature(signature); + case '-' : return TypeFactory.createTypeFromSignature(signature); + case '?' : return TypeFactory.createTypeFromSignature(signature); case 'T' : return new UnresolvedTypeVariableReferenceType(new TypeVariable(signature.substring(1))); default: throw new BCException("Bad type signature " + signature); } @@ -514,6 +521,33 @@ public class UnresolvedType implements TypeVariableDeclaringElement { return UnresolvedType.forSignature(getErasureSignature()); } + /** + * Get the upper bound for a generic wildcard + */ + public UnresolvedType getUpperBound() { + return upperBound; + } + + /** + * Get the lower bound for a generic wildcard + */ + public UnresolvedType getLowerBound() { + return lowerBound; + } + + /** + * Set the upper bound for a generic wildcard + */ + public void setUpperBound(UnresolvedType aBound) { + this.upperBound = aBound; + } + + /** + * Set the lower bound for a generic wildcard + */ + public void setLowerBound(UnresolvedType aBound) { + this.lowerBound = aBound; + } /** @@ -628,8 +662,9 @@ public class UnresolvedType implements TypeVariableDeclaringElement { // case '<': // // its a generic! // if (signature.charAt(1)=='>') return signatureToName(signature.substring(2)); - case '+' : return signatureToName(signature.substring(1, signature.length())); - case '-' : return signatureToName(signature.substring(1, signature.length())); + case '+' : return "? extends " + signatureToName(signature.substring(1, signature.length())); + case '-' : return "? super " + signatureToName(signature.substring(1, signature.length())); + case '?' : return "?"; default: throw new BCException("Bad type signature: " + signature); } @@ -645,6 +680,7 @@ public class UnresolvedType implements TypeVariableDeclaringElement { if (name.equals("short")) return "S"; if (name.equals("boolean")) return "Z"; if (name.equals("void")) return "V"; + if (name.equals("?")) return name; if (name.endsWith("[]")) return "[" + nameToSignature(name.substring(0, name.length() - 2)); if (name.length() != 0) { @@ -789,8 +825,8 @@ public class UnresolvedType implements TypeVariableDeclaringElement { public String toString() { return type; - } - +} + private TypeKind(String type) { this.type = type; } diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index f16077487..136737207 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -112,6 +112,7 @@ public abstract class World implements Dump.INode { } } + // ============================================================================= // T Y P E R E S O L U T I O N // ============================================================================= @@ -182,7 +183,12 @@ public abstract class World implements Dump.INode { if (ret != null) { ret.world = this; // Set the world for the RTX return ret; - } + } else if ( signature.equals("?")) { + // fault in generic wildcard, can't be done earlier because of init issues + ResolvedType something = new BoundedReferenceType("?",this); + typeMap.put("?",something); + return something; + } // no existing resolved type, create one if (ty.isArray()) { @@ -256,7 +262,10 @@ public abstract class World implements Dump.INode { ReferenceType genericType = (ReferenceType)resolveGenericTypeFor(ty,false); return genericType; - } else { + } else if (ty.isGenericWildcard()) { + // ======= generic wildcard types ============= + return resolveGenericWildcardFor(ty); + } else { // ======= simple and raw types =============== String erasedSignature = ty.getErasureSignature(); ReferenceType simpleOrRawType = new ReferenceType(erasedSignature, this); @@ -313,6 +322,21 @@ public abstract class World implements Dump.INode { } } + // we have a generic wildcard with either extends or super, resolves to a + // BoundedReferenceType + private ReferenceType resolveGenericWildcardFor(UnresolvedType aType) { + BoundedReferenceType ret = null; + if (aType.isGenericWildcardExtends()) { + ReferenceType upperBound = (ReferenceType) resolve(aType.getUpperBound()); + ret = new BoundedReferenceType(upperBound,true,this); + } else { + ReferenceType lowerBound = (ReferenceType) resolve(aType.getLowerBound()); + ret = new BoundedReferenceType(lowerBound,false,this); + } + typeMap.put(aType.getSignature(),ret); + return ret; + } + /** * Find the ReferenceTypeDelegate behind this reference type so that it can * fulfill its contract. diff --git a/weaver/src/org/aspectj/weaver/weaver-messages.properties b/weaver/src/org/aspectj/weaver/weaver-messages.properties index ddc4b79f6..eeb4843ce 100644 --- a/weaver/src/org/aspectj/weaver/weaver-messages.properties +++ b/weaver/src/org/aspectj/weaver/weaver-messages.properties @@ -143,4 +143,4 @@ noParameterizedTypePatternInHandler=a parameterized type pattern may not be used incorrectNumberOfTypeArguments=Type pattern does not match because the wrong number of type parameters are specified: Type {0} requires {1} parameter(s) violatesTypeVariableBounds=Type {0} does not meet the specification for type parameter {1} ({2}) in generic type {3} notAGenericType=Type pattern does not match because {0} is not a generic type -noStaticInitJPsForParameterizedTypes=no static initialization join points for parameterized types, use generic or raw type instead
\ No newline at end of file +noStaticInitJPsForParameterizedTypes=no static initialization join points for parameterized types, use raw type instead
\ No newline at end of file |