diff options
author | aclement <aclement> | 2005-07-29 13:40:55 +0000 |
---|---|---|
committer | aclement <aclement> | 2005-07-29 13:40:55 +0000 |
commit | 14b0f911d8452c172e037d2db88f082b2f0c3bb4 (patch) | |
tree | 053a5100237956b7b9808b4b7cda79d571917955 | |
parent | 0401dd1abd3417b49640ace6e477c2e0a2ba36e6 (diff) | |
download | aspectj-14b0f911d8452c172e037d2db88f082b2f0c3bb4.tar.gz aspectj-14b0f911d8452c172e037d2db88f082b2f0c3bb4.zip |
genericitds: using wildcard '? extends Type' and '? extends <TypeVariable>'. Basically preserves wildcardbindings that are built by eclipse as boundedreferencetypes.
5 files changed, 104 insertions, 12 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java index 84d230050..4ebc962e3 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java @@ -27,6 +27,7 @@ import org.aspectj.ajdt.internal.core.builder.AjBuildManager; import org.aspectj.ajdt.internal.core.builder.AsmHierarchyBuilder; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.weaver.BoundedReferenceType; import org.aspectj.weaver.ConcreteTypeMunger; import org.aspectj.weaver.IHasPosition; import org.aspectj.weaver.Member; @@ -48,6 +49,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclarati import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.EmptyStatement; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant; import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BaseTypes; @@ -61,6 +63,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; @@ -196,6 +199,21 @@ public class EclipseFactory { return fromTypeVariableBinding((TypeVariableBinding)binding); } + + if (binding instanceof WildcardBinding) { + WildcardBinding eWB = (WildcardBinding) binding; + UnresolvedType ut = TypeFactory.createTypeFromSignature(CharOperation.charToString(eWB.genericTypeSignature())); + // If the bound for the wildcard is a typevariable, e.g. '? extends E' then + // the type variable in the unresolvedtype will be correct only in name. In that + // case let's set it correctly based on the one in the eclipse WildcardBinding + if (eWB.bound instanceof TypeVariableBinding) { + UnresolvedType tVar = fromTypeVariableBinding((TypeVariableBinding)eWB.bound); + if (ut.isGenericWildcardSuper()) ut.setLowerBound(tVar); + if (ut.isGenericWildcardExtends()) ut.setUpperBound(tVar); + } + return ut; + } + if (binding instanceof ParameterizedTypeBinding) { if (binding instanceof RawTypeBinding) { // special case where no parameters are specified! @@ -208,12 +226,7 @@ public class EclipseFactory { if (ptb.arguments!=null) { // null can mean this is an inner type of a Parameterized Type with no bounds of its own (pr100227) arguments = new UnresolvedType[ptb.arguments.length]; for (int i = 0; i < arguments.length; i++) { - if (ptb.arguments[i] instanceof WildcardBinding) { - WildcardBinding wcb = (WildcardBinding) ptb.arguments[i]; - arguments[i] = fromTypeVariableBinding(wcb.typeVariable()); - } else { - arguments[i] = fromBinding(ptb.arguments[i]); - } + arguments[i] = fromBinding(ptb.arguments[i]); } } ResolvedType baseType = UnresolvedType.forName(getName(binding)).resolve(getWorld()); @@ -263,7 +276,10 @@ public class EclipseFactory { } TypeVariable tv = new TypeVariable(name,superclassType,superinterfaces); tv.setRank(aTypeVariableBinding.rank); - tv.setDeclaringElement(fromBinding(aTypeVariableBinding.declaringElement)); + // getting things right for method declaring elements is tricky... + if (!(aTypeVariableBinding.declaringElement instanceof MethodBinding)) { + tv.setDeclaringElement(fromBinding(aTypeVariableBinding.declaringElement)); + } tv.resolve(world); ret.setTypeVariable(tv); typeVariableBindingsInProgress.remove(aTypeVariableBinding); @@ -435,6 +451,22 @@ public class EclipseFactory { ReferenceBinding baseTypeBinding = lookupBinding(typeX.getBaseName()); RawTypeBinding rtb = lookupEnvironment.createRawType(baseTypeBinding,baseTypeBinding.enclosingType()); return rtb; + } else if (typeX.isGenericWildcard()) { + // translate from boundedreferencetype to WildcardBinding + BoundedReferenceType brt = (BoundedReferenceType)typeX; + // Work out 'kind' for the WildcardBinding + int boundkind = Wildcard.UNBOUND; + if (brt.isGenericWildcardExtends()) boundkind = Wildcard.EXTENDS; + if (brt.isGenericWildcardSuper()) boundkind = Wildcard.SUPER; + // get the bound right + TypeBinding bound = null; + if (brt.isGenericWildcardExtends()) bound = makeTypeBinding(brt.getUpperBound()); + if (brt.isGenericWildcardSuper()) bound = makeTypeBinding(brt.getLowerBound()); + TypeBinding[] otherBounds = null; + if (brt.getAdditionalBounds()!=null && brt.getAdditionalBounds().length!=0) otherBounds = makeTypeBindings(brt.getAdditionalBounds()); + // FIXME asc rank should not always be 0 ... + WildcardBinding wb = lookupEnvironment.createWildcard(null,0,bound,otherBounds,boundkind); + return wb; } else { return lookupBinding(typeX.getName()); } @@ -485,17 +517,27 @@ public class EclipseFactory { public MethodBinding makeMethodBinding(ResolvedMember member) { typeVariableToTypeBinding.clear(); + ReferenceBinding declaringType = (ReferenceBinding)makeTypeBinding(member.getDeclaringType()); MethodBinding mb = new MethodBinding(member.getModifiers(), member.getName().toCharArray(), makeTypeBinding(member.getReturnType()), makeTypeBindings(member.getParameterTypes()), makeReferenceBindings(member.getExceptions()), - (ReferenceBinding)makeTypeBinding(member.getDeclaringType())); + declaringType); if (member.getTypeVariables()!=null) { if (member.getTypeVariables().length==0) { mb.typeVariables = MethodBinding.NoTypeVariables; } else { TypeVariableBinding[] tvbs = makeTypeVariableBindings(member.getTypeVariables()); + // fixup the declaring element, we couldn't do it whilst processing the typevariables as we'll end up in recursion. + for (int i = 0; i < tvbs.length; i++) { + TypeVariableBinding binding = tvbs[i]; + if (binding.declaringElement==null && ((TypeVariableReference)member.getTypeVariables()[i]).getTypeVariable().getDeclaringElement() instanceof Member) { + tvbs[i].declaringElement = mb; + } else { + tvbs[i].declaringElement = declaringType; + } + } mb.typeVariables = tvbs; } } @@ -543,6 +585,7 @@ public class EclipseFactory { // } tvBinding = new TypeVariableBinding(tVar.getName().toCharArray(),declaringElement,tVar.getRank()); tvBinding.superclass=(ReferenceBinding)makeTypeBinding(tVar.getUpperBound()); + tvBinding.firstBound=tvBinding.superclass; // FIXME asc is this correct? possibly it could be first superinterface if (tVar.getAdditionalInterfaceBounds()==null) { tvBinding.superInterfaces=TypeVariableBinding.NoSuperInterfaces; } else { diff --git a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java index b382f1ff2..e04a08eed 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java @@ -162,10 +162,19 @@ public class GenericsTests extends XMLBasedAjcTestCase { runTest("itd of static member"); } - public void testGenericITDComplex() { - runTest("more complex static member itd"); + public void testStaticGenericMethodITD() { + runTest("static generic method itd"); } + // non static +// public void testNonStaticGenericCtorITD1() {runTest("generic ctor itd - 1");} + + public void testGenericMethodITD1() {runTest("generic method itd - 1");} + public void testGenericMethodITD2() {runTest("generic method itd - 2");} + + public void testParameterizedMethodITD1() {runTest("parameterized method itd - 1");} + public void testParameterizedMethodITD2() {runTest("parameterized method itd - 2");} + // public void testGenericITFSharingTypeVariable() { // runTest("generic intertype field declaration, sharing type variable"); // } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index acbdc7465..0861d0ea4 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -2377,7 +2377,7 @@ </run> </ajc-test> - <ajc-test dir="java5/generics/itds" title="more complex static member itd"> + <ajc-test dir="java5/generics/itds" title="static generic method itd"> <compile files="StaticGenericMethodITD.aj" options="-1.5"/> <run class="StaticGenericMethodITD"> <stderr> @@ -2386,6 +2386,40 @@ </run> </ajc-test> + <ajc-test dir="java5/generics/itds" title="non static generic ctor itd - 1"> + <compile files="NonstaticGenericCtorITD1.aj" options="-1.5"/> + <run class="NonstaticGenericCtorITD1"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="parameterized method itd - 1"> + <compile files="ParameterizedMethodITD1.aj" options="-1.5"/> + <run class="ParameterizedMethodITD1"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="parameterized method itd - 2"> + <compile files="ParameterizedMethodITD2.aj" options="-1.5"> + <message kind="error" line="9" text="The method simple(List<? extends Number>) in the type X is not applicable for the arguments (List<A>)"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 1"> + <compile files="GenericMethodITD1.aj" options="-1.5"/> + <run class="GenericMethodITD1"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic method itd - 2"> + <compile files="GenericMethodITD2.aj" options="-1.5"> + <!-- this next line might contain a 'bad message' that is fixed in the final 3.1 compiler, I don't think the middle bit should say List<? extends A> - it should probably say List<A> --> + <message kind="error" line="9" text="Bound mismatch: The generic method simple(List<? extends E>) of type X is not applicable for the arguments (List<? extends A>) since the type A is not a valid substitute for the bounded parameter <E extends Number>"/> + </compile> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="non static generic method itd - 2"> + <compile files="NonstaticGenericCtorITD2.aj" options="-1.5"/> + <run class="NonstaticGenericCtorITD2"/> + </ajc-test> + + <ajc-test dir="java5/generics/itds" title="generic intertype field declaration, sharing type variable"> <compile files="FieldITDOnGeneric.aj" options="-1.5"/> <run class="FieldITDOnGeneric"> diff --git a/weaver/src/org/aspectj/weaver/BoundedReferenceType.java b/weaver/src/org/aspectj/weaver/BoundedReferenceType.java index a08032082..dfb8efc30 100644 --- a/weaver/src/org/aspectj/weaver/BoundedReferenceType.java +++ b/weaver/src/org/aspectj/weaver/BoundedReferenceType.java @@ -44,6 +44,10 @@ public class BoundedReferenceType extends ReferenceType { this.additionalInterfaceBounds = additionalInterfaces; } + public ReferenceType[] getAdditionalBounds() { + return additionalInterfaceBounds; + } + /** * only for use when resolving GenericsWildcardTypeX or a TypeVariableReferenceType */ diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 136737207..13c0e4889 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -183,7 +183,9 @@ 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("?")) { + } else if ( signature.equals("?") || signature.equals("*")) { + // might be a problem here, not sure '?' should make it to here as a signature, the + // proper signature for wildcard '?' is '*' // fault in generic wildcard, can't be done earlier because of init issues ResolvedType something = new BoundedReferenceType("?",this); typeMap.put("?",something); |