All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.CompilerOptions Maven / Gradle / Ivy

There is a newer version: 9.0.8
Show newest version
/*
 * Copyright 2009 The Closure Compiler Authors.
 *
 * Licensed 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 com.google.javascript.jscomp;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Ascii;
import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.primitives.Chars;
import com.google.javascript.jscomp.deps.ModuleLoader;
import com.google.javascript.jscomp.parsing.Config;
import com.google.javascript.jscomp.parsing.parser.FeatureSet;
import com.google.javascript.jscomp.resources.ResourceLoader;
import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.SourcePosition;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * Compiler options
 *
 * @author [email protected] (Nick Santos)
 */
public class CompilerOptions implements Serializable {
  // The number of characters after which we insert a line break in the code
  static final int DEFAULT_LINE_LENGTH_THRESHOLD = 500;

  static final char[] POLYMER_PROPERTY_RESERVED_FIRST_CHARS =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ$".toCharArray();
  static final char[] POLYMER_PROPERTY_RESERVED_NON_FIRST_CHARS = "_$".toCharArray();
  static final char[] ANGULAR_PROPERTY_RESERVED_FIRST_CHARS = {'$'};

  /**
   * A common enum for compiler passes that can run either globally or locally.
   */
  public enum Reach {
    ALL,
    LOCAL_ONLY,
    NONE;

    public boolean isOn() {
      return this != NONE;
    }

    public boolean includesGlobals() {
      return this == ALL;
    }
  }

  public enum PropertyCollapseLevel {
    ALL,
    NONE,
    MODULE_EXPORT
  }

  // TODO(nicksantos): All public properties of this class should be made
  // package-private, and have a public setter.

  /**
   * Should the compiled output start with "'use strict';"?
   */
  private Optional emitUseStrict = Optional.absent();

  /**
   * The JavaScript language version accepted.
   */
  private LanguageMode languageIn;

  /**
   * The JavaScript language version that should be produced.
   */
  private LanguageMode languageOut;

  /**
   * The builtin set of externs to be used
   */
  private Environment environment;

  /**
   * Instrument code for the purpose of collecting coverage data - restrict to coverage pass only,
   * and skip all other passes.
   */
  private boolean instrumentForCoverageOnly = false;

  public void setInstrumentForCoverageOnly(boolean instrumentForCoverageOnly) {
    this.instrumentForCoverageOnly = instrumentForCoverageOnly;
  }

  public boolean getInstrumentForCoverageOnly() {
    return instrumentForCoverageOnly;
  }

  @Deprecated
  public void setSkipTranspilationAndCrash(boolean value) {}

  /**
   * Sets the input sourcemap files, indexed by the JS files they refer to.
   *
   * @param inputSourceMaps the collection of input sourcemap files
   */
  public void setInputSourceMaps(final ImmutableMap inputSourceMaps) {
    this.inputSourceMaps = inputSourceMaps;
  }

  /**
   * Whether to infer consts. This should not be configurable by
   * external clients. This is a transitional flag for a new type
   * of const analysis.
   *
   * TODO(nicksantos): Remove this option.
   */
  boolean inferConsts = true;

  // TODO(tbreisacher): Remove this method after ctemplate issues are solved.
  public void setInferConst(boolean value) {
    inferConsts = value;
  }

  /**
   * Whether the compiler should assume that a function's "this" value
   * never needs coercion (for example in non-strict "null" or "undefined" will
   * be coerced to the global "this" and primitives to objects).
   */
  private boolean assumeStrictThis;

  private boolean allowHotswapReplaceScript = false;
  private boolean preserveDetailedSourceInfo = false;
  private boolean continueAfterErrors = false;

  public enum IncrementalCheckMode {
    /** Normal mode */
    OFF,

    /**
     * The compiler should generate an output file that represents the type-only interface
     * of the code being compiled.  This is useful for incremental type checking.
     */
    GENERATE_IJS,

    /**
     * The compiler should check type-only interface definitions generated above.
     */
    CHECK_IJS,
  }

  private IncrementalCheckMode incrementalCheckMode = IncrementalCheckMode.OFF;

  public void setIncrementalChecks(IncrementalCheckMode value) {
    incrementalCheckMode = value;
    switch (value) {
      case OFF:
        break;
      case GENERATE_IJS:
        setPreserveTypeAnnotations(true);
        setOutputJs(OutputJs.NORMAL);
        break;
      case CHECK_IJS:
        setChecksOnly(true);
        setOutputJs(OutputJs.SENTINEL);
        break;
    }
  }

  // TODO(tbreisacher): When this is false, report an error if there's a goog.provide
  // in an externs file.
  public boolean inIncrementalCheckMode() {
    return incrementalCheckMode != IncrementalCheckMode.OFF;
  }

  public boolean shouldGenerateTypedExterns() {
    return incrementalCheckMode == IncrementalCheckMode.GENERATE_IJS;
  }

  private Config.JsDocParsing parseJsDocDocumentation = Config.JsDocParsing.TYPES_ONLY;

  private boolean printExterns;

  void setPrintExterns(boolean printExterns) {
    this.printExterns = printExterns;
  }

  boolean shouldPrintExterns() {
    return this.printExterns || incrementalCheckMode == IncrementalCheckMode.GENERATE_IJS;
  }

  /**
   * Even if checkTypes is disabled, clients such as IDEs might want to still infer types.
   */
  boolean inferTypes;

  private boolean useNewTypeInference;

  /**
   * Several passes after type checking use type information. We have converted all these passes
   * to use TypeI, and most users of NTI use NTI types throughout their compilation.
   * But there are a few NTI users that still use the old mode, where OTI runs after NTI
   * and the optimizations see the old types. We plan to switch these users to NTI-only builds
   * and delete this option.
   */
  private boolean runOTIafterNTI = false;

  /**
   * Relevant only when {@link #useNewTypeInference} is true, where we normally disable OTI errors.
   * If you want both NTI and OTI errors in this case, set to true.
   * E.g. if using using a warnings guard to filter NTI or OTI warnings in new or legacy code,
   * respectively.
   * This will be removed when NTI entirely replaces OTI.
   */
  boolean reportOTIErrorsUnderNTI = false;

  /**
   * Run type checking natively on the subset of ES6 features that we are able to typecheck
   * natively, and then transpile them after NTI.
   * Doing this currently causes reordering of {@link LateEs6ToEs3Converter} pass
   * and {@link Es6RewriteBlockScopedDeclaration} pass, which has the potential to break builds.
   * This option should eventually be turned on by default and removed.
   */
  private boolean typeCheckEs6Natively = false;

  /**
   * Configures the compiler to skip as many passes as possible.
   * If transpilation is requested, it will be run, but all others passes will be skipped.
   */
  boolean skipNonTranspilationPasses;

  /**
   * Configures the compiler to run expensive validity checks after
   * every pass. Only intended for internal development.
   */
  DevMode devMode;

  /**
   * Configures the compiler to log a hash code of the AST after
   * every pass. Only intended for internal development.
   */
  private boolean checkDeterminism;

  //--------------------------------
  // Input Options
  //--------------------------------

  DependencyOptions dependencyOptions = new DependencyOptions();

  /** Returns localized replacement for MSG_* variables */
  public MessageBundle messageBundle = null;

  //--------------------------------
  // Checks
  //--------------------------------

  /** Checks that all symbols are defined */
  // TODO(tbreisacher): Remove this and deprecate the corresponding setter.
  public boolean checkSymbols;

  /** Checks for suspicious statements that have no effect */
  public boolean checkSuspiciousCode;

  /** Checks types on expressions */
  public boolean checkTypes;

  public CheckLevel checkGlobalNamesLevel;

  /**
   * Checks the integrity of references to qualified global names.
   * (e.g. "a.b")
   */
  public void setCheckGlobalNamesLevel(CheckLevel level) {
    checkGlobalNamesLevel = level;
  }

  @Deprecated
  public CheckLevel brokenClosureRequiresLevel;

  /**
   * Sets the check level for bad Closure require calls.
   * Do not use; this should always be an error.
   */
  @Deprecated
  public void setBrokenClosureRequiresLevel(CheckLevel level) {
    brokenClosureRequiresLevel = level;
  }

  public CheckLevel checkGlobalThisLevel;

  /**
   * Checks for certain uses of the {@code this} keyword that are considered
   * unsafe because they are likely to reference the global {@code this}
   * object unintentionally.
   *
   * If this is off, but collapseProperties is on, then the compiler will
   * usually ignore you and run this check anyways.
   */
  public void setCheckGlobalThisLevel(CheckLevel level) {
    this.checkGlobalThisLevel = level;
  }

  public CheckLevel checkMissingGetCssNameLevel;

  /**
   * Checks that certain string literals only appear in strings used as
   * goog.getCssName arguments.
   */
  public void setCheckMissingGetCssNameLevel(CheckLevel level) {
    this.checkMissingGetCssNameLevel = level;
  }

  /**
   * Regex of string literals that may only appear in goog.getCssName arguments.
   */
  public String checkMissingGetCssNameBlacklist;

  /**
   * A set of extra annotation names which are accepted and silently ignored
   * when encountered in a source file. Defaults to null which has the same
   * effect as specifying an empty set.
   */
  Set extraAnnotationNames;

  /** @deprecated No longer has any effect. */
  @Deprecated
  public enum DisposalCheckingPolicy {
    /**
     * Don't check any disposal.
     */
    OFF,

    /**
     * Default/conservative disposal checking.
     */
    ON,

    /**
     * Aggressive disposal checking.
     */
    AGGRESSIVE,
  }

  /** @deprecated No longer has any effect. */
  @Deprecated
  public void setCheckEventfulObjectDisposalPolicy(DisposalCheckingPolicy policy) {}

  /** @deprecated No longer has any effect. */
  @Deprecated
  public DisposalCheckingPolicy getCheckEventfulObjectDisposalPolicy() {
    return DisposalCheckingPolicy.OFF;
  }

  /**
   * Used for projects that are not well maintained, but are still used.
   * Does not allow promoting warnings to errors, and disables some potentially
   * risky optimizations.
   */
  boolean legacyCodeCompile = false;

  public boolean getLegacyCodeCompile() {
    return this.legacyCodeCompile;
  }

  public void setLegacyCodeCompile(boolean legacy) {
    this.legacyCodeCompile = legacy;
  }

  // TODO(bradfordcsmith): Investigate how can we use multi-threads as default.
  int numParallelThreads = 1;

  /**
   * Sets the level of parallelism for compilation passes that can exploit multi-threading.
   *
   * 

Some compiler passes may take advantage of multi-threading, for example, parsing inputs. * This sets the level of parallelism. The compiler will not start more than this number of * threads. * * @param parallelism up to this number of parallel threads may be created. */ public void setNumParallelThreads(int parallelism) { numParallelThreads = parallelism; } //-------------------------------- // Optimizations //-------------------------------- /** Prefer commas over semicolons when doing statement fusion */ boolean aggressiveFusion; /** Folds constants (e.g. (2 + 3) to 5) */ public boolean foldConstants; /** Remove assignments to values that can not be referenced */ public boolean deadAssignmentElimination; /** Inlines constants (symbols that are all CAPS) */ public boolean inlineConstantVars; /** * For projects that want to avoid the creation of giant functions after * inlining. */ int maxFunctionSizeAfterInlining; static final int UNLIMITED_FUN_SIZE_AFTER_INLINING = -1; /** More aggressive function inlining */ boolean assumeClosuresOnlyCaptureReferences; /** Inlines properties */ private boolean inlineProperties; /** Move code to a deeper module */ public boolean crossModuleCodeMotion; /** * Don't generate stub functions when moving methods deeper. * * Note, switching on this option may break existing code that depends on * enumerating prototype methods for mixin behavior, such as goog.mixin or * goog.object.extend, since the prototype assignments will be removed from * the parent module and moved to a later module. **/ boolean crossModuleCodeMotionNoStubMethods; /** * Whether when module B depends on module A and module B declares a symbol, * this symbol can be seen in A after B has been loaded. This is often true, * but may not be true when loading code using nested eval. */ boolean parentModuleCanSeeSymbolsDeclaredInChildren; /** Merge two variables together as one. */ public boolean coalesceVariableNames; /** Move methods to a deeper module */ public boolean crossModuleMethodMotion; /** Inlines trivial getters */ boolean inlineGetters; /** Inlines variables */ public boolean inlineVariables; /** Inlines variables */ boolean inlineLocalVariables; // TODO(user): This is temporary. Once flow sensitive inlining is stable // Remove this. public boolean flowSensitiveInlineVariables; /** Removes code associated with unused global names */ public boolean smartNameRemoval; /** Removes code associated with unused global names */ boolean extraSmartNameRemoval; /** Removes code that will never execute */ public boolean removeDeadCode; public enum ExtractPrototypeMemberDeclarationsMode { OFF, USE_GLOBAL_TEMP, USE_IIFE } /** Extracts common prototype member declarations */ ExtractPrototypeMemberDeclarationsMode extractPrototypeMemberDeclarations; /** Removes unused member prototypes */ public boolean removeUnusedPrototypeProperties; /** Tells AnalyzePrototypeProperties it can remove externed props. */ public boolean removeUnusedPrototypePropertiesInExterns; /** Removes unused member properties */ public boolean removeUnusedClassProperties; /** Removes unused constructor properties */ boolean removeUnusedConstructorProperties; /** Removes unused variables */ public boolean removeUnusedVars; /** Removes unused variables in local scope. */ public boolean removeUnusedLocalVars; /** Collapses multiple variable declarations into one */ public boolean collapseVariableDeclarations; /** * Collapses anonymous function declarations into named function * declarations */ public boolean collapseAnonymousFunctions; /** * If set to a non-empty set, those strings literals will be aliased to a * single global instance per string, to avoid creating more objects than * necessary. */ public Set aliasableStrings; /** * A blacklist in the form of a regular expression to block strings that * contains certain words from being aliased. * If the value is the empty string, no words are blacklisted. */ public String aliasStringsBlacklist; /** * Aliases all string literals to global instances, to avoid creating more * objects than necessary (if true, overrides any set of strings passed in * to aliasableStrings) */ public boolean aliasAllStrings; /** Print string usage as part of the compilation log. */ boolean outputJsStringUsage; /** Converts quoted property accesses to dot syntax (a['b'] → a.b) */ public boolean convertToDottedProperties; /** Reduces the size of common function expressions. */ public boolean rewriteFunctionExpressions; /** * Remove unused parameters from call sites. */ public boolean optimizeCalls; /** * Provide formal names for elements of arguments array. */ public boolean optimizeArgumentsArray; /** Use type information to enable additional optimization opportunities. */ boolean useTypesForLocalOptimization; boolean useSizeHeuristicToStopOptimizationLoop = true; /** * Do up to this many iterations of the optimization loop. * Setting this field to some small number, say 3 or 4, allows a large project to build faster, * but sacrifice some code size. */ int optimizationLoopMaxIterations; //-------------------------------- // Renaming //-------------------------------- /** Controls which variables get renamed. */ public VariableRenamingPolicy variableRenaming; /** Controls which properties get renamed. */ PropertyRenamingPolicy propertyRenaming; /** Controls label renaming. */ public boolean labelRenaming; /** Reserve property names on the global this object. */ public boolean reserveRawExports; /** Should shadow variable names in outer scope. */ boolean shadowVariables; /** * Use a renaming heuristic with better stability across source * changes. With this option each symbol is more likely to receive * the same name between builds. The cost may be a slight increase * in code size. */ boolean preferStableNames; /** * Generate pseudo names for variables and properties for debugging purposes. */ public boolean generatePseudoNames; /** Specifies a prefix for all globals */ public String renamePrefix; /** * Specifies the name of an object that will be used to store all non-extern * globals. */ public String renamePrefixNamespace; /** * Used by tests of the RescopeGlobalSymbols pass to avoid having declare 2 * modules in simple cases. */ boolean renamePrefixNamespaceAssumeCrossModuleNames = false; void setRenamePrefixNamespaceAssumeCrossModuleNames(boolean assume) { renamePrefixNamespaceAssumeCrossModuleNames = assume; } private PropertyCollapseLevel collapsePropertiesLevel; /** Flattens multi-level property names (e.g. a$b = x) */ public boolean shouldCollapseProperties() { return collapsePropertiesLevel != PropertyCollapseLevel.NONE; } public PropertyCollapseLevel getPropertyCollapseLevel() { return collapsePropertiesLevel; } /** Split object literals into individual variables when possible. */ boolean collapseObjectLiterals; public void setCollapseObjectLiterals(boolean enabled) { collapseObjectLiterals = enabled; } /** * Devirtualize prototype method by rewriting them to be static calls that * take the this pointer as their first argument */ public boolean devirtualizePrototypeMethods; /** * Use @nosideeffects annotations, function bodies and name graph * to determine if calls have side effects. Requires --check_types. */ public boolean computeFunctionSideEffects; /** * Where to save debug report for compute function side effects. */ String debugFunctionSideEffectsPath; /** * Rename private properties to disambiguate between unrelated fields based on * the coding convention. */ boolean disambiguatePrivateProperties; /** * Rename properties to disambiguate between unrelated fields based on * type information. */ private boolean disambiguateProperties; /** Rename unrelated properties to the same name to reduce code size. */ private boolean ambiguateProperties; /** Input sourcemap files, indexed by the JS files they refer to */ ImmutableMap inputSourceMaps; /** Give anonymous functions names for easier debugging */ public AnonymousFunctionNamingPolicy anonymousFunctionNaming; /** Input anonymous function renaming map. */ VariableMap inputAnonymousFunctionNamingMap; /** * Input variable renaming map. *

During renaming, the compiler uses this map and the inputPropertyMap to * try to preserve renaming mappings from a previous compilation. * The application is delta encoding: keeping the diff between consecutive * versions of one's code small. * The compiler does NOT guarantee to respect these maps; projects should not * use these maps to prevent renaming or to select particular names. * Point questioners to this post: * http://closuretools.blogspot.com/2011/01/property-by-any-other-name-part-3.html */ VariableMap inputVariableMap; /** Input property renaming map. */ VariableMap inputPropertyMap; /** Whether to export test functions. */ public boolean exportTestFunctions; /** Whether to declare globals declared in externs as properties on window */ boolean declaredGlobalExternsOnWindow; /** Shared name generator */ NameGenerator nameGenerator; public void setNameGenerator(NameGenerator nameGenerator) { this.nameGenerator = nameGenerator; } //-------------------------------- // Special-purpose alterations //-------------------------------- /** * Replace UI strings with chrome.i18n.getMessage calls. * Used by Chrome extensions/apps. */ boolean replaceMessagesWithChromeI18n; String tcProjectId; public void setReplaceMessagesWithChromeI18n( boolean replaceMessagesWithChromeI18n, String tcProjectId) { if (replaceMessagesWithChromeI18n && messageBundle != null && !(messageBundle instanceof EmptyMessageBundle)) { throw new RuntimeException("When replacing messages with" + " chrome.i18n.getMessage, a message bundle should not be specified."); } this.replaceMessagesWithChromeI18n = replaceMessagesWithChromeI18n; this.tcProjectId = tcProjectId; } /** Inserts run-time type assertions for debugging. */ boolean runtimeTypeCheck; /** * A JS function to be used for logging run-time type assertion * failures. It will be passed the warning as a string and the * faulty expression as arguments. */ String runtimeTypeCheckLogFunction; /** A CodingConvention to use during the compile. */ private CodingConvention codingConvention; @Nullable public String syntheticBlockStartMarker; @Nullable public String syntheticBlockEndMarker; /** Compiling locale */ public String locale; /** Sets the special "COMPILED" value to true */ public boolean markAsCompiled; /** Processes goog.provide() and goog.require() calls */ public boolean closurePass; /** Do not strip goog.provide()/goog.require() calls from the code. */ private boolean preserveClosurePrimitives; /** Processes AngularJS-specific annotations */ boolean angularPass; /** If non-null, processes Polymer code */ @Nullable Integer polymerVersion; /** Processes cr.* functions */ private boolean chromePass; /** Processes the output of the Dart Dev Compiler */ boolean dartPass; /** Processes the output of J2CL */ J2clPassMode j2clPassMode; /** Remove goog.abstractMethod assignments and @abstract methods. */ boolean removeAbstractMethods; /** Remove methods that only make a super call without changing the arguments. */ boolean removeSuperMethods; /** Remove goog.asserts calls. */ boolean removeClosureAsserts; /** Remove J2CL assert calls. */ boolean removeJ2clAsserts = true; /** Gather CSS names (requires closurePass) */ public boolean gatherCssNames; /** Names of types to strip */ public Set stripTypes; /** Name suffixes that determine which variables and properties to strip */ public Set stripNameSuffixes; /** Name prefixes that determine which variables and properties to strip */ public Set stripNamePrefixes; /** Qualified type name prefixes that determine which types to strip */ public Set stripTypePrefixes; /** Custom passes */ protected transient Multimap customPasses; /** Mark no side effect calls */ public boolean markNoSideEffectCalls; /** Replacements for @defines. Will be Boolean, Numbers, or Strings */ private Map defineReplacements; /** What kind of processing to do for goog.tweak functions. */ private TweakProcessing tweakProcessing; /** Replacements for tweaks. Will be Boolean, Numbers, or Strings */ private Map tweakReplacements; /** Move top-level function declarations to the top */ public boolean moveFunctionDeclarations; /** Instrumentation template to use with #recordFunctionInformation */ public Instrumentation instrumentationTemplate; String appNameStr; /** * App identifier string for use by the instrumentation template's * app_name_setter. @see #instrumentationTemplate */ public void setAppNameStr(String appNameStr) { this.appNameStr = appNameStr; } /** Record function information */ public boolean recordFunctionInformation; boolean checksOnly; static enum OutputJs { // Don't output anything. NONE, // Output a "sentinel" file containing just a comment. SENTINEL, // Output the compiled JS. NORMAL, } OutputJs outputJs; public boolean generateExports; // TODO(dimvar): generate-exports should always run after typechecking. // If it runs before, it adds a bunch of properties to Object, which masks // many type warnings. Cleanup all clients and remove this. boolean generateExportsAfterTypeChecking; boolean exportLocalPropertyDefinitions; /** Map used in the renaming of CSS class names. */ public CssRenamingMap cssRenamingMap; /** Whitelist used in the renaming of CSS class names. */ Set cssRenamingWhitelist; /** Process instances of goog.testing.ObjectPropertyString. */ boolean processObjectPropertyString; /** Replace id generators */ boolean replaceIdGenerators = true; // true by default for legacy reasons. /** Id generators to replace. */ ImmutableMap idGenerators; /** Hash function to use for xid generation. */ Xid.HashFunction xidHashFunction; /** * A previous map of ids (serialized to a string by a previous compile). * This will be used as a hint during the ReplaceIdGenerators pass, which * will attempt to reuse the same ids. */ String idGeneratorsMapSerialized; /** Configuration strings */ List replaceStringsFunctionDescriptions; String replaceStringsPlaceholderToken; // A list of strings that should not be used as replacements Set replaceStringsReservedStrings; // A previous map of replacements to strings. VariableMap replaceStringsInputMap; /** List of properties that we report invalidation errors for. */ Map propertyInvalidationErrors; /** Transform AMD to CommonJS modules. */ boolean transformAMDToCJSModules = false; /** Rewrite CommonJS modules so that they can be concatenated together. */ boolean processCommonJSModules = false; /** CommonJS module prefix. */ List moduleRoots = ImmutableList.of(ModuleLoader.DEFAULT_FILENAME_PREFIX); /** Rewrite polyfills. */ boolean rewritePolyfills = false; /** Runtime libraries to always inject. */ List forceLibraryInjection = ImmutableList.of(); /** Runtime libraries to never inject. */ boolean preventLibraryInjection = false; boolean assumeForwardDeclaredForMissingTypes = false; /** * If {@code true}, considers all missing types to be forward declared (useful for partial * compilation). */ public void setAssumeForwardDeclaredForMissingTypes( boolean assumeForwardDeclaredForMissingTypes) { this.assumeForwardDeclaredForMissingTypes = assumeForwardDeclaredForMissingTypes; } //-------------------------------- // Output options //-------------------------------- /** Do not strip closure-style type annotations from code. */ public boolean preserveTypeAnnotations; /** Output in pretty indented format */ private boolean prettyPrint; /** Line break the output a bit more aggressively */ public boolean lineBreak; /** Prefer line breaks at end of file */ public boolean preferLineBreakAtEndOfFile; /** Prints a separator comment before each JS script */ public boolean printInputDelimiter; /** The string to use as the separator for printInputDelimiter */ public String inputDelimiter = "// Input %num%"; /** Whether to write keyword properties as foo['class'] instead of foo.class; needed for IE8. */ private boolean quoteKeywordProperties; boolean preferSingleQuotes; /** * Normally, when there are an equal number of single and double quotes * in a string, the compiler will use double quotes. Set this to true * to prefer single quotes. */ public void setPreferSingleQuotes(boolean enabled) { this.preferSingleQuotes = enabled; } boolean trustedStrings; /** * Some people want to put arbitrary user input into strings, which are then * run through the compiler. These scripts are then put into HTML. * By default, we assume strings are untrusted. If the compiler is run * from the command-line, we assume that strings are trusted. */ public void setTrustedStrings(boolean yes) { trustedStrings = yes; } private boolean allowMethodCallDecomposing; /** * See https://github.com/google/closure-compiler/wiki/FAQ#i-get-an-undecomposable-expression-error-for-my-yield-or-await-expression-what-do-i-do */ boolean allowMethodCallDecomposing() { return allowMethodCallDecomposing; } /** * Setting this to true indicates that it's safe to rewrite x.y() as: fn = x.y; fn.call(x); * This should be false if supporting IE 8 or IE 9 is necessary. * * See https://github.com/google/closure-compiler/wiki/FAQ#i-get-an-undecomposable-expression-error-for-my-yield-or-await-expression-what-do-i-do */ public void setAllowMethodCallDecomposing(boolean value) { this.allowMethodCallDecomposing = value; } // Should only be used when debugging compiler bugs. boolean printSourceAfterEachPass; // Used to narrow down the printed source when overall input size is large. If these are both // empty the entire source is printed. List filesToPrintAfterEachPassRegexList = ImmutableList.of(); List modulesToPrintAfterEachPassRegexList = ImmutableList.of(); public void setPrintSourceAfterEachPass(boolean printSource) { this.printSourceAfterEachPass = printSource; } public void setFilesToPrintAfterEachPassRegexList(List filePathRegexList) { this.filesToPrintAfterEachPassRegexList = filePathRegexList; } public void setModulesToPrintAfterEachPassRegexList(List modulePathRegexList) { this.modulesToPrintAfterEachPassRegexList = modulePathRegexList; } String reportPath; /** Where to save a report of global name usage */ public void setReportPath(String reportPath) { this.reportPath = reportPath; } private TracerMode tracer; public TracerMode getTracerMode() { return tracer; } // NOTE: Timing information will not be printed if compiler.disableThreads() is called! public void setTracerMode(TracerMode mode) { this.tracer = mode; } private PrintStream tracerOutput; PrintStream getTracerOutput() { return tracerOutput; } public void setTracerOutput(PrintStream out) { tracerOutput = out; } private boolean colorizeErrorOutput; public ErrorFormat errorFormat; private ComposeWarningsGuard warningsGuard = new ComposeWarningsGuard(); int summaryDetailLevel = 1; int lineLengthThreshold = DEFAULT_LINE_LENGTH_THRESHOLD; /** * Whether to use the original names of nodes in the code output. This option is only really * useful when using the compiler to print code meant to check in to source. */ boolean useOriginalNamesInOutput = false; //-------------------------------- // Special Output Options //-------------------------------- /** * Whether the exports should be made available via {@link Result} after * compilation. This is implicitly true if {@link #externExportsPath} is set. */ private boolean externExports; /** The output path for the created externs file. */ String externExportsPath; //-------------------------------- // Debugging Options //-------------------------------- /** The output path for the source map. */ public String sourceMapOutputPath; /** The detail level for the generated source map. */ public SourceMap.DetailLevel sourceMapDetailLevel = SourceMap.DetailLevel.ALL; /** The source map file format */ public SourceMap.Format sourceMapFormat = SourceMap.Format.DEFAULT; /** * Whether to parse inline source maps. */ boolean parseInlineSourceMaps = true; /** * Whether to apply input source maps to the output, i.e. map back to original inputs from * input files that have source maps applied to them. */ boolean applyInputSourceMaps = false; /** * Whether to resolve source mapping annotations. Cannot do this in an appengine or js environment * since we don't have access to the filesystem. */ boolean resolveSourceMapAnnotations = true; public List sourceMapLocationMappings = Collections.emptyList(); /** * Whether to include full file contents in the source map. */ boolean sourceMapIncludeSourcesContent = false; /** * Charset to use when generating code. If null, then output ASCII. */ transient Charset outputCharset; /** * Transitional option. */ boolean enforceAccessControlCodingConventions; /** * When set, assume that apparently side-effect free code is meaningful. */ private boolean protectHiddenSideEffects; /** * When enabled, assume that apparently side-effect free code is meaningful. */ public void setProtectHiddenSideEffects(boolean enable) { this.protectHiddenSideEffects = enable; } /** * Whether or not the compiler should wrap apparently side-effect free code * to prevent it from being removed */ public boolean shouldProtectHiddenSideEffects() { return protectHiddenSideEffects && !checksOnly && !allowHotswapReplaceScript; } /** * Data holder Alias Transformation information accumulated during a compile. */ private transient AliasTransformationHandler aliasHandler; /** * Handler for compiler warnings and errors. */ transient ErrorHandler errorHandler; /** * Instrument code for the purpose of collecting coverage data. */ public boolean instrumentForCoverage; /** Instrument branch coverage data - valid only if instrumentForCoverage is True */ public boolean instrumentBranchCoverage; String instrumentationTemplateFile; /** * List of conformance configs to use in CheckConformance. * *

The first entry of this list is always the Global ConformanceConfig */ private ImmutableList conformanceConfigs = ImmutableList.of(ResourceLoader.loadGlobalConformance(CompilerOptions.class)); /** * For use in {@link CompilationLevel#WHITESPACE_ONLY} mode, when using goog.module. */ boolean wrapGoogModulesForWhitespaceOnly = true; public void setWrapGoogModulesForWhitespaceOnly(boolean enable) { this.wrapGoogModulesForWhitespaceOnly = enable; } /** * Print all configuration options to stderr after the compiler is initialized. */ boolean printConfig = false; /** * Are the input files written for strict mode? */ private Optional isStrictModeInput = Optional.absent(); /** Which algorithm to use for locating ES6 and CommonJS modules */ ModuleLoader.ResolutionMode moduleResolutionMode; /** Which entries to look for in package.json files when processing modules */ List packageJsonEntryNames; /** * Should the compiler print its configuration options to stderr when they are initialized? * *

Default {@code false}. */ public void setPrintConfig(boolean printConfig) { this.printConfig = printConfig; } /** * Initializes compiler options. All options are disabled by default. * * Command-line frontends to the compiler should set these properties * like a builder. */ public CompilerOptions() { // Accepted language languageIn = LanguageMode.ECMASCRIPT_2017; languageOut = LanguageMode.NO_TRANSPILE; // Which environment to use environment = Environment.BROWSER; // Modules moduleResolutionMode = ModuleLoader.ResolutionMode.BROWSER; packageJsonEntryNames = ImmutableList.of("browser", "module", "main"); // Checks skipNonTranspilationPasses = false; devMode = DevMode.OFF; checkDeterminism = false; checkSymbols = false; checkSuspiciousCode = false; checkTypes = false; checkGlobalNamesLevel = CheckLevel.OFF; brokenClosureRequiresLevel = CheckLevel.ERROR; checkGlobalThisLevel = CheckLevel.OFF; checkMissingGetCssNameLevel = CheckLevel.OFF; checkMissingGetCssNameBlacklist = null; computeFunctionSideEffects = false; extraAnnotationNames = null; // Optimizations foldConstants = false; coalesceVariableNames = false; deadAssignmentElimination = false; inlineConstantVars = false; inlineFunctionsLevel = Reach.NONE; maxFunctionSizeAfterInlining = UNLIMITED_FUN_SIZE_AFTER_INLINING; assumeStrictThis = false; assumeClosuresOnlyCaptureReferences = false; inlineProperties = false; crossModuleCodeMotion = false; parentModuleCanSeeSymbolsDeclaredInChildren = false; crossModuleMethodMotion = false; inlineGetters = false; inlineVariables = false; inlineLocalVariables = false; smartNameRemoval = false; extraSmartNameRemoval = false; removeDeadCode = false; extractPrototypeMemberDeclarations = ExtractPrototypeMemberDeclarationsMode.OFF; removeUnusedPrototypeProperties = false; removeUnusedPrototypePropertiesInExterns = false; removeUnusedClassProperties = false; removeUnusedConstructorProperties = false; removeUnusedVars = false; removeUnusedLocalVars = false; collapseVariableDeclarations = false; collapseAnonymousFunctions = false; aliasableStrings = Collections.emptySet(); aliasStringsBlacklist = ""; aliasAllStrings = false; outputJsStringUsage = false; convertToDottedProperties = false; rewriteFunctionExpressions = false; // Renaming variableRenaming = VariableRenamingPolicy.OFF; propertyRenaming = PropertyRenamingPolicy.OFF; labelRenaming = false; generatePseudoNames = false; shadowVariables = false; preferStableNames = false; renamePrefix = null; collapsePropertiesLevel = PropertyCollapseLevel.NONE; collapseObjectLiterals = false; devirtualizePrototypeMethods = false; disambiguateProperties = false; ambiguateProperties = false; anonymousFunctionNaming = AnonymousFunctionNamingPolicy.OFF; exportTestFunctions = false; declaredGlobalExternsOnWindow = true; nameGenerator = new DefaultNameGenerator(); // Alterations runtimeTypeCheck = false; runtimeTypeCheckLogFunction = null; syntheticBlockStartMarker = null; syntheticBlockEndMarker = null; locale = null; markAsCompiled = false; closurePass = false; preserveClosurePrimitives = false; angularPass = false; polymerVersion = null; dartPass = false; j2clPassMode = J2clPassMode.AUTO; removeAbstractMethods = false; removeSuperMethods = false; removeClosureAsserts = false; stripTypes = Collections.emptySet(); stripNameSuffixes = Collections.emptySet(); stripNamePrefixes = Collections.emptySet(); stripTypePrefixes = Collections.emptySet(); customPasses = null; markNoSideEffectCalls = false; defineReplacements = new HashMap<>(); tweakProcessing = TweakProcessing.OFF; tweakReplacements = new HashMap<>(); moveFunctionDeclarations = false; appNameStr = ""; recordFunctionInformation = false; checksOnly = false; outputJs = OutputJs.NORMAL; generateExports = false; generateExportsAfterTypeChecking = true; exportLocalPropertyDefinitions = false; cssRenamingMap = null; cssRenamingWhitelist = null; processObjectPropertyString = false; idGenerators = ImmutableMap.of(); replaceStringsFunctionDescriptions = Collections.emptyList(); replaceStringsPlaceholderToken = ""; replaceStringsReservedStrings = Collections.emptySet(); propertyInvalidationErrors = new HashMap<>(); inputSourceMaps = ImmutableMap.of(); // Instrumentation instrumentationTemplate = null; // instrument functions instrumentForCoverage = false; // instrument lines instrumentBranchCoverage = false; // instrument branches instrumentationTemplateFile = ""; // Output preserveTypeAnnotations = false; printInputDelimiter = false; prettyPrint = false; lineBreak = false; preferLineBreakAtEndOfFile = false; reportPath = null; tracer = TracerMode.OFF; colorizeErrorOutput = false; errorFormat = ErrorFormat.SINGLELINE; debugFunctionSideEffectsPath = null; externExports = false; // Debugging aliasHandler = NULL_ALIAS_TRANSFORMATION_HANDLER; errorHandler = null; printSourceAfterEachPass = false; } /** * @return Whether to attempt to remove unused class properties */ public boolean isRemoveUnusedClassProperties() { return removeUnusedClassProperties; } /** * @param removeUnusedClassProperties Whether to attempt to remove * unused class properties */ public void setRemoveUnusedClassProperties(boolean removeUnusedClassProperties) { this.removeUnusedClassProperties = removeUnusedClassProperties; } /** * @return Whether to attempt to remove unused constructor properties */ public boolean isRemoveUnusedConstructorProperties() { return removeUnusedConstructorProperties; } /** * @param removeUnused Whether to attempt to remove * unused constructor properties */ public void setRemoveUnusedConstructorProperties(boolean removeUnused) { this.removeUnusedConstructorProperties = removeUnused; } /** * Returns the map of define replacements. */ public Map getDefineReplacements() { return getReplacementsHelper(defineReplacements); } /** * Returns the map of tweak replacements. */ public Map getTweakReplacements() { return getReplacementsHelper(tweakReplacements); } /** Creates a map of String->Node from a map of String->Number/String/Boolean. */ private static ImmutableMap getReplacementsHelper(Map source) { ImmutableMap.Builder map = ImmutableMap.builder(); for (Map.Entry entry : source.entrySet()) { String name = entry.getKey(); Object value = entry.getValue(); if (value instanceof Boolean) { map.put(name, NodeUtil.booleanNode(((Boolean) value).booleanValue())); } else if (value instanceof Integer) { map.put(name, IR.number(((Integer) value).intValue())); } else if (value instanceof Double) { map.put(name, IR.number(((Double) value).doubleValue())); } else { checkState(value instanceof String); map.put(name, IR.string((String) value)); } } return map.build(); } /** * Sets the value of the {@code @define} variable in JS * to a boolean literal. */ public void setDefineToBooleanLiteral(String defineName, boolean value) { defineReplacements.put(defineName, value); } /** * Sets the value of the {@code @define} variable in JS to a * String literal. */ public void setDefineToStringLiteral(String defineName, String value) { defineReplacements.put(defineName, value); } /** * Sets the value of the {@code @define} variable in JS to a * number literal. */ public void setDefineToNumberLiteral(String defineName, int value) { defineReplacements.put(defineName, value); } /** * Sets the value of the {@code @define} variable in JS to a * number literal. */ public void setDefineToDoubleLiteral(String defineName, double value) { defineReplacements.put(defineName, value); } /** * Sets the value of the tweak in JS * to a boolean literal. */ public void setTweakToBooleanLiteral(String tweakId, boolean value) { tweakReplacements.put(tweakId, value); } /** * Sets the value of the tweak in JS to a * String literal. */ public void setTweakToStringLiteral(String tweakId, String value) { tweakReplacements.put(tweakId, value); } /** * Sets the value of the tweak in JS to a * number literal. */ public void setTweakToNumberLiteral(String tweakId, int value) { tweakReplacements.put(tweakId, value); } /** * Sets the value of the tweak in JS to a * number literal. */ public void setTweakToDoubleLiteral(String tweakId, double value) { tweakReplacements.put(tweakId, value); } /** * Skip all possible passes, to make the compiler as fast as possible. */ public void skipAllCompilerPasses() { skipNonTranspilationPasses = true; } /** * Whether the warnings guard in this Options object enables the given * group of warnings. */ boolean enables(DiagnosticGroup type) { return this.warningsGuard.enables(type); } /** * Whether the warnings guard in this Options object disables the given * group of warnings. */ boolean disables(DiagnosticGroup type) { return this.warningsGuard.disables(type); } /** * Configure the given type of warning to the given level. */ public void setWarningLevel(DiagnosticGroup type, CheckLevel level) { addWarningsGuard(new DiagnosticGroupWarningsGuard(type, level)); } WarningsGuard getWarningsGuard() { return this.warningsGuard; } /** * Reset the warnings guard. */ public void resetWarningsGuard() { this.warningsGuard = new ComposeWarningsGuard(); } /** * The emergency fail safe removes all strict and ERROR-escalating * warnings guards. */ void useEmergencyFailSafe() { this.warningsGuard = this.warningsGuard.makeEmergencyFailSafeGuard(); } void useNonStrictWarningsGuard() { this.warningsGuard = this.warningsGuard.makeNonStrict(); } /** * Add a guard to the set of warnings guards. */ public void addWarningsGuard(WarningsGuard guard) { this.warningsGuard.addGuard(guard); } /** * Sets the variable and property renaming policies for the compiler, * in a way that clears warnings about the renaming policy being * uninitialized from flags. */ public void setRenamingPolicy(VariableRenamingPolicy newVariablePolicy, PropertyRenamingPolicy newPropertyPolicy) { this.variableRenaming = newVariablePolicy; this.propertyRenaming = newPropertyPolicy; } /** Should shadow outer scope variable name during renaming. */ public void setShadowVariables(boolean shadow) { this.shadowVariables = shadow; } /** * If true, process goog.testing.ObjectPropertyString instances. */ public void setProcessObjectPropertyString(boolean process) { processObjectPropertyString = process; } /** * @param replaceIdGenerators the replaceIdGenerators to set */ public void setReplaceIdGenerators(boolean replaceIdGenerators) { this.replaceIdGenerators = replaceIdGenerators; } /** * Sets the id generators to replace. */ public void setIdGenerators(Set idGenerators) { RenamingMap gen = new UniqueRenamingToken(); ImmutableMap.Builder builder = ImmutableMap.builder(); for (String name : idGenerators) { builder.put(name, gen); } this.idGenerators = builder.build(); } /** * Sets the id generators to replace. */ public void setIdGenerators(Map idGenerators) { this.idGenerators = ImmutableMap.copyOf(idGenerators); } /** * A previous map of ids (serialized to a string by a previous compile). * This will be used as a hint during the ReplaceIdGenerators pass, which * will attempt to reuse the same ids. */ public void setIdGeneratorsMap(String previousMappings) { this.idGeneratorsMapSerialized = previousMappings; } /** * Sets the hash function to use for Xid */ public void setXidHashFunction(Xid.HashFunction xidHashFunction) { this.xidHashFunction = xidHashFunction; } private Reach inlineFunctionsLevel; /** Use {@link #setInlineFunctions(Reach)} instead */ @Deprecated public void setInlineFunctions(boolean inlineFunctions) { this.setInlineFunctions(inlineFunctions ? Reach.ALL : Reach.NONE); } /** * Set the function inlining policy for the compiler. */ public void setInlineFunctions(Reach reach) { this.inlineFunctionsLevel = reach; } /** * Get the function inlining policy for the compiler. */ public Reach getInlineFunctionsLevel() { return this.inlineFunctionsLevel; } public void setMaxFunctionSizeAfterInlining(int funAstSize) { checkArgument(funAstSize > 0); this.maxFunctionSizeAfterInlining = funAstSize; } public void setInlineVariables(boolean inlineVariables) { this.inlineVariables = inlineVariables; } /** * Set the variable inlining policy for the compiler. */ public void setInlineVariables(Reach reach) { switch (reach) { case ALL: this.inlineVariables = true; this.inlineLocalVariables = true; break; case LOCAL_ONLY: this.inlineVariables = false; this.inlineLocalVariables = true; break; case NONE: this.inlineVariables = false; this.inlineLocalVariables = false; break; default: throw new IllegalStateException("unexpected"); } } /** * Set the function inlining policy for the compiler. */ public void setInlineProperties(boolean enable) { inlineProperties = enable; } public boolean shouldInlineProperties() { return inlineProperties; } /** * Set the variable removal policy for the compiler. */ public void setRemoveUnusedVariables(Reach reach) { switch (reach) { case ALL: this.removeUnusedVars = true; this.removeUnusedLocalVars = true; break; case LOCAL_ONLY: this.removeUnusedVars = false; this.removeUnusedLocalVars = true; break; case NONE: this.removeUnusedVars = false; this.removeUnusedLocalVars = false; break; default: throw new IllegalStateException("unexpected"); } } /** * Sets the functions whose debug strings to replace. */ public void setReplaceStringsConfiguration( String placeholderToken, List functionDescriptors) { this.replaceStringsPlaceholderToken = placeholderToken; this.replaceStringsFunctionDescriptions = new ArrayList<>(functionDescriptors); } public void setRemoveAbstractMethods(boolean remove) { this.removeAbstractMethods = remove; } public void setRemoveSuperMethods(boolean remove) { this.removeSuperMethods = remove; } public boolean getRemoveSuperMethods() { return removeSuperMethods; } public void setRemoveClosureAsserts(boolean remove) { this.removeClosureAsserts = remove; } public void setRemoveJ2clAsserts(boolean remove) { this.removeJ2clAsserts = remove; } public void setColorizeErrorOutput(boolean colorizeErrorOutput) { this.colorizeErrorOutput = colorizeErrorOutput; } public boolean shouldColorizeErrorOutput() { return colorizeErrorOutput; } /** * Enable run-time type checking, which adds JS type assertions for debugging. * * @param logFunction A JS function to be used for logging run-time type * assertion failures. */ public void enableRuntimeTypeCheck(String logFunction) { this.runtimeTypeCheck = true; this.runtimeTypeCheckLogFunction = logFunction; } public void disableRuntimeTypeCheck() { this.runtimeTypeCheck = false; } public void setChecksOnly(boolean checksOnly) { this.checksOnly = checksOnly; } void setOutputJs(OutputJs outputJs) { this.outputJs = outputJs; } public void setGenerateExports(boolean generateExports) { this.generateExports = generateExports; } public void setExportLocalPropertyDefinitions(boolean export) { this.exportLocalPropertyDefinitions = export; } public boolean shouldExportLocalPropertyDefinitions() { return this.exportLocalPropertyDefinitions; } public void setAngularPass(boolean angularPass) { this.angularPass = angularPass; } public void setPolymerVersion(Integer polymerVersion) { checkArgument(polymerVersion == null || polymerVersion == 1 || polymerVersion == 2, "Invalid Polymer version:", polymerVersion); this.polymerVersion = polymerVersion; } public void setChromePass(boolean chromePass) { this.chromePass = chromePass; } public boolean isChromePassEnabled() { return chromePass; } public void setDartPass(boolean dartPass) { this.dartPass = dartPass; } public void setJ2clPass(J2clPassMode j2clPassMode) { this.j2clPassMode = j2clPassMode; } public void setCodingConvention(CodingConvention codingConvention) { this.codingConvention = codingConvention; } public CodingConvention getCodingConvention() { return codingConvention; } /** * Sets dependency options. See the DependencyOptions class for more info. * This supersedes manageClosureDependencies. */ public void setDependencyOptions(DependencyOptions options) { this.dependencyOptions = options; } public DependencyOptions getDependencyOptions() { return dependencyOptions; } /** * Sort inputs by their goog.provide/goog.require calls, and prune inputs * whose symbols are not required. */ public void setManageClosureDependencies(boolean newVal) { dependencyOptions.setDependencySorting( newVal || dependencyOptions.shouldSortDependencies()); dependencyOptions.setDependencyPruning( newVal || dependencyOptions.shouldPruneDependencies()); dependencyOptions.setMoocherDropping(false); } /** * Sort inputs by their goog.provide/goog.require calls. * * @param entryPoints Entry points to the program. Must be goog.provide'd * symbols. Any goog.provide'd symbols that are not a transitive * dependency of the entry points will be deleted. * Files without goog.provides, and their dependencies, * will always be left in. */ public void setManageClosureDependencies(List entryPoints) { checkNotNull(entryPoints); setManageClosureDependencies(true); List normalizedEntryPoints = new ArrayList<>(); for (String entryPoint : entryPoints) { normalizedEntryPoints.add(ModuleIdentifier.forClosure(entryPoint)); } dependencyOptions.setEntryPoints(normalizedEntryPoints); } /** * Controls how detailed the compilation summary is. Values: * 0 (never print summary), 1 (print summary only if there are * errors or warnings), 2 (print summary if type checking is on, * see --check_types), 3 (always print summary). The default level * is 1 */ public void setSummaryDetailLevel(int summaryDetailLevel) { this.summaryDetailLevel = summaryDetailLevel; } /** * @deprecated replaced by {@link #setExternExports} */ @Deprecated public void enableExternExports(boolean enabled) { this.externExports = enabled; } public void setExtraAnnotationNames(Iterable extraAnnotationNames) { this.extraAnnotationNames = ImmutableSet.copyOf(extraAnnotationNames); } public boolean isExternExportsEnabled() { return externExports; } /** * Sets the output charset. */ public void setOutputCharset(Charset charset) { this.outputCharset = charset; } /** * Gets the output charset. */ Charset getOutputCharset() { return outputCharset; } /** * Sets how goog.tweak calls are processed. */ public void setTweakProcessing(TweakProcessing tweakProcessing) { this.tweakProcessing = tweakProcessing; } public TweakProcessing getTweakProcessing() { return tweakProcessing; } /** * Sets ECMAScript version to use. */ public void setLanguage(LanguageMode language) { checkState(language != LanguageMode.NO_TRANSPILE); this.languageIn = language; this.languageOut = language; } /** * Sets ECMAScript version to use for the input. If you are not * transpiling from one version to another, use #setLanguage instead. */ public void setLanguageIn(LanguageMode languageIn) { checkState(languageIn != LanguageMode.NO_TRANSPILE); this.languageIn = languageIn; } public LanguageMode getLanguageIn() { return languageIn; } /** * Sets ECMAScript version to use for the output. If you are not * transpiling from one version to another, use #setLanguage instead. */ public void setLanguageOut(LanguageMode languageOut) { this.languageOut = languageOut; } public LanguageMode getLanguageOut() { if (languageOut == LanguageMode.NO_TRANSPILE) { return languageIn; } return languageOut; } public boolean needsTranspilationFrom(FeatureSet languageLevel) { return getLanguageIn().toFeatureSet().contains(languageLevel) && !getLanguageOut().toFeatureSet().contains(languageLevel); } public boolean needsTranspilationOf(FeatureSet.Feature feature) { return getLanguageIn().toFeatureSet().has(feature) && !getLanguageOut().toFeatureSet().has(feature); } /** * Set which set of builtin externs to use. */ public void setEnvironment(Environment environment) { this.environment = environment; } public Environment getEnvironment() { return environment; } public void setAliasTransformationHandler( AliasTransformationHandler changes) { this.aliasHandler = changes; } public AliasTransformationHandler getAliasTransformationHandler() { return this.aliasHandler; } /** * Set a custom handler for warnings and errors. * * This is mostly used for piping the warnings and errors to * a file behind the scenes. * * If you want to filter warnings and errors, you should use a WarningsGuard. * * If you want to change how warnings and errors are reported to the user, * you should set a ErrorManager on the Compiler. An ErrorManager is * intended to summarize the errors for a single compile job. */ public void setErrorHandler(ErrorHandler handler) { this.errorHandler = handler; } /** * If true, enables type inference. If checkTypes is enabled, this flag has * no effect. */ public void setInferTypes(boolean enable) { inferTypes = enable; } /** * Gets the inferTypes flag. Note that if checkTypes is enabled, this flag * is ignored when configuring the compiler. */ public boolean getInferTypes() { return inferTypes; } public boolean getNewTypeInference() { return this.useNewTypeInference; } public void setNewTypeInference(boolean enable) { this.useNewTypeInference = enable; } /** * @return true if either typechecker is ON. */ public boolean isTypecheckingEnabled() { return this.checkTypes || this.useNewTypeInference; } public boolean getRunOTIafterNTI() { return this.runOTIafterNTI; } public void setRunOTIafterNTI(boolean enable) { this.runOTIafterNTI = enable; } // Not dead code; used by the open-source users of the compiler. public void setReportOTIErrorsUnderNTI(boolean enable) { this.reportOTIErrorsUnderNTI = enable; } public boolean getTypeCheckEs6Natively() { return this.typeCheckEs6Natively; } public void setTypeCheckEs6Natively(boolean enable) { this.typeCheckEs6Natively = enable; } /** * @return Whether assumeStrictThis is set. */ public boolean assumeStrictThis() { return assumeStrictThis; } /** * If true, enables enables additional optimizations. */ public void setAssumeStrictThis(boolean enable) { this.assumeStrictThis = enable; } /** * @return Whether assumeClosuresOnlyCaptureReferences is set. */ public boolean assumeClosuresOnlyCaptureReferences() { return assumeClosuresOnlyCaptureReferences; } /** * Whether to assume closures capture only what they reference. This allows * more aggressive function inlining. */ public void setAssumeClosuresOnlyCaptureReferences(boolean enable) { this.assumeClosuresOnlyCaptureReferences = enable; } /** * Sets the list of properties that we report property invalidation errors * for. */ public void setPropertyInvalidationErrors( Map propertyInvalidationErrors) { this.propertyInvalidationErrors = ImmutableMap.copyOf(propertyInvalidationErrors); } /** * Configures the compiler for use as an IDE backend. In this mode: *

    *
  • No optimization passes will run.
  • *
  • The last time custom passes are invoked is * {@link CustomPassExecutionTime#BEFORE_OPTIMIZATIONS}
  • *
  • The compiler will always try to process all inputs fully, even * if it encounters errors.
  • *
  • The compiler may record more information than is strictly * needed for codegen.
  • *
* * @deprecated Some "IDE" clients will need some of these options but not * others. Consider calling setChecksOnly, setAllowRecompilation, etc, * explicitly, instead of calling this method which does a variety of * different things. */ @Deprecated public void setIdeMode(boolean ideMode) { setChecksOnly(ideMode); setContinueAfterErrors(ideMode); setAllowHotswapReplaceScript(ideMode); setPreserveDetailedSourceInfo(ideMode); setParseJsDocDocumentation( ideMode ? Config.JsDocParsing.INCLUDE_DESCRIPTIONS_NO_WHITESPACE : Config.JsDocParsing.TYPES_ONLY); } public void setAllowHotswapReplaceScript(boolean allowRecompilation) { this.allowHotswapReplaceScript = allowRecompilation; } boolean allowsHotswapReplaceScript() { return allowHotswapReplaceScript; } public void setPreserveDetailedSourceInfo(boolean preserveDetailedSourceInfo) { this.preserveDetailedSourceInfo = preserveDetailedSourceInfo; } boolean preservesDetailedSourceInfo() { return preserveDetailedSourceInfo; } public void setContinueAfterErrors(boolean continueAfterErrors) { this.continueAfterErrors = continueAfterErrors; } boolean canContinueAfterErrors() { return continueAfterErrors; } /** * Enables or disables the parsing of JSDoc documentation, and optionally also * the preservation of all whitespace and formatting within a JSDoc comment. * By default, whitespace is collapsed for all comments except {@literal @license} and * {@literal @preserve} blocks, * */ public void setParseJsDocDocumentation(Config.JsDocParsing parseJsDocDocumentation) { this.parseJsDocDocumentation = parseJsDocDocumentation; } /** * Checks JSDoc documentation will be parsed. * * @return True when JSDoc documentation will be parsed, false if not. */ public Config.JsDocParsing isParseJsDocDocumentation() { return this.parseJsDocDocumentation; } /** * Skip all passes (other than transpilation, if requested). Don't inject any * runtime libraries (unless explicitly requested) or do any checks/optimizations * (this is useful for per-file transpilation). */ public void setSkipNonTranspilationPasses(boolean skipNonTranspilationPasses) { this.skipNonTranspilationPasses = skipNonTranspilationPasses; } public void setDevMode(DevMode devMode) { this.devMode = devMode; } public void setCheckDeterminism(boolean checkDeterminism) { this.checkDeterminism = checkDeterminism; } public boolean getCheckDeterminism() { return checkDeterminism; } public void setMessageBundle(MessageBundle messageBundle) { this.messageBundle = messageBundle; } public void setCheckSymbols(boolean checkSymbols) { this.checkSymbols = checkSymbols; } public void setCheckSuspiciousCode(boolean checkSuspiciousCode) { this.checkSuspiciousCode = checkSuspiciousCode; } public void setCheckTypes(boolean checkTypes) { this.checkTypes = checkTypes; } public void setCheckMissingGetCssNameBlacklist(String blackList) { this.checkMissingGetCssNameBlacklist = blackList; } public void setFoldConstants(boolean foldConstants) { this.foldConstants = foldConstants; } public void setDeadAssignmentElimination(boolean deadAssignmentElimination) { this.deadAssignmentElimination = deadAssignmentElimination; } public void setInlineConstantVars(boolean inlineConstantVars) { this.inlineConstantVars = inlineConstantVars; } public void setCrossModuleCodeMotion(boolean crossModuleCodeMotion) { this.crossModuleCodeMotion = crossModuleCodeMotion; } public void setCrossModuleCodeMotionNoStubMethods(boolean crossModuleCodeMotionNoStubMethods) { this.crossModuleCodeMotionNoStubMethods = crossModuleCodeMotionNoStubMethods; } public void setParentModuleCanSeeSymbolsDeclaredInChildren( boolean parentModuleCanSeeSymbolsDeclaredInChildren) { this.parentModuleCanSeeSymbolsDeclaredInChildren = parentModuleCanSeeSymbolsDeclaredInChildren; } public void setCoalesceVariableNames(boolean coalesceVariableNames) { this.coalesceVariableNames = coalesceVariableNames; } public void setCrossModuleMethodMotion(boolean crossModuleMethodMotion) { this.crossModuleMethodMotion = crossModuleMethodMotion; } public void setInlineLocalVariables(boolean inlineLocalVariables) { this.inlineLocalVariables = inlineLocalVariables; } public void setFlowSensitiveInlineVariables(boolean enabled) { this.flowSensitiveInlineVariables = enabled; } public void setSmartNameRemoval(boolean smartNameRemoval) { // TODO(bradfordcsmith): Remove the smart name removal option. this.smartNameRemoval = smartNameRemoval; if (smartNameRemoval) { // To get the effect this option used to have we need to enable these options. // Don't disable them here if they were set explicitly, though. this.removeUnusedVars = true; this.removeUnusedPrototypeProperties = true; } } public void setExtraSmartNameRemoval(boolean smartNameRemoval) { this.extraSmartNameRemoval = smartNameRemoval; } public void setRemoveDeadCode(boolean removeDeadCode) { this.removeDeadCode = removeDeadCode; } public void setExtractPrototypeMemberDeclarations(boolean enabled) { this.extractPrototypeMemberDeclarations = enabled ? ExtractPrototypeMemberDeclarationsMode.USE_GLOBAL_TEMP : ExtractPrototypeMemberDeclarationsMode.OFF; } // USE_IIFE is currently unused. Consider removing support for it and // deleting this setter. public void setExtractPrototypeMemberDeclarations(ExtractPrototypeMemberDeclarationsMode mode) { this.extractPrototypeMemberDeclarations = mode; } public void setRemoveUnusedPrototypeProperties(boolean enabled) { this.removeUnusedPrototypeProperties = enabled; // InlineSimpleMethods makes similar assumptions to // RemoveUnusedCode, so they are enabled together. this.inlineGetters = enabled; } public void setRemoveUnusedPrototypePropertiesInExterns(boolean enabled) { this.removeUnusedPrototypePropertiesInExterns = enabled; } public void setCollapseVariableDeclarations(boolean enabled) { this.collapseVariableDeclarations = enabled; } public void setCollapseAnonymousFunctions(boolean enabled) { this.collapseAnonymousFunctions = enabled; } public void setAliasableStrings(Set aliasableStrings) { this.aliasableStrings = aliasableStrings; } public void setAliasStringsBlacklist(String aliasStringsBlacklist) { this.aliasStringsBlacklist = aliasStringsBlacklist; } public void setAliasAllStrings(boolean aliasAllStrings) { this.aliasAllStrings = aliasAllStrings; } public void setOutputJsStringUsage(boolean outputJsStringUsage) { this.outputJsStringUsage = outputJsStringUsage; } public void setConvertToDottedProperties(boolean convertToDottedProperties) { this.convertToDottedProperties = convertToDottedProperties; } public void setUseTypesForLocalOptimization(boolean useTypesForLocalOptimization) { this.useTypesForLocalOptimization = useTypesForLocalOptimization; } public boolean shouldUseTypesForLocalOptimization() { return this.useTypesForLocalOptimization; } @Deprecated public void setUseTypesForOptimization(boolean useTypesForOptimization) { if (useTypesForOptimization) { this.disambiguateProperties = useTypesForOptimization; this.ambiguateProperties = useTypesForOptimization; this.inlineProperties = useTypesForOptimization; this.useTypesForLocalOptimization = useTypesForOptimization; } } public void setRewriteFunctionExpressions(boolean rewriteFunctionExpressions) { this.rewriteFunctionExpressions = rewriteFunctionExpressions; } public void setOptimizeCalls(boolean optimizeCalls) { this.optimizeCalls = optimizeCalls; } public void setOptimizeArgumentsArray(boolean optimizeArgumentsArray) { this.optimizeArgumentsArray = optimizeArgumentsArray; } public void setVariableRenaming(VariableRenamingPolicy variableRenaming) { this.variableRenaming = variableRenaming; } public void setPropertyRenaming(PropertyRenamingPolicy propertyRenaming) { this.propertyRenaming = propertyRenaming; } public PropertyRenamingPolicy getPropertyRenaming() { return this.propertyRenaming; } public void setLabelRenaming(boolean labelRenaming) { this.labelRenaming = labelRenaming; } public void setReserveRawExports(boolean reserveRawExports) { this.reserveRawExports = reserveRawExports; } public void setPreferStableNames(boolean preferStableNames) { this.preferStableNames = preferStableNames; } public void setGeneratePseudoNames(boolean generatePseudoNames) { this.generatePseudoNames = generatePseudoNames; } public void setRenamePrefix(String renamePrefix) { this.renamePrefix = renamePrefix; } public String getRenamePrefixNamespace() { return this.renamePrefixNamespace; } public void setRenamePrefixNamespace(String renamePrefixNamespace) { this.renamePrefixNamespace = renamePrefixNamespace; } public void setCollapsePropertiesLevel(PropertyCollapseLevel level) { this.collapsePropertiesLevel = level; } @Deprecated public void setCollapseProperties(boolean fullyCollapse) { this.collapsePropertiesLevel = fullyCollapse ? PropertyCollapseLevel.ALL : PropertyCollapseLevel.NONE; } public void setDevirtualizePrototypeMethods(boolean devirtualizePrototypeMethods) { this.devirtualizePrototypeMethods = devirtualizePrototypeMethods; } public void setComputeFunctionSideEffects(boolean computeFunctionSideEffects) { this.computeFunctionSideEffects = computeFunctionSideEffects; } public void setDebugFunctionSideEffectsPath(String debugFunctionSideEffectsPath) { this.debugFunctionSideEffectsPath = debugFunctionSideEffectsPath; } /** * @return Whether disambiguate private properties is enabled. */ public boolean isDisambiguatePrivateProperties() { return disambiguatePrivateProperties; } /** * @param value Whether to enable private property disambiguation based on * the coding convention. */ public void setDisambiguatePrivateProperties(boolean value) { this.disambiguatePrivateProperties = value; } public void setDisambiguateProperties(boolean disambiguateProperties) { this.disambiguateProperties = disambiguateProperties; } public boolean shouldDisambiguateProperties() { return this.disambiguateProperties; } public void setAmbiguateProperties(boolean ambiguateProperties) { this.ambiguateProperties = ambiguateProperties; } public boolean shouldAmbiguateProperties() { return this.ambiguateProperties; } public void setAnonymousFunctionNaming( AnonymousFunctionNamingPolicy anonymousFunctionNaming) { this.anonymousFunctionNaming = anonymousFunctionNaming; } public void setInputAnonymousFunctionNamingMap(VariableMap inputMap) { this.inputAnonymousFunctionNamingMap = inputMap; } public void setInputVariableMap(VariableMap inputVariableMap) { this.inputVariableMap = inputVariableMap; } public void setInputPropertyMap(VariableMap inputPropertyMap) { this.inputPropertyMap = inputPropertyMap; } public void setExportTestFunctions(boolean exportTestFunctions) { this.exportTestFunctions = exportTestFunctions; } public void setRuntimeTypeCheck(boolean runtimeTypeCheck) { this.runtimeTypeCheck = runtimeTypeCheck; } public void setRuntimeTypeCheckLogFunction(String runtimeTypeCheckLogFunction) { this.runtimeTypeCheckLogFunction = runtimeTypeCheckLogFunction; } public void setSyntheticBlockStartMarker(String syntheticBlockStartMarker) { this.syntheticBlockStartMarker = syntheticBlockStartMarker; } public void setSyntheticBlockEndMarker(String syntheticBlockEndMarker) { this.syntheticBlockEndMarker = syntheticBlockEndMarker; } public void setLocale(String locale) { this.locale = locale; } public void setMarkAsCompiled(boolean markAsCompiled) { this.markAsCompiled = markAsCompiled; } public void setClosurePass(boolean closurePass) { this.closurePass = closurePass; } /** Preserve closure primitives. * * For now, this only preserves goog.provide(), goog.require() and goog.module() calls. */ public void setPreserveClosurePrimitives(boolean preserveClosurePrimitives) { this.preserveClosurePrimitives = preserveClosurePrimitives; } // TODO(bangert): Delete this alias once it has been deprecated for 3 months. /** Preserve goog.provide(), goog.require() and goog.module() calls. */ @Deprecated public void setPreserveGoogProvidesAndRequires(boolean preserveGoogProvidesAndRequires) { setPreserveClosurePrimitives(preserveGoogProvidesAndRequires); } public boolean shouldPreservesGoogProvidesAndRequires() { return this.preserveClosurePrimitives || this.shouldGenerateTypedExterns(); } public boolean shouldPreserveGoogModule() { return this.preserveClosurePrimitives; } /** Do not process goog. intrinsics, such as goog.getCssName(). */ public boolean shouldPreserveGoogLibraryPrimitives() { return this.preserveClosurePrimitives; } public void setPreserveTypeAnnotations(boolean preserveTypeAnnotations) { this.preserveTypeAnnotations = preserveTypeAnnotations; } public void setGatherCssNames(boolean gatherCssNames) { this.gatherCssNames = gatherCssNames; } public void setStripTypes(Set stripTypes) { this.stripTypes = stripTypes; } public void setStripNameSuffixes(Set stripNameSuffixes) { this.stripNameSuffixes = stripNameSuffixes; } public void setStripNamePrefixes(Set stripNamePrefixes) { this.stripNamePrefixes = stripNamePrefixes; } public void setStripTypePrefixes(Set stripTypePrefixes) { this.stripTypePrefixes = stripTypePrefixes; } public void addCustomPass(CustomPassExecutionTime time, CompilerPass customPass) { if (customPasses == null) { customPasses = LinkedHashMultimap.create(); } customPasses.put(time, customPass); } public void setMarkNoSideEffectCalls(boolean markNoSideEffectCalls) { this.markNoSideEffectCalls = markNoSideEffectCalls; } public void setDefineReplacements(Map defineReplacements) { this.defineReplacements = defineReplacements; } public void setTweakReplacements(Map tweakReplacements) { this.tweakReplacements = tweakReplacements; } public void setMoveFunctionDeclarations(boolean moveFunctionDeclarations) { this.moveFunctionDeclarations = moveFunctionDeclarations; } public void setInstrumentationTemplate(Instrumentation instrumentationTemplate) { this.instrumentationTemplate = instrumentationTemplate; } public void setInstrumentationTemplateFile(String filename){ this.instrumentationTemplateFile = filename; } public void setRecordFunctionInformation(boolean recordFunctionInformation) { this.recordFunctionInformation = recordFunctionInformation; } public void setCssRenamingMap(CssRenamingMap cssRenamingMap) { this.cssRenamingMap = cssRenamingMap; } public void setCssRenamingWhitelist(Set whitelist) { this.cssRenamingWhitelist = whitelist; } public void setReplaceStringsFunctionDescriptions( List replaceStringsFunctionDescriptions) { this.replaceStringsFunctionDescriptions = replaceStringsFunctionDescriptions; } public void setReplaceStringsPlaceholderToken( String replaceStringsPlaceholderToken) { this.replaceStringsPlaceholderToken = replaceStringsPlaceholderToken; } public void setReplaceStringsReservedStrings( Set replaceStringsReservedStrings) { this.replaceStringsReservedStrings = replaceStringsReservedStrings; } public void setReplaceStringsInputMap(VariableMap serializedMap) { this.replaceStringsInputMap = serializedMap; } public void setPrettyPrint(boolean prettyPrint) { this.prettyPrint = prettyPrint; } public boolean isPrettyPrint() { return this.prettyPrint; } public void setLineBreak(boolean lineBreak) { this.lineBreak = lineBreak; } public boolean getPreferLineBreakAtEndOfFile() { return this.preferLineBreakAtEndOfFile; } public void setPreferLineBreakAtEndOfFile(boolean lineBreakAtEnd) { this.preferLineBreakAtEndOfFile = lineBreakAtEnd; } public void setPrintInputDelimiter(boolean printInputDelimiter) { this.printInputDelimiter = printInputDelimiter; } public void setInputDelimiter(String inputDelimiter) { this.inputDelimiter = inputDelimiter; } public void setQuoteKeywordProperties(boolean quoteKeywordProperties) { this.quoteKeywordProperties = quoteKeywordProperties; } public boolean shouldQuoteKeywordProperties() { // Never quote properties in .i.js files if (incrementalCheckMode == IncrementalCheckMode.GENERATE_IJS) { return false; } return this.quoteKeywordProperties || languageOut == LanguageMode.ECMASCRIPT3; } public void setErrorFormat(ErrorFormat errorFormat) { this.errorFormat = errorFormat; } public ErrorFormat getErrorFormat() { return this.errorFormat; } public void setWarningsGuard(ComposeWarningsGuard warningsGuard) { this.warningsGuard = warningsGuard; } public void setLineLengthThreshold(int lineLengthThreshold) { this.lineLengthThreshold = lineLengthThreshold; } public int getLineLengthThreshold() { return this.lineLengthThreshold; } public void setUseOriginalNamesInOutput(boolean useOriginalNamesInOutput) { this.useOriginalNamesInOutput = useOriginalNamesInOutput; } public boolean getUseOriginalNamesInOutput() { return this.useOriginalNamesInOutput; } public void setExternExports(boolean externExports) { this.externExports = externExports; } public void setExternExportsPath(String externExportsPath) { this.externExportsPath = externExportsPath; } public void setSourceMapOutputPath(String sourceMapOutputPath) { this.sourceMapOutputPath = sourceMapOutputPath; } public void setApplyInputSourceMaps(boolean applyInputSourceMaps) { this.applyInputSourceMaps = applyInputSourceMaps; } public void setResolveSourceMapAnnotations(boolean resolveSourceMapAnnotations) { this.resolveSourceMapAnnotations = resolveSourceMapAnnotations; } public void setSourceMapIncludeSourcesContent(boolean sourceMapIncludeSourcesContent) { this.sourceMapIncludeSourcesContent = sourceMapIncludeSourcesContent; } public void setSourceMapDetailLevel(SourceMap.DetailLevel sourceMapDetailLevel) { this.sourceMapDetailLevel = sourceMapDetailLevel; } public void setSourceMapFormat(SourceMap.Format sourceMapFormat) { this.sourceMapFormat = sourceMapFormat; } public void setSourceMapLocationMappings( List sourceMapLocationMappings) { this.sourceMapLocationMappings = sourceMapLocationMappings; } /** * Activates transformation of AMD to CommonJS modules. */ public void setTransformAMDToCJSModules(boolean transformAMDToCJSModules) { this.transformAMDToCJSModules = transformAMDToCJSModules; } /** * Rewrites CommonJS modules so that modules can be concatenated together, * by renaming all globals to avoid conflicting with other modules. */ public void setProcessCommonJSModules(boolean processCommonJSModules) { this.processCommonJSModules = processCommonJSModules; } /** * Sets a path prefix for CommonJS modules (maps to {@link #setModuleRoots(List)}). */ public void setCommonJSModulePathPrefix(String commonJSModulePathPrefix) { setModuleRoots(ImmutableList.of(commonJSModulePathPrefix)); } /** * Sets the module roots. */ public void setModuleRoots(List moduleRoots) { this.moduleRoots = moduleRoots; } /** * Sets whether to rewrite polyfills. */ public void setRewritePolyfills(boolean rewritePolyfills) { this.rewritePolyfills = rewritePolyfills; } public boolean getRewritePolyfills() { return this.rewritePolyfills; } /** * Sets list of libraries to always inject, even if not needed. */ public void setForceLibraryInjection(Iterable libraries) { this.forceLibraryInjection = ImmutableList.copyOf(libraries); } /** * Sets the set of libraries to never inject, even if required. */ public void setPreventLibraryInjection(boolean preventLibraryInjection) { this.preventLibraryInjection = preventLibraryInjection; } /** * Set whether or not code should be modified to provide coverage * information. */ public void setInstrumentForCoverage(boolean instrumentForCoverage) { this.instrumentForCoverage = instrumentForCoverage; } /** Set whether to instrument to collect branch coverage */ public void setInstrumentBranchCoverage(boolean instrumentBranchCoverage) { if (instrumentForCoverage || !instrumentBranchCoverage) { this.instrumentBranchCoverage = instrumentBranchCoverage; } else { throw new RuntimeException("The option instrumentForCoverage must be set to true for " + "instrumentBranchCoverage to be set to true."); } } public final ImmutableList getConformanceConfigs() { return conformanceConfigs; } /** Both enable and configure conformance checks, if non-null. */ @GwtIncompatible("Conformance") public void setConformanceConfig(ConformanceConfig conformanceConfig) { setConformanceConfigs(ImmutableList.of(conformanceConfig)); } /** * Both enable and configure conformance checks, if non-null. */ @GwtIncompatible("Conformance") public void setConformanceConfigs(List configs) { this.conformanceConfigs = ImmutableList.builder() .add(ResourceLoader.loadGlobalConformance(CompilerOptions.class)) .addAll(configs) .build(); } public boolean shouldEmitUseStrict() { return this.emitUseStrict.or(getLanguageOut().isDefaultStrict()); } public CompilerOptions setEmitUseStrict(boolean emitUseStrict) { this.emitUseStrict = Optional.of(emitUseStrict); return this; } public ModuleLoader.ResolutionMode getModuleResolutionMode() { return this.moduleResolutionMode; } public void setModuleResolutionMode(ModuleLoader.ResolutionMode mode) { this.moduleResolutionMode = mode; } public List getPackageJsonEntryNames() { return this.packageJsonEntryNames; } public void setPackageJsonEntryNames(List names) { this.packageJsonEntryNames = names; } /** Serializes compiler options to a stream. */ @GwtIncompatible("ObjectOutputStream") public void serialize(OutputStream objectOutputStream) throws IOException { new java.io.ObjectOutputStream(objectOutputStream).writeObject(this); } /** Deserializes compiler options from a stream. */ @GwtIncompatible("ObjectInputStream") public static CompilerOptions deserialize(InputStream objectInputStream) throws IOException, ClassNotFoundException { return (CompilerOptions) new java.io.ObjectInputStream(objectInputStream).readObject(); } @Override public String toString() { String strValue = MoreObjects.toStringHelper(this) .omitNullValues() .add("aggressiveFusion", aggressiveFusion) .add("aliasableStrings", aliasableStrings) .add("aliasAllStrings", aliasAllStrings) .add("aliasHandler", getAliasTransformationHandler()) .add("aliasStringsBlacklist", aliasStringsBlacklist) .add("allowHotswapReplaceScript", allowsHotswapReplaceScript()) .add("ambiguateProperties", ambiguateProperties) .add("angularPass", angularPass) .add("anonymousFunctionNaming", anonymousFunctionNaming) .add("appNameStr", appNameStr) .add("assumeClosuresOnlyCaptureReferences", assumeClosuresOnlyCaptureReferences) .add("assumeStrictThis", assumeStrictThis()) .add("brokenClosureRequiresLevel", brokenClosureRequiresLevel) .add("checkDeterminism", getCheckDeterminism()) .add("checkGlobalNamesLevel", checkGlobalNamesLevel) .add("checkGlobalThisLevel", checkGlobalThisLevel) .add("checkMissingGetCssNameBlacklist", checkMissingGetCssNameBlacklist) .add("checkMissingGetCssNameLevel", checkMissingGetCssNameLevel) .add("checksOnly", checksOnly) .add("checkSuspiciousCode", checkSuspiciousCode) .add("checkSymbols", checkSymbols) .add("checkTypes", checkTypes) .add("closurePass", closurePass) .add("coalesceVariableNames", coalesceVariableNames) .add("codingConvention", getCodingConvention()) .add("collapseAnonymousFunctions", collapseAnonymousFunctions) .add("collapseObjectLiterals", collapseObjectLiterals) .add("collapseProperties", collapsePropertiesLevel) .add("collapseVariableDeclarations", collapseVariableDeclarations) .add("colorizeErrorOutput", shouldColorizeErrorOutput()) .add("computeFunctionSideEffects", computeFunctionSideEffects) .add("conformanceConfigs", getConformanceConfigs()) .add("continueAfterErrors", canContinueAfterErrors()) .add("convertToDottedProperties", convertToDottedProperties) .add("crossModuleCodeMotion", crossModuleCodeMotion) .add("crossModuleCodeMotionNoStubMethods", crossModuleCodeMotionNoStubMethods) .add("crossModuleMethodMotion", crossModuleMethodMotion) .add("cssRenamingMap", cssRenamingMap) .add("cssRenamingWhitelist", cssRenamingWhitelist) .add("customPasses", customPasses) .add("dartPass", dartPass) .add("deadAssignmentElimination", deadAssignmentElimination) .add("debugFunctionSideEffectsPath", debugFunctionSideEffectsPath) .add("declaredGlobalExternsOnWindow", declaredGlobalExternsOnWindow) .add("defineReplacements", getDefineReplacements()) .add("dependencyOptions", dependencyOptions) .add("devirtualizePrototypeMethods", devirtualizePrototypeMethods) .add("devMode", devMode) .add("disambiguatePrivateProperties", disambiguatePrivateProperties) .add("disambiguateProperties", disambiguateProperties) .add("enforceAccessControlCodingConventions", enforceAccessControlCodingConventions) .add("environment", getEnvironment()) .add("errorFormat", errorFormat) .add("errorHandler", errorHandler) .add("exportLocalPropertyDefinitions", exportLocalPropertyDefinitions) .add("exportTestFunctions", exportTestFunctions) .add("externExports", isExternExportsEnabled()) .add("externExportsPath", externExportsPath) .add("extraAnnotationNames", extraAnnotationNames) .add("extractPrototypeMemberDeclarations", extractPrototypeMemberDeclarations) .add("extraSmartNameRemoval", extraSmartNameRemoval) .add("filesToPrintAfterEachPassRegexList", filesToPrintAfterEachPassRegexList) .add("flowSensitiveInlineVariables", flowSensitiveInlineVariables) .add("foldConstants", foldConstants) .add("forceLibraryInjection", forceLibraryInjection) .add("gatherCssNames", gatherCssNames) .add("generateExportsAfterTypeChecking", generateExportsAfterTypeChecking) .add("generateExports", generateExports) .add("generatePseudoNames", generatePseudoNames) .add("generateTypedExterns", shouldGenerateTypedExterns()) .add("idGenerators", idGenerators) .add("idGeneratorsMapSerialized", idGeneratorsMapSerialized) .add("inferConsts", inferConsts) .add("inferTypes", inferTypes) .add("inlineConstantVars", inlineConstantVars) .add("inlineFunctionsLevel", inlineFunctionsLevel) .add("inlineGetters", inlineGetters) .add("inlineLocalVariables", inlineLocalVariables) .add("inlineProperties", inlineProperties) .add("inlineVariables", inlineVariables) .add("inputAnonymousFunctionNamingMap", inputAnonymousFunctionNamingMap) .add("inputDelimiter", inputDelimiter) .add("inputPropertyMap", inputPropertyMap) .add("inputSourceMaps", inputSourceMaps) .add("inputVariableMap", inputVariableMap) .add("instrumentationTemplateFile", instrumentationTemplateFile) .add("instrumentationTemplate", instrumentationTemplate) .add("instrumentForCoverage", instrumentForCoverage) .add("instrumentForCoverageOnly", instrumentForCoverageOnly) .add("instrumentBranchCoverage", instrumentBranchCoverage) .add("j2clPassMode", j2clPassMode) .add("labelRenaming", labelRenaming) .add("languageIn", getLanguageIn()) .add("languageOut", getLanguageOut()) .add("legacyCodeCompile", legacyCodeCompile) .add("lineBreak", lineBreak) .add("lineLengthThreshold", lineLengthThreshold) .add("locale", locale) .add("markAsCompiled", markAsCompiled) .add("markNoSideEffectCalls", markNoSideEffectCalls) .add("maxFunctionSizeAfterInlining", maxFunctionSizeAfterInlining) .add("messageBundle", messageBundle) .add("moduleRoots", moduleRoots) .add("modulesToPrintAfterEachPassRegexList", modulesToPrintAfterEachPassRegexList) .add("moveFunctionDeclarations", moveFunctionDeclarations) .add("nameGenerator", nameGenerator) .add("optimizeArgumentsArray", optimizeArgumentsArray) .add("optimizeCalls", optimizeCalls) .add("outputCharset", outputCharset) .add("outputJs", outputJs) .add("outputJsStringUsage", outputJsStringUsage) .add( "parentModuleCanSeeSymbolsDeclaredInChildren", parentModuleCanSeeSymbolsDeclaredInChildren) .add("parseJsDocDocumentation", isParseJsDocDocumentation()) .add("polymerVersion", polymerVersion) .add("preferLineBreakAtEndOfFile", preferLineBreakAtEndOfFile) .add("preferSingleQuotes", preferSingleQuotes) .add("preferStableNames", preferStableNames) .add("preserveDetailedSourceInfo", preservesDetailedSourceInfo()) .add("preserveGoogProvidesAndRequires", preserveClosurePrimitives) .add("preserveTypeAnnotations", preserveTypeAnnotations) .add("prettyPrint", prettyPrint) .add("preventLibraryInjection", preventLibraryInjection) .add("printConfig", printConfig) .add("printInputDelimiter", printInputDelimiter) .add("printSourceAfterEachPass", printSourceAfterEachPass) .add("processCommonJSModules", processCommonJSModules) .add("processObjectPropertyString", processObjectPropertyString) .add("propertyInvalidationErrors", propertyInvalidationErrors) .add("propertyRenaming", propertyRenaming) .add("protectHiddenSideEffects", protectHiddenSideEffects) .add("quoteKeywordProperties", quoteKeywordProperties) .add("recordFunctionInformation", recordFunctionInformation) .add("removeAbstractMethods", removeAbstractMethods) .add("removeSuperMethods", removeSuperMethods) .add("removeClosureAsserts", removeClosureAsserts) .add("removeJ2clAsserts", removeJ2clAsserts) .add("removeDeadCode", removeDeadCode) .add("removeUnusedClassProperties", removeUnusedClassProperties) .add("removeUnusedConstructorProperties", removeUnusedConstructorProperties) .add("removeUnusedLocalVars", removeUnusedLocalVars) .add( "removeUnusedPrototypePropertiesInExterns", removeUnusedPrototypePropertiesInExterns) .add("removeUnusedPrototypeProperties", removeUnusedPrototypeProperties) .add("removeUnusedVars", removeUnusedVars) .add( "renamePrefixNamespaceAssumeCrossModuleNames", renamePrefixNamespaceAssumeCrossModuleNames) .add("renamePrefixNamespace", renamePrefixNamespace) .add("renamePrefix", renamePrefix) .add("replaceIdGenerators", replaceIdGenerators) .add("replaceMessagesWithChromeI18n", replaceMessagesWithChromeI18n) .add("replaceStringsFunctionDescriptions", replaceStringsFunctionDescriptions) .add("replaceStringsInputMap", replaceStringsInputMap) .add("replaceStringsPlaceholderToken", replaceStringsPlaceholderToken) .add("replaceStringsReservedStrings", replaceStringsReservedStrings) .add("reportOTIErrorsUnderNTI", reportOTIErrorsUnderNTI) .add("reportPath", reportPath) .add("reserveRawExports", reserveRawExports) .add("rewriteFunctionExpressions", rewriteFunctionExpressions) .add("rewritePolyfills", rewritePolyfills) .add("runtimeTypeCheckLogFunction", runtimeTypeCheckLogFunction) .add("runtimeTypeCheck", runtimeTypeCheck) .add("shadowVariables", shadowVariables) .add("skipNonTranspilationPasses", skipNonTranspilationPasses) .add("smartNameRemoval", smartNameRemoval) .add("sourceMapDetailLevel", sourceMapDetailLevel) .add("sourceMapFormat", sourceMapFormat) .add("sourceMapLocationMappings", sourceMapLocationMappings) .add("sourceMapOutputPath", sourceMapOutputPath) .add("stripNamePrefixes", stripNamePrefixes) .add("stripNameSuffixes", stripNameSuffixes) .add("stripTypePrefixes", stripTypePrefixes) .add("stripTypes", stripTypes) .add("summaryDetailLevel", summaryDetailLevel) .add("syntheticBlockEndMarker", syntheticBlockEndMarker) .add("syntheticBlockStartMarker", syntheticBlockStartMarker) .add("tcProjectId", tcProjectId) .add("tracer", tracer) .add("transformAMDToCJSModules", transformAMDToCJSModules) .add("trustedStrings", trustedStrings) .add("tweakProcessing", getTweakProcessing()) .add("tweakReplacements", getTweakReplacements()) .add("useNewTypeInference", getNewTypeInference()) .add("emitUseStrict", emitUseStrict) .add("useTypesForLocalOptimization", useTypesForLocalOptimization) .add("variableRenaming", variableRenaming) .add("warningsGuard", getWarningsGuard()) .add("wrapGoogModulesForWhitespaceOnly", wrapGoogModulesForWhitespaceOnly) .toString(); return strValue; } ////////////////////////////////////////////////////////////////////////////// // Enums /** * A language mode applies to the whole compilation job. * As a result, the compiler does not support mixed strict and non-strict in * the same compilation job. Therefore, the 'use strict' directive is ignored * when the language mode is not strict. */ public static enum LanguageMode { /** * 90's JavaScript */ ECMASCRIPT3, /** * Traditional JavaScript */ ECMASCRIPT5, /** * Nitpicky, traditional JavaScript */ ECMASCRIPT5_STRICT, /** ECMAScript standard approved in 2015. */ ECMASCRIPT_2015, /** * A superset of ES6 which adds Typescript-style type declarations. Always strict. */ ECMASCRIPT6_TYPED, /** * ECMAScript standard approved in 2016. * Adds the exponent operator (**). */ ECMASCRIPT_2016, /** ECMAScript standard approved in 2017. Adds async/await and other syntax */ ECMASCRIPT_2017, /** ECMAScript latest draft standard. */ ECMASCRIPT_NEXT, /** * For languageOut only. The same language mode as the input. */ NO_TRANSPILE; /** Whether this language mode defaults to strict mode */ boolean isDefaultStrict() { switch (this) { case ECMASCRIPT3: case ECMASCRIPT5: return false; default: return true; } } /** Whether this is ECMAScript 6 or higher. */ @Deprecated public boolean isEs6OrHigher() { return this.toFeatureSet().contains(FeatureSet.ES6); } public static LanguageMode fromString(String value) { if (value == null) { return null; } // Trim spaces, disregard case, and allow abbreviation of ECMASCRIPT for convenience. String canonicalizedName = Ascii.toUpperCase(value.trim()).replaceFirst("^ES", "ECMASCRIPT"); if (canonicalizedName.equals("ECMASCRIPT6") || canonicalizedName.equals("ECMASCRIPT6_STRICT")) { return ECMASCRIPT_2015; } try { return LanguageMode.valueOf(canonicalizedName); } catch (IllegalArgumentException e) { return null; // unknown name. } } FeatureSet toFeatureSet() { switch (this) { case ECMASCRIPT3: return FeatureSet.ES3; case ECMASCRIPT5: case ECMASCRIPT5_STRICT: return FeatureSet.ES5; case ECMASCRIPT_2015: return FeatureSet.ES6_MODULES; case ECMASCRIPT_2016: return FeatureSet.ES7_MODULES; case ECMASCRIPT_2017: return FeatureSet.ES8_MODULES; case ECMASCRIPT_NEXT: return FeatureSet.ES_NEXT; case ECMASCRIPT6_TYPED: return FeatureSet.TYPESCRIPT; case NO_TRANSPILE: throw new IllegalStateException(); } throw new IllegalStateException(); } } /** When to do the extra validity checks */ public static enum DevMode { /** * Don't do any extra checks. */ OFF, /** * After the initial parse */ START, /** * At the start and at the end of all optimizations. */ START_AND_END, /** * After every pass */ EVERY_PASS } /** How much tracing we want to do */ public static enum TracerMode { ALL, // Collect all timing and size metrics. Very slow. RAW_SIZE, // Collect all timing and size metrics, except gzipped size. Slow. AST_SIZE, // For size data, don't serialize the AST, just count the number of nodes. TIMING_ONLY, // Collect timing metrics only. OFF; // Collect no timing and size metrics. boolean isOn() { return this != OFF; } } /** Option for the ProcessTweaks pass */ public static enum TweakProcessing { OFF, // Do not run the ProcessTweaks pass. CHECK, // Run the pass, but do not strip out the calls. STRIP; // Strip out all calls to goog.tweak.*. public boolean isOn() { return this != OFF; } public boolean shouldStrip() { return this == STRIP; } } /** What kind of isolation is going to be used */ public static enum IsolationMode { NONE, // output does not include additional isolation. IIFE; // The output should be wrapped in an IIFE to isolate global variables. } /** * A Role Specific Interface for JS Compiler that represents a data holder * object which is used to store goog.scope alias code changes to code made * during a compile. There is no guarantee that individual alias changes are * invoked in the order they occur during compilation, so implementations * should not assume any relevance to the order changes arrive. *

* Calls to the mutators are expected to resolve very quickly, so * implementations should not perform expensive operations in the mutator * methods. * * @author [email protected] (Tyler Goodwin) */ public interface AliasTransformationHandler { /** * Builds an AliasTransformation implementation and returns it to the * caller. *

* Callers are allowed to request multiple AliasTransformation instances for * the same file, though it is expected that the first and last char values * for multiple instances will not overlap. *

* This method is expected to have a side-effect of storing off the created * AliasTransformation, which guarantees that invokers of this interface * cannot leak AliasTransformation to this implementation that the * implementor did not create * * @param sourceFile the source file the aliases re contained in. * @param position the region of the source file associated with the * goog.scope call. The item of the SourcePosition is the returned * AliasTransformation */ public AliasTransformation logAliasTransformation( String sourceFile, SourcePosition position); } /** * A Role Specific Interface for the JS Compiler to report aliases used to * change the code during a compile. *

* While aliases defined by goog.scope are expected to by only 1 per file, and * the only top-level structure in the file, this is not enforced. */ public interface AliasTransformation { /** * Adds an alias definition to the AliasTransformation instance. *

* Last definition for a given alias is kept if an alias is inserted * multiple times (since this is generally the behavior in JavaScript code). * * @param alias the name of the alias. * @param definition the definition of the alias. */ void addAlias(String alias, String definition); } /** * A Null implementation of the CodeChanges interface which performs all * operations as a No-Op */ static final AliasTransformationHandler NULL_ALIAS_TRANSFORMATION_HANDLER = new NullAliasTransformationHandler(); private static class NullAliasTransformationHandler implements AliasTransformationHandler { private static final AliasTransformation NULL_ALIAS_TRANSFORMATION = new NullAliasTransformation(); @Override public AliasTransformation logAliasTransformation( String sourceFile, SourcePosition position) { position.setItem(NULL_ALIAS_TRANSFORMATION); return NULL_ALIAS_TRANSFORMATION; } private static class NullAliasTransformation implements AliasTransformation { @Override public void addAlias(String alias, String definition) { } } } /** * An environment specifies the built-in externs that are loaded for a given * compilation. */ public static enum Environment { /** * Hand crafted externs that have traditionally been the default externs. */ BROWSER, /** * Only language externs are loaded. */ CUSTOM } /** * Whether standard input or standard output should be an array of * JSON encoded files */ static enum JsonStreamMode { /** * stdin/out are both single files. */ NONE, /** * stdin is a json stream. */ IN, /** * stdout is a json stream. */ OUT, /** * stdin and stdout are both json streams. */ BOTH } /** How compiler should prune files based on the provide-require dependency graph */ public static enum DependencyMode { /** * All files will be included in the compilation */ NONE, /** * Files must be discoverable from specified entry points. Files * which do not goog.provide a namespace and are not either * an ES6 or CommonJS module will be automatically treated as entry points. * Module files will be included only if referenced from an entry point. */ LOOSE, /** * Files must be discoverable from specified entry points. Files which * do not goog.provide a namespace and are neither * an ES6 or CommonJS module will be dropped. Module files will be included * only if referenced from an entry point. */ STRICT } /** * A mode enum used to indicate whether J2clPass should be enabled, disabled, or enabled * automatically if there is any J2cl source file (i.e. in the AUTO mode). */ public static enum J2clPassMode { /** J2clPass is disabled. */ OFF, /** It auto-detects whether there are J2cl generated file. If yes, execute J2clPass. */ AUTO; boolean shouldAddJ2clPasses() { return this == AUTO; } } public boolean expectStrictModeInput() { return isStrictModeInput.or(getLanguageIn().isDefaultStrict()); } public CompilerOptions setStrictModeInput(boolean isStrictModeInput) { this.isStrictModeInput = Optional.of(isStrictModeInput); return this; } public char[] getPropertyReservedNamingFirstChars() { char[] reservedChars = anonymousFunctionNaming.getReservedCharacters(); if (polymerVersion != null && polymerVersion > 1) { if (reservedChars == null) { reservedChars = POLYMER_PROPERTY_RESERVED_FIRST_CHARS; } else { reservedChars = Chars.concat(reservedChars, POLYMER_PROPERTY_RESERVED_FIRST_CHARS); } } else if (angularPass) { if (reservedChars == null) { reservedChars = ANGULAR_PROPERTY_RESERVED_FIRST_CHARS; } else { reservedChars = Chars.concat(reservedChars, ANGULAR_PROPERTY_RESERVED_FIRST_CHARS); } } return reservedChars; } public char[] getPropertyReservedNamingNonFirstChars() { char[] reservedChars = anonymousFunctionNaming.getReservedCharacters(); if (polymerVersion != null && polymerVersion > 1) { if (reservedChars == null) { reservedChars = POLYMER_PROPERTY_RESERVED_NON_FIRST_CHARS; } else { reservedChars = Chars.concat(reservedChars, POLYMER_PROPERTY_RESERVED_NON_FIRST_CHARS); } } return reservedChars; } @GwtIncompatible("ObjectOutputStream") private void writeObject(ObjectOutputStream out) throws IOException, ClassNotFoundException { out.defaultWriteObject(); out.writeObject(outputCharset == null ? null : outputCharset.name()); } @GwtIncompatible("ObjectInputStream") private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); String outputCharsetName = (String) in.readObject(); if (outputCharsetName != null) { outputCharset = Charset.forName(outputCharsetName); } } boolean shouldOptimize() { return !skipNonTranspilationPasses && !checksOnly && !shouldGenerateTypedExterns() && !instrumentForCoverageOnly; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy