diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/developer/amcDesignNotes.txt | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/docs/developer/amcDesignNotes.txt b/docs/developer/amcDesignNotes.txt new file mode 100644 index 000000000..981fd3ae8 --- /dev/null +++ b/docs/developer/amcDesignNotes.txt @@ -0,0 +1,388 @@ + +How Compilation Progresses in the JDT: +====================================== + +Compiler.compile(ICompilationUnit[] sourceUnits) { + + foreach sourceUnit + create a new CompilationUnitResult + CompilationUnitDeclaration = parser.parse(sourceUnit, result) + remember CompilationUnitDeclaration (holds ref to result) in + "unitsToProcess" + end + + foreach unitToProcess + resolve + analyse + generateCode + puts class files (plural) into CompilationUnitResult + + unit.cleanup (discards AST info etc.) + requestor.acceptResult(result) -- each requestor does there own thing + discard CompilationUnitDeclaration + end +} + +Some portions of the JDT call the resolve method instead of compile, +this works the same way except that there is only a single sourceUnit +passed to the compiler, and the code generation phase is optional +(controlled by flag passed by caller). + + +How (batch) Compilation Progresses in AspectJ 1.1.x +=================================================== + +AjBuildManager.doBuild() { + + init phase + ---------- + new AjState().prepareForNextBuild() + builds empty lists to hold classes etc. + + setUpModel() // this stage should be omitted unless s.one wants it + + new BcelWorld(classpath) + new BcelWeaver(world) + + add all aspectpath entries to weaver + add all injars to weaver + add all inpath entries to weaver + add all source path *resources* to weaver + + compile phase + ------------- + build name environment, lookup environment, problem reporter and + compiler + + compiler.compile() + proceeds as above, we pass in a requestor that adds the + resulting class files in the result into a list of addedClassFiles + in AjState + + weave phase + ----------- + add the addedClassFiles to the weaver + + pass over all class files known to weaver, building xcut set + pass over all types, adding interTypeMungers to them + pass over all aspects, weave them + pass over all classes, weave them + + write out any resources added to weaver +} + +How we want (batch) compilation to proceed in AspectJ 1.2 +========================================================= + +The key design goal is to do all the work inside the compile method of +the compiler (this makes life much easier for integration with the +rest of the JDT that, quite reasonably, expects the class files to be +ready for action once a compile has completed). The second design goal +is that it should be up to the requestor passed into the compiler +whether or not the class files actually get written out to disk +(different parts of the JDT pass in many different kinds of requestors +that do different things). + +This simple model ignores aspectpath, inpath, injars, outjar, +sourceDirs for now. + +Compiler.compile(ICompilationUnit[] sourceUnits) { + + initial parse phase + ------------------- + foreach sourceUnit + create a new CompilationUnitResult + CompilationUnitDeclaration = parser.parse(sourceUnit, result) + remember CompilationUnitDeclaration (holds ref to result) in + "unitsToProcess" + end + + generate phase + -------------- + foreach unitToProcess + resolve + analyse + generateCode + puts class files (plural) into CompilationUnitResult + + unit.cleanup (discards AST info etc.) + + // up to this point we are identical to JDT current behaviour, + // from now on we deviate + resultsPendingWeave.add(result) + discard CompilationUnitDeclaration + end + + weave phase + ----------- + //createWorldAndWeaver(classpath) + //the world and weaver have to be passed into the compiler, to + //support incremental use cases. + + buildXCutSet(resultsPendingWeave) + addTypeMungers(resultsPendingWeave) + weaveAspects(resultsPendingWeave) + weaveClasses(resultsPendingWeave) + + completion phase + ---------------- + foreach resultPendingWeave + requestor.acceptResult(result) -- each requestor does their own + thing + end + + // note : movement of any resouces is moved to outside of compile + // altogether. In eclipse, the xxxImageBuilders handle this. +} + + +buildXCutSet(resultsPendingWeave) { + foreach resultPendingWeave + foreach classfile + resolve + if aspect, add to xcut set. + end + end +} + +addTypeMungers(resultsPendingWeave) { + foreach resultPendingWeave + foreach classfile + resolve + addTypeMungers + end + end +} + +weaveAspect(resultsPendingWeave) { + foreach resultPendingWeave + foreach classfile + get corresponding BcelObjectType + weave + update classfile held in result + end + end +} + +weaveClass(resultsPendingWeave) { + foreach resultPendingWeave + foreach classfile + get corresponding BcelObjectType + weave + update classfile held in result + end + end +} + + +Note on createWorldAndWeaver(classpath) + - we can probably avoid having to turn the Eclipse nameEnvironment + into an externalized classpath by extending + weaver.bcel.ClasspathManager to cope with "third party" managed + classpath entries. On the eclipse side we can implement some + interface and map it back into a call to INameEnvironment.findType - + will need to cast returned IBinaryType into ClassFileReader, this is + the only nasty. Much better than doing classpath nonsense though. + +Note on handling the outjar option: + - this will be addressed by the requestor, if they want the results + to go into an outjar, they can do so when accepting results. It will + also have to be known by the piece of logic that moves resources (but + that is outside of compile anyway). + +Note on handling sourceDirs: + - this is a command-line option only, and is handled by adding all + the source files in the directories to the list of sourceUnits passed + into compile. + +Note on handling aspectpath: + - this is a list of directories and jar files containing class files + to be added to the list of aspects. These class files will be added + to the weaver's list of added aspects at the start of the weave phase + +Note on handling injars, inpath: + - these contain a set of class files that were not generated via + parsing source, but instead are read directly from disk. We build a + dummy CompilationResult in which getClassFiles() returns ClassFile + objects for each of the class files. (Note, may need to define a + ClassFile subclass with that just takes byte[] - this is a horrid + hack but contained, and keeps the rest of the design clean). + +Note on handling -XnoWeave: + - just skip the weave phase! + + +Handling Batch Compiles From Eclipse Using the New Model +======================================================== + +Eclipse is responsible for building the name enviroment and list of +ICompilationUnits to be compiled (does this already today). Eclipse is +also responsible for creating and passing in the desired requestor +(does this already today too). + +We will add a new BcelWorld constructor that takes an +org.aspectj.weaver.IManagedClasspath or similar in place of a +List of String classpath entries. ClasspathManager will be extended to +do the right thing with this, and on the Eclipse side we will +implement the interface backed by an INameEnvironment as discussed in +the notes above. + +The AspectJ specific options (aspectpath etc) are stored in an +extension of IJavaProject, IAspectJProject, and persisted in .ajpath +(analagous to .classpath) in the AspectJ project. + +The AbstractImageBuilder handles resource copying, and we don't need +to change this logic in any way. + +That's all folks! + +Handling Batch Compiles From ajc Using the New Model +==================================================== + +AjBuildManager creates the list of ICompilationUnits to be compiled in +the same way that it does today. + +It could obtain a classpath to give to the weaver from AjBuildConfig +in the same way that it does today - but it might be simpler and more +consistent to pass across an IManagedClasspath built from the +FileSystem (INameEnvironment) built from the classpath - this will +give consistency across inside and outside Eclipse compiles. + +The compiler is constructed with a requestor that writes class files +in CompilationUnitResults out to disk at the output location (or jar +file) in the AjBuildConfig. + +The AspectJ specific options (aspectpath etc) are obtained from +AjBuildConfig as today. + +Resource copying will ideally be handled outside of the weaver (from +source dirs and inpath dirs only) inside AjBuildManager. + +How Incremental Compilation Works in the JDT +============================================ + +Incremental compilation begins in the JavaBuilder with a request to +perform an incremental build. If the classpath of the project has +changed, or a binary project member (jar or .class file) has changed, +it reverts to a full build. + +An IncrementalImageBuilder is then created and asked to build the +deltas since the last build. If this succeeds the new build state is +recorded for the next compile, otherwise we revert to a full build. + +The IncrementalImageBuilder algorithm proceeds as follows: + // initialize builder + // walk this project's deltas, find changed source files + // walk prereq projects' deltas, find changed class files & add + affected source files + // use the build state # to skip the deltas for certain prereq projects + // ignore changed zip/jar files since they caused a full build + // compile the source files & acceptResult() + // compare the produced class files against the existing ones on disk + // recompile all dependent source files of any type with structural + changes or new/removed secondary type + // keep a loop counter to abort & perform a full build (after 5 attempts) + + + +How Incremental Compilation Works in AspectJ 1.1.x +================================================== + +As per batch building, except that: + +* if previous built state (AjState) exists, we do not create a new + bcelWorld (will use existing one). +* create list of source files to compile by looking at all source + files modified since last build date +* delete any class files that resulted from now deleted files, tell + the weaver about them +* extend list of source files to compile with files containing types + that reference types defined in modified source files +* ask the compiler to compile the source files +* find the list of source files that refer to things we changed, if + its non-empty, defer to a batch build (this is like the eclipse + algorithm, but with a loop count of 1). + +now hand-off to weaver... + +* tell the weaver about every class file we wrote +* weaver determines whether or not it needs to reweave everything by + looking at added and deleted classes and searching for aspects + (slight simplification) +* weave proceeds as before, weaving either only the added classes, or + everything, as required. + +How we want Incremental Compilation to proceed in AspectJ 1.2 +============================================================= + +This is harder to get right than batch (surprise). We still want the +same two statements to hold at the end of the compilation of an +individual source file: +1) all the class files have been written out and are ready to be used +2) all errors in any type defined in the file have been reported + +In both cases, the real 'incremental' logic is outside of the Compiler +itself (in IncrementalImageBuilder and in AjBuildManager). In the +current ajc case though, all compilation iterations have completed +before entering a single back-end weave phase. Pushing weaving inside +compile (as outlined in the proposal for batch building) makes this +design harder to accomplish in the new world. We are saved by the fact +that the current AspectJ incremental implementation currently only +supports one go round the loop before bailing out to a full build, and +we can mimic that behaviour easily. + +The logic in AjState that currently updates the weaver with +addedClassFiles as compilation results are produced will have to be +moved into the compiler (adaptor), to occur between the intermediate +class file generation and the weaving phase. + +Incremental AspectJ Compilation in Eclipse +========================================== + +The JavaBuilder (one per project) will be responsible for managing the +bcelWorld and bcelWeaver. These will be passed to the Compiler +(Adaptor) prior to calling compile. The incremental build manager +which processes deltas will be responsible for informing the weaver of +deleted class files. Added class files are determined as compilation +progresses. Weaving will happen inside the compile method, as +described for batch, with the twist that the whole world may be +rewoven if the weaver feels this is necessary. To keep things +initially as close to the current AspectJ implementation as possible, +we will set the maximum loop limit to 1 in the IncrementalImageBuilder +so that we bail out to a full build if we don't compile everything we +need in the first go. With a suitable test suite in place, there's no +conceptual reason why we couldn't put that back up to 5 (the JDT +default) as far as I can see right now. + When performing a whole world weave, the compiler may end up asking +requestors to acceptResult()s that they didn't request to be compiled, +but this is no different to the dependency analysis done on +referencing types that may then get added into subsequent incremental +loops in the JDT today. + +Incremental AspectJ Compilation in ajc +====================================== + +AjBuildManager manages the bcelWorld and weaver as it does today, and +passes them to the compiler adaptor for it to call the weave method +rather than AjBuildManager calling weave directly as it does +today. + + +Note on handling aspectpath: +If the JavaBuilder detects that the aspectpath itself has changed in +any way, it will request a full build. If delta analysis during the +first phase of incremental compilation detects that a jar or class +file in an aspectpath has changed, it will bail out to a full build. + +Note on handling injars, inpath: +We must make sure that the delta analysis allows a project with only +an inpath change to proceed to building (rather than thinking that +there is nothing to do). Any changed jars or class files will have +their classes added to the weaver, and the weaver will be notified of +deletions too. We need to ensure that we still continue on to +compilation even when there are no "source files" in the work queue - +will need some design. + +For tomorrow: start looking at refactoring AspectJ codebase itself to +fit the new shape, ahead of trying to do ImageBuilder integration at +the same time (in AspectJ, I have the test harness to guide me).
\ No newline at end of file |