package org.dynjs.runtime; import org.dynjs.Config; import org.dynjs.compiler.CompilationContext; import org.dynjs.compiler.DefaultCompilationContext; import org.dynjs.compiler.JSCompiler; import org.dynjs.debugger.Debugger; import org.dynjs.ir.Builder; import org.dynjs.parser.ast.ProgramTree; import org.dynjs.parser.js.JavascriptParser; import org.dynjs.parser.js.ParserException; import org.dynjs.runtime.source.FileSourceProvider; import org.dynjs.runtime.source.StringSourceProvider; import java.io.*; /** * @author Bob McWhirter */ public class Compiler { private final Config config; private CompilationContext compilationContext; private SourceProvider sourceProvider; private String fileName; private boolean forceStrict; public Compiler() { this.config = new Config(); } public Compiler(Config config) { this.config = config; } public Compiler withContext(ExecutionContext context) { this.compilationContext = context; return this; } public Compiler forceStrict() { return forceStrict(true); } public Compiler forceStrict(boolean forceStrict) { this.forceStrict = forceStrict; return this; } public Compiler withSource(String source) { this.sourceProvider = new StringSourceProvider(source); return this; } public Compiler withSource(SourceProvider source) { this.sourceProvider = source; return this; } public Compiler withSource(File source) throws IOException { this.sourceProvider = new FileSourceProvider(source); return this; } public Compiler withFileName(String fileName) { this.fileName = fileName; return this; } public JSProgram compile() throws IOException { JSProgram program = compile(parse()); return program; } public ProgramTree parse() throws IOException { JavascriptParser parser = new JavascriptParser(compilationContext()); Reader source = null; try { if ( this.fileName != null ) { this.sourceProvider.setName( this.fileName ); } else { this.fileName = this.sourceProvider.getName(); } source = this.sourceProvider.openReader(); ProgramTree tree = parser.parse(source, this.fileName, this.forceStrict); tree.setSource( this.sourceProvider ); this.fileName = null; return tree; } finally { if (source != null) { source.close(); } } } protected CompilationContext compilationContext() { if (this.compilationContext == null) { this.compilationContext = new DefaultCompilationContext(this.config); } if (this.compilationContext.getBlockManager() == null) { this.compilationContext = new DefaultCompilationContext(this.compilationContext); } return this.compilationContext; } protected JSProgram compile(ProgramTree tree) { // FIXME: getCompiler will go away so just add special IR check for now. final Config.CompileMode compileMode = compilationContext().getConfig().getCompileMode(); if (compileMode == Config.CompileMode.IR) { return Builder.compile(compilationContext(), tree); } JSCompiler compiler = compilationContext().getCompiler(); return compiler.compileProgram(compilationContext(), tree, this.forceStrict); } }