Merge branch 'develop' into dual
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..f58a860 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
@@ -29,6 +29,7 @@
import java.util.List;
import java.util.Set;
import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
import org.apache.flex.compiler.codegen.as.IASWriter;
import org.apache.flex.compiler.codegen.js.flexjs.IJSFlexJSASDocEmitter;
import org.apache.flex.compiler.driver.IBackend;
@@ -42,11 +43,15 @@
import org.apache.flex.compiler.internal.driver.js.goog.GoogBackend;
import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSASDocBackend;
import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSASDocDITABackend;
+import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSBackend;
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.FlexJSASDocProject;
+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.UnableToBuildSWFProblem;
@@ -58,7 +63,7 @@
* @author Erik de Bruin
* @author Michael Schmalle
*/
-public class ASDOCJSC extends MXMLJSC
+public class ASDOCJSC extends MXMLJSCFlex
{
/*
* Exit code enumerations.
@@ -117,7 +122,7 @@
{
if (s.contains("js-output-type"))
{
- jsOutputType = JSOutputType.fromString(s.split("=")[1]);
+ jsOutputType = MXMLJSC.JSOutputType.fromString(s.split("=")[1]);
switch (jsOutputType)
{
@@ -160,9 +165,20 @@
public ASDOCJSC(IBackend backend)
{
- super(backend);
+ super(backend);
project = new FlexJSASDocProject(workspace, backend);
}
+
+ protected void init()
+ {
+ IBackend backend = new MXMLFlexJSBackend();
+ 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
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..f13ee22 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 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;
@@ -48,6 +52,7 @@
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.goog.JSGoogCompcConfiguration;
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.projects.CompilerProject;
@@ -57,10 +62,12 @@
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,39 +127,8 @@
{
long startTime = System.nanoTime();
- IBackend backend = new ASBackend();
- for (String s : args)
- {
- if (s.contains("-js-output-type"))
- {
- jsOutputType = JSOutputType.fromString(s.split("=")[1]);
-
- switch (jsOutputType)
- {
- case AMD:
- backend = new AMDBackend();
- break;
-
- case JSC:
- backend = new MXMLJSCJSSWCBackend();
- break;
-
- case FLEXJS:
- case FLEXJS_DUAL:
- backend = new MXMLFlexJSSWCBackend();
- break;
-
- case GOOG:
- backend = new GoogBackend();
- break;
-
- default:
- throw new UnsupportedOperationException();
- }
- }
- }
-
- final COMPJSC mxmlc = new COMPJSC(backend);
+ final COMPJSC mxmlc = new COMPJSC();
+ mxmlc.configurationClass = JSGoogCompcConfiguration.class;
final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
final int exitCode = mxmlc.mainNoExit(args, problems, true);
@@ -162,9 +138,146 @@
return exitCode;
}
- public COMPJSC(IBackend backend)
+ @Override
+ public int mainNoExit(final String[] args, List<ICompilerProblem> problems,
+ Boolean printProblems)
{
- super(backend);
+ int exitCode = -1;
+ try
+ {
+ exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems);
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.toString());
+ }
+ finally
+ {
+ if (problems != null && !problems.isEmpty())
+ {
+ if (printProblems)
+ {
+ final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter(
+ workspace);
+ final ProblemPrinter printer = new ProblemPrinter(formatter);
+ printer.printProblems(problems);
+ }
+ }
+ }
+ return exitCode;
+ }
+
+ /**
+ * 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)
+ {
+ System.out.println("args:");
+ for (String arg : args)
+ System.out.println(arg);
+ ExitCode exitCode = ExitCode.SUCCESS;
+ try
+ {
+ final boolean continueCompilation = configure(args);
+
+/* if (outProblems != null && !config.isVerbose())
+ JSSharedData.STDOUT = JSSharedData.STDERR = null;*/
+
+ if (continueCompilation)
+ {
+ List<String> targets = config.getCompilerTargets();
+ for (String target : targets)
+ System.out.println("target:" + target);
+ targetloop:
+ for (String target : config.getCompilerTargets())
+ {
+ int result = 0;
+ switch (JSTargetType.fromString(target))
+ {
+ case SWF:
+ System.out.println("COMPC");
+ COMPC compc = new COMPC();
+ compc.configurationClass = JSGoogCompcConfiguration.class;
+ result = compc.mainNoExit(removeJSArgs(args));
+ if (result != 0)
+ {
+ problems.addAll(compc.problems.getProblems());
+ break targetloop;
+ }
+ break;
+ case JS_FLEX:
+ System.out.println("COMPCJSCFlex");
+ COMPJSCFlex flex = new COMPJSCFlex();
+ result = flex.mainNoExit(removeASArgs(args), problems.getProblems(), false);
+ if (result != 0)
+ {
+ break targetloop;
+ }
+ break;
+ case JS_NATIVE:
+ COMPJSCNative jsc = new COMPJSCNative();
+ result = jsc.mainNoExit(removeASArgs(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();
+
+ if (outProblems != null && problems.hasFilteredProblems())
+ {
+ for (ICompilerProblem problem : problems.getFilteredProblems())
+ {
+ outProblems.add(problem);
+ }
+ }
+ }
+ return exitCode.code;
+ }
+
+ public COMPJSC()
+ {
+ super();
}
/**
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..c403bbc
--- /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 MXMLJSCFlex
+{
+ /*
+ * 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;
+ }
+}
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..c578249
--- /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 MXMLJSCNative
+{
+ /*
+ * 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;
+ }
+}
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 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());
}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSCompilerEntryPoint.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSCompilerEntryPoint.java
index 0ffa22e..6b028da 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSCompilerEntryPoint.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSCompilerEntryPoint.java
@@ -26,4 +26,9 @@
public interface JSCompilerEntryPoint {
public int mainNoExit(final String[] args, List<ICompilerProblem> problems,
Boolean printProblems);
+
+ public List<String> getSourceList();
+
+ public String getMainSource();
+
}
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..4427df4 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,11 +19,28 @@
package org.apache.flex.compiler.clients;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+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.ConfigurationBuffer;
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.FlexOnly;
+import org.apache.flex.compiler.internal.config.annotations.InfiniteArguments;
import org.apache.flex.compiler.internal.config.annotations.Mapping;
+import org.apache.flex.compiler.internal.config.annotations.SoftPrerequisites;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
+
+import com.google.common.collect.ImmutableList;
/**
* The {@link JSConfiguration} class holds all compiler arguments needed for
@@ -43,22 +60,45 @@
}
//
- // 'js-output-type'
+ // 'compiler.targets' option
//
- private String jsOutputType = MXMLJSC.JSOutputType.FLEXJS.getText();
+ protected final List<String> targets = new ArrayList<String>();
- public String getJSOutputType()
+ public List<String> getCompilerTargets()
{
- return jsOutputType;
+ if (targets.size() == 0)
+ targets.add(JSTargetType.JS_FLEX.getText());
+ return targets;
}
+ /**
+ * The list of compiler outputs to generate
+ */
+ @Config(allowMultiple = true, isPath = false)
+ @Mapping({ "compiler", "targets" })
+ @Arguments("target")
+ @InfiniteArguments
+ public void setCompilerTargets(ConfigurationValue cv, String[] targetlist)
+ {
+ targets.clear();
+ 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;
+ // ignore if set via compiler.targets
+ if (targets.size() > 0) return;
+ targets.clear();
+ targets.add(value);
}
//
@@ -80,4 +120,245 @@
sourceMap = value;
}
+ //
+ // 'compiler.js-external-library-path' option
+ //
+
+ private final List<String> jsexternalLibraryPath = new ArrayList<String>();
+
+ public List<String> getCompilerJsExternalLibraryPath()
+ {
+ return jsexternalLibraryPath;
+ }
+
+ @Config(allowMultiple = true, isPath = true)
+ @Mapping({ "compiler", "js-external-library-path" })
+ @Arguments(Arguments.PATH_ELEMENT)
+ @InfiniteArguments
+ public void setCompilerJsExternalLibraryPath(ConfigurationValue cv, String[] pathlist) throws ConfigurationException
+ {
+ final ImmutableList<String> pathElements = ImmutableList.copyOf(pathlist);
+ final ImmutableList<String> resolvedPaths = expandTokens(pathElements, locales, cv,
+ !reportMissingCompilerLibraries);
+ jsexternalLibraryPath.addAll(resolvedPaths);
+ }
+
+ //
+ // 'compiler.js-library-path' option
+ //
+
+ private final List<String> jslibraryPath = new ArrayList<String>();
+
+ public List<String> getCompilerJsLibraryPath()
+ {
+ return jslibraryPath;
+ }
+
+ /**
+ * Links SWC files to the resulting application SWF file. The compiler only links in those classes for the SWC file
+ * that are required. You can specify a directory or individual SWC files.
+ */
+ @Config(allowMultiple = true, isPath = true)
+ @Mapping({ "compiler", "js-library-path" })
+ @Arguments(Arguments.PATH_ELEMENT)
+ @InfiniteArguments
+ public void setCompilerJsLibraryPath(ConfigurationValue cv, String[] pathlist) throws CannotOpen
+ {
+ final ImmutableList<String> resolvedPaths = expandTokens(Arrays.asList(pathlist), locales, cv,
+ !reportMissingCompilerLibraries);
+ jslibraryPath.addAll(resolvedPaths);
+ }
+
+ /**
+ * Syntax:<br/>
+ * <code>-define=<name>,<value></code> where name is <code>NAMESPACE::name</code> and value is a legal
+ * definition value (e.g. <code>true</code> or <code>1</code> or <code>!CONFIG::debugging</code>)
+ *
+ * Example: <code>-define=CONFIG::debugging,true</code>
+ *
+ * In <code>flex-config.xml</code>:<br/>
+ *
+ * <pre>
+ * <flex-config>
+ * <compiler>
+ * <define>
+ * <name>CONFIG::debugging</name>
+ * <value>true</value>
+ * </define>
+ * ...
+ * </compile>
+ * </flex-config>
+ * </pre>
+ *
+ * Values:<br/>
+ * Values are ActionScript expressions that must coerce and evaluate to constants at compile-time. Effectively, they
+ * are replaced in AS code, verbatim, so <code>-define=TEST::oneGreaterTwo,"1>2"</code> will getCompiler coerced and
+ * evaluated, at compile-time, to <code>false</code>.
+ *
+ * It is good practice to wrap values with double-quotes, so that MXMLC correctly parses them as a single argument:
+ * <br/>
+ * <code>-define=TEST::oneShiftRightTwo,"1 >> 2"</code>
+ *
+ * Values may contain compile-time constants and other configuration values:<br/>
+ * <code>-define=CONFIG::bool2,false -define=CONFIG::and1,"CONFIG::bool2 && false" TestApp.mxml</code>
+ *
+ * String values on the command-line <i>must</i> be surrounded by double-quotes, and either escape-quoted (
+ * <code>"\"foo\""</code> or <code>"\'foo\'"</code>) or single-quoted (<code>"'foo'"</code>).
+ *
+ * String values in configuration files need only be single- or double- quoted:<br/>
+ *
+ * <pre>
+ * <flex-config>
+ * <compiler>
+ * <define>
+ * <name>NAMES::Organization</name>
+ * <value>'Apache Software Foundation'</value>
+ * </define>
+ * <define>
+ * <name>NAMES::Application</name>
+ * <value>"Flex 4.8.0"</value>
+ * </define>
+ * ...
+ * </compile>
+ * </flex-config>
+ * </pre>
+ *
+ * Empty strings <i>must</i> be passed as <code>"''"</code> on the command-line, and <code>''</code> or
+ * <code>""</code> in configuration files.
+ *
+ * Finally, if you have existing definitions in a configuration file, and you would like to add to them with the
+ * command-line (let's say most of your build setCompilertings are in the configuration, and that you are adding one
+ * temporarily using the command-line), you use the following syntax: <code>-define+=TEST::temporary,false</code>
+ * (noting the plus sign)
+ *
+ * Note that definitions can be overridden/redefined if you use the append ("+=") syntax (on the commandline or in a
+ * user config file, for instance) with the same namespace and name, and a new value.
+ *
+ * Definitions cannot be removed/undefined. You can undefine ALL existing definitions from (e.g. from
+ * flex-config.xml) if you do not use append syntax ("=" or append="false").
+ *
+ * IMPORTANT FOR FLEXBUILDER If you are using "Additional commandline arguments" to "-define", don't use the
+ * following syntax though I suggest it above: -define+=CONFIG::foo,"'value'" The trouble is that FB parses the
+ * double quotes incorrectly as <"'value'> -- the trailing double-quote is dropped. The solution is to avoid inner
+ * double-quotes and put them around the whole expression: -define+="CONFIG::foo,'value'"
+ */
+ private Map<String, String> jsconfigVars;
+
+ /**
+ * @return A list of ConfigVars
+ */
+ @Override
+ public Map<String, String> getCompilerDefine()
+ {
+ if (jsconfigVars != null)
+ return jsconfigVars;
+ return super.getCompilerDefine();
+ }
+
+ @Config(advanced = true, allowMultiple = true)
+ @Arguments({ "name", "value" })
+ public void setJsCompilerDefine(ConfigurationValue cv, String name, String value) throws ConfigurationException
+ {
+ if (jsconfigVars == null)
+ jsconfigVars = new LinkedHashMap<String, String>();
+
+ jsconfigVars.put(name, value);
+ }
+
+ //
+ // 'output' option
+ //
+
+ private String jsoutput;
+
+ @Override
+ public String getOutput()
+ {
+ if (jsoutput != null)
+ return jsoutput;
+ return super.getOutput();
+ }
+
+ @Config
+ @Arguments("filename")
+ public void setJsOutput(ConfigurationValue val, String output) throws ConfigurationException
+ {
+ this.jsoutput = getOutputPath(val, output);
+ }
+
+ /**
+ * @return JS equivalent of -load-config
+ */
+ public String getJsLoadConfig()
+ {
+ return null;
+ }
+
+ /**
+ * Placeholder. MXMLJSC picks off these values and changes them to load-config for the JS compilers
+ */
+ @Config(allowMultiple = true)
+ @Arguments("filename")
+ public void setJsLoadConfig(ConfigurationValue cv, String filename) throws ConfigurationException
+ {
+
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // compiler.js-namespaces
+ //////////////////////////////////////////////////////////////////////////
+
+ private List<MXMLNamespaceMapping> jsmanifestMappings;
+
+ public List<MXMLNamespaceMapping> getCompilerJsNamespacesManifestMappings()
+ {
+ return jsmanifestMappings;
+ }
+
+ /**
+ * Configures a list of many manifests mapped to a single namespace URI.
+ * <namespace> <uri>library:adobe/flex/something</uri> <manifest>something-manifest.xml</manifest>
+ * <manifest>something-else-manifest.xml</manifest> ... </namespace>
+ *
+ * @param cfgval The configuration value context.
+ * @param args A List of values for the namespace element, with the first item expected to be the uri and the
+ * remaining are manifest paths.
+ */
+ @Config(allowMultiple = true)
+ @Mapping({ "compiler", "js-namespaces", "namespace" })
+ @Arguments({ "uri", "manifest" })
+ @InfiniteArguments
+ @FlexOnly
+ public void setCompilerJsNamespacesNamespace(ConfigurationValue cfgval, List<String> args)
+ throws ConfigurationException
+ {
+ if (args == null)
+ throw new ConfigurationException.CannotOpen(null, cfgval.getVar(), cfgval.getSource(), cfgval.getLine());
+
+ // allow -compiler.namespaces.namespace= which means don't add
+ // anything, which matches the behavior of things like -compiler.library-path
+ // which don't throw an error in this case either.
+ if (args.isEmpty())
+ return;
+
+ if (args.size() < 2)
+ throw new ConfigurationException.NamespaceMissingManifest("namespace", cfgval.getSource(),
+ cfgval.getLine());
+
+ if (args.size() % 2 != 0)
+ throw new ConfigurationException.IncorrectArgumentCount(args.size() + 1, args.size(), cfgval.getVar(),
+ cfgval.getSource(), cfgval.getLine());
+
+ if (jsmanifestMappings == null)
+ jsmanifestMappings = new ArrayList<MXMLNamespaceMapping>();
+
+ for (int i = 0; i < args.size() - 1; i += 2)
+ {
+ final String uri = args.get(i);
+ final String manifestFile = args.get(i + 1);
+ final String path = resolvePathStrict(manifestFile, cfgval);
+ jsmanifestMappings.add(new MXMLNamespaceMapping(uri, path));
+ }
+ }
+
}
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..795466e 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
@@ -24,14 +24,17 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.MXMLC.ExitCode;
import org.apache.flex.compiler.clients.problems.ProblemPrinter;
import org.apache.flex.compiler.clients.problems.ProblemQuery;
import org.apache.flex.compiler.clients.problems.ProblemQueryProvider;
@@ -75,11 +78,17 @@
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.compiler.units.ICompilationUnit.UnitType;
+import org.apache.flex.swf.ISWF;
+import org.apache.flex.swf.SWF;
+import org.apache.flex.swf.types.RGB;
+import org.apache.flex.swf.types.Rect;
import org.apache.flex.tools.FlexTool;
import org.apache.flex.utils.ArgumentUtil;
import org.apache.flex.utils.FilenameNormalization;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
/**
@@ -96,8 +105,8 @@
}
/*
- * JS output type enumerations.
- */
+ * JS output type enumerations.
+ */
public enum JSOutputType
{
AMD("amd"),
@@ -132,6 +141,40 @@
}
/*
+ * 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
@@ -149,6 +192,11 @@
}
final int code;
+
+ int getCode()
+ {
+ return code;
+ }
}
public static JSOutputType jsOutputType;
@@ -186,48 +234,10 @@
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);
+ System.out.println("MXMLJSC");
+ for (String arg : args)
+ System.out.println(arg);
+ final MXMLJSC mxmlc = new MXMLJSC();
final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
final int exitCode = mxmlc.mainNoExit(args, problems, true);
@@ -242,7 +252,7 @@
protected ProblemQuery problems;
protected ISourceFileHandler asFileHandler;
- protected Configuration config;
+ public JSConfiguration config;
protected Configurator projectConfigurator;
private ConfigurationBuffer configBuffer;
private ICompilationUnit mainCU;
@@ -250,14 +260,16 @@
protected ITargetSettings targetSettings;
protected IJSApplication jsTarget;
private IJSPublisher jsPublisher;
+ private MXMLC mxmlc;
+ private JSCompilerEntryPoint lastCompiler;
+ public boolean noLink;
+ public OutputStream err;
+ public Class<? extends Configuration> configurationClass = JSGoogConfiguration.class;
- 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 +321,66 @@
if (continueCompilation)
{
- project.setProblems(problems.getProblems());
- compile();
+
+ targetloop:
+ for (String target : config.getCompilerTargets())
+ {
+ int result = 0;
+ switch (JSTargetType.fromString(target))
+ {
+ case SWF:
+ mxmlc = new MXMLC();
+ mxmlc.configurationClass = configurationClass;
+ if (noLink)
+ result = mxmlc.mainCompileOnly(removeJSArgs(args), err);
+ else
+ result = mxmlc.mainNoExit(removeJSArgs(args));
+ if (result != 0)
+ {
+ problems.addAll(mxmlc.problems.getProblems());
+ break targetloop;
+ }
+ break;
+ case JS_FLEX:
+ MXMLJSCFlex flex = new MXMLJSCFlex();
+ lastCompiler = flex;
+ result = flex.mainNoExit(removeASArgs(args), problems.getProblems(), false);
+ if (result != 0)
+ {
+ break targetloop;
+ }
+ break;
+ case JS_FLEX_CORDOVA:
+ MXMLJSCFlexCordova flexCordova = new MXMLJSCFlexCordova();
+ lastCompiler = flexCordova;
+ result = flexCordova.mainNoExit(removeASArgs(args), problems.getProblems(), false);
+ if (result != 0)
+ {
+ break targetloop;
+ }
+ break;
+ case JS_NODE:
+ MXMLJSCNode node = new MXMLJSCNode();
+ lastCompiler = node;
+ result = node.mainNoExit(removeASArgs(args), problems.getProblems(), false);
+ if (result != 0)
+ {
+ break targetloop;
+ }
+ break;
+ case JS_NATIVE:
+ MXMLJSCNative jsc = new MXMLJSCNative();
+ lastCompiler = jsc;
+ result = jsc.mainNoExit(removeASArgs(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,7 +424,49 @@
}
return exitCode.code;
}
+
+ protected 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("-compiler.js-external-library-path") ||
+ arg.startsWith("-compiler.js-library-path") ||
+ arg.startsWith("-compiler.js-define") ||
+ arg.startsWith("-js-output") ||
+ arg.startsWith("-js-load-config") ||
+ arg.startsWith("-source-map")))
+ list.add(arg);
+ }
+ return list.toArray(new String[0]);
+ }
+ protected String[] removeASArgs(String[] args)
+ {
+ ArrayList<String> list = new ArrayList<String>();
+ boolean hasJSLoadConfig = false;
+ for (String arg : args)
+ {
+ if (arg.startsWith("-js-load-config"))
+ hasJSLoadConfig = true;
+ }
+ if (!hasJSLoadConfig)
+ return args;
+ for (String arg : args)
+ {
+ if (!arg.startsWith("-load-config"))
+ {
+ if (arg.startsWith("-js-load-config"))
+ arg = arg.substring(3);
+ list.add(arg);
+ }
+ }
+ return list.toArray(new String[0]);
+ }
+
/**
* Main body of this program. This method is called from the public static
* method's for this program.
@@ -692,11 +804,10 @@
* @param args command line arguments
* @return True if mxmlc should continue with compilation.
*/
- protected boolean configure(final String[] args)
+ public boolean configure(final String[] args)
{
- project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
- project.configurator = projectConfigurator = createConfigurator();
-
+ projectConfigurator = new Configurator(configurationClass);
+
try
{
if (useFlashBuilderProjectFiles(args))
@@ -712,30 +823,20 @@
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 +848,7 @@
{
if (config == null)
{
- config = new Configuration();
+ config = new JSConfiguration();
configBuffer = new ConfigurationBuffer(Configuration.class,
Configuration.getAliases());
}
@@ -813,4 +914,63 @@
{
workspace.close();
}
+
+ public List<String> getSourceList()
+ {
+ if (lastCompiler != null)
+ return lastCompiler.getSourceList();
+ if (mxmlc != null)
+ return mxmlc.getSourceList();
+ return null;
+ }
+
+ public String getMainSource()
+ {
+ if (lastCompiler != null)
+ return lastCompiler.getMainSource();
+ if (mxmlc != null)
+ return mxmlc.getMainSource();
+ return null;
+ }
+
+
+ /**
+ * return a data structure for FB integration
+ * @return
+ */
+ public ISWF getSWFTarget()
+ {
+ SWF swf = new SWF();
+ Rect rect = new Rect(getTargetSettings().getDefaultWidth(),
+ getTargetSettings().getDefaultHeight());
+ swf.setFrameSize(rect);
+ // we might need to report actual color some day
+ swf.setBackgroundColor(new RGB(255, 255, 255));
+ swf.setTopLevelClass(config.getTargetFile());
+ return swf;
+ }
+
+ public long writeSWF(OutputStream output)
+ {
+ if (mxmlc != null)
+ return mxmlc.writeSWF(output);
+ return 0;
+ }
+
+ /**
+ * Determines whether an exit code should be considered
+ * a fatal failure, such as for an Ant task.
+ *
+ * @param code A numeric exit code.
+ * @return <code>true</code> if the Ant task failed.
+ */
+ public static boolean isFatalFailure(final int code)
+ {
+ // This method really belongs in ExitCode
+ // but that would complicate FlexTask.
+ return code == ExitCode.FAILED_WITH_ERRORS.getCode() ||
+ code == ExitCode.FAILED_WITH_EXCEPTIONS.getCode() ||
+ code == ExitCode.FAILED_WITH_CONFIG_PROBLEMS.getCode();
+ }
+
}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCFlex.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCFlex.java
new file mode 100644
index 0000000..76186f3
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCFlex.java
@@ -0,0 +1,784 @@
+/*
+ *
+ * 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.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemPrinter;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.clients.problems.ProblemQueryProvider;
+import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter;
+import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.config.ConfigurationBuffer;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.config.ICompilerSettingsConstants;
+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.exceptions.ConfigurationException.OnlyOneSource;
+import org.apache.flex.compiler.internal.config.FlashBuilderConfigurator;
+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.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.driver.js.jsc.JSCBackend;
+import org.apache.flex.compiler.internal.driver.js.node.NodeBackend;
+import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSBackend;
+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.projects.ISourceFileHandler;
+import org.apache.flex.compiler.internal.targets.FlexJSTarget;
+import org.apache.flex.compiler.internal.targets.JSTarget;
+import org.apache.flex.compiler.internal.units.ResourceModuleCompilationUnit;
+import org.apache.flex.compiler.internal.units.SourceCompilationUnitFactory;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.problems.ConfigurationProblem;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.InternalCompilerProblem;
+import org.apache.flex.compiler.problems.UnableToBuildSWFProblem;
+import org.apache.flex.compiler.problems.UnexpectedExceptionProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.targets.ITarget;
+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.compiler.units.ICompilationUnit.UnitType;
+import org.apache.flex.tools.FlexTool;
+import org.apache.flex.utils.ArgumentUtil;
+import org.apache.flex.utils.FilenameNormalization;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Erik de Bruin
+ * @author Michael Schmalle
+ */
+public class MXMLJSCFlex implements JSCompilerEntryPoint, ProblemQueryProvider,
+ FlexTool
+{
+ @Override
+ public ProblemQuery getProblemQuery()
+ {
+ return problems;
+ }
+
+
+ /*
+ * Exit code enumerations.
+ */
+ static enum ExitCode
+ {
+ SUCCESS(0),
+ PRINT_HELP(1),
+ FAILED_WITH_PROBLEMS(2),
+ FAILED_WITH_ERRORS(3),
+ FAILED_WITH_EXCEPTIONS(4),
+ FAILED_WITH_CONFIG_PROBLEMS(5);
+
+ ExitCode(int code)
+ {
+ this.code = code;
+ }
+
+ final int code;
+ }
+
+ public static MXMLJSC.JSOutputType jsOutputType;
+
+ @Override
+ public String getName()
+ {
+ return FLEX_TOOL_MXMLC;
+ }
+
+ @Override
+ public int execute(String[] args)
+ {
+ final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
+ return mainNoExit(args, problems, true);
+ }
+
+ /**
+ * 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 MXMLJSCFlex mxmlc = new MXMLJSCFlex();
+ 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;
+ }
+
+ protected Workspace workspace;
+ protected FlexJSProject project;
+
+ protected ProblemQuery problems;
+ protected ISourceFileHandler asFileHandler;
+ protected Configuration config;
+ protected Configurator projectConfigurator;
+ private ConfigurationBuffer configBuffer;
+ private ICompilationUnit mainCU;
+ protected ITarget target;
+ protected ITargetSettings targetSettings;
+ protected IJSApplication jsTarget;
+ private IJSPublisher jsPublisher;
+
+ public MXMLJSCFlex()
+ {
+ this(new MXMLFlexJSBackend());
+ }
+
+ public MXMLJSCFlex(IBackend backend)
+ {
+ 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
+ public int mainNoExit(final String[] args, List<ICompilerProblem> problems,
+ Boolean printProblems)
+ {
+ int exitCode = -1;
+ try
+ {
+ exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems);
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.toString());
+ }
+ finally
+ {
+ if (problems != null && !problems.isEmpty())
+ {
+ if (printProblems)
+ {
+ final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter(
+ workspace);
+ final ProblemPrinter printer = new ProblemPrinter(formatter);
+ printer.printProblems(problems);
+ }
+ }
+ }
+ return exitCode;
+ }
+
+ /**
+ * 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);
+
+/* if (outProblems != null && !config.isVerbose())
+ JSSharedData.STDOUT = JSSharedData.STDERR = null;*/
+
+ if (continueCompilation)
+ {
+ project.setProblems(problems.getProblems());
+ compile();
+ if (problems.hasFilteredProblems())
+ {
+ if (problems.hasErrors())
+ exitCode = ExitCode.FAILED_WITH_ERRORS;
+ 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();
+
+ if (outProblems != null && problems.hasFilteredProblems())
+ {
+ for (ICompilerProblem problem : problems.getFilteredProblems())
+ {
+ outProblems.add(problem);
+ }
+ }
+ }
+ return exitCode.code;
+ }
+
+ /**
+ * 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
+ */
+ protected boolean compile()
+ {
+ JSGoogConfiguration googConfiguration = (JSGoogConfiguration) config;
+ boolean compilationSuccess = false;
+
+ try
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ if (!setupTargetFile()) {
+ return false;
+ }
+
+ buildArtifact();
+ }
+ if (jsTarget != null || googConfiguration.getSkipTranspile())
+ {
+ List<ICompilerProblem> errors = new ArrayList<ICompilerProblem>();
+ List<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>();
+
+ if (!config.getCreateTargetWithErrors())
+ {
+ problems.getErrorsAndWarnings(errors, warnings);
+ if (errors.size() > 0)
+ return false;
+ }
+
+ jsPublisher = (IJSPublisher) project.getBackend().createPublisher(
+ project, errors, config);
+
+ File outputFolder = jsPublisher.getOutputFolder();
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
+ ((FlexJSTarget)target).collectMixinMetaData(project.mixinClassNames, reachableCompilationUnits);
+ for (final ICompilationUnit cu : reachableCompilationUnits)
+ {
+ 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);
+
+ System.out.println("Compiling file: " + outputClassFile);
+
+ ICompilationUnit unit = cu;
+
+ IJSWriter writer;
+ if (cuType == ICompilationUnit.UnitType.AS_UNIT)
+ {
+ writer = (IJSWriter) project.getBackend().createWriter(project,
+ errors, unit, false);
+ }
+ else
+ {
+ writer = (IJSWriter) project.getBackend().createMXMLWriter(
+ project, errors, unit, false);
+ }
+
+ BufferedOutputStream out = new BufferedOutputStream(
+ new FileOutputStream(outputClassFile));
+
+ File outputSourceMapFile = null;
+ if (project.config.getSourceMap())
+ {
+ outputSourceMapFile = getOutputSourceMapFile(
+ cu.getQualifiedNames().get(0), outputFolder);
+ }
+
+ writer.writeTo(out, outputSourceMapFile);
+ out.flush();
+ out.close();
+ writer.close();
+ }
+ }
+ }
+
+ if (jsPublisher != null)
+ {
+ compilationSuccess = jsPublisher.publish(problems);
+ }
+ else
+ {
+ compilationSuccess = true;
+ }
+ }
+ }
+ catch (Exception 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
+ */
+ protected void buildArtifact() throws InterruptedException, IOException,
+ ConfigurationException
+ {
+ jsTarget = buildJSTarget();
+ }
+
+ private IJSApplication buildJSTarget() throws InterruptedException,
+ FileNotFoundException, ConfigurationException
+ {
+ final List<ICompilerProblem> problemsBuildingSWF = new ArrayList<ICompilerProblem>();
+
+ project.mainCU = mainCU;
+ final IJSApplication app = buildApplication(project,
+ config.getMainDefinition(), mainCU, 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
+ return config.getOutput();
+ }
+
+ /**
+ * @author Erik de Bruin
+ *
+ * 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.
+ *
+ * @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());
+ }
+
+ /**
+ * @param qname
+ * @param outputFolder
+ * @return output source map file path
+ */
+ private File getOutputSourceMapFile(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() + ".map");
+ }
+
+ /**
+ * 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 OnlyOneSource
+ * @throws InterruptedException
+ */
+ protected boolean setupTargetFile() throws InterruptedException
+ {
+ final String mainFileName = config.getTargetFile();
+
+ final String normalizedMainFileName = FilenameNormalization.normalize(mainFileName);
+
+ final SourceCompilationUnitFactory compilationUnitFactory = project.getSourceCompilationUnitFactory();
+
+ File normalizedMainFile = new File(normalizedMainFileName);
+ if (compilationUnitFactory.canCreateCompilationUnit(normalizedMainFile))
+ {
+ project.addIncludeSourceFile(normalizedMainFile);
+
+ final List<String> sourcePath = config.getCompilerSourcePath();
+ String mainQName = null;
+ if (sourcePath != null && !sourcePath.isEmpty())
+ {
+ for (String path : sourcePath)
+ {
+ final String otherPath = new File(path).getAbsolutePath();
+ if (mainFileName.startsWith(otherPath))
+ {
+ mainQName = mainFileName.substring(otherPath.length() + 1);
+ mainQName = mainQName.replaceAll("\\\\", "/");
+ mainQName = mainQName.replaceAll("\\/", ".");
+ if (mainQName.endsWith(".as"))
+ mainQName = mainQName.substring(0,
+ mainQName.length() - 3);
+ break;
+ }
+ }
+ }
+
+ if (mainQName == null)
+ mainQName = FilenameUtils.getBaseName(mainFileName);
+
+ Collection<ICompilationUnit> mainFileCompilationUnits = workspace.getCompilationUnits(
+ normalizedMainFileName, project);
+
+ mainCU = Iterables.getOnlyElement(mainFileCompilationUnits);
+
+ config.setMainDefinition(mainQName);
+ }
+
+ Preconditions.checkNotNull(mainCU,
+ "Main compilation unit can't be null");
+
+ ITargetSettings settings = getTargetSettings();
+ if (settings != null)
+ project.setTargetSettings(settings);
+
+ target = project.getBackend().createTarget(project,
+ getTargetSettings(), null);
+
+ return true;
+ }
+
+ private ITargetSettings getTargetSettings()
+ {
+ if (targetSettings == null)
+ targetSettings = projectConfigurator.getTargetSettings(null);
+
+ return targetSettings;
+ }
+
+ /**
+ * Create a new Configurator. This method may be overridden to allow
+ * Configurator subclasses to be created that have custom configurations.
+ *
+ * @return a new instance or subclass of {@link Configurator}.
+ */
+ protected Configurator createConfigurator()
+ {
+ return project.getBackend().createConfigurator();
+ }
+
+ /**
+ * Load configurations from all the sources.
+ *
+ * @param args command line arguments
+ * @return True if mxmlc should continue with compilation.
+ */
+ protected boolean configure(final String[] args)
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+ project.configurator = projectConfigurator = createConfigurator();
+
+ try
+ {
+ if (useFlashBuilderProjectFiles(args))
+ {
+ projectConfigurator.setConfiguration(
+ FlashBuilderConfigurator.computeFlashBuilderArgs(args,
+ getTargetType().getExtension()),
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+ else
+ {
+ projectConfigurator.setConfiguration(args,
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+
+ projectConfigurator.applyToProject(project);
+ project.config = (JSGoogConfiguration) projectConfigurator.getConfiguration();
+
+ config = projectConfigurator.getConfiguration();
+ configBuffer = projectConfigurator.getConfigurationBuffer();
+
+ problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings());
+ problems.addAll(projectConfigurator.getConfigurationProblems());
+
+ 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,
+ -1, -1, -1, e.getMessage());
+ problems.add(problem);
+ return false;
+ }
+ finally
+ {
+ if (config == null)
+ {
+ config = new Configuration();
+ configBuffer = new ConfigurationBuffer(Configuration.class,
+ Configuration.getAliases());
+ }
+ }
+ }
+
+ private boolean useFlashBuilderProjectFiles(String[] args)
+ {
+ for (String arg : args)
+ {
+ if (arg.equals("-fb")
+ || arg.equals("-use-flashbuilder-project-files"))
+ return true;
+ }
+ return false;
+ }
+
+ protected TargetType getTargetType()
+ {
+ return TargetType.SWF;
+ }
+
+ /**
+ * Validate target file.
+ *
+ * @throws MustSpecifyTarget
+ * @throws IOError
+ */
+ protected void validateTargetFile() throws ConfigurationException
+ {
+ if (mainCU instanceof ResourceModuleCompilationUnit)
+ return; //when compiling a Resource Module, no target file is defined.
+
+ final String targetFile = config.getTargetFile();
+ if (targetFile == null)
+ throw new ConfigurationException.MustSpecifyTarget(null, null, -1);
+
+ final File file = new File(targetFile);
+ if (!file.exists())
+ throw new ConfigurationException.IOError(targetFile);
+ }
+
+ /**
+ * Wait till the workspace to finish compilation and close.
+ */
+ protected void waitAndClose()
+ {
+ workspace.startIdleState();
+ try
+ {
+ workspace.close();
+ }
+ finally
+ {
+ workspace.endIdleState(Collections.<ICompilerProject, Set<ICompilationUnit>> emptyMap());
+ }
+ }
+
+ /**
+ * Force terminate the compilation process.
+ */
+ protected void close()
+ {
+ workspace.close();
+ }
+
+ public List<String> getSourceList()
+ {
+ ArrayList<String> list = new ArrayList<String>();
+ LinkedList<ICompilerProblem> problemList = new LinkedList<ICompilerProblem>();
+ try
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> units = project.getReachableCompilationUnitsInSWFOrder(roots);
+ for (ICompilationUnit unit : units)
+ {
+ UnitType ut = unit.getCompilationUnitType();
+ if (ut == UnitType.AS_UNIT || ut == UnitType.MXML_UNIT)
+ {
+ list.add(unit.getAbsoluteFilename());
+ }
+ }
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return list;
+ }
+
+ public String getMainSource()
+ {
+ return mainCU.getAbsoluteFilename();
+ }
+
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCFlexCordova.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCFlexCordova.java
new file mode 100644
index 0000000..fe0b16e
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCFlexCordova.java
@@ -0,0 +1,784 @@
+/*
+ *
+ * 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.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemPrinter;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.clients.problems.ProblemQueryProvider;
+import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter;
+import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.config.ConfigurationBuffer;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.config.ICompilerSettingsConstants;
+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.exceptions.ConfigurationException.OnlyOneSource;
+import org.apache.flex.compiler.internal.config.FlashBuilderConfigurator;
+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.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.driver.js.jsc.JSCBackend;
+import org.apache.flex.compiler.internal.driver.js.node.NodeBackend;
+import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSCordovaBackend;
+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.projects.ISourceFileHandler;
+import org.apache.flex.compiler.internal.targets.FlexJSTarget;
+import org.apache.flex.compiler.internal.targets.JSTarget;
+import org.apache.flex.compiler.internal.units.ResourceModuleCompilationUnit;
+import org.apache.flex.compiler.internal.units.SourceCompilationUnitFactory;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.problems.ConfigurationProblem;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.InternalCompilerProblem;
+import org.apache.flex.compiler.problems.UnableToBuildSWFProblem;
+import org.apache.flex.compiler.problems.UnexpectedExceptionProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.targets.ITarget;
+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.compiler.units.ICompilationUnit.UnitType;
+import org.apache.flex.tools.FlexTool;
+import org.apache.flex.utils.ArgumentUtil;
+import org.apache.flex.utils.FilenameNormalization;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Erik de Bruin
+ * @author Michael Schmalle
+ */
+public class MXMLJSCFlexCordova implements JSCompilerEntryPoint, ProblemQueryProvider,
+ FlexTool
+{
+ @Override
+ public ProblemQuery getProblemQuery()
+ {
+ return problems;
+ }
+
+
+ /*
+ * Exit code enumerations.
+ */
+ static enum ExitCode
+ {
+ SUCCESS(0),
+ PRINT_HELP(1),
+ FAILED_WITH_PROBLEMS(2),
+ FAILED_WITH_ERRORS(3),
+ FAILED_WITH_EXCEPTIONS(4),
+ FAILED_WITH_CONFIG_PROBLEMS(5);
+
+ ExitCode(int code)
+ {
+ this.code = code;
+ }
+
+ final int code;
+ }
+
+ public static MXMLJSC.JSOutputType jsOutputType;
+
+ @Override
+ public String getName()
+ {
+ return FLEX_TOOL_MXMLC;
+ }
+
+ @Override
+ public int execute(String[] args)
+ {
+ final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
+ return mainNoExit(args, problems, true);
+ }
+
+ /**
+ * 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 MXMLJSCFlexCordova mxmlc = new MXMLJSCFlexCordova();
+ 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;
+ }
+
+ protected Workspace workspace;
+ protected FlexJSProject project;
+
+ protected ProblemQuery problems;
+ protected ISourceFileHandler asFileHandler;
+ protected Configuration config;
+ protected Configurator projectConfigurator;
+ private ConfigurationBuffer configBuffer;
+ private ICompilationUnit mainCU;
+ protected ITarget target;
+ protected ITargetSettings targetSettings;
+ protected IJSApplication jsTarget;
+ private IJSPublisher jsPublisher;
+
+ public MXMLJSCFlexCordova()
+ {
+ this(new MXMLFlexJSCordovaBackend());
+ }
+
+ public MXMLJSCFlexCordova(IBackend backend)
+ {
+ 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
+ public int mainNoExit(final String[] args, List<ICompilerProblem> problems,
+ Boolean printProblems)
+ {
+ int exitCode = -1;
+ try
+ {
+ exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems);
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.toString());
+ }
+ finally
+ {
+ if (problems != null && !problems.isEmpty())
+ {
+ if (printProblems)
+ {
+ final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter(
+ workspace);
+ final ProblemPrinter printer = new ProblemPrinter(formatter);
+ printer.printProblems(problems);
+ }
+ }
+ }
+ return exitCode;
+ }
+
+ /**
+ * 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);
+
+/* if (outProblems != null && !config.isVerbose())
+ JSSharedData.STDOUT = JSSharedData.STDERR = null;*/
+
+ if (continueCompilation)
+ {
+ project.setProblems(problems.getProblems());
+ compile();
+ if (problems.hasFilteredProblems())
+ {
+ if (problems.hasErrors())
+ exitCode = ExitCode.FAILED_WITH_ERRORS;
+ 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();
+
+ if (outProblems != null && problems.hasFilteredProblems())
+ {
+ for (ICompilerProblem problem : problems.getFilteredProblems())
+ {
+ outProblems.add(problem);
+ }
+ }
+ }
+ return exitCode.code;
+ }
+
+ /**
+ * 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
+ */
+ protected boolean compile()
+ {
+ JSGoogConfiguration googConfiguration = (JSGoogConfiguration) config;
+ boolean compilationSuccess = false;
+
+ try
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ if (!setupTargetFile()) {
+ return false;
+ }
+
+ buildArtifact();
+ }
+ if (jsTarget != null || googConfiguration.getSkipTranspile())
+ {
+ List<ICompilerProblem> errors = new ArrayList<ICompilerProblem>();
+ List<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>();
+
+ if (!config.getCreateTargetWithErrors())
+ {
+ problems.getErrorsAndWarnings(errors, warnings);
+ if (errors.size() > 0)
+ return false;
+ }
+
+ jsPublisher = (IJSPublisher) project.getBackend().createPublisher(
+ project, errors, config);
+
+ File outputFolder = jsPublisher.getOutputFolder();
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
+ ((FlexJSTarget)target).collectMixinMetaData(project.mixinClassNames, reachableCompilationUnits);
+ for (final ICompilationUnit cu : reachableCompilationUnits)
+ {
+ 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);
+
+ System.out.println("Compiling file: " + outputClassFile);
+
+ ICompilationUnit unit = cu;
+
+ IJSWriter writer;
+ if (cuType == ICompilationUnit.UnitType.AS_UNIT)
+ {
+ writer = (IJSWriter) project.getBackend().createWriter(project,
+ errors, unit, false);
+ }
+ else
+ {
+ writer = (IJSWriter) project.getBackend().createMXMLWriter(
+ project, errors, unit, false);
+ }
+
+ BufferedOutputStream out = new BufferedOutputStream(
+ new FileOutputStream(outputClassFile));
+
+ File outputSourceMapFile = null;
+ if (project.config.getSourceMap())
+ {
+ outputSourceMapFile = getOutputSourceMapFile(
+ cu.getQualifiedNames().get(0), outputFolder);
+ }
+
+ writer.writeTo(out, outputSourceMapFile);
+ out.flush();
+ out.close();
+ writer.close();
+ }
+ }
+ }
+
+ if (jsPublisher != null)
+ {
+ compilationSuccess = jsPublisher.publish(problems);
+ }
+ else
+ {
+ compilationSuccess = true;
+ }
+ }
+ }
+ catch (Exception 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
+ */
+ protected void buildArtifact() throws InterruptedException, IOException,
+ ConfigurationException
+ {
+ jsTarget = buildJSTarget();
+ }
+
+ private IJSApplication buildJSTarget() throws InterruptedException,
+ FileNotFoundException, ConfigurationException
+ {
+ final List<ICompilerProblem> problemsBuildingSWF = new ArrayList<ICompilerProblem>();
+
+ project.mainCU = mainCU;
+ final IJSApplication app = buildApplication(project,
+ config.getMainDefinition(), mainCU, 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
+ return config.getOutput();
+ }
+
+ /**
+ * @author Erik de Bruin
+ *
+ * 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.
+ *
+ * @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());
+ }
+
+ /**
+ * @param qname
+ * @param outputFolder
+ * @return output source map file path
+ */
+ private File getOutputSourceMapFile(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() + ".map");
+ }
+
+ /**
+ * 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 OnlyOneSource
+ * @throws InterruptedException
+ */
+ protected boolean setupTargetFile() throws InterruptedException
+ {
+ final String mainFileName = config.getTargetFile();
+
+ final String normalizedMainFileName = FilenameNormalization.normalize(mainFileName);
+
+ final SourceCompilationUnitFactory compilationUnitFactory = project.getSourceCompilationUnitFactory();
+
+ File normalizedMainFile = new File(normalizedMainFileName);
+ if (compilationUnitFactory.canCreateCompilationUnit(normalizedMainFile))
+ {
+ project.addIncludeSourceFile(normalizedMainFile);
+
+ final List<String> sourcePath = config.getCompilerSourcePath();
+ String mainQName = null;
+ if (sourcePath != null && !sourcePath.isEmpty())
+ {
+ for (String path : sourcePath)
+ {
+ final String otherPath = new File(path).getAbsolutePath();
+ if (mainFileName.startsWith(otherPath))
+ {
+ mainQName = mainFileName.substring(otherPath.length() + 1);
+ mainQName = mainQName.replaceAll("\\\\", "/");
+ mainQName = mainQName.replaceAll("\\/", ".");
+ if (mainQName.endsWith(".as"))
+ mainQName = mainQName.substring(0,
+ mainQName.length() - 3);
+ break;
+ }
+ }
+ }
+
+ if (mainQName == null)
+ mainQName = FilenameUtils.getBaseName(mainFileName);
+
+ Collection<ICompilationUnit> mainFileCompilationUnits = workspace.getCompilationUnits(
+ normalizedMainFileName, project);
+
+ mainCU = Iterables.getOnlyElement(mainFileCompilationUnits);
+
+ config.setMainDefinition(mainQName);
+ }
+
+ Preconditions.checkNotNull(mainCU,
+ "Main compilation unit can't be null");
+
+ ITargetSettings settings = getTargetSettings();
+ if (settings != null)
+ project.setTargetSettings(settings);
+
+ target = project.getBackend().createTarget(project,
+ getTargetSettings(), null);
+
+ return true;
+ }
+
+ private ITargetSettings getTargetSettings()
+ {
+ if (targetSettings == null)
+ targetSettings = projectConfigurator.getTargetSettings(null);
+
+ return targetSettings;
+ }
+
+ /**
+ * Create a new Configurator. This method may be overridden to allow
+ * Configurator subclasses to be created that have custom configurations.
+ *
+ * @return a new instance or subclass of {@link Configurator}.
+ */
+ protected Configurator createConfigurator()
+ {
+ return project.getBackend().createConfigurator();
+ }
+
+ /**
+ * Load configurations from all the sources.
+ *
+ * @param args command line arguments
+ * @return True if mxmlc should continue with compilation.
+ */
+ protected boolean configure(final String[] args)
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+ project.configurator = projectConfigurator = createConfigurator();
+
+ try
+ {
+ if (useFlashBuilderProjectFiles(args))
+ {
+ projectConfigurator.setConfiguration(
+ FlashBuilderConfigurator.computeFlashBuilderArgs(args,
+ getTargetType().getExtension()),
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+ else
+ {
+ projectConfigurator.setConfiguration(args,
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+
+ projectConfigurator.applyToProject(project);
+ project.config = (JSGoogConfiguration) projectConfigurator.getConfiguration();
+
+ config = projectConfigurator.getConfiguration();
+ configBuffer = projectConfigurator.getConfigurationBuffer();
+
+ problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings());
+ problems.addAll(projectConfigurator.getConfigurationProblems());
+
+ 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,
+ -1, -1, -1, e.getMessage());
+ problems.add(problem);
+ return false;
+ }
+ finally
+ {
+ if (config == null)
+ {
+ config = new Configuration();
+ configBuffer = new ConfigurationBuffer(Configuration.class,
+ Configuration.getAliases());
+ }
+ }
+ }
+
+ private boolean useFlashBuilderProjectFiles(String[] args)
+ {
+ for (String arg : args)
+ {
+ if (arg.equals("-fb")
+ || arg.equals("-use-flashbuilder-project-files"))
+ return true;
+ }
+ return false;
+ }
+
+ protected TargetType getTargetType()
+ {
+ return TargetType.SWF;
+ }
+
+ /**
+ * Validate target file.
+ *
+ * @throws MustSpecifyTarget
+ * @throws IOError
+ */
+ protected void validateTargetFile() throws ConfigurationException
+ {
+ if (mainCU instanceof ResourceModuleCompilationUnit)
+ return; //when compiling a Resource Module, no target file is defined.
+
+ final String targetFile = config.getTargetFile();
+ if (targetFile == null)
+ throw new ConfigurationException.MustSpecifyTarget(null, null, -1);
+
+ final File file = new File(targetFile);
+ if (!file.exists())
+ throw new ConfigurationException.IOError(targetFile);
+ }
+
+ /**
+ * Wait till the workspace to finish compilation and close.
+ */
+ protected void waitAndClose()
+ {
+ workspace.startIdleState();
+ try
+ {
+ workspace.close();
+ }
+ finally
+ {
+ workspace.endIdleState(Collections.<ICompilerProject, Set<ICompilationUnit>> emptyMap());
+ }
+ }
+
+ /**
+ * Force terminate the compilation process.
+ */
+ protected void close()
+ {
+ workspace.close();
+ }
+
+ public List<String> getSourceList()
+ {
+ ArrayList<String> list = new ArrayList<String>();
+ LinkedList<ICompilerProblem> problemList = new LinkedList<ICompilerProblem>();
+ try
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> units = project.getReachableCompilationUnitsInSWFOrder(roots);
+ for (ICompilationUnit unit : units)
+ {
+ UnitType ut = unit.getCompilationUnitType();
+ if (ut == UnitType.AS_UNIT || ut == UnitType.MXML_UNIT)
+ {
+ list.add(unit.getAbsoluteFilename());
+ }
+ }
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return list;
+ }
+
+ public String getMainSource()
+ {
+ return mainCU.getAbsoluteFilename();
+ }
+
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCNative.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCNative.java
new file mode 100644
index 0000000..2a33277
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCNative.java
@@ -0,0 +1,779 @@
+/*
+ *
+ * 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.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemPrinter;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.clients.problems.ProblemQueryProvider;
+import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter;
+import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.config.ConfigurationBuffer;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.config.ICompilerSettingsConstants;
+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.exceptions.ConfigurationException.OnlyOneSource;
+import org.apache.flex.compiler.internal.config.FlashBuilderConfigurator;
+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.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.driver.js.jsc.JSCBackend;
+import org.apache.flex.compiler.internal.driver.js.node.NodeBackend;
+import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSBackend;
+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.projects.ISourceFileHandler;
+import org.apache.flex.compiler.internal.targets.FlexJSTarget;
+import org.apache.flex.compiler.internal.targets.JSTarget;
+import org.apache.flex.compiler.internal.units.ResourceModuleCompilationUnit;
+import org.apache.flex.compiler.internal.units.SourceCompilationUnitFactory;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.problems.ConfigurationProblem;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.InternalCompilerProblem;
+import org.apache.flex.compiler.problems.UnableToBuildSWFProblem;
+import org.apache.flex.compiler.problems.UnexpectedExceptionProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.targets.ITarget;
+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.compiler.units.ICompilationUnit.UnitType;
+import org.apache.flex.tools.FlexTool;
+import org.apache.flex.utils.ArgumentUtil;
+import org.apache.flex.utils.FilenameNormalization;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Erik de Bruin
+ * @author Michael Schmalle
+ */
+public class MXMLJSCNative implements JSCompilerEntryPoint, ProblemQueryProvider,
+ FlexTool
+{
+ @Override
+ public ProblemQuery getProblemQuery()
+ {
+ return problems;
+ }
+
+
+ /*
+ * Exit code enumerations.
+ */
+ static enum ExitCode
+ {
+ SUCCESS(0),
+ PRINT_HELP(1),
+ FAILED_WITH_PROBLEMS(2),
+ FAILED_WITH_ERRORS(3),
+ FAILED_WITH_EXCEPTIONS(4),
+ FAILED_WITH_CONFIG_PROBLEMS(5);
+
+ ExitCode(int code)
+ {
+ this.code = code;
+ }
+
+ final int code;
+ }
+
+ @Override
+ public String getName()
+ {
+ return FLEX_TOOL_MXMLC;
+ }
+
+ @Override
+ public int execute(String[] args)
+ {
+ final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
+ return mainNoExit(args, problems, true);
+ }
+
+ /**
+ * 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 MXMLJSCNative mxmlc = new MXMLJSCNative();
+ 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;
+ }
+
+ protected Workspace workspace;
+ protected FlexJSProject project;
+
+ protected ProblemQuery problems;
+ protected ISourceFileHandler asFileHandler;
+ protected Configuration config;
+ protected Configurator projectConfigurator;
+ private ConfigurationBuffer configBuffer;
+ private ICompilationUnit mainCU;
+ protected ITarget target;
+ protected ITargetSettings targetSettings;
+ protected IJSApplication jsTarget;
+ private IJSPublisher jsPublisher;
+
+ public MXMLJSCNative()
+ {
+ IBackend backend = new JSCBackend();
+
+ 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
+ public int mainNoExit(final String[] args, List<ICompilerProblem> problems,
+ Boolean printProblems)
+ {
+ int exitCode = -1;
+ try
+ {
+ exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems);
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.toString());
+ }
+ finally
+ {
+ if (problems != null && !problems.isEmpty())
+ {
+ if (printProblems)
+ {
+ final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter(
+ workspace);
+ final ProblemPrinter printer = new ProblemPrinter(formatter);
+ printer.printProblems(problems);
+ }
+ }
+ }
+ return exitCode;
+ }
+
+ /**
+ * 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);
+
+/* if (outProblems != null && !config.isVerbose())
+ JSSharedData.STDOUT = JSSharedData.STDERR = null;*/
+
+ if (continueCompilation)
+ {
+ project.setProblems(problems.getProblems());
+ compile();
+ if (problems.hasFilteredProblems())
+ {
+ if (problems.hasErrors())
+ exitCode = ExitCode.FAILED_WITH_ERRORS;
+ 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();
+
+ if (outProblems != null && problems.hasFilteredProblems())
+ {
+ for (ICompilerProblem problem : problems.getFilteredProblems())
+ {
+ outProblems.add(problem);
+ }
+ }
+ }
+ return exitCode.code;
+ }
+
+ /**
+ * 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
+ */
+ protected boolean compile()
+ {
+ JSGoogConfiguration googConfiguration = (JSGoogConfiguration) config;
+ boolean compilationSuccess = false;
+
+ try
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ if (!setupTargetFile()) {
+ return false;
+ }
+
+ buildArtifact();
+ }
+ if (jsTarget != null || googConfiguration.getSkipTranspile())
+ {
+ List<ICompilerProblem> errors = new ArrayList<ICompilerProblem>();
+ List<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>();
+
+ if (!config.getCreateTargetWithErrors())
+ {
+ problems.getErrorsAndWarnings(errors, warnings);
+ if (errors.size() > 0)
+ return false;
+ }
+
+ jsPublisher = (IJSPublisher) project.getBackend().createPublisher(
+ project, errors, config);
+
+ File outputFolder = jsPublisher.getOutputFolder();
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
+ ((FlexJSTarget)target).collectMixinMetaData(project.mixinClassNames, reachableCompilationUnits);
+ for (final ICompilationUnit cu : reachableCompilationUnits)
+ {
+ 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);
+
+ System.out.println("Compiling file: " + outputClassFile);
+
+ ICompilationUnit unit = cu;
+
+ IJSWriter writer;
+ if (cuType == ICompilationUnit.UnitType.AS_UNIT)
+ {
+ writer = (IJSWriter) project.getBackend().createWriter(project,
+ errors, unit, false);
+ }
+ else
+ {
+ writer = (IJSWriter) project.getBackend().createMXMLWriter(
+ project, errors, unit, false);
+ }
+
+ BufferedOutputStream out = new BufferedOutputStream(
+ new FileOutputStream(outputClassFile));
+
+ File outputSourceMapFile = null;
+ if (project.config.getSourceMap())
+ {
+ outputSourceMapFile = getOutputSourceMapFile(
+ cu.getQualifiedNames().get(0), outputFolder);
+ }
+
+ writer.writeTo(out, outputSourceMapFile);
+ out.flush();
+ out.close();
+ writer.close();
+ }
+ }
+ }
+
+ if (jsPublisher != null)
+ {
+ compilationSuccess = jsPublisher.publish(problems);
+ }
+ else
+ {
+ compilationSuccess = true;
+ }
+ }
+ }
+ catch (Exception 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
+ */
+ protected void buildArtifact() throws InterruptedException, IOException,
+ ConfigurationException
+ {
+ jsTarget = buildJSTarget();
+ }
+
+ private IJSApplication buildJSTarget() throws InterruptedException,
+ FileNotFoundException, ConfigurationException
+ {
+ final List<ICompilerProblem> problemsBuildingSWF = new ArrayList<ICompilerProblem>();
+
+ project.mainCU = mainCU;
+ final IJSApplication app = buildApplication(project,
+ config.getMainDefinition(), mainCU, 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
+ return config.getOutput();
+ }
+
+ /**
+ * @author Erik de Bruin
+ *
+ * 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.
+ *
+ * @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());
+ }
+
+ /**
+ * @param qname
+ * @param outputFolder
+ * @return output source map file path
+ */
+ private File getOutputSourceMapFile(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() + ".map");
+ }
+
+ /**
+ * 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 OnlyOneSource
+ * @throws InterruptedException
+ */
+ protected boolean setupTargetFile() throws InterruptedException
+ {
+ final String mainFileName = config.getTargetFile();
+
+ final String normalizedMainFileName = FilenameNormalization.normalize(mainFileName);
+
+ final SourceCompilationUnitFactory compilationUnitFactory = project.getSourceCompilationUnitFactory();
+
+ File normalizedMainFile = new File(normalizedMainFileName);
+ if (compilationUnitFactory.canCreateCompilationUnit(normalizedMainFile))
+ {
+ project.addIncludeSourceFile(normalizedMainFile);
+
+ final List<String> sourcePath = config.getCompilerSourcePath();
+ String mainQName = null;
+ if (sourcePath != null && !sourcePath.isEmpty())
+ {
+ for (String path : sourcePath)
+ {
+ final String otherPath = new File(path).getAbsolutePath();
+ if (mainFileName.startsWith(otherPath))
+ {
+ mainQName = mainFileName.substring(otherPath.length() + 1);
+ mainQName = mainQName.replaceAll("\\\\", "/");
+ mainQName = mainQName.replaceAll("\\/", ".");
+ if (mainQName.endsWith(".as"))
+ mainQName = mainQName.substring(0,
+ mainQName.length() - 3);
+ break;
+ }
+ }
+ }
+
+ if (mainQName == null)
+ mainQName = FilenameUtils.getBaseName(mainFileName);
+
+ Collection<ICompilationUnit> mainFileCompilationUnits = workspace.getCompilationUnits(
+ normalizedMainFileName, project);
+
+ mainCU = Iterables.getOnlyElement(mainFileCompilationUnits);
+
+ config.setMainDefinition(mainQName);
+ }
+
+ Preconditions.checkNotNull(mainCU,
+ "Main compilation unit can't be null");
+
+ ITargetSettings settings = getTargetSettings();
+ if (settings != null)
+ project.setTargetSettings(settings);
+
+ target = project.getBackend().createTarget(project,
+ getTargetSettings(), null);
+
+ return true;
+ }
+
+ private ITargetSettings getTargetSettings()
+ {
+ if (targetSettings == null)
+ targetSettings = projectConfigurator.getTargetSettings(null);
+
+ return targetSettings;
+ }
+
+ /**
+ * Create a new Configurator. This method may be overridden to allow
+ * Configurator subclasses to be created that have custom configurations.
+ *
+ * @return a new instance or subclass of {@link Configurator}.
+ */
+ protected Configurator createConfigurator()
+ {
+ return project.getBackend().createConfigurator();
+ }
+
+ /**
+ * Load configurations from all the sources.
+ *
+ * @param args command line arguments
+ * @return True if mxmlc should continue with compilation.
+ */
+ protected boolean configure(final String[] args)
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+ project.configurator = projectConfigurator = createConfigurator();
+
+ try
+ {
+ if (useFlashBuilderProjectFiles(args))
+ {
+ projectConfigurator.setConfiguration(
+ FlashBuilderConfigurator.computeFlashBuilderArgs(args,
+ getTargetType().getExtension()),
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+ else
+ {
+ projectConfigurator.setConfiguration(args,
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+
+ projectConfigurator.applyToProject(project);
+ project.config = (JSGoogConfiguration) projectConfigurator.getConfiguration();
+
+ config = projectConfigurator.getConfiguration();
+ configBuffer = projectConfigurator.getConfigurationBuffer();
+
+ problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings());
+ problems.addAll(projectConfigurator.getConfigurationProblems());
+
+ 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,
+ -1, -1, -1, e.getMessage());
+ problems.add(problem);
+ return false;
+ }
+ finally
+ {
+ if (config == null)
+ {
+ config = new Configuration();
+ configBuffer = new ConfigurationBuffer(Configuration.class,
+ Configuration.getAliases());
+ }
+ }
+ }
+
+ private boolean useFlashBuilderProjectFiles(String[] args)
+ {
+ for (String arg : args)
+ {
+ if (arg.equals("-fb")
+ || arg.equals("-use-flashbuilder-project-files"))
+ return true;
+ }
+ return false;
+ }
+
+ protected TargetType getTargetType()
+ {
+ return TargetType.SWF;
+ }
+
+ /**
+ * Validate target file.
+ *
+ * @throws MustSpecifyTarget
+ * @throws IOError
+ */
+ protected void validateTargetFile() throws ConfigurationException
+ {
+ if (mainCU instanceof ResourceModuleCompilationUnit)
+ return; //when compiling a Resource Module, no target file is defined.
+
+ final String targetFile = config.getTargetFile();
+ if (targetFile == null)
+ throw new ConfigurationException.MustSpecifyTarget(null, null, -1);
+
+ final File file = new File(targetFile);
+ if (!file.exists())
+ throw new ConfigurationException.IOError(targetFile);
+ }
+
+ /**
+ * Wait till the workspace to finish compilation and close.
+ */
+ protected void waitAndClose()
+ {
+ workspace.startIdleState();
+ try
+ {
+ workspace.close();
+ }
+ finally
+ {
+ workspace.endIdleState(Collections.<ICompilerProject, Set<ICompilationUnit>> emptyMap());
+ }
+ }
+
+ /**
+ * Force terminate the compilation process.
+ */
+ protected void close()
+ {
+ workspace.close();
+ }
+
+ public List<String> getSourceList()
+ {
+ ArrayList<String> list = new ArrayList<String>();
+ LinkedList<ICompilerProblem> problemList = new LinkedList<ICompilerProblem>();
+ try
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> units = project.getReachableCompilationUnitsInSWFOrder(roots);
+ for (ICompilationUnit unit : units)
+ {
+ UnitType ut = unit.getCompilationUnitType();
+ if (ut == UnitType.AS_UNIT || ut == UnitType.MXML_UNIT)
+ {
+ list.add(unit.getAbsoluteFilename());
+ }
+ }
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return list;
+ }
+
+ public String getMainSource()
+ {
+ return mainCU.getAbsoluteFilename();
+ }
+
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCNode.java b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCNode.java
new file mode 100644
index 0000000..49a4013
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/MXMLJSCNode.java
@@ -0,0 +1,777 @@
+/*
+ *
+ * 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.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemPrinter;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.clients.problems.ProblemQueryProvider;
+import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter;
+import org.apache.flex.compiler.codegen.js.IJSPublisher;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.config.ConfigurationBuffer;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.config.ICompilerSettingsConstants;
+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.exceptions.ConfigurationException.OnlyOneSource;
+import org.apache.flex.compiler.internal.config.FlashBuilderConfigurator;
+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.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.driver.js.jsc.JSCBackend;
+import org.apache.flex.compiler.internal.driver.js.node.NodeBackend;
+import org.apache.flex.compiler.internal.driver.mxml.flexjs.MXMLFlexJSBackend;
+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.projects.ISourceFileHandler;
+import org.apache.flex.compiler.internal.targets.FlexJSTarget;
+import org.apache.flex.compiler.internal.targets.JSTarget;
+import org.apache.flex.compiler.internal.units.ResourceModuleCompilationUnit;
+import org.apache.flex.compiler.internal.units.SourceCompilationUnitFactory;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.problems.ConfigurationProblem;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.InternalCompilerProblem;
+import org.apache.flex.compiler.problems.UnableToBuildSWFProblem;
+import org.apache.flex.compiler.problems.UnexpectedExceptionProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.targets.ITarget;
+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.compiler.units.ICompilationUnit.UnitType;
+import org.apache.flex.tools.FlexTool;
+import org.apache.flex.utils.ArgumentUtil;
+import org.apache.flex.utils.FilenameNormalization;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Erik de Bruin
+ * @author Michael Schmalle
+ */
+public class MXMLJSCNode implements JSCompilerEntryPoint, ProblemQueryProvider,
+ FlexTool
+{
+ @Override
+ public ProblemQuery getProblemQuery()
+ {
+ return problems;
+ }
+
+ /*
+ * Exit code enumerations.
+ */
+ static enum ExitCode
+ {
+ SUCCESS(0),
+ PRINT_HELP(1),
+ FAILED_WITH_PROBLEMS(2),
+ FAILED_WITH_ERRORS(3),
+ FAILED_WITH_EXCEPTIONS(4),
+ FAILED_WITH_CONFIG_PROBLEMS(5);
+
+ ExitCode(int code)
+ {
+ this.code = code;
+ }
+
+ final int code;
+ }
+
+ @Override
+ public String getName()
+ {
+ return FLEX_TOOL_MXMLC;
+ }
+
+ @Override
+ public int execute(String[] args)
+ {
+ final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
+ return mainNoExit(args, problems, true);
+ }
+
+ /**
+ * 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 MXMLJSCNode mxmlc = new MXMLJSCNode();
+ 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;
+ }
+
+ protected Workspace workspace;
+ protected FlexJSProject project;
+
+ protected ProblemQuery problems;
+ protected ISourceFileHandler asFileHandler;
+ protected Configuration config;
+ protected Configurator projectConfigurator;
+ private ConfigurationBuffer configBuffer;
+ private ICompilationUnit mainCU;
+ protected ITarget target;
+ protected ITargetSettings targetSettings;
+ protected IJSApplication jsTarget;
+ private IJSPublisher jsPublisher;
+
+ public MXMLJSCNode()
+ {
+ IBackend backend = new NodeBackend();
+ 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
+ public int mainNoExit(final String[] args, List<ICompilerProblem> problems,
+ Boolean printProblems)
+ {
+ int exitCode = -1;
+ try
+ {
+ exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems);
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.toString());
+ }
+ finally
+ {
+ if (problems != null && !problems.isEmpty())
+ {
+ if (printProblems)
+ {
+ final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter(
+ workspace);
+ final ProblemPrinter printer = new ProblemPrinter(formatter);
+ printer.printProblems(problems);
+ }
+ }
+ }
+ return exitCode;
+ }
+
+ /**
+ * 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);
+
+/* if (outProblems != null && !config.isVerbose())
+ JSSharedData.STDOUT = JSSharedData.STDERR = null;*/
+
+ if (continueCompilation)
+ {
+ project.setProblems(problems.getProblems());
+ compile();
+ if (problems.hasFilteredProblems())
+ {
+ if (problems.hasErrors())
+ exitCode = ExitCode.FAILED_WITH_ERRORS;
+ 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();
+
+ if (outProblems != null && problems.hasFilteredProblems())
+ {
+ for (ICompilerProblem problem : problems.getFilteredProblems())
+ {
+ outProblems.add(problem);
+ }
+ }
+ }
+ return exitCode.code;
+ }
+
+ /**
+ * 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
+ */
+ protected boolean compile()
+ {
+ JSGoogConfiguration googConfiguration = (JSGoogConfiguration) config;
+ boolean compilationSuccess = false;
+
+ try
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ if (!setupTargetFile()) {
+ return false;
+ }
+
+ buildArtifact();
+ }
+ if (jsTarget != null || googConfiguration.getSkipTranspile())
+ {
+ List<ICompilerProblem> errors = new ArrayList<ICompilerProblem>();
+ List<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>();
+
+ if (!config.getCreateTargetWithErrors())
+ {
+ problems.getErrorsAndWarnings(errors, warnings);
+ if (errors.size() > 0)
+ return false;
+ }
+
+ jsPublisher = (IJSPublisher) project.getBackend().createPublisher(
+ project, errors, config);
+
+ File outputFolder = jsPublisher.getOutputFolder();
+
+ if (!googConfiguration.getSkipTranspile())
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
+ ((FlexJSTarget)target).collectMixinMetaData(project.mixinClassNames, reachableCompilationUnits);
+ for (final ICompilationUnit cu : reachableCompilationUnits)
+ {
+ 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);
+
+ System.out.println("Compiling file: " + outputClassFile);
+
+ ICompilationUnit unit = cu;
+
+ IJSWriter writer;
+ if (cuType == ICompilationUnit.UnitType.AS_UNIT)
+ {
+ writer = (IJSWriter) project.getBackend().createWriter(project,
+ errors, unit, false);
+ }
+ else
+ {
+ writer = (IJSWriter) project.getBackend().createMXMLWriter(
+ project, errors, unit, false);
+ }
+
+ BufferedOutputStream out = new BufferedOutputStream(
+ new FileOutputStream(outputClassFile));
+
+ File outputSourceMapFile = null;
+ if (project.config.getSourceMap())
+ {
+ outputSourceMapFile = getOutputSourceMapFile(
+ cu.getQualifiedNames().get(0), outputFolder);
+ }
+
+ writer.writeTo(out, outputSourceMapFile);
+ out.flush();
+ out.close();
+ writer.close();
+ }
+ }
+ }
+
+ if (jsPublisher != null)
+ {
+ compilationSuccess = jsPublisher.publish(problems);
+ }
+ else
+ {
+ compilationSuccess = true;
+ }
+ }
+ }
+ catch (Exception 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
+ */
+ protected void buildArtifact() throws InterruptedException, IOException,
+ ConfigurationException
+ {
+ jsTarget = buildJSTarget();
+ }
+
+ private IJSApplication buildJSTarget() throws InterruptedException,
+ FileNotFoundException, ConfigurationException
+ {
+ final List<ICompilerProblem> problemsBuildingSWF = new ArrayList<ICompilerProblem>();
+
+ project.mainCU = mainCU;
+ final IJSApplication app = buildApplication(project,
+ config.getMainDefinition(), mainCU, 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
+ return config.getOutput();
+ }
+
+ /**
+ * @author Erik de Bruin
+ *
+ * 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.
+ *
+ * @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());
+ }
+
+ /**
+ * @param qname
+ * @param outputFolder
+ * @return output source map file path
+ */
+ private File getOutputSourceMapFile(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() + ".map");
+ }
+
+ /**
+ * 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 OnlyOneSource
+ * @throws InterruptedException
+ */
+ protected boolean setupTargetFile() throws InterruptedException
+ {
+ final String mainFileName = config.getTargetFile();
+
+ final String normalizedMainFileName = FilenameNormalization.normalize(mainFileName);
+
+ final SourceCompilationUnitFactory compilationUnitFactory = project.getSourceCompilationUnitFactory();
+
+ File normalizedMainFile = new File(normalizedMainFileName);
+ if (compilationUnitFactory.canCreateCompilationUnit(normalizedMainFile))
+ {
+ project.addIncludeSourceFile(normalizedMainFile);
+
+ final List<String> sourcePath = config.getCompilerSourcePath();
+ String mainQName = null;
+ if (sourcePath != null && !sourcePath.isEmpty())
+ {
+ for (String path : sourcePath)
+ {
+ final String otherPath = new File(path).getAbsolutePath();
+ if (mainFileName.startsWith(otherPath))
+ {
+ mainQName = mainFileName.substring(otherPath.length() + 1);
+ mainQName = mainQName.replaceAll("\\\\", "/");
+ mainQName = mainQName.replaceAll("\\/", ".");
+ if (mainQName.endsWith(".as"))
+ mainQName = mainQName.substring(0,
+ mainQName.length() - 3);
+ break;
+ }
+ }
+ }
+
+ if (mainQName == null)
+ mainQName = FilenameUtils.getBaseName(mainFileName);
+
+ Collection<ICompilationUnit> mainFileCompilationUnits = workspace.getCompilationUnits(
+ normalizedMainFileName, project);
+
+ mainCU = Iterables.getOnlyElement(mainFileCompilationUnits);
+
+ config.setMainDefinition(mainQName);
+ }
+
+ Preconditions.checkNotNull(mainCU,
+ "Main compilation unit can't be null");
+
+ ITargetSettings settings = getTargetSettings();
+ if (settings != null)
+ project.setTargetSettings(settings);
+
+ target = project.getBackend().createTarget(project,
+ getTargetSettings(), null);
+
+ return true;
+ }
+
+ private ITargetSettings getTargetSettings()
+ {
+ if (targetSettings == null)
+ targetSettings = projectConfigurator.getTargetSettings(null);
+
+ return targetSettings;
+ }
+
+ /**
+ * Create a new Configurator. This method may be overridden to allow
+ * Configurator subclasses to be created that have custom configurations.
+ *
+ * @return a new instance or subclass of {@link Configurator}.
+ */
+ protected Configurator createConfigurator()
+ {
+ return project.getBackend().createConfigurator();
+ }
+
+ /**
+ * Load configurations from all the sources.
+ *
+ * @param args command line arguments
+ * @return True if mxmlc should continue with compilation.
+ */
+ protected boolean configure(final String[] args)
+ {
+ project.getSourceCompilationUnitFactory().addHandler(asFileHandler);
+ project.configurator = projectConfigurator = createConfigurator();
+
+ try
+ {
+ if (useFlashBuilderProjectFiles(args))
+ {
+ projectConfigurator.setConfiguration(
+ FlashBuilderConfigurator.computeFlashBuilderArgs(args,
+ getTargetType().getExtension()),
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+ else
+ {
+ projectConfigurator.setConfiguration(args,
+ ICompilerSettingsConstants.FILE_SPECS_VAR);
+ }
+
+ projectConfigurator.applyToProject(project);
+ project.config = (JSGoogConfiguration) projectConfigurator.getConfiguration();
+
+ config = projectConfigurator.getConfiguration();
+ configBuffer = projectConfigurator.getConfigurationBuffer();
+
+ problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings());
+ problems.addAll(projectConfigurator.getConfigurationProblems());
+
+ 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,
+ -1, -1, -1, e.getMessage());
+ problems.add(problem);
+ return false;
+ }
+ finally
+ {
+ if (config == null)
+ {
+ config = new Configuration();
+ configBuffer = new ConfigurationBuffer(Configuration.class,
+ Configuration.getAliases());
+ }
+ }
+ }
+
+ private boolean useFlashBuilderProjectFiles(String[] args)
+ {
+ for (String arg : args)
+ {
+ if (arg.equals("-fb")
+ || arg.equals("-use-flashbuilder-project-files"))
+ return true;
+ }
+ return false;
+ }
+
+ protected TargetType getTargetType()
+ {
+ return TargetType.SWF;
+ }
+
+ /**
+ * Validate target file.
+ *
+ * @throws MustSpecifyTarget
+ * @throws IOError
+ */
+ protected void validateTargetFile() throws ConfigurationException
+ {
+ if (mainCU instanceof ResourceModuleCompilationUnit)
+ return; //when compiling a Resource Module, no target file is defined.
+
+ final String targetFile = config.getTargetFile();
+ if (targetFile == null)
+ throw new ConfigurationException.MustSpecifyTarget(null, null, -1);
+
+ final File file = new File(targetFile);
+ if (!file.exists())
+ throw new ConfigurationException.IOError(targetFile);
+ }
+
+ /**
+ * Wait till the workspace to finish compilation and close.
+ */
+ protected void waitAndClose()
+ {
+ workspace.startIdleState();
+ try
+ {
+ workspace.close();
+ }
+ finally
+ {
+ workspace.endIdleState(Collections.<ICompilerProject, Set<ICompilationUnit>> emptyMap());
+ }
+ }
+
+ /**
+ * Force terminate the compilation process.
+ */
+ protected void close()
+ {
+ workspace.close();
+ }
+
+ public List<String> getSourceList()
+ {
+ ArrayList<String> list = new ArrayList<String>();
+ LinkedList<ICompilerProblem> problemList = new LinkedList<ICompilerProblem>();
+ try
+ {
+ ArrayList<ICompilationUnit> roots = new ArrayList<ICompilationUnit>();
+ roots.add(mainCU);
+ Set<ICompilationUnit> incs = target.getIncludesCompilationUnits();
+ roots.addAll(incs);
+ project.mixinClassNames = new TreeSet<String>();
+ List<ICompilationUnit> units = project.getReachableCompilationUnitsInSWFOrder(roots);
+ for (ICompilationUnit unit : units)
+ {
+ UnitType ut = unit.getCompilationUnitType();
+ if (ut == UnitType.AS_UNIT || ut == UnitType.MXML_UNIT)
+ {
+ list.add(unit.getAbsoluteFilename());
+ }
+ }
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ return list;
+ }
+
+ public String getMainSource()
+ {
+ return mainCU.getAbsoluteFilename();
+ }
+
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
index 23c5fa1..1afe68f 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/goog/JSGoogPublisher.java
@@ -132,12 +132,12 @@
// XXX (mschmalle) until we figure out what is going on with this configuration, just skip
// HTML generation for JSC output type
- String outputType = googConfiguration.getJSOutputType();
- if (!outputType.equals(JSOutputType.JSC.getText()))
- {
+ //String outputType = googConfiguration.getJSOutputType();
+ //if (!outputType.equals(JSOutputType.JSC.getText()))
+ //{
writeHTML("intermediate", projectName, intermediateDirPath);
writeHTML("release", projectName, releaseDirPath);
- }
+ //}
ArrayList<String> optionList = new ArrayList<String>();
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSCordovaPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSCordovaPublisher.java
new file mode 100644
index 0000000..6196c44
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSCordovaPublisher.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.internal.codegen.mxml.flexjs;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.internal.codegen.js.jsc.JSCPublisher;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+public class MXMLFlexJSCordovaPublisher extends MXMLFlexJSPublisher
+{
+ public MXMLFlexJSCordovaPublisher(Configuration config, FlexJSProject project)
+ {
+ super(project, config);
+ }
+
+ @Override
+ public boolean publish(ProblemQuery problems) throws IOException
+ {
+ createCordovaProjectIfNeeded();
+ //loadCordovaPlatformsIfNeeded();
+
+ if (super.publish(problems))
+ {
+ //loadCordovaPlugins();
+ }
+
+ return true;
+ }
+
+ private void createCordovaProjectIfNeeded()
+ {
+ // The "intermediate" is the "js-debug" output.
+ final File intermediateDir = outputFolder;
+ final String projectName = FilenameUtils.getBaseName(configuration.getTargetFile());
+
+ // The "release" is the "js-release" directory.
+ File releaseDir = new File(outputParentFolder, FLEXJS_RELEASE_DIR_NAME);
+
+ }
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java
index 838b1f7..9168d4b 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSPublisher.java
@@ -86,12 +86,20 @@
this.project = project;
}
- private FlexJSProject project;
+ protected FlexJSProject project;
private boolean isMarmotinniRun;
private String outputPathParameter;
private boolean useStrictPublishing;
+ private GoogDepsWriter getGoogDepsWriter(File intermediateDir,
+ String projectName,
+ JSGoogConfiguration googConfiguration,
+ List<ISWC> swcs)
+ {
+ return new GoogDepsWriter(intermediateDir, projectName, googConfiguration, swcs);
+ }
+
@Override
public File getOutputFolder()
{
@@ -304,7 +312,7 @@
// Add all files generated by the compiler to the compilation unit.
/////////////////////////////////////////////////////////////////////////////////
- GoogDepsWriter gdw = new GoogDepsWriter(intermediateDir, projectName, googConfiguration, swcs);
+ GoogDepsWriter gdw = getGoogDepsWriter(intermediateDir, projectName, googConfiguration, swcs);
// This list contains all files generated by the compiler, this is both the
// compiled js files created by the sources of the current project plus the
// js files of used dependencies.
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java
index fe1c5e9..2a77161 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/flexjs/JSCSSCompilationSession.java
@@ -370,6 +370,10 @@
{
// TODO: implement me
}
+ else if ("calc".equals(functionCall.name))
+ {
+ // TODO: implement me
+ }
else if ("Embed".equals(functionCall.name))
{
// TODO: implement me
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogCompcConfiguration.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogCompcConfiguration.java
new file mode 100644
index 0000000..ab690e4
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogCompcConfiguration.java
@@ -0,0 +1,407 @@
+/*
+ *
+ * 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.internal.driver.js.goog;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.flex.compiler.clients.JSConfiguration;
+import org.apache.flex.compiler.clients.MXMLJSC;
+import org.apache.flex.compiler.config.ConfigurationValue;
+import org.apache.flex.compiler.exceptions.ConfigurationException;
+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.FlexOnly;
+import org.apache.flex.compiler.internal.config.annotations.InfiniteArguments;
+import org.apache.flex.compiler.internal.config.annotations.Mapping;
+
+/**
+ * The {@link JSGoogCompcConfiguration} class holds all compiler arguments needed for
+ * compiling ActionScript to JavaScript the 'goog' way.
+ * <p>
+ * Specific flags are implemented here for the configuration to be loaded by the
+ * configure() method of {@link MXMLJSC}.
+ * <p>
+ * This class inherits all compiler arguments from the MXMLC compiler.
+ *
+ * @author Erik de Bruin
+ */
+public class JSGoogCompcConfiguration extends JSConfiguration
+{
+ public JSGoogCompcConfiguration()
+ {
+ setDebug(true);
+ }
+
+ //
+ // 'closure-lib'
+ //
+
+ protected String closureLib = "";
+
+ public boolean isClosureLibSet() {
+ return !closureLib.isEmpty();
+ }
+
+ public String getClosureLib()
+ {
+ try
+ {
+ if (closureLib.equals(""))
+ {
+ return getAbsolutePathFromPathRelativeToMXMLC(
+ "../../js/lib/google/closure-library");
+ }
+ }
+ catch (Exception e) { /* better to try and fail... */ }
+
+ return closureLib;
+ }
+
+ @Config
+ @Mapping("closure-lib")
+ public void setClosureLib(ConfigurationValue cv, String value)
+ throws ConfigurationException
+ {
+ if (value != null)
+ closureLib = value;
+ }
+
+ //
+ // Override 'compiler.binding-value-change-event-type'
+ //
+
+ private String bindingValueChangeEventType = "valueChange";
+
+ @Override
+ public String getBindingValueChangeEventType()
+ {
+ return bindingValueChangeEventType;
+ }
+
+ @Override
+ @Config(advanced = true)
+ public void setCompilerBindingValueChangeEventType(ConfigurationValue cv, String b)
+ {
+ bindingValueChangeEventType = b;
+ }
+
+ //
+ // Override 'compiler.mxml.children-as-data'
+ //
+
+ private Boolean childrenAsData = true;
+
+ @Override
+ public Boolean getCompilerMxmlChildrenAsData()
+ {
+ return childrenAsData;
+ }
+
+ @Override
+ @Config
+ @Mapping({"compiler", "mxml", "children-as-data"})
+ @FlexOnly
+ public void setCompilerMxmlChildrenAsData(ConfigurationValue cv, Boolean asData) throws ConfigurationException
+ {
+ childrenAsData = asData;
+ }
+
+ //
+ // 'marmotinni'
+ //
+
+ private String marmotinni;
+
+ public String getMarmotinni()
+ {
+ return marmotinni;
+ }
+
+ @Config
+ @Mapping("marmotinni")
+ public void setMarmotinni(ConfigurationValue cv, String value)
+ throws ConfigurationException
+ {
+ marmotinni = value;
+ }
+
+ //
+ // 'sdk-js-lib'
+ //
+
+ protected List<String> sdkJSLib = new ArrayList<String>();
+
+ public List<String> getSDKJSLib()
+ {
+ if (sdkJSLib.size() == 0)
+ {
+ try
+ {
+ String path = getAbsolutePathFromPathRelativeToMXMLC(
+ "../../frameworks/js/FlexJS/src");
+
+ sdkJSLib.add(path);
+ }
+ catch (Exception e) { /* better to try and fail... */ }
+ }
+
+ return sdkJSLib;
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("sdk-js-lib")
+ @Arguments(Arguments.PATH_ELEMENT)
+ @InfiniteArguments
+ public void setSDKJSLib(ConfigurationValue cv, List<String> value)
+ throws ConfigurationException
+ {
+ sdkJSLib.addAll(value);
+ }
+
+ //
+ // 'external-js-lib'
+ //
+
+ private List<String> externalJSLib = new ArrayList<String>();
+
+ public List<String> getExternalJSLib()
+ {
+ return externalJSLib;
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("external-js-lib")
+ @Arguments(Arguments.PATH_ELEMENT)
+ @InfiniteArguments
+ public void setExternalJSLib(ConfigurationValue cv, List<String> value)
+ throws ConfigurationException
+ {
+ externalJSLib.addAll(value);
+ }
+
+ //
+ // 'strict-publish'
+ //
+
+ private boolean strictPublish = true;
+
+ public boolean getStrictPublish()
+ {
+ return strictPublish;
+ }
+
+ @Config
+ @Mapping("strict-publish")
+ public void setStrictPublish(ConfigurationValue cv, boolean value)
+ throws ConfigurationException
+ {
+ strictPublish = value;
+ }
+
+ //
+ // 'keep-asdoc'
+ //
+
+ private boolean keepASDoc = true;
+
+ public boolean getKeepASDoc()
+ {
+ return keepASDoc;
+ }
+
+ @Config
+ @Mapping("keep-asdoc")
+ public void setKeepASDoc(ConfigurationValue cv, boolean value)
+ throws ConfigurationException
+ {
+ keepASDoc = value;
+ }
+
+
+
+ //
+ // 'remove-circulars'
+ //
+
+ private boolean removeCirculars = false;
+
+ public boolean getRemoveCirculars()
+ {
+ return removeCirculars;
+ }
+
+ @Config
+ @Mapping("remove-circulars")
+ public void setRemoveCirculars(ConfigurationValue cv, boolean value)
+ throws ConfigurationException
+ {
+ removeCirculars = value;
+ }
+
+
+ //
+ // 'skip-transpile'
+ //
+
+ private boolean skipTranspile = false;
+
+ public boolean getSkipTranspile()
+ {
+ return skipTranspile;
+ }
+
+ @Config
+ @Mapping("skip-transpile")
+ public void setSkipTranspile(ConfigurationValue cv, boolean value)
+ throws ConfigurationException
+ {
+ skipTranspile = value;
+ }
+
+
+
+ protected String getAbsolutePathFromPathRelativeToMXMLC(String relativePath)
+ throws IOException
+ {
+ String mxmlcURL = MXMLJSC.class.getProtectionDomain().getCodeSource()
+ .getLocation().getPath();
+
+ File mxmlc = new File(URLDecoder.decode(mxmlcURL, "utf-8"));
+
+ return new File(mxmlc.getParent() + File.separator + relativePath)
+ .getCanonicalPath();
+ }
+
+ //
+ // 'js-compiler-option'
+ //
+
+ protected List<String> jsCompilerOptions = new ArrayList<String>();
+
+ public List<String> getJSCompilerOptions()
+ {
+ return jsCompilerOptions;
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("js-compiler-option")
+ @Arguments("option")
+ @InfiniteArguments
+ public void setJSCompilerOptions(ConfigurationValue cv, List<String> value)
+ throws ConfigurationException
+ {
+ jsCompilerOptions.addAll(value);
+ }
+
+ //
+ // 'js-output-optimization'
+ //
+
+ protected List<String> jsOutputOptimizations = new ArrayList<String>();
+
+ public List<String> getJSOutputOptimizations()
+ {
+ return jsOutputOptimizations;
+ }
+
+ @Config(allowMultiple = true)
+ @Mapping("js-output-optimization")
+ @Arguments("optimization")
+ @InfiniteArguments
+ public void setJSOutputOptimizations(ConfigurationValue cv, List<String> value)
+ throws ConfigurationException
+ {
+ jsOutputOptimizations.addAll(value);
+ }
+
+ // 'html-template' option
+ //
+
+ private String htmlTemplateFileName = null;
+
+ public File getHtmlTemplate()
+ {
+ return htmlTemplateFileName != null ? new File(htmlTemplateFileName) : null;
+ }
+
+ /**
+ * Specify an HTML template with tokens to replace with application-specific values.
+ * If not specified a standard template is generated.
+ */
+ @Config(advanced = true)
+ @Mapping("html-template")
+ @Arguments("filename")
+ public void setHtmlTemplate(ConfigurationValue cv, String filename)
+ {
+ this.htmlTemplateFileName = getOutputPath(cv, filename);
+ }
+
+ // 'html-output-filename' option
+ //
+
+ private String htmlOutputFileName = "index.html";
+
+ public String getHtmlOutputFileName()
+ {
+ return htmlOutputFileName;
+ }
+
+ /**
+ * Specify the name of the HTML file that goes in the output folder. Default is index.html.
+ */
+ @Config(advanced = true)
+ @Mapping("html-output-filename")
+ @Arguments("filename")
+ public void setHtmlOutputFileName(ConfigurationValue cv, String filename)
+ {
+ this.htmlOutputFileName = filename;
+ }
+
+ //
+ // 'compiler.keep-code-with-metadata' option
+ //
+
+ private Set<String> keepCodeWithMetadata = null;
+
+ public Set<String> getCompilerKeepCodeWithMetadata()
+ {
+ return keepCodeWithMetadata == null ? Collections.<String> emptySet() : keepCodeWithMetadata;
+ }
+
+ @Config(advanced = true, allowMultiple = true)
+ @Mapping({ "compiler", "keep-code-with-metadata" })
+ @Arguments("name")
+ @InfiniteArguments
+ public void setCompilerKeepCodeWithMetadata(ConfigurationValue cv, List<String> values)
+ {
+ if (keepCodeWithMetadata == null)
+ keepCodeWithMetadata = new HashSet<String>();
+ keepCodeWithMetadata.addAll(values);
+ }
+
+
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java
index 0c6df76..318c90b 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java
@@ -173,6 +173,7 @@
@Config(allowMultiple = true)
@Mapping("sdk-js-lib")
+ @Arguments(Arguments.PATH_ELEMENT)
@InfiniteArguments
public void setSDKJSLib(ConfigurationValue cv, List<String> value)
throws ConfigurationException
@@ -193,6 +194,7 @@
@Config(allowMultiple = true)
@Mapping("external-js-lib")
+ @Arguments(Arguments.PATH_ELEMENT)
@InfiniteArguments
public void setExternalJSLib(ConfigurationValue cv, List<String> value)
throws ConfigurationException
@@ -306,6 +308,7 @@
@Config(allowMultiple = true)
@Mapping("js-compiler-option")
+ @Arguments("option")
@InfiniteArguments
public void setJSCompilerOptions(ConfigurationValue cv, List<String> value)
throws ConfigurationException
@@ -326,6 +329,7 @@
@Config(allowMultiple = true)
@Mapping("js-output-optimization")
+ @Arguments("optimization")
@InfiniteArguments
public void setJSOutputOptimizations(ConfigurationValue cv, List<String> value)
throws ConfigurationException
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSCordovaBackend.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSCordovaBackend.java
new file mode 100644
index 0000000..841a536
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/mxml/flexjs/MXMLFlexJSCordovaBackend.java
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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.internal.driver.mxml.flexjs;
+
+import java.io.FilterWriter;
+import java.util.List;
+
+import org.apache.flex.compiler.codegen.IDocEmitter;
+import org.apache.flex.compiler.codegen.as.IASEmitter;
+import org.apache.flex.compiler.codegen.js.IJSEmitter;
+import org.apache.flex.compiler.codegen.js.IJSWriter;
+import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter;
+import org.apache.flex.compiler.config.Configuration;
+import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.driver.IBackend;
+import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
+import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogDocEmitter;
+import org.apache.flex.compiler.internal.codegen.mxml.MXMLBlockWalker;
+import org.apache.flex.compiler.internal.codegen.mxml.MXMLWriter;
+import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSBlockWalker;
+import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSCordovaPublisher;
+import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSEmitter;
+import org.apache.flex.compiler.internal.codegen.mxml.flexjs.MXMLFlexJSPublisher;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.driver.mxml.MXMLBackend;
+import org.apache.flex.compiler.internal.projects.FlexJSProject;
+import org.apache.flex.compiler.internal.targets.FlexJSTarget;
+import org.apache.flex.compiler.internal.targets.JSTarget;
+import org.apache.flex.compiler.internal.visitor.as.ASNodeSwitch;
+import org.apache.flex.compiler.internal.visitor.mxml.MXMLNodeSwitch;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.targets.ITargetProgressMonitor;
+import org.apache.flex.compiler.targets.ITargetSettings;
+import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.visitor.IBlockVisitor;
+import org.apache.flex.compiler.visitor.IBlockWalker;
+import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker;
+
+/**
+ * A concrete implementation of the {@link IBackend} API where the
+ * {@link MXMLBlockWalker} is used to traverse the {@link IMXMLFileNode} AST.
+ *
+ * @author Erik de Bruin
+ */
+public class MXMLFlexJSCordovaBackend extends MXMLFlexJSBackend
+{
+
+ @Override
+ public Configurator createConfigurator()
+ {
+ return new Configurator(JSGoogConfiguration.class);
+ }
+
+ @Override
+ public MXMLFlexJSPublisher createPublisher(FlexJSProject project,
+ List<ICompilerProblem> errors, Configuration config)
+ {
+ return new MXMLFlexJSCordovaPublisher(config, project);
+ }
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/graph/GoogDepsWriter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/graph/GoogDepsWriter.java
index 49038cd..b26b632 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/graph/GoogDepsWriter.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/graph/GoogDepsWriter.java
@@ -827,6 +827,63 @@
return "";
}
+ private ArrayList<String> getDirectDependencies(String fn)
+ {
+ ArrayList<String> deps = new ArrayList<String>();
+
+ FileInputStream fis;
+ try {
+ fis = new FileInputStream(fn);
+ Scanner scanner = new Scanner(fis, "UTF-8");
+ boolean inInjectHTML = false;
+ while (scanner.hasNextLine())
+ {
+ String s = scanner.nextLine();
+ if (s.contains("goog.inherits"))
+ break;
+ if (inInjectHTML)
+ {
+ int c = s.indexOf("</inject_html>");
+ if (c > -1)
+ {
+ inInjectHTML = false;
+ continue;
+ }
+ }
+ if (inInjectHTML)
+ {
+ s = s.trim();
+ if (s.startsWith("*"))
+ s = s.substring(1);
+ additionalHTML.add(s);
+ continue;
+ }
+ else
+ otherScanning(s);
+ int c = s.indexOf(JSGoogEmitterTokens.GOOG_REQUIRE.getToken());
+ if (c > -1)
+ {
+ int c2 = s.indexOf(")");
+ s = s.substring(c + 14, c2 - 1);
+ deps.add(s);
+ }
+ c = s.indexOf("<inject_html>");
+ if (c > -1)
+ {
+ inInjectHTML = true;
+ }
+ }
+ scanner.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ return deps;
+ }
+
+ protected void otherScanning(String s)
+ {
+ }
+
private String getDependencies(ArrayList<String> deps)
{
String s = "";
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/graph/GoogDepsWriterCordova.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/graph/GoogDepsWriterCordova.java
new file mode 100644
index 0000000..c053381
--- /dev/null
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/graph/GoogDepsWriterCordova.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * 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.internal.graph;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.flex.compiler.clients.problems.ProblemQuery;
+import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
+import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.problems.FileNotFoundProblem;
+import org.apache.flex.swc.ISWC;
+import org.apache.flex.swc.ISWCFileEntry;
+
+import com.google.common.io.Files;
+
+public class GoogDepsWriterCordova extends GoogDepsWriter {
+
+ public GoogDepsWriterCordova(File outputFolder, String mainClassName, JSGoogConfiguration config, List<ISWC> swcs)
+ {
+ super(outputFolder, mainClassName, config, swcs);
+ }
+
+ private final String FLEXJS_CORDOVA_PLUGIN = "@flexjscordovaplugin";
+
+ public ArrayList<String> cordovaPlugins = new ArrayList<String>();
+
+ @Override
+ protected void otherScanning(String s)
+ {
+ int c = s.indexOf(FLEXJS_CORDOVA_PLUGIN);
+ if (c > -1)
+ {
+ cordovaPlugins.add(s.substring(c + FLEXJS_CORDOVA_PLUGIN.length()).trim());
+ }
+ }
+}
diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java
index 3dec3ab..2dbbcf7 100644
--- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java
+++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/projects/FlexJSProject.java
@@ -23,11 +23,16 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import org.apache.flex.compiler.clients.JSConfiguration;
import org.apache.flex.compiler.common.DependencyType;
+import org.apache.flex.compiler.config.Configuration;
import org.apache.flex.compiler.config.Configurator;
+import org.apache.flex.compiler.css.ICSSMediaQueryCondition;
+import org.apache.flex.compiler.css.ICSSRule;
import org.apache.flex.compiler.definitions.IDefinition;
import org.apache.flex.compiler.definitions.metadata.IMetaTag;
import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute;
@@ -37,6 +42,7 @@
import org.apache.flex.compiler.internal.definitions.InterfaceDefinition;
import org.apache.flex.compiler.internal.driver.js.flexjs.JSCSSCompilationSession;
import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.internal.scopes.ASProjectScope.DefinitionPromise;
import org.apache.flex.compiler.internal.targets.ITargetAttributes;
import org.apache.flex.compiler.internal.targets.LinkageChecker;
@@ -49,6 +55,8 @@
import org.apache.flex.compiler.tree.as.IDefinitionNode;
import org.apache.flex.compiler.units.ICompilationUnit;
+import com.google.common.collect.ImmutableList;
+
/**
* @author aharui
*
@@ -363,4 +371,64 @@
return backend;
}
+ @Override
+ protected void overrideDefines(Map<String, String> defines)
+ {
+ if (defines.containsKey("COMPILE::SWF"))
+ {
+ if (defines.get("COMPILE::SWF").equals("AUTO"))
+ defines.put("COMPILE::SWF", "false");
+ }
+ if (defines.containsKey("COMPILE::JS"))
+ {
+ if (defines.get("COMPILE::JS").equals("AUTO"))
+ defines.put("COMPILE::JS", "true");
+ }
+ }
+
+ /**
+ * List of external libraries so it can be overridden
+ */
+ public List<String> getCompilerExternalLibraryPath(Configuration config)
+ {
+ List<String> list = ((JSConfiguration)config).getCompilerJsExternalLibraryPath();
+ if (list != null && list.size() > 0)
+ return list;
+ return config.getCompilerExternalLibraryPath();
+ }
+
+ /**
+ * List of libraries so it can be overridden
+ */
+ public List<String> getCompilerLibraryPath(Configuration config)
+ {
+ List<String> list = ((JSConfiguration)config).getCompilerJsLibraryPath();
+ if (list != null && list.size() > 0)
+ return list;
+ return config.getCompilerLibraryPath();
+ }
+
+ /**
+ * List of libraries so it can be overridden
+ */
+ public List<MXMLNamespaceMapping> getCompilerNamespacesManifestMappings(Configuration config)
+ {
+ List<MXMLNamespaceMapping> list = ((JSConfiguration)config).getCompilerJsNamespacesManifestMappings();
+ if (list != null && list.size() > 0)
+ return list;
+ return config.getCompilerNamespacesManifestMappings();
+ }
+
+ @Override
+ public boolean isPlatformRule(ICSSRule rule) {
+ ImmutableList<ICSSMediaQueryCondition> mqlist = rule.getMediaQueryConditions();
+ int n = mqlist.size();
+ if (n > 0)
+ {
+ if (mqlist.get(0).toString().equals("-flex-flash"))
+ return false;
+ }
+ return true;
+ }
+
}
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
index 608aabe..d9cc4f3 100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/externals/ExternalsTestUtils.java
@@ -100,10 +100,12 @@
{
config.addFieldExclude("Window", "focus");
config.addClassExclude("controlRange");
+ config.addClassExclude("ITemplateArray");
config.addExclude("Array", "toSource");
config.addExclude("Date", "valueOf");
config.addExclude("String", "valueOf");
+ config.addExclude("String", "raw");
// SVG
config.addExclude("SVGStylable", "className");
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java
index 50ff64a..9354c66 100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSProject.java
@@ -174,7 +174,7 @@
} catch (ConfigurationException e) {
Assert.fail(e.getMessage());
}
- project.setTargetSettings(new TargetSettings(((FlexJSProject)project).config));
+ project.setTargetSettings(new TargetSettings(((FlexJSProject)project).config, (FlexJSProject)project));
sourcePath = new File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
projectDirPath + "/overrides").getPath();
@@ -197,7 +197,7 @@
} catch (ConfigurationException e) {
Assert.fail(e.getMessage());
}
- project.setTargetSettings(new TargetSettings(((FlexJSProject)project).config));
+ project.setTargetSettings(new TargetSettings(((FlexJSProject)project).config, (FlexJSProject)project));
sourcePath = new File(TestAdapterFactory.getTestAdapter().getUnitTestBaseDir(),
projectDirPath + "/bad_overrides").getPath();
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java
index f91a1dd..ae28748 100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/TestFlexJSMXMLApplication.java
@@ -21,13 +21,16 @@
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
+import org.apache.flex.compiler.clients.MXMLJSC;
import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
import org.apache.flex.compiler.internal.driver.js.flexjs.JSCSSCompilationSession;
import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
import org.apache.flex.compiler.internal.projects.FlexJSProject;
import org.apache.flex.compiler.internal.test.FlexJSTestBase;
+import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
import org.apache.flex.compiler.tree.mxml.IMXMLFileNode;
+import org.apache.flex.utils.FilenameNormalization;
import org.apache.flex.utils.ITestAdapter;
import org.apache.flex.utils.TestAdapterFactory;
import org.junit.Test;
@@ -818,6 +821,61 @@
assertOutMXMLPostProcess(outTemplate.replaceAll("AppName", appName), true);
}
+ @Test
+ public void testFlexJSMainFileDual()
+ {
+ MXMLJSC mxmlc = new MXMLJSC();
+ String[] args = new String[8];
+ args[0] = "-compiler.targets=SWF,JSFlex";
+ args[1] = "-compiler.allow-subclass-overrides";
+ args[2] = "-remove-circulars";
+ args[3] = "-library-path=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/libs")).getPath();
+ args[4] = "-external-library-path+=" + testAdapter.getPlayerglobal().getPath();
+ args[5] = "-output=" + new File(testAdapter.getTempDir(), "bin-debug/FlexJSTest_again.swf").getPath();
+ if (env.GOOG != null)
+ args[6] = "-closure-lib=" + new File(FilenameNormalization.normalize(env.GOOG)).getPath();
+ else
+ args[6] = "-define=COMPILE::temp,false";
+ args[7] = new File(testAdapter.getUnitTestBaseDir(), "flexjs/files/FlexJSTest_again.mxml").getPath();
+
+ ArrayList<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
+ int result = mxmlc.mainNoExit(args, problems, true);
+ assertThat(result, is(0));
+ }
+
+ @Test
+ public void testFlexJSMainFileDualFlash()
+ {
+ /* this should error because a Flash APi is used */
+ MXMLJSC mxmlc = new MXMLJSC();
+ String[] args = new String[18];
+ args[0] = "-compiler.targets=SWF,JSFlex";
+ args[1] = "-remove-circulars";
+ args[2] = "-library-path=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/libs/Core.swc")).getPath();
+ args[3] = "-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/libs/Binding.swc")).getPath();
+ args[4] = "-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/libs/Network.swc")).getPath();
+ args[5] = "-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/libs/Collections.swc")).getPath();
+ args[6] = "-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/libs/Basic.swc")).getPath();
+ args[7] = "-external-library-path+=" + testAdapter.getPlayerglobal().getPath();
+ args[8] = "-output=" + new File(testAdapter.getTempDir(), "bin-debug/FlexJSTest_again_Flash.swf").getPath();
+ if (env.GOOG != null)
+ args[9] = "-closure-lib=" + new File(FilenameNormalization.normalize(env.GOOG)).getPath();
+ else
+ args[9] = "-define=COMPILE::temp,false";
+ args[10] = "-compiler.allow-subclass-overrides";
+ args[11] = "-compiler.js-library-path=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/js/FlexJS/libs/CoreJS.swc")).getPath();
+ args[12] = "-compiler.js-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/js/FlexJS/libs/BindingJS.swc")).getPath();
+ args[13] = "-compiler.js-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/js/FlexJS/libs/NetworkJS.swc")).getPath();
+ args[14] = "-compiler.js-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/js/FlexJS/libs/CollectionsJS.swc")).getPath();
+ args[15] = "-compiler.js-library-path+=" + new File(FilenameNormalization.normalize(env.ASJS + "/frameworks/js/FlexJS/libs/BasicJS.swc")).getPath();
+ args[16] = "-compiler.js-external-library-path=" + new File(FilenameNormalization.normalize(env.ASJS + "/js/libs/js.swc")).getPath();
+ args[17] = new File(testAdapter.getUnitTestBaseDir(), "flexjs/files/FlexJSTest_again_Flash.mxml").getPath();
+
+ int result = mxmlc.mainNoExit(args, errors, true);
+ assertThat(result, is(3));
+ assertErrors("Access of possibly undefined property scrollRect.");
+ }
+
@Override
protected void addSourcePaths(List<File> sourcePaths)
{
diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/FlexJSTestBase.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/FlexJSTestBase.java
index 30fcebc..11c275b 100644
--- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/FlexJSTestBase.java
+++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/test/FlexJSTestBase.java
@@ -66,6 +66,7 @@
libraries.add(new File(FilenameNormalization.normalize(env.SDK
+ "\\frameworks\\libs\\rpc.swc")));
libraries.add(new File(env.ASJS + "/frameworks/libs/Core.swc"));
+ libraries.add(new File(env.ASJS + "/frameworks/libs/Basic.swc"));
libraries.add(new File(env.ASJS + "/frameworks/libs/HTML.swc"));
libraries.add(new File(env.ASJS + "/frameworks/libs/Binding.swc"));
libraries.add(new File(env.ASJS + "/frameworks/libs/Network.swc"));
diff --git a/compiler-jx/src/test/java/org/apache/flex/utils/EnvProperties.java b/compiler-jx/src/test/java/org/apache/flex/utils/EnvProperties.java
index ee2c3f3..a481a6e 100644
--- a/compiler-jx/src/test/java/org/apache/flex/utils/EnvProperties.java
+++ b/compiler-jx/src/test/java/org/apache/flex/utils/EnvProperties.java
@@ -66,15 +66,14 @@
public String ASJS;
/**
- * PLAYERGLOBAL_VERSION
- */
- public String FPVER;
-
- /**
* GOOG_HOME
*/
public String GOOG;
+ /**
+ * PLAYERGLOBAL_VERSION
+ */
+ public String FPVER;
private static EnvProperties env;
@@ -151,7 +150,7 @@
System.out.println("environment property - ASJS_HOME = " + ASJS);
GOOG = p.getProperty(prefix + "GOOG_HOME", System.getenv("GOOG_HOME"));
-
+ System.out.println("environment property - GOOG_HOME = " + GOOG);
}
}
diff --git a/compiler-jx/src/test/resources/flexjs/files/CSSTestSource.css b/compiler-jx/src/test/resources/flexjs/files/CSSTestSource.css
index f18dc6f..6bbb192 100755
--- a/compiler-jx/src/test/resources/flexjs/files/CSSTestSource.css
+++ b/compiler-jx/src/test/resources/flexjs/files/CSSTestSource.css
@@ -84,5 +84,5 @@
.usescalc {
color: #fff;
- width: calc((100% - 50px)/3;
+ width: calc((100% - 50px)/3);
}
diff --git a/compiler-jx/src/test/resources/flexjs/files/CSSTestSource_result.css b/compiler-jx/src/test/resources/flexjs/files/CSSTestSource_result.css
index 6a17c84..bc01e64 100755
--- a/compiler-jx/src/test/resources/flexjs/files/CSSTestSource_result.css
+++ b/compiler-jx/src/test/resources/flexjs/files/CSSTestSource_result.css
@@ -85,7 +85,7 @@
.usescalc {
color: #fff;
- width: calc((100% - 50px) / 3;
+ width: calc((100% - 50px)/3);
}
diff --git a/compiler-jx/src/test/resources/flexjs/files/FlexJSTest_again_Flash.mxml b/compiler-jx/src/test/resources/flexjs/files/FlexJSTest_again_Flash.mxml
new file mode 100644
index 0000000..286664d
--- /dev/null
+++ b/compiler-jx/src/test/resources/flexjs/files/FlexJSTest_again_Flash.mxml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+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.
+
+-->
+<basic:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
+ xmlns:local="*"
+ xmlns:basic="library://ns.apache.org/flexjs/basic"
+ xmlns:models="models.*"
+ xmlns:controllers="controllers.*"
+ initialize="MyModel(model).labelText='Hello World'; scrollRect = null"
+ >
+ <basic:valuesImpl>
+ <basic:SimpleCSSValuesImpl />
+ </basic:valuesImpl>
+ <basic:initialView>
+ <local:MyInitialView />
+ </basic:initialView>
+ <basic:model>
+ <models:MyModel />
+ </basic:model>
+ <basic:controller>
+ <controllers:MyController />
+ </basic:controller>
+ <basic:beads>
+ <basic:HTTPService id="service">
+ <basic:LazyCollection id="collection">
+ <basic:inputParser>
+ <basic:JSONInputParser />
+ </basic:inputParser>
+ <basic:itemConverter>
+ <local:StockDataJSONItemConverter />
+ </basic:itemConverter>
+ </basic:LazyCollection>
+ </basic:HTTPService>
+ </basic:beads>
+</basic:Application>
\ No newline at end of file
diff --git a/compiler-jx/src/test/resources/flexjs/files/MyInitialView.mxml b/compiler-jx/src/test/resources/flexjs/files/MyInitialView.mxml
index 1fe77f9..c083269 100644
--- a/compiler-jx/src/test/resources/flexjs/files/MyInitialView.mxml
+++ b/compiler-jx/src/test/resources/flexjs/files/MyInitialView.mxml
@@ -48,7 +48,7 @@
return String(comboBox.selectedItem);
}
- public function startTimer(event:org.apache.flex.events.Event):void
+ public function startTimer():void
{
timer = new org.apache.flex.utils.Timer(1000);
timer.addEventListener('timer', timerHandler);
@@ -69,7 +69,7 @@
destinationPropertyName="text" />
</basic:beads>
</basic:Label>
- <basic:TextButton text="Let's Start Timer" x="100" y="75" click="startTimer(event)" />
+ <basic:TextButton text="Let's Start Timer" x="100" y="75" click="startTimer()" />
<basic:TextButton text="Stop Timer" x="100" y="100" click="timer.removeEventListener('timer', timerHandler);timer.stop()" />
<basic:Label id="timerLabel" x="100" y="125" />
diff --git a/compiler-jx/src/test/resources/flexjs/files/MyInitialView_result.js b/compiler-jx/src/test/resources/flexjs/files/MyInitialView_result.js
index 1bc0837..f3bd88d 100644
--- a/compiler-jx/src/test/resources/flexjs/files/MyInitialView_result.js
+++ b/compiler-jx/src/test/resources/flexjs/files/MyInitialView_result.js
@@ -222,9 +222,8 @@
/**
* @export
- * @param {org.apache.flex.events.Event} event
*/
-MyInitialView.prototype.startTimer = function(event) {
+MyInitialView.prototype.startTimer = function() {
this.timer = new org.apache.flex.utils.Timer(1000);
this.timer.addEventListener('timer', org.apache.flex.utils.Language.closure(this.timerHandler, this, 'timerHandler'));
this.timer.start();
@@ -282,7 +281,7 @@
*/
MyInitialView.prototype.$EH0 = function(event)
{
- this.startTimer(event);
+ this.startTimer();
};
@@ -880,7 +879,7 @@
},
methods: function () {
return {
- 'startTimer': { type: 'void', declaredBy: 'MyInitialView', parameters: function () { return [ { index: 1, type: 'org.apache.flex.events.Event', optional: false } ]; }},
+ 'startTimer': { type: 'void', declaredBy: 'MyInitialView'},
'timerHandler': { type: 'void', declaredBy: 'MyInitialView', parameters: function () { return [ { index: 1, type: 'org.apache.flex.events.Event', optional: false } ]; }},
'MyInitialView': { type: '', declaredBy: 'MyInitialView'},
'$EH0': { type: 'void', declaredBy: 'MyInitialView'},
diff --git a/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g
index af9348a..726b09f 100644
--- a/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g
+++ b/compiler/src/main/antlr3/org/apache/flex/compiler/internal/css/CSS.g
@@ -580,9 +580,9 @@
/** Arguments of a function call property value. */
ARGUMENTS
- : '(' ( options {greedy=false;}: . )* ')'
+ : '(' ( options {greedy=false;}: ARGUMENTS | . )* ')'
;
-
+
/**
* Match multiple semi-colons in Lexer level so that the parser can have a
* finite number of look ahead, instead of LL(*);
diff --git a/compiler/src/main/java/org/apache/flex/compiler/clients/COMPC.java b/compiler/src/main/java/org/apache/flex/compiler/clients/COMPC.java
index 547f40f..0c7ac71 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/clients/COMPC.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/clients/COMPC.java
@@ -108,7 +108,7 @@
@Override
protected Configurator createConfigurator()
{
- return new Configurator(COMPCConfiguration.class);
+ return new Configurator(configurationClass);
}
@Override
diff --git a/compiler/src/main/java/org/apache/flex/compiler/clients/MXMLC.java b/compiler/src/main/java/org/apache/flex/compiler/clients/MXMLC.java
index 7a7bfdd..d77db73 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/clients/MXMLC.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/clients/MXMLC.java
@@ -399,6 +399,7 @@
public ProblemQuery problems;
public ConfigurationBuffer configBuffer;
+ public Class<? extends Configuration> configurationClass = Configuration.class;
protected Configurator projectConfigurator;
protected ICompilationUnit mainCU;
@@ -449,9 +450,9 @@
* @return a new instance or subclass of {@link Configurator}.
*
*/
- protected Configurator createConfigurator()
+ protected Configurator createConfigurator()
{
- return new Configurator();
+ return new Configurator(configurationClass);
}
/**
diff --git a/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java b/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java
index fa8d612..6356c88 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/config/Configuration.java
@@ -1892,7 +1892,7 @@
configVars.put(name, value);
}
-
+
//
// 'compiler.conservative' option (hidden)
//
@@ -2061,6 +2061,37 @@
}
//
+ // 'compiler.swf-external-library-path' option
+ //
+
+ private final List<String> swfExternalLibraryPath = new ArrayList<String>();
+
+ public List<String> getCompilerSwfExternalLibraryPath()
+ {
+ return swfExternalLibraryPath;
+ }
+
+ @Config(allowMultiple = true, isPath = true)
+ @Mapping({ "compiler", "swf-external-library-path" })
+ @Arguments(Arguments.PATH_ELEMENT)
+ @SoftPrerequisites({ "target-player", "exclude-native-js-libraries" })
+ @InfiniteArguments
+ public void setCompilerSwfExternalLibraryPath(ConfigurationValue cv, String[] pathlist) throws ConfigurationException
+ {
+ pathlist = removeNativeJSLibrariesIfNeeded(pathlist);
+
+ final ImmutableList<String> pathElements = ImmutableList.copyOf(pathlist);
+ final ImmutableList<String> resolvedPaths = expandTokens(pathElements, locales, cv,
+ !reportMissingCompilerLibraries);
+ swfExternalLibraryPath.addAll(resolvedPaths);
+
+ // TODO: Review usages of "compilingForAIR", because only looking at path elements
+ // on library path isn't enough. There might be a folder on the library path that
+ // contains AIR libraries.
+ compilingForAIR = containsAIRLibraries(pathElements);
+ }
+
+ //
// 'compiler.generated-directory' option
// This can only be configured using getter and setter.
//
@@ -2244,7 +2275,7 @@
//
private final List<String> libraryPath = new ArrayList<String>();
- private boolean reportMissingCompilerLibraries = true;
+ protected boolean reportMissingCompilerLibraries = true;
/**
* Sets whether to report missing libraries in the configuration. If this is false any missing libraries will not be
@@ -2281,10 +2312,51 @@
}
//
+ // 'compiler.swf-library-path' option
+ //
+
+ private final List<String> swfLibraryPath = new ArrayList<String>();
+ protected boolean reportMissingCompilerSwfLibraries = true;
+
+ /**
+ * Sets whether to report missing libraries in the configuration. If this is false any missing libraries will not be
+ * warned about, and the filename will also be added to list of libraries in the project when it doesn't exist. If
+ * reportMissingCompilerLibraries is true, any missing libraries will not be added to the project.
+ *
+ * @param reportMissingCompilerLibraries true to report missing libraries
+ */
+ public void setReportMissingCompilerSwfLibraries(boolean reportMissingCompilerLibraries)
+ {
+ this.reportMissingCompilerLibraries = reportMissingCompilerLibraries;
+ }
+
+ public List<String> getCompilerSwfLibraryPath()
+ {
+ return swfLibraryPath;
+ }
+
+ /**
+ * Links SWC files to the resulting application SWF file. The compiler only links in those classes for the SWC file
+ * that are required. You can specify a directory or individual SWC files.
+ */
+ @Config(allowMultiple = true, isPath = true)
+ @Mapping({ "compiler", "swf-library-path" })
+ @Arguments(Arguments.PATH_ELEMENT)
+ @InfiniteArguments
+ @SoftPrerequisites({ "locale", "target-player", "exclude-native-js-libraries" })
+ public void setCompilerSwfLibraryPath(ConfigurationValue cv, String[] pathlist) throws CannotOpen
+ {
+ pathlist = removeNativeJSLibrariesIfNeeded(pathlist);
+ final ImmutableList<String> resolvedPaths = expandTokens(Arrays.asList(pathlist), locales, cv,
+ !reportMissingCompilerLibraries);
+ swfLibraryPath.addAll(resolvedPaths);
+ }
+
+ //
// 'compiler.locale' option
//
- private final List<String> locales = new ArrayList<String>();
+ protected final List<String> locales = new ArrayList<String>();
public List<String> getCompilerLocales()
{
diff --git a/compiler/src/main/java/org/apache/flex/compiler/config/Configurator.java b/compiler/src/main/java/org/apache/flex/compiler/config/Configurator.java
index 55d23ff..4f53b62 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/config/Configurator.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/config/Configurator.java
@@ -287,6 +287,7 @@
private Collection<ICompilerProblem> configurationProblems;
private boolean extrasRequireDefaultVariable;
private IPathResolver configurationPathResolver;
+ private IFlexProject project;
//
// IConfigurator related methods
@@ -309,6 +310,7 @@
@Override
public boolean applyToProject(IFlexProject project)
{
+ this.project = project;
final IWorkspace workspace = project.getWorkspace();
boolean success = processConfiguration();
workspace.startIdleState();
@@ -426,7 +428,7 @@
return null;
}
- return new TargetSettings(configuration);
+ return new TargetSettings(configuration, project);
}
@Override
@@ -595,7 +597,7 @@
LinkedHashSet<File> libraries = new LinkedHashSet<File>();
// add External Library Path
- List<File> externalLibraryFiles = toFileList(configuration.getCompilerExternalLibraryPath());
+ List<File> externalLibraryFiles = toFileList(project.getCompilerExternalLibraryPath(configuration));
libraries.addAll(externalLibraryFiles);
// add RSLs
@@ -605,7 +607,7 @@
libraries.addAll(toFileList(configuration.getCompilerIncludeLibraries()));
// add Library Path
- libraries.addAll(toFileList(configuration.getCompilerLibraryPath()));
+ libraries.addAll(toFileList(project.getCompilerLibraryPath(configuration)));
project.setLibraries(new ArrayList<File>(libraries));
@@ -801,7 +803,7 @@
protected void setupNamespaces(IFlexProject project)
{
final List<? extends IMXMLNamespaceMapping> configManifestMappings =
- configuration.getCompilerNamespacesManifestMappings();
+ project.getCompilerNamespacesManifestMappings(configuration);
if (configManifestMappings != null)
{
project.setNamespaceMappings(configManifestMappings);
diff --git a/compiler/src/main/java/org/apache/flex/compiler/constants/IMetaAttributeConstants.java b/compiler/src/main/java/org/apache/flex/compiler/constants/IMetaAttributeConstants.java
index b30948c..6db2842 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/constants/IMetaAttributeConstants.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/constants/IMetaAttributeConstants.java
@@ -200,6 +200,7 @@
static final String ATTRIBUTE_SWFOVERRIDE = "SWFOverride";
static final String NAME_SWFOVERRIDE_RETURNS = "returns";
static final String NAME_SWFOVERRIDE_PARAMS = "params";
+ static final String NAME_SWFOVERRIDE_ALTPARAMS = "altparams";
// [VisualContentHolder]
static final String ATTRIBUTE_VISUALCONTENTHOLDER = "VisualContentHolder";
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/config/FileConfigurator.java b/compiler/src/main/java/org/apache/flex/compiler/internal/config/FileConfigurator.java
index 89e015f..cbd9c4a 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/config/FileConfigurator.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/config/FileConfigurator.java
@@ -456,6 +456,7 @@
protected static final ImmutableSet<String> VALID_SUBTREE_TAG = ImmutableSet.of(
"compiler",
"compiler.namespaces",
+ "compiler.js-namespaces",
"compiler.fonts",
"compiler.fonts.languages",
"compiler.mxml",
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/config/TargetSettings.java b/compiler/src/main/java/org/apache/flex/compiler/internal/config/TargetSettings.java
index 3776606..61ac6fd 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/config/TargetSettings.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/config/TargetSettings.java
@@ -34,6 +34,7 @@
import org.apache.flex.compiler.config.Configurator;
import org.apache.flex.compiler.config.RSLSettings;
import org.apache.flex.compiler.internal.projects.LibraryPathManager;
+import org.apache.flex.compiler.projects.IFlexProject;
import org.apache.flex.compiler.targets.ITargetSettings;
import org.apache.flex.utils.FilenameNormalization;
import com.google.common.collect.ImmutableList;
@@ -46,9 +47,10 @@
*/
public class TargetSettings implements ITargetSettings
{
- public TargetSettings(Configuration configuration)
+ public TargetSettings(Configuration configuration, IFlexProject project)
{
this.configuration = configuration;
+ this.project = project;
}
private File output;
@@ -62,6 +64,7 @@
private Map<String, File> includeFiles;
private final Configuration configuration;
+ private final IFlexProject project;
private Set<String> externalLinkageLibraries;
@@ -374,7 +377,8 @@
{
if (externalLibraryPath == null)
{
- List<File> files = Configurator.toFileList(configuration.getCompilerExternalLibraryPath());
+ List<File> files = Configurator.toFileList(project != null ? project.getCompilerExternalLibraryPath(configuration) :
+ configuration.getCompilerExternalLibraryPath());
Set<File> expandedFiles = LibraryPathManager.discoverSWCFilePathsAsFiles(files.toArray(new File[files.size()]));
externalLibraryPath = new ArrayList<File>(expandedFiles.size());
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/css/semantics/CSSSemanticAnalyzer.java b/compiler/src/main/java/org/apache/flex/compiler/internal/css/semantics/CSSSemanticAnalyzer.java
index 64dfa7f..e2f244c 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/css/semantics/CSSSemanticAnalyzer.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/css/semantics/CSSSemanticAnalyzer.java
@@ -219,12 +219,13 @@
final IXMLNameResolver xmlNameResolver,
final ICSSDocument css,
final Collection<ICompilerProblem> problems,
+ final IFlexProject project,
final boolean isCompatibilityVersion3)
{
assert xmlNameResolver != null : "Expected xmlNameResolver";
assert css != null : "Expected CSS";
- final ImmutableSet<ICSSSelector> allSelectors = getAllSelectors(css);
+ final ImmutableSet<ICSSSelector> allSelectors = getAllSelectors(css, project);
if (isCompatibilityVersion3)
return resolveSelectorsAsFlex3Style(allSelectors);
@@ -314,13 +315,15 @@
* @param document CSS document
* @return All the selectors in the CSS.
*/
- public static ImmutableSet<ICSSSelector> getAllSelectors(final ICSSDocument document)
+ public static ImmutableSet<ICSSSelector> getAllSelectors(final ICSSDocument document, final IFlexProject project)
{
assert document != null : "Expected CSS document";
final ImmutableSet.Builder<ICSSSelector> builder = new ImmutableSet.Builder<ICSSSelector>();
for (final ICSSRule rule : document.getRules())
{
+ if (!project.isPlatformRule(rule))
+ continue;
for (final ICSSSelector subject : rule.getSelectorGroup())
{
ICSSSelector selector = subject;
@@ -469,7 +472,7 @@
{
final boolean isFlex3CSS = flexProject.getCSSManager().isFlex3CSS();
final ImmutableMap<ICSSSelector, String> resolvedSelectors =
- resolveSelectors(flexProject, cssDocument, problems, isFlex3CSS);
+ resolveSelectors(flexProject, cssDocument, problems, flexProject, isFlex3CSS);
final Predicate<ICSSRule> predicate;
if (isFlex3CSS)
{
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/projects/FlexProject.java b/compiler/src/main/java/org/apache/flex/compiler/internal/projects/FlexProject.java
index 602de21..c2d58c4 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/projects/FlexProject.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/projects/FlexProject.java
@@ -39,10 +39,12 @@
import org.apache.flex.compiler.asdoc.IASDocBundleDelegate;
import org.apache.flex.compiler.common.DependencyTypeSet;
import org.apache.flex.compiler.common.XMLName;
+import org.apache.flex.compiler.config.Configuration;
import org.apache.flex.compiler.config.RSLSettings;
import org.apache.flex.compiler.constants.IASLanguageConstants;
import org.apache.flex.compiler.constants.IMetaAttributeConstants;
import org.apache.flex.compiler.css.ICSSManager;
+import org.apache.flex.compiler.css.ICSSRule;
import org.apache.flex.compiler.definitions.IClassDefinition;
import org.apache.flex.compiler.definitions.IDefinition;
import org.apache.flex.compiler.definitions.IEffectDefinition;
@@ -1774,12 +1776,27 @@
@Override
public void setDefineDirectives(Map<String, String> defines)
{
+ overrideDefines(defines);
// TODO: This seems strange. Each call to the setter
// adds new defines. How do you get rid of the old ones?
addConfigVariables(defines);
clean();
}
+ protected void overrideDefines(Map<String, String> defines)
+ {
+ if (defines.containsKey("COMPILE::SWF"))
+ {
+ if (defines.get("COMPILE::SWF").equals("AUTO"))
+ defines.put("COMPILE::SWF", "true");
+ }
+ if (defines.containsKey("COMPILE::JS"))
+ {
+ if (defines.get("COMPILE::JS").equals("AUTO"))
+ defines.put("COMPILE::JS", "false");
+ }
+ }
+
@Override
public void setExtensionLibraries(Map<File, List<String>> extensions)
{
@@ -2129,12 +2146,13 @@
thisPackage = scopeDef.getPackageName();
else
{
- if (scope instanceof PackageScope)
- thisPackage = ((PackageScope)scope).getDefinition().getBaseName();
- else
+ while (!(scope instanceof PackageScope))
{
- return null;
+ scope = scope.getContainingScope();
}
+ if (!(scope instanceof PackageScope))
+ return null;
+ thisPackage = ((PackageScope)scope).getDefinition().getBaseName();
}
String package1 = def1.getPackageName();
String package2 = def2.getPackageName();
@@ -2283,7 +2301,72 @@
}
}
}
+ IMetaTag[] metas = func.getAllMetaTags();
+ for (IMetaTag meta : metas)
+ {
+ if (meta.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_SWFOVERRIDE))
+ {
+ IMetaTagAttribute attr = meta.getAttribute(IMetaAttributeConstants.NAME_SWFOVERRIDE_ALTPARAMS);
+ if (attr != null)
+ {
+ // format is expectedQName:allowedQName,expectedQName:allowedQName.
+ // we don't know which parameter it is so we're assuming for now that any mapping
+ // applies to all occurences of that type in the parameter list
+ String paramList = attr.getValue();
+ String[] paramMap;
+ if (paramList.contains(","))
+ paramMap = paramList.split(",");
+ else
+ {
+ paramMap = new String[1];
+ paramMap[0] = paramList;
+ }
+ for (String item : paramMap)
+ {
+ String[] parts = item.split(":");
+ if (expectedDefinition.getQualifiedName().equals(parts[0]))
+ if (((ITypeDefinition)actualDefinition).isInstanceOf(parts[1], this))
+ return true;
+ }
+ }
+ }
+ }
return false;
}
+ /**
+ * List of external libraries so it can be overridden
+ */
+ public List<String> getCompilerExternalLibraryPath(Configuration config)
+ {
+ List<String> list = config.getCompilerSwfExternalLibraryPath();
+ if (list != null && list.size() > 0)
+ return list;
+ return config.getCompilerExternalLibraryPath();
+ }
+
+ /**
+ * List of libraries so it can be overridden
+ */
+ public List<String> getCompilerLibraryPath(Configuration config)
+ {
+ List<String> list = config.getCompilerSwfLibraryPath();
+ if (list != null && list.size() > 0)
+ return list;
+ return config.getCompilerLibraryPath();
+ }
+
+ /**
+ * List of libraries so it can be overridden
+ */
+ public List<MXMLNamespaceMapping> getCompilerNamespacesManifestMappings(Configuration config)
+ {
+ return config.getCompilerNamespacesManifestMappings();
+ }
+
+ @Override
+ public boolean isPlatformRule(ICSSRule rule) {
+ return true;
+ }
+
}
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/semantics/SemanticUtils.java b/compiler/src/main/java/org/apache/flex/compiler/internal/semantics/SemanticUtils.java
index a67a880..aee5c33 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/semantics/SemanticUtils.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/semantics/SemanticUtils.java
@@ -832,7 +832,12 @@
public static boolean hasDynamicBase(Binding binding, ICompilerProject project)
{
ExpressionNodeBase base = getBaseNode(binding);
- return base != null && base.isDynamicExpression(project);
+ if (base != null && base.isDynamicExpression(project))
+ return true;
+ // the JS version of XML is not currently dynamic so special case it here.
+ if (base != null && base.getNodeID() == ASTNodeID.IdentifierID && IdentifierNode.isXMLish(base.resolveType(project), project))
+ return true;
+ return false;
}
/**
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/targets/SWFTarget.java b/compiler/src/main/java/org/apache/flex/compiler/internal/targets/SWFTarget.java
index 59afb54..06f932a 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/targets/SWFTarget.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/targets/SWFTarget.java
@@ -468,6 +468,7 @@
{
String base = name.getBaseName();
if (base == null) continue;
+ if (name.getQualifiers().length() != 1) continue;
Namespace ns = name.getSingleQualifier();
if (ns == null) continue;
String nsName = ns.getName();
@@ -526,6 +527,7 @@
{
String base = name.getBaseName();
if (base == null) continue;
+ if (name.getQualifiers().length() != 1) continue;
Namespace ns = name.getSingleQualifier();
if (ns == null) continue;
String nsName = ns.getName();
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/units/CompilationUnitBase.java b/compiler/src/main/java/org/apache/flex/compiler/internal/units/CompilationUnitBase.java
index 99d656e..0ae3bc0 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/internal/units/CompilationUnitBase.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/units/CompilationUnitBase.java
@@ -68,6 +68,7 @@
import org.apache.flex.compiler.internal.units.requests.SyntaxTreeRequestResult;
import org.apache.flex.compiler.mxml.IXMLNameResolver;
import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.InternalCompilerProblem;
import org.apache.flex.compiler.problems.InternalCompilerProblem2;
import org.apache.flex.compiler.projects.ICompilerProject;
import org.apache.flex.compiler.projects.IFlexProject;
@@ -168,7 +169,7 @@
{
final boolean isFlex3CSS = ((IFlexProject)project).getCSSManager().isFlex3CSS();
final ImmutableMap<ICSSSelector, String> resolvedSelectors =
- CSSSemanticAnalyzer.resolveSelectors(xmlNameResolver, cssDocument, problems, isFlex3CSS);
+ CSSSemanticAnalyzer.resolveSelectors(xmlNameResolver, cssDocument, problems, (IFlexProject) project, isFlex3CSS);
// Store resolved type selectors required by CSS code generation.
cssCompilationSession.resolvedSelectors.putAll(resolvedSelectors);
@@ -176,6 +177,8 @@
// Store resolved embed compilation units required by CSS code generation.
for (final ICSSRule cssRule : cssDocument.getRules())
{
+ if (project instanceof IFlexProject && !((IFlexProject)project).isPlatformRule(cssRule))
+ continue;
final Map<CSSFunctionCallPropertyValue, EmbedCompilationUnit> resolvedEmbedProperties =
new HashMap<CSSFunctionCallPropertyValue, EmbedCompilationUnit>();
CSSSemanticAnalyzer.resolveDependencies(
@@ -1052,8 +1055,22 @@
Collections.addAll(problems, getSyntaxTreeRequest().get().getProblems());
Collections.addAll(problems, getFileScopeRequest().get().getProblems());
Collections.addAll(problems, getOutgoingDependenciesRequest().get().getProblems());
- Collections.addAll(problems, getABCBytesRequest().get().getProblems());
- Collections.addAll(problems, getSWFTagsRequest().get().getProblems());
+ if (targetType == null)
+ {
+ ICompilerProblem[] probs = getABCBytesRequest().get().getProblems();
+ for (ICompilerProblem prob : probs)
+ {
+ if (!(prob instanceof InternalCompilerProblem2))
+ {
+ problems.add(prob);
+ }
+ }
+ }
+ else
+ {
+ Collections.addAll(problems, getABCBytesRequest().get().getProblems());
+ Collections.addAll(problems, getSWFTagsRequest().get().getProblems());
+ }
}
@Override
diff --git a/compiler/src/main/java/org/apache/flex/compiler/projects/IFlexProject.java b/compiler/src/main/java/org/apache/flex/compiler/projects/IFlexProject.java
index 2e61677..adf8817 100644
--- a/compiler/src/main/java/org/apache/flex/compiler/projects/IFlexProject.java
+++ b/compiler/src/main/java/org/apache/flex/compiler/projects/IFlexProject.java
@@ -27,11 +27,14 @@
import org.apache.flex.compiler.common.DependencyTypeSet;
import org.apache.flex.compiler.common.XMLName;
+import org.apache.flex.compiler.config.Configuration;
import org.apache.flex.compiler.config.RSLSettings;
import org.apache.flex.compiler.css.ICSSManager;
+import org.apache.flex.compiler.css.ICSSRule;
import org.apache.flex.compiler.exceptions.LibraryCircularDependencyException;
import org.apache.flex.compiler.internal.config.IWriteOnlyProjectSettings;
import org.apache.flex.compiler.internal.css.CSSManager;
+import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping;
import org.apache.flex.compiler.mxml.IXMLNameResolver;
import org.apache.flex.compiler.targets.ISWCTarget;
@@ -205,4 +208,25 @@
* <code>"library://ns.adobe.com/flex/spark"</code>.
*/
Collection<XMLName> getTagNamesForClass(String className);
+
+ /**
+ * List of external libraries so it can be overridden
+ */
+ List<String> getCompilerExternalLibraryPath(Configuration config);
+
+ /**
+ * List of libraries so it can be overridden
+ */
+ List<String> getCompilerLibraryPath(Configuration config);
+
+ /**
+ * List of external libraries so it can be overridden
+ */
+ List<MXMLNamespaceMapping> getCompilerNamespacesManifestMappings(Configuration config);
+
+ /**
+ * True if Rule will work on the destination platform
+ */
+ boolean isPlatformRule(ICSSRule rule);
+
}
diff --git a/env-template.properties b/env-template.properties
index 9a1f083..1afc86a 100644
--- a/env-template.properties
+++ b/env-template.properties
@@ -105,6 +105,11 @@
#env.ASJS_HOME=
#
+# Set this to the directory that contains Google Closure Library
+#
+#env.GOOG_HOME=
+
+#
# If you use a player global that is different that the default of 11.0,
# you need to set it here.
#env.PLAYERGLOBAL_VERSION=21.0
\ No newline at end of file
diff --git a/flex-compiler-oem/src/main/java/flex2/compiler/common/CompilerConfiguration.java b/flex-compiler-oem/src/main/java/flex2/compiler/common/CompilerConfiguration.java
index 4da4828..cce9fb6 100644
--- a/flex-compiler-oem/src/main/java/flex2/compiler/common/CompilerConfiguration.java
+++ b/flex-compiler-oem/src/main/java/flex2/compiler/common/CompilerConfiguration.java
@@ -617,6 +617,146 @@
};
}
+ //
+ // 'compiler.js-define' option
+ //
+
+ /**
+ * Syntax:<br/>
+ * <code>-define=<name>,<value></code>
+ * where name is <code>NAMESPACE::name</code> and value is a legal definition value
+ * (e.g. <code>true</code> or <code>1</code> or <code>!CONFIG::debugging</code>)
+ *
+ * Example: <code>-define=CONFIG::debugging,true</code>
+ *
+ * In <code>flex-config.xml</code>:<br/>
+ * <pre>
+ * <flex-config>
+ * <compiler>
+ * <define>
+ * <name>CONFIG::debugging</name>
+ * <value>true</value>
+ * </define>
+ * ...
+ * </compile>
+ * </flex-config>
+ * </pre>
+ *
+ * Values:<br/>
+ * Values are ActionScript expressions that must coerce and evaluate to constants at compile-time.
+ * Effectively, they are replaced in AS code, verbatim, so <code>-define=TEST::oneGreaterTwo,"1>2"</code>
+ * will get coerced and evaluated, at compile-time, to <code>false</code>.
+ *
+ * It is good practice to wrap values with double-quotes,
+ * so that MXMLC correctly parses them as a single argument:<br/>
+ * <code>-define=TEST::oneShiftRightTwo,"1 >> 2"</code>
+ *
+ * Values may contain compile-time constants and other configuration values:<br/>
+ * <code>-define=CONFIG::bool2,false -define=CONFIG::and1,"CONFIG::bool2 && false" TestApp.mxml</code>
+ *
+ * String values on the command-line <i>must</i> be surrounded by double-quotes, and either
+ * escape-quoted (<code>"\"foo\""</code> or <code>"\'foo\'"</code>) or single-quoted
+ * (<code>"'foo'"</code>).
+ *
+ * String values in configuration files need only be single- or double- quoted:<br/>
+ * <pre>
+ * <flex-config>
+ * <compiler>
+ * <define>
+ * <name>NAMES::Company</name>
+ * <value>'Apache Software Foundation'</value>
+ * </define>
+ * <define>
+ * <name>NAMES::Application</name>
+ * <value>"Flex 4.7"</value>
+ * </define>
+ * ...
+ * </compile>
+ * </flex-config>
+ * </pre>
+ *
+ * Empty strings <i>must</i> be passed as <code>"''"</code> on the command-line, and
+ * <code>''</code> or <code>""</code> in configuration files.
+ *
+ * Finally, if you have existing definitions in a configuration file, and you would
+ * like to add to them with the command-line (let's say most of your build settings
+ * are in the configuration, and that you are adding one temporarily using the
+ * command-line), you use the following syntax:
+ * <code>-define+=TEST::temporary,false</code> (noting the plus sign)
+ *
+ * Note that definitions can be overridden/redefined if you use the append ("+=") syntax
+ * (on the commandline or in a user config file, for instance) with the same namespace
+ * and name, and a new value.
+ *
+ * Definitions cannot be removed/undefined. You can undefine ALL existing definitions
+ * from (e.g. from flex-config.xml) if you do not use append syntax ("=" or append="false").
+ *
+ * IMPORTANT FOR FLEXBUILDER
+ * If you are using "Additional commandline arguments" to "-define", don't use the following
+ * syntax though I suggest it above:
+ * -define+=CONFIG::foo,"'value'"
+ * The trouble is that FB parses the double quotes incorrectly as <"'value'> -- the trailing
+ * double-quote is dropped. The solution is to avoid inner double-quotes and put them around the whole expression:
+ * -define+="CONFIG::foo,'value'"
+ */
+ private ObjectList<ConfigVar> jsconfigVars = new ObjectList<ConfigVar>();
+
+ /**
+ * @return A list of ConfigVars
+ */
+ public ObjectList<ConfigVar> jsgetDefine()
+ {
+ return configVars;
+ }
+
+ public void cfgJsDefine( ConfigurationValue _cv, final String _name, String _value )
+ throws ConfigurationException
+ {
+ assert _name != null;
+ assert _value != null;
+ assert _cv != null;
+
+ // macromedia.asc.embedding.Main.parseConfigVar(_name + "=" + _value)
+ final int ns_end = _name.indexOf("::");
+ if( (ns_end == -1) || (ns_end == 0) || (ns_end == _name.length()-2) )
+ {
+ throw new ConfigurationException.BadDefinition(_name + " " + _value,
+ _cv.getVar(),
+ _cv.getSource(),
+ _cv.getLine());
+ }
+
+ final String ns = _name.substring(0, ns_end);
+ final String name = _name.substring(ns_end + 2);
+
+ if (configVars == null)
+ {
+ configVars = new ObjectList<ConfigVar>();
+ }
+
+ // try removing any existing definition
+ for (final Iterator<ConfigVar> iter = configVars.iterator(); iter.hasNext();)
+ {
+ final ConfigVar other = iter.next();
+ if (ns.equals(other.ns) && name.equals(other.name))
+ {
+ iter.remove();
+ break;
+ }
+ }
+
+ configVars.add(new ConfigVar(ns, name, _value));
+ }
+
+ public static ConfigurationInfo getJsDefineInfo()
+ {
+ return new ConfigurationInfo(new String[] {"name", "value"})
+ {
+ public boolean allowMultiple() { return true; }
+ public boolean isAdvanced() { return true; }
+ };
+ }
+
//
// 'compiler.conservative' option (hidden)
//
@@ -851,6 +991,50 @@
}
//
+ // 'compiler.js-external-library-path' option
+ //
+
+ private VirtualFile[] jsexternalLibraryPath;
+
+ public VirtualFile[] getJsExternalLibraryPath()
+ {
+ return jsexternalLibraryPath;
+ }
+
+ public void cfgJsExternalLibraryPath( ConfigurationValue cv, String[] pathlist ) throws ConfigurationException
+ {
+ String[] locales = getLocales();
+ VirtualFile[] newPathElements = expandTokens(pathlist, locales, cv);
+ jsexternalLibraryPath = (VirtualFile[])merge(jsexternalLibraryPath, newPathElements, VirtualFile.class);
+ }
+
+ public static ConfigurationInfo getJsExternalLibraryPathInfo()
+ {
+ return new ConfigurationInfo( -1, new String[] { "path-element" } )
+ {
+ public boolean allowMultiple()
+ {
+ return true;
+ }
+
+ public String[] getSoftPrerequisites()
+ {
+ return PATH_TOKENS;
+ }
+
+ public boolean isPath()
+ {
+ return true;
+ }
+
+ public boolean doChecksum()
+ {
+ return false;
+ }
+ };
+ }
+
+ //
// 'compiler.fonts.*' options
//
@@ -1232,6 +1416,103 @@
}
//
+ // 'compiler.js-library-path' option
+ //
+
+ /**
+ * A list of SWC component libraries or directories containing SWCs.
+ * All SWCs found in the library-path are merged together
+ * and resolved via priority and version.
+ * The order in the library-path is ignored.
+ *
+ * The specified compiler.library-path can have path elements
+ * which contain a special {locale} token.
+ * If you compile for a single locale,
+ * this token is replaced by the specified locale.
+ * If you compile for multiple locales,
+ * any path element with the {locale} token
+ * is expanded into multiple path elements,
+ * one for each locale.
+ * If you compile for no locale,
+ * any path element with {locale} is ignored.
+ */
+ private VirtualFile[] jslibraryPath;
+
+ public VirtualFile[] getJsLibraryPath()
+ {
+ return jslibraryPath;
+ }
+
+ public void cfgJsLibraryPath( ConfigurationValue cv, String[] pathlist ) throws ConfigurationException
+ {
+ String[] locales = getLocales();
+ VirtualFile[] newPathElements = expandTokens(pathlist, locales, cv);
+ libraryPath = (VirtualFile[])merge(libraryPath, newPathElements, VirtualFile.class);
+ }
+
+ public static ConfigurationInfo getJsLibraryPathInfo()
+ {
+ return new ConfigurationInfo( -1, new String[] { "path-element" } )
+ {
+ public boolean allowMultiple()
+ {
+ return true;
+ }
+
+ public String[] getSoftPrerequisites()
+ {
+ return PATH_TOKENS;
+ }
+
+ public boolean isPath()
+ {
+ return true;
+ }
+
+ public boolean doChecksum()
+ {
+ return false;
+ }
+ };
+ }
+
+ //
+ // 'compiler.targets' option
+ //
+
+ /*
+ * This is never null. If you specify "no targets"
+ * it will compile to JS.
+ */
+ private String[] targets = new String[] {};
+
+ public String[] getTargets()
+ {
+ return targets;
+ }
+
+ public String targets()
+ {
+ return targets.length > 0 ? locales[0] : null;
+ }
+
+ public void cfgTargets( ConfigurationValue cv, String[] newTargets )
+ {
+ targets = (String[])merge(newTargets, targets, String.class);
+ }
+
+ public static ConfigurationInfo getTargetsInfo()
+ {
+ return new ConfigurationInfo( -1, new String[] { "target-element" } )
+ {
+ public boolean allowMultiple()
+ {
+ return true;
+ }
+ };
+ }
+
+ //
// 'compiler.locale' option
//
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/CommandLineConfiguration.java b/flex-compiler-oem/src/main/java/flex2/tools/CommandLineConfiguration.java
index b0a4f12..a158543 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/CommandLineConfiguration.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/CommandLineConfiguration.java
@@ -257,6 +257,26 @@
}
//
+ // 'js-output' option
+ //
+
+ public void cfgJsOutput(ConfigurationValue val, String output) throws ConfigurationException
+ {
+ this.output = Configuration.getOutputPath(val, output);
+ }
+
+ public static ConfigurationInfo getJsOutputInfo()
+ {
+ return new ConfigurationInfo(1, "filename")
+ {
+ public boolean isRequired()
+ {
+ return false;
+ }
+ };
+ }
+
+ //
// 'projector' option (hidden)
//
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/Compc.java b/flex-compiler-oem/src/main/java/flex2/tools/Compc.java
index 9186cbc..db8c1c2 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/Compc.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/Compc.java
@@ -42,7 +42,6 @@
public static int compcNoExit(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
- COMPILER = COMPC.class;
JS_COMPILER = CompJSC.class;
return compile(args);
@@ -50,7 +49,6 @@
public static void compc(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
- COMPILER = COMPC.class;
JS_COMPILER = CompJSC.class;
compile(args);
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/Mxmlc.java b/flex-compiler-oem/src/main/java/flex2/tools/Mxmlc.java
index 93ed8e2..c78f90b 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/Mxmlc.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/Mxmlc.java
@@ -61,7 +61,6 @@
public static int mxmlcNoExit(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
- COMPILER = MXMLC.class;
JS_COMPILER = MxmlJSC.class;
return compile(args);
@@ -69,7 +68,6 @@
public static void mxmlc(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
- COMPILER = MXMLC.class;
JS_COMPILER = MxmlJSC.class;
compile(args);
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/Tool.java b/flex-compiler-oem/src/main/java/flex2/tools/Tool.java
index 7d1f138..dc59a00 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/Tool.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/Tool.java
@@ -57,7 +57,6 @@
*/
public class Tool
{
- protected static Class<? extends MXMLC> COMPILER;
protected static Class<? extends MxmlJSC> JS_COMPILER;
protected static int compile(String[] args)
@@ -65,223 +64,14 @@
{
int exitCode;
- final String value = ArgumentUtil.getValue(args, "-js-output-type");
- JSOutputType jsOutputType = null;
+ MxmlJSC mxmlJSC = JS_COMPILER.newInstance();
+ exitCode = mxmlJSC.execute(args);
- if (value != null)
+ if (mxmlJSC.getProblemQuery().hasErrors())
{
- jsOutputType = JSOutputType.fromString(value);
+ processProblemReport(mxmlJSC);
}
- if (jsOutputType != null)
- {
- ArgumentBag bag = prepareJs(new ArgumentBag(args));
-
- MxmlJSC mxmlJSC = JS_COMPILER.newInstance();
- exitCode = mxmlJSC.execute(bag.args);
-
- if (!mxmlJSC.getProblemQuery().hasErrors())
- {
- if (jsOutputType.equals(FLEXJS_DUAL))
- {
- prepareAs3(bag);
- exitCode = flexCompile(bag.args);
- }
- }
- else
- {
- processProblemReport(mxmlJSC);
- }
- }
- else
- {
- exitCode = flexCompile(args);
- }
-
- return exitCode;
- }
-
- protected static ArgumentBag prepareJs(ArgumentBag bag)
- {
- SwitchDefineToCompileJs(bag);
- prepareJsOutput(bag);
-
- return bag;
- }
-
- protected static ArgumentBag prepareAs3(ArgumentBag bag)
- {
- SwitchDefineToCompileAs3(bag);
- prepareAs3Output(bag);
- removeNativeJSLibraries(bag);
-
- return bag;
- }
-
- private static void removeNativeJSLibraries(ArgumentBag bag)
- {
- final List<String> argList = new ArrayList<String>(Arrays.asList(bag.args));
- argList.add("--exclude-native-js-libraries=true");
- bag.args = argList.toArray(new String[argList.size()]);
- }
-
- private static void prepareJsOutput(ArgumentBag bag)
- {
- bag.isCommandLineOutput = true;
- bag.oldOutputPath = ArgumentUtil.getValue(bag.args, "-output");
-
- if (bag.oldOutputPath == null)
- {
- bag.oldOutputPath = ArgumentUtil.getValue(bag.args, "-o");
- if (bag.oldOutputPath != null)
- {
- bag.outputAlias = "-o";
- }
- }
- else
- {
- bag.outputAlias = "-output";
- }
-
- if (bag.oldOutputPath == null)
- {
- bag.isCommandLineOutput = false;
- List<ConfigurationBuffer> flexConfigs = null;
-
- try
- {
- flexConfigs = loadConfig(bag.args);
-
- for (ConfigurationBuffer flexConfig : flexConfigs)
- {
- if (bag.oldOutputPath == null) {
- final List<ConfigurationValue> output = flexConfig != null ? flexConfig.getVar("output") : null;
- final ConfigurationValue configurationValue = output != null ? output.get(0) : null;
- bag.oldOutputPath = configurationValue != null ? configurationValue.getArgs().get(0)
- : bag.oldOutputPath;
- }
- }
- }
- catch (org.apache.flex.compiler.exceptions.ConfigurationException ignored)
- {
- }
- }
-
- if (bag.oldOutputPath != null)
- {
- final int lastIndexOf = Math.max(bag.oldOutputPath.lastIndexOf("/"), bag.oldOutputPath.lastIndexOf("\\"));
-
- if (lastIndexOf > -1)
- {
- bag.newOutputPath = bag.oldOutputPath.substring(0, lastIndexOf) + File.separator + "js" + File.separator
- + "out";
-
- if (bag.isCommandLineOutput)
- {
- ArgumentUtil.setValue(bag.args, bag.outputAlias, bag.newOutputPath);
- }
- else
- {
- bag.args = ArgumentUtil.addValue(bag.args, "-output", bag.newOutputPath);
- }
- }
- }
- }
-
- private static void SwitchDefineToCompileJs(ArgumentBag bag)
- {
- final Collection<String> defines = ArgumentUtil.getValues(bag.args, "-define");
- if (defines.contains("COMPILE::AS3,AUTO") && defines.contains("COMPILE::JS,AUTO"))
- {
- bag.args = ArgumentUtil.removeElementWithValue(bag.args, "-define", "COMPILE::JS,AUTO");
- bag.args = ArgumentUtil.removeElementWithValue(bag.args, "-define", "COMPILE::AS3,AUTO");
-
- bag.args = ArgumentUtil.addValue(bag.args, "-define", "COMPILE::JS,true", true);
- bag.args = ArgumentUtil.addValue(bag.args, "-define", "COMPILE::AS3,false", true);
-
- bag.args = ArgumentUtil.addValue(bag.args, "-keep-asdoc", null);
- }
- }
-
- private static void prepareAs3Output(ArgumentBag bag)
- {
- if (bag.oldOutputPath != null)
- {
- if (bag.isCommandLineOutput)
- {
- ArgumentUtil.setValue(bag.args, bag.outputAlias, bag.oldOutputPath);
- }
- else
- {
- bag.args = ArgumentUtil.removeElement(bag.args, "-output");
- }
- }
-
- if (COMPILER.getName().equals(COMPC.class.getName()))
- {
- bag.args = ArgumentUtil.addValue(bag.args, "-include-file",
- "js" + File.separator + "out" + File.separator + "*," + bag.newOutputPath);
- }
- }
-
- private static void SwitchDefineToCompileAs3(ArgumentBag bag)
- {
- final Collection<String> defines = ArgumentUtil.getValues(bag.args, "-define");
- if (defines.contains("COMPILE::AS3,false") && defines.contains("COMPILE::JS,true"))
- {
- bag.args = ArgumentUtil.removeElement(bag.args, "-keep-asdoc");
- bag.args = ArgumentUtil.removeElementWithValue(bag.args, "-define", "COMPILE::AS3,false");
- bag.args = ArgumentUtil.removeElementWithValue(bag.args, "-define", "COMPILE::JS,true");
-
- bag.args = ArgumentUtil.addValue(bag.args, "-define", "COMPILE::JS,false", true);
- bag.args = ArgumentUtil.addValue(bag.args, "-define", "COMPILE::AS3,true", true);
- }
-
- bag.args = ArgumentUtil.removeElement(bag.args, "-js-output-type");
- }
-
- private static List<ConfigurationBuffer> loadConfig(String[] args)
- throws org.apache.flex.compiler.exceptions.ConfigurationException
- {
- List<ConfigurationBuffer> configurationBuffers = null;
-
- final Collection<String> configFilePaths = ArgumentUtil.getValues(args, "-load-config");
- if (configFilePaths != null)
- {
- for (String configFilePath : configFilePaths)
- {
- final File configFile = new File(configFilePath);
- final FileSpecification fileSpecification = new FileSpecification(configFile.getAbsolutePath());
- final ConfigurationBuffer cfgbuf = createConfigurationBuffer(Configuration.class);
-
- FileConfigurator.load(cfgbuf, fileSpecification, new File(configFile.getPath()).getParent(),
- "flex-config", false);
-
- if (configurationBuffers == null)
- {
- configurationBuffers = new ArrayList<ConfigurationBuffer>(0);
- }
- configurationBuffers.add(cfgbuf);
- }
- }
-
- return configurationBuffers;
- }
-
- private static ConfigurationBuffer createConfigurationBuffer(Class<? extends Configuration> configurationClass)
- {
- return new ConfigurationBuffer(configurationClass, Configuration.getAliases());
- }
-
- protected static int flexCompile(String[] args)
- throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
- {
- int exitCode;
-
- MXMLC mxmlc = COMPILER.newInstance();
- exitCode = mxmlc.execute(args);
- processProblemReport(new CompilerRequestableProblems(mxmlc));
-
return exitCode;
}
@@ -444,34 +234,4 @@
}
}
- static class CompilerRequestableProblems implements ProblemQueryProvider
- {
- private MXMLC mxmlc;
-
- public CompilerRequestableProblems(MXMLC mxmlc)
- {
- this.mxmlc = mxmlc;
- }
-
- @Override
- public ProblemQuery getProblemQuery()
- {
- return mxmlc.getProblems();
- }
- }
-
- protected static class ArgumentBag
- {
- public String[] args;
-
- public String outputAlias;
- public String oldOutputPath;
- public String newOutputPath;
- public boolean isCommandLineOutput;
-
- public ArgumentBag(String[] args)
- {
- this.args = args;
- }
- }
}
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/oem/Application.java b/flex-compiler-oem/src/main/java/flex2/tools/oem/Application.java
index 5c5cfe5..0d9a307 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/oem/Application.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/oem/Application.java
@@ -33,7 +33,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import org.apache.flex.compiler.clients.MXMLC;
+import org.apache.flex.compiler.clients.MXMLJSC;
import org.apache.flex.compiler.clients.problems.ProblemFormatter;
import org.apache.flex.compiler.clients.problems.ProblemQuery;
import org.apache.flex.compiler.problems.CompilerProblemSeverity;
@@ -56,6 +56,7 @@
import flex2.compiler.util.ThreadLocalToolkit;
import flex2.linker.SimpleMovie;
import flex2.tools.ToolsConfiguration;
+import flex2.tools.oem.internal.ApplicationCompilerConfiguration;
import flex2.tools.oem.internal.OEMConfiguration;
import flex2.tools.oem.internal.OEMReport;
import flex2.tools.oem.internal.OEMUtil;
@@ -300,6 +301,8 @@
// clean() would null out the following variables.
private String cacheName, configurationReport;
private List<Message> messages;
+ private boolean setOutputCalled;
+ private int loaded = 0;
/**
* @inheritDoc
@@ -378,6 +381,7 @@
*/
public void setOutput(File output)
{
+ setOutputCalled = true;
this.output = output;
}
@@ -533,6 +537,9 @@
*/
public void clean()
{
+ // assuming FB takes care of deleting bin-release and bin-debug, we want to delete bin.
+ // but this also gets called when quitting FB.
+ setOutputCalled = false;
}
/**
@@ -540,6 +547,7 @@
*/
public void load(InputStream in) throws IOException
{
+ loaded++;
}
/**
@@ -547,6 +555,7 @@
*/
public long save(OutputStream out) throws IOException
{
+ loaded--;
return 1;
}
@@ -622,15 +631,16 @@
//Map licenseMap = OEMUtil.getLicenseMap(tempOEMConfiguration.configuration);
- mxmlc = new MXMLC();
+ mxmljsc = new MXMLJSC();
+ mxmljsc.noLink = true;
//int returnValue = mxmlc.mainCompileOnly(constructCommandLine2(tempOEMConfiguration.configuration), null);
- int returnValue = mxmlc.mainCompileOnly(constructCommandLine(oemConfiguration), null);
+ int returnValue = mxmljsc.mainNoExit(constructCommandLine(oemConfiguration), null, true);
if (returnValue == 0)
returnValue = OK;
else
returnValue = FAIL;
- processMXMLCReport(mxmlc, tempOEMConfiguration);
+ processMXMLCReport(mxmljsc, tempOEMConfiguration);
clean(returnValue == FAIL /* cleanData */,
false /* cleanCache */,
@@ -650,22 +660,21 @@
public long link(OutputStream output)
{
- return mxmlc.writeSWF(output);
+ return mxmljsc.writeSWF(output);
}
- private MXMLC mxmlc = new MXMLC();
+ private MXMLJSC mxmljsc = new MXMLJSC();
private List<Source> sources;
private SimpleMovie movie;
private SourceList sourceList;
- void processMXMLCReport(MXMLC mxmlc, OEMConfiguration config)
+ void processMXMLCReport(MXMLJSC mxmljsc, OEMConfiguration config)
{
- /* not sure we need this
ApplicationCompilerConfiguration acc = ((ApplicationCompilerConfiguration)config.configuration);
sources = new ArrayList<Source>();
VirtualFile[] sourcePaths = acc.getCompilerConfiguration().getSourcePath();
- List<String> sourceFiles = mxmlc.getSourceList();
- String mainFile = mxmlc.getMainSource();
+ List<String> sourceFiles = mxmljsc.getSourceList();
+ String mainFile = mxmljsc.getMainSource();
for (String sourceFile : sourceFiles)
{
for (VirtualFile sourcePath : sourcePaths)
@@ -684,8 +693,7 @@
}
}
}
- */
- ProblemQuery pq = mxmlc.getProblems();
+ ProblemQuery pq = mxmljsc.getProblemQuery();
List<ICompilerProblem> probs = pq.getProblems();
for (ICompilerProblem prob : probs)
{
@@ -774,7 +782,7 @@
}
}
- ISWF swf = mxmlc.getSWFTarget();
+ ISWF swf = mxmljsc.getSWFTarget();
movie = new SimpleMovie(null);
org.apache.flex.swf.types.Rect r = swf.getFrameSize();
flash.swf.types.Rect fr = new flash.swf.types.Rect();
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/ConfigurationConstants.java b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/ConfigurationConstants.java
index 1d59834..8f4a64d 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/ConfigurationConstants.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/ConfigurationConstants.java
@@ -28,6 +28,7 @@
interface ConfigurationConstants
{
String USE_NETWORK = "--use-network";
+ String REMOVE_CIRCULARS = "--remove-circulars";
String RUNTIME_SHARED_LIBRARIES = "--runtime-shared-libraries";
String RAW_METADATA = "--raw-metadata";
String PROJECTOR = "--projector";
@@ -38,6 +39,7 @@
String METADATA_DATE = "--metadata.date";
String METADATA_CREATOR = "--metadata.creator";
String METADATA_CONTRIBUTOR = "--metadata.contributor";
+ String JS_OUTPUT = "--js-output";
String LINK_REPORT = "--link-report";
String SIZE_REPORT = "--size-report";
String LICENSES_LICENSE = "--licenses.license";
@@ -104,7 +106,9 @@
String COMPILER_NAMESPACES_NAMESPACE = "--compiler.namespaces.namespace";
String COMPILER_MOBILE = "--compiler.mobile";
String COMPILER_LOCALE = "--compiler.locale";
+ String COMPILER_TARGETS = "--compiler.targets";
String COMPILER_LIBRARY_PATH = "--compiler.library-path";
+ String COMPILER_JS_LIBRARY_PATH = "--compiler.js-library-path";
String COMPILER_INCLUDE_LIBRARIES = "--compiler.include-libraries";
String COMPILER_KEEP_GENERATED_ACTIONSCRIPT = "--compiler.keep-generated-actionscript";
String COMPILER_KEEP_AS3_METADATA = "--compiler.keep-as3-metadata";
@@ -119,6 +123,7 @@
String COMPILER_FONTS_FLASH_TYPE = "--compiler.fonts.flash-type";
String COMPILER_FONTS_ADVANCED_ANTI_ALIASING = "--compiler.fonts.advanced-anti-aliasing";
String COMPILER_EXTERNAL_LIBRARY_PATH = "--compiler.external-library-path";
+ String COMPILER_JS_EXTERNAL_LIBRARY_PATH = "--compiler.js-external-library-path";
String COMPILER_ES = "--compiler.es";
String COMPILER_DEFAULTS_CSS_URL = "--compiler.defaults-css-url";
String COMPILER_DEBUG = "--compiler.debug";
@@ -133,6 +138,7 @@
String VERIFY_DIGESTS = "--verify-digests";
String COMPILER_COMPUTE_DIGEST = "--compute-digest";
String COMPILER_DEFINE = "--compiler.define";
+ String COMPILER_JS_DEFINE = "--compiler.js-define";
String COMPILER_MXML_COMPATIBILITY = "--compiler.mxml.compatibility-version";
String COMPILER_EXTENSIONS = "--compiler.extensions.extension";
String REMOVE_UNUSED_RSLS = "--remove-unused-rsls";
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMConfiguration.java b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMConfiguration.java
index f8f3ff1..f141fd8 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMConfiguration.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMConfiguration.java
@@ -978,6 +978,11 @@
addFiles(COMPILER_LIBRARY_PATH, paths);
}
+ public void setTargets(String[] targets)
+ {
+ args.put(COMPILER_TARGETS, targets);
+ }
+
/**
* Sets the locales that the compiler would use to replace <code>{locale}</code> tokens that appear in some configuration values.
* This is equivalent to using <code>mxmlc/compc --compiler.locale</code>.
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMReport.java b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMReport.java
index c39aa25..21b1d73 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMReport.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMReport.java
@@ -24,6 +24,7 @@
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -158,7 +159,7 @@
if (sources != null)
{
- //processSources(sources, sourceNames, assetNames, libraryNames, data, locations);
+ processSources(sources, sourceNames, assetNames, libraryNames, data, locations);
}
timestamps = new HashMap<String, Long>();
@@ -292,10 +293,6 @@
public boolean contentUpdated()
{
- // AJH for now, just return true to force another build. Someday be smarter about what sources
- // we have and what their time stamps are.
- return true;
- /*
for (Iterator<String> i = timestamps.keySet().iterator(); i.hasNext(); )
{
String path = i.next();
@@ -308,7 +305,6 @@
}
}
return false;
- */
}
public String[] getSourceNames(Object report)
@@ -526,10 +522,18 @@
}
}
}
+ */
private void processSources(List<Source> sources, TreeSet<String> sourceNames, TreeSet<String> assetNames,
TreeSet<String> libraryNames, Map<String, Data> data, Map<String, String> locations)
{
+ // use this version for now
+ for (Source s : sources)
+ {
+ sourceNames.add(s.getName());
+ }
+ /*
+ // AJH not sure why all this is needed
for (Source s : sources)
{
CompilationUnit u = (s == null) ? null : s.getCompilationUnit();
@@ -609,8 +613,10 @@
data.put(s.getName(), d);
}
}
+ */
}
+ /*
private void processFrames(SimpleMovie movie)
{
int count = movie == null ? 0 : movie.frames.size();
diff --git a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMUtil.java b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMUtil.java
index e530ce3..b6e1d5b 100644
--- a/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMUtil.java
+++ b/flex-compiler-oem/src/main/java/flex2/tools/oem/internal/OEMUtil.java
@@ -40,8 +40,8 @@
import flex2.tools.ToolsConfiguration;
import flex2.tools.oem.*;
-import org.apache.flex.compiler.clients.COMPC;
-import org.apache.flex.compiler.clients.MXMLC;
+import org.apache.flex.compiler.clients.COMPJSC;
+import org.apache.flex.compiler.clients.MXMLJSC;
/**
* A collection of utility methods used by classes in flex2.tools.oem.
@@ -145,7 +145,7 @@
ApplicationCompilerConfiguration.getAliases());
cfgbuf.setDefaultVar("--file-specs" /*Mxmlc.FILE_SPECS*/);
DefaultsConfigurator.loadDefaults(cfgbuf);
- MXMLC mxmlc = new MXMLC();
+ MXMLJSC mxmlc = new MXMLJSC();
mxmlc.configure(args);
ApplicationCompilerConfiguration configuration = processMXMLCConfiguration(mxmlc.config);
@@ -212,6 +212,30 @@
// TODO Auto-generated catch block
e.printStackTrace();
}
+ List<String> libraries = config.getCompilerLibraryPath();
+ String[] libs = new String[libraries.size()];
+ libraries.toArray(libs);
+ try
+ {
+ cc.cfgLibraryPath(null, libs);
+ }
+ catch (ConfigurationException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ List<String> sources = config.getCompilerSourcePath();
+ String[] srcs = new String[sources.size()];
+ sources.toArray(srcs);
+ try
+ {
+ cc.cfgSourcePath(null, srcs);
+ }
+ catch (ConfigurationException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
return acc;
}
@@ -271,7 +295,7 @@
ConfigurationBuffer cfgbuf = new ConfigurationBuffer(LibraryCompilerConfiguration.class,
LibraryCompilerConfiguration.getAliases());
DefaultsConfigurator.loadOEMCompcDefaults( cfgbuf );
- COMPC compc = new COMPC();
+ COMPJSC compc = new COMPJSC();
compc.configure(args);
LibraryCompilerConfiguration configuration = processCOMPCCConfiguration(compc.config);
configuration.keepLinkReport(keepLinkReport);
@@ -331,7 +355,7 @@
ApplicationCompilerConfiguration.getAliases());
cfgbuf.setDefaultVar("--file-specs" /*Mxmlc.FILE_SPECS*/);
DefaultsConfigurator.loadDefaults(cfgbuf);
- MXMLC mxmlc = new MXMLC();
+ MXMLJSC mxmlc = new MXMLJSC();
mxmlc.configure(args);
ApplicationCompilerConfiguration configuration = processMXMLCConfiguration(mxmlc.config);
diff --git a/flexjs-ant-tasks/build.xml b/flexjs-ant-tasks/build.xml
index 1b9258f..193db3b 100644
--- a/flexjs-ant-tasks/build.xml
+++ b/flexjs-ant-tasks/build.xml
@@ -46,8 +46,8 @@
<!-- The 'sdk' property is the absolute path, with forward slashes, to the compiler/lib directory -->
<!-- where a Falcon SDK is built -->
<!-- All output paths are expressed as absolute paths starting with ${sdk} -->
- <property name="sdk" value="${flextasks}/../compiler/lib"/>
- <property name="compiler" value="${flextasks}/../compiler"/>
+ <property name="sdk" value="${flextasks}/../compiler-jx/lib"/>
+ <property name="compiler" value="${flextasks}/../compiler-jx"/>
<property name="src.depend" value="true"/>
@@ -76,7 +76,7 @@
-->
<path id="classpath">
- <fileset dir="${compiler}/lib/external" includes="**/*.jar"/>
+ <fileset dir="${compiler}/lib" includes="**/*.jar"/>
<fileset dir="${compiler}/../compiler-build-tools/target/classes" includes="**/*.class"/>
</path>
@@ -116,7 +116,7 @@
<attribute name="Implementation-Title" value="${manifest.Implementation-Title} - ant Tasks"/>
<attribute name="Implementation-Version" value="${manifest.Implementation-Version}.${build.number}"/>
<attribute name="Implementation-Vendor" value="${manifest.Implementation-Vendor}"/>
- <attribute name="Class-Path" value="compiler.jar"/>
+ <attribute name="Class-Path" value="jsc.jar ../../compiler/lib/compiler.jar ../../lib/compiler.jar"/>
</manifest>
<fileset dir="${flextasks}/src/main/resources" includes="flexTasks.tasks"/>
<fileset dir="${flextasks}/target/classes" includes="${flextasks.ant.binaries}"/>
@@ -153,7 +153,7 @@
<target name="clean" description="clean">
<delete dir="${flextasks}/target" failonerror="false"/>
- <delete dir="${sdk}/falcon-flextasks.jar" failonerror="false"/>
+ <delete file="${sdk}/falcon-flextasks.jar" failonerror="false"/>
</target>
<target name="wipe" depends="clean" description="Wipes everything that didn't come from Git.">
diff --git a/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/COMPCTask.java b/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/COMPCTask.java
index 71ddc25..178e227 100644
--- a/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/COMPCTask.java
+++ b/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/COMPCTask.java
@@ -82,9 +82,9 @@
private static final String TASK_NAME = "compc";
- private static final String TOOL_JAR_FILE_NAME = "compiler.jar";
+ private static final String TOOL_JAR_FILE_NAME = "jsc.jar";
- private static final String TOOL_CLASS_NAME = "org.apache.flex.compiler.clients.COMPC";
+ private static final String TOOL_CLASS_NAME = "org.apache.flex.compiler.clients.COMPJSC";
private static final String TOOL_METHOD_NAME = "staticMainNoExit";
@@ -175,6 +175,7 @@
new ConfigString(new OptionSpec("compiler.locale")),
new ConfigString(new OptionSpec("compiler.minimum-supported-version", "msv")),
new ConfigString(new OptionSpec("compiler.services")),
+ new ConfigString(new OptionSpec("compiler.targets")),
new ConfigString(new OptionSpec("debug-password")),
new ConfigString(new OptionSpec("dump-config")),
new ConfigString(new OptionSpec("link-report")),
@@ -215,12 +216,24 @@
private static final OptionSpec EXTERNAL_LIBRARY_PATH =
new OptionSpec("compiler.external-library-path", "el");
+ private static final OptionSpec JS_EXTERNAL_LIBRARY_PATH =
+ new OptionSpec("compiler.js-external-library-path");
+
+ private static final OptionSpec SWF_EXTERNAL_LIBRARY_PATH =
+ new OptionSpec("compiler.swf-external-library-path");
+
private static final OptionSpec INCLUDE_LIBRARIES =
new OptionSpec("compiler.include-libraries");
private static final OptionSpec LIBRARY_PATH =
new OptionSpec("compiler.library-path", "l");
+ private static final OptionSpec JS_LIBRARY_PATH =
+ new OptionSpec("compiler.js-library-path");
+
+ private static final OptionSpec SWF_LIBRARY_PATH =
+ new OptionSpec("compiler.swf-library-path");
+
private static final OptionSpec SOURCE_PATH =
new OptionSpec("compiler.source-path", "sp");
@@ -420,6 +433,18 @@
nestedFileSets.add(fs);
return fs;
}
+ else if (JS_EXTERNAL_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(JS_EXTERNAL_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
+ else if (SWF_EXTERNAL_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(SWF_EXTERNAL_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
else if (INCLUDE_LIBRARIES.matches(name))
{
FlexFileSet fs = new FlexSWCFileSet(INCLUDE_LIBRARIES, true);
@@ -432,6 +457,18 @@
nestedFileSets.add(fs);
return fs;
}
+ else if (JS_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(JS_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
+ else if (SWF_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(SWF_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
else if (THEME.matches(name))
{
FlexFileSet fs = new FlexFileSet(THEME);
diff --git a/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/FlexTask.java b/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/FlexTask.java
index 6b32540..fb84a89 100644
--- a/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/FlexTask.java
+++ b/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/FlexTask.java
@@ -237,9 +237,9 @@
if (flexHomeProperty == null)
throw new BuildException("FLEX_HOME must be set to use the Flex Ant Tasks");
- String falconHomeProperty = getProject().getProperty("FALCON_HOME");
+ String falconHomeProperty = getProject().getProperty("FALCONJX_HOME");
if (falconHomeProperty == null)
- throw new BuildException("FALCON_HOME must be set to use the Flex Ant Tasks");
+ throw new BuildException("FALCONJX_HOME must be set to use the Flex Ant Tasks");
System.setProperty("FLEX_HOME", flexHomeProperty);
String flexlibProperty = flexHomeProperty.concat("/frameworks/");
@@ -361,7 +361,7 @@
}
catch (ClassNotFoundException ignoredClassNotFoundException)
{
- String flexHomeProperty = getProject().getProperty("FALCON_HOME");
+ String flexHomeProperty = getProject().getProperty("FALCONJX_HOME");
if (flexHomeProperty != null)
{
@@ -408,7 +408,7 @@
else
{
throw new BuildException("The class, " + className +
- ", must be in the classpath or the FALCON_HOME property must be set.",
+ ", must be in the classpath or the FALCONJX_HOME property must be set.",
getLocation());
}
}
diff --git a/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/MXMLCTask.java b/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/MXMLCTask.java
index 5df9ddd..613ac2a 100644
--- a/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/MXMLCTask.java
+++ b/flexjs-ant-tasks/src/main/java/org/apache/flex/compiler/ant/MXMLCTask.java
@@ -80,9 +80,9 @@
private static final String TASK_NAME = "mxmlc";
- private static final String TOOL_JAR_FILE_NAME = "compiler.jar";
+ private static final String TOOL_JAR_FILE_NAME = "jsc.jar";
- private static final String TOOL_CLASS_NAME = "org.apache.flex.compiler.clients.MXMLC";
+ private static final String TOOL_CLASS_NAME = "org.apache.flex.compiler.clients.MXMLJSC";
private static final String TOOL_METHOD_NAME = "staticMainNoExit";
@@ -158,6 +158,7 @@
new ConfigBoolean(new OptionSpec("compiler.warn-unlikely-function-value")),
new ConfigBoolean(new OptionSpec("compiler.warn-xml-class-has-changed")),
new ConfigBoolean(new OptionSpec("static-link-runtime-shared-libraries", "static-rsls")),
+ new ConfigBoolean(new OptionSpec("skip-transpile")),
new ConfigBoolean(new OptionSpec("verify-digests")),
new ConfigBoolean(new OptionSpec("use-direct-blit")),
new ConfigBoolean(new OptionSpec("use-gpu")),
@@ -170,6 +171,8 @@
new ConfigString(new OptionSpec("compiler.locale")),
new ConfigString(new OptionSpec("compiler.mxml.compatibility-version")),
new ConfigString(new OptionSpec("compiler.services")),
+ new ConfigString(new OptionSpec("compiler.targets")),
+ new ConfigString(new OptionSpec("closure-lib")),
new ConfigString(new OptionSpec("debug-password")),
new ConfigString(new OptionSpec("dump-config")),
new ConfigString(new OptionSpec("link-report")),
@@ -215,12 +218,24 @@
private static final OptionSpec EXTERNAL_LIBRARY_PATH =
new OptionSpec("compiler.external-library-path", "el");
+ private static final OptionSpec JS_EXTERNAL_LIBRARY_PATH =
+ new OptionSpec("compiler.js-external-library-path");
+
+ private static final OptionSpec SWF_EXTERNAL_LIBRARY_PATH =
+ new OptionSpec("compiler.swf-external-library-path");
+
private static final OptionSpec INCLUDE_LIBRARIES =
new OptionSpec("compiler.include-libraries");
private static final OptionSpec LIBRARY_PATH =
new OptionSpec("compiler.library-path", "l");
+ private static final OptionSpec JS_LIBRARY_PATH =
+ new OptionSpec("compiler.js-library-path", "l");
+
+ private static final OptionSpec SWF_LIBRARY_PATH =
+ new OptionSpec("compiler.swf-library-path");
+
private static final OptionSpec SOURCE_PATH =
new OptionSpec("compiler.source-path", "sp");
@@ -409,6 +424,18 @@
nestedFileSets.add(fs);
return fs;
}
+ else if (JS_EXTERNAL_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(JS_EXTERNAL_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
+ else if (SWF_EXTERNAL_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(SWF_EXTERNAL_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
else if (INCLUDE_LIBRARIES.matches(name))
{
FlexFileSet fs = new FlexSWCFileSet(INCLUDE_LIBRARIES, true);
@@ -421,6 +448,18 @@
nestedFileSets.add(fs);
return fs;
}
+ else if (JS_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(JS_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
+ else if (SWF_LIBRARY_PATH.matches(name))
+ {
+ FlexFileSet fs = new FlexSWCFileSet(SWF_LIBRARY_PATH, true);
+ nestedFileSets.add(fs);
+ return fs;
+ }
else if (THEME.matches(name))
{
FlexFileSet fs = new FlexFileSet(THEME);
diff --git a/flexjs-ant-tasks/src/test/build.xml b/flexjs-ant-tasks/src/test/build.xml
index f6d1c7a..4dc0989 100644
--- a/flexjs-ant-tasks/src/test/build.xml
+++ b/flexjs-ant-tasks/src/test/build.xml
@@ -31,8 +31,26 @@
<property file="../../../env.properties" />
<property name="test.timeout" value="3000000" />
<property name="maxmem" value="512" />
+
+ <condition property="GOOG_HOME" value="${env.GOOG_HOME}">
+ <and>
+ <not>
+ <isset property="GOOG_HOME" />
+ </not>
+ <available file="${env.GOOG_HOME}/closure/goog/base.js" type="file" />
+ </and>
+ </condition>
+
+ <condition property="GOOG_HOME" value="${FLEXJS_HOME}/js/lib/google/closure-library">
+ <and>
+ <not>
+ <isset property="GOOG_HOME" />
+ </not>
+ <available file="${FLEXJS_HOME}/js/lib/google/closure-library/closure/goog/base.js" type="file" />
+ </and>
+ </condition>
- <property name="compiler" value="${flextasks.tests}/../../../compiler"/>
+ <property name="compiler" value="${flextasks.tests}/../../../compiler-jx"/>
<condition property="flexsdk" value="${FLEX_HOME}" else="${env.FLEX_HOME}">
<isset property="FLEX_HOME" />
</condition>
@@ -46,22 +64,27 @@
<path id="lib.path">
<fileset dir="${falcon}/lib" includes="falcon-flexTasks.jar"/>
- <fileset dir="${falcon}/lib" includes="compiler.jar"/>
+ <fileset dir="${falcon}/lib" includes="jsc.jar"/>
</path>
<target name="ant.tests">
<property name="FLEX_HOME" value="${flexsdk}"/>
- <property name="FALCON_HOME" value="${falcon}"/>
+ <property name="FALCONJX_HOME" value="${falcon}"/>
+ <echo message="GOOG_HOME: ${GOOG_HOME}"/>
<echo>FLEX_HOME=${flexsdk}</echo>
- <echo>FALCON_HOME=${falcon}</echo>
+ <echo>FALCONJX_HOME=${FALCONJX_HOME}</echo>
<taskdef resource="flexTasks.tasks" classpathref="lib.path"/>
<mxmlc file="${flextasks.tests}/as/Hello.as"
output="${flextasks}/target/junit/Hello.swf"
+ compiler.targets="SWF"
+ closure-lib="${GOOG_HOME}"
target-player="${playerglobal.version}">
<arg value="+env.PLAYERGLOBAL_HOME=${env.PLAYERGLOBAL_HOME}" />
</mxmlc>
<delete file="${flextasks}/target/junit/Hello.swf"/>
- <compc output="${flextasks}/target/junit/Hello.swc" include-classes="Hello" target-player="${playerglobal.version}">
+ <compc output="${flextasks}/target/junit/Hello.swc" include-classes="Hello"
+ compiler.targets="SWF"
+ target-player="${playerglobal.version}">
<source-path path-element="${flextasks.tests}/as"/>
<arg value="+env.PLAYERGLOBAL_HOME=${env.PLAYERGLOBAL_HOME}" />
</compc>
diff --git a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/BaseMojo.java b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/BaseMojo.java
index f294d2f..315c8c1 100644
--- a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/BaseMojo.java
+++ b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/BaseMojo.java
@@ -86,7 +86,7 @@
protected boolean failOnCompilerWarnings = false;
@Parameter
- protected boolean allowSubclassOverrides = false;
+ protected boolean allowSubclassOverrides = true;
@Parameter
private Boolean includeLookupOnly = null;
@@ -115,14 +115,19 @@
project, repositorySystemSession, projectDependenciesResolver);
List<Artifact> filteredLibraries = getFilteredLibraries(allLibraries);
List<Artifact> libraries = getLibraries(filteredLibraries);
+ List<Artifact> jsLibraries = getJSLibraries(filteredLibraries);
List<Artifact> externalLibraries = getExternalLibraries(filteredLibraries);
+ List<Artifact> jsExternalLibraries = getJSExternalLibraries(filteredLibraries);
List<Artifact> themeLibraries = getThemeLibraries(filteredLibraries);
List<String> sourcePaths = getSourcePaths();
context.put("libraries", libraries);
context.put("externalLibraries", externalLibraries);
+ context.put("jsLibraries", jsLibraries);
+ context.put("jsExternalLibraries", jsExternalLibraries);
context.put("themeLibraries", themeLibraries);
context.put("sourcePaths", sourcePaths);
context.put("namespaces", getNamespaces());
+ context.put("jsNamespaces", getNamespacesJS());
context.put("namespaceUris", getNamespaceUris());
context.put("includeClasses", includeClasses);
context.put("includeFiles", includeFiles);
@@ -154,6 +159,16 @@
return namespaces;
}
+ protected List<Namespace> getNamespacesJS() {
+ List<Namespace> namespaces = new LinkedList<Namespace>();
+ if(this.namespaces != null) {
+ for (Namespace namespace : this.namespaces) {
+ namespaces.add(namespace);
+ }
+ }
+ return namespaces;
+ }
+
protected Set<String> getNamespaceUris() {
Set<String> namespaceUris = new HashSet<String>();
for(Namespace namespace : getNamespaces()) {
@@ -302,6 +317,10 @@
return Collections.emptyList();
}
+ protected List<Artifact> getJSLibraries(List<Artifact> artifacts) {
+ return internalGetLibrariesJS(artifacts);
+ }
+
protected List<Artifact> getThemeLibraries(List<Artifact> artifacts) {
List<Artifact> themeLibraries = new LinkedList<Artifact>();
for(Artifact artifact : artifacts) {
@@ -328,6 +347,19 @@
return externalLibraries;
}
+ protected List<Artifact> getJSExternalLibraries(List<Artifact> artifacts) {
+ List<Artifact> externalLibraries = new LinkedList<Artifact>();
+ for(Artifact artifact : artifacts) {
+ if(("provided".equalsIgnoreCase(artifact.getScope()) || "runtime".equalsIgnoreCase(artifact.getScope()))
+ && includeLibraryJS(artifact)) {
+ if(!"pom".equals(artifact.getType())) {
+ externalLibraries.add(artifact);
+ }
+ }
+ }
+ return externalLibraries;
+ }
+
protected boolean isForceSwcExternalLibraryPath() {
return forceSwcExternalLibraryPath;
}
@@ -345,6 +377,19 @@
return libraries;
}
+ private List<Artifact> internalGetLibrariesJS(List<Artifact> artifacts) {
+ List<Artifact> libraries = new LinkedList<Artifact>();
+ for (Artifact artifact : artifacts) {
+ if (!("provided".equalsIgnoreCase(artifact.getScope()) || "runtime".equalsIgnoreCase(artifact.getScope()))
+ && includeLibraryJS(artifact)) {
+ if(!"pom".equals(artifact.getType())) {
+ libraries.add(artifact);
+ }
+ }
+ }
+ return libraries;
+ }
+
protected List<Define> getDefines() throws MojoExecutionException {
List<Define> defines = new LinkedList<Define>();
if(this.defines != null) {
@@ -359,4 +404,8 @@
return true;
}
+ protected boolean includeLibraryJS(Artifact library) {
+ return true;
+ }
+
}
diff --git a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileASMojo.java b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileASMojo.java
index a32200b..c4dbdc3 100644
--- a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileASMojo.java
+++ b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileASMojo.java
@@ -44,7 +44,7 @@
@Override
protected String getToolGroupName() {
- return "Falcon";
+ return "FlexJS";
}
@Override
@@ -54,7 +54,7 @@
@Override
protected String getConfigFileName() throws MojoExecutionException {
- return "compile-as-config.xml";
+ return "compile-swf-config.xml";
}
@Override
@@ -78,6 +78,14 @@
}
@Override
+ protected List<String> getCompilerArgs(File configFile) throws MojoExecutionException {
+ List<String> args = super.getCompilerArgs(configFile);
+ args.add("-compiler.targets=SWF,JSFlex");
+ args.add("-compiler.strict-xml=true");
+ return args;
+ }
+
+ @Override
protected List<Namespace> getNamespaces() {
List<Namespace> namespaces = new LinkedList<Namespace>();
for(Namespace namespace : super.getNamespaces()) {
@@ -89,16 +97,35 @@
}
@Override
+ protected List<Namespace> getNamespacesJS() {
+ List<Namespace> namespaces = new LinkedList<Namespace>();
+ for(Namespace namespace : super.getNamespaces()) {
+ if(namespace.getType().equals(Namespace.TYPE_DEFAULT) || namespace.getType().equals(Namespace.TYPE_JS)) {
+ namespaces.add(namespace);
+ }
+ }
+ return namespaces;
+ }
+
+ @Override
protected List<Define> getDefines() throws MojoExecutionException {
List<Define> defines = super.getDefines();
- defines.add(new Define("COMPILE::JS", "false"));
- defines.add(new Define("COMPILE::SWF", "true"));
+ defines.add(new Define("COMPILE::JS", "AUTO"));
+ defines.add(new Define("COMPILE::SWF", "AUTO"));
return defines;
}
@Override
protected boolean includeLibrary(Artifact library) {
- return !"typedefs".equalsIgnoreCase(library.getClassifier());
+ return !("typedefs".equalsIgnoreCase(library.getClassifier()) ||
+ "js".equalsIgnoreCase(library.getClassifier()));
}
+
+ @Override
+ protected boolean includeLibraryJS(Artifact library) {
+ return "typedefs".equalsIgnoreCase(library.getClassifier()) ||
+ "js".equalsIgnoreCase(library.getClassifier());
+ }
+
}
diff --git a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileAppMojo.java b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileAppMojo.java
index 5f4b11b..61ab8bf 100644
--- a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileAppMojo.java
+++ b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileAppMojo.java
@@ -47,23 +47,19 @@
/**
* Allows providing of a custom htmlTemplate which overrides the built-in one.
- * This option is only effective if outputJavaScript is true.
*/
@Parameter
protected String htmlTemplate;
- @Parameter(defaultValue = "false")
- protected boolean outputJavaScript;
-
+ @Parameter
+ protected String targets = "SWF,JSFlex";
+
@Parameter(defaultValue = "false")
protected boolean removeCirculars;
@Override
protected String getToolGroupName() {
- if(outputJavaScript) {
- return "FlexJS";
- }
- return "Falcon";
+ return "FlexJS";
}
@Override
@@ -73,10 +69,7 @@
@Override
protected String getConfigFileName() throws MojoExecutionException {
- if(outputJavaScript) {
- return "compile-app-javascript-config.xml";
- }
- return "compile-app-flash-config.xml";
+ return "compile-app-config.xml";
}
@Override
@@ -89,9 +82,6 @@
@Override
protected File getOutput() throws MojoExecutionException {
- if(outputJavaScript) {
- return new File(outputDirectory, javascriptOutputDirectoryName);
- }
return new File(outputDirectory, flashOutputFileName);
}
@@ -105,6 +95,9 @@
throw new MojoExecutionException("Could not find main class");
}
List<String> args = super.getCompilerArgs(configFile);
+ File jsOutput = new File(outputDirectory, "javascript");
+ args.add("-js-output=" + jsOutput.getAbsolutePath());
+ args.add("-compiler.targets=" + targets);
args.add(mainClassPath);
return args;
}
@@ -114,11 +107,8 @@
super.execute();
if(getOutput().exists()) {
- // If we are building JavaScript output, the war plugin will attach the war
- if(!outputJavaScript) {
- // Attach the file created by the compiler as artifact file to maven.
- project.getArtifact().setFile(getOutput());
- }
+ // Attach the file created by the compiler as artifact file to maven.
+ project.getArtifact().setFile(getOutput());
}
}
@@ -172,24 +162,25 @@
@Override
protected List<Define> getDefines() throws MojoExecutionException {
List<Define> defines = super.getDefines();
- defines.add(new Define("COMPILE::JS", outputJavaScript ? "true" : "false"));
- defines.add(new Define("COMPILE::SWF", outputJavaScript ? "false" : "true"));
+ defines.add(new Define("COMPILE::JS", "AUTO"));
+ defines.add(new Define("COMPILE::SWF", "AUTO"));
return defines;
}
@Override
protected boolean includeLibrary(Artifact library) {
- // Strip out all externs except if the dependency was declared inside the pom itself.
- return !"typedefs".equalsIgnoreCase(library.getClassifier()) ||
- (outputJavaScript && library.getDependencyTrail().size() == 2);
+ return !("typedefs".equalsIgnoreCase(library.getClassifier()) ||
+ "js".equalsIgnoreCase(library.getClassifier()));
}
@Override
- protected boolean isForceSwcExternalLibraryPath() {
- // The forceSwcExternalLibraryPath should only apply to Flash compilations.
- return !outputJavaScript && super.isForceSwcExternalLibraryPath();
+ protected boolean includeLibraryJS(Artifact library) {
+ // Strip out all externs except if the dependency was declared inside the pom itself.
+ return ("typedefs".equalsIgnoreCase(library.getClassifier()) ||
+ "js".equalsIgnoreCase(library.getClassifier()));
+ // || library.getDependencyTrail().size() == 2;
}
-
+
/*private void zipDirectory(File source, File target) {
byte[] buffer = new byte[1024];
try {
diff --git a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileJSMojo.java b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileJSMojo.java
index 2347f4a..98bbe75 100644
--- a/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileJSMojo.java
+++ b/flexjs-maven-plugin/src/main/java/org/apache/flex/maven/flexjs/CompileJSMojo.java
@@ -17,9 +17,12 @@
import org.apache.flex.tools.FlexTool;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProjectHelper;
+
import java.io.*;
import java.util.LinkedList;
@@ -35,7 +38,7 @@
extends BaseMojo
{
- @Parameter(defaultValue = "${project.artifactId}-${project.version}.swc")
+ @Parameter(defaultValue = "${project.artifactId}-${project.version}-js.swc")
private String outputFileName;
@Parameter(defaultValue = "false")
@@ -44,6 +47,9 @@
@Parameter(defaultValue = "false")
private boolean skipJS;
+ @Component
+ private MavenProjectHelper projectHelper;
+
@Override
protected String getToolGroupName() {
return "FlexJS";
@@ -70,23 +76,6 @@
}
@Override
- public void execute() throws MojoExecutionException {
- // FlexJS requires an existing SWC. If we skipped
- // the AS compilation, this doesn't exist yet so
- // we simply generate an empty swc and use that.
- if(!getOutput().exists()) {
- createEmptySwc(getOutput());
- }
-
- super.execute();
-
- if(getOutput().exists()) {
- // Attach the file created by the compiler as artifact file to maven.
- project.getArtifact().setFile(getOutput());
- }
- }
-
- @Override
protected boolean isForceSwcExternalLibraryPath() {
// The forceSwcExternalLibraryPath should only apply to Flash compilations.
return false;
@@ -95,12 +84,23 @@
@Override
protected List<String> getCompilerArgs(File configFile) throws MojoExecutionException {
List<String> args = super.getCompilerArgs(configFile);
- args.add("-js-output-type=FLEXJS");
+ args.add("-compiler.targets=SWF,JSFlex");
args.add("-compiler.strict-xml=true");
return args;
}
@Override
+ public void execute() throws MojoExecutionException
+ {
+ super.execute();
+
+ if(getOutput().exists()) {
+ // Add the extern to the artifact.
+ projectHelper.attachArtifact(project, getOutput(), "js");
+ }
+ }
+
+ @Override
protected List<Namespace> getNamespaces() {
List<Namespace> namespaces = new LinkedList<Namespace>();
for(Namespace namespace : super.getNamespaces()) {
@@ -121,7 +121,16 @@
@Override
protected boolean includeLibrary(Artifact library) {
- return "typedefs".equalsIgnoreCase(library.getClassifier());
+ return "typedefs".equalsIgnoreCase(library.getClassifier()) ||
+ "js".equalsIgnoreCase(library.getClassifier());
+ }
+
+ /* return false since we will already list the libraries we want on the
+ regular library-path and external-library-path
+ */
+ @Override
+ protected boolean includeLibraryJS(Artifact library) {
+ return false;
}
private void createEmptySwc(File outputFile) throws MojoExecutionException {
diff --git a/flexjs-maven-plugin/src/main/resources/config/compile-app-javascript-config.xml b/flexjs-maven-plugin/src/main/resources/config/compile-app-config.xml
similarity index 96%
rename from flexjs-maven-plugin/src/main/resources/config/compile-app-javascript-config.xml
rename to flexjs-maven-plugin/src/main/resources/config/compile-app-config.xml
index 1e709d2..60a87e4 100644
--- a/flexjs-maven-plugin/src/main/resources/config/compile-app-javascript-config.xml
+++ b/flexjs-maven-plugin/src/main/resources/config/compile-app-config.xml
@@ -61,6 +61,11 @@
#end
</external-library-path>
+ <js-external-library-path>
+#foreach($artifact in $jsExternalLibraries) <path-element>$artifact.file</path-element>
+#end
+ </js-external-library-path>
+
<!-- Turn on writing of generated/*.as files to disk. These files are generated by -->
<!-- the compiler during mxml translation and are helpful with understanding and -->
<!-- debugging Flex applications. -->
@@ -79,6 +84,13 @@
#end
</library-path>
+ <js-library-path>
+#foreach($artifact in $jsLibraries) <path-element>$artifact.file</path-element>
+#end
+ </js-library-path>
+
+ <allow-subclass-overrides>$allowSubclassOverrides</allow-subclass-overrides>
+
<mxml>
<children-as-data>true</children-as-data>
<imports>
@@ -93,6 +105,7 @@
<binding-value-change-event-type>valueChange</binding-value-change-event-type>
<binding-event-handler-event>org.apache.flex.events.Event</binding-event-handler-event>
<binding-event-handler-class>org.apache.flex.events.EventDispatcher</binding-event-handler-class>
+ <binding-event-handler-interface>org.apache.flex.events.IEventDispatcher</binding-event-handler-interface>
<states-class>org.apache.flex.states.State</states-class>
<states-instance-override-class>org.apache.flex.states.AddItems</states-instance-override-class>
<states-property-override-class>org.apache.flex.states.SetProperty</states-property-override-class>
diff --git a/flexjs-maven-plugin/src/main/resources/config/compile-app-flash-config.xml b/flexjs-maven-plugin/src/main/resources/config/compile-app-flash-config.xml
deleted file mode 100644
index c5bf8c4..0000000
--- a/flexjs-maven-plugin/src/main/resources/config/compile-app-flash-config.xml
+++ /dev/null
@@ -1,382 +0,0 @@
-<?xml version="1.0"?>
-<!--
-
- 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.
-
--->
-<flex-config>
- <!-- Specifies the version of the compiled SWF -->
- <swf-version>14</swf-version>
-
- <output>${output}</output>
-
- <compiler>
-
- <!-- Turn on generation of accessible SWFs. -->
- <accessible>true</accessible>
-
- <!-- Specifies the locales for internationalization. -->
- <locale>
- <locale-element>en_US</locale-element>
- </locale>
-
- <!-- List of path elements that form the roots of ActionScript class hierarchies. -->
- <source-path>
-#foreach($sourcePath in $sourcePaths) <path-element>$sourcePath</path-element>
-#end
- </source-path>
-
- <!-- Allow the source-path to have path-elements which contain other path-elements -->
- <allow-source-path-overlap>false</allow-source-path-overlap>
-
- <!-- Run the AS3 compiler in a mode that detects legal but potentially incorrect -->
- <!-- code. -->
- <show-actionscript-warnings>true</show-actionscript-warnings>
-
- <!-- Turn on generation of debuggable SWFs. False by default for mxmlc, -->
- <debug>$debug</debug>
-
- <!-- Turn on writing of generated/*.as files to disk. These files are generated by -->
- <!-- the compiler during mxml translation and are helpful with understanding and -->
- <!-- debugging Flex applications. -->
- <keep-generated-actionscript>false</keep-generated-actionscript>
-
- <!-- not set -->
- <!--
- <include-libraries>
- <library>string</library>
- </include-libraries>
- -->
-
-
- <!-- List of SWC files or directories that contain SWC files. -->
- <library-path>
-#foreach($artifact in $libraries) <path-element>$artifact.file</path-element>
-#end
- </library-path>
-
- <!-- List of SWC files or directories to compile against but to omit from -->
- <!-- linking. -->
- <external-library-path>
-#foreach($artifact in $externalLibraries) <path-element>$artifact.file</path-element>
-#end
- </external-library-path>
-
- <theme>
-#foreach($artifact in $themeLibraries) <filename>$artifact.file</filename>
-#end
- </theme>
-
- <mxml>
- <children-as-data>true</children-as-data>
- <imports>
- <implicit-import>org.apache.flex.events.*</implicit-import>
- <implicit-import>org.apache.flex.geom.*</implicit-import>
- <implicit-import>org.apache.flex.core.ClassFactory</implicit-import>
- <implicit-import>org.apache.flex.core.IFactory</implicit-import>
- </imports>
- </mxml>
-
- <binding-value-change-event>org.apache.flex.events.ValueChangeEvent</binding-value-change-event>
- <binding-value-change-event-kind>org.apache.flex.events.ValueChangeEvent</binding-value-change-event-kind>
- <binding-value-change-event-type>valueChange</binding-value-change-event-type>
- <binding-event-handler-event>org.apache.flex.events.Event</binding-event-handler-event>
- <binding-event-handler-class>org.apache.flex.events.EventDispatcher</binding-event-handler-class>
- <states-class>org.apache.flex.states.State</states-class>
- <states-instance-override-class>org.apache.flex.states.AddItems</states-instance-override-class>
- <states-property-override-class>org.apache.flex.states.SetProperty</states-property-override-class>
- <states-event-override-class>org.apache.flex.states.SetEventHandler</states-event-override-class>
- <component-factory-class>org.apache.flex.core.ClassFactory</component-factory-class>
- <component-factory-interface>org.apache.flex.core.IFactory</component-factory-interface>
-
- <namespaces>
-#foreach($namespace in $namespaces) <namespace>
- <uri>$namespace.uri</uri>
- <manifest>$namespace.manifest</manifest>
- </namespace>
-#end
- </namespaces>
-
- <!-- Enable post-link SWF optimization. -->
- <optimize>true</optimize>
-
- <!-- Enable trace statement omission. -->
- <omit-trace-statements>true</omit-trace-statements>
-
- <!-- Keep the following AS3 metadata in the bytecodes. -->
- <!-- Warning: For the data binding feature in the Flex framework to work properly, -->
- <!-- the following metadata must be kept: -->
- <!-- 1. Bindable -->
- <!-- 2. Managed -->
- <!-- 3. ChangeEvent -->
- <!-- 4. NonCommittingChangeEvent -->
- <!-- 5. Transient -->
- <!--
- <keep-as3-metadata>
- <name>Bindable</name>
- <name>Managed</name>
- <name>ChangeEvent</name>
- <name>NonCommittingChangeEvent</name>
- <name>Transient</name>
- </keep-as3-metadata>
- -->
-
- <!-- Turn on reporting of data binding warnings. For example: Warning: Data binding -->
- <!-- will not be able to detect assignments to "foo". -->
- <show-binding-warnings>true</show-binding-warnings>
-
- <!-- toggle whether warnings generated from unused type selectors are displayed -->
- <show-unused-type-selector-warnings>true</show-unused-type-selector-warnings>
-
- <!-- Run the AS3 compiler in strict error checking mode. -->
- <strict>true</strict>
-
- <!-- Use the ActionScript 3 class based object model for greater performance and better error reporting. -->
- <!-- In the class based object model most built-in functions are implemented as fixed methods of classes -->
- <!-- (-strict is recommended, but not required, for earlier errors) -->
- <as3>true</as3>
-
- <!-- Use the ECMAScript edition 3 prototype based object model to allow dynamic overriding of prototype -->
- <!-- properties. In the prototype based object model built-in functions are implemented as dynamic -->
- <!-- properties of prototype objects (-strict is allowed, but may result in compiler errors for -->
- <!-- references to dynamic properties) -->
- <es>false</es>
-
- <!-- List of CSS or SWC files to apply as a theme. -->
- <theme>
- </theme>
-
- <!-- Turns on the display of stack traces for uncaught runtime errors. -->
- <verbose-stacktraces>false</verbose-stacktraces>
-
- <!-- Defines the AS3 file encoding. -->
- <!-- not set -->
- <!--
- <actionscript-file-encoding></actionscript-file-encoding>
- -->
-
- <fonts>
-
- <!-- Enables advanced anti-aliasing for embedded fonts, which provides greater clarity for small -->
- <!-- fonts. This setting can be overriden in CSS for specific fonts. -->
- <!-- NOTE: flash-type has been deprecated. Please use advanced-anti-aliasing <flash-type>true</flash-type> -->
- <advanced-anti-aliasing>true</advanced-anti-aliasing>
-
- <!-- The number of embedded font faces that are cached. -->
- <max-cached-fonts>20</max-cached-fonts>
-
- <!-- The number of character glyph outlines to cache for each font face. -->
- <max-glyphs-per-face>1000</max-glyphs-per-face>
-
- <!-- Defines ranges that can be used across multiple font-face declarations. -->
- <!-- See flash-unicode-table.xml for more examples. -->
- <!-- not set -->
- <!--
- <languages>
- <language-range>
- <lang>englishRange</lang>
- <range>U+0020-007E</range>
- </language-range>
- </languages>
- -->
-
- <!-- Compiler font manager classes, in policy resolution order -->
- <!-- NOTE: For Apache Flex -->
- <!-- AFEFontManager and CFFFontManager both use proprietary technology. -->
- <!-- You must install the optional font jars if you wish to use embedded fonts -->
- <!-- directly or you can use fontswf to precompile the font as a swf. -->
- <managers>
- <manager-class>flash.fonts.JREFontManager</manager-class>
- <manager-class>flash.fonts.BatikFontManager</manager-class>
- <manager-class>flash.fonts.AFEFontManager</manager-class>
- <manager-class>flash.fonts.CFFFontManager</manager-class>
- </managers>
-
- <!-- File containing cached system font licensing information produced via
- java -cp mxmlc.jar flex2.tools.FontSnapshot (fontpath)
- Will default to winFonts.ser on Windows XP and
- macFonts.ser on Mac OS X, so is commented out by default.
-
- <local-fonts-snapshot>localFonts.ser</local-fonts-snapshot>
- -->
-
- </fonts>
-
- <!-- Array.toString() format has changed. -->
- <warn-array-tostring-changes>false</warn-array-tostring-changes>
-
- <!-- Assignment within conditional. -->
- <warn-assignment-within-conditional>true</warn-assignment-within-conditional>
-
- <!-- Possibly invalid Array cast operation. -->
- <warn-bad-array-cast>true</warn-bad-array-cast>
-
- <!-- Non-Boolean value used where a Boolean value was expected. -->
- <warn-bad-bool-assignment>true</warn-bad-bool-assignment>
-
- <!-- Invalid Date cast operation. -->
- <warn-bad-date-cast>true</warn-bad-date-cast>
-
- <!-- Unknown method. -->
- <warn-bad-es3-type-method>true</warn-bad-es3-type-method>
-
- <!-- Unknown property. -->
- <warn-bad-es3-type-prop>true</warn-bad-es3-type-prop>
-
- <!-- Illogical comparison with NaN. Any comparison operation involving NaN will evaluate to false because NaN != NaN. -->
- <warn-bad-nan-comparison>true</warn-bad-nan-comparison>
-
- <!-- Impossible assignment to null. -->
- <warn-bad-null-assignment>true</warn-bad-null-assignment>
-
- <!-- Illogical comparison with null. -->
- <warn-bad-null-comparison>true</warn-bad-null-comparison>
-
- <!-- Illogical comparison with undefined. Only untyped variables (or variables of type *) can be undefined. -->
- <warn-bad-undefined-comparison>true</warn-bad-undefined-comparison>
-
- <!-- Boolean() with no arguments returns false in ActionScript 3.0. Boolean() returned undefined in ActionScript 2.0. -->
- <warn-boolean-constructor-with-no-args>false</warn-boolean-constructor-with-no-args>
-
- <!-- __resolve is no longer supported. -->
- <warn-changes-in-resolve>false</warn-changes-in-resolve>
-
- <!-- Class is sealed. It cannot have members added to it dynamically. -->
- <warn-class-is-sealed>true</warn-class-is-sealed>
-
- <!-- Constant not initialized. -->
- <warn-const-not-initialized>true</warn-const-not-initialized>
-
- <!-- Function used in new expression returns a value. Result will be what the -->
- <!-- function returns, rather than a new instance of that function. -->
- <warn-constructor-returns-value>false</warn-constructor-returns-value>
-
- <!-- EventHandler was not added as a listener. -->
- <warn-deprecated-event-handler-error>false</warn-deprecated-event-handler-error>
-
- <!-- Unsupported ActionScript 2.0 function. -->
- <warn-deprecated-function-error>true</warn-deprecated-function-error>
-
- <!-- Unsupported ActionScript 2.0 property. -->
- <warn-deprecated-property-error>true</warn-deprecated-property-error>
-
- <!-- More than one argument by the same name. -->
- <warn-duplicate-argument-names>true</warn-duplicate-argument-names>
-
- <!-- Duplicate variable definition -->
- <warn-duplicate-variable-def>true</warn-duplicate-variable-def>
-
- <!-- ActionScript 3.0 iterates over an object's properties within a "for x in target" statement in random order. -->
- <warn-for-var-in-changes>false</warn-for-var-in-changes>
-
- <!-- Importing a package by the same name as the current class will hide that class identifier in this scope. -->
- <warn-import-hides-class>true</warn-import-hides-class>
-
- <!-- Use of the instanceof operator. -->
- <warn-instance-of-changes>true</warn-instance-of-changes>
-
- <!-- Internal error in compiler. -->
- <warn-internal-error>true</warn-internal-error>
-
- <!-- _level is no longer supported. For more information, see the flash.display package. -->
- <warn-level-not-supported>true</warn-level-not-supported>
-
- <!-- Missing namespace declaration (e.g. variable is not defined to be public, private, etc.). -->
- <warn-missing-namespace-decl>true</warn-missing-namespace-decl>
-
- <!-- Negative value will become a large positive value when assigned to a uint data type. -->
- <warn-negative-uint-literal>true</warn-negative-uint-literal>
-
- <!-- Missing constructor. -->
- <warn-no-constructor>false</warn-no-constructor>
-
- <!-- The super() statement was not called within the constructor. -->
- <warn-no-explicit-super-call-in-constructor>false</warn-no-explicit-super-call-in-constructor>
-
- <!-- Missing type declaration. -->
- <warn-no-type-decl>true</warn-no-type-decl>
-
- <!-- In ActionScript 3.0, white space is ignored and '' returns 0. Number() returns -->
- <!-- NaN in ActionScript 2.0 when the parameter is '' or contains white space. -->
- <warn-number-from-string-changes>false</warn-number-from-string-changes>
-
- <!-- Change in scoping for the this keyword. Class methods extracted from an -->
- <!-- instance of a class will always resolve this back to that instance. In -->
- <!-- ActionScript 2.0 this is looked up dynamically based on where the method -->
- <!-- is invoked from. -->
- <warn-scoping-change-in-this>false</warn-scoping-change-in-this>
-
- <!-- Inefficient use of += on a TextField.-->
- <warn-slow-text-field-addition>true</warn-slow-text-field-addition>
-
- <!-- Possible missing parentheses. -->
- <warn-unlikely-function-value>true</warn-unlikely-function-value>
-
- <!-- Possible usage of the ActionScript 2.0 XML class. -->
- <warn-xml-class-has-changed>false</warn-xml-class-has-changed>
-
-#foreach($define in $defines) <define>
- <name>$define.name</name>
- <value>$define.value</value>
- </define>
-#end
-
- </compiler>
-
-#if($includeSources)
- <include-sources>
-#foreach($sourcePath in $sourcePaths) <path-element>$sourcePath</path-element>
-#end
- </include-sources>
-#end
-
-#if($includeClasses)
- <include-classes>
-#foreach($includeClass in $includeClasses) <class>$includeClass</class>
-#end
- </include-classes>
-#end
-
- <!-- compute-digest: writes a digest to the catalog.xml of a library. Use this when the library will be used as a
- cross-domain rsl.-->
- <!-- compute-digest usage:
- <compute-digest>boolean</compute-digest>
- -->
-
- <!-- remove-unused-rsls: remove RSLs that are not being used by the application-->
- <remove-unused-rsls>true</remove-unused-rsls>
-
- <!-- static-link-runtime-shared-libraries: statically link the libraries specified by the -runtime-shared-libraries-path option.-->
- <static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
-
- <!-- target-player: specifies the version of the player the application is targeting.
- Features requiring a later version will not be compiled into the application.
- The minimum value supported is "9.0.0".-->
- <target-player>${targetPlayer}</target-player>
-
- <!-- Enables SWFs to access the network. -->
- <use-network>true</use-network>
-
- <!-- Metadata added to SWFs via the SWF Metadata tag. -->
- <metadata>
- <title>Apache FlexJS Application</title>
- <description>http://flex.apache.org/</description>
- <publisher>Apache Software Foundation</publisher>
- <creator>unknown</creator>
- <language>EN</language>
- </metadata>
-
-</flex-config>
diff --git a/flexjs-maven-plugin/src/main/resources/config/compile-js-config.xml b/flexjs-maven-plugin/src/main/resources/config/compile-js-config.xml
index 4cc8d31..8d010e4 100644
--- a/flexjs-maven-plugin/src/main/resources/config/compile-js-config.xml
+++ b/flexjs-maven-plugin/src/main/resources/config/compile-js-config.xml
@@ -57,11 +57,25 @@
<mxml>
<children-as-data>true</children-as-data>
+ <imports>
+ <implicit-import>org.apache.flex.events.*</implicit-import>
+ <implicit-import>org.apache.flex.geom.*</implicit-import>
+ <implicit-import>org.apache.flex.core.ClassFactory</implicit-import>
+ <implicit-import>org.apache.flex.core.IFactory</implicit-import>
+ </imports>
</mxml>
-
<binding-value-change-event>org.apache.flex.events.ValueChangeEvent</binding-value-change-event>
<binding-value-change-event-kind>org.apache.flex.events.ValueChangeEvent</binding-value-change-event-kind>
<binding-value-change-event-type>valueChange</binding-value-change-event-type>
+ <binding-event-handler-event>org.apache.flex.events.Event</binding-event-handler-event>
+ <binding-event-handler-class>org.apache.flex.events.EventDispatcher</binding-event-handler-class>
+ <binding-event-handler-interface>org.apache.flex.events.IEventDispatcher</binding-event-handler-interface>
+ <states-class>org.apache.flex.states.State</states-class>
+ <states-instance-override-class>org.apache.flex.states.AddItems</states-instance-override-class>
+ <states-property-override-class>org.apache.flex.states.SetProperty</states-property-override-class>
+ <states-event-override-class>org.apache.flex.states.SetEventHandler</states-event-override-class>
+ <component-factory-class>org.apache.flex.core.ClassFactory</component-factory-class>
+ <component-factory-interface>org.apache.flex.core.IFactory</component-factory-interface>
<show-deprecation-warnings>false</show-deprecation-warnings>
@@ -93,7 +107,15 @@
</include-namespaces>
#end
- <js-output-type>FLEXJS</js-output-type>
+#foreach($includeFile in $includeFiles) <include-file>
+ <name>$includeFile.name</name>
+ <path>$includeFile.path</path>
+</include-file>
+#end
+
+#if($includeLookupOnly)
+<include-lookup-only>$includeLookupOnly</include-lookup-only>
+#end
<keep-asdoc>true</keep-asdoc>
diff --git a/flexjs-maven-plugin/src/main/resources/config/compile-as-config.xml b/flexjs-maven-plugin/src/main/resources/config/compile-swf-config.xml
similarity index 65%
rename from flexjs-maven-plugin/src/main/resources/config/compile-as-config.xml
rename to flexjs-maven-plugin/src/main/resources/config/compile-swf-config.xml
index af45b0a..afee4db 100644
--- a/flexjs-maven-plugin/src/main/resources/config/compile-as-config.xml
+++ b/flexjs-maven-plugin/src/main/resources/config/compile-swf-config.xml
@@ -28,11 +28,21 @@
#end
</library-path>
+ <js-library-path>
+ #foreach($artifact in $jsLibraries) <path-element>$artifact.file</path-element>
+ #end
+ </js-library-path>
+
<external-library-path>
#foreach($artifact in $externalLibraries) <path-element>$artifact.file</path-element>
#end
</external-library-path>
+ <js-external-library-path>
+ #foreach($artifact in $jsExternalLibraries) <path-element>$artifact.file</path-element>
+ #end
+ </js-external-library-path>
+
<theme>
#foreach($artifact in $themeLibraries) <filename>$artifact.file</filename>
#end
@@ -51,6 +61,14 @@
#end
</namespaces>
+ <js-namespaces>
+#foreach($jsnamespace in $jsNamespaces) <namespace>
+ <uri>$jsnamespace.uri</uri>
+ <manifest>$jsnamespace.manifest</manifest>
+ </namespace>
+#end
+ </js-namespaces>
+
<keep-as3-metadata>
#foreach($metadata in $keepAs3Metadata) <name>$metadata</name>
#end
@@ -60,11 +78,25 @@
<mxml>
<children-as-data>true</children-as-data>
+ <imports>
+ <implicit-import>org.apache.flex.events.*</implicit-import>
+ <implicit-import>org.apache.flex.geom.*</implicit-import>
+ <implicit-import>org.apache.flex.core.ClassFactory</implicit-import>
+ <implicit-import>org.apache.flex.core.IFactory</implicit-import>
+ </imports>
</mxml>
-
<binding-value-change-event>org.apache.flex.events.ValueChangeEvent</binding-value-change-event>
<binding-value-change-event-kind>org.apache.flex.events.ValueChangeEvent</binding-value-change-event-kind>
<binding-value-change-event-type>valueChange</binding-value-change-event-type>
+ <binding-event-handler-event>org.apache.flex.events.Event</binding-event-handler-event>
+ <binding-event-handler-class>org.apache.flex.events.EventDispatcher</binding-event-handler-class>
+ <binding-event-handler-interface>org.apache.flex.events.IEventDispatcher</binding-event-handler-interface>
+ <states-class>org.apache.flex.states.State</states-class>
+ <states-instance-override-class>org.apache.flex.states.AddItems</states-instance-override-class>
+ <states-property-override-class>org.apache.flex.states.SetProperty</states-property-override-class>
+ <states-event-override-class>org.apache.flex.states.SetEventHandler</states-event-override-class>
+ <component-factory-class>org.apache.flex.core.ClassFactory</component-factory-class>
+ <component-factory-interface>org.apache.flex.core.IFactory</component-factory-interface>
<locale>
</locale>