summaryrefslogtreecommitdiffstats
path: root/org.aspectj.ajdt.core
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 /org.aspectj.ajdt.core
parenta26f850c10f1790682ff9d1f13a4f8d5253f5e71 (diff)
downloadaspectj-900a3e81d5b09c55e4044451f311f0566c025ec6.tar.gz
aspectj-900a3e81d5b09c55e4044451f311f0566c025ec6.zip
genericitds: lots of new support for recursive type variables and ITD ctors.
Diffstat (limited to 'org.aspectj.ajdt.core')
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java26
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java31
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java171
3 files changed, 143 insertions, 85 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
index d524dcfbd..0f0cf78b2 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java
@@ -13,6 +13,7 @@
package org.aspectj.ajdt.internal.compiler.ast;
+import java.lang.reflect.Modifier;
import org.aspectj.ajdt.internal.compiler.lookup.*;
import org.aspectj.weaver.*;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
@@ -94,9 +95,16 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration {
pre.scope = new MethodScope(scope, pre, true);
//??? do we need to do anything with scope???
- pre.binding = world.makeMethodBinding(
- AjcMemberMaker.preIntroducedConstructor(aspectTypeX, targetTypeX,
- world.fromBindings(binding.parameters)));
+
+
+ // Use the factory to build a semi-correct resolvedmember - then patch it up with
+ // reset calls. This is SAFE
+ ResolvedMember preIntroducedConstructorRM = world.makeResolvedMember(binding);
+ preIntroducedConstructorRM.resetName(NameMangler.preIntroducedConstructor(aspectTypeX, targetTypeX));
+ preIntroducedConstructorRM.resetModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
+ preIntroducedConstructorRM.resetReturnTypeToObjectArray();
+
+ pre.binding = world.makeMethodBinding(preIntroducedConstructorRM);
pre.bindArguments();
pre.bindThrownExceptions();
@@ -218,12 +226,14 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration {
ResolvedType declaringTypeX = world.fromEclipse(onTypeBinding);
ResolvedType aspectType = world.fromEclipse(classScope.referenceContext.binding);
- ResolvedMember bindingAsMember = world.makeResolvedMember(binding);
- ResolvedMember signature =
- new ResolvedMemberImpl(Member.CONSTRUCTOR, declaringTypeX, declaredModifiers,
- ResolvedType.VOID, "<init>", bindingAsMember.getParameterTypes(),
- world.fromEclipse(binding.thrownExceptions));
+
+ // This signature represents what we want consumers of the targetted type to 'see'
+ ResolvedMember signature = world.makeResolvedMember(binding,onTypeBinding);
+ signature.resetKind(Member.CONSTRUCTOR);
+ signature.resetName("<init>");
+ signature.resetModifiers(declaredModifiers);
+
ResolvedMember syntheticInterMember =
AjcMemberMaker.interConstructor(declaringTypeX, signature, aspectType);
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
index f20476fdd..21c5f2106 100644
--- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
+++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
@@ -17,16 +17,6 @@ import java.lang.reflect.Modifier;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger;
-import org.aspectj.weaver.AjAttribute;
-import org.aspectj.weaver.AjcMemberMaker;
-import org.aspectj.weaver.Member;
-import org.aspectj.weaver.NameMangler;
-import org.aspectj.weaver.NewMethodTypeMunger;
-import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.ResolvedMemberImpl;
-import org.aspectj.weaver.ResolvedType;
-import org.aspectj.weaver.Shadow;
-import org.aspectj.weaver.UnresolvedType;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
@@ -39,6 +29,14 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AjcMemberMaker;
+import org.aspectj.weaver.NameMangler;
+import org.aspectj.weaver.NewMethodTypeMunger;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.UnresolvedType;
/**
* An inter-type method declaration.
@@ -125,12 +123,13 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration {
if (isTargetAnnotation(classScope,"method")) return null; // Error message output in isTargetAnnotation
if (isTargetEnum(classScope,"method")) return null; // Error message output in isTargetEnum
- ResolvedMemberImpl sig = new ResolvedMemberImpl(Member.METHOD, world.fromBinding(onTypeBinding),
- declaredModifiers, world.fromBinding(binding.returnType), new String(declaredSelector),
- world.fromBindings(binding.parameters),
- world.fromEclipse(binding.thrownExceptions));
-
- sig.setTypeVariables(world.fromBindings(binding.typeVariables));
+
+ // This signature represents what we want consumers of the targetted type to 'see'
+ // must use the factory method to build it since there may be typevariables from the binding
+ // referred to in the parameters/returntype
+ ResolvedMember sig = world.makeResolvedMember(binding,onTypeBinding);
+ sig.resetName(new String(declaredSelector));
+ sig.resetModifiers(declaredModifiers);
NewMethodTypeMunger myMunger = new NewMethodTypeMunger(sig, null);
setMunger(myMunger);
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 b853c14a0..85810decc 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
@@ -24,26 +24,8 @@ import java.util.Map;
import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.AstUtil;
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;
-import org.aspectj.weaver.ReferenceType;
-import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.ResolvedMemberImpl;
-import org.aspectj.weaver.ResolvedType;
-import org.aspectj.weaver.Shadow;
-import org.aspectj.weaver.TypeFactory;
-import org.aspectj.weaver.TypeVariable;
-import org.aspectj.weaver.TypeVariableDeclaringElement;
-import org.aspectj.weaver.TypeVariableReference;
-import org.aspectj.weaver.TypeVariableReferenceType;
-import org.aspectj.weaver.UnresolvedType;
-import org.aspectj.weaver.UnresolvedTypeVariableReferenceType;
-import org.aspectj.weaver.World;
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
@@ -64,9 +46,24 @@ 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;
+import org.aspectj.weaver.BoundedReferenceType;
+import org.aspectj.weaver.ConcreteTypeMunger;
+import org.aspectj.weaver.IHasPosition;
+import org.aspectj.weaver.Member;
+import org.aspectj.weaver.ReferenceType;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedMemberImpl;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.TypeFactory;
+import org.aspectj.weaver.TypeVariable;
+import org.aspectj.weaver.TypeVariableDeclaringElement;
+import org.aspectj.weaver.TypeVariableReference;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.UnresolvedTypeVariableReferenceType;
+import org.aspectj.weaver.World;
/**
* @author Jim Hugunin
@@ -231,10 +228,14 @@ public class EclipseFactory {
}
}
ResolvedType baseType = UnresolvedType.forName(getName(binding)).resolve(getWorld());
- return TypeFactory.createParameterizedType(
- baseType,
- arguments,
- getWorld());
+
+ // Create an unresolved parameterized type. We can't create a resolved one as the
+ // act of resolution here may cause recursion problems since the parameters may
+ // be type variables that we haven't fixed up yet.
+ if (!baseType.isGenericType() && arguments!=null) baseType = baseType.getGenericType();
+ if (arguments==null) arguments=new UnresolvedType[0];
+ String parameterizedSig = ResolvedType.PARAMETERIZED_TYPE_IDENTIFIER+CharOperation.charToString(binding.genericTypeSignature()).substring(1);
+ return TypeFactory.createUnresolvedParameterizedType(parameterizedSig,baseType.getErasureSignature(),arguments);
}
// Convert the source type binding for a generic type into a generic UnresolvedType
@@ -261,27 +262,47 @@ public class EclipseFactory {
return UnresolvedType.forName(getName(binding));
}
+ /**
+ * Some type variables refer to themselves recursively, this enables us to avoid
+ * recursion problems.
+ */
private static Map typeVariableBindingsInProgress = new HashMap();
+
+ /**
+ * Convert from the eclipse form of type variable (TypeVariableBinding) to the AspectJ
+ * form (TypeVariable).
+ */
private UnresolvedType fromTypeVariableBinding(TypeVariableBinding aTypeVariableBinding) {
+ // first, check for recursive call to this method for the same tvBinding
if (typeVariableBindingsInProgress.containsKey(aTypeVariableBinding)) {
return (UnresolvedType) typeVariableBindingsInProgress.get(aTypeVariableBinding);
}
+ if (typeVariablesForThisMember.containsKey(new Integer(aTypeVariableBinding.rank))) {
+ return (UnresolvedType)typeVariablesForThisMember.get(new Integer(aTypeVariableBinding.rank));
+ }
+ // Create the UnresolvedTypeVariableReferenceType for the type variable
+ String name = CharOperation.charToString(aTypeVariableBinding.sourceName());
+
UnresolvedTypeVariableReferenceType ret = new UnresolvedTypeVariableReferenceType();
typeVariableBindingsInProgress.put(aTypeVariableBinding,ret);
+
+ // Dont set any bounds here, you'll get in a recursive mess
// TODO -- what about lower bounds??
- String name = new String(aTypeVariableBinding.sourceName());
- UnresolvedType superclassType = fromBinding(aTypeVariableBinding.superclass());
+ UnresolvedType superclassType = fromBinding(aTypeVariableBinding.superclass());
UnresolvedType[] superinterfaces = new UnresolvedType[aTypeVariableBinding.superInterfaces.length];
for (int i = 0; i < superinterfaces.length; i++) {
superinterfaces[i] = fromBinding(aTypeVariableBinding.superInterfaces[i]);
}
TypeVariable tv = new TypeVariable(name,superclassType,superinterfaces);
+ tv.setUpperBound(superclassType);
+ tv.setAdditionalInterfaceBounds(superinterfaces);
tv.setRank(aTypeVariableBinding.rank);
- // getting things right for method declaring elements is tricky...
- if (!(aTypeVariableBinding.declaringElement instanceof MethodBinding)) {
- tv.setDeclaringElement(fromBinding(aTypeVariableBinding.declaringElement));
- }
- tv.resolve(world);
+// dont need the declaring element yet...
+// if (aTypeVariableBinding.declaringElement instanceof MethodBinding) {
+// tv.setDeclaringElement(fromBinding((MethodBinding)aTypeVariableBinding.declaringElement);
+// } else {
+// // tv.setDeclaringElement(fromBinding(aTypeVariableBinding.declaringElement));
+// }
ret.setTypeVariable(tv);
typeVariableBindingsInProgress.remove(aTypeVariableBinding);
return ret;
@@ -369,8 +390,30 @@ public class EclipseFactory {
return makeResolvedMember(binding, binding.declaringClass);
}
+ /**
+ * Conversion from a methodbinding (eclipse) to a resolvedmember (aspectj) is now done
+ * in the scope of some type variables. Before converting the parts of a methodbinding
+ * (params, return type) we store the type variables in this structure, then should any
+ * component of the method binding refer to them, we grab them from the map.
+ */
+ // FIXME asc convert to array, indexed by rank
+ private Map typeVariablesForThisMember = new HashMap();
+
public ResolvedMember makeResolvedMember(MethodBinding binding, TypeBinding declaringType) {
//System.err.println("member for: " + binding + ", " + new String(binding.declaringClass.sourceName));
+
+ // Convert the type variables and store them
+ UnresolvedType[] ajTypeRefs = null;
+
+ // This is the set of type variables available whilst building the resolved member...
+ if (binding.typeVariables!=null) {
+ ajTypeRefs = new UnresolvedType[binding.typeVariables.length];
+ for (int i = 0; i < binding.typeVariables.length; i++) {
+ ajTypeRefs[i] = fromBinding(binding.typeVariables[i]);
+ typeVariablesForThisMember.put(new Integer(binding.typeVariables[i].rank),ajTypeRefs[i]);
+ }
+ }
+
// AMC these next two lines shouldn't be needed once we sort out generic types properly in the world map
ResolvedType realDeclaringType = world.resolve(fromBinding(declaringType));
if (realDeclaringType.isRawType()) realDeclaringType = realDeclaringType.getGenericType();
@@ -378,10 +421,14 @@ public class EclipseFactory {
binding.isConstructor() ? Member.CONSTRUCTOR : Member.METHOD,
realDeclaringType,
binding.modifiers,
- world.resolve(fromBinding(binding.returnType)),
+ fromBinding(binding.returnType),
new String(binding.selector),
- world.resolve(fromBindings(binding.parameters)),
- world.resolve(fromBindings(binding.thrownExceptions)));
+ fromBindings(binding.parameters),
+ fromBindings(binding.thrownExceptions)
+ );
+ if (ajTypeRefs!=null) ret.setTypeVariables(ajTypeRefs);
+ typeVariablesForThisMember.clear();
+ ret.resolve(world);
return ret;
}
@@ -407,7 +454,7 @@ public class EclipseFactory {
if (ret == null) {
ret = makeTypeBinding1(typeX);
// FIXME asc keep type variables *out* of the map for now, they go in typeVariableToTypeBinding
- if (!(typeX instanceof TypeVariableReference))
+ if (!(typeX instanceof BoundedReferenceType))
typexToBinding.put(typeX, ret);
}
if (ret == null) {
@@ -457,8 +504,8 @@ public class EclipseFactory {
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;
+ if (brt.isExtends()) boundkind = Wildcard.EXTENDS;
+ if (brt.isSuper()) boundkind = Wildcard.SUPER;
// get the bound right
TypeBinding bound = null;
if (brt.isGenericWildcardExtends()) bound = makeTypeBinding(brt.getUpperBound());
@@ -518,46 +565,48 @@ 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()),
- declaringType);
+ TypeVariableBinding[] tvbs = null;
+
if (member.getTypeVariables()!=null) {
if (member.getTypeVariables().length==0) {
- mb.typeVariables = MethodBinding.NoTypeVariables;
+ tvbs = MethodBinding.NoTypeVariables;
} else {
- TypeVariableBinding[] tvbs = makeTypeVariableBindings(member.getTypeVariables());
+ 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;
- }
+// if (binding.declaringElement==null && ((TypeVariableReference)member.getTypeVariables()[i]).getTypeVariable().getDeclaringElement() instanceof Member) {
+// tvbs[i].declaringElement = mb;
+// } else {
+// tvbs[i].declaringElement = declaringType;
+// }
}
- mb.typeVariables = tvbs;
}
- }
+ }
+
+ ReferenceBinding declaringType = (ReferenceBinding)makeTypeBinding(member.getDeclaringType());
+ MethodBinding mb = new MethodBinding(member.getModifiers(),
+ member.getName().toCharArray(),
+ makeTypeBinding(member.getReturnType()),
+ makeTypeBindings(member.getParameterTypes()),
+ makeReferenceBindings(member.getExceptions()),
+ declaringType);
+
+ if (tvbs!=null) mb.typeVariables = tvbs;
typeVariableToTypeBinding.clear();
+
return mb;
}
-
+ /**
+ * Convert a bunch of type variables in one go, from AspectJ form to Eclipse form.
+ */
private TypeVariableBinding[] makeTypeVariableBindings(UnresolvedType[] typeVariables) {
int len = typeVariables.length;
TypeVariableBinding[] ret = new TypeVariableBinding[len];
for (int i = 0; i < len; i++) {
- TypeVariableReference tvReference = (TypeVariableReference)typeVariables[i];
- TypeVariableBinding tvb = (TypeVariableBinding)typeVariableToTypeBinding.get(tvReference.getTypeVariable().getName());
- if (tvb==null) {
- tvb = makeTypeVariableBinding(tvReference);
- }
- ret[i] = tvb;
+ ret[i] = makeTypeVariableBinding((TypeVariableReference)typeVariables[i]);
}
return ret;
}
@@ -575,7 +624,7 @@ public class EclipseFactory {
*/
private TypeVariableBinding makeTypeVariableBinding(TypeVariableReference tvReference) {
TypeVariable tVar = tvReference.getTypeVariable();
- TypeVariableBinding tvBinding = (TypeVariableBinding)typeVariableToTypeBinding.get(tVar);
+ TypeVariableBinding tvBinding = (TypeVariableBinding)typeVariableToTypeBinding.get(tVar.getName());
if (tvBinding==null) {
Binding declaringElement = null;
// this will cause an infinite loop or NPE... not required yet luckily.
@@ -585,6 +634,7 @@ public class EclipseFactory {
// declaringElement = makeTypeBinding((UnresolvedType)tVar.getDeclaringElement());
// }
tvBinding = new TypeVariableBinding(tVar.getName().toCharArray(),declaringElement,tVar.getRank());
+ typeVariableToTypeBinding.put(tVar.getName(),tvBinding);
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) {
@@ -596,7 +646,6 @@ public class EclipseFactory {
rbs[i] = (ReferenceBinding)tbs[i];
}
tvBinding.superInterfaces=rbs;
- typeVariableToTypeBinding.put(tVar.getName(),tvBinding);
}
}
return tvBinding;