Browse Source

generic itds - see pr112105

tags/V1_5_0RC1
aclement 18 years ago
parent
commit
0a69e42808
24 changed files with 473 additions and 104 deletions
  1. 0
    1
      aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java
  2. 3
    3
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
  3. 45
    3
      org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java
  4. 1
    0
      tests/.classpath
  5. 6
    0
      tests/java5/generics/itds/design/DesignA.java
  6. 12
    0
      tests/java5/generics/itds/design/DesignB.java
  7. 10
    0
      tests/java5/generics/itds/design/DesignC.java
  8. 1
    0
      tests/multiIncremental/PR111779/inc1/Bar.aj
  9. 1
    0
      tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java
  10. 167
    0
      tests/src/org/aspectj/systemtest/ajc150/GenericITDsDesign.java
  11. 15
    0
      tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
  12. 1
    1
      tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java
  13. 2
    0
      tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java
  14. 6
    2
      weaver/src/org/aspectj/weaver/JoinPointSignature.java
  15. 2
    2
      weaver/src/org/aspectj/weaver/ResolvedMember.java
  16. 51
    28
      weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
  17. 2
    5
      weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
  18. 50
    12
      weaver/src/org/aspectj/weaver/TypeVariable.java
  19. 1
    1
      weaver/src/org/aspectj/weaver/TypeVariableDeclaringElement.java
  20. 19
    12
      weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java
  21. 9
    4
      weaver/src/org/aspectj/weaver/UnresolvedType.java
  22. 49
    19
      weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java
  23. 13
    1
      weaver/src/org/aspectj/weaver/World.java
  24. 7
    10
      weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java

+ 0
- 1
aspectj5rt/java5-testsrc/org/aspectj/internal/lang/reflect/AjTypeTestsWithAspects.java View File

@@ -17,7 +17,6 @@ import java.lang.reflect.Modifier;
import junit.framework.TestCase;

import org.aspectj.internal.lang.annotation.ajcDeclareEoW;
import org.aspectj.internal.lang.annotation.ajcITD;
import org.aspectj.internal.lang.annotation.ajcPrivileged;
import org.aspectj.lang.annotation.AdviceName;
import org.aspectj.lang.annotation.After;

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

@@ -47,7 +47,6 @@ 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.RawTypeBinding;
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;
@@ -57,7 +56,6 @@ import org.aspectj.weaver.AsmRelationshipProvider;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.WeaverStateInfo;
@@ -543,6 +541,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
needOldStyleWarning = false;
}
onType.addInterTypeMunger(munger);
/*
//TODO: Andy Should be done at weave time.
// Unfortunately we can't do it at weave time unless the type mungers remember where
// they came from. Thats why we do it here during complation because at this time
@@ -554,6 +553,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
// AsmRelationshipProvider (see BCELTypeMunger)
if (!ResolvedTypeMunger.persistSourceLocation) // Do it up front if we bloody have to
AsmInterTypeRelationshipProvider.getDefault().addRelationship(onType, munger);
*/
}
}
@@ -863,7 +863,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
needFieldsAndMethods,
accessRestriction);
factory.getWorld().validateType(factory.fromBinding(ret));
// if you need the bytes to pass to validate, here they are:ClassFileReader)binaryType).getReferenceBytes()
// if you need the bytes to pass to validate, here they are:((ClassFileReader)binaryType).getReferenceBytes()
weaveInterTypeDeclarations(ret);
return ret;
} finally {

+ 45
- 3
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java View File

@@ -464,10 +464,11 @@ public class EclipseFactory {
ret.setVarargsMethod();
}
if (typeVariablesForThisMember.size()!=0) {
UnresolvedType[] tvars = new UnresolvedType[typeVariablesForThisMember.size()];
// SAUSAGES this might be broken with the change for resolved members to own type variables
TypeVariable[] tvars = new TypeVariable[typeVariablesForThisMember.size()];
int i =0;
for (Iterator iter = typeVariablesForThisMember.values().iterator(); iter.hasNext();) {
tvars[i++] = (UnresolvedType)iter.next();
tvars[i++] = ((TypeVariableReference)((UnresolvedType)iter.next())).getTypeVariable();
}
ret.setTypeVariables(tvars);
}
@@ -621,7 +622,7 @@ public class EclipseFactory {
if (member.getTypeVariables().length==0) {
tvbs = MethodBinding.NoTypeVariables;
} else {
tvbs = makeTypeVariableBindings(member.getTypeVariables());
tvbs = makeTypeVariableBindingsFromAJTypeVariables(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];
@@ -661,6 +662,15 @@ public class EclipseFactory {
}
return ret;
}
private TypeVariableBinding[] makeTypeVariableBindingsFromAJTypeVariables(TypeVariable[] typeVariables) {
int len = typeVariables.length;
TypeVariableBinding[] ret = new TypeVariableBinding[len];
for (int i = 0; i < len; i++) {
ret[i] = makeTypeVariableBindingFromAJTypeVariable(typeVariables[i]);
}
return ret;
}

// only accessed through private methods in this class. Ensures all type variables we encounter
// map back to the same type binding - this is important later when Eclipse code is processing
@@ -705,6 +715,38 @@ public class EclipseFactory {
}
return tvBinding;
}
private TypeVariableBinding makeTypeVariableBindingFromAJTypeVariable(TypeVariable tv) {
TypeVariableBinding tvBinding = (TypeVariableBinding)typeVariableToTypeBinding.get(tv.getName());
if (currentType!=null) {
TypeVariableBinding tvb = currentType.getTypeVariable(tv.getName().toCharArray());
if (tvb!=null) return tvb;
}
if (tvBinding==null) {
Binding declaringElement = null;
// this will cause an infinite loop or NPE... not required yet luckily.
// if (tVar.getDeclaringElement() instanceof Member) {
// declaringElement = makeMethodBinding((ResolvedMember)tVar.getDeclaringElement());
// } else {
// declaringElement = makeTypeBinding((UnresolvedType)tVar.getDeclaringElement());
// }
tvBinding = new TypeVariableBinding(tv.getName().toCharArray(),declaringElement,tv.getRank());
typeVariableToTypeBinding.put(tv.getName(),tvBinding);
tvBinding.superclass=(ReferenceBinding)makeTypeBinding(tv.getUpperBound());
tvBinding.firstBound=tvBinding.superclass; // FIXME asc is this correct? possibly it could be first superinterface
if (tv.getAdditionalInterfaceBounds()==null) {
tvBinding.superInterfaces=TypeVariableBinding.NoSuperInterfaces;
} else {
TypeBinding tbs[] = makeTypeBindings(tv.getAdditionalInterfaceBounds());
ReferenceBinding[] rbs= new ReferenceBinding[tbs.length];
for (int i = 0; i < tbs.length; i++) {
rbs[i] = (ReferenceBinding)tbs[i];
}
tvBinding.superInterfaces=rbs;
}
}
return tvBinding;
}

public MethodBinding makeMethodBindingForCall(Member member) {
return new MethodBinding(member.getCallsiteModifiers(),

+ 1
- 0
tests/.classpath View File

@@ -14,5 +14,6 @@
<classpathentry kind="lib" path="/lib/ant/lib/ant-launcher.jar"/>
<classpathentry kind="src" path="testsrc"/>
<classpathentry kind="var" path="JAVA_HOME/lib/tools.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/weaver"/>
<classpathentry kind="output" path="bin"/>
</classpath>

+ 6
- 0
tests/java5/generics/itds/design/DesignA.java View File

@@ -0,0 +1,6 @@
class C {
}

aspect X {
<T> void C.m(T t) {}
}

+ 12
- 0
tests/java5/generics/itds/design/DesignB.java View File

@@ -0,0 +1,12 @@
class C {}

interface I {}

aspect X {

<T extends Number> void C.m0(T t) {} // L7

<Q extends I> void C.m1(Q q) {} // L9

<R extends Number,I> void C.m2(R r) {} // L11
}

+ 10
- 0
tests/java5/generics/itds/design/DesignC.java View File

@@ -0,0 +1,10 @@
class C {}

interface I {}

aspect X {

<T extends Number,Q extends I> void C.m0(T t,Q q) {} // L7

<A,B,C> List<A> C.m1(B b,Collection<C> cs) {} // L9
}

+ 1
- 0
tests/multiIncremental/PR111779/inc1/Bar.aj View File

@@ -1,6 +1,7 @@
import java.util.*;

public aspect Bar {

private List<String> Foo.l;



+ 1
- 0
tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java View File

@@ -47,6 +47,7 @@ public class AllTestsAspectJ150 {
suite.addTest(SuppressedWarnings.suite());
suite.addTest(DeclareAnnotationTests.suite());
suite.addTest(GenericsTests.suite());
suite.addTest(GenericITDsDesign.suite());
suite.addTest(AtAjSyntaxTests.suite());
suite.addTest(AtAjMisuseTests.suite());
suite.addTest(AtAjLTWTests.suite());

+ 167
- 0
tests/src/org/aspectj/systemtest/ajc150/GenericITDsDesign.java View File

@@ -0,0 +1,167 @@
package org.aspectj.systemtest.ajc150;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import junit.framework.Test;

import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Signature;
import org.aspectj.apache.bcel.util.ClassPath;
import org.aspectj.apache.bcel.util.SyntheticRepository;
import org.aspectj.testing.XMLBasedAjcTestCase;
import org.aspectj.tools.ajc.Ajc;
import org.aspectj.weaver.CrosscuttingMembers;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.TypeVariable;
import org.aspectj.weaver.TypeVariableReference;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.BcelTypeMunger;
import org.aspectj.weaver.bcel.BcelWorld;

public class GenericITDsDesign extends XMLBasedAjcTestCase {

private World recentWorld;
public static Test suite() {
return XMLBasedAjcTestCase.loadSuite(GenericITDsDesign.class);
}

protected File getSpecFile() {
return new File("../tests/src/org/aspectj/systemtest/ajc150/ajc150.xml");
}

public static Signature getClassSignature(Ajc ajc,String classname) {
try {
ClassPath cp =
new ClassPath(ajc.getSandboxDirectory() + File.pathSeparator + System.getProperty("java.class.path"));
SyntheticRepository sRepos = SyntheticRepository.getInstance(cp);
JavaClass clazz = sRepos.loadClass(classname);
Signature sigAttr = null;
Attribute[] attrs = clazz.getAttributes();
for (int i = 0; i < attrs.length; i++) {
Attribute attribute = attrs[i];
if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute;
}
return sigAttr;
} catch (ClassNotFoundException e) {
fail("Couldn't find class "+classname+" in the sandbox directory.");
}
return null;
}
// Check the signature attribute on a class is correct
public static void verifyClassSignature(Ajc ajc,String classname,String sig) {
Signature sigAttr = getClassSignature(ajc,classname);
assertTrue("Failed to find signature attribute for class "+classname,sigAttr!=null);
assertTrue("Expected signature to be '"+sig+"' but was '"+sigAttr.getSignature()+"'",
sigAttr.getSignature().equals(sig));
}
public List /*BcelTypeMunger*/ getTypeMunger(String classname) {
ClassPath cp =
new ClassPath(ajc.getSandboxDirectory() + File.pathSeparator +
System.getProperty("java.class.path"));
recentWorld = new BcelWorld(cp.toString());
ReferenceType resolvedType = (ReferenceType)recentWorld.resolve(classname);
CrosscuttingMembers cmembers = resolvedType.collectCrosscuttingMembers();
List tmungers = cmembers.getTypeMungers();
return tmungers;
}
private BcelTypeMunger getMungerFromLine(String classname,int linenumber) {
List allMungers = getTypeMunger(classname);
for (Iterator iter = allMungers.iterator(); iter.hasNext();) {
BcelTypeMunger element = (BcelTypeMunger) iter.next();
if (element.getMunger().getSourceLocation().getLine()==linenumber) return element;
}
for (Iterator iter = allMungers.iterator(); iter.hasNext();) {
BcelTypeMunger element = (BcelTypeMunger) iter.next();
System.err.println("Line: "+element.getMunger().getSourceLocation().getLine()+" > "+element);
}
fail("Couldn't find a type munger from line "+linenumber+" in class "+classname);
return null;
}
/*
test plan:
1. Serializing and recovering 'default bounds' type variable info:
a. methods
b. fields
c. ctors
2. Serializing and recovering 'extends' with a class bounded type variable info:
a. methods
b. fields
c. ctors
3. Serializing and recovering 'extends' with an interface bounded type variable info:
a. methods
b. fields
c. ctors
4. Multiple interface bounds
a. methods
b. fields
c. ctors
5. wildcard bounds '? extends/? super'
a. methods
b. fields
c. ctors
6. using type variables in an ITD from the containing aspect, no bounds
a. methods
b. fields
c. ctors
*/
// Verify: a) After storing it in a class file and recovering it (through deserialization), we can see the type
// variable and that the parameter refers to the type variable.
public void testDesignA() {
runTest("generic itds - design A");
BcelTypeMunger theBcelMunger = getMungerFromLine("X",5);
ResolvedType typeC = recentWorld.resolve("C");
ResolvedTypeMunger rtMunger = theBcelMunger.getMunger();
ResolvedMember theMember = rtMunger.getSignature();
// Let's check all parts of the member
assertTrue("Declaring type should be C: "+theMember,
theMember.getDeclaringType().equals(typeC));
TypeVariable tVar = theMember.getTypeVariables()[0];
TypeVariableReference tvrt = (TypeVariableReference)theMember.getParameterTypes()[0];
theMember.resolve(recentWorld); // resolution will join the type variables together (i.e. make them refer to the same instance)
tVar = theMember.getTypeVariables()[0];
tvrt = (TypeVariableReference)theMember.getParameterTypes()[0];
assertTrue("Post resolution, the type variable in the parameter should be identical to the type variable declared on the member",
tVar==tvrt.getTypeVariable());
}
// Verify: bounds are preserved and accessible after serialization
public void xtestDesignB() {
runTest("generic itds - design B");
BcelTypeMunger theBcelMunger = getMungerFromLine("X",7);
}
// Verify: a) multiple type variables work.
// b) type variables below the 'top level' (e.g. List<A>) are preserved.
public void xtestDesignC() {
runTest("generic itds - design B");
BcelTypeMunger theBcelMunger = getMungerFromLine("X",7);
}
/*
* broken stuff:
*
* When generic signatures are unpacked from members, the typevariables attached to the bcelmethod/field won't
* be the same instances as those held in the TypeVariableReferenceTypes for anything that occurs in the
* return type or parameterset - we should perhaps fix that up.
*/

}

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

@@ -5024,4 +5024,19 @@
</stdout>
</run>
</ajc-test>
<!-- generic ITDs -->
<ajc-test dir="java5/generics/itds/design" title="generic itds - design A">
<compile files="DesignA.java" options="-1.5"/>
</ajc-test>
<ajc-test dir="java5/generics/itds/design" title="generic itds - design B">
<compile files="DesignB.java" options="-1.5"/>
</ajc-test>
<ajc-test dir="java5/generics/itds/design" title="generic itds - design C">
<compile files="DesignC.java" options="-1.5"/>
</ajc-test>
</suite>

+ 1
- 1
tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java View File

@@ -663,7 +663,7 @@ public class AjdeInteractionTestbed extends TestCase {
}

public String getSourceCompatibilityLevel() {
return null;
return "1.5";
}

public Set getWarnings() {

+ 2
- 0
tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java View File

@@ -289,12 +289,14 @@ public class MultiProjectIncrementalTests extends AjdeInteractionTestbed {
}
/* public void testPr111779() {
super.VERBOSE=true;
initialiseProject("PR111779");
build("PR111779");
alter("PR111779","inc1");
build("PR111779");
}
*/

// other possible tests:
// - memory usage (freemem calls?)

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

@@ -202,13 +202,17 @@ public class JoinPointSignature implements ResolvedMember {
return realMember.parameterizedWith(typeParameters, newDeclaringType, isParameterized);
}

public void setTypeVariables(UnresolvedType[] types) {
public void setTypeVariables(TypeVariable[] types) {
realMember.setTypeVariables(types);
}

public UnresolvedType[] getTypeVariables() {
public TypeVariable[] getTypeVariables() {
return realMember.getTypeVariables();
}
public TypeVariable getTypeVariableNamed(String name) {
return realMember.getTypeVariableNamed(name);
}

public ResolvedMember getErasure() {
throw new UnsupportedOperationException("Adrian doesn't think you should be asking for the erasure of one of these...");

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

@@ -113,9 +113,9 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
UnresolvedType[] typeParameters, ResolvedType newDeclaringType,
boolean isParameterized);

public void setTypeVariables(UnresolvedType[] types);
public void setTypeVariables(TypeVariable[] types);

public UnresolvedType[] getTypeVariables();
public TypeVariable[] getTypeVariables();

/**
* If this member is defined by a parameterized super-type, return the erasure

+ 51
- 28
weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java View File

@@ -50,7 +50,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
private boolean isAjSynthetic = true;
// generic methods have type variables
private UnresolvedType[] typeVariables;
private TypeVariable[] typeVariables;
// these three fields hold the source location of this member
protected int start, end;
@@ -385,9 +385,10 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno

int tvcount = s.readInt();
if (tvcount!=0) {
m.typeVariables = new UnresolvedType[tvcount];
m.typeVariables = new TypeVariable[tvcount];
for (int i=0;i<tvcount;i++) {
m.typeVariables[i]=UnresolvedType.read(s);
m.typeVariables[i]=TypeVariable.read(s);
m.typeVariables[i].setDeclaringElement(m);
}
}
}
@@ -407,30 +408,37 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
public ResolvedMember resolve(World world) {
// 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();) {
UnresolvedType element = (UnresolvedType) iter.next();
r.add(world.resolve(element));
}
annotationTypes = r;
}
declaringType = declaringType.resolve(world);
if (declaringType.isRawType()) declaringType = ((ReferenceType)declaringType).getGenericType();
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);
try {
if (typeVariables!=null && typeVariables.length>0) {
for (int i = 0; i < typeVariables.length; i++) {
typeVariables[i] = typeVariables[i].resolve(world);
}
}
world.setTypeVariableLookupScope(this);
if (annotationTypes!=null) {
Set r = new HashSet();
for (Iterator iter = annotationTypes.iterator(); iter.hasNext();) {
UnresolvedType element = (UnresolvedType) iter.next();
r.add(world.resolve(element));
}
annotationTypes = r;
}
declaringType = declaringType.resolve(world);
if (declaringType.isRawType()) declaringType = ((ReferenceType)declaringType).getGenericType();
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);
parameterTypes[i] = parameterTypes[i].resolve(world);
}
}
returnType = returnType.resolve(world);
} finally {
world.setTypeVariableLookupScope(null);
}
returnType = returnType.resolve(world);return this;
return this;
}
public ISourceContext getSourceContext(World world) {
@@ -567,11 +575,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
public void setTypeVariables(UnresolvedType[] types) {
typeVariables = types;
public void setTypeVariables(TypeVariable[] tvars) {
typeVariables = tvars;
}
public UnresolvedType[] getTypeVariables() {
public TypeVariable[] getTypeVariables() {
return typeVariables;
}
@@ -758,5 +766,20 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}
return buf.toString();
}


public TypeVariable getTypeVariableNamed(String name) {
// Check locally...
if (typeVariables!=null) {
for (int i = 0; i < typeVariables.length; i++) {
if (typeVariables[i].getName().equals(name)) return typeVariables[i];
}
}
// Bugger, check the declaring type!
return declaringType.getTypeVariableNamed(name);

// Do generic aspects with ITDs that share type variables with the aspect and the target type and have their own tvars cause this to be messier?
}
}

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

@@ -47,8 +47,6 @@ public abstract class ResolvedTypeMunger {
// might need serializing the class file for binary weaving.
protected List /*String*/ typeVariableToGenericTypeVariableIndex;
public static transient boolean persistSourceLocation = true;
private Set /* resolvedMembers */ superMethodsCalled = Collections.EMPTY_SET;
private ISourceLocation location; // Lost during serialize/deserialize !
@@ -138,6 +136,7 @@ public abstract class ResolvedTypeMunger {
Set ret = new HashSet();
int n = s.readInt();
if (n<0) throw new BCException("Problem deserializing type munger");
for (int i=0; i < n; i++) {
ret.add(ResolvedMemberImpl.readResolvedMember(s, null));
}
@@ -146,7 +145,7 @@ public abstract class ResolvedTypeMunger {
protected void writeSuperMethodsCalled(DataOutputStream s) throws IOException {
if (superMethodsCalled == null) {
if (superMethodsCalled == null || superMethodsCalled.size()==0) {
s.writeInt(0);
return;
}
@@ -163,7 +162,6 @@ public abstract class ResolvedTypeMunger {
}

protected static ISourceLocation readSourceLocation(VersionedDataInputStream s) throws IOException {
if (!persistSourceLocation) return null;
// Location persistence for type mungers was added after 1.2.1 was shipped...
if (s.getMajorVersion()<AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) return null;
SourceLocation ret = null;
@@ -196,7 +194,6 @@ public abstract class ResolvedTypeMunger {
}
protected void writeSourceLocation(DataOutputStream s) throws IOException {
if (!persistSourceLocation) return;
ObjectOutputStream oos = new ObjectOutputStream(s);
// oos.writeObject(location);
oos.writeObject(new Boolean(location!=null));

+ 50
- 12
weaver/src/org/aspectj/weaver/TypeVariable.java View File

@@ -11,6 +11,8 @@
* ******************************************************************/
package org.aspectj.weaver;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

@@ -106,10 +108,10 @@ public class TypeVariable {
/**
* resolve all the bounds of this type variable
*/
public void resolve(World inSomeWorld) {
if (beingResolved) { return; } // avoid spiral of death
public TypeVariable resolve(World inSomeWorld) {
if (beingResolved) { return this; } // avoid spiral of death
beingResolved = true;
if (isResolved) return;
if (isResolved) return this;

TypeVariable resolvedTVar = null;

@@ -128,13 +130,14 @@ public class TypeVariable {
} else {
// look for type variable on method...
ResolvedMember declaring = (ResolvedMember) declaringElement;
UnresolvedType[] tvrts = declaring.getTypeVariables();
TypeVariable[] tvrts = declaring.getTypeVariables();
for (int i = 0; i < tvrts.length; i++) {
if (tvrts[i].isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) tvrts[i].resolve(inSomeWorld);
TypeVariable tv = tvrt.getTypeVariable();
if (tv.getName().equals(getName())) resolvedTVar = tv;
}
if (tvrts[i].getName().equals(getName())) resolvedTVar = tvrts[i];
// if (tvrts[i].isTypeVariableReference()) {
// TypeVariableReferenceType tvrt = (TypeVariableReferenceType) tvrts[i].resolve(inSomeWorld);
// TypeVariable tv = tvrt.getTypeVariable();
// if (tv.getName().equals(getName())) resolvedTVar = tv;
// }
}
}
@@ -155,12 +158,14 @@ public class TypeVariable {
upperBound = upperBound.resolve(inSomeWorld);
if (lowerBound != null) lowerBound = lowerBound.resolve(inSomeWorld);
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
additionalInterfaceBounds[i] = additionalInterfaceBounds[i].resolve(inSomeWorld);
if (additionalInterfaceBounds!=null) {
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
additionalInterfaceBounds[i] = additionalInterfaceBounds[i].resolve(inSomeWorld);
}
}
isResolved = true;
beingResolved = false;
return this;
}
/**
@@ -320,4 +325,37 @@ public class TypeVariable {
return declaringElementKind;
}
public void write(DataOutputStream s) throws IOException {
// name, upperbound, additionalInterfaceBounds, lowerbound
s.writeUTF(name);
upperBound.write(s);
if (additionalInterfaceBounds==null || additionalInterfaceBounds.length==0) {
s.writeInt(0);
} else {
s.writeInt(additionalInterfaceBounds.length);
for (int i = 0; i < additionalInterfaceBounds.length; i++) {
UnresolvedType ibound = additionalInterfaceBounds[i];
ibound.write(s);
}
}
}
public static TypeVariable read(VersionedDataInputStream s) throws IOException {
//if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
String name = s.readUTF();
UnresolvedType ubound = UnresolvedType.read(s);
int iboundcount = s.readInt();
UnresolvedType[] ibounds = null;
if (iboundcount>0) {
ibounds = new UnresolvedType[iboundcount];
for (int i=0; i<iboundcount; i++) {
ibounds[i] = UnresolvedType.read(s);
}
}
TypeVariable newVariable = new TypeVariable(name,ubound,ibounds);
return newVariable;
}
}

+ 1
- 1
weaver/src/org/aspectj/weaver/TypeVariableDeclaringElement.java View File

@@ -19,5 +19,5 @@ package org.aspectj.weaver;
* the declaring element
*/
public interface TypeVariableDeclaringElement {
public TypeVariable getTypeVariableNamed(String name);
}

+ 19
- 12
weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java View File

@@ -22,6 +22,12 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
private TypeVariable typeVariable;
private boolean resolvedIfBounds = false;
// If 'fixedUp' then the type variable in here is a reference to the real one that may
// exist either on a member or a type. Not fixedUp means that we unpacked a generic
// signature and weren't able to fix it up during resolution (didn't quite know enough
// at the right time). Wonder if we can fix it up late?
boolean fixedUp = false;
public TypeVariableReferenceType(
TypeVariable aTypeVariable,
World aWorld) {
@@ -62,6 +68,7 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
}
public TypeVariable getTypeVariable() {
// if (!fixedUp) throw new BCException("ARGH"); // SAUSAGES - fix it up now?
return typeVariable;
}
@@ -104,17 +111,17 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
public void write(DataOutputStream s) throws IOException {
super.write(s);
TypeVariableDeclaringElement tvde = typeVariable.getDeclaringElement();
if (tvde == null) {
s.writeInt(TypeVariable.UNKNOWN);
} else {
s.writeInt(typeVariable.getDeclaringElementKind());
if (typeVariable.getDeclaringElementKind() == TypeVariable.TYPE) {
((UnresolvedType)tvde).write(s);
} else if (typeVariable.getDeclaringElementKind() == TypeVariable.METHOD){
// it's a method
((ResolvedMember)tvde).write(s);
}
}
// TypeVariableDeclaringElement tvde = typeVariable.getDeclaringElement();
// if (tvde == null) {
// s.writeInt(TypeVariable.UNKNOWN);
// } else {
// s.writeInt(typeVariable.getDeclaringElementKind());
// if (typeVariable.getDeclaringElementKind() == TypeVariable.TYPE) {
// ((UnresolvedType)tvde).write(s);
// } else if (typeVariable.getDeclaringElementKind() == TypeVariable.METHOD){
// // it's a method
// ((ResolvedMember)tvde).write(s);
// }
// }
}
}

+ 9
- 4
weaver/src/org/aspectj/weaver/UnresolvedType.java View File

@@ -779,10 +779,6 @@ public class UnresolvedType implements TypeVariableDeclaringElement {
return ResolvedType.MISSING;
} else {
UnresolvedType ret = UnresolvedType.forSignature(sig);
// ugh, this is horrid, we shouldn't know about this subclass.
if (ret instanceof UnresolvedTypeVariableReferenceType) {
UnresolvedTypeVariableReferenceType.readDeclaringElement(s, (UnresolvedTypeVariableReferenceType)ret);
}
return ret;
}
}
@@ -883,5 +879,14 @@ public class UnresolvedType implements TypeVariableDeclaringElement {
throw new RuntimeException("I dont know - you should ask a resolved version of me: "+this);
}
public TypeVariable getTypeVariableNamed(String name) {
if (typeVariables==null || typeVariables.length==0) return null;
for (int i = 0; i < typeVariables.length; i++) {
TypeVariable aVar = typeVariables[i];
if (aVar.getName().equals(name)) return aVar;
}
return null;
}
}


+ 49
- 19
weaver/src/org/aspectj/weaver/UnresolvedTypeVariableReferenceType.java View File

@@ -11,7 +11,6 @@
* ******************************************************************/
package org.aspectj.weaver;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

@@ -41,13 +40,56 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
}
public ResolvedType resolve(World world) {
if (typeVariable == null) {
throw new BCException("Cannot resolve this type variable reference, the type variable has not been set!");
TypeVariableDeclaringElement typeVariableScope = world.getTypeVariableLookupScope();
TypeVariable resolvedTypeVariable = null;
TypeVariableReferenceType tvrt = null;
if (typeVariableScope == null) {
// throw new BCException("There is no scope in which to lookup type variables!");
// SAUSAGES correct thing to do is go bang, but to limp along, lets cope with the scope missing
resolvedTypeVariable = typeVariable.resolve(world);
tvrt = new TypeVariableReferenceType(resolvedTypeVariable,world);
} else {
boolean foundOK = false;
resolvedTypeVariable = typeVariableScope.getTypeVariableNamed(typeVariable.getName());
// SAUSAGES remove this when the shared type var stuff is sorted
if (resolvedTypeVariable == null) {
resolvedTypeVariable = typeVariable.resolve(world);
} else {
foundOK = true;
}
tvrt = new TypeVariableReferenceType(resolvedTypeVariable,world);
tvrt.fixedUp = foundOK;
}
typeVariable.resolve(world);
return new TypeVariableReferenceType(typeVariable,world);
return tvrt;
// // SAUSAGES should really be resolved in a scope, or you won't get the type variable you really want!
// //throw new BCException("NO - UnresolvedTypeVariableReferenceTypes must be resolved in a type variable scope");
// 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);
}
// public ResolvedType resolve(World world,TypeVariableDeclaringElement tvde) {
// if (typeVariable == null) {
// throw new BCException("Cannot resolve this type variable reference, the type variable has not been set!");
// }
//
// // SAUSAGES temporary whilst the ITD logic gets sorted out
// if (tvde == null) return new TypeVariableReferenceType(typeVariable.resolve(world),world);
//
// TypeVariable resolvedTypeVariable = tvde.getTypeVariableNamed(typeVariable.getName());
// if (resolvedTypeVariable == null) {
// resolvedTypeVariable = typeVariable.resolve(world);
// // SAUSAGES put this in once ITDs remember the complex shared type var stuff
// // throw new BCException("Could not locate type variable '"+typeVariable.getName()+"' during resolution, scope was: "+tvde);
// }
// TypeVariableReferenceType tvrt = new TypeVariableReferenceType(resolvedTypeVariable,world);
// tvrt.fixedUp = true;
// return tvrt;
// }
public boolean isTypeVariableReference() {
return true;
}
@@ -71,20 +113,8 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
public void write(DataOutputStream s) throws IOException {
super.write(s);
TypeVariableDeclaringElement tvde = typeVariable.getDeclaringElement();
if (tvde == null) {
s.writeInt(TypeVariable.UNKNOWN);
} else {
s.writeInt(typeVariable.getDeclaringElementKind());
if (typeVariable.getDeclaringElementKind() == TypeVariable.TYPE) {
((UnresolvedType)tvde).write(s);
} else if (typeVariable.getDeclaringElementKind() == TypeVariable.METHOD){
// it's a method
((ResolvedMember)tvde).write(s);
}
}
}
/*
public static void readDeclaringElement(DataInputStream s, UnresolvedTypeVariableReferenceType utv)
throws IOException {
int kind = s.readInt();
@@ -97,5 +127,5 @@ public class UnresolvedTypeVariableReferenceType extends UnresolvedType implemen
utv.typeVariable.setDeclaringElement(rm);
}
}
*/
}

+ 13
- 1
weaver/src/org/aspectj/weaver/World.java View File

@@ -45,6 +45,9 @@ public abstract class World implements Dump.INode {
/** handler for cross-reference information produced during the weaving process */
private ICrossReferenceHandler xrefHandler = null;

/** Currently 'active' scope in which to lookup (resolve) typevariable references */
private TypeVariableDeclaringElement typeVariableLookupScope;
/** The heart of the world, a map from type signatures to resolved types */
protected TypeMap typeMap = new TypeMap(); // Signature to ResolvedType

@@ -329,7 +332,7 @@ public abstract class World implements Dump.INode {
// 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) {
if (rawType.isSimpleType() && (anUnresolvedType.typeParameters==null || anUnresolvedType.typeParameters.length==0)) {
rawType.world = this;
return rawType;
}
@@ -546,6 +549,15 @@ public abstract class World implements Dump.INode {
public ICrossReferenceHandler getCrossReferenceHandler() {
return this.xrefHandler;
}
public void setTypeVariableLookupScope(TypeVariableDeclaringElement scope) {
this.typeVariableLookupScope = scope;
}

public TypeVariableDeclaringElement getTypeVariableLookupScope() {
return typeVariableLookupScope;
}


public List getDeclareParents() {
return crosscuttingMembersSet.getDeclareParents();

+ 7
- 10
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java View File

@@ -106,15 +106,12 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
weaver.getLazyClassGen().getOrCreateWeaverStateInfo(weaver.getReweavableMode());
info.addConcreteMunger(this);
}
// Whilst type mungers aren't persisting their source locations, we add this relationship during
// compilation time (see other reference to ResolvedTypeMunger.persist)
if (ResolvedTypeMunger.persistSourceLocation) {
if (changed && worthReporting) {
if (munger.getKind().equals(ResolvedTypeMunger.Parent)) {
AsmRelationshipProvider.getDefault().addRelationship(weaver.getLazyClassGen().getType(), munger,getAspectType());
} else {
AsmRelationshipProvider.getDefault().addRelationship(weaver.getLazyClassGen().getType(), munger,getAspectType());
}

if (changed && worthReporting) {
if (munger.getKind().equals(ResolvedTypeMunger.Parent)) {
AsmRelationshipProvider.getDefault().addRelationship(weaver.getLazyClassGen().getType(), munger,getAspectType());
} else {
AsmRelationshipProvider.getDefault().addRelationship(weaver.getLazyClassGen().getType(), munger,getAspectType());
}
}
@@ -894,7 +891,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
boolean matchOK = true;
for (int j = 0; j < memberParams.length && matchOK; j++){
UnresolvedType memberParam = memberParams[j];
UnresolvedType lookingForParam = lookingForParams[j].resolve(aspectType.getWorld());
UnresolvedType lookingForParam = lookingForParams[j].resolve(aspectType.getWorld());
if (lookingForParam.isTypeVariableReference()) lookingForParam = lookingForParam.getUpperBound();
if (!memberParam.equals(lookingForParam)){
matchOK=false;

Loading…
Cancel
Save