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

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

/*
 * 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 com.google.javascript.jscomp.CompilerOptions.PropertyCollapseLevel;
import com.google.javascript.jscomp.CompilerOptions.Reach;
import org.jspecify.nullness.Nullable;

/**
 * A CompilationLevel represents the level of optimization that should be
 * applied when compiling JavaScript code.
 */
public enum CompilationLevel {
  /** BUNDLE Simply orders and concatenates files to the output. */
  BUNDLE,

  /**
   * WHITESPACE_ONLY removes comments and extra whitespace in the input JS.
   */
  WHITESPACE_ONLY,

  /**
   * SIMPLE_OPTIMIZATIONS performs transformations to the input JS that do not
   * require any changes to JS that depend on the input JS. For example,
   * function arguments are renamed (which should not matter to code that
   * depends on the input JS), but functions themselves are not renamed (which
   * would otherwise require external code to change to use the renamed function
   * names).
   */
  SIMPLE_OPTIMIZATIONS,

  /**
   * ADVANCED_OPTIMIZATIONS aggressively reduces code size by renaming function
   * names and variables, removing code which is never called, etc.
   */
  ADVANCED_OPTIMIZATIONS,
  ;

  public static @Nullable CompilationLevel fromString(String value) {
    if (value == null) {
      return null;
    }
    switch (value) {
      case "BUNDLE":
        return CompilationLevel.BUNDLE;
      case "WHITESPACE_ONLY":
      case "WHITESPACE":
        return CompilationLevel.WHITESPACE_ONLY;
      case "SIMPLE_OPTIMIZATIONS":
      case "SIMPLE":
        return CompilationLevel.SIMPLE_OPTIMIZATIONS;
      case "ADVANCED_OPTIMIZATIONS":
      case "ADVANCED":
        return CompilationLevel.ADVANCED_OPTIMIZATIONS;
      default:
        return null;
    }
  }

  private CompilationLevel() {}

  public void setOptionsForCompilationLevel(CompilerOptions options) {
    switch (this) {
      case BUNDLE:
        break;
      case WHITESPACE_ONLY:
        applyBasicCompilationOptions(options);
        break;
      case SIMPLE_OPTIMIZATIONS:
        applySafeCompilationOptions(options);
        break;
      case ADVANCED_OPTIMIZATIONS:
        applyFullCompilationOptions(options);
        break;
    }
  }

  public void setDebugOptionsForCompilationLevel(CompilerOptions options) {
    options.generatePseudoNames = true;
    options.removeClosureAsserts = false;
    options.removeJ2clAsserts = false;
  }

  /**
   * Gets options that only strip whitespace and comments.
   * @param options The CompilerOptions object to set the options on.
   */
  private static void applyBasicCompilationOptions(CompilerOptions options) {
    options.skipAllCompilerPasses();
  }

  /**
   * Add options that are safe. Safe means options that won't break the
   * JavaScript code even if no symbols are exported and no coding convention
   * is used.
   * @param options The CompilerOptions object to set the options on.
   */
  private static void applySafeCompilationOptions(CompilerOptions options) {
    // TODO(tjgq): Remove this.
    options.setDependencyOptions(DependencyOptions.sortOnly());

    // ReplaceIdGenerators is on by default, but should run in simple mode.
    options.replaceIdGenerators = false;

    // Does not call applyBasicCompilationOptions(options) because the call to
    // skipAllCompilerPasses() cannot be easily undone.
    options.setClosurePass(true);
    options.setRenamingPolicy(VariableRenamingPolicy.LOCAL, PropertyRenamingPolicy.OFF);
    options.setInlineVariables(Reach.LOCAL_ONLY);
    options.setInlineFunctions(Reach.LOCAL_ONLY);
    options.setAssumeClosuresOnlyCaptureReferences(false);
    options.setWarningLevel(DiagnosticGroups.GLOBAL_THIS, CheckLevel.OFF);
    options.setFoldConstants(true);
    options.setCoalesceVariableNames(true);
    options.setDeadAssignmentElimination(true);
    options.setCollapseVariableDeclarations(true);
    options.convertToDottedProperties = true;
    options.labelRenaming = true;
    options.setRemoveDeadCode(true);
    options.setOptimizeArgumentsArray(true);
    options.setRemoveUnusedVariables(Reach.LOCAL_ONLY);
    options.collapseObjectLiterals = true;
    options.setProtectHiddenSideEffects(true);
  }

  /**
   * Add the options that will work only if the user exported all the symbols
   * correctly.
   * @param options The CompilerOptions object to set the options on.
   */
  private static void applyFullCompilationOptions(CompilerOptions options) {
    // TODO(tjgq): Remove this.
    options.setDependencyOptions(DependencyOptions.sortOnly());

    // Do not call applySafeCompilationOptions(options) because the call can
    // create possible conflicts between multiple diagnostic groups.

    options.setCheckSymbols(true);
    options.setCheckTypes(true);

    // All the safe optimizations.
    options.setClosurePass(true);
    options.setFoldConstants(true);
    options.setCoalesceVariableNames(true);
    options.setDeadAssignmentElimination(true);
    options.setExtractPrototypeMemberDeclarations(true);
    options.setCollapseVariableDeclarations(true);
    options.setConvertToDottedProperties(true);
    options.setLabelRenaming(true);
    options.setRemoveDeadCode(true);
    options.setOptimizeArgumentsArray(true);
    options.setCollapseObjectLiterals(true);
    options.setProtectHiddenSideEffects(true);

    // All the advanced optimizations.
    options.setRemoveClosureAsserts(true);
    options.setRemoveAbstractMethods(true);
    options.setReserveRawExports(true);
    options.setRenamingPolicy(VariableRenamingPolicy.ALL, PropertyRenamingPolicy.ALL_UNQUOTED);
    options.setRemoveUnusedPrototypeProperties(true);
    options.setRemoveUnusedClassProperties(true);
    options.setCollapseAnonymousFunctions(true);
    options.setCollapsePropertiesLevel(PropertyCollapseLevel.ALL);
    options.setWarningLevel(DiagnosticGroups.GLOBAL_THIS, CheckLevel.WARNING);
    options.setRewriteFunctionExpressions(false);
    options.setSmartNameRemoval(true);
    options.setInlineConstantVars(true);
    options.setInlineFunctions(Reach.ALL);
    options.setAssumeClosuresOnlyCaptureReferences(false);
    options.setInlineVariables(Reach.ALL);
    options.setComputeFunctionSideEffects(true);
    options.setAssumeStrictThis(true);

    // Remove unused vars also removes unused functions.
    options.setRemoveUnusedVariables(Reach.ALL);

    // Move code around based on the defined modules.
    options.setCrossChunkCodeMotion(true);
    options.setCrossChunkMethodMotion(true);

    // Call optimizations
    options.setDevirtualizeMethods(true);
    options.setOptimizeCalls(true);
    options.setOptimizeESClassConstructors(true);
  }

  /**
   * Enable additional optimizations that use type information. Only has
   * an effect for ADVANCED_OPTIMIZATIONS; this is a no-op for other modes.
   * @param options The CompilerOptions object to set the options on.
   */
  public void setTypeBasedOptimizationOptions(CompilerOptions options) {
    switch (this) {
      case ADVANCED_OPTIMIZATIONS:
        options.setDisambiguateProperties(true);
        options.setAmbiguateProperties(true);
        options.setInlineProperties(true);
        options.setUseTypesForLocalOptimization(true);
        break;
      case SIMPLE_OPTIMIZATIONS:
      case WHITESPACE_ONLY:
      case BUNDLE:
        break;
    }
  }

  /**
   * Enable additional optimizations that operate on global declarations. Advanced mode does
   * this by default, but this isn't valid in simple mode in the general case and should only
   * be enabled when code is self contained (such as when it is enclosed by a function wrapper.
   *
   * @param options The CompilerOptions object to set the options on.
   */
  public void setWrappedOutputOptimizations(CompilerOptions options) {
    // Global variables and properties names can't conflict.
    options.reserveRawExports = false;
    switch (this) {
      case SIMPLE_OPTIMIZATIONS:
        // Enable global variable optimizations (but not property optimizations)
        options.setVariableRenaming(VariableRenamingPolicy.ALL);
        options.setCollapsePropertiesLevel(PropertyCollapseLevel.MODULE_EXPORT);
        options.setCollapseAnonymousFunctions(true);
        options.setInlineConstantVars(true);
        options.setInlineFunctions(Reach.ALL);
        options.setInlineVariables(Reach.ALL);
        options.setRemoveUnusedVariables(Reach.ALL);
        break;
      case ADVANCED_OPTIMIZATIONS:
      case WHITESPACE_ONLY:
      case BUNDLE:
        break;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy