// variation of "weave" that sources class files from an external source.
public Collection weave(IClassFileProvider input) throws IOException {
ContextToken weaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING, "");
Collection wovenClassNames = new ArrayList();
IWeaveRequestor requestor = input.getRequestor();
// special case for AtAspectJMungerOnly - see #113587
if (input.isApplyAtAspectJMungersOnly()) {
ContextToken atAspectJMungersOnly = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY, "");
requestor.weavingAspects();
ContextToken aspectToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, "");
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
UnwovenClassFile classFile = (UnwovenClassFile)i.next();
String className = classFile.getClassName();
ResolvedType theType = world.resolve(className);
if (theType.isAnnotationStyleAspect()) {
BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
if (classType==null) {
throw new BCException("Can't find bcel delegate for "+className+" type="+theType.getClass());
}
LazyClassGen clazz = classType.getLazyClassGen();
BcelPerClauseAspectAdder selfMunger = new BcelPerClauseAspectAdder(theType, theType.getPerClause().getKind());
selfMunger.forceMunge(clazz, true);
classType.finishedWith();
UnwovenClassFile[] newClasses = getClassFilesFor(clazz);
for (int news = 0; news < newClasses.length; news++) {
requestor.acceptResult(newClasses[news]);
}
wovenClassNames.add(classFile.getClassName());
}
}
requestor.weaveCompleted();
CompilationAndWeavingContext.leavingPhase(atAspectJMungersOnly);
return wovenClassNames;
}
requestor.processingReweavableState();
ContextToken reweaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE,"");
prepareToProcessReweavableState();
// clear all state from files we'll be reweaving
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
UnwovenClassFile classFile = (UnwovenClassFile)i.next();
String className = classFile.getClassName();
BcelObjectType classType = getClassType(className);
// null return from getClassType() means the delegate is an eclipse source type - so
// there *cant* be any reweavable state... (he bravely claimed...)
if (classType !=null) {
ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, className);
processReweavableStateIfPresent(className, classType);
CompilationAndWeavingContext.leavingPhase(tok);
}
}
CompilationAndWeavingContext.leavingPhase(reweaveToken);
ContextToken typeMungingToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS,"");
requestor.addingTypeMungers();
// We process type mungers in two groups, first mungers that change the type
// hierarchy, then 'normal' ITD type mungers.
// Process the types in a predictable order (rather than the order encountered).
// For class A, the order is superclasses of A then superinterfaces of A
// (and this mechanism is applied recursively)
List typesToProcess = new ArrayList();
for (Iterator iter = input.getClassFileIterator(); iter.hasNext();) {
UnwovenClassFile clf = (UnwovenClassFile) iter.next();
typesToProcess.add(clf.getClassName());
}
while (typesToProcess.size()>0) {
weaveParentsFor(typesToProcess,(String)typesToProcess.get(0));
}
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
UnwovenClassFile classFile = (UnwovenClassFile)i.next();
String className = classFile.getClassName();
addNormalTypeMungers(className);
}
CompilationAndWeavingContext.leavingPhase(typeMungingToken);
requestor.weavingAspects();
ContextToken aspectToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, "");
// first weave into aspects
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
UnwovenClassFile classFile = (UnwovenClassFile)i.next();
String className = classFile.getClassName();
ResolvedType theType = world.resolve(className);
if (theType.isAspect()) {
BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
if (classType==null) {
// Sometimes.. if the Bcel Delegate couldn't be found then a problem occurred at compile time - on
// a previous compiler run. In this case I assert the delegate will still be an EclipseSourceType
// and we can ignore the problem here (the original compile error will be reported again from
// the eclipse source type) - pr113531
ReferenceTypeDelegate theDelegate = ((ReferenceType)theType).getDelegate();
if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) continue;
throw new BCException("Can't find bcel delegate for "+className+" type="+theType.getClass());
}
weaveAndNotify(classFile, classType,requestor);
wovenClassNames.add(className);
}
}
CompilationAndWeavingContext.leavingPhase(aspectToken);
requestor.weavingClasses();
ContextToken classToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_CLASSES, "");
// then weave into non-aspects
for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
UnwovenClassFile classFile = (UnwovenClassFile)i.next();
String className = classFile.getClassName();
ResolvedType theType = world.resolve(className);
if (!theType.isAspect()) {
BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
if (classType==null) {
throw new BCException("Can't find bcel delegate for "+className+" type="+theType.getClass());
}
weaveAndNotify(classFile, classType, requestor);
wovenClassNames.add(className);
}
}
CompilationAndWeavingContext.leavingPhase(classToken);
addedClasses = new ArrayList();
deletedTypenames = new ArrayList();
warnOnUnmatchedAdvice();
requestor.weaveCompleted();
CompilationAndWeavingContext.leavingPhase(weaveToken);
return wovenClassNames;
}