blob: 4d4c8b161892d788754e53273977b9abc170d342 [file] [log] [blame]
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.runtime;
import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
import java.io.PrintWriter;
import jdk.nashorn.internal.parser.Token;
/**
* Handles JavaScript error reporting.
*/
public class ErrorManager {
// TODO - collect and sort/collapse error messages.
// TODO - property based error messages.
/** Reporting writer. */
private final PrintWriter writer;
/** Error count. */
private int errors;
/** Warning count */
private int warnings;
/** Limit of the number of messages. */
private int limit;
/** Treat warnings as errors. */
private boolean warningsAsErrors;
/**
* Constructor
*/
public ErrorManager() {
this(new PrintWriter(System.err, true)); //bootstrapping, context may not be initialized
}
/**
* Constructor.
* @param writer I/O writer to report on.
*/
public ErrorManager(final PrintWriter writer) {
this.writer = writer;
this.limit = 100;
this.warningsAsErrors = false;
}
/**
* Check to see if number of errors exceed limit.
*/
private void checkLimit() {
int count = errors;
if (warningsAsErrors) {
count += warnings;
}
if (limit != 0 && count > limit) {
throw rangeError("too.many.errors", Integer.toString(limit));
}
}
/**
* Format an error message to include source and line information.
* @param message Error message string.
* @param source Source file information.
* @param line Source line number.
* @param column Source column number.
* @param token Offending token descriptor.
* @return formatted string
*/
public static String format(final String message, final Source source, final int line, final int column, final long token) {
final String eoln = System.lineSeparator();
final int position = Token.descPosition(token);
final StringBuilder sb = new StringBuilder();
// Source description and message.
sb.append(source.getName()).
append(':').
append(line).
append(':').
append(column).
append(' ').
append(message).
append(eoln);
// Source content.
final String sourceLine = source.getSourceLine(position);
sb.append(sourceLine).append(eoln);
// Pointer to column.
for (int i = 0; i < column; i++) {
if (i < sourceLine.length() && sourceLine.charAt(i) == '\t') {
sb.append('\t');
} else {
sb.append(' ');
}
}
sb.append('^');
// Use will append eoln.
// buffer.append(eoln);
return sb.toString();
}
/**
* Report an error using information provided by the ParserException
*
* @param e ParserException object
*/
public void error(final ParserException e) {
error(e.getMessage());
}
/**
* Report an error message provided
*
* @param message Error message string.
*/
public void error(final String message) {
writer.println(message);
writer.flush();
errors++;
checkLimit();
}
/**
* Report a warning using information provided by the ParserException
*
* @param e ParserException object
*/
public void warning(final ParserException e) {
warning(e.getMessage());
}
/**
* Report a warning message provided
*
* @param message Error message string.
*/
public void warning(final String message) {
writer.println(message);
writer.flush();
warnings++;
checkLimit();
}
/**
* Test to see if errors have occurred.
* @return True if errors.
*/
public boolean hasErrors() {
return errors != 0;
}
/**
* Get the message limit
* @return max number of messages
*/
public int getLimit() {
return limit;
}
/**
* Set the message limit
* @param limit max number of messages
*/
public void setLimit(final int limit) {
this.limit = limit;
}
/**
* Check whether warnings should be treated like errors
* @return true if warnings should be treated like errors
*/
public boolean isWarningsAsErrors() {
return warningsAsErrors;
}
/**
* Set warnings to be treated as errors
* @param warningsAsErrors true if warnings should be treated as errors, false otherwise
*/
public void setWarningsAsErrors(final boolean warningsAsErrors) {
this.warningsAsErrors = warningsAsErrors;
}
/**
* Get the number of errors
* @return number of errors
*/
public int getNumberOfErrors() {
return errors;
}
/**
* Get number of warnings
* @return number of warnings
*/
public int getNumberOfWarnings() {
return warnings;
}
/**
* Clear warnings and error count.
*/
void reset() {
warnings = 0;
errors = 0;
}
}