http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler.js/src/org/apache/flex/compiler/clients/MXMLJSC.java ---------------------------------------------------------------------- diff --git a/compiler.js/src/org/apache/flex/compiler/clients/MXMLJSC.java b/compiler.js/src/org/apache/flex/compiler/clients/MXMLJSC.java deleted file mode 100644 index 1f8f070..0000000 --- a/compiler.js/src/org/apache/flex/compiler/clients/MXMLJSC.java +++ /dev/null @@ -1,1629 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.flex.compiler.clients; - -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.javascript.jscomp.*; -import com.google.javascript.jscomp.Compiler; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.output.CountingOutputStream; -import org.apache.flex.compiler.clients.problems.ProblemPrinter; -import org.apache.flex.compiler.clients.problems.ProblemQuery; -import org.apache.flex.compiler.clients.problems.WorkspaceProblemFormatter; -import org.apache.flex.compiler.common.DependencyType; -import org.apache.flex.compiler.common.VersionInfo; -import org.apache.flex.compiler.config.*; -import org.apache.flex.compiler.config.RSLSettings.RSLAndPolicyFileURLPair; -import org.apache.flex.compiler.definitions.IDefinition; -import org.apache.flex.compiler.exceptions.ConfigurationException; -import org.apache.flex.compiler.exceptions.ConfigurationException.IOError; -import org.apache.flex.compiler.exceptions.ConfigurationException.MustSpecifyTarget; -import org.apache.flex.compiler.exceptions.ConfigurationException.OnlyOneSource; -import org.apache.flex.compiler.filespecs.IFileSpecification; -import org.apache.flex.compiler.internal.as.codegen.*; -import org.apache.flex.compiler.internal.config.localization.LocalizationManager; -import org.apache.flex.compiler.internal.definitions.ClassDefinition; -import org.apache.flex.compiler.internal.driver.IBackend; -import org.apache.flex.compiler.internal.driver.JSBackend; -import org.apache.flex.compiler.internal.driver.JSTarget; -import org.apache.flex.compiler.internal.graph.GoogDepsWriter; -import org.apache.flex.compiler.internal.graph.GraphMLWriter; -import org.apache.flex.compiler.internal.projects.*; -import org.apache.flex.compiler.internal.projects.DefinitionPriority.BasePriority; -import org.apache.flex.compiler.internal.resourcebundles.ResourceBundleUtils; -import org.apache.flex.compiler.internal.scopes.ASProjectScope; -import org.apache.flex.compiler.internal.scopes.ASProjectScope.DefinitionPromise; -import org.apache.flex.compiler.internal.targets.LinkageChecker; -import org.apache.flex.compiler.internal.targets.Target; -import org.apache.flex.compiler.internal.tree.mxml.MXMLClassDefinitionNode; -import org.apache.flex.compiler.internal.units.*; -import org.apache.flex.compiler.internal.workspaces.Workspace; -import org.apache.flex.compiler.problems.*; -import org.apache.flex.compiler.projects.ICompilerProject; -import org.apache.flex.compiler.targets.ISWFTarget; -import org.apache.flex.compiler.targets.ITarget.TargetType; -import org.apache.flex.compiler.targets.ITargetReport; -import org.apache.flex.compiler.targets.ITargetSettings; -import org.apache.flex.compiler.tree.as.IASNode; -import org.apache.flex.compiler.units.ICompilationUnit; -import org.apache.flex.compiler.units.ICompilationUnit.UnitType; -import org.apache.flex.compiler.units.requests.IFileScopeRequestResult; -import org.apache.flex.swc.ISWC; -import org.apache.flex.swf.ISWF; -import org.apache.flex.swf.io.ISWFWriter; -import org.apache.flex.swf.types.Rect; -import org.apache.flex.utils.ArgumentUtil; -import org.apache.flex.utils.FilenameNormalization; - -import java.io.*; -import java.util.*; - -/** - * The entry-point class for the FalconJS version of mxmlc. - */ -public class MXMLJSC -{ - private static final String DEFAULT_VAR = "file-specs"; - private static final String L10N_CONFIG_PREFIX = "flex2.configuration"; - private static final int TWIPS_PER_PIXEL = 20; - - /* - * Exit code enumerations. - */ - static enum ExitCode - { - SUCCESS(0), - PRINT_HELP(1), - FAILED_WITH_PROBLEMS(2), - FAILED_WITH_EXCEPTIONS(3), - FAILED_WITH_CONFIG_PROBLEMS(4); - - ExitCode(int code) - { - this.code = code; - } - - final int code; - } - - /** - * Java program entry point. - * - * @param args command line arguments - */ - public static void main(final String[] args) - { - long startTime = System.nanoTime(); - - final IBackend backend = new JSBackend(); - final MXMLJSC mxmlc = new MXMLJSC(backend); - final Set<ICompilerProblem> problems = new HashSet<ICompilerProblem>(); - final int exitCode = mxmlc.mainNoExit(args, problems, true); - - long endTime = System.nanoTime(); - JSSharedData.instance.stdout((endTime - startTime) / 1e9 + " seconds"); - - System.exit(exitCode); - } - - public static int mainNoExit(final String[] args, List<ICompilerProblem> problemList) - { - final IBackend backend = new JSBackend(); - final MXMLJSC mxmlc = new MXMLJSC(backend); - final Set<ICompilerProblem> problems = new HashSet<ICompilerProblem>(); - final int exitCode = mxmlc.mainNoExit(args, problems, problemList == null); - if (problemList != null) - problemList.addAll(problems); - return exitCode; - } - - public int mainNoExit(final String[] args, Set<ICompilerProblem> problems, Boolean printProblems) - { - int exitCode = -1; - try - { - exitCode = _mainNoExit(ArgumentUtil.fixArgs(args), problems); - } - catch (Exception e) - { - JSSharedData.instance.stderr(e.toString()); - } - finally - { - if (problems != null && !problems.isEmpty()) - { - if (printProblems) - { - final WorkspaceProblemFormatter formatter = new WorkspaceProblemFormatter(workspace); - final ProblemPrinter printer = new ProblemPrinter(formatter); - printer.printProblems(problems); - } - } - } - return exitCode; - } - - /** - * Entry point that doesn't call <code>System.exit()</code>. This is for - * unit testing. - * - * @param args command line arguments - * @return exit code - */ - private int _mainNoExit(final String[] args, Set<ICompilerProblem> outProblems) - { - ExitCode exitCode = ExitCode.SUCCESS; - try - { - final boolean continueCompilation = configure(args); - - if (outProblems != null && !config.isVerbose()) - JSSharedData.STDOUT = JSSharedData.STDERR = null; - - if (continueCompilation) - { - compile(); - if (problems.hasFilteredProblems()) - exitCode = ExitCode.FAILED_WITH_PROBLEMS; - } - else if (problems.hasFilteredProblems()) - { - exitCode = ExitCode.FAILED_WITH_CONFIG_PROBLEMS; - } - else - { - exitCode = ExitCode.PRINT_HELP; - } - } - catch (Exception e) - { - if (outProblems == null) - JSSharedData.instance.stderr(e.getMessage()); - else - { - final ICompilerProblem unexpectedExceptionProblem = new UnexpectedExceptionProblem(e); - problems.add(unexpectedExceptionProblem); - } - exitCode = ExitCode.FAILED_WITH_EXCEPTIONS; - } - finally - { - waitAndClose(); - - if (outProblems != null && problems.hasFilteredProblems()) - { - for (ICompilerProblem problem : problems.getFilteredProblems()) - { - outProblems.add(problem); - } - } - } - return exitCode.code; - } - - protected MXMLJSC(IBackend backend) - { - JSSharedData.backend = backend; - workspace = new Workspace(); - project = new FlexJSProject(workspace); - MXMLClassDefinitionNode.GENERATED_ID_BASE = "$ID"; - problems = new ProblemQuery(); - JSSharedData.OUTPUT_EXTENSION = backend.getOutputExtension(); - JSSharedData.workspace = workspace; - asFileHandler = backend.getSourceFileHandlerInstance(); - } - - protected Workspace workspace; - protected FlexProject project; - protected Configuration config; - protected ProblemQuery problems; - private ConfigurationBuffer configBuffer; - - protected Configurator projectConfigurator; - - protected ICompilationUnit mainCU; - protected JSTarget target; - private ITargetSettings targetSettings; - private ISWF swfTarget; - - private Collection<ICompilationUnit> includedResourceBundleCompUnits; - protected ISourceFileHandler asFileHandler; - - /** - * Print a message. - * - * @param msg Message text. - */ - public void println(final String msg) - { - JSSharedData.instance.stdout(msg); - } - - /** - * Wait till the workspace to finish compilation and close. - */ - protected void waitAndClose() - { - workspace.startIdleState(); - try - { - workspace.close(); - } - finally - { - workspace.endIdleState(Collections.<ICompilerProject, Set<ICompilationUnit>> emptyMap()); - } - } - - /** - * Force terminate the compilation process. - */ - protected void close() - { - workspace.close(); - } - - /** - * Create a new Configurator. This method may be overridden to allow - * Configurator subclasses to be created that have custom configurations. - * - * @return a new instance or subclass of {@link Configurator}. - */ - protected Configurator createConfigurator() - { - return JSSharedData.backend.createConfigurator(); - } - - /** - * Load configurations from all the sources. - * - * @param args command line arguments - * @return True if mxmlc should continue with compilation. - */ - protected boolean configure(final String[] args) - { - project.getSourceCompilationUnitFactory().addHandler(asFileHandler); - CodeGeneratorManager.setFactory(JSGenerator.getABCGeneratorFactory()); - projectConfigurator = createConfigurator(); - - try - { - // Print brief usage if no arguments provided. - if (args.length == 0) - { - final String usage = CommandLineConfigurator.brief( - getProgramName(), DEFAULT_VAR, LocalizationManager.get(), L10N_CONFIG_PREFIX); - if (usage != null) - println(usage); - return false; - } - - projectConfigurator.setConfiguration(args, ICompilerSettingsConstants.FILE_SPECS_VAR); - projectConfigurator.applyToProject(project); - problems = new ProblemQuery(projectConfigurator.getCompilerProblemSettings()); - - // Get the configuration and configBuffer which are now initialized. - config = projectConfigurator.getConfiguration(); - configBuffer = projectConfigurator.getConfigurationBuffer(); - problems.addAll(projectConfigurator.getConfigurationProblems()); - - // Print version if "-version" is present. - if (configBuffer.getVar("version") != null) //$NON-NLS-1$ - { - println(VersionInfo.buildMessage() + " (" + JSSharedData.COMPILER_VERSION + ")"); - return false; - } - - // Print help if "-help" is present. - final List<ConfigurationValue> helpVar = configBuffer.getVar("help"); //$NON-NLS-1$ - if (helpVar != null) - { - processHelp(helpVar); - return false; - } - - for (String fileName : projectConfigurator.getLoadedConfigurationFiles()) - { - JSSharedData.instance.stdout("Loading configuration: " + fileName); - } - - if (config.isVerbose()) - { - for (final IFileSpecification themeFile : project.getThemeFiles()) - { - JSSharedData.instance.stdout(String.format("Found theme file %s", themeFile.getPath())); - } - } - - // If we have configuration errors then exit before trying to - // validate the target. - if (problems.hasErrors()) - return false; - - validateTargetFile(); - return true; - } - catch (ConfigurationException e) - { - final ICompilerProblem problem = new ConfigurationProblem(e); - problems.add(problem); - return false; - } - catch (Exception e) - { - final ICompilerProblem problem = new ConfigurationProblem(null, -1, -1, -1, -1, e.getMessage()); - problems.add(problem); - return false; - } - finally - { - // If we couldn't create a configuration, then create a default one - // so we can exit without throwing an exception. - if (config == null) - { - config = new Configuration(); - configBuffer = new ConfigurationBuffer(Configuration.class, Configuration.getAliases()); - } - } - } - - /** - * Validate target file. - * - * @throws MustSpecifyTarget - * @throws IOError - */ - protected void validateTargetFile() throws ConfigurationException - { - if (mainCU instanceof ResourceModuleCompilationUnit) - return; //when compiling a Resource Module, no target file is defined. - - final String targetFile = config.getTargetFile(); - if (targetFile == null) - throw new ConfigurationException.MustSpecifyTarget(null, null, -1); - - final File file = new File(targetFile); - if (!file.exists()) - throw new ConfigurationException.IOError(targetFile); - } - - /** - * Main body of this program. This method is called from the public static - * method's for this program. - * - * @return true if compiler succeeds - * @throws IOException - * @throws InterruptedException - */ - protected boolean compile() - { - ArrayList<String> otherFiles = new ArrayList<String>(); - - boolean compilationSuccess = false; - try - { - setupJS(); - if (!setupTargetFile()) - return false; - - if (config.isDumpAst()) - dumpAST(); - - buildArtifact(); - - final File outputFile = new File(getOutputFilePath()); - final File outputFolder = outputFile.getParentFile(); - if (!outputFolder.exists()) - { - outputFolder.mkdirs(); - } - - if (swfTarget != null) - { - Collection<ICompilerProblem> errors = new ArrayList<ICompilerProblem>(); - Collection<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>(); - - // Don't create a swf if there are errors unless a - // developer requested otherwise. - if (!config.getCreateTargetWithErrors()) - { - problems.getErrorsAndWarnings(errors, warnings); - if (errors.size() > 0) - return false; - } - - final int swfSize = writeSWF(swfTarget, outputFile); - - println(String.format("%d bytes written to %s", swfSize, outputFile.getCanonicalPath())); - - if (JSSharedData.OUTPUT_ISOLATED) - { - List<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(ImmutableSet.of(mainCU)); - for (final ICompilationUnit cu : reachableCompilationUnits) - { - if ((cu.getCompilationUnitType() == UnitType.AS_UNIT || - cu.getCompilationUnitType() == UnitType.MXML_UNIT) && cu != mainCU) - { - final File outputClassFile = new File(outputFolder.getAbsolutePath() + File.separator + cu.getShortNames().get(0) + ".js"); - System.out.println(outputClassFile.getAbsolutePath()); - otherFiles.add(outputClassFile.getAbsolutePath()); - final ISWFWriter swfWriter = JSSharedData.backend.createJSWriter(project, (List<ICompilerProblem>) errors, ImmutableSet.of(cu), false); - - if (swfWriter instanceof JSWriter) - { - final JSWriter writer = (JSWriter)swfWriter; - - final CountingOutputStream output = - new CountingOutputStream(new BufferedOutputStream(new FileOutputStream(outputClassFile))); - writer.writeTo(output); - output.flush(); - output.close(); - writer.close(); - } - } - } - } - } - - dumpDependencyGraphIfNeeded(); - - generateGoogDepsIfNeeded(outputFile.getParentFile()); - - compilationSuccess = true; - - if (JSSharedData.OPTIMIZE) - { - compilationSuccess = closureCompile(outputFile, problems); - if (compilationSuccess) - { - for (String fn : otherFiles) - { - File f = new File(fn); - f.delete(); - } - } - } - - - } - catch (Exception e) - { - final ICompilerProblem problem = new InternalCompilerProblem(e); - problems.add(problem); - } - return compilationSuccess; - } - - /** - * Setup theme files. - */ - protected void setupThemeFiles() - { - project.setThemeFiles(toFileSpecifications(config.getCompilerThemeFiles(), workspace)); - - if (config.isVerbose()) - { - for (final IFileSpecification themeFile : project.getThemeFiles()) - { - verboseMessage(String.format("Found theme file %s", themeFile.getPath())); - } - } - } - - /** - * Setup {@code -compatibility-version} level. Falcon only support Flex 3+. - */ - protected void setupCompatibilityVersion() - { - final int compatibilityVersion = config.getCompilerMxmlCompatibilityVersion(); - if (compatibilityVersion < Configuration.MXML_VERSION_3_0) - throw new UnsupportedOperationException("Unsupported compatibility version: " + config.getCompilerCompatibilityVersionString()); - this.project.setCompatibilityVersion( - config.getCompilerMxmlMajorCompatibilityVersion(), - config.getCompilerMxmlMinorCompatibilityVersion(), - config.getCompilerMxmlRevisionCompatibilityVersion()); - } - - /** - * Parse all source files and dumpAST - * - * @throws InterruptedException - */ - private void dumpAST() throws InterruptedException - { - final List<String> astDump = new ArrayList<String>(); - final ImmutableList<ICompilationUnit> compilationUnits = getReachableCompilationUnits(); - for (final ICompilationUnit compilationUnit : compilationUnits) - { - final IASNode ast = compilationUnit.getSyntaxTreeRequest().get().getAST(); - astDump.add(ast.toString()); - } - - println(Joiner.on("\n\n").join(astDump)); //$NON-NLS-1$ - } - - /** - * Build target artifact. - * - * @throws InterruptedException threading error - * @throws IOException IO error - * @throws ConfigurationException - */ - protected void buildArtifact() throws InterruptedException, IOException, ConfigurationException - { - swfTarget = buildSWFModel(); - } - - /** - * Build SWF model object and collect problems building SWF in - * {@link #problems}. - * - * @return SWF model or null if SWF can't be built. - * @throws InterruptedException concurrency problem - * @throws ConfigurationException - * @throws FileNotFoundException - */ - private ISWF buildSWFModel() throws InterruptedException, FileNotFoundException, ConfigurationException - { - final List<ICompilerProblem> problemsBuildingSWF = - new ArrayList<ICompilerProblem>(); - - final ISWF swf = buildSWF(project, config.getMainDefinition(), mainCU, problemsBuildingSWF); - problems.addAll(problemsBuildingSWF); - if (swf == null) - { - ICompilerProblem problem = new UnableToBuildSWFProblem(getOutputFilePath()); - problems.add(problem); - } - else - { - swf.setFrameRate(config.getDefaultFrameRate()); - final int swfWidth = config.getDefaultWidth() * TWIPS_PER_PIXEL; - final int swfHeight = config.getDefaultHeight() * TWIPS_PER_PIXEL; - swf.setFrameSize(new Rect(swfWidth, swfHeight)); - swf.setVersion(config.getSwfVersion()); - swf.setTopLevelClass(config.getMainDefinition()); - swf.setUseAS3(true); - } - - reportRequiredRSLs(target); - - return swf; - } - - private void reportRequiredRSLs(ISWFTarget target) throws FileNotFoundException, InterruptedException, ConfigurationException - { - // Report the required RSLs: - if (hasRSLs()) - { - ITargetReport report = target.getTargetReport(); - - if (report == null) - return; // target must not have been built. - - // TODO (dloverin): localize messages - JSSharedData.instance.stdout("Required RSLs:"); - - // loop thru the RSLs and print out the required RSLs. - for (RSLSettings rslSettings : report.getRequiredRSLs()) - { - List<RSLAndPolicyFileURLPair> rslUrls = rslSettings.getRSLURLs(); - - switch (rslUrls.size()) - { - case 0: - assert false; // One RSL URL is required. - break; - case 1: - JSSharedData.instance.stdout(" " + rslUrls.get(0).getRSLURL()); - //ThreadLocalToolkit.log(new RequiredRSLUrl(rslUrls.get(0))); - break; - case 2: - JSSharedData.instance.stdout(" " + rslUrls.get(0).getRSLURL() + " with 1 failover."); - //ThreadLocalToolkit.log(new RequiredRSLUrlWithFailover(rslUrls.get(0))); - break; - default: - JSSharedData.instance.stdout(" " + rslUrls.get(0).getRSLURL() + " with " + (rslUrls.size() - 1) + " failovers."); - // ThreadLocalToolkit.log(new RequiredRSLUrlWithMultipleFailovers( - // rslUrls.get(0), - // rslUrls.size() - 1)); - break; - } - - } - - // All -runtime-shared-libraries are required - for (String rslUrl : targetSettings.getRuntimeSharedLibraries()) - { - JSSharedData.instance.stdout(" " + rslUrl); - //ThreadLocalToolkit.log(new RequiredRSLUrl(rslUrls.get(0))); - } - } - } - - private ITargetSettings getTargetSettings() - { - if (targetSettings == null) - targetSettings = projectConfigurator.getTargetSettings(TargetType.SWF); - - return targetSettings; - } - - private boolean hasRSLs() throws FileNotFoundException, InterruptedException, ConfigurationException - { - return (getTargetSettings().getRuntimeSharedLibraryPath().size() > 0) || - (getTargetSettings().getRuntimeSharedLibraryPath().size() > 0); - } - - /** - * Write out SWF file and return file size in bytes. - * - * @param swf SWF model - * @param outputFile output SWF file handle - * @return SWF file size in bytes - * @throws FileNotFoundException error - * @throws IOException error - */ - private int writeSWF(final ISWF swf, final File outputFile) throws FileNotFoundException, IOException - { - int swfSize = 0; - final List<ICompilerProblem> problemList = new ArrayList<ICompilerProblem>(); - final ISWFWriter swfWriter = JSSharedData.backend.createSWFWriter(project, problemList, swf, false, config.debug()); - - if (swfWriter instanceof JSWriter) - { - final JSWriter writer = (JSWriter)swfWriter; - - final CountingOutputStream output = - new CountingOutputStream(new BufferedOutputStream(new FileOutputStream(outputFile))); - writer.writeTo(output); - output.flush(); - output.close(); - writer.close(); - swfSize = output.getCount(); - } - - /* - * W#3047880 falconjs_cs6: internal compiler error generated with - * optimize enabled compiling as3_enumerate.fla and fails to release the - * JS file http://watsonexp.corp.adobe.com/#bug=3047880 This is part #3 - * of the fix: The closure compiler throws RTEs on internal compiler - * errors, that don't get caught until they bubble up to MXMLJSC's - * scope. On their way out files remain unclosed and cause problems, - * because Flame cannot delete open files. We now get - * InternalCompilerProblems, which we need to transfer to our problem - * list. - */ - problems.addAll(problemList); - - return swfSize; - } - - /** - * Computes the set of compilation units that root the dependency walk. The - * returned set of compilation units and their dependencies will be - * compiled. - * <p> - * This method can be overriden by sub-classes. - * - * @return The set of rooted {@link ICompilationUnit}'s. - */ - protected ImmutableSet<ICompilationUnit> getRootedCompilationUnits() - { - return ImmutableSet.of(mainCU); - } - - /** - * @return All the reachable compilation units in this job. - */ - protected ImmutableList<ICompilationUnit> getReachableCompilationUnits() - { - final Set<ICompilationUnit> root = getRootedCompilationUnits(); - final List<ICompilationUnit> reachableCompilationUnitsInSWFOrder = - project.getReachableCompilationUnitsInSWFOrder(root); - final ImmutableList<ICompilationUnit> compilationUnits = ImmutableList.<ICompilationUnit> copyOf(reachableCompilationUnitsInSWFOrder); - return compilationUnits; - } - - /** - * Mxmlc uses target file as the main compilation unit and derive the output - * SWF file name from this file. - * - * @return true if successful, false otherwise. - * @throws OnlyOneSource - * @throws InterruptedException - */ - protected boolean setupTargetFile() throws InterruptedException - { - final String mainFileName = config.getTargetFile(); - - if (mainFileName != null) - { - final String normalizedMainFileName = FilenameNormalization.normalize(mainFileName); - - // Can not add a SourceHandler for *.css file because we don't want - // to create compilation units for CSS files on the source path. - if (mainFileName.toLowerCase().endsWith(".css")) //$NON-NLS-1$ - { - mainCU = new StyleModuleCompilationUnit( - project, - workspace.getFileSpecification(normalizedMainFileName), - BasePriority.SOURCE_LIST); - // TODO: Use CSS file name once CSS module runtime code is finalized. (scai) - config.setMainDefinition("CSSModule2Main"); //$NON-NLS-1$ - project.addCompilationUnitsAndUpdateDefinitions( - Collections.singleton(mainCU)); - } - else - { - final SourceCompilationUnitFactory compilationUnitFactory = - project.getSourceCompilationUnitFactory(); - - File normalizedMainFile = new File(normalizedMainFileName); - if (compilationUnitFactory.canCreateCompilationUnit(normalizedMainFile)) - { - project.addIncludeSourceFile(normalizedMainFile); - - // just using the basename is obviously wrong: - // final String mainQName = FilenameUtils.getBaseName(normalizedMainFile); - - final List<String> sourcePath = config.getCompilerSourcePath(); - String mainQName = null; - if (sourcePath != null && !sourcePath.isEmpty()) - { - for (String path : sourcePath) - { - final String otherPath = new File(path).getAbsolutePath(); - if (mainFileName.startsWith(otherPath)) - { - mainQName = mainFileName.substring(otherPath.length() + 1); - mainQName = mainQName.replaceAll("\\\\", "/"); - mainQName = mainQName.replaceAll("\\/", "."); - if (mainQName.endsWith(".as")) - mainQName = mainQName.substring(0, mainQName.length() - 3); - break; - } - } - } - - if (mainQName == null) - mainQName = FilenameUtils.getBaseName(mainFileName); - - Collection<ICompilationUnit> mainFileCompilationUnits = - workspace.getCompilationUnits(normalizedMainFileName, project); - - assert mainFileCompilationUnits.size() == 1; - mainCU = Iterables.getOnlyElement(mainFileCompilationUnits); - - assert ((DefinitionPriority)mainCU.getDefinitionPriority()).getBasePriority() == DefinitionPriority.BasePriority.SOURCE_LIST; - - // Use main source file name as the root class name. - config.setMainDefinition(mainQName); - } - } - } - else - { - final List<ICompilerProblem> resourceBundleProblems = new ArrayList<ICompilerProblem>(); - Collection<ICompilationUnit> includedResourceBundles = target.getIncludedResourceBundlesCompilationUnits(resourceBundleProblems); - problems.addAll(resourceBundleProblems); - - if (includedResourceBundles.size() > 0) - { - //This means that a Resource Module is requested to be built. - mainCU = new ResourceModuleCompilationUnit(project, "GeneratedResourceModule", //$NON-NLS-1$ - includedResourceBundles, - BasePriority.SOURCE_LIST); - config.setMainDefinition("GeneratedResourceModule"); //$NON-NLS-1$ - project.addCompilationUnitsAndUpdateDefinitions( - Collections.singleton(mainCU)); - } - } - - Preconditions.checkNotNull(mainCU, "Main compilation unit can't be null"); //$NON-NLS-1$ - - /* - * final String mainFileName = new - * File(config.getTargetFile()).getAbsolutePath(); final - * SourceCompilationUnitFactory compilationUnitFactory = - * project.getSourceCompilationUnitFactory(); final File mainFile = new - * File(mainFileName); // just using the basename is obviously wrong: // - * final String mainQName = FilenameUtils.getBaseName(mainFileName); - * final List<String> sourcePath = config.getCompilerSourcePath(); - * String mainQName = null; if( sourcePath != null && - * !sourcePath.isEmpty() ) { for( String path : sourcePath ) { final - * String otherPath = new File(path).getAbsolutePath(); if( - * mainFileName.startsWith(otherPath) ) { mainQName = - * mainFileName.substring(otherPath.length() + 1); mainQName = - * mainQName.replaceAll("\\\\", "/"); mainQName = - * mainQName.replaceAll("\\/", "."); if( mainQName.endsWith(".as") ) - * mainQName = mainQName.substring(0, mainQName.length() - 3); break; } - * } } if( mainQName == null ) mainQName = - * FilenameUtils.getBaseName(mainFileName); mainCU = - * compilationUnitFactory.createCompilationUnit( mainFile, - * DefinitionPriority.BasePriority.SOURCE_LIST, mainQName, null); - * Preconditions.checkNotNull(mainCU, - * "Main compilation unit can't be null"); - * project.addCompilationUnitsAndUpdateDefinitions( - * Collections.singleton(mainCU)); // Use main source file name as the - * root class name. config.setMainDefinition(mainQName); - */ - - // target = (FlexSWFTarget)project.createSWFTarget(getTargetSettings(), null); - if (getTargetSettings() == null) - return false; - - project.setTargetSettings(getTargetSettings()); - target = (JSTarget)JSSharedData.backend.createSWFTarget(project, getTargetSettings(), null); - - return true; - } - - /** - * @return a list of resource bundle compilation units that are included - * into the build process by -include-resource-bundles compiler argument. - */ - protected Collection<ICompilationUnit> getIncludedResourceBundlesCompUnits() throws InterruptedException - { - Collection<ICompilerProblem> bundleProblems = new ArrayList<ICompilerProblem>(); - if (includedResourceBundleCompUnits == null) - { - includedResourceBundleCompUnits = new HashSet<ICompilationUnit>(); - - for (String bundleName : config.getIncludeResourceBundles()) - { - includedResourceBundleCompUnits.addAll(ResourceBundleUtils.findCompilationUnits(bundleName, project, bundleProblems)); - problems.addAll(bundleProblems); - } - } - - return includedResourceBundleCompUnits; - } - - /** - * Setup the source paths. - * - * @throws InterruptedException - */ - /** - * Setup the source paths. - * - * @throws InterruptedException - */ - protected void setupSourcePath() throws InterruptedException - { - project.setSourcePath(toFiles(config.getCompilerSourcePath())); - } - - /** - * Setups the locale related settings. - */ - protected void setupLocaleSettings() - { - project.setLocales(config.getCompilerLocales()); - project.setLocaleDependentResources(config.getLocaleDependentSources()); - } - - /** - * Get the output file path. If {@code -output} is specified, use its value; - * otherwise, use the same base name as the target file. - * - * @return output file path - */ - private String getOutputFilePath() - { - if (config.getOutput() == null) - { - final String extension = "." + JSSharedData.OUTPUT_EXTENSION; - return FilenameUtils.removeExtension(config.getTargetFile()).concat(extension); - } - else - return config.getOutput(); - } - - private void verboseMessage(String s) - { - if (config.isVerbose()) - println(s); - } - - /** - * Convert file path strings to {@code File} objects. Null values are - * discarded. - * - * @param fileSpecs file specifications - * @return List of File objects. No null values will be returned. - */ - public static List<File> toFiles(final List<String> paths) - { - final List<File> result = new ArrayList<File>(); - for (final String path : paths) - { - if (path != null) - result.add(new File(path)); - } - return result; - } - - /** - * Resolve a list of normalized paths to {@link IFileSpecification} objects - * from the given {@code workspace}. - * - * @param paths A list of normalized paths. - * @param workspace Workspace. - * @return A list of file specifications. - */ - public static List<IFileSpecification> toFileSpecifications( - final List<String> paths, - final Workspace workspace) - { - return Lists.transform(paths, new Function<String, IFileSpecification>() - { - @Override - public IFileSpecification apply(final String path) - { - return workspace.getFileSpecification(path); - } - }); - } - - /** - * Get my program name. - * - * @return always "mxmlc". - */ - protected String getProgramName() - { - return "mxmljsc"; //$NON-NLS-1$ - } - - /** - * Print detailed help information if -help is provided. - */ - private void processHelp(final List<ConfigurationValue> helpVar) - { - final Set<String> keywords = new LinkedHashSet<String>(); - for (final ConfigurationValue val : helpVar) - { - for (final Object element : val.getArgs()) - { - String keyword = (String)element; - while (keyword.startsWith("-")) //$NON-NLS-1$ - keyword = keyword.substring(1); - keywords.add(keyword); - } - } - - if (keywords.size() == 0) - keywords.add("help"); //$NON-NLS-1$ - - final String usages = CommandLineConfigurator.usage( - getProgramName(), - DEFAULT_VAR, - configBuffer, - keywords, - LocalizationManager.get(), - L10N_CONFIG_PREFIX); - println(usages); - } - - /** - * "compc" subclass will override this method. - * - * @return False if the client is not "compc". - */ - protected boolean isCompc() - { - return false; - } - - private void dumpDependencyGraphIfNeeded() throws IOException, InterruptedException, ConfigurationException - { - File dependencyGraphOutput = config.getDependencyGraphOutput(); - if (dependencyGraphOutput != null) - { - LinkedList<ICompilerProblem> problemList = new LinkedList<ICompilerProblem>(); - LinkageChecker linkageChecker = new LinkageChecker(project, getTargetSettings()); - final Target.RootedCompilationUnits rootedCompilationUnits = target.getRootedCompilationUnits(); - problems.addAll(rootedCompilationUnits.getProblems()); - GraphMLWriter dependencyGraphWriter = - new GraphMLWriter(project.getDependencyGraph(), - rootedCompilationUnits.getUnits(), true, - linkageChecker); - BufferedOutputStream graphStream = new BufferedOutputStream(new FileOutputStream(dependencyGraphOutput)); - dependencyGraphWriter.writeToStream(graphStream, problemList); - problems.addAll(problemList); - } - } - - // see http://blog.bolinfest.com/2009/11/calling-closure-compiler-from-java.html - private boolean closureCompile(File outputFile, ProblemQuery problems) throws IOException - { - /* - * <arg value="--compilation_level=ADVANCED_OPTIMIZATIONS"/> <arg value= - * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/jquery-1.5.js" - * /> <arg value= - * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/svg.js" - * /> <arg value= - * "--externs=${falcon-sdk}/lib/google/closure-compiler/contrib/externs/jsTestDriver.js" - * /> <arg value="--formatting=PRETTY_PRINT"/> <arg - * value="--js=${falcon-sdk}/frameworks/javascript/goog/base.js"/> <arg - * value="--js=${build.target.js}"/> <arg - * value="--js_output_file=${build.target.compiled.js}"/> <arg - * value="--create_source_map=${build.target.compiled.map}"/> - */ - Compiler compiler = new Compiler(); - - CompilerOptions options = new CompilerOptions(); - - if (JSSharedData.CLOSURE_compilation_level.equals("ADVANCED_OPTIMIZATIONS")) - CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options); - else if (JSSharedData.CLOSURE_compilation_level.equals("WHITESPACE_ONLY")) - CompilationLevel.WHITESPACE_ONLY.setOptionsForCompilationLevel(options); - else - CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options); - - final List<JSSourceFile> extern = CommandLineRunner.getDefaultExterns(); - - final List<JSSourceFile> input = new ArrayList<JSSourceFile>(); - String googHome = System.getenv("GOOG_HOME"); - if (googHome == null || googHome.length() == 0) - System.out.println("GOOG_HOME not defined. Should point to goog folder containing base.js."); - - input.add(JSSourceFile.fromFile(googHome + "/base.js")); - - GoogDepsWriter dependencyGraphWriter = - new GoogDepsWriter(mainCU, outputFile.getParentFile()); - - ArrayList<String> files; - try { - files = dependencyGraphWriter.getListOfFiles(); - for (String fileName : files) - { - input.add(JSSourceFile.fromFile(fileName)); - } - } catch (InterruptedException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - if (JSSharedData.CLOSURE_create_source_map != null) - options.sourceMapOutputPath = JSSharedData.CLOSURE_create_source_map; - - if (JSSharedData.CLOSURE_formatting != null) - { - if (JSSharedData.CLOSURE_formatting.equals("PRETTY_PRINT")) - options.prettyPrint = true; - else if (JSSharedData.CLOSURE_formatting.equals("PRINT_INPUT_DELIMITER")) - options.prettyPrint = true; - else - throw new RuntimeException("Unknown formatting option: " + JSSharedData.CLOSURE_formatting); - } - else if (JSSharedData.DEBUG) - { - options.prettyPrint = true; - } - - try - { - // compile() returns a Result, but it is not needed here. - compiler.compile(extern, input, options); - - if (compiler.getErrorCount() == 0) - { - // The compiler is responsible for generating the compiled code; it is not - // accessible via the Result. - final String optimizedCode = compiler.toSource(); - BufferedOutputStream outputbuffer; - try { - String mainName = mainCU.getShortNames().get(0); - File outputFolder = outputFile.getParentFile(); - outputbuffer = new BufferedOutputStream(new FileOutputStream(outputFile)); - outputbuffer.write(optimizedCode.getBytes()); - outputbuffer.flush(); - outputbuffer.close(); - File htmlFile = new File(outputFolder.getAbsolutePath() + File.separator + mainName + ".example.html"); - outputbuffer = new BufferedOutputStream(new FileOutputStream(htmlFile)); - String html = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; - html += "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"; - html += "<head>\n"; - html += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"; - html += "<script type=\"text/javascript\" src=\"" + mainName + ".js" + "\" ></script>\n"; - html += "<script type=\"text/javascript\">\n"; - html += " var app = new " + mainName + "();\n"; - html += "</script>\n"; - html += "<title>" + mainName + "</title>\n"; - html += "</head>\n"; - html += "<body onload=\"app.start()\">\n"; - html += "</body>\n"; - html += "</html>\n"; - outputbuffer.write(html.getBytes()); - outputbuffer.flush(); - outputbuffer.close(); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - else if (problems != null) - { - final JSError[] errors = compiler.getErrors(); - for (JSError err : errors) - problems.add(new ClosureProblem(err)); - - return false; - } - } - - /* - * internal compiler error generated with optimize enabled compiling - * as3_enumerate.fla and fails to release the JS file - * http://watsonexp.corp.adobe.com/#bug=3047880 This is part #3 of the - * fix: The closure compiler throws RTEs on internal compiler errors, - * that don't get caught until they bubble up to MXMLJSC's scope. On - * their way out files remain unclosed and cause problems, because Flame - * cannot delete open files. The change below addresses this problem. - */ - catch (RuntimeException rte) - { - if (problems != null) - { - final ICompilerProblem problem = new InternalCompilerProblem(rte); - problems.add(problem); - return false; - } - } - return true; - } - - private void generateGoogDepsIfNeeded(File outputFolder) throws IOException, InterruptedException, ConfigurationException - { - final File depsOutput = new File(outputFolder.getAbsolutePath() + File.separator + mainCU.getShortNames().get(0) + "Deps.js"); - if (!JSSharedData.OPTIMIZE) - { - GoogDepsWriter dependencyGraphWriter = - new GoogDepsWriter(mainCU, outputFolder); - BufferedOutputStream graphStream = new BufferedOutputStream(new FileOutputStream(depsOutput)); - dependencyGraphWriter.writeToStream(graphStream); - graphStream.flush(); - graphStream.close(); - } - } - - /** - * Get the current project. - * - * @return project - */ - protected FlexProject getProject() - { - return this.project; - } - - /** - * sets up JavaScript specific options - * - * @throws IOException - * @throws InterruptedException - */ - protected void setupJS() throws IOException, InterruptedException - { - JSGeneratingReducer.validate(); - - JSSharedData.instance.reset(); - project.getSourceCompilationUnitFactory().addHandler(asFileHandler); - - if (isCompc()) - JSSharedData.COMPILER_NAME = "COMPJSC"; - else - JSSharedData.COMPILER_NAME = "MXMLJSC"; - - JSSharedData.instance.setVerbose(config.isVerbose()); - - JSSharedData.DEBUG = config.debug(); - JSSharedData.OPTIMIZE = !config.debug() && config.optimize(); - - // workaround for Falcon bug: getCompilerLibraryPath() is not supported yet. - /* - * if( config.getCompilerLibraryPath() != null ) { final List<String> - * libs = config.getCompilerLibraryPath(); final File libPaths[] = new - * File[libs.size()]; int nthPath = 0; for( String lib: libs ) { if( lib - * == null ) throw JSSharedData.backend.createException( - * "Invalid swc path in -compiler.library-path"); final String pathname - * = lib; final File libPath = new File(pathname); libPaths[nthPath++] = - * libPath; if( JSSharedData.SDK_PATH == null && - * libPath.getName().equals("browserglobal.swc")) { // - * ../sdk/frameworks/libs/browser/browserglobal.swc File sdkFolder = - * libPath.getParentFile(); if( sdkFolder != null ) { sdkFolder = - * sdkFolder.getParentFile(); if( sdkFolder != null ) { sdkFolder = - * sdkFolder.getParentFile(); if( sdkFolder != null ) { sdkFolder = - * sdkFolder.getParentFile(); if( sdkFolder != null ) - * JSSharedData.SDK_PATH = sdkFolder.getAbsolutePath(); } } } } } // - * Setting the library path into the project // causes an ISWC to be - * built for each SWC on the library path. // It also causes an - * MXMLManifestManager to be built for the project // from the manifest - * info in the project's SWCs. project.setInternalLibraryPath(libPaths); - * } - */ - - final Set<ICompilationUnit> compilationUnits = new HashSet<ICompilationUnit>(); - - // workaround for Falcon bug: getCompilerIncludeLibraries() is not supported yet. - /* - * if( config.getCompilerIncludeLibraries() != null ) { // see - * LibraryPathManager.computeUnitsToAdd() for( String swcSpec: - * config.getCompilerIncludeLibraries() ) { final ISWCManager swcManager - * = project.getWorkspace().getSWCManager(); final String swcFilePath = - * swcSpec; final ISWC swc = swcManager.get(new File(swcFilePath)); - * final boolean isExternal = true; for (final ISWCLibrary library : - * swc.getLibraries()) { for (final ISWCScript script : - * library.getScripts()) { // Multiple definition in a script share the - * same compilation unit // with the same ABC byte code block. final - * List<String> qnames = new - * ArrayList<String>(script.getDefinitions().size()); for (final String - * definitionQName : script.getDefinitions()) { final String defName = - * definitionQName.replace(":", "."); qnames.add(defName); //$NON-NLS-1$ - * //$NON-NLS-2$ } final ICompilationUnit cu = new SWCCompilationUnit( - * project, swc, library, script, qnames, isExternal); - * compilationUnits.add(cu); } } } } - */ - - // add builtins - final File builtin = new File(JSSharedData.BUILT_IN); - if (builtin.canRead()) - { - if (config.isVerbose()) - JSSharedData.instance.stdout("[abc] found: " + builtin); - ABCCompilationUnit cu = new ABCCompilationUnit(project, builtin.getPath()); - compilationUnits.add(cu); - } - - if (!compilationUnits.isEmpty()) - { - final List<ICompilationUnit> units = new LinkedList<ICompilationUnit>(); - units.addAll(compilationUnits); - project.addCompilationUnitsAndUpdateDefinitions(units); - - if (config.isVerbose()) - { - for (final ISWC swc : project.getLibraries()) - { - JSSharedData.instance.stdout(String.format("[lib] found library %s", swc.getSWCFile().getPath())); - } - } - } - - registerSWCs(project); - } - - /** - * Replaces FlexApplicationProject::buildSWF() - * - * @param applicationProject - * @param rootClassName - * @param problems - * @return - * @throws InterruptedException - */ - - private ISWF buildSWF(CompilerProject applicationProject, String rootClassName, ICompilationUnit mainCU, Collection<ICompilerProblem> problems) throws - InterruptedException, ConfigurationException, FileNotFoundException - { - Collection<ICompilerProblem> fatalProblems = applicationProject.getFatalProblems(); - if (!fatalProblems.isEmpty()) - { - problems.addAll(fatalProblems); - return null; - } - - return target.build(mainCU, problems); - } - - protected void verboseMessage(PrintStream strm, String s) - { - if (strm != null && config.isVerbose()) - strm.println(s); - } - - /** - * Scans JavaScript code for @requires tags and registers class - * dependencies. - * - * @param cu current CompilationUnit - * @param classDef ClassDefinition of the JavaScript code - * @param jsCode JavaScript code of the ClassDefinition. private static void - * registerDependencies( ICompilationUnit cu, ClassDefinition classDef, - * String jsCode ) { final JSSharedData sharedData = JSSharedData.instance; - * final String requiresTag = "@requires"; // extract @requires class names - * and register dependencies. if( jsCode.contains(requiresTag) ) { final - * String line = jsCode.substring( jsCode.indexOf(requiresTag) + - * requiresTag.length() ); for( String part : line.split(requiresTag) ) { - * final String[] names = part.split("\\s+"); if( names.length > 1 ) { final - * String depClassName = names[1]; ASProjectScope projectScope = - * (ASProjectScope)cu.getProject().getScope(); IDefinition depClassDef = - * projectScope.findDefinitionByName(depClassName); if(depClassDef != null) - * { sharedData.addDependency(classDef, depClassDef); } } } } } - */ - - public static Boolean addDependency(ICompilationUnit cu, String className, DependencyType dt) - { - if (JSGeneratingReducer.isReservedDataType(className)) - return false; - - final ICompilationUnit fromCU = cu; - final CompilerProject compilerProject = (CompilerProject)cu.getProject(); - final ASProjectScope projectScope = compilerProject.getScope(); - - final IDefinition classDef = projectScope.findDefinitionByName(className); - if (classDef == null) - return false; - - final ICompilationUnit toCU = projectScope.getCompilationUnitForDefinition(classDef); - if (fromCU == toCU) - return false; - - // sharedData.verboseMessage( "Adding dependency: " + className ); - compilerProject.addDependency(fromCU, toCU, dt); - JSSharedData.instance.registerDefinition(classDef); - return true; - } - - public static List<IDefinition> getDefinitions(ICompilationUnit cu, Boolean onlyClasses) throws InterruptedException - { - final List<IDefinition> classDefs = new ArrayList<IDefinition>(); - // populate the IDefinition to ClassDefinition map - final List<IDefinition> defs = cu.getDefinitionPromises(); - for (IDefinition def : defs) - { - if (def instanceof DefinitionPromise) - { - // see DefinitionPromise::getActualDefinition - final String qname = def.getQualifiedName(); - final IFileScopeRequestResult fileScopeRequestResult = cu.getFileScopeRequest().get(); - def = fileScopeRequestResult.getMainDefinition(qname); - } - - if (def != null && !onlyClasses || (def instanceof ClassDefinition)) - { - classDefs.add(def); - } - } - return classDefs; - } - - public static void registerSWCs(CompilerProject project) throws InterruptedException - { - final JSSharedData sharedData = JSSharedData.instance; - - // collect all SWCCompilationUnit in swcUnits - final List<ICompilationUnit> swcUnits = new ArrayList<ICompilationUnit>(); - for (ICompilationUnit cu : project.getCompilationUnits()) - { - if (cu instanceof SWCCompilationUnit) - swcUnits.add(cu); - - final List<IDefinition> defs = getDefinitions(cu, false); - for (IDefinition def : defs) - { - sharedData.registerDefinition(def); - } - } - - } - - protected String getFlexHomePath() - { - final String loadConfig = config.getLoadConfig(); - if (loadConfig == null || loadConfig.isEmpty()) - return null; - // throw new Error("Cannot find load configuration file: " + loadConfig.getPath() ); - - final File loadConfigFile = new File(loadConfig); - if (!loadConfigFile.isFile()) - return null; - // throw new Error("Cannot find load configuration file: " + loadConfigFile.getAbsolutePath() ); - - final File frameworksFolder = new File(loadConfigFile.getParent()); - if (!frameworksFolder.isDirectory()) - return null; - // throw new Error("Cannot find framework folder: " + frameworksFolder.getAbsolutePath() ); - - final String flexHome = frameworksFolder.getParent(); - if (flexHome == null || flexHome.isEmpty()) - return null; - // throw new Error("Cannot find FLEX_HOME environment variable."); - - return flexHome; - } - - protected JSCommandLineConfiguration getConfiguration() - { - if (config instanceof JSCommandLineConfiguration) - return (JSCommandLineConfiguration)config; - return null; - } - - public class ClosureProblem implements ICompilerProblem - { - private JSError m_error; - - public ClosureProblem(JSError error) - { - m_error = error; - } - - /** - * Returns a unique identifier for this type of problem. - * <p> - * Clients can use this identifier to look up, in a .properties file, a - * localized template string describing the problem. The template string - * can have named placeholders such as ${name} to be filled in, based on - * correspondingly-named fields in the problem instance. - * <p> - * Clients can also use this identifier to decide whether the problem is - * an error, a warning, or something else; for example, they might keep - * a list of error ids and a list of warning ids. - * <p> - * The unique identifier happens to be the fully-qualified classname of - * the problem class. - * - * @return A unique identifier for the type of problem. - */ - public String getID() - { - // Return the fully-qualified classname of the CompilerProblem subclass - // as a String to identify the type of problem that occurred. - return getClass().getName(); - } - - /** - * Gets the path of the file in which the problem occurred. - * - * @return The path of the source file, or null if unknown. - */ - public String getFilePath() - { - return m_error.sourceName; - } - - /** - * Gets the offset within the source buffer at which the problem starts. - * - * @return The starting offset, or -1 if unknown. - */ - public int getStart() - { - return m_error.getCharno(); - } - - /** - * Gets the offset within the source buffer at which the problem ends. - * - * @return The ending offset, or -1 if unknown. - */ - public int getEnd() - { - return -1; - } - - /** - * Gets the line number within the source buffer at which the problem - * starts. Line numbers start at 0, not 1. - * - * @return The line number, or -1 if unknown. - */ - public int getLine() - { - return m_error.lineNumber; - } - - /** - * Gets the column number within the source buffer at which the problem - * starts. Column numbers start at 0, not 1. - * - * @return The column number, of -1 if unknown. - */ - public int getColumn() - { - return -1; - } - - /** - * Returns a readable description of the problem, by substituting field - * values for named placeholders such as ${name} in the localized - * template. - * - * @param template A localized template string describing the problem, - * determined by the client from the problem ID. If this parameter is - * null, an English template string, stored as the DESCRIPTION of the - * problem class, will be used. - * @return A readable description of the problem. - */ - public String getDescription(String template) - { - return m_error.description; - } - - /** - * Compares this problem to another problem by path, line, and column so - * that problems can be sorted. - */ - final public int compareTo(final ICompilerProblem other) - { - if (getFilePath() != null && other.getSourcePath() != null) - { - final int pathCompare = getFilePath().compareTo(other.getSourcePath()); - if (pathCompare != 0) - return pathCompare; - } - else if (getFilePath() != null && other.getSourcePath() == null) - { - return 1; - } - else if (getFilePath() == null && other.getSourcePath() != null) - { - return -1; - } - - if (getLine() < other.getLine()) - return -1; - else if (getLine() > other.getLine()) - return 1; - - if (getColumn() < other.getColumn()) - return -1; - else if (getColumn() > other.getColumn()) - return 1; - - return 0; - } - - public int getAbsoluteEnd() - { - // TODO Auto-generated method stub - return 0; - } - - public int getAbsoluteStart() - { - // TODO Auto-generated method stub - return 0; - } - - public String getSourcePath() - { - // TODO Auto-generated method stub - return null; - } - - } -}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/ABCGeneratingReducer.java ---------------------------------------------------------------------- diff --git a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/ABCGeneratingReducer.java b/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/ABCGeneratingReducer.java deleted file mode 100644 index 624d992..0000000 --- a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/ABCGeneratingReducer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.flex.compiler.internal.as.codegen; - -public class ABCGeneratingReducer extends JSGeneratingReducer -{ - public ABCGeneratingReducer() - { - super(JSSharedData.instance); - } -} http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSClassDirectiveProcessor.java ---------------------------------------------------------------------- diff --git a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSClassDirectiveProcessor.java b/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSClassDirectiveProcessor.java deleted file mode 100644 index ebf8998..0000000 --- a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSClassDirectiveProcessor.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.flex.compiler.internal.as.codegen; - -import static org.apache.flex.abc.ABCConstants.*; - -import org.apache.flex.abc.ABCConstants; -import org.apache.flex.abc.visitors.IABCVisitor; -import org.apache.flex.abc.visitors.ITraitVisitor; -import org.apache.flex.abc.visitors.ITraitsVisitor; -import org.apache.flex.abc.semantics.MethodInfo; -import org.apache.flex.abc.semantics.Name; -import org.apache.flex.abc.semantics.Namespace; -import org.apache.flex.abc.semantics.Trait; -import org.apache.flex.abc.instructionlist.InstructionList; -import org.apache.flex.compiler.common.ASModifier; -import org.apache.flex.compiler.internal.as.codegen.ICodeGenerator.IConstantValue; -import org.apache.flex.compiler.internal.definitions.ClassDefinition; -import org.apache.flex.compiler.internal.definitions.DefinitionBase; -import org.apache.flex.compiler.internal.definitions.FunctionDefinition; -import org.apache.flex.compiler.internal.definitions.NamespaceDefinition; -import org.apache.flex.compiler.internal.semantics.SemanticUtils; -import org.apache.flex.compiler.internal.tree.as.ClassNode; -import org.apache.flex.compiler.internal.tree.as.FunctionNode; -import org.apache.flex.compiler.internal.tree.as.NamespaceNode; -import org.apache.flex.compiler.internal.tree.as.VariableNode; -import org.apache.flex.compiler.problems.StaticNamespaceDefinitionProblem; -import org.apache.flex.compiler.projects.ICompilerProject; -import org.apache.flex.compiler.tree.as.IASNode; -import org.apache.flex.compiler.tree.as.ICommonClassNode; - -/** - * A ClassDirectiveProcessor generates an ABC class from a ClassNode and its - * contents. JSClassDirectiveProcessor is derived from ClassDirectiveProcessor - * and adds workarounds necessary for FalconJS. Ideally FalconJS should use - * ClassDirectiveProcessor and retire JSClassDirectiveProcessor. This - * implementation is part of FalconJS. For more details on FalconJS see - * org.apache.flex.compiler.JSDriver. - */ -@SuppressWarnings("nls") -public class JSClassDirectiveProcessor extends ClassDirectiveProcessor -{ - JSGenerator m_generator; - - /** - * Instructions to place in the class' initializer. Note that these are part - * of the class itself, as opposed to the above instructions which create - * the class at the global scope. - */ - InstructionList looseInsns = new InstructionList(); - - /** - * Constructor. Initializes the ClassDirectiveProcessor and its associated - * AET data structures. - * - * @param c - the class' AST. - * @param enclosing_scope - the immediately enclosing lexical scope. - * @param emitter - the active ABC emitter. - */ - public JSClassDirectiveProcessor(JSGenerator generator, ClassNode c, LexicalScope enclosing_scope, IABCVisitor emitter) - { - this(generator, c, addDefinition(enclosing_scope.getProject(), c.getDefinition()), enclosing_scope, emitter); - } - - private static ClassDefinition addDefinition(ICompilerProject project, ClassDefinition cdef) - { - JSSharedData.instance.registerDefinition(cdef); - return cdef; - } - - /** - * Constructor. Initializes the ClassDirectiveProcessor and its associated - * AET data structures. - * - * @param class_definition - the class' definition - * @param enclosing_scope - the immediately enclosing lexical scope. - * @param emitter - the active ABC emitter. - */ - public JSClassDirectiveProcessor(JSGenerator generator, IASNode node, ClassDefinition class_definition, LexicalScope enclosing_scope, IABCVisitor emitter) - { - super((ICommonClassNode)node, class_definition, enclosing_scope, emitter); - m_generator = generator; - - /* - * // add explicit dependencies. final ICompilerProject project = - * classScope.getProject(); final ClassDefinition superclassDefinition = - * class_definition.resolveBaseClass( new ASDefinitionCache(project), - * new RecursionGuard(), classScope.getProblems()); if( - * superclassDefinition != null ) - * JSSharedData.instance.addDependency(class_definition, - * superclassDefinition); - */ - - generator.getReducer().setClassDefinition(enclosing_scope.getProject(), class_definition); - } - - /** - * Finish the class' definition. - */ - @Override - void finishClassDefinition() - { - // Create the class' constructor function. - if (this.ctorFunction != null /* || !iinitInsns.isEmpty() */) - { - MethodInfo mi = m_generator.generateFunction(this.ctorFunction, classScope, this.iinitInsns); - if (mi != null) - this.iinfo.iInit = mi; - - this.ctorFunction = null; - this.iinitInsns = new InstructionList(); - } - - // clear cinitInsns if there are no side effects - // by initializing the static members directly. - final String fullName = JSGeneratingReducer.createFullNameFromDefinition(classScope.getProject(), classDefinition); - if (!JSSharedData.instance.hasClassInit(fullName)) - cinitInsns = new InstructionList(); - - // support for class inits - // loose statement are now collected in looseInsns - if (!this.looseInsns.isEmpty()) - cinitInsns.addAll(looseInsns); - - // base class injects ABC if not empty and then NPEs. - // save our insns and give it an empty list then restore - InstructionList cinitHack = cinitInsns; - cinitInsns = new InstructionList(); - super.finishClassDefinition(); - cinitInsns = cinitHack; - - m_generator.getReducer().setClassDefinition(null, null); - } - - /** - * Declare a function. TODO: static vs. instance. - */ - @Override - void declareFunction(FunctionNode func) - { - func.parseFunctionBody(classScope.getProblems()); - - boolean is_constructor = func.isConstructor(); - - functionSemanticChecks(func); - - // Save the constructor function until - // we've seen all the instance variables - // that might need initialization. - if (is_constructor) - { - this.ctorFunction = func; - } - else - { - MethodInfo mi = m_generator.generateFunction(func, classScope, null); - ITraitVisitor tv; - - if (mi != null) - { - FunctionDefinition funcDef = func.getDefinition(); - Name funcName = funcDef.getMName(classScope.getProject()); - - if (func.hasModifier(ASModifier.STATIC)) - tv = ctraits.visitMethodTrait(functionTraitKind(func, TRAIT_Method), funcName, 0, mi); - else - { - tv = itraits.visitMethodTrait(functionTraitKind(func, TRAIT_Method), funcName, 0, mi); - if (funcDef.getNamespaceReference() instanceof NamespaceDefinition.IProtectedNamespaceDefinition) - this.iinfo.flags |= ABCConstants.CLASS_FLAG_protected; - } - - this.classScope.processMetadata(tv, funcDef.getAllMetaTags()); - - if (func.hasModifier(ASModifier.FINAL)) - tv.visitAttribute(Trait.TRAIT_FINAL, Boolean.TRUE); - if (func.hasModifier(ASModifier.OVERRIDE)) - tv.visitAttribute(Trait.TRAIT_OVERRIDE, Boolean.TRUE); - } - } - } - - /** - * Declare a variable. TODO: static vs. instance. - */ - @Override - void declareVariable(VariableNode var) - { - verifyVariableModifiers(var); - - DefinitionBase varDef = var.getDefinition(); - m_generator.getReducer().startDeclareVariable(varDef); - - boolean is_static = var.hasModifier(ASModifier.STATIC); - boolean is_const = SemanticUtils.isConst(var, classScope.getProject()); - // simple initializers for public/protected vars go right on prototype. - // the rest (all private vars), all "complex" initializers (like array) get - // initialized in the constructor - boolean needs_constructor_init = true; - - // generateConstantValue() returns null if no constant value - // can be generated, and null is the correct value for "no value." - IConstantValue constantValue = m_generator.generateConstantValue(var.getAssignedValueNode(), this.classScope.getProject()); - - // initializer is null if no constant value - // can be generated, and null is the correct value for "no value." - Object initializer = constantValue != null ? constantValue.getValue() : null; - - ITraitVisitor tv = declareVariable(var, varDef, is_static, is_const, initializer); - - this.classScope.processMetadata(tv, varDef.getAllMetaTags()); - - // Generate variable initializers and append them to the - // proper initialization list. - if (var.getChildCount() > 1) - { - // We need to put the correct traits visitor on the class' - // LexicalScope; the BURM may encounter variable declarations - // chained onto this one, and it will need the traits visitor to declare them. - - // Save the scope's current traits visitor (which should be null) - // and restore it - ITraitsVisitor saved_traits_visitor = this.classScope.traitsVisitor; - assert (saved_traits_visitor == null); - try - { - // the following line causes duplicate Traits. - // JSEmitter::emitTraits works around duplicate Traits by checking against - // a visitedTraits set. - this.classScope.traitsVisitor = (is_static) ? ctraits : itraits; - this.classScope.resetDebugInfo(); - InstructionList init_expression = m_generator.generateInstructions(var, CmcJSEmitter.__statement_NT, this.classScope); - if (init_expression != null && !init_expression.isEmpty()) - { - // final JSEmitter emitter = (JSEmitter)this.classScope.getEmitter(); - final String str = JSGeneratingReducer.instructionListToString(init_expression, true); - - if (str.contains(" = ")) - { - final String varInit = m_generator.getReducer().getVariableInitializer(varDef); - if (varInit != null && !varInit.isEmpty()) - { - // set the value of the slot trait. - final String varName = varDef.getBaseName(); - for (Trait t : this.classScope.traitsVisitor.getTraits()) - { - final byte kind = t.getKind(); - if (kind == TRAIT_Const || kind == TRAIT_Var) - { - boolean is_private = false; - final Name name = t.getNameAttr(Trait.TRAIT_NAME); - Namespace ns = name.getSingleQualifier(); - if (ns.getKind() == CONSTANT_PrivateNs) - is_private = true; - if (name.getBaseName().equals(varName)) - { - t.setAttr(Trait.SLOT_VALUE, varInit); - if (!is_private) - needs_constructor_init = false; - break; - } - } - } - - } - - if (is_static) - { - // see finishClassDefinition. - // We clear cinitInsns only if there are no side effects - // by initializing the static members directly. - // If varInit is null, or varInit is isEmpty() - // then we have side effects. - if (!init_expression.isEmpty()) - registerClassInit(var); - - cinitInsns.addAll(init_expression); - } - else if (needs_constructor_init) - iinitInsns.addAll(init_expression); - } - } - } - finally - { - this.classScope.traitsVisitor = saved_traits_visitor; - } - } - - m_generator.getReducer().endDeclareVariable(varDef); - } - - /** - * Ignore modifier nodes that are in the AST, but processed as attributes of - * the definition nodes. Other loose directives are processed as statements - * and added to the class' static init method. - */ - @Override - void processDirective(IASNode n) - { - switch (n.getNodeID()) - { - - case StaticID: - case FinalID: - case OverrideID: - case UseID: - break; - - case NamespaceID: - { - NamespaceNode ns = (NamespaceNode)n; - - if (ns.hasModifier(ASModifier.STATIC)) - { - this.classScope.addProblem(new StaticNamespaceDefinitionProblem(ns)); - } - else - { - try - { - this.classScope.traitsVisitor = itraits; - m_generator.generateInstructions(n, CmcEmitter.__statement_NT, this.classScope); - // assert(stmt_insns == null); - } - finally - { - this.classScope.traitsVisitor = null; - } - } - break; - } - default: - { - // support for class inits. - // loose statement are now collected in looseInsns - // Handle a loose statement. - InstructionList stmt_insns = m_generator.generateInstructions(n, CmcJSEmitter.__statement_NT, this.classScope); - if (stmt_insns != null) - { - if (looseInsns.size() == 0) - registerClassInit(n); - - looseInsns.addAll(stmt_insns); - } - break; - } - } - } - - private void registerClassInit(IASNode node) - { - final String fullName = JSGeneratingReducer.createFullNameFromDefinition(classScope.getProject(), classDefinition); - if (!fullName.equals(JSSharedData.JS_FRAMEWORK_NAME)) - { - JSSharedData.instance.registerClassInit(fullName); - m_generator.getReducer().warnClassInitPerformance(node); - m_generator.getReducer().setNeedsSecondPass(); - } - } -}