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

com.google.javascript.jscomp.colors.Color Maven / Gradle / Ivy

Go to download

Closure Compiler is a JavaScript optimizing compiler. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls. It is used in many of Google's JavaScript apps, including Gmail, Google Web Search, Google Maps, and Google Docs.

There is a newer version: v20240317
Show newest version
/*
 * Copyright 2020 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.colors;

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

import com.google.auto.value.AutoValue;
import com.google.auto.value.extension.memoized.Memoized;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import java.util.LinkedHashSet;
import java.util.Set;
import org.jspecify.nullness.Nullable;

/** A simplified version of a Closure or TS type for use by optimizations */
@AutoValue
public abstract class Color {

  public abstract ColorId getId();

  /** Given `function Foo() {}` or `class Foo {}`, color of Foo.prototype. null otherwise. */
  public abstract ImmutableSet getPrototypes();

  public abstract ImmutableSet getInstanceColors();

  public abstract boolean isInvalidating();

  public abstract boolean getPropertiesKeepOriginalName();

  public abstract boolean isConstructor();

  /**
   * Property names 'declared' on an object (as opposed to being conceptually inherited from some
   * supertype).
   */
  public abstract ImmutableSet getOwnProperties();

  public abstract @Nullable ColorId getBoxId();

  /**
   * Whether this type is some Closure assertion function removable by Closure-specific
   * optimizations.
   */
  public abstract boolean isClosureAssert();

  public abstract ImmutableSet getUnionElements();

  public static Builder singleBuilder() {
    return new AutoValue_Color.Builder()
        .setClosureAssert(false)
        .setConstructor(false)
        .setInstanceColors(ImmutableSet.of())
        .setInvalidating(false)
        .setOwnProperties(ImmutableSet.of())
        .setPropertiesKeepOriginalName(false)
        .setPrototypes(ImmutableSet.of())
        .setUnionElements(ImmutableSet.of());
  }

  public static Color createUnion(Set elements) {
    switch (elements.size()) {
      case 0:
        throw new IllegalStateException();
      case 1:
        return Iterables.getOnlyElement(elements);
      default:
        break;
    }

    ImmutableSet.Builder instanceColors = ImmutableSet.builder();
    ImmutableSet.Builder prototypes = ImmutableSet.builder();
    ImmutableSet.Builder newElements = ImmutableSet.builder();
    ImmutableSet.Builder ids = ImmutableSet.builder();
    ImmutableSet.Builder ownProperties = ImmutableSet.builder();
    boolean isClosureAssert = true;
    boolean isConstructor = true;
    boolean isInvalidating = false;
    boolean propertiesKeepOriginalName = false;

    for (Color element : elements) {
      if (element.isUnion()) {
        for (Color nestedElement : element.getUnionElements()) {
          newElements.add(nestedElement);
          ids.add(nestedElement.getId());
        }
      } else {
        newElements.add(element);
        ids.add(element.getId());
      }

      instanceColors.addAll(element.getInstanceColors());
      isClosureAssert &= element.isClosureAssert();
      isConstructor &= element.isConstructor();
      isInvalidating |= element.isInvalidating();
      ownProperties.addAll(element.getOwnProperties());
      propertiesKeepOriginalName |= element.getPropertiesKeepOriginalName();
      prototypes.addAll(element.getPrototypes());
    }

    return new AutoValue_Color.Builder()
        .setClosureAssert(isClosureAssert)
        .setConstructor(isConstructor)
        .setId(ColorId.union(ids.build()))
        .setInstanceColors(instanceColors.build())
        .setInvalidating(isInvalidating)
        .setOwnProperties(ownProperties.build())
        .setPropertiesKeepOriginalName(propertiesKeepOriginalName)
        .setPrototypes(prototypes.build())
        .setUnionElements(newElements.build())
        .buildUnion();
  }

  Color() {
    // No public constructor.
  }

  /**
   * Whether this corresponds to a single JavaScript primitive like number or symbol.
   *
   * 

Note that the boxed versions of primitives (String, Number, etc.) are /not/ considered * "primitive" by this method. */ public final boolean isPrimitive() { /** * Avoid the design headache about whether unions are primitives. The union *color* isn't * primitive, but the *value* held by a union reference may be. */ checkState(!this.isUnion(), this); return StandardColors.PRIMITIVE_COLORS.containsKey(this.getId()); } public final boolean isUnion() { // Single element sets are banned in the builder. return !this.getUnionElements().isEmpty(); } @Memoized public Color subtractNullOrVoid() { /** Avoid defining NULL_OR_VOID.subtract(NULL_OR_VOID) */ checkState(this.isUnion()); if (!this.getUnionElements().contains(StandardColors.NULL_OR_VOID)) { return this; } LinkedHashSet elements = new LinkedHashSet<>(this.getUnionElements()); elements.remove(StandardColors.NULL_OR_VOID); return createUnion(elements); } /** * Builder for a singleton color. Should be passed to {@link * Color#createSingleton(SingletonColorFields)} after building and before using */ @AutoValue.Builder public abstract static class Builder { public abstract Builder setId(ColorId x); public abstract Builder setInvalidating(boolean x); public abstract Builder setPropertiesKeepOriginalName(boolean x); public abstract Builder setConstructor(boolean x); public abstract Builder setOwnProperties(ImmutableSet x); public abstract Builder setClosureAssert(boolean x); public abstract Builder setInstanceColors(ImmutableSet x); public abstract Builder setPrototypes(ImmutableSet x); abstract Builder setUnionElements(ImmutableSet x); abstract Builder setBoxId(@Nullable ColorId x); public Builder setPrototype(Color x) { return this.setPrototypes((x == null) ? ImmutableSet.of() : ImmutableSet.of(x)); } public Builder setInstanceColor(Color x) { return this.setInstanceColors((x == null) ? ImmutableSet.of() : ImmutableSet.of(x)); } abstract Color buildInternal(); public final Color build() { Color result = this.buildInternal(); checkState(result.getUnionElements().isEmpty(), result); checkState(result.getBoxId() == null, result); checkState(!StandardColors.AXIOMATIC_COLORS.containsKey(result.getId()), result); return result; } private final Color buildUnion() { Color result = this.buildInternal(); checkState(result.getUnionElements().size() > 1, result); checkState(result.getBoxId() == null, result); return result; } final Color buildAxiomatic() { checkState(StandardColors.AXIOMATIC_COLORS == null, "StandardColors are all defined"); Color result = this.buildInternal(); checkState(result.getUnionElements().isEmpty(), result); return result; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy