}
// ??? duplicates some of super's code
public void completeTypeBindings() {
AsmManager.setCompletingTypeBindings(true);
ContextToken completeTypeBindingsToken = CompilationAndWeavingContext.enteringPhase(
CompilationAndWeavingContext.COMPLETING_TYPE_BINDINGS, "");
// builtInterTypesAndPerClauses = false;
// pendingTypesToWeave = new ArrayList();
stepCompleted = BUILD_TYPE_HIERARCHY;
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CHECK_AND_SET_IMPORTS,
units[i].compilationResult.fileName);
units[i].scope.checkAndSetImports();
CompilationAndWeavingContext.leavingPhase(tok);
}
stepCompleted = CHECK_AND_SET_IMPORTS;
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CONNECTING_TYPE_HIERARCHY,
units[i].compilationResult.fileName);
units[i].scope.connectTypeHierarchy();
CompilationAndWeavingContext.leavingPhase(tok);
}
stepCompleted = CONNECT_TYPE_HIERARCHY;
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.BUILDING_FIELDS_AND_METHODS,
units[i].compilationResult.fileName);
// units[i].scope.checkParameterizedTypes(); do this check a little
// later, after ITDs applied to stbs
units[i].scope.buildFieldsAndMethods();
CompilationAndWeavingContext.leavingPhase(tok);
}
// would like to gather up all TypeDeclarations at this point and put
// them in the factory
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
SourceTypeBinding[] b = units[i].scope.topLevelTypes;
for (int j = 0; j < b.length; j++) {
factory.addSourceTypeBinding(b[j], units[i]);
}
}
// We won't find out about anonymous types until later though, so
// register to be
// told about them when they turn up.
AnonymousClassPublisher.aspectOf().setAnonymousClassCreationListener(this);
// need to build inter-type declarations for all AspectDeclarations at
// this point
// this MUST be done in order from super-types to subtypes
List<SourceTypeBinding> typesToProcess = new ArrayList<SourceTypeBinding>();
List<SourceTypeBinding> aspectsToProcess = new ArrayList<SourceTypeBinding>();
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
CompilationUnitScope cus = units[i].scope;
SourceTypeBinding[] stbs = cus.topLevelTypes;
for (int j = 0; j < stbs.length; j++) {
SourceTypeBinding stb = stbs[j];
typesToProcess.add(stb);
TypeDeclaration typeDeclaration = stb.scope.referenceContext;
if (typeDeclaration instanceof AspectDeclaration) {
aspectsToProcess.add(stb);
}
}
}
factory.getWorld().getCrosscuttingMembersSet().reset();
// Need to do these before the other ITDs
for (SourceTypeBinding aspectToProcess : aspectsToProcess) {
processInterTypeMemberTypes(aspectToProcess.scope);
}
while (typesToProcess.size() > 0) {
// removes types from the list as they are processed...
collectAllITDsAndDeclares(typesToProcess.get(0), typesToProcess);
}
factory.finishTypeMungers();
// now do weaving
List<ConcreteTypeMunger> typeMungers = factory.getTypeMungers();
List<DeclareParents> declareParents = factory.getDeclareParents();
List<DeclareAnnotation> declareAnnotationOnTypes = factory.getDeclareAnnotationOnTypes();
doPendingWeaves();
// We now have some list of types to process, and we are about to apply
// the type mungers.
// There can be situations where the order of types passed to the
// compiler causes the
// output from the compiler to vary - THIS IS BAD. For example, if we
// have class A
// and class B extends A. Also, an aspect that 'declare parents: A+
// implements Serializable'
// then depending on whether we see A first, we may or may not make B
// serializable.
// The fix is to process them in the right order, ensuring that for a
// type we process its
// supertypes and superinterfaces first. This algorithm may have
// problems with:
// - partial hierarchies (e.g. suppose types A,B,C are in a hierarchy
// and A and C are to be woven but not B)
// - weaving that brings new types in for processing (see
// pendingTypesToWeave.add() calls) after we thought
// we had the full list.
//
// but these aren't common cases (he bravely said...)
boolean typeProcessingOrderIsImportant = declareParents.size() > 0 || declareAnnotationOnTypes.size() > 0; // DECAT
if (typeProcessingOrderIsImportant) {
typesToProcess = new ArrayList<SourceTypeBinding>();
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
CompilationUnitScope cus = units[i].scope;
SourceTypeBinding[] stbs = cus.topLevelTypes;
for (int j = 0; j < stbs.length; j++) {
SourceTypeBinding stb = stbs[j];
typesToProcess.add(stb);
}
}
List<SourceTypeBinding> stb2 = new ArrayList<SourceTypeBinding>();
stb2.addAll(typesToProcess);
while (typesToProcess.size() > 0) {
// A side effect of weaveIntertypes() is that the processed type is removed from the collection
weaveIntertypes(typesToProcess, typesToProcess.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 1);
}
while (stb2.size() > 0) {
// A side effect of weaveIntertypes() is that the processed type is removed from the collection
weaveIntertypes(stb2, stb2.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 2);
}
} else {
// Order isn't important
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents, declareAnnotationOnTypes);
}
}
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
units[i].scope.checkParameterizedTypes();
}
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
SourceTypeBinding[] b = units[i].scope.topLevelTypes;
for (int j = 0; j < b.length; j++) {
ContextToken tok = CompilationAndWeavingContext.enteringPhase(
CompilationAndWeavingContext.RESOLVING_POINTCUT_DECLARATIONS, b[j].sourceName);
resolvePointcutDeclarations(b[j].scope);
CompilationAndWeavingContext.leavingPhase(tok);
}
}
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
SourceTypeBinding[] b = units[i].scope.topLevelTypes;
for (int j = 0; j < b.length; j++) {
ContextToken tok = CompilationAndWeavingContext.enteringPhase(
CompilationAndWeavingContext.ADDING_DECLARE_WARNINGS_AND_ERRORS, b[j].sourceName);
addAdviceLikeDeclares(b[j].scope);
CompilationAndWeavingContext.leavingPhase(tok);
}
}