super(typeRequestor, options, problemReporter, nameEnvironment);
}
//??? duplicates some of super's code
public void completeTypeBindings() {
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.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 typesToProcess = new ArrayList();
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);
}
}
while (typesToProcess.size()>0) {
// removes types from the list as they are processed...
collectAllITDsAndDeclares((SourceTypeBinding)typesToProcess.get(0),typesToProcess);
}
factory.finishTypeMungers();
// now do weaving
Collection typeMungers = factory.getTypeMungers();
Collection declareParents = factory.getDeclareParents();
Collection 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();
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);
}
}
while (typesToProcess.size()>0) {
// A side effect of weaveIntertypes() is that the processed type is removed from the collection
weaveIntertypes(typesToProcess,(SourceTypeBinding)typesToProcess.get(0),typeMungers,declareParents,declareAnnotationOnTypes);
}
} else {
// Order isn't important
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
//System.err.println("Working on "+new String(units[i].getFileName()));
weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents,declareAnnotationOnTypes);
}
}
for (int i = lastCompletedUnitIndex +1; i<=lastUnitIndex; i++) {
SourceTypeBinding[] b = units[i].scope.topLevelTypes;
for (int j = 0; j < b.length; j++) {
verifyAnyTypeParametersMeetBounds(b[j]);
}
}
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);
}
}