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

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

There is a newer version: 9.0.8
Show newest version
/*
 * Copyright 2007 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.common.base.Objects;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;

/**
 * 

A basic error manager that sorts all errors and warnings reported to it to * generate a sorted report when the {@link #generateReport()} method * is called.

* *

This error manager does not produce any output, but subclasses can * override the {@link #println(CheckLevel, JSError)} method to generate custom * output.

* */ public abstract class BasicErrorManager implements ErrorManager { final PriorityQueue messages = new PriorityQueue<>(1, new LeveledJSErrorComparator()); private final Set alreadyAdded = new HashSet<>(); private int errorCount = 0; private int warningCount = 0; private double typedPercent = 0.0; @Override public void report(CheckLevel level, JSError error) { ErrorWithLevel e = new ErrorWithLevel(error, level); if (alreadyAdded.add(e)) { messages.add(e); if (level == CheckLevel.ERROR) { errorCount++; } else if (level == CheckLevel.WARNING) { warningCount++; } } } @Override public void generateReport() { List list = new ArrayList<>(); for (ErrorWithLevel message = messages.poll(); message != null; message = messages.poll()) { println(message.level, message.error); list.add(message); } // Restore the messages since some tests assert the values after generating the report. messages.addAll(list); printSummary(); } /** * Print a message with a trailing new line. This method is called by the * {@link #generateReport()} method when generating messages. */ public abstract void println(CheckLevel level, JSError error); /** * Print the summary of the compilation - number of errors and warnings. */ protected abstract void printSummary(); @Override public int getErrorCount() { return errorCount; } @Override public int getWarningCount() { return warningCount; } @Override public JSError[] getErrors() { return toArray(CheckLevel.ERROR); } @Override public JSError[] getWarnings() { return toArray(CheckLevel.WARNING); } @Override public void setTypedPercent(double typedPercent) { this.typedPercent = typedPercent; } @Override public double getTypedPercent() { return typedPercent; } private JSError[] toArray(CheckLevel level) { List errors = new ArrayList<>(messages.size()); for (ErrorWithLevel p : messages) { if (p.level == level) { errors.add(p.error); } } return errors.toArray(new JSError[0]); } /** * Comparator of {@link JSError} with an associated {@link CheckLevel}. The ordering is the * standard lexical ordering on the quintuple (file name, line number, {@link CheckLevel}, * character number, description). * *

Note: this comparator imposes orderings that are inconsistent with {@link * JSError#equals(Object)}. */ static final class LeveledJSErrorComparator implements Comparator { private static final int P1_LT_P2 = -1; private static final int P1_GT_P2 = 1; @Override public int compare(ErrorWithLevel p1, ErrorWithLevel p2) { // null is the smallest value if (p2 == null) { if (p1 == null) { return 0; } else { return P1_GT_P2; } } // check level if (p1.level != p2.level) { return p2.level.compareTo(p1.level); } // sourceName comparison String source1 = p1.error.sourceName; String source2 = p2.error.sourceName; if (source1 != null && source2 != null) { int sourceCompare = source1.compareTo(source2); if (sourceCompare != 0) { return sourceCompare; } } else if (source1 == null && source2 != null) { return P1_LT_P2; } else if (source1 != null && source2 == null) { return P1_GT_P2; } // lineno comparison int lineno1 = p1.error.lineNumber; int lineno2 = p2.error.lineNumber; if (lineno1 != lineno2) { return lineno1 - lineno2; } else if (lineno1 < 0 && 0 <= lineno2) { return P1_LT_P2; } else if (0 <= lineno1 && lineno2 < 0) { return P1_GT_P2; } // charno comparison int charno1 = p1.error.getCharno(); int charno2 = p2.error.getCharno(); if (charno1 != charno2) { return charno1 - charno2; } else if (charno1 < 0 && 0 <= charno2) { return P1_LT_P2; } else if (0 <= charno1 && charno2 < 0) { return P1_GT_P2; } // description return p1.error.description.compareTo(p2.error.description); } } static class ErrorWithLevel { final JSError error; final CheckLevel level; ErrorWithLevel(JSError error, CheckLevel level) { this.error = error; this.level = level; } @Override public int hashCode() { return Objects.hashCode( level, error.description, error.sourceName, error.lineNumber, error.getCharno()); } @Override public boolean equals(Object obj) { return obj.hashCode() == this.hashCode(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy