Updated Branches: refs/heads/develop 04e19da0b -> d8bb65f1e
MXMLJSC now supports FlexJS output (MXML and AS) A bunch of changes all aimed towards the goal of getting MXML and AS cross compiled to JS by MXMLJSC. Signed-off-by: Erik de Bruin <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/d8bb65f1 Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/d8bb65f1 Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/d8bb65f1 Branch: refs/heads/develop Commit: d8bb65f1ea159f1743c4cd6572dc84ff3719db0d Parents: 04e19da Author: Erik de Bruin <[email protected]> Authored: Wed Mar 27 18:37:22 2013 +0100 Committer: Erik de Bruin <[email protected]> Committed: Wed Mar 27 18:37:22 2013 +0100 ---------------------------------------------------------------------- .../org/apache/flex/compiler/clients/MXMLJSC.java | 43 ++- .../org/apache/flex/compiler/driver/IBackend.java | 3 + .../internal/codegen/js/goog/JSGoogPublisher.java | 12 +- .../codegen/mxml/flexjs/MXMLFlexJSPublisher.java | 204 +++++++++++++++ .../compiler/internal/driver/as/ASBackend.java | 8 + .../compiler/internal/driver/js/JSBackend.java | 8 + .../driver/js/goog/JSGoogConfiguration.java | 14 +- .../driver/mxml/flexjs/MXMLFlexJSBackend.java | 2 +- 8 files changed, 266 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java b/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java index d9bb8c5..216f762 100644 --- a/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java +++ b/compiler.jx/src/org/apache/flex/compiler/clients/MXMLJSC.java @@ -51,6 +51,7 @@ import org.apache.flex.compiler.exceptions.ConfigurationException.OnlyOneSource; import org.apache.flex.compiler.internal.codegen.js.JSPublisher; import org.apache.flex.compiler.internal.codegen.js.JSSharedData; import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogPublisher; +import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSPublisher; import org.apache.flex.compiler.internal.driver.as.ASBackend; import org.apache.flex.compiler.internal.driver.js.amd.AMDBackend; import org.apache.flex.compiler.internal.driver.js.goog.GoogBackend; @@ -333,7 +334,7 @@ public class MXMLJSC File outputFolder = new File(getOutputFilePath()); if (!outputFolder.isDirectory()) outputFolder = outputFolder.getParentFile(); - + // output type specific pre-compile actions switch (jsOutputType) { @@ -344,7 +345,9 @@ public class MXMLJSC } case FLEXJS: { - // jsPublisher = new MXMLFlexJSPublisher(config); + jsPublisher = new MXMLFlexJSPublisher(config); + + outputFolder = jsPublisher.getOutputFolder(); break; } @@ -354,10 +357,6 @@ public class MXMLJSC outputFolder = jsPublisher.getOutputFolder(); - if (outputFolder.exists()) - org.apache.commons.io.FileUtils - .deleteQuietly(outputFolder); - break; } default: { @@ -365,6 +364,9 @@ public class MXMLJSC } } + if (outputFolder.exists()) + org.apache.commons.io.FileUtils.deleteQuietly(outputFolder); + if (!outputFolder.exists()) outputFolder.mkdirs(); @@ -373,8 +375,11 @@ public class MXMLJSC .of(mainCU)); for (final ICompilationUnit cu : reachableCompilationUnits) { - if (cu.getCompilationUnitType() == ICompilationUnit.UnitType.AS_UNIT - || cu.getCompilationUnitType() == ICompilationUnit.UnitType.MXML_UNIT) + ICompilationUnit.UnitType cuType = cu + .getCompilationUnitType(); + + if (cuType == ICompilationUnit.UnitType.AS_UNIT + || cuType == ICompilationUnit.UnitType.MXML_UNIT) { final File outputClassFile = getOutputClassFile(cu .getQualifiedNames().get(0), outputFolder); @@ -383,17 +388,27 @@ public class MXMLJSC .println("Compiling file: " + outputClassFile); ICompilationUnit unit = cu; - IASWriter jswriter = JSSharedData.backend.createWriter( - project, (List<ICompilerProblem>) errors, unit, - false); - // XXX (mschmalle) hack what is CountingOutputStream? + IASWriter writer; + if (cuType == ICompilationUnit.UnitType.AS_UNIT) + { + writer = JSSharedData.backend.createWriter(project, + (List<ICompilerProblem>) errors, unit, + false); + } + else + { + writer = JSSharedData.backend.createMXMLWriter( + project, (List<ICompilerProblem>) errors, + unit, false); + } + BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(outputClassFile)); - jswriter.writeTo(out); + writer.writeTo(out); out.flush(); out.close(); - jswriter.close(); + writer.close(); } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/driver/IBackend.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/driver/IBackend.java b/compiler.jx/src/org/apache/flex/compiler/driver/IBackend.java index e410298..3f12ba5 100644 --- a/compiler.jx/src/org/apache/flex/compiler/driver/IBackend.java +++ b/compiler.jx/src/org/apache/flex/compiler/driver/IBackend.java @@ -93,6 +93,9 @@ public interface IBackend IASWriter createWriter(IASProject project, List<ICompilerProblem> errors, ICompilationUnit compilationUnit, boolean enableDebug); + IASWriter createMXMLWriter(IASProject project, List<ICompilerProblem> errors, + ICompilationUnit compilationUnit, boolean enableDebug); + IASBlockWalker createWalker(IASProject project, List<ICompilerProblem> errors, IASEmitter emitter); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java index 4a37350..3f46334 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java @@ -74,7 +74,7 @@ public class JSGoogPublisher extends JSPublisher implements IJSPublisher final String closureTPTgtLibDirPath = intermediateDirPath + "/library/third_party/closure/goog"; final String vanillaSDKSrcLibDirPath = ((JSGoogConfiguration) configuration) - .getVanillaSDKLib(); + .getSDKJSLib(); final String vanillaSDKTgtLibDirPath = intermediateDirPath + "/VanillaSDK"; @@ -146,7 +146,7 @@ public class JSGoogPublisher extends JSPublisher implements IJSPublisher JSClosureCompilerUtil.run(options); - appendSourceMapLocation(projectReleaseJSFilePath); + appendSourceMapLocation(projectReleaseJSFilePath, projectName); System.out.println("The project '" + projectName + "' has been successfully compiled and optimized."); @@ -166,14 +166,14 @@ public class JSGoogPublisher extends JSPublisher implements IJSPublisher writeFile(path, appendString.toString(), true); } - private void appendSourceMapLocation(String path) throws IOException + protected void appendSourceMapLocation(String path, String projectName) throws IOException { StringBuilder appendString = new StringBuilder(); - appendString.append("\n//@ sourceMappingURL=./Example.js.map"); + appendString.append("\n//@ sourceMappingURL=./" + projectName + ".js.map"); writeFile(path, appendString.toString(), true); } - private void copyFile(String srcPath, String tgtPath) throws IOException + protected void copyFile(String srcPath, String tgtPath) throws IOException { File srcFile = new File(srcPath); if (srcFile.isDirectory()) @@ -224,7 +224,7 @@ public class JSGoogPublisher extends JSPublisher implements IJSPublisher false); } - private void writeFile(String path, String content, boolean append) + protected void writeFile(String path, String content, boolean append) throws IOException { File tgtFile = new File(path); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java new file mode 100644 index 0000000..49832a3 --- /dev/null +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java @@ -0,0 +1,204 @@ +package org.apache.flex.compiler.internal.codegen.mxml.flexjs; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.filefilter.DirectoryFileFilter; +import org.apache.commons.io.filefilter.RegexFileFilter; +import org.apache.flex.compiler.codegen.js.IJSPublisher; +import org.apache.flex.compiler.config.Configuration; +import org.apache.flex.compiler.internal.codegen.js.JSSharedData; +import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogPublisher; +import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration; +import org.apache.flex.compiler.utils.JSClosureCompilerUtil; + +import com.google.javascript.jscomp.ErrorManager; +import com.google.javascript.jscomp.SourceFile; +import com.google.javascript.jscomp.SourceMap; +import com.google.javascript.jscomp.deps.DepsGenerator; +import com.google.javascript.jscomp.deps.DepsGenerator.InclusionStrategy; + +public class MXMLFlexJSPublisher extends JSGoogPublisher implements + IJSPublisher +{ + + public static final String FLEXJS_INTERMEDIATE_DIR_NAME = "bin/js-debug"; + public static final String FLEXJS_RELEASE_DIR_NAME = "bin/js-release"; + + private File outputFolder; + + public MXMLFlexJSPublisher(Configuration config) + { + super(config); + + this.outputFolder = new File(configuration.getTargetFileDirectory()) + .getParentFile(); + } + + public File getOutputFolder() + { + return new File(outputFolder, FLEXJS_INTERMEDIATE_DIR_NAME); + } + + public void publish() throws IOException + { + final String intermediateDirPath = getOutputFolder().getPath(); + + final String projectName = FilenameUtils.getBaseName(configuration + .getTargetFile()); + final String outputFileName = projectName + + "." + JSSharedData.OUTPUT_EXTENSION; + + File releaseDir = new File(outputFolder, FLEXJS_RELEASE_DIR_NAME); + final String releaseDirPath = releaseDir.getPath(); + if (releaseDir.exists()) + org.apache.commons.io.FileUtils.deleteQuietly(releaseDir); + releaseDir.mkdirs(); + + final String closureLibDirPath = ((JSGoogConfiguration) configuration) + .getClosureLib(); + final String closureGoogSrcLibDirPath = closureLibDirPath + + "/closure/goog/"; + final String closureGoogTgtLibDirPath = intermediateDirPath + + "/library/closure/goog"; + final String closureTPSrcLibDirPath = closureLibDirPath + + "/third_party/closure/goog/"; + final String closureTPTgtLibDirPath = intermediateDirPath + + "/library/third_party/closure/goog"; + final String sdkJSLibSrcDirPath = ((JSGoogConfiguration) configuration) + .getSDKJSLib(); + final String sdkJSLibTgtDirPath = intermediateDirPath; + + final String depsSrcFilePath = intermediateDirPath + + "/library/closure/goog/deps.js"; + final String depsTgtFilePath = intermediateDirPath + "/deps.js"; + final String projectIntermediateJSFilePath = intermediateDirPath + + File.separator + outputFileName; + final String projectReleaseJSFilePath = releaseDirPath + + File.separator + outputFileName; + + appendExportSymbol(projectIntermediateJSFilePath, projectName); + + copyFile(sdkJSLibSrcDirPath, sdkJSLibTgtDirPath); + + List<SourceFile> inputs = new ArrayList<SourceFile>(); + Collection<File> files = org.apache.commons.io.FileUtils.listFiles( + new File(intermediateDirPath), + new RegexFileFilter("^.*(\\.js)"), + DirectoryFileFilter.DIRECTORY); + for (File file : files) + { + inputs.add(SourceFile.fromFile(file)); + } + + copyFile(closureGoogSrcLibDirPath, closureGoogTgtLibDirPath); + copyFile(closureTPSrcLibDirPath, closureTPTgtLibDirPath); + + File srcDeps = new File(depsSrcFilePath); + + final List<SourceFile> deps = new ArrayList<SourceFile>(); + deps.add(SourceFile.fromFile(srcDeps)); + + ErrorManager errorManager = new JSGoogErrorManager(); + DepsGenerator depsGenerator = new DepsGenerator(deps, inputs, + InclusionStrategy.ALWAYS, closureGoogTgtLibDirPath, + errorManager); + writeFile(depsTgtFilePath, depsGenerator.computeDependencyCalls(), + false); + + org.apache.commons.io.FileUtils.deleteQuietly(srcDeps); + org.apache.commons.io.FileUtils.moveFile(new File(depsTgtFilePath), + srcDeps); + + writeHTML("intermediate", projectName, intermediateDirPath); + writeHTML("release", projectName, releaseDirPath); + + ArrayList<String> optionList = new ArrayList<String>(); + + files = org.apache.commons.io.FileUtils.listFiles(new File( + intermediateDirPath), new RegexFileFilter("^.*(\\.js)"), + DirectoryFileFilter.DIRECTORY); + for (File file : files) + { + optionList.add("--js=" + file.getCanonicalPath()); + } + + optionList.add("--closure_entry_point=" + projectName); + optionList.add("--only_closure_dependencies"); + optionList.add("--compilation_level=ADVANCED_OPTIMIZATIONS"); + optionList.add("--js_output_file=" + projectReleaseJSFilePath); + optionList.add("--output_manifest=" + + releaseDirPath + File.separator + "manifest.txt"); + optionList.add("--create_source_map=" + + projectReleaseJSFilePath + ".map"); + optionList.add("--source_map_format=" + SourceMap.Format.V3); + + String[] options = (String[]) optionList.toArray(new String[0]); + + JSClosureCompilerUtil.run(options); + + appendSourceMapLocation(projectReleaseJSFilePath, projectName); + + System.out.println("The project '" + + projectName + + "' has been successfully compiled and optimized."); + } + + private void appendExportSymbol(String path, String projectName) + throws IOException + { + StringBuilder appendString = new StringBuilder(); + appendString + .append("\n\n// Ensures the symbol will be visible after compiler renaming.\n"); + appendString.append("goog.exportSymbol('"); + appendString.append(projectName); + appendString.append("', "); + appendString.append(projectName); + appendString.append(");\n"); + writeFile(path, appendString.toString(), true); + } + + private void writeHTML(String type, String projectName, String dirPath) + throws IOException + { + StringBuilder htmlFile = new StringBuilder(); + htmlFile.append("<!DOCTYPE html>\n"); + htmlFile.append("<html>\n"); + htmlFile.append("<head>\n"); + htmlFile.append("\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n"); + htmlFile.append("\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"); + + if (type == "intermediate") + { + htmlFile.append("\t<script type=\"text/javascript\" src=\"./library/closure/goog/base.js\"></script>\n"); + htmlFile.append("\t<script type=\"text/javascript\">\n"); + htmlFile.append("\t\tgoog.require(\""); + htmlFile.append(projectName); + htmlFile.append("\");\n"); + htmlFile.append("\t</script>\n"); + } + else + { + htmlFile.append("\t<script type=\"text/javascript\" src=\"./"); + htmlFile.append(projectName); + htmlFile.append(".js\"></script>\n"); + } + + htmlFile.append("</head>\n"); + htmlFile.append("<body>\n"); + htmlFile.append("\t<script type=\"text/javascript\">\n"); + htmlFile.append("\t\tnew "); + htmlFile.append(projectName); + htmlFile.append("();\n"); + htmlFile.append("\t</script>\n"); + htmlFile.append("</body>\n"); + htmlFile.append("</html>"); + + writeFile(dirPath + File.separator + "index.html", htmlFile.toString(), + false); + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/internal/driver/as/ASBackend.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/as/ASBackend.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/as/ASBackend.java index b25d0c4..485fa82 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/driver/as/ASBackend.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/as/ASBackend.java @@ -135,6 +135,14 @@ public class ASBackend implements IBackend } @Override + public IASWriter createMXMLWriter(IASProject project, + List<ICompilerProblem> problems, ICompilationUnit compilationUnit, + boolean enableDebug) + { + return null; + } + + @Override public IDocEmitter createDocEmitter(IASEmitter emitter) { return null; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java index 0a2b9b2..56d64bb 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/JSBackend.java @@ -126,6 +126,14 @@ public class JSBackend implements IBackend } @Override + public IJSWriter createMXMLWriter(IASProject project, + List<ICompilerProblem> problems, ICompilationUnit compilationUnit, + boolean enableDebug) + { + return null; + } + + @Override public IDocEmitter createDocEmitter(IASEmitter emitter) { return new JSDocEmitter((IJSEmitter) emitter); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java index 2f90f71..eea0637 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java @@ -63,22 +63,22 @@ public class JSGoogConfiguration extends JSConfiguration } // - // 'vanilla-sdk-lib' + // 'sdk-js-lib' // - private String vanillaSDKLib; + private String sdkJSLib; - public String getVanillaSDKLib() + public String getSDKJSLib() { - return vanillaSDKLib; + return sdkJSLib; } @Config - @Mapping("vanilla-sdk-lib") - public void setVanillaSDKLib(ConfigurationValue cv, String value) + @Mapping("sdk-js-lib") + public void setSDKJSLib(ConfigurationValue cv, String value) throws ConfigurationException { - vanillaSDKLib = value; + sdkJSLib = value; } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/d8bb65f1/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java b/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java index 4233931..cdb9845 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSBackend.java @@ -101,7 +101,7 @@ public class MXMLFlexJSBackend extends MXMLBackend } @Override - public IJSWriter createWriter(IASProject project, + public IJSWriter createMXMLWriter(IASProject project, List<ICompilerProblem> problems, ICompilationUnit compilationUnit, boolean enableDebug) {
