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

com.google.javascript.jscomp.JSError 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 2004 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.Strings.emptyToNull;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.javascript.rhino.Node;
import java.io.Serializable;
import java.util.Objects;
import org.jspecify.nullness.Nullable;

/** Compile error description. */
@AutoValue
public abstract class JSError implements Serializable {

  /** A type of the error. */
  public abstract DiagnosticType getType();

  /** Description of the error. */
  public abstract String getDescription();

  /** Name of the source */
  public abstract @Nullable String getSourceName();

  /** One-indexed line number of the error location. */
  public abstract int getLineno();

  /** Zero-indexed character number of the error location. */
  public abstract int getCharno();

  /** Node where the warning occurred. */
  public abstract @Nullable Node getNode();

  /** The default level, before any of the {@code WarningsGuard}s are applied. */
  public abstract CheckLevel getDefaultLevel();

  private static final int DEFAULT_LINENO = -1;
  private static final int DEFAULT_CHARNO = -1;
  private static final @Nullable String DEFAULT_SOURCENAME = null;
  private static final @Nullable Node DEFAULT_NODE = null;

  /**
   * Creates a JSError with no source information
   *
   * @param type The DiagnosticType
   * @param arguments Arguments to be incorporated into the message
   */
  public static JSError make(DiagnosticType type, String... arguments) {
    return builder(type, arguments).build();
  }

  /**
   * Creates a JSError at a given source location
   *
   * @param sourceName The source file name
   * @param lineno Line number with source file, or -1 if unknown
   * @param charno Column number within line, or -1 for whole line.
   * @param type The DiagnosticType
   * @param arguments Arguments to be incorporated into the message
   */
  public static JSError make(
      String sourceName, int lineno, int charno, DiagnosticType type, String... arguments) {
    return builder(type, arguments).setSourceLocation(sourceName, lineno, charno).build();
  }

  /**
   * Creates a JSError from a file and Node position.
   *
   * @param n Determines the line and char position and source file name
   * @param type The DiagnosticType
   * @param arguments Arguments to be incorporated into the message
   */
  public static JSError make(Node n, DiagnosticType type, String... arguments) {
    return builder(type, arguments).setNode(n).build();
  }

  static final class Builder {
    private final DiagnosticType type;
    private final String[] args;

    private CheckLevel level;
    private Node n = DEFAULT_NODE;
    private String sourceName = DEFAULT_SOURCENAME;
    private int lineno = DEFAULT_LINENO;
    private int charno = DEFAULT_CHARNO;

    private Builder(DiagnosticType type, String... args) {
      this.type = type;
      this.args = args;
      this.level = type.level; // may be overwritten later
    }

    /**
     * Sets the location where this error occurred.
     *
     * 

Incompatible with {@link #setSourceLocation(String, int, int)} */ @CanIgnoreReturnValue Builder setNode(Node n) { Preconditions.checkState( Objects.equals(DEFAULT_SOURCENAME, this.sourceName), "Cannot provide a Node when there's already a source name"); this.n = n; this.sourceName = n.getSourceFileName(); this.lineno = n.getLineno(); this.charno = n.getCharno(); return this; } /** * Sets the default level, before any WarningGuards, of this JSError. Overwrites the default * level of the DiagnosticType. * *

This method is rarely useful: prefer whenever possible to rely on the default level of the * DiagnosticType. */ @CanIgnoreReturnValue Builder setLevel(CheckLevel level) { this.level = Preconditions.checkNotNull(level); return this; } /** * Sets the location where this error occurred * *

Incompatible with {@link #setNode(Node)} * * @param sourceName The source file name * @param lineno Line number with source file, or -1 if unknown * @param charno Column number within line, or -1 for whole line. */ @CanIgnoreReturnValue Builder setSourceLocation(String sourceName, int lineno, int charno) { Preconditions.checkState( this.n == DEFAULT_NODE, "Cannot provide a source location when there is already a Node"); this.sourceName = sourceName; this.lineno = lineno; this.charno = charno; return this; } JSError build() { return new AutoValue_JSError(type, type.format(args), sourceName, lineno, charno, n, level); } } /** * Creates a new builder. * * @param type the associated DiagnosticType * @param arguments formatting arguments used to format the DiagnosticType's description */ static Builder builder(DiagnosticType type, String... arguments) { return new Builder(type, arguments); } /** @return the default rendering of an error as text. */ @Override public final String toString() { String sourceName = emptyToNull(this.getSourceName()) != null ? this.getSourceName() : "(unknown source)"; String lineno = this.getLineno() != DEFAULT_LINENO ? String.valueOf(this.getLineno()) : "(unknown line)"; String charno = this.getCharno() != DEFAULT_CHARNO ? String.valueOf(this.getCharno()) : "(unknown column)"; return this.getType().key + ". " + this.getDescription() + " at " + sourceName + " line " + lineno + " : " + charno; } /** * Format a message at the given level. * * @return the formatted message or {@code null} */ public final @Nullable String format(CheckLevel level, MessageFormatter formatter) { switch (level) { case ERROR: return formatter.formatError(this); case WARNING: return formatter.formatWarning(this); default: return null; } } /** @return the offset of the region the Error applies to, or -1 if the offset is unknown. */ public final int getNodeSourceOffset() { return this.getNode() != null ? this.getNode().getSourceOffset() : -1; } /** @return the length of the region the Error applies to, or 0 if the length is unknown. */ public final int getNodeLength() { return this.getNode() != null ? this.getNode().getLength() : 0; } /** Alias for {@link #getLineno()}. */ public final int getLineNumber() { return this.getLineno(); } JSError() { // Package private. } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy