All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsweet.transpiler.JSweetFactory Maven / Gradle / Ivy

The newest version!
package org.jsweet.transpiler;

import java.lang.reflect.Constructor;
import java.util.List;

import org.apache.log4j.Logger;
import org.jsweet.transpiler.JavaCompilationComponents.JavaCompilerOptions;
import org.jsweet.transpiler.extension.Java2TypeScriptAdapter;
import org.jsweet.transpiler.extension.PrinterAdapter;
import org.jsweet.transpiler.extension.RemoveJavaDependenciesAdapter;

import com.sun.source.tree.CompilationUnitTree;

/**
 * The factory object is the one creating instances for key JSweet transpilation
 * elements. By subclassing the factory, programmers can extend the transpiler
 * behavior.
 * 
 * @author Renaud Pawlak
 *
 */
public class JSweetFactory {

	/**
	 * A logger to be used for internal messages.
	 */
	protected final static Logger logger = Logger.getLogger(JSweetFactory.class);

	/**
	 * An empty constructor is mandatory for all subclasses.
	 */
	public JSweetFactory() {
	}

	/**
	 * Creates the transpiler's context or any subclass.
	 */
	public JSweetContext createContext(JSweetOptions options) {
		return new JSweetContext(options);
	}

	/**
	 * Creates the printer adapter or any subclass.
	 * 
	 * 

* This is the method to be overridden to create composable extensions. Adapters * are chainable (decorator pattern) and new adapters will delegate to parent * adapters when not overriding the parent behavior. * *

* For instance, here my own adapter will override the needed behavior and * delegate to the default adapter chain: * *

	 * @Override
	 * public PrinterAdapter createAdapter(JSweetContext context) {
	 * 	return new MyOwnAdapter(super.createAdapter(context));
	 * }
	 * 
*/ public PrinterAdapter createAdapter(JSweetContext context) { if (context.options.getConfiguration() != null && context.options.getConfiguration().containsKey("adapters")) { // generically creates the adapter chain from the "adapters" // configuration entry logger.info("constructing adapters: " + context.options.getConfiguration().get("adapters")); try { Class adapterClass; PrinterAdapter adapter = null; List adapters = (List) context.options.getConfiguration().get("adapters"); for (int i = adapters.size() - 1; i >= 0; i--) { if (adapters.get(i) instanceof String) { adapterClass = PrinterAdapter.class.getClassLoader().loadClass((String) adapters.get(i)); if (i == adapters.size() - 1) { Constructor constructor = null; try { constructor = adapterClass.getConstructor(JSweetContext.class); } catch (Exception e) { // swallow } if (constructor == null) { logger.debug("constructing default adapter"); adapter = context.isUsingJavaRuntime() ? new Java2TypeScriptAdapter(context) : new RemoveJavaDependenciesAdapter(context); try { constructor = adapterClass.getConstructor(PrinterAdapter.class); } catch (Exception e) { // swallow } if (constructor != null) { adapter = (PrinterAdapter) constructor.newInstance(adapter); } else { throw new RuntimeException("wrong adapter class " + adapterClass.getName() + ": the last adapter must be chainable or be the root adapter (see the PrinterAdapter API)"); } } else { adapter = (PrinterAdapter) constructor.newInstance(context); } } else { Constructor constructor = adapterClass.getConstructor(PrinterAdapter.class); if (constructor == null) { throw new RuntimeException("wrong adapter class " + adapterClass.getName() + ": a chainable adapter must define a constructor accepting a parent adapter"); } else { adapter = (PrinterAdapter) constructor.newInstance(adapter); } } } } return adapter; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } } else { if (context.isUsingJavaRuntime()) { return new Java2TypeScriptAdapter(context); } else { return new RemoveJavaDependenciesAdapter(context); } } } /** * Creates the core translator or any subclass. */ public Java2TypeScriptTranslator createTranslator(PrinterAdapter adapter, TranspilationHandler transpilationHandler, JSweetContext context, CompilationUnitTree compilationUnit, boolean fillSourceMap) { return new Java2TypeScriptTranslator(adapter, transpilationHandler, context, compilationUnit, fillSourceMap); } /** * Creates the scanner which is called before translating the program. * *

* A typical use would be to return a subclass of * {@link GlobalBeforeTranslationScanner} in order to fill the context with some * specific global analysis results that can be used later on by the translator. */ public GlobalBeforeTranslationScanner createBeforeTranslationScanner(TranspilationHandler transpilationHandler, JSweetContext context) { return new GlobalBeforeTranslationScanner(transpilationHandler, context); } /** * Creates a diagnostic handler (responsible for reporting Java * errors/warnings). * *

* One can override with a subclass to tune how JSweet reports Java messages. */ public JSweetDiagnosticHandler createDiagnosticHandler(TranspilationHandler transpilationHandler, JSweetContext context) { return new JSweetDiagnosticHandler(transpilationHandler, context); } public JavaCompilerOptions finalizeJavaCompilerOptions(JavaCompilerOptions options) { return options; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy