So here is the 12-steps plan:
- Get the Javac source, commit these sources to to your source repository and then tag the snapshot. Thus, revision 1.1 of a file will always be the original.
- Reformat all source files according to your preferred coding style.
- Commit to the source repository and tag this snapshot. Thus, revision 1.2 of a file will be the reformatted form of the original. If something stops working, you will be able to easily diff to see what is it that you broke. Note that diffing with revision 1.1 will not be useful - the output will be cluttered with many differences due to the difference in coding styles.
- Compiler entry point. Create a new main class for the compiler, e.g.: MyCompiler. Your new functionality will be activated by having MyCompiler create subclasses of the original compiler modules (see the "Subclassing a module" section in this post).
- Execution entry point. Create a class (e.g.: MyLauncher) that will run your compiled program (a replacement for the "java" program).
Discussion: In its simplest form MyLauncher.main() accepts a command line with a user supplied class path, the name of a main class and a vector of command line arguments. It will first create a new class-loader configured with these two locations (order is important):
- The user supplied class-path
- The class-path with which MyLauncher.main() was invoked: System.getProperty("java.class.path").
The parent of this new class-loader should be the system class loader (that is: ClassLoader.getSystemClassLoader()).
MyLauncher.main() will load the user specified main class from the newly created loader and will start the program by invoking the main() method of that class.
then uses MyLauncher to run test/bin/HelloWorld.class. The test case should capture the output of the program and compare it with the expected output.
That's it. You're now ready to extend the compiler.