blob: 6356c88e3f01cd91771d29d9be8604fc456db15e [file] [log] [blame]
/*
*
* 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.config;
import java.io.*;
import java.text.DateFormat;
import java.util.*;
import java.util.regex.Pattern;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.flex.compiler.common.IPathResolver;
import org.apache.flex.compiler.common.VersionInfo;
import org.apache.flex.compiler.exceptions.ConfigurationException;
import org.apache.flex.compiler.exceptions.ConfigurationException.*;
import org.apache.flex.compiler.filespecs.FileSpecification;
import org.apache.flex.compiler.filespecs.IFileSpecification;
import org.apache.flex.compiler.internal.config.*;
import org.apache.flex.compiler.internal.config.annotations.*;
import org.apache.flex.compiler.internal.config.localization.LocalizationManager;
import org.apache.flex.compiler.internal.mxml.MXMLNamespaceMapping;
import org.apache.flex.compiler.mxml.IMXMLTypeConstants;
import org.apache.flex.compiler.problems.*;
import org.apache.flex.swc.catalog.XMLFormatter;
import org.apache.flex.utils.FileUtils;
import org.apache.flex.utils.FilenameNormalization;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* The model for all the configuration options supported by the compiler. Each option is stored in a private field. It
* usually has a getter method, a setter method and a configuration method (started with "cfg"). The configuration
* methods are used by the configurators to set the values of a given option name.
* <p>
* This class is currently being reviewed and refactored. See CMP-471 as the master bug for the tasks.
* <p>
* Steps to refactor:
* <ol>
* <li>Check "mxmlc" manual (http://adobe.ly/bffN8A) and copy documents to Javadoc on setters of options.</li>
* <li>Check "configuration support" WIKI (http://bit.ly/oAI8gj) to see if an option should be deprecated.</li>
* <li>Merge {@code cfgXXX} to {@code setXXX}, and annotate the setter.</li>
* <li>Remove {@code getXXXInfo()} static method.</li>
* </ol>
*
* @see "http://bugs.adobe.com/jira/browse/CMP-471"
*/
public class Configuration
{
private static final int DEFAULT_HEIGHT_MAX = 4096;
private static final int DEFAULT_HEIGHT_MIN = 1;
private static final int DEFAULT_WIDTH_MAX = 4096;
private static final int DEFAULT_WIDTH_MIN = 1;
public static final String DEFAULT_OUTPUT_DIRECTORY_TOKEN = "org.apache.flex.default.output.directory";
public static final String SWC_AIRGLOBAL = "airglobal.swc";
/**
* Singleton empty string list. All getters returning a list of string should return this object when the field is
* null.
*/
private static final List<String> EMPTY_STRING_LIST = Collections.emptyList();
private static final List<String> compcOnlyOptions = new ArrayList<String>(9);
static
{
compcOnlyOptions.add("directory");
compcOnlyOptions.add("include-classes");
compcOnlyOptions.add("include-file");
compcOnlyOptions.add("include-lookup-only");
compcOnlyOptions.add("include-namespaces");
compcOnlyOptions.add("include-sources");
compcOnlyOptions.add("include-stylesheet");
compcOnlyOptions.add("include-inheritance-dependencies-only");
}
/**
* Validate configuration options values.
*
* @param configurationBuffer Configuration buffer.
* @throws ConfigurationException Error.
*/
public void validate(ConfigurationBuffer configurationBuffer) throws ConfigurationException
{
// process the merged configuration buffer. right, can't just process the args.
processDeprecatedAndRemovedOptions(configurationBuffer);
validateDumpConfig(configurationBuffer);
}
private String[] removeNativeJSLibrariesIfNeeded(String[] libraryPaths)
{
List<String> libraryPathList = new ArrayList<String>(Arrays.asList(libraryPaths));
String appHome = System.getProperty("application.home");
if (appHome == null)
return libraryPaths;
appHome = appHome.replace("\\", "/");
if (isExcludeNativeJSLibraries)
{
Iterator<String> pathIterator = libraryPathList.iterator();
while (pathIterator.hasNext())
{
final String path = pathIterator.next().replace("\\", "/");
final boolean isNativeJS = path.contains(appHome + "/js/libs")
&& path.lastIndexOf(".swc") == path.length() - ".swc".length();
if (isNativeJS)
{
pathIterator.remove();
}
}
}
return libraryPathList.toArray(new String[libraryPathList.size()]);
}
/**
* Validate that no compc-only options are used in a given configuration buffer. Use this method to verify no
* compc-only args are used in mxmlc.
*
* @param configurationBuffer the configuration buffer to check for compc-only options.
*
* @throws ConfigurationException if a compc-only option is found in the configuration buffer.
*/
public static void validateNoCompcOnlyOptions(ConfigurationBuffer configurationBuffer) throws ConfigurationException
{
for (String option : compcOnlyOptions)
{
List<ConfigurationValue> values = configurationBuffer.getVar(option);
if (values != null && values.size() > 0)
throw new ConfigurationException.UnknownVariable(values.get(0).getVar(), values.get(0).getSource(),
values.get(0).getLine());
}
}
/**
* The path of a given file name based on the context of the configuration value or the default output directory
* token.
*
* @param cv
* @param fileName
* @return the full path of the file.
*/
protected String getOutputPath(ConfigurationValue cv, String fileName)
{
String result = fileName;
if (fileName != null)
{
File file = new File(fileName);
if (!FileUtils.isAbsolute(file))
{
String directory = cv.getBuffer().getToken(DEFAULT_OUTPUT_DIRECTORY_TOKEN);
// if no default output directory, then use the configuration context.
if (directory == null)
{
directory = cv.getContext();
}
if (directory != null)
{
result = FileUtils.addPathComponents(directory, fileName, File.separatorChar);
}
}
}
return pathResolver.resolve(result).getAbsolutePath();
}
private static Map<String, String> aliases = null;
public static Map<String, String> getAliases()
{
if (aliases == null)
{
aliases = new HashMap<String, String>();
aliases.put("l", "compiler.library-path");
aliases.put("el", "compiler.external-library-path");
aliases.put("fb", "use-flashbuilder-project-files");
aliases.put("is", "include-sources");
aliases.put("sp", "compiler.source-path");
aliases.put("rsl", "runtime-shared-libraries");
aliases.put("keep", "compiler.keep-generated-actionscript");
aliases.put("o", "output");
aliases.put("rslp", "runtime-shared-library-path");
aliases.put("static-rsls", "static-link-runtime-shared-libraries");
}
return aliases;
}
//
// PathResolver
//
private IPathResolver pathResolver;
/**
* Set a path resolver to resolver files relative to a configuration. Files inside of configuration files are
* resolved relative to those configuration files and files on the command line are resolved relative to the root
* directory of the compile.
*
* @param pathResolver a path resolver for this configuration. May not be null.
*/
public void setPathResolver(IPathResolver pathResolver)
{
this.pathResolver = pathResolver;
}
//
// mainDefinition
//
private String mainDefinition;
/**
* Main definition is the root class of a SWF. {@code mxmlc} only takes one file in the source list. The main
* definition name is the main source file name.
*
* @return main definition
*/
public String getMainDefinition()
{
return mainDefinition;
}
public void setMainDefinition(String mainDefinition)
{
assert mainDefinition != null : "main definition can't be null";
assert!"".equals(mainDefinition) : "main definition can't be empty";
this.mainDefinition = mainDefinition;
}
//
// 'benchmark' option
//
@Config(removed = true)
@Mapping("benchmark")
public void setBenchmark(ConfigurationValue cv, boolean b)
{
}
//
// 'debug-password' option
//
private String debugPassword;
/**
* Lets you engage in remote debugging sessions with the Flash IDE.
*/
public String getDebugPassword()
{
return debugPassword;
}
@Config(advanced = true)
@Mapping("debug-password")
@DefaultArgumentValue("")
public void setDebugPassword(ConfigurationValue cv, String debugPassword)
{
this.debugPassword = debugPassword;
}
//
// 'default-background-color' option
//
private int backgroundColor = 0x50727E;
public int getDefaultBackgroundColor()
{
return this.backgroundColor;
}
@Config(advanced = true)
@Mapping("default-background-color")
public void setDefaultBackgroundColor(ConfigurationValue cv, int backgroundColor)
{
this.backgroundColor = backgroundColor;
}
//
// 'default-frame-rate' option
//
private int frameRate = 24;
public int getDefaultFrameRate()
{
return frameRate;
}
@Config(advanced = true)
@Mapping("default-frame-rate")
public void setDefaultFrameRate(ConfigurationValue cv, int rate) throws ConfigurationException
{
if (rate <= 0)
throw new ConfigurationException.GreaterThanZero(cv.getVar(), cv.getSource(), cv.getLine());
frameRate = rate;
}
//
// 'default-script-limits' option
//
private int scriptLimit = 60;
private int scriptRecursionLimit = 1000;
private boolean scriptLimitsSet = false;
public int getScriptTimeLimit()
{
return scriptLimit;
}
public int getScriptRecursionLimit()
{
return scriptRecursionLimit;
}
public boolean scriptLimitsSet()
{
return scriptLimitsSet;
}
@Config(advanced = true)
@Mapping("default-script-limits")
@Arguments({ "max-recursion-depth", "max-execution-time" })
public void setDefaultScriptLimits(ConfigurationValue cv, int scriptLimit, int scriptRecursionLimit)
throws ConfigurationException
{
if (scriptLimit <= 0)
throw new ConfigurationException.GreaterThanZero(cv.getVar(), cv.getSource(), cv.getLine());
if (scriptRecursionLimit <= 0)
throw new ConfigurationException.GreaterThanZero(cv.getVar(), cv.getSource(), cv.getLine());
this.scriptLimitsSet = true;
this.scriptLimit = scriptRecursionLimit;
this.scriptRecursionLimit = scriptLimit;
}
//
// 'default-size' option
//
private int defaultWidth = 500;
private int defaultHeight = 375;
public int getDefaultWidth()
{
return defaultWidth;
}
public int getDefaultHeight()
{
return defaultHeight;
}
@Config(advanced = true)
@Arguments({ "width", "height" })
@Mapping("default-size")
public void setDefaultSize(ConfigurationValue cv, int width, int height) throws ConfigurationException
{
if (width < DEFAULT_WIDTH_MIN || width > DEFAULT_WIDTH_MAX || height < DEFAULT_HEIGHT_MIN
|| height > DEFAULT_HEIGHT_MAX)
throw new ConfigurationException.IllegalDimensions(width, height, cv.getVar(), cv.getSource(),
cv.getLine());
this.defaultWidth = width;
this.defaultHeight = height;
}
//
// 'externs' option
//
private final Set<String> externs = new LinkedHashSet<String>();
public Set<String> getExterns()
{
return externs;
}
/**
* Sets a list of classes to exclude from linking when compiling a SWF file. This option provides compile-time link
* checking for external references that are dynamically linked.
*/
@Config(advanced = true, allowMultiple = true)
@Mapping("externs")
@Arguments("symbol")
@InfiniteArguments
public void setExterns(ConfigurationValue cfgval, List<String> vals)
{
externs.addAll(QNameNormalization.normalize(vals));
}
//
// 'includes' option
//
private final Set<String> includes = new LinkedHashSet<String>();
public Set<String> getIncludes()
{
return includes;
}
/**
* Links one or more classes to the resulting application SWF file, whether or not those classes are required at
* compile time. To link an entire SWC file rather than individual classes, use the include-libraries option.
*/
@Config(allowMultiple = true, advanced = true)
@Mapping("includes")
@Arguments("symbol")
@InfiniteArguments
public void setIncludes(ConfigurationValue cfgval, List<String> vals)
{
includes.addAll(QNameNormalization.normalize(vals));
}
//
// 'framework' option
//
//
@Config(allowMultiple = true, advanced = true, removed = true)
@Mapping("framework")
public void setFramework(ConfigurationValue cfgval, String value)
{
}
// 'link-report' option
//
private String linkReportFileName = null;
public File getLinkReport()
{
return linkReportFileName != null ? new File(linkReportFileName) : null;
}
/**
* Prints linking information to the specified output file. This file is an XML file that contains {@code def} tags,
* {@code pre} tags and {@code ext} tags showing linker dependencies in the final SWF file. The file format output
* by this command can be used to write a file for input to the {@code load-externs} option.
*/
@Config(advanced = true)
@Mapping("link-report")
@Arguments("filename")
public void setLinkReport(ConfigurationValue cv, String filename)
{
this.linkReportFileName = getOutputPath(cv, filename);
}
//
// 'size-report' option
//
private String sizeReportFileName = null;
public File getSizeReport()
{
return sizeReportFileName != null ? new File(sizeReportFileName) : null;
}
@Config(advanced = true)
@Mapping("size-report")
@Arguments("filename")
public void setSizeReport(ConfigurationValue cv, String filename)
{
this.sizeReportFileName = getOutputPath(cv, filename);
}
//
// 'load-externs' option
//
/**
* Specifies the location of an XML file that contains def, pre, and ext symbols to omit from linking when compiling
* a SWF file. The XML file uses the same syntax as the one produced by the link-report option.
* <p>
* This option provides compile-time link checking for external components that are dynamically linked.
*/
@Config(allowMultiple = true, advanced = true)
@Mapping("load-externs")
@Arguments("filename")
public void setLoadExterns(ConfigurationValue cfgval, String filename) throws ConfigurationException
{
final String path = resolvePathStrict(filename, cfgval);
final FileSpecification f = new FileSpecification(path);
final List<String> externsFromFile = LoadExternsParser.collectExterns(cfgval, f);
externs.addAll(externsFromFile);
}
//
// 'raw-metadata' option
//
private String metadata = null;
public String getRawMetadata()
{
if (metadata != null)
return metadata;
return generateMetadata();
}
private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
private static final String DC_URI = "http://purl.org/dc/elements/1.1";
/**
* @return Metadata XML string.
*/
private final String generateMetadata()
{
final XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance();
assert xmlOutputFactory != null : "Expect XMLOutputFactory implementation.";
final StringWriter stringWriter = new StringWriter();
XMLStreamWriter xmlWriter = null;
try
{
xmlWriter = new XMLFormatter(xmlOutputFactory.createXMLStreamWriter(stringWriter));
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("rdf", "RDF", RDF_URI);
xmlWriter.setPrefix("rdf", RDF_URI);
xmlWriter.writeNamespace("rdf", RDF_URI);
// write rdf:Description
xmlWriter.writeStartElement(RDF_URI, "Description");
xmlWriter.setPrefix("dc", DC_URI);
xmlWriter.setPrefix(VersionInfo.COMPILER_NAMESPACE_PREFIX, VersionInfo.COMPILER_NAMESPACE_URI);
xmlWriter.writeNamespace("dc", DC_URI);
xmlWriter.writeNamespace(VersionInfo.COMPILER_NAMESPACE_PREFIX, VersionInfo.COMPILER_NAMESPACE_URI);
// write dc:format
xmlWriter.writeStartElement(DC_URI, "format");
xmlWriter.writeCharacters("application/x-shockwave-flash");
xmlWriter.writeEndElement();
if (isFlex())
{
// write localizedTitles
writeMap(xmlWriter, DC_URI, "description", localizedDescriptions);
// write localizedDescription
writeMap(xmlWriter, DC_URI, "title", localizedTitles);
// write publisher
writeCollection(xmlWriter, DC_URI, "publisher", publishers);
// write creators
writeCollection(xmlWriter, DC_URI, "creator", creators);
// write contributor
writeCollection(xmlWriter, DC_URI, "contributor", contributors);
// write language
writeCollection(xmlWriter, DC_URI, "language", langs);
// write date
writeDate(xmlWriter);
}
// write compiledBy
writeCompiledBy(xmlWriter);
// write
xmlWriter.writeEndElement(); // Description
xmlWriter.writeEndDocument();
}
catch (XMLStreamException e)
{
return "";
}
return stringWriter.toString();
}
/**
* Write information about the compiler that compiled the swf.
*
* @param writer
* @throws XMLStreamException
*/
private void writeCompiledBy(XMLStreamWriter writer) throws XMLStreamException
{
writer.writeEmptyElement(VersionInfo.COMPILER_NAMESPACE_URI, VersionInfo.COMPILER_ELEMENT);
writer.writeAttribute(VersionInfo.COMPILER_NAME_ATTRIBUTE, VersionInfo.getCompilerName());
writer.writeAttribute(VersionInfo.COMPILER_VERSION_ATTRIBUTE, VersionInfo.getCompilerVersion());
writer.writeAttribute(VersionInfo.COMPILER_BUILD_ATTRIBUTE, VersionInfo.getCompilerBuild());
writer.writeEndElement(); // compiledBy
}
/**
* Write the data to rdf/xml
*
* @param writer
* @throws XMLStreamException
*/
private void writeDate(XMLStreamWriter writer) throws XMLStreamException
{
if (date == null)
{
date = DateFormat.getDateInstance().format(new Date());
}
writer.writeStartElement(DC_URI, "date");
writer.writeCharacters(date);
writer.writeEndElement();
}
/**
* Write a map of values to rdf/xml
*
* @param writer
* @param namespaceURI
* @param localName
* @param mapData
* @throws XMLStreamException
*/
private void writeMap(XMLStreamWriter writer, String namespaceURI, String localName, Map<String, String> mapData)
throws XMLStreamException
{
if (mapData.size() > 0)
{
writer.writeStartElement(namespaceURI, localName);
if ((mapData.size() == 1) && (mapData.get("x-default") != null))
{
String data = mapData.get("x-default");
writer.writeCharacters(data);
}
else
{
writer.writeStartElement(RDF_URI, "Alt");
for (final String key : mapData.keySet())
{
final String value = mapData.get(key);
writer.writeStartElement(RDF_URI, "li");
writer.writeAttribute("xml", "", "lang", key);
writer.writeCharacters(value);
writer.writeEndElement();
}
writer.writeEndElement();
}
writer.writeEndElement();
}
}
/**
* Write a collection values to rdf/xml.
*
* @param writer
* @param namespaceURI
* @param localName
* @param values
* @throws XMLStreamException
*/
private void writeCollection(XMLStreamWriter writer, String namespaceURI, String localName,
Collection<String> values) throws XMLStreamException
{
if (values.isEmpty())
return;
writer.writeStartElement(namespaceURI, localName);
if (values.size() > 1)
writer.writeStartElement(RDF_URI, "Bag");
for (String value : values)
{
writer.writeCharacters(value);
}
if (values.size() > 1)
writer.writeEndElement();
writer.writeEndElement();
}
/**
* Defines the metadata for the resulting SWF file. The value of this option overrides any metadata-related compiler
* options such as contributor, creator, date, and description.
*/
@Config(advanced = true)
@Mapping("raw-metadata")
@Arguments("text")
public void setRawMetadata(ConfigurationValue cv, String xml) throws ConfigurationException
{
if (metadata != null)
{
throw new ConfigurationException.BadMetadataCombo(cv.getVar(), cv.getSource(), cv.getLine());
}
this.metadata = xml;
}
//
// 'resource-bundle-list' option
//
private String rbListFileName = null;
public String getResourceBundleList()
{
return rbListFileName;
}
//
// 'include-resource-bundles' option
//
/**
* include-resource-bundles [...]
*/
private List<String> includeResourceBundles = new ArrayList<String>();
/**
* @return a list of resource bundles to include in the swc
*/
public List<String> getIncludeResourceBundles()
{
return includeResourceBundles;
}
/**
* Sets the resource bundles that should be included in this SWC or SWF. This list can have locale independent
* qualified name for property files (with the name not including the suffix) or qualified name for classes that
* extend ResourceBundle.
* <p>
* Qualified name of a properties file is determined by its relative path to its parent source folder. Such as:
* <p>
* Source path: locale/{locale}
* <p>
* Path of properties file 1: locale/en_US/A.properties Qualified name of properties file 1: A
* <p>
* Path of properties file 2: locale/en_US/com/resources/B.properties Qualified name of properties file 1:
* com.resources.B
* <p>
* Note: Source folders of all the properties files passed using this argument should be in the project's source
* path list.
*
* @param cv configuration value objects
* @param values list of resource bundles to include in the swc or swf
*/
@Config(allowMultiple = true)
@Mapping("include-resource-bundles")
@Arguments("bundle")
@FlexOnly
public void setIncludeResourceBundles(ConfigurationValue cv, List<String> values)
{
includeResourceBundles.addAll(values);
}
/**
* Prints a list of resource bundles that are used by the current application to a file named with the filename
* argument. You then use this list as input that you specify with the include-resource-bundles option to create a
* resource module.
*/
@Config(advanced = true)
@Mapping("resource-bundle-list")
@Arguments("filename")
@FlexOnly
public void setResourceBundleList(ConfigurationValue cv, String filename)
{
this.rbListFileName = getOutputPath(cv, filename);
}
//
// 'runtime-shared-libraries' option
//
private List<String> rslList = new LinkedList<String>();
public List<String> getRuntimeSharedLibraries()
{
return rslList;
}
/**
* Specifies a list of runtime shared libraries (RSLs) to use for this application. RSLs are dynamically-linked at
* run time. The compiler externalizes the contents of the application that you are compiling that overlap with the
* RSL.
* <p>
* You specify the location of the SWF file relative to the deployment location of the application. For example, if
* you store a file named library.swf file in the web_root/libraries directory on the web server, and the
* application in the web root, you specify libraries/library.swf.
*/
@Config(allowMultiple = true)
@Mapping("runtime-shared-libraries")
@Arguments("url")
@InfiniteArguments
@FlexOnly
public void setRuntimeSharedLibraries(ConfigurationValue cfgval, List<String> urls) throws ConfigurationException
{
rslList.addAll(urls);
}
//
// 'use-network' option
//
private boolean useNetwork = true;
public boolean getUseNetwork()
{
return useNetwork;
}
/**
* Specifies that the current application uses network services.
* <p>
* The default value is true.
* <p>
* When the use-network property is set to false, the application can access the local filesystem (for example, use
* the XML.load() method with file: URLs) but not network services. In most circumstances, the value of this
* property should be true.
*/
@Config
@Mapping("use-network")
public void setUseNetwork(ConfigurationValue cv, boolean b)
{
this.useNetwork = b;
}
//
// runtime-shared-library-path
//
private List<RuntimeSharedLibraryPathInfo> rslPathInfoList;
/**
* @return List of of all the -runtime-shared-libraries-path options. Each-runtime-shared-libraries-path option
* supplied results in a RslPathInfo object. Each object in the list is of type RslPathInfo.
* <p>
* The list will be empty if -static-link-runtime-shared-libraries=true.
* <p>
* TODO Verify if this is still true and make the code do what it says.
*/
public List<RuntimeSharedLibraryPathInfo> getRslPathInfo()
{
if (rslPathInfoList == null)
return Collections.emptyList();
else
return rslPathInfoList;
}
public List<File> getRslExcludedLibraries()
{
if (rslPathInfoList == null || getStaticLinkRsl())
return Collections.emptyList();
return Lists.transform(rslPathInfoList, new Function<RuntimeSharedLibraryPathInfo, File>()
{
@Override
public File apply(RuntimeSharedLibraryPathInfo info)
{
return info.getSWCFile();
}
});
}
/**
* Specifies the location of a runtime shared library (RSL). The compiler externalizes the contents of the
* application that you are compiling that overlap with the RSL.
* <p>
* The path-element argument is the location of the SWC file or open directory to compile against. For example,
* c:\flexsdk\frameworks\libs\framework.swc. This is the equivalent of the using the external-library-path option
* when compiling against an RSL using the runtime-shared-libraries option.
* <p>
* The rsl-url argument is the URL of the RSL that will be used to load the RSL at runtime. The compiler does not
* verify the existence of the SWF file at this location at compile time. It does store this string in the
* application, however, and uses it at run time. As a result, the SWF file must be available at run time but
* necessarily not at compile time.
* <p>
* The policy-file-url is the location of the crossdomain.xml file that gives permission to read the RSL from the
* server. This might be necessary because the RSL can be on a separate server as the application. For example,
* http://www.mydomain.com/rsls/crossdomain.xml.
* <p>
* The failover-url and second policy-file-url arguments specify the location of the secondary RSL and
* crossdomain.xml file if the first RSL cannot be loaded. This most commonly happens when the client Player version
* does not support cross-domain RSLs. You can add any number of failover RSLs, but must include a policy file URL
* for each one.
* <p>
* Do not include spaces between the comma-separated values. The following example shows how to use this option:
*
* <pre>
* mxmlc -o=../lib/app.swf -runtime-shared-library-path=../lib/mylib.swc,../bin/myrsl.swf Main.mxml
* </pre>
*
* You can specify more than one library file to be used as an RSL. You do this by adding additional
* runtime-shared-library-path options.
* <p>
* You can also use the runtime-shared-libraries command to use RSLs with your applications. However, the
* runtime-shared-library-path option lets you also specify the location of the policy file and failover RSL.
* <p>
*/
// NOTE: if the annotations are modified, then also modify the annotations
// in COMPCConfiguration.
@Config(allowMultiple = true)
@Mapping({ "runtime-shared-library-path" })
@SoftPrerequisites({ "static-link-runtime-shared-libraries" })
@ArgumentNameGenerator(RSLArgumentNameGenerator.class)
@InfiniteArguments
@FlexOnly
public void setRuntimeSharedLibraryPath(ConfigurationValue cfgval, List<String> urls) throws ConfigurationException
{
if (urls.isEmpty())
return;
// Usage rule: if you use -rslp on the command line
// it will take effect unless you also specify -static-rsls=true on the command line.
if (CommandLineConfigurator.SOURCE_COMMAND_LINE.equals(cfgval.getSource()))
{
setOverrideStaticLinkRsl(false);
}
// ignore rsl if told to
if (getStaticLinkRsl())
{
return;
}
if (urls.size() < 2)
{
// insufficent arguments
throw new ConfigurationException.MissingArgument("rsl-url", "runtime-shared-library-path",
cfgval.getSource(), cfgval.getLine());
}
RuntimeSharedLibraryPathInfo info = new RuntimeSharedLibraryPathInfo();
// validate the first argument, the swc or open directory, required.
String include = resolvePathStrict(urls.get(0), cfgval, true);
info.setSWCPath(urls.get(0));
info.setSWCFile(new File(include));
// the rest of the args are: rsl-url, policy-file-url, rsl-url, policy-file-url,...
for (int i = 1; i < urls.size(); ++i)
{
final String url = urls.get(i);
if ((i + 1) % 2 == 0)
{
if ("".equals(url.length()))
{
// rsl urls is required
throw new ConfigurationException.MissingArgument("rsl-url", "runtime-shared-library-path",
cfgval.getSource(), cfgval.getLine());
}
info.addRSLURL(url);
}
else
{
info.addPolicyFileURL(url);
}
}
// if the last policy file was not specified, then add an empty one so
// there are always the same number of rsls and policy files.
if ((urls.size() % 2) == 0)
{
info.addPolicyFileURL("");
}
// take local variables and add to overall arguments.
if (rslPathInfoList == null)
{
rslPathInfoList = new ArrayList<RuntimeSharedLibraryPathInfo>();
}
rslPathInfoList.add(info);
}
//
// 'static-link-runtime-shared-libraries' option
//
private boolean staticLinkRsl = true;
private String staticLinkRslSource;
/**
* @return true if -cd-rsl option should be used. False otherwise.
*/
public boolean getStaticLinkRsl()
{
return staticLinkRsl;
}
/**
* Allow another option, namely -rslp to override the value of static-rsls. But you can not override a -static-rsls
* option that came from the command line.
*
* @param staticLinkRsl
*/
protected void setOverrideStaticLinkRsl(boolean staticLinkRsl)
{
if (CommandLineConfigurator.SOURCE_COMMAND_LINE.equals(staticLinkRslSource))
{
return;
}
this.staticLinkRsl = staticLinkRsl;
}
/**
* Determines whether to compile against libraries statically or use RSLs. Set this option to true to ignore the
* RSLs specified by the runtime-shared-library-path option. Set this option to false to use the RSLs.
* <p>
* This option is useful so that you can quickly switch between a statically and dynamically linked application
* without having to change the runtime-shared-library-path option, which can be verbose, or edit the configuration
* files.
*/
@Config
@Mapping("static-link-runtime-shared-libraries")
@FlexOnly
public void setStaticLinkRuntimeSharedLibraries(ConfigurationValue cv, boolean b)
{
staticLinkRsl = b;
staticLinkRslSource = cv.getSource();
}
//
// 'use-flashbuilder-project-files' option
//
private Boolean useFlashBuilderProjectFiles = false;
public Boolean getUseFlashBuilderProjectFiles()
{
return useFlashBuilderProjectFiles;
}
@Config
@Mapping({ "use-flashbuilder-project-files" })
@FlexOnly
public void setUseFlashBuilderProjectFiles(ConfigurationValue cv, Boolean useFiles) throws ConfigurationException
{
useFlashBuilderProjectFiles = useFiles;
}
//
// 'verify-digests' options
//
private boolean verifyDigests = true;
/**
* @return true if digest information associated with the -cd-rsl option is used by the application at runtime.
* False otherwise.
*/
public boolean getVerifyDigests()
{
return verifyDigests;
}
/**
* Instructs the application to check the digest of the RSL SWF file against the digest that was compiled into the
* application at compile time. This is a security measure that lets you load RSLs from remote domains or different
* sub-domains. It also lets you enforce versioning of your RSLs by forcing an application's digest to match the
* RSL's digest. If the digests are out of sync, you must recompile your application or load a different RSL SWF
* file.
*/
@Config(advanced = true)
@FlexOnly
public void setVerifyDigests(ConfigurationValue cv, boolean b)
{
verifyDigests = b;
}
//
// 'remove-unused-rsls' option
//
private boolean removeUnusedRSLs = false;
/**
* @return true if the user wants to remove unused RSLs. Otherwise false.
*/
public boolean getRemoveUnusedRsls()
{
return removeUnusedRSLs;
}
@Config(advanced = true)
@FlexOnly
public void setRemoveUnusedRsls(ConfigurationValue cv, boolean b)
{
removeUnusedRSLs = b;
}
//
// '-include-inheritance-dependencies-only' option
//
private boolean includeInheritanceDependenciesOnly = false;
/**
* @return true if the user want to include inheritance dependencies only.
*/
public boolean getIncludeInheritanceDependenciesOnly()
{
return includeInheritanceDependenciesOnly;
}
@Config(advanced = true)
public void setIncludeInheritanceDependenciesOnly(ConfigurationValue cv, boolean b)
{
includeInheritanceDependenciesOnly = b;
}
//
// 'target-player' option
//
// targeted player version (also set in DefaultsConfigurator)
private int majorVersionTarget = 11;
private int minorVersionTarget = 1;
private int revisionTarget = 0;
/**
* The major part the earliest player version that this compiler can target. The code generator generates bytecode
* which will not pass verification on players earlier than 10.1.
*/
public static final int TARGET_PLAYER_MAJOR_VERSION_MIN = 10;
/**
* The minor part the earliest player version that this compiler can target. The code generator generates bytecode
* which will not pass verification on players earlier than 10.1.
*/
public static final int TARGET_PLAYER_MINOR_VERSION_MIN = 1;
/**
* @return The major version of the player targeted by this application. The returned value will be greater to or
* equal to 9.
*/
public int getTargetPlayerMajorVersion()
{
return majorVersionTarget;
}
/**
* @return The minor version of the player targeted by this application. The returned value will be greater to or
* equal to 0.
*/
public int getTargetPlayerMinorVersion()
{
return minorVersionTarget;
}
/**
* @return The revision of the player targeted by this application. The returned value will be greater to or equal
* to 0.
*/
public int getTargetPlayerRevision()
{
return revisionTarget;
}
/**
* Specifies the version of Flash Player that you want to target with the application. Features requiring a later
* version of Flash Player are not compiled into the application.
* <p>
* The player_version parameter has the following format:<br>
* <code>major_version.minor_version.revision</code>
* <p>
* The major_version is required while minor_version and revision are optional. The minimum value is 10.0.0. If you
* do not specify the minor_version or revision, then the compiler uses zeros.
* <p>
* The value of major_version is also used by the {targetPlayerMajorVersion} token in the flex-config.xml file. This
* token can be used in any <path-element> element.
* <p>
* If you do not explicitly set the value of this option, the compiler uses the default from the flex-config.xml
* file. The value in flex-config.xml is the version of Flash Player that shipped with the SDK.
* <p>
* This option is useful if your application's audience has a specific player and cannot upgrade. You can use this
* to "downgrade" your application for that audience.
*/
@Config
@Arguments("version")
public void setTargetPlayer(ConfigurationValue cv, String version) throws ConfigurationException
{
if (version == null || version.equals(""))
return;
final String[] results = Iterables.toArray(Splitter.on(".").omitEmptyStrings().trimResults().split(version),
String.class);
// major.minor.revision
// major is required, minor and revision are optional
if (results.length < 1 || results.length > 3)
throw new ConfigurationException.BadVersion(version, "target-player");
final String majorVersion = results[0];
final String minorVersion;
if (results.length > 1)
minorVersion = results[1];
else
minorVersion = "0";
final String revision;
if (results.length > 2)
revision = results[2];
else
revision = "0";
try
{
majorVersionTarget = Integer.parseInt(majorVersion);
minorVersionTarget = Integer.parseInt(minorVersion);
revisionTarget = Integer.parseInt(revision);
}
catch (NumberFormatException e)
{
throw new ConfigurationException.BadVersion(version, "target-player");
}
if (majorVersionTarget < TARGET_PLAYER_MAJOR_VERSION_MIN
|| majorVersionTarget == TARGET_PLAYER_MAJOR_VERSION_MIN
&& minorVersionTarget < TARGET_PLAYER_MINOR_VERSION_MIN)
{
throw new ConfigurationException.BadVersion(version, "target-player");
}
}
//
// 'swf-version' option
//
// swf version 13 is what shipped with player 11, and is the min version for
// LZMA compression
private static final Map<String, Integer> targetPlayerToSWFVersionMap = getSwfVersionMap();
private static Map<String, Integer> getSwfVersionMap()
{
// Player 9 and below are not supported.
// 10.0 -> 10
// 10.1 -> 10
// 10.2 -> 11
// 10.3 -> 12
// 11.0 -> 13
// 11.1 -> 14
// 11.2 -> 15
// 11.3 -> 16
// 11.4 -> 17
// 11.5 -> 18
// 11.6 -> 19
// 11.7 -> 20
// 11.8 -> 21
// 11.9 -> 22
Map<String, Integer> map = new HashMap<String, Integer>(10);
map.put("10.0", 10);
map.put("10.1", 10);
map.put("10.2", 11);
map.put("10.3", 12);
map.put("11.0", 13);
map.put("11.1", 14);
map.put("11.2", 15);
map.put("11.3", 16);
map.put("11.4", 17);
map.put("11.5", 18);
map.put("11.6", 19);
map.put("11.7", 20);
map.put("11.8", 21);
map.put("11.9", 22);
return map;
}
private int lookupSwfVersion()
{
int swfVersion = DEFAULT_SWF_VERSION;
Integer lookupVersion = targetPlayerToSWFVersionMap.get(Integer.toString(getTargetPlayerMajorVersion()) + "."
+ Integer.toString(getTargetPlayerMinorVersion()));
if (lookupVersion != null)
swfVersion = lookupVersion;
return swfVersion;
}
private final int UNSET_SWF_VERSION = -1;
private final int DEFAULT_SWF_VERSION = 14; // matches default target-player
private final int MINIMUM_SWF_VERSION = 10; // matches minimum target-player
private int swfVersion = UNSET_SWF_VERSION;
public int getSwfVersion()
{
if (swfVersion == UNSET_SWF_VERSION)
swfVersion = lookupSwfVersion();
return swfVersion;
}
@Config
@Mapping("swf-version")
public void setSwfVersion(ConfigurationValue cv, int version) throws ConfigurationException
{
if (version < MINIMUM_SWF_VERSION)
throw new ConfigurationException.BadVersion(Integer.toString(version), "swf-version");
swfVersion = version;
}
//
// 'use-direct-blit' option
//
private boolean useDirectBlit = true;
public boolean getUseDirectBlit()
{
return useDirectBlit;
}
@Config
public void setUseDirectBlit(ConfigurationValue cv, boolean value)
{
useDirectBlit = value;
}
//
// 'use-gpu' option
//
private boolean useGpu = true;
public boolean getUseGpu()
{
return useGpu;
}
@Config
public void setUseGpu(ConfigurationValue cv, boolean value)
{
useGpu = value;
}
//
// 'tools-locale' options
//
private Locale toolsLocale = null;
/**
* @return locale to use when reporting compile time errors, or <code>null</code> if not specified. In that case,
* system's locale is used.
*/
public Locale getToolsLocale()
{
return toolsLocale;
}
/**
* Configures the LocalizationManager's locale, which is used when reporting compile time errors, warnings, and
* info.
*
* @param toolsLocale A locale in Java format. For example, "en" or "ja_JP".
* @throws ConfigurationException When the specified toolsLocale is not available a ToolsLocaleNotAvailable error is
* reported.
*/
@Config
@Mapping("tools-locale")
public void setToolsLocale(ConfigurationValue cv, String toolsLocale) throws ConfigurationException
{
Locale[] locales = Locale.getAvailableLocales();
for (int i = 0; i < locales.length; i++)
{
if (locales[i].toString().equals(toolsLocale))
{
this.toolsLocale = locales[i];
LocalizationManager.get().setLocale(locales[i]);
return;
}
}
throw new ConfigurationException.ToolsLocaleNotAvailable(cv.getVar(), cv.getSource(), cv.getLine());
}
//
// 'compiler.accessible' option
//
private boolean accessible = false;
public boolean getCompilerAccessible()
{
return accessible;
}
/**
* Enables accessibility features when compiling the application or SWC file.
*/
@Config
@Mapping({ "compiler", "accessible" })
@FlexOnly
public void setCompilerAccessible(ConfigurationValue cv, boolean accessible)
{
this.accessible = accessible;
}
//
// 'compiler.actionscript-file-encoding' option
//
private String actionscriptFileEncoding = null;
public String getCompilerActionscriptFileEncoding()
{
return actionscriptFileEncoding;
}
/**
* Sets the file encoding for ActionScript files.
*/
@Config
@Mapping({ "compiler", "actionscript-file-encoding" })
public void setCompilerActionscriptFileEncoding(ConfigurationValue cv, String encoding)
{
actionscriptFileEncoding = encoding;
}
//
// 'compiler.adjust-opdebugline' option (hidden)
//
private boolean adjustOpDebugLine = true;
public boolean getAdjustOpDebugLine()
{
return adjustOpDebugLine;
}
/**
* For internal use only. Set it to false so that debugging mxmlc auto-generated code is easier.
*/
@Config(advanced = true, hidden = true)
public void setCompilerAdjustOpdebugline(ConfigurationValue cv, boolean b)
{
adjustOpDebugLine = b;
}
//
// 'compiler.allow-source-path-overlap' option
//
private boolean allowSourcePathOverlap = false;
public boolean getAllowSourcePathOverlap()
{
return allowSourcePathOverlap;
}
/**
* Checks if a source-path entry is a sub-directory of another source-path entry. It helps make the package names of
* MXML components unambiguous.
*/
@Config(advanced = true)
public void setCompilerAllowSourcePathOverlap(ConfigurationValue cv, boolean b)
{
allowSourcePathOverlap = b;
}
//
// 'compiler.binding-value-change-event' option
//
private String bindingValueChangeEvent = "mx.events.PropertyChangeEvent";
public String getBindingValueChangeEvent()
{
return bindingValueChangeEvent;
}
/**
* The change event class for generated binding code
*/
@Config(advanced = true)
public void setCompilerBindingValueChangeEvent(ConfigurationValue cv, String b)
{
bindingValueChangeEvent = b;
}
//
// 'compiler.binding-value-change-event-kind' option
//
private String bindingValueChangeEventKind = "mx.events.PropertyChangeEventKind";
public String getBindingValueChangeEventKind()
{
return bindingValueChangeEventKind;
}
/**
* The change event kind for generated binding code
*/
@Config(advanced = true)
public void setCompilerBindingValueChangeEventKind(ConfigurationValue cv, String b)
{
bindingValueChangeEventKind = b;
}
//
// 'compiler.binding-value-change-event-type' option
//
private String bindingValueChangeEventType = "propertyChange";
public String getBindingValueChangeEventType()
{
return bindingValueChangeEventType;
}
/**
* The change event type for generated binding code
*/
@Config(advanced = true)
public void setCompilerBindingValueChangeEventType(ConfigurationValue cv, String b)
{
bindingValueChangeEventType = b;
}
//
// 'compiler.binding-event-handler-event' option
//
private String bindingEventHandlerEvent = "flash.events.Event";
public String getBindingEventHandlerEvent()
{
return bindingEventHandlerEvent;
}
/**
* The event handler event for generated binding code
*/
@Config(advanced = true)
public void setCompilerBindingEventHandlerEvent(ConfigurationValue cv, String b)
{
bindingEventHandlerEvent = b;
}
//
// 'compiler.binding-event-handler-class' option
//
private String bindingEventHandlerClass = "flash.events.EventDispatcher";
public String getBindingEventHandlerClass()
{
return bindingEventHandlerClass;
}
/**
* The event handler class for generated binding code
*/
@Config(advanced = true)
public void setCompilerBindingEventHandlerClass(ConfigurationValue cv, String b)
{
bindingEventHandlerClass = b;
}
//
// 'compiler.binding-event-handler-interface' option
//
private String bindingEventHandlerInterface = "flash.events.IEventDispatcher";
public String getBindingEventHandlerInterface()
{
return bindingEventHandlerInterface;
}
/**
* The event handler interface for generated binding code
*/
@Config(advanced = true)
public void setCompilerBindingEventHandlerInterface(ConfigurationValue cv, String b)
{
bindingEventHandlerInterface = b;
}
//
// 'compiler.byte-array-embed-class' option
//
private String byteArrayEmbedClass = "mx.core.ByteArrayAsset";
public String getByteArrayEmbedClass()
{
return byteArrayEmbedClass;
}
/**
* The class for embedded byte arrays
*/
@Config(advanced = true)
public void setCompilerByteArrayEmbedClass(ConfigurationValue cv, String b)
{
byteArrayEmbedClass = b;
}
//
// 'compiler.states-class' option
//
private String statesClass = "mx.states.State";
public String getStatesClass()
{
return statesClass;
}
/**
* The class for states
*/
@Config(advanced = true)
public void setCompilerStatesClass(ConfigurationValue cv, String b)
{
statesClass = b;
}
//
// 'compiler.states-instance-override-class' option
//
private String statesInstanceOverrideClass = "mx.states.AddItems";
public String getStatesInstanceOverrideClass()
{
return statesInstanceOverrideClass;
}
/**
* The class for state-dependent instances
*/
@Config(advanced = true)
public void setCompilerStatesInstanceOverrideClass(ConfigurationValue cv, String b)
{
statesInstanceOverrideClass = b;
}
//
// 'compiler.states-property-override-class' option
//
private String statesPropertyOverrideClass = "mx.states.SetProperty";
public String getStatesPropertyOverrideClass()
{
return statesPropertyOverrideClass;
}
/**
* The class for state-dependent properties
*/
@Config(advanced = true)
public void setCompilerStatesPropertyOverrideClass(ConfigurationValue cv, String b)
{
statesPropertyOverrideClass = b;
}
//
// 'compiler.states-event-override-class' option
//
private String statesEventOverrideClass = "mx.states.SetEventHandler";
public String getStatesEventOverrideClass()
{
return statesEventOverrideClass;
}
/**
* The class for state-dependent events
*/
@Config(advanced = true)
public void setCompilerStatesEventOverrideClass(ConfigurationValue cv, String b)
{
statesEventOverrideClass = b;
}
//
// 'compiler.states-style-override-class' option
//
private String statesStyleOverrideClass = "mx.states.SetStyle";
public String getStatesStyleOverrideClass()
{
return statesStyleOverrideClass;
}
/**
* The class for state-dependent styles
*/
@Config(advanced = true)
public void setCompilerStatesStyleOverrideClass(ConfigurationValue cv, String b)
{
statesStyleOverrideClass = b;
}
//
// 'compiler.proxy-base-class' option
//
private String proxyBaseClass = "org.apache.flex.utils.Proxy";
public String getProxyBaseClass()
{
return proxyBaseClass;
}
/**
* The class for proxy code generation
*/
@Config(advanced = true)
public void setCompilerProxyBaseClass(ConfigurationValue cv, String b)
{
proxyBaseClass = b;
}
//
// 'compiler.component-factory-class' option
//
private String componentFactoryClass = "mx.core.ClassFactory";
public String getComponentFactoryClass()
{
return componentFactoryClass;
}
/**
* The class for inline component factories
*/
@Config(advanced = true)
public void setCompilerComponentFactoryClass(ConfigurationValue cv, String b)
{
componentFactoryClass = b;
}
//
// 'compiler.component-factory-interface' option
//
private String componentFactoryInterface = "mx.core.IFactory";
public String getComponentFactoryInterface()
{
return componentFactoryInterface;
}
/**
* The interface for inline component factories
*/
@Config(advanced = true)
public void setCompilerComponentFactoryInterface(ConfigurationValue cv, String b)
{
componentFactoryInterface = b;
}
/**
* Syntax:<br/>
* <code>-define=&lt;name&gt;,&lt;value&gt;</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> configVars;
/**
* @return A list of ConfigVars
*/
public Map<String, String> getCompilerDefine()
{
return configVars;
}
@Config(advanced = true, allowMultiple = true)
@Arguments({ "name", "value" })
public void setCompilerDefine(ConfigurationValue cv, String name, String value) throws ConfigurationException
{
if (configVars == null)
configVars = new LinkedHashMap<String, String>();
configVars.put(name, value);
}
//
// 'compiler.conservative' option (hidden)
//
private boolean useConservativeAlgorithm = false;
public boolean useConservativeAlgorithm()
{
return useConservativeAlgorithm;
}
@Config(advanced = true, hidden = true)
@Mapping({ "compiler", "conservative" })
public void setCompilerConservative(ConfigurationValue cv, boolean c)
{
useConservativeAlgorithm = c;
}
//
// 'compiler.context-root' option
//
private String contextRoot = null;
public String getCompilerContextRoot()
{
return contextRoot;
}
/**
* "Context root" is used to resolve {context.root} tokens in services configuration files to improve portability.
*/
@Config
@Mapping({ "compiler", "context-root" })
@Arguments("context-path")
@FlexOnly
public void setCompilerContextRoot(ConfigurationValue cv, String contextRoot)
{
this.contextRoot = contextRoot;
}
//
// 'compiler.debug' option
//
private boolean generateDebugTags = false;
public boolean isDebuggingEnabled()
{
return generateDebugTags;
}
protected void setDebug(boolean value)
{
generateDebugTags = value;
}
@Config
@Mapping({ "compiler", "debug" })
public void setCompilerDebug(ConfigurationValue cv, boolean generateDebugTags)
{
this.generateDebugTags = generateDebugTags;
}
//
// 'compiler.defaults-css-url' option
//
/**
* Location of defaults stylesheet.
*/
private String defaultsCssUrl;
public String getCompilerDefaultsCssUrl()
{
return defaultsCssUrl;
}
/**
* Defines the location of the default style sheet. Setting this option overrides the implicit use of the
* defaults.css style sheet in the framework.swc file.
*/
@Config(advanced = true)
@Mapping({ "compiler", "defaults-css-url" })
@FlexOnly
public void setCompilerDefaultsCssUrl(ConfigurationValue cv, String defaultsCssUrlPath) throws CannotOpen
{
defaultsCssUrl = resolvePathStrict(defaultsCssUrlPath, cv);
}
//
// 'compiler.doc' option (hidden)
//
private boolean doc = false;
public boolean getCompilerDoc()
{
return this.doc;
}
@Config(advanced = true, hidden = true)
@Mapping({ "compiler", "doc" })
public void setCompilerDoc(ConfigurationValue cv, boolean doc)
{
this.doc = doc;
}
//
// 'compiler.external-library-path' option
//
private final List<String> externalLibraryPath = new ArrayList<String>();
public List<String> getCompilerExternalLibraryPath()
{
return externalLibraryPath;
}
private boolean compilingForAIR = false;
/**
* @return True if AIR libraries are included in the {@code external-library-path}.
*/
public boolean getCompilingForAIR()
{
return compilingForAIR;
}
@Config(allowMultiple = true, isPath = true)
@Mapping({ "compiler", "external-library-path" })
@Arguments(Arguments.PATH_ELEMENT)
@SoftPrerequisites({ "target-player", "exclude-native-js-libraries" })
@InfiniteArguments
public void setCompilerExternalLibraryPath(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);
externalLibraryPath.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);
}
/**
* Returns true if there's AIR libraries on the library paths.
*
* @param libraryPaths Library paths.
* @return True if there's AIR libraries on the library paths.
*/
private static boolean containsAIRLibraries(final ImmutableList<String> libraryPaths)
{
for (final String path : libraryPaths)
{
if (path.equals(SWC_AIRGLOBAL) || path.endsWith("/" + SWC_AIRGLOBAL) || path.endsWith("\\" + SWC_AIRGLOBAL))
{
return true;
}
}
return false;
}
//
// '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.
//
private String generatedDir = null;
public String getCompilerGeneratedDirectory()
{
return generatedDir;
}
public void setCompilerGeneratedDirectory(String generatedDir)
{
this.generatedDir = generatedDir;
}
//
// 'compiler.headless-server' option
//
private boolean headlessServer;
public boolean isHeadlessServer()
{
return headlessServer;
}
@Config(advanced = true)
@Mapping({ "compiler", "headless-server" })
@FlexOnly
public void setCompilerHeadlessServer(ConfigurationValue cv, boolean headlessServer)
{
this.headlessServer = headlessServer;
}
//
// 'compiler.include-libraries' option
//
private final List<String> includeLibraries = new ArrayList<String>();
public List<String> getCompilerIncludeLibraries()
{
return includeLibraries;
}
/**
* Links all classes inside a SWC file to the resulting application SWF file, regardless of whether or not they are
* used.
* <p>
* Contrast this option with the library-path option that includes only those classes that are referenced at compile
* time.
* <p>
* To link one or more classes whether or not they are used and not an entire SWC file, use the includes option.
* <p>
* This option is commonly used to specify resource bundles.
*/
@Config(allowMultiple = true, isPath = true)
@Mapping({ "compiler", "include-libraries" })
@Arguments("library")
@InfiniteArguments
public void setCompilerIncludeLibraries(ConfigurationValue cv, String[] pathlist) throws CannotOpen
{
final ImmutableList<String> resolvedPaths = expandTokens(Arrays.asList(pathlist), locales, cv,
!reportMissingCompilerLibraries);
includeLibraries.addAll(resolvedPaths);
}
//
// 'compiler.incremental' option
//
@Config(removed = true)
@Mapping({ "compiler", "incremental" })
public void setCompilerIncremental(ConfigurationValue cv, boolean b)
{
}
//
// 'compiler.keep-all-type-selectors' option.
/**
* This was initially used by Flex Builder when building design view, but they no longer use it.
*/
private boolean keepAllTypeSelectors;
public boolean keepAllTypeSelectors()
{
return keepAllTypeSelectors;
}
@Config(advanced = true)
@Mapping({ "compiler", "keep-all-type-selectors" })
@FlexOnly
public void setCompilerKeepAllTypeSelectors(ConfigurationValue cv, boolean keepAllTypeSelectors)
{
this.keepAllTypeSelectors = keepAllTypeSelectors;
}
//
// 'compiler.keep-as3-metadata' option
//
private Set<String> as3metadata = null;
public Set<String> getCompilerKeepAs3Metadata()
{
return as3metadata == null ? Collections.<String> emptySet() : as3metadata;
}
@Config(advanced = true, allowMultiple = true)
@Mapping({ "compiler", "keep-as3-metadata" })
@Arguments("name")
@InfiniteArguments
public void setCompilerKeepAs3Metadata(ConfigurationValue cv, List<String> values)
{
if (as3metadata == null)
as3metadata = new HashSet<String>();
as3metadata.addAll(values);
}
//
// 'compiler.keep-generated-actionscript' option (removed)
//
@Config(removed = true)
@Mapping({ "compiler", "keep-generated-actionscript" })
public void setCompilerKeepGeneratedActionscript(ConfigurationValue cv, boolean keep)
{
}
//
// 'compiler.keep-generated-signatures' option (removed)
//
@Config(removed = true)
@Mapping({ "compiler", "keep-generated-signatures" })
public void setCompilerKeepGeneratedSignatures(ConfigurationValue cv, boolean keep)
{
}
//
// 'compiler.enable-runtime-design-layers' option
//
private boolean enableRuntimeDesignLayers = true;
public boolean getEnableRuntimeDesignLayers()
{
return enableRuntimeDesignLayers;
}
@Config
@Mapping({ "compiler", "enable-runtime-design-layers" })
@FlexOnly
public void setCompilerEnableRuntimeDesignLayers(ConfigurationValue cv, boolean enable)
{
enableRuntimeDesignLayers = enable;
}
//
// 'compiler.enable-swc-version-filtering' option
//
private boolean enableSwcVersionFiltering = true;
public boolean getEnableSwcVersionFiltering()
{
return enableSwcVersionFiltering;
}
@Config(advanced = true, hidden = true)
@Mapping({ "compiler", "enable-swc-version-filtering" })
public void setCompilerEnableSwcVersionFiltering(ConfigurationValue cv, boolean enable)
{
this.enableSwcVersionFiltering = enable;
}
//
// 'compiler.library-path' option
//
private final List<String> libraryPath = new ArrayList<String>();
protected boolean reportMissingCompilerLibraries = 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 setReportMissingCompilerLibraries(boolean reportMissingCompilerLibraries)
{
this.reportMissingCompilerLibraries = reportMissingCompilerLibraries;
}
public List<String> getCompilerLibraryPath()
{
return libraryPath;
}
/**
* 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", "library-path" })
@Arguments(Arguments.PATH_ELEMENT)
@InfiniteArguments
@SoftPrerequisites({ "locale", "target-player", "exclude-native-js-libraries" })
public void setCompilerLibraryPath(ConfigurationValue cv, String[] pathlist) throws CannotOpen
{
pathlist = removeNativeJSLibrariesIfNeeded(pathlist);
final ImmutableList<String> resolvedPaths = expandTokens(Arrays.asList(pathlist), locales, cv,
!reportMissingCompilerLibraries);
libraryPath.addAll(resolvedPaths);
}
//
// '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
//
protected final List<String> locales = new ArrayList<String>();
public List<String> getCompilerLocales()
{
return locales;
}
/**
* Specifies one or more locales to be compiled into the SWF file. If you do not specify a locale, then the compiler
* uses the default locale from the flex-config.xml file. The default value is en_US. You can append additional
* locales to the default locale by using the += operator. If you remove the default locale from the flex-config.xml
* file, and do not specify one on the command line, then the compiler will use the machine's locale.
*/
@Config(allowMultiple = true)
@Mapping({ "compiler", "locale" })
@Arguments("locale-element")
@InfiniteArguments
@FlexOnly
public void setCompilerLocale(ConfigurationValue cv, String[] newLocales)
{
locales.addAll(Arrays.asList(newLocales));
}
//
// 'compiler.metadata-export' option (incomplete)
//
private boolean metadataExport;
public boolean metadataExport()
{
return metadataExport;
}
// metadataExport does not have the normal configuration setCompilerter because it is not
// a normal configuration value but rather something setCompiler by the compiler
public void setCompilerMetadataExport(boolean metadataExport)
{
this.metadataExport = metadataExport;
}
//
// 'compiler.mxml.children-as-data' option
//
private Boolean childrenAsData = false;
public Boolean getCompilerMxmlChildrenAsData()
{
return childrenAsData;
}
@Config
@Mapping({ "compiler", "mxml", "children-as-data" })
@FlexOnly
public void setCompilerMxmlChildrenAsData(ConfigurationValue cv, Boolean asData) throws ConfigurationException
{
childrenAsData = asData;
}
//
// 'compiler.info.flex' option
// used to suppress some of info() fields
//
private Boolean infoFlex = true;
public Boolean getCompilerInfoFlex()
{
return infoFlex;
}
@Config
@Mapping({ "compiler", "info", "flex" })
@FlexOnly
public void setCompilerInfoFlex(ConfigurationValue cv, Boolean asData) throws ConfigurationException
{
infoFlex = asData;
}
//
// 'compiler.allow-subclass-overrides' option
//
private Boolean allowSubclassOverrides = false;
public Boolean getCompilerAllowSubclassOverrides()
{
return allowSubclassOverrides;
}
@Config
@Mapping({ "compiler", "allow-subclass-overrides" })
@FlexOnly
public void setCompilerAllowSubclassOverrides(ConfigurationValue cv, Boolean allow) throws ConfigurationException
{
allowSubclassOverrides = allow;
}
//
// 'compiler.mxml.implicitImports' option
//
private String[] implicitImports;
public String[] getCompilerMxmlImplicitImports()
{
return implicitImports;
}
@Config(allowMultiple = true)
@Mapping({ "compiler", "mxml", "imports" })
@Arguments("implicit-import")
@InfiniteArguments
@FlexOnly
public void setCompilerMxmlImplicitImports(ConfigurationValue cv, String[] imports) throws ConfigurationException
{
implicitImports = imports;
}
//
// 'compiler.mxml.compatibility-version' option
//
public String getCompilerCompatibilityVersionString()
{
return getCompilerMxmlCompatibilityVersionString();
}
public int getCompilerCompatibilityVersion()
{
return getCompilerMxmlCompatibilityVersion();
}
//
// 'compiler.mxml.minimum-supported-version' option
//
public String getCompilerMinimumSupportedVersionString()
{
return getCompilerMxmlMinimumSupportedVersionString();
}
public int getCompilerMinimumSupportedVersion()
{
return getCompilerMxmlMinimumSupportedVersion();
}
@Config
@Mapping({ "compiler", "minimum-supported-version" })
@FlexOnly
public void setCompilerMinimumSupportedVersion(ConfigurationValue cv, String version) throws ConfigurationException
{
setCompilerMxmlMinimumSupportedVersion(cv, version);
}
//
// 'qualified-type-selectors' option
//
@Config(advanced = true, removed = true)
@Mapping({ "compiler", "mxml", "qualified-type-selectors" })
public void setCompilerMxmlQualifiedTypeSelectors(ConfigurationValue cv, boolean b)
{
}
//
// 'compiler.omit-trace-statements' option
//
private boolean omitTraceStatements = true;
public boolean omitTraceStatements()
{
return omitTraceStatements;
}
@Config
@Mapping({ "compiler", "omit-trace-statements" })
public void setCompilerOmitTraceStatements(ConfigurationValue cv, boolean b)
{
omitTraceStatements = b;
}
//
// 'compiler.optimize' option
//
private boolean optimize = false;
public boolean optimize()
{
return optimize;
}
public boolean getCompilerOptimize()
{
return optimize;
}
@Config
@Mapping({ "compiler", "optimize" })
public void setCompilerOptimize(ConfigurationValue cv, boolean b)
{
optimize = b;
}
//
// 'compiler.preloader' option
//
private String preloader = null;
/**
*
* @return Returns the preloader class configured by the user. If the user did not configure a preloader, the
* "mx.preloader.DownloaderProgressBar" preloader will be returned if the compatibility version is less than
* 4.0. Otherwise the "mx.preloaders.SparkDownloadProgressBar" preloader will be returned.
*/
public String getPreloader()
{
if (preloader != null)
return preloader;
if (getCompilerMxmlCompatibilityVersion() < MXML_VERSION_4_0)
return IMXMLTypeConstants.DownloadProgressBar;
else
return IMXMLTypeConstants.SparkDownloadProgressBar;
}
public String getCompilerPreloader()
{
return preloader;
}
@Config
@Mapping({ "compiler", "preloader" })
@FlexOnly
public void setCompilerPreloader(ConfigurationValue cv, String value)
{
preloader = value;
}
//
// 'compiler.services' option
//
private File servicesConfigFile;
//protected ServicesDependencies servicesDependencies;
public File getCompilerServices()
{
return servicesConfigFile;
}
/**
* Used by the compiler to record the client dependencies from the Flex Data Services configuration file.
*/
/*
* public ServicesDependencies getCompilerServicesDependencies() { if
* (servicesDependencies == null && servicesConfigFile != null) { String
* servicesPath = servicesConfigFile.getName(); servicesDependencies = new
* ServicesDependencies(servicesPath, null, getCompilerContextRoot()); }
* return servicesDependencies; } public void
* setCompilerServicesDependencies(ServicesDependencies deps) {
* servicesDependencies = deps; }
*/
@Config
@Mapping({ "compiler", "services" })
@Arguments("filename")
@FlexOnly
public void setCompilerServices(ConfigurationValue cv, String servicesPath) throws ConfigurationException
{
try
{
servicesConfigFile = new File(resolvePathStrict(servicesPath, cv));
}
catch (Exception e)
{
throw new ConfigurationException.CannotOpen(servicesPath, cv.getVar(), cv.getSource(), cv.getLine());
}
}
//
// 'compiler.show-actionscript-warnings' option
//
/**
* Enable asc -warnings
*/
private boolean ascWarnings;
public boolean warnings()
{
return this.ascWarnings;
}
@Config
@Mapping({ "compiler", "show-actionscript-warnings" })
public void setCompilerShowActionscriptWarnings(ConfigurationValue cv, boolean ascWarnings)
{
this.ascWarnings = ascWarnings;
}
//
// 'compiler.show-binding-warnings' option
//
/**
* Controls whether binding warnings are displayed.
*/
private boolean showBindingWarnings = true;
public boolean showBindingWarnings()
{
return showBindingWarnings;
}
@Config
@Mapping({ "compiler", "show-binding-warnings" })
public void setCompilerShowBindingWarnings(ConfigurationValue cv, boolean show)
{
this.showBindingWarnings = show;
}
@Config
@Mapping({ "compiler", "show-multiple-definition-warnings" })
public void setCompilerShowMultipleDefinitionWarnings(ConfigurationValue cv, boolean show)
{
this.showMultipleDefinitionWarnings = show;
}
//
// 'compiler.show-dependency-warnings' option (hidden)
//
private boolean showDependencyWarnings = false;
public boolean showDependencyWarnings()
{
return showDependencyWarnings;
}
@Config(advanced = true, hidden = true)
@Mapping({ "compiler", "show-dependency-warnings" })
public void setCompilerShowDependencyWarnings(ConfigurationValue cv, boolean show)
{
this.showDependencyWarnings = show;
}
//
// 'compiler.report-invalid-styles-as-warnings' option
//
/**
* Controls whether invalid styles are report as errors or warnings.
*/
private boolean reportInvalidStylesAsWarnings = false;
/**
* Get value of {@code compiler.report-invalid-styles-as-warnings} option value.
* <p>
* <h2>What's "invalid styles"?</h2> The term "invalid style" only applies to MXML style specifier (a.k.a. inline
* style). If a style of a component is defined with "theme" attribute, the style is only effective with such theme.
* If a theme-specific style is used in an application who doesn't use the required theme, the style is considered
* invalid.
* <p>
* For example, style "fooStyle" is defined to used only with theme called "fooTheme":
*
* <pre>
* [Style(name="fooStyle", type="uint", format="Color", inherit="yes", theme="fooTheme")]
* public class MyComponent extends UIComponent
* </pre>
*
* If "fooTheme" isn't used by the current application, the following style specifier is considered "invalid styles"
* . <br>
* {@code <local:MyComponent fooStyle="white" />}
*
* @return True if invalid styles are reported as warnings instead of errors.
*/
public boolean getReportInvalidStylesAsWarnings()
{
return reportInvalidStylesAsWarnings;
}
@Config
@Mapping({ "compiler", "report-invalid-styles-as-warnings" })
@FlexOnly
public void setCompilerReportInvalidStylesAsWarnings(ConfigurationValue cv, boolean show)
{
this.reportInvalidStylesAsWarnings = show;
}
//
// 'compiler.report-missing-required-skin-parts-as-warnings' option
//
private boolean reportMissingRequiredSkinPartsAsWarnings = false;
/**
* Allow the user to configure whether it should be considered an error to not create a required skin part or if it
* should just be a warning.
*/
public boolean reportMissingRequiredSkinPartsAsWarnings()
{
return reportMissingRequiredSkinPartsAsWarnings;
}
@Config(advanced = true)
@Mapping({ "compiler", "report-missing-required-skin-parts-as-warnings" })
@FlexOnly
public void setCompilerReportMissingRequiredSkinPartsAsWarnings(ConfigurationValue cv, boolean b)
{
reportMissingRequiredSkinPartsAsWarnings = b;
}
//
// 'compiler.show-invalid-css-property-warnings' option
//
private boolean showInvalidCSSPropertyWarnings = true;
/**
* Controls whether warnings are displayed when styles, which don't apply to the current theme(s), are used in CSS.
* <p>
* See {@link #getReportInvalidStylesAsWarnings()} for definition of "invalid style".
* <p>
* This option applies to <i>invalid styles</i> in a {@code <fx:Style>} block.
*/
public boolean getShowInvalidCSSPropertyWarnings()
{
return showInvalidCSSPropertyWarnings;
}
@Config
@Mapping({ "compiler", "show-invalid-css-property-warnings" })
@FlexOnly
public void setShowInvalidCssPropertyWarnings(ConfigurationValue cv, boolean show)
{
this.showInvalidCSSPropertyWarnings = show;
}
//
// 'compiler.show-deprecation-warnings' option
//
/**
* Controls whether warnings are displayed when a deprecated API is used.
*/
private boolean showDeprecationWarnings = false;
public boolean showDeprecationWarnings()
{
return showDeprecationWarnings;
}
@Config(advanced = true, hidden = true)
@Mapping({ "compiler", "show-deprecation-warnings" })
public void setCompilerShowDeprecationWarnings(ConfigurationValue cv, boolean show)
{
this.showDeprecationWarnings = show;
}
//
// 'compiler.show-shadowed-device-font-warnings' option
//
@Config
@Mapping({ "compiler", "show-shadowed-device-font-warnings" })
@FlexOnly
public void setCompilerShowShadowedDeviceFontWarnings(ConfigurationValue cv, boolean show)
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
//
// 'compiler.show-unused-type-selector-warnings' option
//
private boolean showUnusedTypeSelectorWarnings = true;
public boolean showUnusedTypeSelectorWarnings()
{
return showUnusedTypeSelectorWarnings;
}
//
// 'compiler.show-multiple-definition-warnings' option
//
private boolean showMultipleDefinitionWarnings = true;
public boolean showMultipleDefinitionWarnings()
{
return showMultipleDefinitionWarnings;
}
@Config
@Mapping({ "compiler", "show-unused-type-selector-warnings" })
@FlexOnly
public void setCompilerShowUnusedTypeSelectorWarnings(ConfigurationValue cv, boolean show)
{
this.showUnusedTypeSelectorWarnings = show;
}
//
// 'compiler.source-path' option
//
/**
* Source path elements searched for ActionScript class files, possibly containing a {locale} token.
*/
private final List<String> unexpandedSourcePath = new ArrayList<String>();
/**
* Directories searched for ActionScript class files. The specified compiler.source-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 ignored,
* because we do not support compiling, for example, both en_US and ja_JP versions of MyComponent into the same SWF.
* A path element with {locale} is similarly ignored if you compile for no locale.
*/
private final List<String> sourcePath = new ArrayList<String>();
/** Context object for "source-path" option. */
private ConfigurationValue sourcePathContext = null;
public List<String> getCompilerSourcePath()
{
return sourcePath;
}
/**
* Get the source paths computed from the given {@code locale}. The locale must be included in the configuration.
*
* @param locale Locale name.
* @return Source paths computed from the given {@code locale}.
* @throws CannotOpen Error resolving one of the paths from this locale.
*/
public ImmutableList<String> getCompilerResourceBundlePathForLocale(String locale) throws CannotOpen
{
assert locales.contains(locale) : "Locale is not configured: " + locale;
return expandTokens(unexpandedSourcePath, ImmutableSet.of(locale), sourcePathContext,
!reportMissingCompilerLibraries);
}
@Config(allowMultiple = true)
@Arguments(Arguments.PATH_ELEMENT)
@SoftPrerequisites("locale")
public void setCompilerSourcePath(ConfigurationValue cv, String[] paths) throws ConfigurationException
{
final List<String> pathList = Arrays.asList(paths);
unexpandedSourcePath.addAll(pathList);
final ImmutableList<String> resolvedSourcePaths = expandTokens(pathList, locales, cv);
assertThatAllPathsAreDirectories(resolvedSourcePaths, cv);
sourcePath.addAll(resolvedSourcePaths);
sourcePathContext = cv;
}
/**
* Check that all paths in the path list are directories.
*
* @param paths A list of paths.
* @param cv Context.
* @throws NotDirectory Path is not a directory exception.
*/
public static void assertThatAllPathsAreDirectories(final List<String> paths, final ConfigurationValue cv)
throws NotDirectory
{
assert paths != null : "Expected path list.";
assert cv != null : "Expected ConfigurationValue as context.";
for (final String path : paths)
{
final File file = new File(path);
if (!file.isDirectory())
throw new NotDirectory(path, cv.getVar(), cv.getSource(), cv.getLine());
}
}
public static ConfigurationInfo getCompilerSourcePathInfo()
{
return new ConfigurationInfo(-1, new String[] { "path-element" })
{
@Override
public boolean allowMultiple()
{
return true;
}
@Override
public boolean isPath()
{
return true;
}
};
}
//
// 'compiler.strict' option
//
/**
* Run the AS3 compiler in strict mode
*/
private boolean strict;
public boolean strict()
{
return this.strict;
}
@Config
@Mapping({ "compiler", "strict" })
public void setCompilerStrict(ConfigurationValue cv, boolean strict)
{
this.strict = strict;
}
//
// 'compiler.suppress-warnings-in-incremental' option (incomplete)
//
// for Zorn
//
// When doing incremental compilation, the compiler doesn't recompile codes that are previously compiled with
// warnings. It only outputs the warning messages so as to remind users of the warnings.
//
// The command-line tool and Zorn work differently in that Zorn keeps the warning logger while the commnad-line
// tool, of course, can't keep the warning logger alive...
//
// Zorn needs this flag to tell the compiler not to output warnings again in incremental compilations because
// it keeps its own log.
private boolean suppressWarningsInIncremental = false;
public boolean suppressWarningsInIncremental()
{
return suppressWarningsInIncremental;
}
public void setCompilerSuppressWarningsInIncremental(boolean b)
{
suppressWarningsInIncremental = b;
}
//
// 'compiler.theme' option
//
private List<String> themeFiles = null;
/**
* Get normalized theme file paths. If a the compiler is in "Flex 3 compatibility" mode and only "Spark" theme is
* used, it will be replaced with the legacy "Halo" theme.
*
* @return A list of normalized paths to the theme files.
*/
public List<String> getCompilerThemeFiles()
{
if (themeFiles == null)
return EMPTY_STRING_LIST;
final boolean isVersion3OrEarlier = getCompilerMxmlCompatibilityVersion() <= MXML_VERSION_3_0;
final boolean hasOnlyOneThemeFile = themeFiles.size() == 1;
if (isVersion3OrEarlier && hasOnlyOneThemeFile)
{
// Swap in the default Flex 3 theme of Halo.
final String path = FilenameUtils.normalize(themeFiles.get(0), true);
final String sparkPath = "/themes/Spark/spark.css";
if (path.endsWith(sparkPath))
{
int index = path.indexOf(sparkPath);
final String haloPath = path.substring(0, index) + "/themes/Halo/halo.swc";
themeFiles.set(0, FilenameNormalization.normalize(haloPath));
}
}
return themeFiles;
}
@Config(allowMultiple = true)
@Mapping({ "compiler", "theme" })
@Arguments("filename")
@InfiniteArguments
@FlexOnly
public void setCompilerTheme(ConfigurationValue cv, List<String> paths) throws CannotOpen
{
// Use "resolvePathsStrict()" if invalid theme file can't be ignored.
final ImmutableList<String> resolved = resolvePathsStrict(ImmutableList.copyOf(paths), cv);
if (themeFiles == null)
themeFiles = new ArrayList<String>();
themeFiles.addAll(resolved);
}
//
// 'compiler.defaults-css-files' option
//
private Deque<String> defaultsCSSFiles = new ArrayDeque<String>();
/**
* List of filenames of defaults style stylesheets (css only).
* <p>
* <b>For example:</b><br>
* <code>-defaults-css-files=[A, B, C]</code><br>
* Then, 'A' should have precedence over 'B', then 'C', then SWCs defaultsCssFiles should have the order: SWCS, C,
* B, A
*
* @see #setDefaultsCSSFiles
*/
public Deque<String> getDefaultsCSSFiles()
{
return defaultsCSSFiles;
}
/**
* Inserts CSS files into the output the same way that a per-SWC defaults.css file works, but without having to
* re-archive the SWC file to test each change.
* <p>
* CSS files included in the output with this option have a higher precedence than default CSS files in existing
* SWCs. For example, a CSS file included with this option overrides definitions in framework.swc's defaults.css
* file, but it has the same overall precedence as other included CSS files inside the SWC file.
* <p>
* This option does not actually insert the CSS file into the SWC file; it simulates it. When you finish developing
* the CSS file, you should rebuild the SWC file with the new integrated CSS file.
* <p>
* This option takes one or more files. The precedence for multiple CSS files included with this option is from
* first to last.
*/
@Config(allowMultiple = true, advanced = true)
@Mapping({ "compiler", "defaults-css-files" })
@Arguments("filename")
@InfiniteArguments
@FlexOnly
public void setDefaultsCSSFiles(ConfigurationValue cv, List<String> paths) throws CannotOpen
{
final ImmutableList<String> resolved = resolvePathsStrict(ImmutableList.copyOf(paths), cv);
for (final String path : resolved)
{
defaultsCSSFiles.addFirst(path);
}
}
//
// 'compiler.exclude-defaults-css-files' option
//
private Deque<String> excludeDefaultsCSSFiles = new ArrayDeque<String>();
/**
* List of filenames to exclude from list of defaults style stylesheets (css only).
* For defaults.css files in a SWC, use HTML.swc:defaults.css where HTML is the
* name of a SWC.
* <p>
* <b>For example:</b><br>
* <code>-exclude-defaults-css-files=[A, B, C]</code><br>
* Then, 'A' should have precedence over 'B', then 'C', then SWCs defaultsCssFiles should have the order: SWCS, C,
* B, A
*
* @see #setExcludeDefaultsCSSFiles
*/
public Deque<String> getExcludeDefaultsCSSFiles()
{
return excludeDefaultsCSSFiles;
}
/**
* Excludes CSS files from the output.
* <p>
* This option takes one or more files. The precedence for multiple CSS files included with this option is from
* first to last.
*/
@Config(allowMultiple = true, advanced = true)
@Mapping({ "compiler", "exclude-defaults-css-files" })
@Arguments("filename")
@InfiniteArguments
@FlexOnly
public void setExcludeDefaultsCSSFiles(ConfigurationValue cv, List<String> paths) throws CannotOpen
{
final ImmutableList<String> resolved = resolvePathsStrict(ImmutableList.copyOf(paths), cv, true);
for (final String path : resolved)
{
excludeDefaultsCSSFiles.addFirst(path);
}
}
/**
* Location of theme style stylesheets (css only, configured via themefiles above).
*/
private List<IFileSpecification> themeCssFiles = new LinkedList<IFileSpecification>();
public List<IFileSpecification> getCompilerThemeCssFiles()
{
return themeCssFiles;
}
public void addThemeCssFiles(List<IFileSpecification> files)
{
themeCssFiles.addAll(files);
}
//
// 'compiler.use-resource-bundle-metadata' option
//
@Config(removed = true)
@Mapping({ "compiler", "use-resource-bundle-metadata" })
public void setCompilerUseResourceBundleMetadata(ConfigurationValue cv, boolean b)
{
}
//
// 'compiler.verbose-stacktraces' option
//
private boolean verboseStacktraces;
// from as3 and mxml configuration interface
public boolean debug()
{
// the debug() in as3 and mxml configuration maps to stacktraceLineNumbers
return verboseStacktraces;
}
public boolean release() {
return !verboseStacktraces;
}
@Config
@Mapping({ "compiler", "verbose-stacktraces" })
public void setCompilerVerboseStacktraces(ConfigurationValue cv, boolean verboseStacktraces)
{
if (generateDebugTags)
{
this.verboseStacktraces = true;
}
else
{
this.verboseStacktraces = verboseStacktraces;
}
}
//
// 'compiler.warn-array-tostring-changes' option
//
private boolean warn_array_tostring_changes = false;
public boolean warn_array_tostring_changes()
{
return warn_array_tostring_changes;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-array-tostring-changes" })
public void setCompilerWarnArrayTostringChanges(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_array_tostring_changes)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-assignment-within-conditional' option
//
private boolean warn_assignment_within_conditional = true;
public boolean warn_assignment_within_conditional()
{
return warn_assignment_within_conditional;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-assignment-within-conditional" })
public void setCompilerWarnAssignmentWithinConditional(ConfigurationValue cv, boolean b)
{
warn_assignment_within_conditional = b;
}
//
// 'compiler.warn-bad-array-cast' option
//
private boolean warn_bad_array_cast = true;
public boolean warn_bad_array_cast()
{
return warn_bad_array_cast;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-array-cast" })
public void setCompilerWarnBadArrayCast(ConfigurationValue cv, boolean b)
{
warn_bad_array_cast = b;
}
//
// 'compiler.warn-bad-bool-assignment' option
//
private boolean warn_bad_bool_assignment = true;
public boolean warn_bad_bool_assignment()
{
return warn_bad_bool_assignment;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-bool-assignment" })
public void setCompilerWarnBadBoolAssignment(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_bad_bool_assignment)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-bad-date-cast' option
//
private boolean warn_bad_date_cast = true;
public boolean warn_bad_date_cast()
{
return warn_bad_date_cast;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-date-cast" })
public void setCompilerWarnBadDateCast(ConfigurationValue cv, boolean b)
{
warn_bad_date_cast = b;
}
//
// 'compiler.warn-bad-es3-type-method' option
//
private boolean warn_bad_es3_type_method = true;
public boolean warn_bad_es3_type_method()
{
return warn_bad_es3_type_method;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-es3-type-method" })
public void setCompilerWarnBadEs3TypeMethod(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_bad_es3_type_method)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-bad-es3-type-prop' option
//
private boolean warn_bad_es3_type_prop = true;
public boolean warn_bad_es3_type_prop()
{
return warn_bad_es3_type_prop;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-es3-type-prop" })
public void setCompilerWarnBadEs3TypeProp(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_bad_es3_type_prop)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-bad-nan-comparison' option
//
private boolean warn_bad_nan_comparison = true;
public boolean warn_bad_nan_comparison()
{
return warn_bad_nan_comparison;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-nan-comparison" })
public void setCompilerWarnBadNanComparison(ConfigurationValue cv, boolean b)
{
warn_bad_nan_comparison = b;
}
//
// 'compiler.warn-bad-null-assignment' option
//
private boolean warn_bad_null_assignment = true;
public boolean warn_bad_null_assignment()
{
return warn_bad_null_assignment;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-null-assignment" })
public void setCompilerWarnBadNullAssignment(ConfigurationValue cv, boolean b)
{
warn_bad_null_assignment = b;
}
//
// 'compiler.warn-bad-null-comparison' option
//
private boolean warn_bad_null_comparison = true;
public boolean warn_bad_null_comparison()
{
return warn_bad_null_comparison;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-null-comparison" })
public void setCompilerWarnBadNullComparison(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_bad_null_comparison)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-bad-undefined-comparison' option
//
private boolean warn_bad_undefined_comparison = true;
public boolean warn_bad_undefined_comparison()
{
return warn_bad_undefined_comparison;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-bad-undefined-comparison" })
public void setCompilerWarnBadUndefinedComparison(ConfigurationValue cv, boolean b)
{
warn_bad_undefined_comparison = b;
}
//
// 'compiler.warn-boolean-constructor-with-no-args' option
//
private boolean warn_boolean_constructor_with_no_args = false;
public boolean warn_boolean_constructor_with_no_args()
{
return warn_boolean_constructor_with_no_args;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-boolean-constructor-with-no-args" })
public void setCompilerWarnBooleanConstructorWithNoArgs(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_boolean_constructor_with_no_args)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-changes-in-resolve' option
//
private boolean warn_changes_in_resolve = false;
public boolean warn_changes_in_resolve()
{
return warn_changes_in_resolve;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-changes-in-resolve" })
public void setCompilerWarnChangesInResolve(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_changes_in_resolve)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-class-is-sealed' option
//
private boolean warn_class_is_sealed = true;
public boolean warn_class_is_sealed()
{
return warn_class_is_sealed;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-class-is-sealed" })
public void setCompilerWarnClassIsSealed(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_class_is_sealed)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-const-not-initialized' option
//
private boolean warn_const_not_initialized = true;
public boolean warn_const_not_initialized()
{
return warn_const_not_initialized;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-const-not-initialized" })
public void setCompilerWarnConstNotInitialized(ConfigurationValue cv, boolean b)
{
warn_const_not_initialized = b;
}
//
// 'compiler.warn-constructor-returns-value' option
//
private boolean warn_constructor_returns_value = false;
public boolean warn_constructor_returns_value()
{
return warn_constructor_returns_value;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-constructor-returns-value" })
public void setCompilerWarnConstructorReturnsValue(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_constructor_returns_value)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-deprecated-event-handler-error' option
//
private boolean warn_deprecated_event_handler_error = false;
public boolean warn_deprecated_event_handler_error()
{
return warn_deprecated_event_handler_error;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-deprecated-event-handler-error" })
public void setCompilerWarnDeprecatedEventHandlerError(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_deprecated_event_handler_error)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-deprecated-function-error' option
//
private boolean warn_deprecated_function_error = true;
public boolean warn_deprecated_function_error()
{
return warn_deprecated_function_error;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-deprecated-function-error" })
public void setCompilerWarnDeprecatedFunctionError(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_deprecated_function_error)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-deprecated-property-error' option
//
private boolean warn_deprecated_property_error = true;
public boolean warn_deprecated_property_error()
{
return warn_deprecated_property_error;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-deprecated-property-error" })
public void setCompilerWarnDeprecatedPropertyError(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_deprecated_property_error)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-duplicate-argument-names' option
//
private boolean warn_duplicate_argument_names = true;
public boolean warn_duplicate_argument_names()
{
return warn_duplicate_argument_names;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-duplicate-argument-names" })
public void setCompilerWarnDuplicateArgumentNames(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_duplicate_argument_names)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-duplicate-variable-def' option
//
private boolean warn_duplicate_variable_def = true;
public boolean warn_duplicate_variable_def()
{
return warn_duplicate_variable_def;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-duplicate-variable-def" })
public void csetCompilerWarnDuplicateVariableDef(ConfigurationValue cv, boolean b)
{
warn_duplicate_variable_def = b;
}
//
// 'compiler.warn-for-var-in-changes' option
//
private boolean warn_for_var_in_changes = false;
public boolean warn_for_var_in_changes()
{
return warn_for_var_in_changes;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-for-var-in-changes" })
public void setCompilerWarnForVarInChanges(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_for_var_in_changes)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-import-hides-class' option
//
private boolean warn_import_hides_class = true;
public boolean warn_import_hides_class()
{
return warn_import_hides_class;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-import-hides-class" })
public void setCompilerWarnImportHidesClass(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_import_hides_class)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-instance-of-changes' option
//
private boolean warn_instance_of_changes = true;
public boolean warn_instance_of_changes()
{
return warn_instance_of_changes;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-instance-of-changes" })
public void setCompilerWarnInstanceOfChanges(ConfigurationValue cv, boolean b)
{
warn_instance_of_changes = b;
}
//
// 'compiler.warn-internal-error' option
//
private boolean warn_internal_error = true;
public boolean warn_internal_error()
{
return warn_internal_error;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-internal-error" })
public void setCompilerWarnInternalError(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_internal_error)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-level-not-supported' option
//
private boolean warn_level_not_supported = true;
public boolean warn_level_not_supported()
{
return warn_level_not_supported;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-level-not-supported" })
public void setCompilerWarnLevelNotSupported(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_level_not_supported)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-missing-namespace-decl' option
//
private boolean warn_missing_namespace_decl = true;
public boolean warn_missing_namespace_decl()
{
return warn_missing_namespace_decl;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-missing-namespace-decl" })
public void setCompilerWarnMissingNamespaceDecl(ConfigurationValue cv, boolean b)
{
warn_missing_namespace_decl = b;
}
//
// 'compiler.warn-negative-uint-literal' option
//
private boolean warn_negative_uint_literal = true;
public boolean warn_negative_uint_literal()
{
return warn_negative_uint_literal;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-negative-uint-literal" })
public void setCompilerWarnNegativeUintLiteral(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_negative_uint_literal)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-no-constructor' option
//
private boolean warn_no_constructor = false;
public boolean warn_no_constructor()
{
return warn_no_constructor;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-no-constructor" })
public void setCompilerWarnNoConstructor(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_no_constructor)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-no-explicit-super-call-in-constructor' option
//
private boolean warn_no_explicit_super_call_in_constructor = false;
public boolean warn_no_explicit_super_call_in_constructor()
{
return warn_no_explicit_super_call_in_constructor;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-no-explicit-super-call-in-constructor" })
public void setCompilerWarnNoExplicitSuperCallInConstructor(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_no_explicit_super_call_in_constructor)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-no-type-decl' option
//
private boolean warn_no_type_decl = true;
public boolean warn_no_type_decl()
{
return warn_no_type_decl;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-no-type-decl" })
public void setCompilerWarnNoTypeDecl(ConfigurationValue cv, boolean b)
{
warn_no_type_decl = b;
}
//
// 'compiler.warn-number-from-string-changes' option
//
private boolean warn_number_from_string_changes = false;
public boolean warn_number_from_string_changes()
{
return warn_number_from_string_changes;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-number-from-string-changes" })
public void setCompilerWarnNumberFromStringChanges(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_number_from_string_changes)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-scoping-change-in-this' option
//
private boolean warn_scoping_change_in_this = false;
public boolean warn_scoping_change_in_this()
{
return warn_scoping_change_in_this;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-scoping-change-in-this" })
public void setCompilerWarnScopingChangeInThis(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_scoping_change_in_this)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-slow-text-field-addition' option
//
private boolean warn_slow_text_field_addition = true;
public boolean warn_slow_text_field_addition()
{
return warn_slow_text_field_addition;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-slow-text-field-addition" })
public void setCompilerWarnSlowTextFieldAddition(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_slow_text_field_addition)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-unlikely-function-value' option
//
private boolean warn_unlikely_function_value = true;
public boolean warn_unlikely_function_value()
{
return warn_unlikely_function_value;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-unlikely-function-value" })
public void setCompilerWarnUnlikelyFunctionValue(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_unlikely_function_value)
addRemovedConfigurationOptionProblem(cv);
}
//
// 'compiler.warn-xml-class-has-changed' option
//
private boolean warn_xml_class_has_changed = false;
public boolean warn_xml_class_has_changed()
{
return warn_xml_class_has_changed;
}
@Config(advanced = true)
@Mapping({ "compiler", "warn-xml-class-has-changed" })
public void setCompilerWarnXmlClassHasChanged(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != warn_xml_class_has_changed)
addRemovedConfigurationOptionProblem(cv);
}
//
// compiler.generate-abstract-syntax-tree
//
private boolean generateAbstractSyntaxTree = true;
@Config(hidden = true)
@Mapping({ "compiler", "generate-abstract-syntax-tree" })
public void setCompilerGenerateAbstractSyntaxTree(ConfigurationValue cv, boolean b)
{
generateAbstractSyntaxTree = b;
}
public boolean getCompilerGenerateAbstractSyntaxTree()
{
return generateAbstractSyntaxTree;
}
//
// 'compiler.isolateStyles' option
//
/**
* Allow the user to decide if the compiled application/module should have its own style manager. Turn off isolate
* styles for compatibility less than 4.0.
*/
private boolean isolateStyles = true;
public boolean getCompilerIsolateStyles()
{
return isolateStyles && (getCompilerCompatibilityVersion() >= MXML_VERSION_4_0);
}
@Config(advanced = true)
@Mapping({ "compiler", "isolate-styles" })
@FlexOnly
public void setCompilerIsolateStyles(ConfigurationValue cv, boolean isolateStyles)
{
this.isolateStyles = isolateStyles;
}
//
// 'compiler.compress' option (default is true)
//
private boolean useCompression = true;
@Config
@Mapping({ "compiler", "compress" })
public void setCompress(ConfigurationValue cv, boolean useCompression)
{
this.useCompression = useCompression;
}
/**
* Setting {@code -compiler.compress=false} will force compiler not to compress the output SWF.
*/
public boolean useCompression()
{
return this.useCompression;
}
// ATTENTION: Please set default values in DefaultsConfigurator.
private static final String LOCALE_TOKEN = "{locale}";
private static final String TARGET_PLAYER_MAJOR_VERSION_TOKEN = "{targetPlayerMajorVersion}";
private static final String TARGET_PLAYER_MINOR_VERSION_TOKEN = "{targetPlayerMinorVersion}";
private static final String TARGET_PLAYER_MAJOR_VERSION_TOKEN_REGEX_ESCAPED = Pattern.quote(
TARGET_PLAYER_MAJOR_VERSION_TOKEN);
private static final String TARGET_PLAYER_MINOR_VERSION_TOKEN_REGEX_ESCAPED = Pattern.quote(
TARGET_PLAYER_MINOR_VERSION_TOKEN);
// Special Case for Apache. These are not currently exposed with command line options.
public static final String PLAYERGLOBAL_HOME_TOKEN = "{playerglobalHome}";
public static final String AIR_HOME_TOKEN = "{airHome}";
public static final String FLEX_VERSION_TOKEN = "{flexVersion}";
public static final String STRICT = "compiler.strict";
public static final String AS3 = "compiler.as3";
public static final String ES = "compiler.es";
public ImmutableList<String> expandTokens(final Iterable<String> pathElements, final Iterable<String> locales,
final ConfigurationValue configurationValue)
{
return expandTokens(pathElements, locales, configurationValue, false);
}
/**
* All path-tokens get expanded from this method, as of now, {locale} and {targetPlayerMajorVersion} Replaces
* instances of "{targetPlayerMajorVersion}" and "{targetPlayerMinorVersion}" with configured value. Expands the
* {locale} token in a list of path elements for the source-path or library-path. The treatment of a path element
* containing "{locale}" depends on whether we are processing a source-path or a library-path, and on whether we are
* compiling for a single locale, multiple locales, or no locale:
*
* <pre>
* -source-path=foo,bar/{locale},baz -locale=en_US
* -> foo,bar/en_US,baz
*
* -source-path=foo,bar/{locale},baz -locale=en_US,ja_JP
* -> foo,bar/en_US,bar/ja_JP,baz
*
* -source-path=foo,bar/{locale},baz -locale=
* -> foo,baz
*
* -library-path=foo,bar/{locale},baz -locale=en_US
* -> foo,bar/en_US,baz
*
* -library-path=foo,bar/{locale},baz -locale=en_US,ja_JP
* -> foo,bar/en_US,bar/ja_JP,baz
*
* -library-path=foo,bar/{locale},baz -locale=
* -> foo,baz
* </pre>
*
* @param pathElements A list of unprocessed paths from configuration values.
* @param locales A set of locales.
* @param configurationValue Context.
* @param returnMissingFiles controls whether or not files that do not exist are included in the list of expanded
* files. Pass true to include files that do not exist, false otherwise.
* @return A list of normalized and resolved file paths.
* @throws CannotOpen
*/
protected ImmutableList<String> expandTokens(final Iterable<String> pathElements, final Iterable<String> locales,
final ConfigurationValue configurationValue, final boolean returnMissingFiles)
{
assert pathElements != null : "Expected path list.";
assert locales != null : "Expected locales.";
assert configurationValue != null : "Expected ConfigurationValue as a context.";
String targetPlayerMajorVersion = String.valueOf(getTargetPlayerMajorVersion());
String targetPlayerMinorVersion = String.valueOf(getTargetPlayerMinorVersion());
// Expand target player and locale tokens.
final ImmutableList.Builder<String> resolvedPaths = new ImmutableList.Builder<String>();
for (String pathElement : pathElements)
{
pathElement = expandRuntimeTokens(pathElement, configurationValue.getBuffer());
String flexVersion = getClass().getPackage().getImplementationVersion();
if (flexVersion != null)
{
pathElement = pathElement.replace(FLEX_VERSION_TOKEN, flexVersion);
}
String playerExpandedPath = pathElement.replaceAll(TARGET_PLAYER_MAJOR_VERSION_TOKEN_REGEX_ESCAPED,
targetPlayerMajorVersion).replaceAll(TARGET_PLAYER_MINOR_VERSION_TOKEN_REGEX_ESCAPED,
targetPlayerMinorVersion);
try
{
if (playerExpandedPath.contains(LOCALE_TOKEN))
{
for (final String locale : locales)
{
final String expandedPath = playerExpandedPath.replace(LOCALE_TOKEN, locale);
String resolvedPath = resolvePathStrict(expandedPath, configurationValue);
resolvedPaths.add(resolvedPath);
//Add this to the locale dependent sources map
localeDependentSources.put(resolvedPath, locale);
}
}
else
{
String resolvedPath = resolvePathStrict(playerExpandedPath, configurationValue, returnMissingFiles);
resolvedPaths.add(resolvedPath);
}
}
catch (CannotOpen e)
{
// Making an exception here and catching this fatal error.
// This is an exception because library paths come thru this
// code path and we don't want to throw all of the libraries
// out because one of the paths is bad. We want to load as
// many libraries as we can an report the ones we couldn't load.
configurationProblems.add(new ConfigurationProblem(e));
}
}
return resolvedPaths.build();
}
/**
* Replaces instances of {playerglobalHome} and {airHome}. Values can come from either ../env.properties (relative
* to jar file) or environment variables. The property file values have precedence. The pairs are
* env.PLAYERGLOBAL_HOME and PLAYERGLOBAL_HOME, and, env.AIR_HOME and AIR_HOME.
*/
private String expandRuntimeTokens(String pathElement, ConfigurationBuffer buffer)
{
// Look at property file first, if it exists, and see if the particular property
// is defined. If not found, then look for the environment variable.
// If there is neither leave the token in place since it is easier to
// diagnose the problem with a token in the error message path then it is with
// a "" in the path.
Properties envProperties = loadEnvPropertyFile();
String playerglobalHome = envProperties != null
? envProperties.getProperty("env.PLAYERGLOBAL_HOME", System.getenv("PLAYERGLOBAL_HOME"))
: System.getenv("PLAYERGLOBAL_HOME");
if (playerglobalHome == null)
playerglobalHome = buffer.getToken("env.PLAYERGLOBAL_HOME");
if (playerglobalHome == null)
playerglobalHome = PLAYERGLOBAL_HOME_TOKEN;
String airHome = envProperties != null ? envProperties.getProperty("env.AIR_HOME", System.getenv("AIR_HOME"))
: System.getenv("AIR_HOME");
if (airHome == null)
airHome = buffer.getToken("env.AIR_HOME");
if (airHome == null)
airHome = AIR_HOME_TOKEN;
pathElement = pathElement.replace(PLAYERGLOBAL_HOME_TOKEN, playerglobalHome);
pathElement = pathElement.replace(AIR_HOME_TOKEN, airHome);
return pathElement;
}
/**
* Load the env.properties file from the classpath.
*
* @return null if env.properties does not exist in classpath or could not be loaded
*/
private Properties loadEnvPropertyFile()
{
Properties properties = null;
InputStream in = null;
try
{
in = getClass().getClassLoader().getResourceAsStream("env.properties");
if (in == null)
{
try
{
File f = new File("../env.properties");
in = new FileInputStream(f);
properties = new Properties();
properties.load(in);
in.close();
return properties;
}
catch (FileNotFoundException e)
{
try
{
File f = new File("unittest.properties");
in = new FileInputStream(f);
properties = new Properties();
properties.load(in);
in.close();
properties.setProperty("env.PLAYERGLOBAL_HOME", properties.getProperty("PLAYERGLOBAL_HOME"));
properties.setProperty("env.AIR_HOME", properties.getProperty("AIR_HOME"));
properties.setProperty("env.PLAYERGLOBAL_VERSION", properties.getProperty("PLAYERGLOBAL_VERSION"));
return properties;
}
catch (FileNotFoundException e1)
{
return null;
}
catch (IOException e1)
{
return null;
}
}
catch (IOException e)
{
return null;
}
}
properties = new Properties();
properties.load(in);
in.close();
}
catch (Exception e)
{
}
return properties;
}
private Map<String, String> localeDependentSources = new HashMap<String, String>();
/**
* Returns a map that stores locale dependent files. For each item in this map, key is the path of the resource and
* value id the locale it belongs to.
*/
public Map<String, String> getLocaleDependentSources()
{
return localeDependentSources;
}
/**
*
* @param path A path to resolve.
* @param cv Configuration context.
* @return A single normalized resolved file. If the path could be expanded into more than one path, then use
* {@link resolvePathsStrict}
* @throws CannotOpen
*/
protected String resolvePathStrict(final String path, final ConfigurationValue cv) throws CannotOpen
{
return resolvePathStrict(path, cv, false);
}
/**
* Resolve a single path. This is a more strict version of {@link #resolvePaths()} in that it throws
* {@link CannotOpen} exception when a file path element can't be resolved.
*
* @param path A path to resolve.
* @param cv Configuration context.
* @param returnMissingFiles Determines if the CannotOpen exception is thrown if a file does not exist. Pass true to
* disable exceptions and return files that do not exist. Pass false to throw exceptions.
* @return A single normalized resolved file. If the path could be expanded into more than one path, then use
* {@link resolvePathsStrict}.
* @throws CannotOpen error
* @see #resolvePaths(ImmutableList, ConfigurationValue)
*/
private String resolvePathStrict(final String path, final ConfigurationValue cv, final boolean returnMissingFiles)
throws CannotOpen
{
ImmutableList<String> singletonPath = ImmutableList.of(path);
ImmutableList<String> results = resolvePathsStrict(singletonPath, cv, returnMissingFiles);
return results.get(0);
}
/**
* Resolve a list of paths. This is a more strict version of {@link #resolvePaths()} in that it throws
* {@link CannotOpen} exception when a file path element can't be resolved.
*
* @param paths A list of paths to resolve.
* @param cv Configuration context.
* @return A list of normalized resolved file paths.
* @throws CannotOpen error
* @see #resolvePaths(ImmutableList, ConfigurationValue)
*/
private ImmutableList<String> resolvePathsStrict(final ImmutableList<String> paths, final ConfigurationValue cv)
throws CannotOpen
{
return resolvePathsStrict(paths, cv, false);
}
/**
* Resolve a list of paths. This is a more strict version of {@link #resolvePaths()} in that it throws
* {@link CannotOpen} exception when a file path element can't be resolved.
*
* @param paths A list of paths to resolve.
* @param cv Configuration context.
* @param returnMissingFiles Determines if the CannotOpen exception is thrown if a file does not exist. Pass true to
* disable exceptions and return files that do not exist. Pass false to throw exceptions.
* @return A list of normalized resolved file paths.
* @throws CannotOpen error
* @see #resolvePaths(ImmutableList, ConfigurationValue)
*/
private ImmutableList<String> resolvePathsStrict(final ImmutableList<String> paths, final ConfigurationValue cv,
final boolean returnMissingFiles) throws CannotOpen
{
assert paths != null : "Expected paths";
assert cv != null : "Require ConfigurationValue as context.";
final ImmutableList.Builder<String> resolvedPathsBuilder = new ImmutableList.Builder<String>();
for (String processedPath : paths)
{
if (cv.getContext() != null)
{
boolean isAbsolute = new File(processedPath).isAbsolute();
if (!isAbsolute)
processedPath = new File(cv.getContext(), processedPath).getAbsolutePath();
}
if (processedPath.contains("*"))
{
// if contains wild card, just prove the part before the wild card is valid
int c = processedPath.lastIndexOf(File.separator, processedPath.indexOf("*"));
if (c != -1)
processedPath = processedPath.substring(0, c);
}
if (!processedPath.contains(".swc:"))
{
final File fileSpec = pathResolver.resolve(processedPath);
if (!returnMissingFiles && !fileSpec.exists())
{
throw new CannotOpen(FilenameNormalization.normalize(processedPath), cv.getVar(), cv.getSource(),
cv.getLine());
}
resolvedPathsBuilder.add(fileSpec.getAbsolutePath());
}
else
resolvedPathsBuilder.add(processedPath);
}
return resolvedPathsBuilder.build();
}
//////////////////////////////////////////////////////////////////////////
// compiler.extensions.*
//////////////////////////////////////////////////////////////////////////
//
// 'compiler.extensions.extension' option
//
/**
* Configures a list of many extensions mapped to a single Extension URI.
* <extension> <extension>something-extension.jar</extension>
* <parameters>version=1.1,content=1.2</parameters> </extension>
*
* @param cv The configuration value context.
* @param pathlist A List of values for the Extension element, with the first item expected to be the uri and the
* remaining are extension paths.
* @throws CannotOpen When no arg is provided or when the jar does not exist.
*/
@Config(allowMultiple = true, removed = true)
@Mapping({ "compiler", "extensions", "extension" })
@Arguments({ "extension", "parameters" })
@InfiniteArguments
public void setExtension(ConfigurationValue cv, String[] pathlist) throws CannotOpen
{
}
//////////////////////////////////////////////////////////////////////////
// compiler.fonts.*
//////////////////////////////////////////////////////////////////////////
@Config
@Mapping({ "compiler", "fonts", "advanced-anti-aliasing" })
@FlexOnly
public void setCompilerFontsAdvancedAntiAliasing(ConfigurationValue cv, boolean val)
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
@Config(allowMultiple = true, advanced = true)
@Mapping({ "compiler", "fonts", "languages", "language-range" })
@Arguments({ "lang", "range" })
@FlexOnly
public void setCompilerFontsLanguagesLanguageRange(ConfigurationValue cv, String lang, String range)
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
@Config
@Mapping({ "compiler", "fonts", "local-fonts-snapshot" })
@FlexOnly
public void setCompilerFontsLocalFontsSnapshot(ConfigurationValue cv, String localFontsSnapshotPath)
throws CannotOpen
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
@Config
@Mapping({ "compiler", "fonts", "local-font-paths" })
@Arguments(Arguments.PATH_ELEMENT)
@InfiniteArguments
@FlexOnly
public void setCompilerFontsLocalFontPaths(ConfigurationValue cv, List<String> list) throws CannotOpen
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
@Config(advanced = true)
@Mapping({ "compiler", "fonts", "managers" })
@Arguments("manager-class")
@InfiniteArguments
@FlexOnly
public void setCompilerFontsManagers(ConfigurationValue cv, List<String> list)
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
@Config
@Mapping({ "compiler", "fonts", "max-cached-fonts" })
@FlexOnly
public void setCompilerFontsMaxCachedFonts(ConfigurationValue cv, String val)
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
@Config
@Mapping({ "compiler", "fonts", "max-glyphs-per-face" })
@FlexOnly
public void setCompilerFontsMaxGlyphsPerFace(ConfigurationValue cv, String val)
{
// intentionally do nothing here as feature removed, but don't annotate as removed
// as to not generate warnings for flex-config's which still set this options
}
//////////////////////////////////////////////////////////////////////////
// compiler.namespaces
//////////////////////////////////////////////////////////////////////////
private List<MXMLNamespaceMapping> manifestMappings;
public List<MXMLNamespaceMapping> getCompilerNamespacesManifestMappings()
{
return manifestMappings;
}
/**
* 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", "namespaces", "namespace" })
@Arguments({ "uri", "manifest" })
@InfiniteArguments
@FlexOnly
public void setCompilerNamespacesNamespace(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 (manifestMappings == null)
manifestMappings = 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);
manifestMappings.add(new MXMLNamespaceMapping(uri, path));
}
}
///////////////////////////////////////////////////////////////////////////
// metadata.*
///////////////////////////////////////////////////////////////////////////
//
// 'metadata.contributor' option
//
private final Set<String> contributors = new TreeSet<String>();
@Config(allowMultiple = true)
@Mapping({ "metadata", "contributor" })
@Arguments("name")
public void setMetadataContributor(ConfigurationValue cv, String name)
{
contributors.add(name);
}
//
// 'metadata.creator' option
//
private final Set<String> creators = new TreeSet<String>();
@Config(allowMultiple = true)
@Mapping({ "metadata", "creator" })
@Arguments("name")
public void setMetadataCreator(ConfigurationValue cv, String name)
{
creators.add(name);
}
//
// 'metadata.date' option
//
public String date = null;
@Config
@Mapping({ "metadata", "date" })
@Arguments("text")
public void setMetadataDate(ConfigurationValue cv, String text)
{
date = text;
}
//
// 'metadata.description' option
//
private final Map<String, String> localizedDescriptions = new LinkedHashMap<String, String>();
@Config
@Mapping({ "metadata", "description" })
@Arguments("text")
public void setMetadataDescription(ConfigurationValue cv, String text)
{
localizedDescriptions.put("x-default", text);
}
//
// 'metadata.language' option
//
public final Set<String> langs = new TreeSet<String>();
@Config(allowMultiple = true)
@Mapping({ "metadata", "language" })
@Arguments("code")
public void setMetadataLanguage(ConfigurationValue cv, String code)
{
langs.add(code);
}
//
// 'metadata.localized-description' option
//
@Config(allowMultiple = true)
@Mapping({ "metadata", "localized-description" })
@Arguments({ "text", "lang" })
public void setMetadataLocalizedDescription(ConfigurationValue cv, String text, String lang)
{
localizedDescriptions.put(lang, text);
}
//
// 'metadata.localized-title' option
//
@Config(allowMultiple = true)
@Mapping({ "metadata", "localized-title" })
@Arguments({ "title", "lang" })
public void setMetadataLocalizedTitle(ConfigurationValue cv, String title, String lang)
{
localizedTitles.put(lang, title);
}
//
// 'metadata.publisher' option
//
private final Set<String> publishers = new TreeSet<String>();
@Config(allowMultiple = true)
@Mapping({ "metadata", "publisher" })
@Arguments("name")
public void setMetadataPublisher(ConfigurationValue cv, String name)
{
publishers.add(name);
}
//
// 'metadata.title' option
//
private final Map<String, String> localizedTitles = new LinkedHashMap<String, String>();
@Config
@Mapping({ "metadata", "title" })
@Arguments("text")
public void setMetadataTitle(ConfigurationValue cv, String title)
{
localizedTitles.put("x-default", title);
}
//////////////////////////////////////////////////////////////////////////
// runtime-shared-library-settings
//////////////////////////////////////////////////////////////////////////
//
// 'force-rsl' option
//
private Set<String> forceRsls;
/**
* Get the array of SWCs that should have their RSLs loaded, even if the compiler detects no classes being used from
* the SWC.
*
* @return Array of SWCs that should have their RSLs loaded.
*/
public Set<String> getForceRsls()
{
if (forceRsls == null)
{
return Collections.emptySet();
}
return forceRsls;
}
@Config(advanced = true, allowMultiple = true)
@Mapping({ "runtime-shared-library-settings", "force-rsls" })
@SoftPrerequisites({ "runtime-shared-library-path" })
@Arguments(Arguments.PATH_ELEMENT)
@InfiniteArguments
@FlexOnly
public void setForceRsls(ConfigurationValue cfgval, String[] args) throws ConfigurationException
{
if (forceRsls == null)
{
forceRsls = new HashSet<String>();
}
// Add swc to the forceRsls set.
for (String arg : args)
{
// path-element parameter (swc)
// verify path exists and the swc has an
// existing -rslp option specified.
String swcPath = resolvePathStrict(arg, cfgval);
// verify the swc is used in an the RSL configuration.
if (!doesSwcHaveRSLInfo(swcPath))
{
throw new ConfigurationException.SwcDoesNotHaveRslData(swcPath, cfgval.getVar(), cfgval.getSource(),
cfgval.getLine());
}
forceRsls.add(swcPath);
}
}
//
// 'application-domain' option
//
/*
* Key: swc file path; Value: application domain target
*/
private HashMap<String, ApplicationDomainTarget> applicationDomains;
/**
* Get the application domain an RSL should be loaded into. The default is the current application domain but the
* user can override this setting.
*
* @param swcPath The full path of the swc file.
*
* @return The application domain the RSL should be loaded into. If the swc is not found, then 'default' is
* returned.
*/
public ApplicationDomainTarget getApplicationDomain(String swcPath)
{
if (applicationDomains == null || swcPath == null)
{
return ApplicationDomainTarget.DEFAULT;
}
for (Map.Entry<String, ApplicationDomainTarget> entry : applicationDomains.entrySet())
{
if (entry.getKey().equals(swcPath))
{
return entry.getValue();
}
}
return ApplicationDomainTarget.DEFAULT;
}
@Config(advanced = true, allowMultiple = true)
@SoftPrerequisites({ "runtime-shared-library-path" })
@Mapping({ "runtime-shared-library-settings", "application-domain" })
@Arguments({ "path-element", "application-domain-target" })
@InfiniteArguments
@FlexOnly
// TODO: need to create an argument name generator for the args.
public void setApplicationDomain(ConfigurationValue cfgval, String[] args) throws ConfigurationException
{
// ignore the force option if we are static linking
if (getStaticLinkRsl())
return;
if (applicationDomains == null)
{
applicationDomains = new HashMap<String, ApplicationDomainTarget>();
}
// Add swc and application domain target to the map.
// The args are: swc file path, application domain type, ...
for (int i = 0; i < args.length; i++)
{
String arg = args[i++];
// path-element parameter (swc)
// verify path exists and the swc has an
// existing -rslp option specified.
String swcPath = resolvePathStrict(arg, cfgval);
// verify the swc is used in an the RSL configuration.
if (!doesSwcHaveRSLInfo(swcPath))
{
throw new ConfigurationException.SwcDoesNotHaveRslData(swcPath, cfgval.getVar(), cfgval.getSource(),
cfgval.getLine());
}
// Verify the application domain target is valid.
arg = args[i];
ApplicationDomainTarget adTarget = getApplicationDomainTarget(arg);
if (adTarget == null)
{
// throw a configuration exception that the application domain
// type is incorrect.
throw new ConfigurationException.BadApplicationDomainValue(swcPath, arg, cfgval.getVar(),
cfgval.getSource(), cfgval.getLine());
}
applicationDomains.put(swcPath, adTarget);
}
}
/**
* Test if the specified parameter is a valid application domain type. If it is then return the corresponding enum.
*
* @param arg String value representing an ApplicationDomainTarget.
* @return An ApplicationDomainTarget enum if the parameter is a valid application domain target, null otherwise.
*/
private ApplicationDomainTarget getApplicationDomainTarget(String arg)
{
for (ApplicationDomainTarget appDomain : ApplicationDomainTarget.values())
{
if (appDomain.getApplicationDomainValue().equals(arg))
return appDomain;
}
return null;
}
/**
* Check if the SWC has any RSL info associated with it.
*
* @param swcPath
* @return true if the swc has RSL info, false otherwise.
*/
private boolean doesSwcHaveRSLInfo(String swcPath)
{
if (swcPath == null)
return false;
List<RuntimeSharedLibraryPathInfo> rslInfoList = getRslPathInfo();
for (RuntimeSharedLibraryPathInfo rslInfo : rslInfoList)
{
if (swcPath.equals(rslInfo.getSWCFile().getPath()))
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
// compiler.mxml
//////////////////////////////////////////////////////////////////////////
//
// 'compiler.mxml.compatibility-version' option
//
public static final int MXML_VERSION_4_7 = 0x04070000;
public static final int MXML_VERSION_4_6 = 0x04060000;
public static final int MXML_VERSION_4_5 = 0x04050000;
public static final int MXML_VERSION_4_0 = 0x04000000;
public static final int MXML_VERSION_3_0 = 0x03000000;
public static final int MXML_VERSION_2_0_1 = 0x02000001;
public static final int MXML_VERSION_2_0 = 0x02000000;
public static final int MXML_CURRENT_VERSION = MXML_VERSION_4_7;
public static final int MXML_EARLIEST_MAJOR_VERSION = 3;
public static final int MXML_LATEST_MAJOR_VERSION = 4;
public static final int MXML_LATEST_MINOR_VERSION = 7;
private int mxml_major = MXML_LATEST_MAJOR_VERSION;
private int mxml_minor = MXML_LATEST_MINOR_VERSION;
private int mxml_revision;
private int mxmlMinMajor = MXML_EARLIEST_MAJOR_VERSION;
private int mxmlMinMinor;
private int mxmlMinRevision;
public int getCompilerMxmlMajorCompatibilityVersion()
{
return mxml_major;
}
public int getCompilerMxmlMinorCompatibilityVersion()
{
return mxml_minor;
}
public int getCompilerMxmlRevisionCompatibilityVersion()
{
return mxml_revision;
}
/*
* Unlike the framework's FlexVersion.compatibilityVersionString, this
* returns null rather than a string like "3.0.0" for the current version.
* But if a -compatibility-version was specified, this string will always be
* of the form N.N.N. For example, if -compatibility-version=2, this string
* is "2.0.0", not "2".
*/
public String getCompilerMxmlCompatibilityVersionString()
{
return (mxml_major == 0 && mxml_minor == 0 && mxml_revision == 0) ? null
: mxml_major + "." + mxml_minor + "." + mxml_revision;
}
/*
* This returns an int that can be compared with version constants such as
* MxmlConfiguration.VERSION_3_0.
*/
public int getCompilerMxmlCompatibilityVersion()
{
int version = (mxml_major << 24) + (mxml_minor << 16) + mxml_revision;
return version != 0 ? version : MXML_CURRENT_VERSION;
}
@Config
@Mapping({ "compiler", "mxml", "compatibility-version" })
@Arguments("version")
@FlexOnly
public void setCompilerMxmlCompatibilityVersion(ConfigurationValue cv, String version) throws ConfigurationException
{
if (version == null)
{
return;
}
String[] results = version.split("\\.");
if (results.length == 0)
{
throw new ConfigurationException.BadVersion(version, "compatibility-version");
}
// Set minor and revision numbers to zero in case only a major number
// was specified.
this.mxml_minor = 0;
this.mxml_revision = 0;
for (int i = 0; i < results.length; i++)
{
int versionNum = 0;
try
{
versionNum = Integer.parseInt(results[i]);
}
catch (NumberFormatException e)
{
throw new ConfigurationException.BadVersion(version, "compatibility-version");
}
if (i == 0)
{
if (versionNum >= MXML_EARLIEST_MAJOR_VERSION && versionNum <= MXML_LATEST_MAJOR_VERSION)
{
this.mxml_major = versionNum;
}
else
{
throw new ConfigurationException.BadVersion(version, "compatibility-version");
}
}
else
{
if (versionNum >= 0)
{
if (i == 1)
{
this.mxml_minor = versionNum;
}
else
{
this.mxml_revision = versionNum;
}
}
else
{
throw new ConfigurationException.BadVersion(version, "compatibility-version");
}
}
}
}
/*
* Minimum supported SDK version for this library. This string will always
* be of the form N.N.N. For example, if -minimum-supported-version=2, this
* string is "2.0.0", not "2".
*/
public String getCompilerMxmlMinimumSupportedVersionString()
{
return (mxmlMinMajor == 0 && mxmlMinMinor == 0 && mxmlMinRevision == 0) ? null
: mxmlMinMajor + "." + mxmlMinMinor + "." + mxmlMinRevision;
}
/*
* This returns an int that can be compared with version constants such as
* MxmlConfiguration.VERSION_3_0.
*/
public int getCompilerMxmlMinimumSupportedVersion()
{
int version = (mxmlMinMajor << 24) + (mxmlMinMinor << 16) + mxmlMinRevision;
return version != 0 ? version : (MXML_EARLIEST_MAJOR_VERSION << 24);
}
public void setCompilerMxmlMinimumSupportedVersion(int version)
{
mxmlMinMajor = version >> 24 & 0xFF;
mxmlMinMinor = version >> 16 & 0xFF;
mxmlMinRevision = version & 0xFF;
}
@Config
@Mapping({ "compiler", "mxml", "minimum-supported-version" })
@FlexOnly
public void setCompilerMxmlMinimumSupportedVersion(ConfigurationValue cv, String version)
throws ConfigurationException
{
if (version == null)
{
return;
}
String[] results = version.split("\\.");
if (results.length == 0)
{
throw new ConfigurationException.BadVersion(version, "minimum-supported-version");
}
for (int i = 0; i < results.length; i++)
{
int versionNum = 0;
try
{
versionNum = Integer.parseInt(results[i]);
}
catch (NumberFormatException e)
{
throw new ConfigurationException.BadVersion(version, "minimum-supported-version");
}
if (i == 0)
{
if (versionNum >= MXML_EARLIEST_MAJOR_VERSION && versionNum <= MXML_LATEST_MAJOR_VERSION)
{
this.mxmlMinMajor = versionNum;
}
else
{
throw new ConfigurationException.BadVersion(version, "minimum-supported-version");
}
}
else
{
if (versionNum >= 0)
{
if (i == 1)
{
mxmlMinMinor = versionNum;
}
else
{
mxmlMinRevision = versionNum;
}
}
else
{
throw new ConfigurationException.BadVersion(version, "minimum-supported-version");
}
}
}
isMinimumSupportedVersionConfigured = true;
}
private boolean isMinimumSupportedVersionConfigured = false;
public boolean isCompilerMxmlMinimumSupportedVersionConfigured()
{
return isMinimumSupportedVersionConfigured;
}
//
// 'compiler.mobile' option
//
private boolean mobile = false;
/**
* @return determines whether the target runtime is a mobile device. This may alter the features available, such as
* certain blend-modes when compiling FXG.
*/
public boolean getMobile()
{
return mobile;
}
@Config()
@Mapping({ "compiler", "mobile" })
public void setMobile(ConfigurationValue cv, boolean b)
{
mobile = b;
}
////////////////////////////////////////////////////////////////////////////
// licenses.*
////////////////////////////////////////////////////////////////////////////
//
// 'license' option
//
@Config(allowMultiple = true, displayed = false, removed = true)
@Mapping({ "licenses", "license" })
@Arguments({ "product", "serial-number" })
public void setLicensesLicense(ConfigurationValue cfgval, String product, String serialNumber)
throws ConfigurationException
{
}
////////////////////////////////////////////////////////////////////////////
// frames.*
////////////////////////////////////////////////////////////////////////////
private List<FrameInfo> frameList = new LinkedList<FrameInfo>();
public List<FrameInfo> getFrameList()
{
return frameList;
}
@Config(advanced = true, allowMultiple = true)
@Mapping({ "frames", "frame" })
@Arguments({ "label", "classname" })
@InfiniteArguments
public void setFramesFrame(ConfigurationValue cv, List<String> args) throws ConfigurationException
{
// "args" are [label, qname, qname, qname, ...]
final FrameInfo info = new FrameInfo();
if (args.size() < 2)
throw new ConfigurationException.BadFrameParameters(cv.getVar(), cv.getSource(), cv.getLine());
for (final String next : args)
{
if (info.getLabel() == null)
{
info.setLabel(next);
}
else
{
info.getFrameClasses().add(next);
}
}
frameList.add(info);
}
//
// -as3
//
private boolean as3 = true;
@Config(advanced = true)
@Mapping({ "compiler", "as3" })
@DeprecatedConfig
public void setAS3(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != as3)
addRemovedConfigurationOptionProblem(cv);
}
//
// -es
//
private boolean es = false;
@Config(advanced = true)
@Mapping({ "compiler", "es" })
@DeprecatedConfig
public void setES(ConfigurationValue cv, boolean b)
{
// This option is set in flex-config.xml so only warn
// if the user sets a non-default value.
if (b != es)
addRemovedConfigurationOptionProblem(cv);
}
////////////////////////////////////////////////////////////////////////////
// Compc Options
////////////////////////////////////////////////////////////////////////////
//
// compute-digest=true|false
//
/**
* Writes a digest to the catalog.xml of a library. Use this when the library will be used as a cross-domain RSL or
* when you want to enforce the versioning of RSLs. The default value is true.
*/
@Config(compcOnly = true, removed = true)
@Mapping("compute-digest")
public void setComputeDigest(ConfigurationValue cv, boolean value)
{
}
/**
* directory=false|true
*/
private boolean outputSwcAsDirectory = false;
/**
* Outputs the SWC file in an open directory format rather than a SWC file. You use this option with the output
* option to specify a destination directory, as the following example shows:
*
* <pre>
* compc -directory=true -output=destination_directory
* </pre>
*/
@Config(compcOnly = true)
@Mapping("directory")
public void setOutputSwcAsDirectory(ConfigurationValue cv, boolean value)
{
outputSwcAsDirectory = value;
}
/**
* @return True if the compiler will build the SWC file in an open directory format rather than a SWC file.
*/
public boolean getOutputSwcAsDirectory()
{
return outputSwcAsDirectory;
}
/**
* include-classes class [...]
*/
private final List<String> includeClasses = new ArrayList<String>();
/**
* Specifies classes to include in the SWC file. You provide the class name (for example, MyClass) rather than the
* file name (for example, MyClass.as) to the file for this option. As a result, all classes specified with this
* option must be in the compiler's source path. You specify this by using the source-path compiler option.
* <p>
* You can use packaged and unpackaged classes. To use components in namespaces, use the include-namespaces option.
* <p>
* If the components are in packages, ensure that you use dot-notation rather than slashes to separate package
* levels.
* <p>
* This is the default option for the component compiler.
*/
@Config(compcOnly = true, allowMultiple = true)
@Arguments(Arguments.CLASS)
@Mapping("include-classes")
public void setIncludeClasses(ConfigurationValue cv, List<String> values)
{
includeClasses.addAll(values);
}
/**
* @return A list of class names to be included in the target.
*/
public List<String> getIncludeClasses()
{
return includeClasses;
}
/**
* include-file name path [...]
*/
public final Map<String, String> includeFilesNamePath = new LinkedHashMap<String, String>();
/**
* Adds the file to the SWC file. This option does not embed files inside the library.swf file. This is useful for
* adding graphics files, where you want to add non-compiled files that can be referenced in a style sheet or
* embedded as assets in MXML files.
* <p>
* If you add a stylesheet that references compiled resources such as programmatic skins, use the include-stylesheet
* option.
* <p>
* If you use the [Embed] syntax to add a resource to your application, you are not required to use this option to
* also link it into the SWC file.
*/
@Config(compcOnly = true, allowMultiple = true)
@Mapping("include-file")
@Arguments({ "name", "path" })
public void setIncludeFiles(ConfigurationValue cv, List<String> values)
throws IncorrectArgumentCount, CannotOpen, RedundantFile
{
// Expect name-path pairs in the arguments.
final int size = values.size();
if (size % 2 != 0)
throw new IncorrectArgumentCount(size + 1, size, cv.getVar(), cv.getSource(), cv.getLine());
for (int nameIndex = 0; nameIndex < size - 1; nameIndex += 2)
{
final String name = values.get(nameIndex);
final String path = resolvePathStrict(values.get(nameIndex + 1), cv);
if (includeFilesNamePath.containsKey(name))
{
throw new ConfigurationException.RedundantFile(name, cv.getVar(), cv.getSource(), cv.getLine());
}
includeFilesNamePath.put(name, path);
}
}
/**
* @return A map of included files. The keys are file entry names; The values are file paths.
*/
public Map<String, String> getIncludeFiles()
{
return includeFilesNamePath;
}
/**
* include-lookup-only=false|true
*/
private boolean includeLookupOnly = false;
/**
* If true, only manifest entries with lookupOnly=true are included in the SWC catalog.
*/
@Config(compcOnly = true, advanced = true)
@Mapping("include-lookup-only")
@FlexOnly
public void setIncludeLookupOnly(ConfigurationValue cv, boolean value)
{
includeLookupOnly = value;
}
/**
* @return If true, only manifest entries with lookupOnly=true are included in the SWC catalog.
*/
public boolean getIncludeLookupOnly()
{
return includeLookupOnly;
}
/**
* include-namespaces uri [...]
*/
private final List<String> includeNamespaces = new ArrayList<String>();
/**
* Specifies namespace-style components in the SWC file. You specify a list of URIs to include in the SWC file. The
* uri argument must already be defined with the namespace option.
* <p>
* To use components in packages, use the include-classes option.
*/
@Config(compcOnly = true, allowMultiple = true)
@Mapping("include-namespaces")
@Arguments({ "uri" })
@FlexOnly
public void setIncludeNamespaces(ConfigurationValue cv, List<String> values)
{
includeNamespaces.addAll(values);
}
/**
* @return A list of URIs to include in the SWC file.
*/
public List<String> getIncludeNamespaces()
{
return includeNamespaces;
}
/**
* include-sources path-element
*/
private final List<String> includeSources = new ArrayList<String>();
/**
* Specifies classes or directories to add to the SWC file. When specifying classes, you specify the path to the
* class file (for example, MyClass.as) rather than the class name itself (for example, MyClass). This lets you add
* classes to the SWC file that are not in the source path. In general, though, use the include-classes option,
* which lets you add classes that are in the source path.
* <p>
* If you specify a directory, this option includes all files with an MXML or AS extension, and ignores all other
* files.
* <p>
* If you use this option to include MXML components that are in a non-default package, you must include the source
* folder in the source path.
*/
@Config(compcOnly = true, allowMultiple = true)
@Mapping("include-sources")
@Arguments(Arguments.PATH_ELEMENT)
public void setIncludeSources(ConfigurationValue cv, List<String> values) throws NotAFile
{
fillListWithResolvedPaths(values, includeSources, cv);
}
/**
* @return Normalized file paths of the included source files.
*/
public List<String> getIncludeSources()
{
return includeSources;
}
/**
* Add resolved file paths from {@code source} list to {@code target} list.
*
* @param source Source list with un-resolved file paths.
* @param target Target list.
* @param cv Context.
* @throws CannotOpen
*/
private void fillListWithResolvedPaths(final List<String> source, final List<String> target,
final ConfigurationValue cv) throws NotAFile
{
for (final String path : source)
{
String resolvedPath;
try
{
resolvedPath = resolvePathStrict(path, cv);
target.add(resolvedPath);
}
catch (CannotOpen e)
{
throw new ConfigurationException.NotAFile(path, cv.getVar(), cv.getSource(), cv.getLine());
}
}
}
/**
* include-stylesheet namepath [...]
*/
private final List<String> includeStyleSheets = new ArrayList<String>();
/**
* Specifies stylesheets to add to the SWC file. This option compiles classes that are referenced by the stylesheet
* before including the stylesheet in the SWC file.
* <p>
* You do not need to use this option for all stylesheets; only stylesheets that reference assets that need to be
* compiled such as programmatic skins or other class files. If your stylesheet does not reference compiled assets,
* you can use the include-file option.
* <p>
* This option does not compile the stylesheet into a SWF file before including it in the SWC file. You compile a
* CSS file into a SWF file when you want to load it at run time.
*/
@Config(compcOnly = true, allowMultiple = true)
@Mapping("include-stylesheet")
@Arguments({ "name", "path" })
@FlexOnly
public void setIncludeStyleSheets(ConfigurationValue cv, List<String> values) throws NotAFile
{
fillListWithResolvedPaths(values, includeStyleSheets, cv);
}
/**
* @return A list of the normalized file path of stylesheets to add to the SWC file.
*/
public List<String> getIncludeStyleSheets()
{
return includeStyleSheets;
}
private File dependencyGraphOutput;
/**
* Specifies a file name that a graphml version of the dependency graph should be written to.
*
*/
@Config(advanced = true)
@Mapping("dependency-graph")
@Arguments("filename")
public void setDependencyGraphOutput(ConfigurationValue cv, String fileName)
{
dependencyGraphOutput = new File(getOutputPath(cv, fileName));
}
/**
* Gets the location the graphml version of the dependency graph should be written to, null if no dependecy graph
* should be written.
*
* @return The location the dependency graph should be written to.
*/
public File getDependencyGraphOutput()
{
return dependencyGraphOutput;
}
//
// 'output' option
//
private String output;
public String getOutput()
{
return output;
}
@Config
@Arguments("filename")
public void setOutput(ConfigurationValue val, String output) throws ConfigurationException
{
this.output = getOutputPath(val, output);
}
//
// 'dump-config-file' option from ToolsConfiguration
//
private String dumpConfigFile = null;
/**
* @return filename of the configuration dump
*/
public String getDumpConfig()
{
return dumpConfigFile;
}
@Config(advanced = true, displayed = false)
@Arguments("filename")
@Mapping("dump-config")
public void setDumpConfig(ConfigurationValue cv, String filename)
{
dumpConfigFile = getOutputPath(cv, filename);
}
//
// 'warnings' option from ToolsConfiguration
//
private boolean warnings = true;
public boolean getWarnings()
{
return warnings;
}
@Config
@Mapping("warnings")
public void setWarnings(ConfigurationValue cv, boolean b)
{
warnings = b;
}
//
// 'error-problems'
//
private Collection<Class<ICompilerProblem>> errorClasses;
/**
* Get the collection of user specified problem classes that should be treated as errors.
*
* @return list of problem classes that should be treated as errors.
*/
public Collection<Class<ICompilerProblem>> getErrorProblems()
{
return errorClasses != null ? errorClasses : Collections.<Class<ICompilerProblem>> emptyList();
}
@Config(allowMultiple = true)
@Arguments(Arguments.CLASS)
@InfiniteArguments
public void setErrorProblems(ConfigurationValue cv, List<String> classNames) throws ConfigurationException
{
if (errorClasses == null)
errorClasses = new HashSet<Class<ICompilerProblem>>();
// Convert string to a class and save.
for (String className : classNames)
{
Class<ICompilerProblem> resolvedClass = resolveProblemClassName(className);
if (resolvedClass == null)
{
throw new ConfigurationException.CompilerProblemClassNotFound(className, cv.getVar(), cv.getSource(),
cv.getLine());
}
errorClasses.add(resolvedClass);
}
}
//
// 'warning-problems'
//
private Collection<Class<ICompilerProblem>> warningClasses;
/**
* Get the collection of user specified problem classes that should be treated as warnings.
*
* @return list of problem classes that should be treated as warnings.
*/
public Collection<Class<ICompilerProblem>> getWarningProblems()
{
return warningClasses != null ? warningClasses : Collections.<Class<ICompilerProblem>> emptyList();
}
@Config(allowMultiple = true)
@Arguments(Arguments.CLASS)
@InfiniteArguments
public void setWarningProblems(ConfigurationValue cv, List<String> classNames) throws ConfigurationException
{
if (warningClasses == null)
warningClasses = new HashSet<Class<ICompilerProblem>>();
// Convert string to a class and save.
for (String className : classNames)
{
Class<ICompilerProblem> resolvedClass = resolveProblemClassName(className);
if (resolvedClass == null)
{
throw new ConfigurationException.CompilerProblemClassNotFound(className, cv.getVar(), cv.getSource(),
cv.getLine());
}
warningClasses.add(resolvedClass);
}
}
//
// 'ignore-problems'
//
private Collection<Class<ICompilerProblem>> ignoreClasses;
/**
* Get the collection of user specified problem classes that should be ignored.
*
* @return list of problem classes that should be ignored.
*/
public Collection<Class<ICompilerProblem>> getIgnoreProblems()
{
return ignoreClasses != null ? ignoreClasses : Collections.<Class<ICompilerProblem>> emptyList();
}
@Config(allowMultiple = true)
@Arguments(Arguments.CLASS)
@InfiniteArguments
public void setIgnoreProblems(ConfigurationValue cv, List<String> classNames) throws ConfigurationException
{
if (ignoreClasses == null)
ignoreClasses = new HashSet<Class<ICompilerProblem>>();
// Convert string to a class and save.
for (String className : classNames)
{
Class<ICompilerProblem> resolvedClass = resolveProblemClassName(className);
if (resolvedClass == null)
{
throw new ConfigurationException.CompilerProblemClassNotFound(className, cv.getVar(), cv.getSource(),
cv.getLine());
}
ignoreClasses.add(resolvedClass);
}
}
//
// 'legacy-message-format'
//
private boolean legacyMessageFormat = true;
public boolean useLegacyMessageFormat()
{
return legacyMessageFormat;
}
@Config(hidden = true)
public void setLegacyMessageFormat(ConfigurationValue cv, boolean value) throws ConfigurationException
{
legacyMessageFormat = value;
}
//
// 'create-target-with-errors'
//
private boolean createTargetWithErrors = false;
public boolean getCreateTargetWithErrors()
{
return createTargetWithErrors;
}
@Config(hidden = true)
public void setCreateTargetWithErrors(ConfigurationValue cv, boolean value) throws ConfigurationException
{
createTargetWithErrors = value;
}
//
// 'flex'
//
private boolean isFlex = false;
public boolean isFlex()
{
return isFlex;
}
/**
* Option to enable or prevent various Flex compiler behaviors. This is currently used to enable/disable the
* generation of a root class for library swfs and generation of Flex specific code for application swfs.
*/
@Config(hidden = true)
public void setFlex(ConfigurationValue cv, boolean value) throws ConfigurationException
{
isFlex = value;
}
private boolean isExcludeNativeJSLibraries = false;
public boolean isExcludeNativeJSLibraries()
{
return isExcludeNativeJSLibraries;
}
/**
* Option to remove the Native JS libraries from external-library-path and library-path as they shouldn't be any
* when compiling SWFs / SWCs.
*/
@Config()
@Mapping("exclude-native-js-libraries")
public void setExcludeNativeJSLibraries(ConfigurationValue cv, boolean value) throws ConfigurationException
{
isExcludeNativeJSLibraries = value;
}
/**
* Resolve a problem class name to a Java Class.
*
* @param className May be fully qualified. If the class name is not fully qualified, it is assumed to live in the
* "org.apache.flex.compiler.problems" package.
*
* @return A class corresponding to the className or null if the class name was not found.
*/
@SuppressWarnings("unchecked")
private Class<ICompilerProblem> resolveProblemClassName(String className)
{
if (className == null)
return null;
Class<?> resolvedClass = null;
try
{
resolvedClass = Class.forName(className);
}
catch (ClassNotFoundException e)
{
return null;
}
if (ICompilerProblem.class.isAssignableFrom(resolvedClass))
return (Class<ICompilerProblem>) resolvedClass;
else
return null;
}
//
// 'file-specs' option
//
private List<String> fileSpecs = new ArrayList<String>();
/**
* Get target file path. Target file is the last file in the {@link #getFileSpecs()}.
* FIXME: Calling this target file is a bit misleading as it's sort of the "main" source file
*/
public String getTargetFile()
{
if (fileSpecs.isEmpty())
return null;
else
return Iterables.getLast(fileSpecs);
}
/**
* @return Path of the target's parent directory.
*/
public String getTargetFileDirectory()
{
final String targetFile = getTargetFile();
if (targetFile == null)
return null;
final String normalizedTargetFile = FilenameNormalization.normalize(targetFile);
return FilenameUtils.getFullPathNoEndSeparator(normalizedTargetFile);
}
/**
* This has been added so that unit tests can change the target file. It isn't normally called when running the
* command line compiler.
*/
public void setTargetFile(String mainFile)
{
fileSpecs.clear();
fileSpecs.add(mainFile);
}
/**
* @return A list of filespecs. It's the default variable for command line.
*/
public List<String> getFileSpecs()
{
return fileSpecs;
}
@Config(allowMultiple = true, hidden = true)
@Arguments(Arguments.PATH_ELEMENT)
@InfiniteArguments
@SoftPrerequisites("flex")
public void setFileSpecs(ConfigurationValue cv, List<String> args) throws ConfigurationException
{
this.fileSpecs.addAll(args);
checkForMxmlFiles(args);
}
private void checkForMxmlFiles(List<String> paths)
{
// If there are mxml or css files then we are compiling a flex
// application so enable "flex".
for (String path : paths)
{
if (path.endsWith(".mxml") || path.endsWith(".css"))
isFlex = true;
}
}
//
// 'help' option from CommandLineConfiguration
//
/**
* dummy, just a trigger for help text
*/
@Config(displayed = false, greedy = true)
@Arguments("keyword")
@InfiniteArguments
public void setHelp(ConfigurationValue cv, String[] keywords)
{
}
//
// 'load-config' option from CommandLineConfiguration
//
private String configFile = null;
/**
* @return Normalized path to a Flex configuration file.
*/
public String getLoadConfig()
{
return configFile;
}
/**
* Since {@link ConfigurationBuffer} loads the "load-config" files, the value of this configuration option isn't
* intersting to the rest part of the compiler.
*/
@Config(allowMultiple = true)
@Arguments("filename")
public void setLoadConfig(ConfigurationValue cv, String filename) throws ConfigurationException
{
configFile = resolvePathStrict(filename, cv);
}
//
// 'version' option from CommandLineConfiguration
//
/**
* Dummy option. Just a trigger for version info.
*/
@Config
public void setVersion(ConfigurationValue cv, boolean value)
{
}
//
// 'verbose' option from CommandLineConfiguration
//
private boolean verbose = false;
public boolean isVerbose()
{
return verbose;
}
@Config(hidden = true)
public void setVerbose(ConfigurationValue cfgval, boolean b)
{
verbose = b;
}
//
// 'dump-ast' option from CommandLineConfiguration
//
private boolean dumpAst;
public boolean isDumpAst()
{
return dumpAst;
}
@Config(hidden = true)
public void setDumpAst(ConfigurationValue cfgval, boolean b)
{
dumpAst = b;
}
//
// 'enable-inlining' option from CommandLineConfiguration
//
private boolean enableInlining = false;
/**
* @return true if function inlining has been enabled.
*/
public boolean isInliningEnabled()
{
return enableInlining;
}
/**
* Enable or disable function inlining.
*
* @param cfgval The configuration value context.
* @param b true to enable inlining, false otherwise.
*/
@Config(hidden = true)
@Mapping({ "compiler", "inline" })
public void setEnableInlining(ConfigurationValue cfgval, boolean b)
{
enableInlining = b;
}
//
// 'remove-dead-code' option from CommandLineConfiguration
//
private boolean removeDeadCode = false;
/**
* @return true if dead code removal has been enabled.
*/
public boolean getRemoveDeadCode()
{
return this.removeDeadCode;
}
/**
* Enable or disable dead code removal.
*
* @param cfgval the configuration value context.
* @param b true to enable dead code removal, false to disable.
*/
@Config(advanced = true)
@Mapping({ "compiler", "remove-dead-code" })
public void setRemoveDeadCode(ConfigurationValue cfgval, boolean b)
{
this.removeDeadCode = b;
}
//
// Validation methods from ToolsConfiguration
//
void validateDumpConfig(ConfigurationBuffer configurationBuffer) throws ConfigurationException
{
if (dumpConfigFile != null)
{
final String text = FileConfigurator.formatBuffer(configurationBuffer, "flex-config",
LocalizationManager.get(), "flex2.configuration");
try
{
final Writer writer = new FileWriter(dumpConfigFile);
IOUtils.write(text, writer);
IOUtils.closeQuietly(writer);
}
catch (IOException e)
{
throw new ConfigurationException.IOError(dumpConfigFile);
}
}
}
/**
* Collection of fatal and non-fatal configuration problems.
*/
private Collection<ICompilerProblem> configurationProblems = new ArrayList<ICompilerProblem>();
/**
* Get the configuration problems. This should be called after the configuration has been processed.
*
* @return a collection of fatal and non-fatal configuration problems.
*/
public Collection<ICompilerProblem> getConfigurationProblems()
{
return configurationProblems;
}
private boolean warnOnFlexOnlyOptionUsage = false;
/**
* @return True if warnings are generated when "Flex only" options are used, false otherwise.
*/
public boolean getWarnOnFlexOnlyOptionUsage()
{
return warnOnFlexOnlyOptionUsage;
}
/**
* Controls if the compiler warns when "Flex only" configuration options are used in the compiler.
*
* @param value True to enable warnings, false to disable warnings. The default is to not warn.
*/
public void setWarnOnFlexOnlyOptionUsage(boolean value)
{
this.warnOnFlexOnlyOptionUsage = value;
}
private boolean enableTelemetry = false;
/**
*
* @return True if telemetry is enabled, false otherwise.
*/
public boolean isEnableTelemetry()
{
return enableTelemetry;
}
/**
* Controls if the flash runtime should allow providing advanced telemetry options to external tools.
*
* @param enableTelemetry True to enable telemetry, false to disable. The default ist to disable.
*/
public void setEnableTelemetry(boolean enableTelemetry)
{
this.enableTelemetry = enableTelemetry;
}
/**
* Turns on the advanced telemetry options of the flash runtime to allow clients like scout to connect.
*
* Remark: Internally and in the spec this option is called "enable telemetry" but by tools and the commandline it's
* referenced by advanced-telemetry.
*/
@Config(advanced = true)
@Mapping({ "compiler", "advanced-telemetry" })
@FlexOnly
public void setEnableTelemetry(ConfigurationValue cv, boolean enableTelemetry) throws CannotOpen
{
this.enableTelemetry = enableTelemetry;
}
private void processDeprecatedAndRemovedOptions(ConfigurationBuffer configurationBuffer)
{
for (final String var : configurationBuffer.getVars())
{
ConfigurationInfo info = configurationBuffer.getInfo(var);
List<ConfigurationValue> values = configurationBuffer.getVar(var);
if (values != null)
{
for (final ConfigurationValue cv : values)
{
if (info.isRemoved())
{
//addRemovedConfigurationOptionProblem(cv);
}
else if (info.isDeprecated() && configurationBuffer.getVar(var) != null)
{
String replacement = info.getDeprecatedReplacement();
String since = info.getDeprecatedSince();
DeprecatedConfigurationOptionProblem problem = new DeprecatedConfigurationOptionProblem(var,
replacement, since, cv.getSource(), cv.getLine());
configurationProblems.add(problem);
}
else if (warnOnFlexOnlyOptionUsage && info.isFlexOnly())
{
FlexOnlyConfigurationOptionNotSupported problem = new FlexOnlyConfigurationOptionNotSupported(
var, cv.getSource(), cv.getLine());
configurationProblems.add(problem);
}
}
}
}
}
/**
* Add a RemovedConfigurationOptionProblem to the list of configuration problems.
*
* @param cv
*/
private void addRemovedConfigurationOptionProblem(ConfigurationValue cv)
{
RemovedConfigurationOptionProblem problem = new RemovedConfigurationOptionProblem(cv.getVar(), cv.getSource(),
cv.getLine());
configurationProblems.add(problem);
}
private boolean strictXML = false;
/**
*
* @return True if strictXML is enabled, false otherwise.
*/
public boolean isStrictXML()
{
return strictXML;
}
/**
* Controls if the compiler should try to resolve XML methods. Enabling this makes it
* possible to write new XML implementations but causes more warnings. Default is false.
*
* @param strictXML True to enable strict XML checking, false to disable. The default is to disable.
*/
public void setStrictXML(boolean strictXML)
{
this.strictXML = strictXML;
}
/**
* Turns on the strict XML checking in the compiler. Enabling this makes it
* possible to write new XML implementations but causes more warnings.
*
*/
@Config(advanced = true)
@Mapping({ "compiler", "strict-xml" })
@FlexOnly
public void setStrictXML(ConfigurationValue cv, boolean strictXML) throws CannotOpen
{
this.strictXML = strictXML;
}
}