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.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).
- 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 inpolyglot.ext.jl5.JL5Scheduler
for more info, as well aspolyglot.translate.JLOutputExtensionInfo
, for more information. - 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 appropriatepolyglot.ext.jl5
classes instead of the base Polyglot versions. For example:- Extend
polyglot.ext.jl5.ExtensionInfo
instead ofpolyglot.frontend.JLExtensionInfo
. - Extend
polyglot.ext.jl5.types.JL5TypeSystem_c
instead ofpolyglot.types.TypeSystem_c
. - Extend
polyglot.ext.jl5.ast.JL5NodeFactory_c
instead ofpolyglot.ast.NodeFactory_c
. - Extend
polyglot.ext.jl5.ast.JL5ExtFactory_c
instead ofpolyglot.ast.AbstractExtFactory_c
. - Etc.
- Extend
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.
- targetFactory() - Signature of TargetFactory constructor → TargetFactory(FileManager fileManager, Location outputLocation, String outExt, boolean so)
- createClassFile() - Signature of the method → createClassFile(FileObject f, byte[] code)
- createFileSource() - Signature of the method → createFileSource(FileObject f, boolean user)
- extFileManager() - You might want to instantiate your own file manager implementation in this method.
- classFileLoader() - You might want to add more locations (for searching .class files) to ClassFileLoader.
- 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.
- 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:
- The constructor signature as mentioned above
- Method outputWriter(String packageName, String className, Source source) throws IOException is deleted.
- outputCodeWriter() - Signature of the method → outputCodeWriter(FileObject f, int width) throws IOException
- 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:
- 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)
- createSerializer() - Signature of the method
→ createSerializer(TypeSystem ts, NodeFactory nf,
long lastModified, ErrorQueue eq, Version version)
- For a class extending polyglot.main.Main, watch out
for the following:
- 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:
- Signature of LoadedClassResolver constructor as mentioned above
- Signature of SourceClassResolver constructor as mentioned above
- For a class extending polyglot.visit.ClassSerializer,
watch out for the following:
- 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 .