## Polyglot 2.5 Porting Guide

Some Polyglot extensions may need minor changes to work with the new version of Polyglot. This document is intended to help developers fix their extensions accordingly.

### JL5 extension

Polyglot 2.5 supoprts Java 1.5 language features, via the JL5 extension (package `polyglot.ext.jl5`). There are two options to implement a Polyglot extension that supports Java 1.5 language features (whether porting an existing extension, or writing a new one).

1. Translate to Java 1.4.

   The JL5 extension can be used to translate from Java 1.5 language features to equivalent Java 1.4 code. Extension writers can leverage this to provide support for Java 1.5 langauge features without needing to directly reason about such features in their extensions.

   The easiest way to write an extension that first translates Java 1.5 code to Java 1.4 code is to use the ExtensionRewriter pattern. This pattern rewrites Java 1.5 AST nodes to the extension's AST nodes. An example of this pattern is used by the JL5 extension to output Java 1.4 files. The JL5 AST is translated to JL ASTs, typechecked as Java 1.4, and then output to disk. See the `RemoveJava5isms` goal in `polyglot.ext.jl5.JL5Scheduler` for more info, as well as `polyglot.translate.JLOutputExtensionInfo`, for more information.

2. Directly support Java 1.5.

   The JL5 extension can be directly extended, allowing extensions to directly support Java 1.5 langauge features such as generics, enhanced for loops, enums, and annotations.

   To extend the JL5 extension, simply extend the appropriate `polyglot.ext.jl5` classes instead of the base Polyglot versions. For example:
   - Extend `polyglot.ext.jl5.ExtensionInfo` instead of `polyglot.frontend.JLExtensionInfo`.
   - Extend `polyglot.ext.jl5.types.JL5TypeSystem_c` instead of `polyglot.types.TypeSystem_c`.
   - Extend `polyglot.ext.jl5.ast.JL5NodeFactory_c` instead of `polyglot.ast.NodeFactory_c`.
   - Extend `polyglot.ext.jl5.ast.JL5ExtFactory_c` instead of `polyglot.ast.AbstractExtFactory_c`.
   - Etc.

### File manager

The new Polyglot uses a file manager as a source and class file loader. For the extensions built on the old Polyglot (directly or indirectly) to be compatible with this new version, developers should look at the design changes made in Polyglot and consider the following issues:

- For a class extending `polyglot.frontend.AbstractExtensionInfo`, `ParserlessJLExtensionInfo` or `JLExtensionInfo`, watch out for the following methods. If the extension overrides any of these methods, they will need to be changed to use a different type signature.
  1. `targetFactory()` - Signature of TargetFactory constructor → `TargetFactory(FileManager fileManager, Location outputLocation, String outExt, boolean so)`
  2. `createClassFile()` - Signature of the method → `createClassFile(FileObject f, byte[] code)`
  3. `createFileSource()` - Signature of the method → `createFileSource(FileObject f, boolean user)`
  4. `extFileManager()` - You might want to instantiate your own file manager implementation in this method.
  5. `classFileLoader()` - You might want to add more locations (for searching `.class` files) to `ClassFileLoader`.
  6. `addLocationsToFileManager()` - You might want to set locations other than standard ones (as in source_output, class_output, bootclasspath, classpath and sourcepath) to your file manager.When you override this method, don't forget to call this method on the output ExtensionInfo instance.
  7. `initTypeSystem()` / `makeLoadedClassResolver()` - Signature of SourceClassResolver constructor → `SourceClassResolver(Compiler compiler, ExtensionInfo ext, boolean allowRawClasses, boolean compileCommandLineOnly, boolean ignoreModTimes)` and LoadedClassResolver constructor → `LoadedClassResolver(ExtensionInfo extInfo, boolean allowRawClasses)`
- In a class `polyglot.frontend.Compiler`, the reference variable `outputFiles` is now `Collection<JavaFileObject>` (instead of Collection of raw types). So you might want to change the way your extension collects the output files (`.java` files).
- For a class extending `polyglot.frontend.TargetFactory`, watch out for the following:
  1. The constructor signature as mentioned above
  2. Method `outputWriter(String packageName, String className, Source source) throws IOException` is deleted.
  3. `outputCodeWriter()` - Signature of the method → `outputCodeWriter(FileObject f, int width) throws IOException`
  4. Methods `File outputFile(String packageName, Source source)` and `File outputFile(String packageName, String className, Source source)` are replaced by `JavaFileObject outputFileObject(String packageName, Source source)` and `JavaFileObject outputFileObject(String packageName, String className, Source source)` respectively.
- For a class extending `polyglot.frontend.goals.Serialized`, watch out for the following:
  1. `createSerializer()` - Signature of the method → `createSerializer(TypeSystem ts, NodeFactory nf, long lastModified, ErrorQueue eq, Version version)`
     (NOTE: Wherever applicable, use `getLastModified()` method of `Source` type to have `long` instead of `Date`)
- For a class extending `polyglot.main.Main`, watch out for the following:
  1. If you override `start(String[] argv, ExtensionInfo ext, ErrorQueue eq) throws TerminationException`, call `addLocationsToFileManager()` method of `polyglot.frontend.ExtensionInfo` immediately after parsing command-line options.
- For a class extending `polyglot.types.LoadedClassResolver` or `SourceClassResolver`, watch out for the following:
  1. Signature of LoadedClassResolver constructor as mentioned above
  2. Signature of SourceClassResolver constructor as mentioned above
- For a class extending `polyglot.visit.ClassSerializer`, watch out for the following:
  1. Signature of ClassSerializer constructor → `ClassSerializer(TypeSystem ts, NodeFactory nf, long time, ErrorQueue eq, Version ver)`

General instructions: In any extension, any source file rewriter that needs an object to hold the translated Java code must call the `getJavaFileForOutput()` method on the `FileManager` instance of the `OutputExtensionInfo` to have a `javax.tools.JavaFileObject` object and use this object to create a `polyglot.frontend.Source` object by calling the `createFileSource()` method of the `OutputExtensionInfo` .