saw it compile for SWF and FlexJS. Needs MXMLFlexJSPublisher fix from develop branch
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/6fced513 Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/6fced513 Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/6fced513 Branch: refs/heads/dual Commit: 6fced513f6268dde43b4a7d1789e7cc45bf59137 Parents: a89c2d7 Author: Alex Harui <[email protected]> Authored: Fri Jan 27 08:48:25 2017 -0800 Committer: Alex Harui <[email protected]> Committed: Fri Jan 27 08:48:25 2017 -0800 ---------------------------------------------------------------------- .../apache/flex/compiler/clients/ASDOCJSC.java | 1 - .../apache/flex/compiler/clients/COMPJSC.java | 165 ++++- .../flex/compiler/clients/COMPJSCFlex.java | 528 +++++++++++++ .../flex/compiler/clients/COMPJSCNative.java | 529 +++++++++++++ .../flex/compiler/clients/FlexJSToolGroup.java | 4 +- .../flex/compiler/clients/JSConfiguration.java | 41 +- .../apache/flex/compiler/clients/MXMLJSC.java | 173 +++-- .../flex/compiler/clients/MXMLJSCFlex.java | 742 +++++++++++++++++++ .../flex/compiler/clients/MXMLJSCNative.java | 741 ++++++++++++++++++ .../flex/compiler/clients/MXMLJSCNode.java | 739 ++++++++++++++++++ .../codegen/js/goog/JSGoogPublisher.java | 8 +- .../mxml/flexjs/TestFlexJSMXMLApplication.java | 24 + .../org/apache/flex/utils/EnvProperties.java | 8 + .../resources/flexjs/files/CSSTestSource.css | 6 + .../flexjs/files/CSSTestSource_result.css | 10 + .../resources/flexjs/files/MyInitialView.mxml | 4 +- 16 files changed, 3609 insertions(+), 114 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6fced513/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ASDOCJSC.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ASDOCJSC.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ASDOCJSC.java index a74c7d8..2c8660f 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ASDOCJSC.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/ASDOCJSC.java @@ -160,7 +160,6 @@ public class ASDOCJSC extends MXMLJSC public ASDOCJSC(IBackend backend) { - super(backend); project = new FlexJSASDocProject(workspace, backend); } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6fced513/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSC.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSC.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSC.java index b208351..0eba441 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSC.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSC.java @@ -38,6 +38,10 @@ import java.util.zip.ZipOutputStream; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; +import org.apache.flex.compiler.clients.MXMLJSC.ExitCode; +import org.apache.flex.compiler.clients.MXMLJSC.JSTargetType; +import org.apache.flex.compiler.clients.problems.ProblemPrinter; +import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter; import org.apache.flex.compiler.codegen.as.IASWriter; import org.apache.flex.compiler.driver.IBackend; import org.apache.flex.compiler.driver.js.IJSApplication; @@ -57,10 +61,12 @@ import org.apache.flex.compiler.problems.ICompilerProblem; import org.apache.flex.compiler.problems.InternalCompilerProblem; import org.apache.flex.compiler.problems.LibraryNotFoundProblem; import org.apache.flex.compiler.problems.UnableToBuildSWFProblem; +import org.apache.flex.compiler.problems.UnexpectedExceptionProblem; import org.apache.flex.compiler.targets.ITarget.TargetType; import org.apache.flex.compiler.targets.ITargetSettings; import org.apache.flex.compiler.units.ICompilationUnit; import org.apache.flex.swc.io.SWCReader; +import org.apache.flex.utils.ArgumentUtil; /** * @author Erik de Bruin @@ -120,51 +126,148 @@ public class COMPJSC extends MXMLJSC { long startTime = System.nanoTime(); - IBackend backend = new ASBackend(); - for (String s : args) + final COMPJSC mxmlc = new COMPJSC(); + final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(); + final int exitCode = mxmlc.mainNoExit(args, problems, true); + + long endTime = System.nanoTime(); + System.out.println((endTime - startTime) / 1e9 + " seconds"); + + return exitCode; + } + + @Override + public int mainNoExit(final String[] args, List<ICompilerProblem> problems, + Boolean printProblems) + { + int exitCode = -1; + try { - if (s.contains("-js-output-type")) + exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems); + } + catch (Exception e) + { + System.err.println(e.toString()); + } + finally + { + if (problems != null && !problems.isEmpty()) { - jsOutputType = JSOutputType.fromString(s.split("=")[1]); - - switch (jsOutputType) + if (printProblems) { - case AMD: - backend = new AMDBackend(); - break; + final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter( + workspace); + final ProblemPrinter printer = new ProblemPrinter(formatter); + printer.printProblems(problems); + } + } + } + return exitCode; + } - case JSC: - backend = new MXMLJSCJSSWCBackend(); - break; + /** + * Entry point that doesn't call <code>System.exit()</code>. This is for + * unit testing. + * + * @param args command line arguments + * @return exit code + */ + private int _mainNoExit(final String[] args, + List<ICompilerProblem> outProblems) + { + ExitCode exitCode = ExitCode.SUCCESS; + try + { + final boolean continueCompilation = configure(args); - case FLEXJS: - case FLEXJS_DUAL: - backend = new MXMLFlexJSSWCBackend(); - break; +/* if (outProblems != null && !config.isVerbose()) + JSSharedData.STDOUT = JSSharedData.STDERR = null;*/ - case GOOG: - backend = new GoogBackend(); - break; + if (continueCompilation) + { - default: - throw new UnsupportedOperationException(); + targetloop: + for (String target : config.getCompilerTargets()) + { + int result = 0; + switch (JSTargetType.fromString(target)) + { + case SWF: + COMPC compc = new COMPC(); + result = compc.mainNoExit(args); + if (result != 0) + { + problems.addAll(compc.problems.getProblems()); + break targetloop; + } + break; + case JS_FLEX: + COMPJSCFlex flex = new COMPJSCFlex(); + result = flex.mainNoExit(args, problems.getProblems(), false); + if (result != 0) + { + break targetloop; + } + break; + case JS_NATIVE: + COMPJSCNative jsc = new COMPJSCNative(); + result = jsc.mainNoExit(args, problems.getProblems(), false); + if (result != 0) + { + break targetloop; + } + break; + // if you add a new js-output-type here, don't forget to also add it + // to flex2.tools.MxmlJSC in flex-compiler-oem for IDE support + } + } + if (problems.hasFilteredProblems()) + { + if (problems.hasErrors()) + exitCode = ExitCode.FAILED_WITH_EXCEPTIONS; + else + exitCode = ExitCode.FAILED_WITH_PROBLEMS; } } + else if (problems.hasFilteredProblems()) + { + exitCode = ExitCode.FAILED_WITH_CONFIG_PROBLEMS; + } + else + { + exitCode = ExitCode.PRINT_HELP; + } } + catch (Exception e) + { + if (outProblems == null) { + System.err.println(e.getMessage()); + } else + { + final ICompilerProblem unexpectedExceptionProblem = new UnexpectedExceptionProblem( + e); + problems.add(unexpectedExceptionProblem); + } + exitCode = ExitCode.FAILED_WITH_EXCEPTIONS; + } + finally + { + waitAndClose(); - final COMPJSC mxmlc = new COMPJSC(backend); - final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(); - final int exitCode = mxmlc.mainNoExit(args, problems, true); - - long endTime = System.nanoTime(); - System.out.println((endTime - startTime) / 1e9 + " seconds"); - - return exitCode; + if (outProblems != null && problems.hasFilteredProblems()) + { + for (ICompilerProblem problem : problems.getFilteredProblems()) + { + outProblems.add(problem); + } + } + } + return exitCode.code; } - public COMPJSC(IBackend backend) + public COMPJSC() { - super(backend); + super(); } /** http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6fced513/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCFlex.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCFlex.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCFlex.java new file mode 100644 index 0000000..dead1c3 --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCFlex.java @@ -0,0 +1,528 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.compiler.clients; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.List; +import java.util.Set; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.flex.compiler.clients.problems.ProblemQuery; +import org.apache.flex.compiler.codegen.as.IASWriter; +import org.apache.flex.compiler.driver.IBackend; +import org.apache.flex.compiler.driver.js.IJSApplication; +import org.apache.flex.compiler.exceptions.ConfigurationException; +import org.apache.flex.compiler.exceptions.ConfigurationException.IOError; +import org.apache.flex.compiler.exceptions.ConfigurationException.MustSpecifyTarget; +import org.apache.flex.compiler.internal.codegen.js.JSWriter; +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; +import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSSWCBackend; +import org.apache.flex.compiler.internal.driver.mxml.jsc.MXMLJSCJSSWCBackend; +import org.apache.flex.compiler.internal.parsing.as.FlexJSASDocDelegate; +import org.apache.flex.compiler.internal.projects.CompilerProject; +import org.apache.flex.compiler.internal.projects.FlexJSProject; +import org.apache.flex.compiler.internal.targets.FlexJSSWCTarget; +import org.apache.flex.compiler.internal.targets.JSTarget; +import org.apache.flex.compiler.internal.workspaces.Workspace; +import org.apache.flex.compiler.problems.ICompilerProblem; +import org.apache.flex.compiler.problems.InternalCompilerProblem; +import org.apache.flex.compiler.problems.LibraryNotFoundProblem; +import org.apache.flex.compiler.problems.UnableToBuildSWFProblem; +import org.apache.flex.compiler.targets.ITarget.TargetType; +import org.apache.flex.compiler.targets.ITargetSettings; +import org.apache.flex.compiler.units.ICompilationUnit; +import org.apache.flex.swc.io.SWCReader; + +/** + * @author Erik de Bruin + * @author Michael Schmalle + */ +public class COMPJSCFlex extends MXMLJSC +{ + /* + * Exit code enumerations. + */ + static enum ExitCode + { + SUCCESS(0), + PRINT_HELP(1), + FAILED_WITH_PROBLEMS(2), + FAILED_WITH_EXCEPTIONS(3), + FAILED_WITH_CONFIG_PROBLEMS(4); + + ExitCode(int code) + { + this.code = code; + } + + final int code; + } + + @Override + public String getName() + { + return FLEX_TOOL_COMPC; + } + + @Override + public int execute(String[] args) + { + return staticMainNoExit(args); + } + + /** + * Java program entry point. + * + * @param args command line arguments + */ + public static void main(final String[] args) + { + int exitCode = staticMainNoExit(args); + System.exit(exitCode); + } + + /** + * Entry point for the {@code <compc>} Ant task. + * + * @param args Command line arguments. + * @return An exit code. + */ + public static int staticMainNoExit(final String[] args) + { + long startTime = System.nanoTime(); + + final COMPJSCFlex mxmlc = new COMPJSCFlex(); + final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(); + final int exitCode = mxmlc.mainNoExit(args, problems, true); + + long endTime = System.nanoTime(); + System.out.println((endTime - startTime) / 1e9 + " seconds"); + + return exitCode; + } + + public COMPJSCFlex() + { + IBackend backend = new MXMLFlexJSSWCBackend(); + + workspace = new Workspace(); + workspace.setASDocDelegate(new FlexJSASDocDelegate()); + project = new FlexJSProject(workspace, backend); + problems = new ProblemQuery(); // this gets replaced in configure(). Do we need it here? + asFileHandler = backend.getSourceFileHandlerInstance(); + } + + /** + * Main body of this program. This method is called from the public static + * method's for this program. + * + * @return true if compiler succeeds + * @throws IOException + * @throws InterruptedException + */ + @Override + protected boolean compile() + { + boolean compilationSuccess = false; + + try + { + project.getSourceCompilationUnitFactory().addHandler(asFileHandler); + + if (setupTargetFile()) + buildArtifact(); + + if (jsTarget != null) + { + Collection<ICompilerProblem> errors = new ArrayList<ICompilerProblem>(); + Collection<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>(); + + if (!config.getCreateTargetWithErrors()) + { + problems.getErrorsAndWarnings(errors, warnings); + if (errors.size() > 0) + return false; + } + + boolean packingSWC = false; + String outputFolderName = getOutputFilePath(); + File swcFile = new File(outputFolderName); + File jsOut = new File("js/out"); + File externsOut = new File("externs"); + ZipFile zipFile = null; + ZipOutputStream zipOutputStream = null; + String catalog = null; + StringBuilder fileList = new StringBuilder(); + if (outputFolderName.endsWith(".swc")) + { + packingSWC = true; + if (!swcFile.exists()) + { + problems.add(new LibraryNotFoundProblem(outputFolderName)); + return false; + } + zipFile = new ZipFile(swcFile, ZipFile.OPEN_READ); + final InputStream catalogInputStream = SWCReader.getInputStream(zipFile, SWCReader.CATALOG_XML); + + catalog = IOUtils.toString(catalogInputStream); + catalogInputStream.close(); + zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outputFolderName + ".new"))); + zipOutputStream.setLevel(Deflater.NO_COMPRESSION); + for (final Enumeration<? extends ZipEntry> entryEnum = zipFile.entries(); entryEnum.hasMoreElements();) + { + final ZipEntry entry = entryEnum.nextElement(); + if (!entry.getName().contains("js/out") && + !entry.getName().contains(SWCReader.CATALOG_XML)) + { + System.out.println("Copy " + entry.getName()); + InputStream input = zipFile.getInputStream(entry); + zipOutputStream.putNextEntry(new ZipEntry(entry.getName())); + IOUtils.copy(input, zipOutputStream); + zipOutputStream.flush(); + zipOutputStream.closeEntry(); + } + } + int filesIndex = catalog.indexOf("<files>"); + if (filesIndex != -1) + { + int filesIndex2 = catalog.indexOf("</files>"); + String files = catalog.substring(filesIndex, filesIndex2); + int fileIndex = files.indexOf("<file", 6); + int pathIndex = files.indexOf("path="); + while (pathIndex != -1) + { + int pathIndex2 = files.indexOf("\"", pathIndex + 6); + int fileIndex2 = files.indexOf("/>", fileIndex); + String path = files.substring(pathIndex + 6, pathIndex2); + if (!path.startsWith("js/out")) + { + fileList.append(files.substring(fileIndex - 8, fileIndex2 + 3)); + } + pathIndex = files.indexOf("path=", pathIndex2); + fileIndex = files.indexOf("<file", fileIndex2); + } + catalog = catalog.substring(0, filesIndex) + catalog.substring(filesIndex2 + 8); + } + } + + File outputFolder = null; + if (!packingSWC) + outputFolder = new File(outputFolderName); + + Set<String> externs = config.getExterns(); + Collection<ICompilationUnit> roots = ((FlexJSSWCTarget)target).getReachableCompilationUnits(errors); + Collection<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots); + for (final ICompilationUnit cu : reachableCompilationUnits) + { + ICompilationUnit.UnitType cuType = cu.getCompilationUnitType(); + + if (cuType == ICompilationUnit.UnitType.AS_UNIT + || cuType == ICompilationUnit.UnitType.MXML_UNIT) + { + String symbol = cu.getQualifiedNames().get(0); + if (externs.contains(symbol)) continue; + + if (project.isExternalLinkage(cu)) continue; + + if (!packingSWC) + { + final File outputClassFile = getOutputClassFile( + cu.getQualifiedNames().get(0), outputFolder); + + System.out.println("Compiling file: " + outputClassFile); + + ICompilationUnit unit = cu; + + IASWriter writer; + if (cuType == ICompilationUnit.UnitType.AS_UNIT) + { + writer = project.getBackend().createWriter(project, + (List<ICompilerProblem>) errors, unit, + false); + } + else + { + writer = project.getBackend().createMXMLWriter( + project, (List<ICompilerProblem>) errors, + unit, false); + } + problems.addAll(errors); + BufferedOutputStream out = new BufferedOutputStream( + new FileOutputStream(outputClassFile)); + writer.writeTo(out); + out.flush(); + out.close(); + writer.close(); + } + else + { + System.out.println("Compiling file: " + cu.getQualifiedNames().get(0)); + + ICompilationUnit unit = cu; + + IASWriter writer; + if (cuType == ICompilationUnit.UnitType.AS_UNIT) + { + writer = project.getBackend().createWriter(project, + (List<ICompilerProblem>) errors, unit, + false); + } + else + { + writer = project.getBackend().createMXMLWriter( + project, (List<ICompilerProblem>) errors, + unit, false); + } + problems.addAll(errors); + ByteArrayOutputStream temp = new ByteArrayOutputStream(); + writer.writeTo(temp); + boolean isExterns = false; + if (writer instanceof JSWriter) + isExterns = ((JSWriter)writer).isExterns(); + String outputClassFile = getOutputClassFile( + cu.getQualifiedNames().get(0), isExterns ? externsOut : jsOut).getPath(); + System.out.println("Writing file: " + outputClassFile); + zipOutputStream.putNextEntry(new ZipEntry(outputClassFile)); + temp.writeTo(zipOutputStream); + zipOutputStream.flush(); + zipOutputStream.closeEntry(); + writer.close(); + fileList.append(" <file path=\"" + outputClassFile + "\" mod=\"" + System.currentTimeMillis() + "\"/>\n"); + } + } + } + if (packingSWC) + { + zipFile.close(); + int libraryIndex = catalog.indexOf("</libraries>"); + catalog = catalog.substring(0, libraryIndex + 13) + + " <files>\n" + fileList.toString() + " </files>" + + catalog.substring(libraryIndex + 13); + zipOutputStream.putNextEntry(new ZipEntry(SWCReader.CATALOG_XML)); + zipOutputStream.write(catalog.getBytes()); + zipOutputStream.flush(); + zipOutputStream.closeEntry(); + zipOutputStream.flush(); + zipOutputStream.close(); + swcFile.delete(); + File newSWCFile = new File(outputFolderName + ".new"); + newSWCFile.renameTo(swcFile); + } + compilationSuccess = true; + } + } + catch (Exception e) + { + System.out.println(e); + final ICompilerProblem problem = new InternalCompilerProblem(e); + problems.add(problem); + } + + return compilationSuccess; + } + + /** + * Build target artifact. + * + * @throws InterruptedException threading error + * @throws IOException IO error + * @throws ConfigurationException + */ + @Override + protected void buildArtifact() throws InterruptedException, IOException, + ConfigurationException + { + jsTarget = buildJSTarget(); + } + + private IJSApplication buildJSTarget() throws InterruptedException, + FileNotFoundException, ConfigurationException + { + final List<ICompilerProblem> problemsBuildingSWF = new ArrayList<ICompilerProblem>(); + + final IJSApplication app = buildApplication(project, + config.getMainDefinition(), null, problemsBuildingSWF); + problems.addAll(problemsBuildingSWF); + if (app == null) + { + ICompilerProblem problem = new UnableToBuildSWFProblem( + getOutputFilePath()); + problems.add(problem); + } + + return app; + } + + /** + * Replaces FlexApplicationProject::buildSWF() + * + * @param applicationProject + * @param rootClassName + * @param problems + * @return + * @throws InterruptedException + */ + + private IJSApplication buildApplication(CompilerProject applicationProject, + String rootClassName, ICompilationUnit mainCU, + Collection<ICompilerProblem> problems) throws InterruptedException, + ConfigurationException, FileNotFoundException + { + Collection<ICompilerProblem> fatalProblems = applicationProject.getFatalProblems(); + if (!fatalProblems.isEmpty()) + { + problems.addAll(fatalProblems); + return null; + } + + return ((JSTarget) target).build(mainCU, problems); + } + + /** + * Get the output file path. If {@code -output} is specified, use its value; + * otherwise, use the same base name as the target file. + * + * @return output file path + */ + private String getOutputFilePath() + { + if (config.getOutput() == null) + { + final String extension = "." + project.getBackend().getOutputExtension(); + return FilenameUtils.removeExtension(config.getTargetFile()).concat( + extension); + } + else + { + String outputFolderName = config.getOutput(); + return outputFolderName; + } + } + + /** + * Get the output class file. This includes the (sub)directory in which the + * original class file lives. If the directory structure doesn't exist, it + * is created. + * + * @author Erik de Bruin + * @param qname + * @param outputFolder + * @return output class file path + */ + private File getOutputClassFile(String qname, File outputFolder) + { + String[] cname = qname.split("\\."); + String sdirPath = outputFolder + File.separator; + if (cname.length > 0) + { + for (int i = 0, n = cname.length - 1; i < n; i++) + { + sdirPath += cname[i] + File.separator; + } + + File sdir = new File(sdirPath); + if (!sdir.exists()) + sdir.mkdirs(); + + qname = cname[cname.length - 1]; + } + + return new File(sdirPath + qname + "." + project.getBackend().getOutputExtension()); + } + + /** + * Mxmlc uses target file as the main compilation unit and derive the output + * SWF file name from this file. + * + * @return true if successful, false otherwise. + * @throws InterruptedException + */ + @Override + protected boolean setupTargetFile() throws InterruptedException + { + config.getTargetFile(); + + ITargetSettings settings = getTargetSettings(); + if (settings != null) + project.setTargetSettings(settings); + else + return false; + + target = project.getBackend().createTarget(project, + getTargetSettings(), null); + + return true; + } + + private ITargetSettings getTargetSettings() + { + if (targetSettings == null) + targetSettings = projectConfigurator.getTargetSettings(getTargetType()); + + if (targetSettings == null) + problems.addAll(projectConfigurator.getConfigurationProblems()); + + return targetSettings; + } + + /** + * Validate target file. + * + * @throws MustSpecifyTarget + * @throws IOError + */ + @Override + protected void validateTargetFile() throws ConfigurationException + { + + } + + protected String getProgramName() + { + return "compc"; + } + + protected boolean isCompc() + { + return true; + } + + @Override + protected TargetType getTargetType() + { + return TargetType.SWC; + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6fced513/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCNative.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCNative.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCNative.java new file mode 100644 index 0000000..7517a63 --- /dev/null +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/COMPJSCNative.java @@ -0,0 +1,529 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.flex.compiler.clients; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.List; +import java.util.Set; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.flex.compiler.clients.problems.ProblemQuery; +import org.apache.flex.compiler.codegen.as.IASWriter; +import org.apache.flex.compiler.driver.IBackend; +import org.apache.flex.compiler.driver.js.IJSApplication; +import org.apache.flex.compiler.exceptions.ConfigurationException; +import org.apache.flex.compiler.exceptions.ConfigurationException.IOError; +import org.apache.flex.compiler.exceptions.ConfigurationException.MustSpecifyTarget; +import org.apache.flex.compiler.internal.codegen.js.JSWriter; +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; +import org.apache.flex.compiler.internal.driver.js.jsc.JSCBackend; +import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSSWCBackend; +import org.apache.flex.compiler.internal.driver.mxml.jsc.MXMLJSCJSSWCBackend; +import org.apache.flex.compiler.internal.parsing.as.FlexJSASDocDelegate; +import org.apache.flex.compiler.internal.projects.CompilerProject; +import org.apache.flex.compiler.internal.projects.FlexJSProject; +import org.apache.flex.compiler.internal.targets.FlexJSSWCTarget; +import org.apache.flex.compiler.internal.targets.JSTarget; +import org.apache.flex.compiler.internal.workspaces.Workspace; +import org.apache.flex.compiler.problems.ICompilerProblem; +import org.apache.flex.compiler.problems.InternalCompilerProblem; +import org.apache.flex.compiler.problems.LibraryNotFoundProblem; +import org.apache.flex.compiler.problems.UnableToBuildSWFProblem; +import org.apache.flex.compiler.targets.ITarget.TargetType; +import org.apache.flex.compiler.targets.ITargetSettings; +import org.apache.flex.compiler.units.ICompilationUnit; +import org.apache.flex.swc.io.SWCReader; + +/** + * @author Erik de Bruin + * @author Michael Schmalle + */ +public class COMPJSCNative extends MXMLJSC +{ + /* + * Exit code enumerations. + */ + static enum ExitCode + { + SUCCESS(0), + PRINT_HELP(1), + FAILED_WITH_PROBLEMS(2), + FAILED_WITH_EXCEPTIONS(3), + FAILED_WITH_CONFIG_PROBLEMS(4); + + ExitCode(int code) + { + this.code = code; + } + + final int code; + } + + @Override + public String getName() + { + return FLEX_TOOL_COMPC; + } + + @Override + public int execute(String[] args) + { + return staticMainNoExit(args); + } + + /** + * Java program entry point. + * + * @param args command line arguments + */ + public static void main(final String[] args) + { + int exitCode = staticMainNoExit(args); + System.exit(exitCode); + } + + /** + * Entry point for the {@code <compc>} Ant task. + * + * @param args Command line arguments. + * @return An exit code. + */ + public static int staticMainNoExit(final String[] args) + { + long startTime = System.nanoTime(); + + final COMPJSCNative mxmlc = new COMPJSCNative(); + final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(); + final int exitCode = mxmlc.mainNoExit(args, problems, true); + + long endTime = System.nanoTime(); + System.out.println((endTime - startTime) / 1e9 + " seconds"); + + return exitCode; + } + + public COMPJSCNative() + { + IBackend backend = new MXMLJSCJSSWCBackend(); + + workspace = new Workspace(); + workspace.setASDocDelegate(new FlexJSASDocDelegate()); + project = new FlexJSProject(workspace, backend); + problems = new ProblemQuery(); // this gets replaced in configure(). Do we need it here? + asFileHandler = backend.getSourceFileHandlerInstance(); + } + + /** + * Main body of this program. This method is called from the public static + * method's for this program. + * + * @return true if compiler succeeds + * @throws IOException + * @throws InterruptedException + */ + @Override + protected boolean compile() + { + boolean compilationSuccess = false; + + try + { + project.getSourceCompilationUnitFactory().addHandler(asFileHandler); + + if (setupTargetFile()) + buildArtifact(); + + if (jsTarget != null) + { + Collection<ICompilerProblem> errors = new ArrayList<ICompilerProblem>(); + Collection<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>(); + + if (!config.getCreateTargetWithErrors()) + { + problems.getErrorsAndWarnings(errors, warnings); + if (errors.size() > 0) + return false; + } + + boolean packingSWC = false; + String outputFolderName = getOutputFilePath(); + File swcFile = new File(outputFolderName); + File jsOut = new File("js/out"); + File externsOut = new File("externs"); + ZipFile zipFile = null; + ZipOutputStream zipOutputStream = null; + String catalog = null; + StringBuilder fileList = new StringBuilder(); + if (outputFolderName.endsWith(".swc")) + { + packingSWC = true; + if (!swcFile.exists()) + { + problems.add(new LibraryNotFoundProblem(outputFolderName)); + return false; + } + zipFile = new ZipFile(swcFile, ZipFile.OPEN_READ); + final InputStream catalogInputStream = SWCReader.getInputStream(zipFile, SWCReader.CATALOG_XML); + + catalog = IOUtils.toString(catalogInputStream); + catalogInputStream.close(); + zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outputFolderName + ".new"))); + zipOutputStream.setLevel(Deflater.NO_COMPRESSION); + for (final Enumeration<? extends ZipEntry> entryEnum = zipFile.entries(); entryEnum.hasMoreElements();) + { + final ZipEntry entry = entryEnum.nextElement(); + if (!entry.getName().contains("js/out") && + !entry.getName().contains(SWCReader.CATALOG_XML)) + { + System.out.println("Copy " + entry.getName()); + InputStream input = zipFile.getInputStream(entry); + zipOutputStream.putNextEntry(new ZipEntry(entry.getName())); + IOUtils.copy(input, zipOutputStream); + zipOutputStream.flush(); + zipOutputStream.closeEntry(); + } + } + int filesIndex = catalog.indexOf("<files>"); + if (filesIndex != -1) + { + int filesIndex2 = catalog.indexOf("</files>"); + String files = catalog.substring(filesIndex, filesIndex2); + int fileIndex = files.indexOf("<file", 6); + int pathIndex = files.indexOf("path="); + while (pathIndex != -1) + { + int pathIndex2 = files.indexOf("\"", pathIndex + 6); + int fileIndex2 = files.indexOf("/>", fileIndex); + String path = files.substring(pathIndex + 6, pathIndex2); + if (!path.startsWith("js/out")) + { + fileList.append(files.substring(fileIndex - 8, fileIndex2 + 3)); + } + pathIndex = files.indexOf("path=", pathIndex2); + fileIndex = files.indexOf("<file", fileIndex2); + } + catalog = catalog.substring(0, filesIndex) + catalog.substring(filesIndex2 + 8); + } + } + + File outputFolder = null; + if (!packingSWC) + outputFolder = new File(outputFolderName); + + Set<String> externs = config.getExterns(); + Collection<ICompilationUnit> roots = ((FlexJSSWCTarget)target).getReachableCompilationUnits(errors); + Collection<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots); + for (final ICompilationUnit cu : reachableCompilationUnits) + { + ICompilationUnit.UnitType cuType = cu.getCompilationUnitType(); + + if (cuType == ICompilationUnit.UnitType.AS_UNIT + || cuType == ICompilationUnit.UnitType.MXML_UNIT) + { + String symbol = cu.getQualifiedNames().get(0); + if (externs.contains(symbol)) continue; + + if (project.isExternalLinkage(cu)) continue; + + if (!packingSWC) + { + final File outputClassFile = getOutputClassFile( + cu.getQualifiedNames().get(0), outputFolder); + + System.out.println("Compiling file: " + outputClassFile); + + ICompilationUnit unit = cu; + + IASWriter writer; + if (cuType == ICompilationUnit.UnitType.AS_UNIT) + { + writer = project.getBackend().createWriter(project, + (List<ICompilerProblem>) errors, unit, + false); + } + else + { + writer = project.getBackend().createMXMLWriter( + project, (List<ICompilerProblem>) errors, + unit, false); + } + problems.addAll(errors); + BufferedOutputStream out = new BufferedOutputStream( + new FileOutputStream(outputClassFile)); + writer.writeTo(out); + out.flush(); + out.close(); + writer.close(); + } + else + { + System.out.println("Compiling file: " + cu.getQualifiedNames().get(0)); + + ICompilationUnit unit = cu; + + IASWriter writer; + if (cuType == ICompilationUnit.UnitType.AS_UNIT) + { + writer = project.getBackend().createWriter(project, + (List<ICompilerProblem>) errors, unit, + false); + } + else + { + writer = project.getBackend().createMXMLWriter( + project, (List<ICompilerProblem>) errors, + unit, false); + } + problems.addAll(errors); + ByteArrayOutputStream temp = new ByteArrayOutputStream(); + writer.writeTo(temp); + boolean isExterns = false; + if (writer instanceof JSWriter) + isExterns = ((JSWriter)writer).isExterns(); + String outputClassFile = getOutputClassFile( + cu.getQualifiedNames().get(0), isExterns ? externsOut : jsOut).getPath(); + System.out.println("Writing file: " + outputClassFile); + zipOutputStream.putNextEntry(new ZipEntry(outputClassFile)); + temp.writeTo(zipOutputStream); + zipOutputStream.flush(); + zipOutputStream.closeEntry(); + writer.close(); + fileList.append(" <file path=\"" + outputClassFile + "\" mod=\"" + System.currentTimeMillis() + "\"/>\n"); + } + } + } + if (packingSWC) + { + zipFile.close(); + int libraryIndex = catalog.indexOf("</libraries>"); + catalog = catalog.substring(0, libraryIndex + 13) + + " <files>\n" + fileList.toString() + " </files>" + + catalog.substring(libraryIndex + 13); + zipOutputStream.putNextEntry(new ZipEntry(SWCReader.CATALOG_XML)); + zipOutputStream.write(catalog.getBytes()); + zipOutputStream.flush(); + zipOutputStream.closeEntry(); + zipOutputStream.flush(); + zipOutputStream.close(); + swcFile.delete(); + File newSWCFile = new File(outputFolderName + ".new"); + newSWCFile.renameTo(swcFile); + } + compilationSuccess = true; + } + } + catch (Exception e) + { + System.out.println(e); + final ICompilerProblem problem = new InternalCompilerProblem(e); + problems.add(problem); + } + + return compilationSuccess; + } + + /** + * Build target artifact. + * + * @throws InterruptedException threading error + * @throws IOException IO error + * @throws ConfigurationException + */ + @Override + protected void buildArtifact() throws InterruptedException, IOException, + ConfigurationException + { + jsTarget = buildJSTarget(); + } + + private IJSApplication buildJSTarget() throws InterruptedException, + FileNotFoundException, ConfigurationException + { + final List<ICompilerProblem> problemsBuildingSWF = new ArrayList<ICompilerProblem>(); + + final IJSApplication app = buildApplication(project, + config.getMainDefinition(), null, problemsBuildingSWF); + problems.addAll(problemsBuildingSWF); + if (app == null) + { + ICompilerProblem problem = new UnableToBuildSWFProblem( + getOutputFilePath()); + problems.add(problem); + } + + return app; + } + + /** + * Replaces FlexApplicationProject::buildSWF() + * + * @param applicationProject + * @param rootClassName + * @param problems + * @return + * @throws InterruptedException + */ + + private IJSApplication buildApplication(CompilerProject applicationProject, + String rootClassName, ICompilationUnit mainCU, + Collection<ICompilerProblem> problems) throws InterruptedException, + ConfigurationException, FileNotFoundException + { + Collection<ICompilerProblem> fatalProblems = applicationProject.getFatalProblems(); + if (!fatalProblems.isEmpty()) + { + problems.addAll(fatalProblems); + return null; + } + + return ((JSTarget) target).build(mainCU, problems); + } + + /** + * Get the output file path. If {@code -output} is specified, use its value; + * otherwise, use the same base name as the target file. + * + * @return output file path + */ + private String getOutputFilePath() + { + if (config.getOutput() == null) + { + final String extension = "." + project.getBackend().getOutputExtension(); + return FilenameUtils.removeExtension(config.getTargetFile()).concat( + extension); + } + else + { + String outputFolderName = config.getOutput(); + return outputFolderName; + } + } + + /** + * Get the output class file. This includes the (sub)directory in which the + * original class file lives. If the directory structure doesn't exist, it + * is created. + * + * @author Erik de Bruin + * @param qname + * @param outputFolder + * @return output class file path + */ + private File getOutputClassFile(String qname, File outputFolder) + { + String[] cname = qname.split("\\."); + String sdirPath = outputFolder + File.separator; + if (cname.length > 0) + { + for (int i = 0, n = cname.length - 1; i < n; i++) + { + sdirPath += cname[i] + File.separator; + } + + File sdir = new File(sdirPath); + if (!sdir.exists()) + sdir.mkdirs(); + + qname = cname[cname.length - 1]; + } + + return new File(sdirPath + qname + "." + project.getBackend().getOutputExtension()); + } + + /** + * Mxmlc uses target file as the main compilation unit and derive the output + * SWF file name from this file. + * + * @return true if successful, false otherwise. + * @throws InterruptedException + */ + @Override + protected boolean setupTargetFile() throws InterruptedException + { + config.getTargetFile(); + + ITargetSettings settings = getTargetSettings(); + if (settings != null) + project.setTargetSettings(settings); + else + return false; + + target = project.getBackend().createTarget(project, + getTargetSettings(), null); + + return true; + } + + private ITargetSettings getTargetSettings() + { + if (targetSettings == null) + targetSettings = projectConfigurator.getTargetSettings(getTargetType()); + + if (targetSettings == null) + problems.addAll(projectConfigurator.getConfigurationProblems()); + + return targetSettings; + } + + /** + * Validate target file. + * + * @throws MustSpecifyTarget + * @throws IOError + */ + @Override + protected void validateTargetFile() throws ConfigurationException + { + + } + + protected String getProgramName() + { + return "compc"; + } + + protected boolean isCompc() + { + return true; + } + + @Override + protected TargetType getTargetType() + { + return TargetType.SWC; + } +} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6fced513/compiler-jx/src/main/java/org/apache/flex/compiler/clients/FlexJSToolGroup.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/FlexJSToolGroup.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/FlexJSToolGroup.java index dd9bc14..63f1c35 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/FlexJSToolGroup.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/FlexJSToolGroup.java @@ -31,8 +31,8 @@ public class FlexJSToolGroup extends AbstractFlexToolGroup { public FlexJSToolGroup() { super("FlexJS"); - addFlexTool(new COMPJSC(new MXMLFlexJSSWCBackend())); - addFlexTool(new MXMLJSC(new MXMLFlexJSBackend())); + addFlexTool(new COMPJSC()); + addFlexTool(new MXMLJSC()); addFlexTool(new ASDOCJSC(new MXMLFlexJSASDocDITABackend())); addFlexTool(new EXTERNC()); } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6fced513/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java index 3ce8665..a06698d 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java @@ -19,12 +19,23 @@ package org.apache.flex.compiler.clients; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.flex.compiler.clients.MXMLJSC.JSOutputType; +import org.apache.flex.compiler.clients.MXMLJSC.JSTargetType; import org.apache.flex.compiler.config.Configuration; import org.apache.flex.compiler.config.ConfigurationValue; import org.apache.flex.compiler.exceptions.ConfigurationException; +import org.apache.flex.compiler.exceptions.ConfigurationException.CannotOpen; +import org.apache.flex.compiler.internal.config.annotations.Arguments; import org.apache.flex.compiler.internal.config.annotations.Config; +import org.apache.flex.compiler.internal.config.annotations.InfiniteArguments; import org.apache.flex.compiler.internal.config.annotations.Mapping; +import com.google.common.collect.ImmutableList; + /** * The {@link JSConfiguration} class holds all compiler arguments needed for * compiling ActionScript to JavaScript. @@ -43,22 +54,42 @@ public class JSConfiguration extends Configuration } // - // 'js-output-type' + // 'compiler.targets' option // - private String jsOutputType = MXMLJSC.JSOutputType.FLEXJS.getText(); + protected final List<String> targets = new ArrayList<String>(); + + public List<String> getCompilerTargets() + { + if (targets.size() == 0) + targets.add(JSTargetType.JS_FLEX.getText()); + return targets; + } - public String getJSOutputType() + /** + * The list of compiler outputs to generate + */ + @Config(allowMultiple = true, isPath = false) + @Mapping({ "compiler", "targets" }) + @Arguments("type") + @InfiniteArguments + public void setCompilerTargets(ConfigurationValue cv, String[] targetlist) { - return jsOutputType; + for (String target : targetlist) + targets.add(target); } + // + // 'js-output-type' + // + @Config @Mapping("js-output-type") public void setJSOutputType(ConfigurationValue cv, String value) throws ConfigurationException { - jsOutputType = value; + targets.clear(); + targets.add(value); } // http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/6fced513/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java index bb10a06..8a96d6d 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSC.java @@ -96,8 +96,8 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, } /* - * JS output type enumerations. - */ + * JS output type enumerations. + */ public enum JSOutputType { AMD("amd"), @@ -132,6 +132,40 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, } /* + * JS output type enumerations. + */ + public enum JSTargetType + { + SWF("SWF"), + JS_FLEX("JSFlex"), + JS_FLEX_CORDOVA("JSFlexCordova"), + JS_NATIVE("JS"), + JS_NODE("JSNode"); + + private String text; + + JSTargetType(String text) + { + this.text = text; + } + + public String getText() + { + return this.text; + } + + public static JSTargetType fromString(String text) + { + for (JSTargetType jsTargetType : JSTargetType.values()) + { + if (text.equalsIgnoreCase(jsTargetType.text)) + return jsTargetType; + } + return JS_FLEX; + } + } + + /* * Exit code enumerations. */ static enum ExitCode @@ -186,48 +220,7 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, public static int staticMainNoExit(final String[] args) { long startTime = System.nanoTime(); - - IBackend backend = new ASBackend(); - String jsOutputTypeString = ""; - for (String s : args) - { - String[] kvp = s.split("="); - - if (s.contains("-js-output-type")) - { - jsOutputTypeString = kvp[1]; - } - } - - if (jsOutputTypeString.equals("")) - { - jsOutputTypeString = JSOutputType.FLEXJS.getText(); - } - - jsOutputType = JSOutputType.fromString(jsOutputTypeString); - switch (jsOutputType) - { - case AMD: - backend = new AMDBackend(); - break; - case JSC: - backend = new JSCBackend(); - break; - case NODE: - backend = new NodeBackend(); - break; - case FLEXJS: - case FLEXJS_DUAL: - backend = new MXMLFlexJSBackend(); - break; - case GOOG: - backend = new GoogBackend(); - break; - // if you add a new js-output-type here, don't forget to also add it - // to flex2.tools.MxmlJSC in flex-compiler-oem for IDE support - } - - final MXMLJSC mxmlc = new MXMLJSC(backend); + final MXMLJSC mxmlc = new MXMLJSC(); final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>(); final int exitCode = mxmlc.mainNoExit(args, problems, true); @@ -242,7 +235,7 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, protected ProblemQuery problems; protected ISourceFileHandler asFileHandler; - protected Configuration config; + protected JSConfiguration config; protected Configurator projectConfigurator; private ConfigurationBuffer configBuffer; private ICompilationUnit mainCU; @@ -251,13 +244,10 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, protected IJSApplication jsTarget; private IJSPublisher jsPublisher; - public MXMLJSC(IBackend backend) + public MXMLJSC() { workspace = new Workspace(); workspace.setASDocDelegate(new FlexJSASDocDelegate()); - project = new FlexJSProject(workspace, backend); - problems = new ProblemQuery(); // this gets replaced in configure(). Do we need it here? - asFileHandler = backend.getSourceFileHandlerInstance(); } @Override @@ -309,8 +299,50 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, if (continueCompilation) { - project.setProblems(problems.getProblems()); - compile(); + + targetloop: + for (String target : config.getCompilerTargets()) + { + int result = 0; + switch (JSTargetType.fromString(target)) + { + case SWF: + MXMLC mxmlc = new MXMLC(); + result = mxmlc.mainNoExit(removeJSArgs(args)); + if (result != 0) + { + problems.addAll(mxmlc.problems.getProblems()); + break targetloop; + } + break; + case JS_FLEX: + MXMLJSCFlex flex = new MXMLJSCFlex(); + result = flex.mainNoExit(args, problems.getProblems(), false); + if (result != 0) + { + break targetloop; + } + break; + case JS_NODE: + MXMLJSCNode node = new MXMLJSCNode(); + result = node.mainNoExit(args, problems.getProblems(), false); + if (result != 0) + { + break targetloop; + } + break; + case JS_NATIVE: + MXMLJSCNative jsc = new MXMLJSCNative(); + result = jsc.mainNoExit(args, problems.getProblems(), false); + if (result != 0) + { + break targetloop; + } + break; + // if you add a new js-output-type here, don't forget to also add it + // to flex2.tools.MxmlJSC in flex-compiler-oem for IDE support + } + } if (problems.hasFilteredProblems()) { if (problems.hasErrors()) @@ -354,6 +386,20 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, } return exitCode.code; } + + private String[] removeJSArgs(String[] args) + { + ArrayList<String> list = new ArrayList<String>(); + for (String arg : args) + { + if (!(arg.startsWith("-compiler.targets") || + arg.startsWith("-closure-lib") || + arg.startsWith("-remove-circulars") || + arg.startsWith("-source-map"))) + list.add(arg); + } + return list.toArray(new String[0]); + } /** * Main body of this program. This method is called from the public static @@ -694,9 +740,8 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, */ protected boolean configure(final String[] args) { - project.getSourceCompilationUnitFactory().addHandler(asFileHandler); - project.configurator = projectConfigurator = createConfigurator(); - + projectConfigurator = new Configurator(JSGoogConfiguration.class); + try { if (useFlashBuilderProjectFiles(args)) @@ -712,30 +757,20 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, ICompilerSettingsConstants.FILE_SPECS_VAR); } - projectConfigurator.applyToProject(project); - project.config = (JSGoogConfiguration) projectConfigurator.getConfiguration(); - - config = projectConfigurator.getConfiguration(); - configBuffer = projectConfigurator.getConfigurationBuffer(); - + // getCompilerProblemSettings initializes the configuration problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings()); problems.addAll(projectConfigurator.getConfigurationProblems()); + config = (JSConfiguration) projectConfigurator.getConfiguration(); + configBuffer = projectConfigurator.getConfigurationBuffer(); if (configBuffer.getVar("version") != null) //$NON-NLS-1$ return false; if (problems.hasErrors()) return false; - - validateTargetFile(); + return true; } - catch (ConfigurationException e) - { - final ICompilerProblem problem = new ConfigurationProblem(e); - problems.add(problem); - return false; - } catch (Exception e) { final ICompilerProblem problem = new ConfigurationProblem(null, -1, @@ -747,7 +782,7 @@ public class MXMLJSC implements JSCompilerEntryPoint, ProblemQueryProvider, { if (config == null) { - config = new Configuration(); + config = new JSConfiguration(); configBuffer = new ConfigurationBuffer(Configuration.class, Configuration.getAliases()); }
