import org.aspectj.weaver.*;
import org.aspectj.weaver.patterns.*;
import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
public class AjLookupEnvironment extends LookupEnvironment {
public EclipseWorld world = null;
+ private boolean builtInterTypesAndPerClauses = false;
+ private List pendingTypesToWeave = new ArrayList();
+
public AjLookupEnvironment(
ITypeRequestor typeRequestor,
CompilerOptions options,
super(typeRequestor, options, problemReporter, nameEnvironment);
}
- //XXX figure out if we can do this through super or not
- //XXX otherwise duplicates some of super's code
+ //??? duplicates some of super's code
public void completeTypeBindings() {
+ builtInterTypesAndPerClauses = false;
+ //pendingTypesToWeave = new ArrayList();
stepCompleted = BUILD_TYPE_HIERARCHY;
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
for (int j = 0; j < b.length; j++) {
buildInterTypeAndPerClause(b[j].scope);
}
- }
- //??? do we need a new stepCompleted
+ }
+ builtInterTypesAndPerClauses = true;
+ doPendingWeaves();
// now do weaving
Collection typeMungers = world.getTypeMungers();
stepCompleted = BUILD_FIELDS_AND_METHODS;
lastCompletedUnitIndex = lastUnitIndex;
}
+
+ private void doPendingWeaves() {
+ for (Iterator i = pendingTypesToWeave.iterator(); i.hasNext(); ) {
+ SourceTypeBinding t = (SourceTypeBinding)i.next();
+ weaveInterTypeDeclarations(t);
+ }
+ pendingTypesToWeave.clear();
+ }
+
private void buildInterTypeAndPerClause(ClassScope s) {
TypeDeclaration dec = s.referenceContext;
}
}
+
+
private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, Collection declareParents) {
for (int i = 0, length = unit.topLevelTypes.length; i < length; i++)
- weaveInterTypeDeclarations(unit.topLevelTypes[i].scope, typeMungers, declareParents);
+ weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents);
//System.err.println("done with inter types");
}
- private void weaveInterTypeDeclarations(ClassScope scope, Collection typeMungers, Collection declareParents) {
- //System.err.println("weaving: " + scope);
- SourceTypeBinding sourceType = scope.referenceContext.binding;
+
+ private void weaveInterTypeDeclarations(SourceTypeBinding sourceType) {
+ if (!builtInterTypesAndPerClauses) {
+ pendingTypesToWeave.add(sourceType);
+ } else {
+ //System.err.println("weaving: " + new String(sourceType.sourceName()) + ", " + world.getTypeMungers());
+ weaveInterTypeDeclarations(sourceType, world.getTypeMungers(), world.getDeclareParents());
+ }
+ }
+
+
+ private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents) {
ResolvedTypeX onType = world.fromEclipse(sourceType);
+ onType.clearInterTypeMungers();
+
for (Iterator i = declareParents.iterator(); i.hasNext();) {
- doDeclareParents((DeclareParents)i.next(), scope);
+ doDeclareParents((DeclareParents)i.next(), sourceType);
}
for (Iterator i = typeMungers.iterator(); i.hasNext();) {
for (Iterator i = onType.getInterTypeMungers().iterator(); i.hasNext();) {
EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
- munger.munge(scope);
+ munger.munge(sourceType);
}
ReferenceBinding[] memberTypes = sourceType.memberTypes;
for (int i = 0, length = memberTypes.length; i < length; i++) {
- weaveInterTypeDeclarations(((SourceTypeBinding) memberTypes[i]).scope, typeMungers, declareParents);
+ if (memberTypes[i] instanceof SourceTypeBinding) {
+ weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents);
+ }
}
}
- private void doDeclareParents(DeclareParents declareParents, ClassScope scope) {
- if (declareParents.match(world.fromEclipse(scope.referenceContext.binding))) {
+ private void doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) {
+ if (declareParents.match(world.fromEclipse(sourceType))) {
TypePatternList l = declareParents.getParents();
for (int i=0, len=l.size(); i < len; i++) {
- addParent(declareParents, scope, l.get(i));
+ addParent(declareParents, sourceType, l.get(i));
}
}
}
- private void addParent(DeclareParents declareParents, ClassScope scope, TypePattern typePattern) {
- SourceTypeBinding sourceType = scope.referenceContext.binding;
+ private void addParent(DeclareParents declareParents, SourceTypeBinding sourceType, TypePattern typePattern) {
//if (!typePattern.assertExactType(world.getMessageHandler())) return;
if (typePattern == TypePattern.NO) return; // already had an error here
TypeX iType = typePattern.getExactType();
}
}
-
- private TypeReference makeReference(ExactTypePattern e) {
- return new SingleTypeReference(e.getType().getName().toCharArray(),
- AstUtil.makeLongPos(e.getStart(), e.getEnd()));
+
+
+
+ private List pendingTypesToFinish = new ArrayList();
+ boolean inBinaryTypeCreation = false;
+ public BinaryTypeBinding createBinaryTypeFrom(
+ IBinaryType binaryType,
+ PackageBinding packageBinding,
+ boolean needFieldsAndMethods)
+ {
+ if (inBinaryTypeCreation) {
+ BinaryTypeBinding ret = super.createBinaryTypeFrom(
+ binaryType,
+ packageBinding,
+ needFieldsAndMethods);
+ pendingTypesToFinish.add(ret);
+ return ret;
+ }
+
+
+ inBinaryTypeCreation = true;
+ try {
+ BinaryTypeBinding ret = super.createBinaryTypeFrom(
+ binaryType,
+ packageBinding,
+ needFieldsAndMethods);
+ weaveInterTypeDeclarations(ret);
+
+ return ret;
+ } finally {
+ inBinaryTypeCreation = false;
+ if (!pendingTypesToFinish.isEmpty()) {
+ for (Iterator i = pendingTypesToFinish.iterator(); i.hasNext(); ) {
+ weaveInterTypeDeclarations((BinaryTypeBinding)i.next());
+ }
+ pendingTypesToFinish.clear();
+ }
+ }
}
-
-
}
public class EclipseTypeMunger extends ConcreteTypeMunger {
protected ReferenceBinding targetBinding = null;
private AbstractMethodDeclaration sourceMethod;
+ private EclipseWorld world;
public EclipseTypeMunger(ResolvedTypeMunger munger, ResolvedTypeX aspectType,
AbstractMethodDeclaration sourceMethod)
{
super(munger, aspectType);
this.sourceMethod = sourceMethod;
+ this.world = (EclipseWorld)aspectType.getWorld();
}
public String toString() {
return "(EclipseTypeMunger " + getMunger() + ")";
}
- private boolean match(ClassScope scope) {
+ private boolean match(SourceTypeBinding sourceType) {
if (targetBinding == null) {
TypeX targetTypeX = munger.getSignature().getDeclaringType();
- targetBinding =
- (ReferenceBinding)EclipseWorld.fromScopeLookupEnvironment(scope).makeTypeBinding(targetTypeX);
+ targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX);
}
//??? assumes instance uniqueness for ReferenceBindings
- return targetBinding == scope.referenceContext.binding;
+ return targetBinding == sourceType;
}
* Modifies signatures of a TypeBinding through its ClassScope,
* i.e. adds Method|FieldBindings, plays with inheritance, ...
*/
- public boolean munge(ClassScope classScope) {
- if (!match(classScope)) return false;
+ public boolean munge(SourceTypeBinding sourceType) {
+ if (!match(sourceType)) return false;
if (munger.getKind() == ResolvedTypeMunger.Field) {
- mungeNewField(classScope, (NewFieldTypeMunger)munger);
+ mungeNewField(sourceType, (NewFieldTypeMunger)munger);
} else if (munger.getKind() == ResolvedTypeMunger.Method) {
- mungeNewMethod(classScope, (NewMethodTypeMunger)munger);
+ mungeNewMethod(sourceType, (NewMethodTypeMunger)munger);
} else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
- mungeNewConstructor(classScope, (NewConstructorTypeMunger)munger);
+ mungeNewConstructor(sourceType, (NewConstructorTypeMunger)munger);
} else {
throw new RuntimeException("unimplemented");
}
}
- private void mungeNewMethod(ClassScope classScope, NewMethodTypeMunger munger) {
- EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
-
+ private void mungeNewMethod(SourceTypeBinding sourceType, NewMethodTypeMunger munger) {
// if (shouldTreatAsPublic()) {
// MethodBinding binding = world.makeMethodBinding(munger.getSignature());
// findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
// } else {
InterTypeMethodBinding binding =
new InterTypeMethodBinding(world, munger.getSignature(), aspectType, sourceMethod);
- findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
+ findOrCreateInterTypeMemberFinder(sourceType).addInterTypeMethod(binding);
// }
}
- private void mungeNewConstructor(ClassScope classScope, NewConstructorTypeMunger munger) {
- EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
-
+ private void mungeNewConstructor(SourceTypeBinding sourceType, NewConstructorTypeMunger munger) {
if (shouldTreatAsPublic()) {
MethodBinding binding = world.makeMethodBinding(munger.getSignature());
- findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
+ findOrCreateInterTypeMemberFinder(sourceType).addInterTypeMethod(binding);
//classScope.referenceContext.binding.addMethod(binding);
} else {
InterTypeMethodBinding binding =
new InterTypeMethodBinding(world, munger.getSignature(), aspectType, sourceMethod);
- findOrCreateInterTypeMemberFinder(classScope).addInterTypeMethod(binding);
+ findOrCreateInterTypeMemberFinder(sourceType).addInterTypeMethod(binding);
}
}
- private void mungeNewField(ClassScope classScope, NewFieldTypeMunger munger) {
- EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
-
+ private void mungeNewField(SourceTypeBinding sourceType, NewFieldTypeMunger munger) {
if (shouldTreatAsPublic() && !targetBinding.isInterface()) {
FieldBinding binding = world.makeFieldBinding(munger.getSignature());
- findOrCreateInterTypeMemberFinder(classScope).addInterTypeField(binding);
+ findOrCreateInterTypeMemberFinder(sourceType).addInterTypeField(binding);
//classScope.referenceContext.binding.addField(binding);
} else {
InterTypeFieldBinding binding =
new InterTypeFieldBinding(world, munger.getSignature(), aspectType, sourceMethod);
- findOrCreateInterTypeMemberFinder(classScope).addInterTypeField(binding);
+ findOrCreateInterTypeMemberFinder(sourceType).addInterTypeField(binding);
}
}
}
- private InterTypeMemberFinder findOrCreateInterTypeMemberFinder(ClassScope classScope) {
+ private InterTypeMemberFinder findOrCreateInterTypeMemberFinder(SourceTypeBinding sourceType) {
InterTypeMemberFinder finder =
- (InterTypeMemberFinder)classScope.referenceContext.binding.memberFinder;
+ (InterTypeMemberFinder)sourceType.memberFinder;
if (finder == null) {
finder = new InterTypeMemberFinder();
- classScope.referenceContext.binding.memberFinder = finder;
- finder.sourceTypeBinding = classScope.referenceContext.binding;
+ sourceType.memberFinder = finder;
+ finder.sourceTypeBinding = sourceType;
}
return finder;
}