com.google.javascript.jscomp.RhinoErrorReporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.frontend.js.minifier
Show all versions of com.liferay.frontend.js.minifier
Liferay Frontend JS Minifier
/*
* 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.common.collect.ImmutableMap;
import com.google.javascript.rhino.ErrorReporter;
import com.google.javascript.rhino.Msg;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
/**
* An error reporter for serializing Rhino errors into our error format.
*/
class RhinoErrorReporter {
static final DiagnosticType PARSE_ERROR =
DiagnosticType.error("JSC_PARSE_ERROR", "Parse error. {0}");
static final DiagnosticType TYPE_PARSE_ERROR =
DiagnosticType.warning("JSC_TYPE_PARSE_ERROR", "{0}");
static final DiagnosticType UNRECOGNIZED_TYPE_ERROR =
DiagnosticType.warning("JSC_UNRECOGNIZED_TYPE_ERROR", "{0}");
static final DiagnosticType UNRECOGNIZED_TYPEOF_ERROR =
DiagnosticType.warning("JSC_UNRECOGNIZED_TYPEOF_ERROR", "{0}");
// This is separate from TYPE_PARSE_ERROR because there are many instances of this warning
// and it is unfeasible to fix them all right away.
static final DiagnosticType JSDOC_MISSING_BRACES_WARNING =
DiagnosticType.disabled("JSC_JSDOC_MISSING_BRACES_WARNING", "{0}");
// This is separate from TYPE_PARSE_ERROR because there are many instances of this warning
// and it is unfeasible to fix them all right away.
static final DiagnosticType JSDOC_MISSING_TYPE_WARNING =
DiagnosticType.disabled("JSC_JSDOC_MISSING_TYPE_WARNING", "{0}");
// Import is supported by VSCode and is pretty much a standard now.
static final DiagnosticType JSDOC_IMPORT_TYPE_WARNING =
DiagnosticType.disabled("JSC_JSDOC_IMPORT_TYPE_WARNING", "{0}");
static final DiagnosticType TOO_MANY_TEMPLATE_PARAMS =
DiagnosticType.disabled("JSC_TOO_MANY_TEMPLATE_PARAMS", "{0}");
// Special-cased errors, so that they can be configured via the
// warnings API.
static final DiagnosticType TRAILING_COMMA =
DiagnosticType.error("JSC_TRAILING_COMMA",
"Parse error. IE8 (and below) will parse trailing commas in " +
"array and object literals incorrectly. " +
"If you are targeting newer versions of JS, " +
"set the appropriate language_in option.");
static final DiagnosticType DUPLICATE_PARAM =
DiagnosticType.error("JSC_DUPLICATE_PARAM", "Parse error. {0}");
static final DiagnosticType DUPLICATE_VISIBILITY =
DiagnosticType.warning("JSC_DUPLICATE_VISIBILITY", "{0}");
static final DiagnosticType UNNECESSARY_ESCAPE =
DiagnosticType.disabled("JSC_UNNECESSARY_ESCAPE", "Parse error. {0}");
static final DiagnosticType INVALID_PARAM =
DiagnosticType.warning("JSC_INVALID_PARAM", "Parse error. {0}");
static final DiagnosticType BAD_JSDOC_ANNOTATION =
DiagnosticType.warning("JSC_BAD_JSDOC_ANNOTATION", "Parse error. {0}");
static final DiagnosticType INVALID_ES3_PROP_NAME = DiagnosticType.warning(
"JSC_INVALID_ES3_PROP_NAME",
"Keywords and reserved words are not allowed as unquoted property " +
"names in older versions of JavaScript. " +
"If you are targeting newer versions of JavaScript, " +
"set the appropriate language_in option.");
static final DiagnosticType PARSE_TREE_TOO_DEEP =
DiagnosticType.error("JSC_PARSE_TREE_TOO_DEEP", "Parse tree too deep.");
static final DiagnosticType INVALID_OCTAL_LITERAL =
DiagnosticType.warning(
"JSC_INVALID_OCTAL_LITERAL",
"This style of octal literal is not supported in strict mode.");
static final DiagnosticType STRING_CONTINUATION =
DiagnosticType.warning("JSC_STRING_CONTINUATION", "{0}");
static final DiagnosticType LANGUAGE_FEATURE =
DiagnosticType.error("JSC_LANGUAGE_FEATURE", "{0}.");
static final DiagnosticType UNSUPPORTED_LANGUAGE_FEATURE =
DiagnosticType.error("JSC_UNSUPPORTED_LANGUAGE_FEATURE", "{0}.");
static final DiagnosticType UNSUPPORTED_BOUNDED_GENERIC_TYPES =
DiagnosticType.error(
"JSC_UNSUPPORTED_BOUNDED_GENERIC_TYPES",
"Bounded generic semantics are currently still in development");
static final DiagnosticType BOUNDED_GENERIC_TYPE_ERROR =
DiagnosticType.error(
"JSC_BOUNDED_GENERIC_TYPE_ERROR",
"Bounded generic type error. "
+ "{0} assigned to template type {1} is not a subtype of bound {2}");
// A map of Rhino messages to their DiagnosticType.
private static final Map typeMap =
ImmutableMap.builder()
// Trailing comma
.put(
Pattern.compile("Trailing comma is not legal in an ECMA-262 object initializer"),
TRAILING_COMMA)
// Duplicate parameter
.put(replacePlaceHolders("Duplicate parameter name \"{0}\""), DUPLICATE_PARAM)
// Duplicate visiblity
.put(replacePlaceHolders(Msg.JSDOC_EXTRA_VISIBILITY.format()), DUPLICATE_VISIBILITY)
.put(Pattern.compile("Unnecessary escape:.*"), UNNECESSARY_ESCAPE)
.put(Pattern.compile("^invalid param name.*"), INVALID_PARAM)
// Unknown @annotations.
.put(replacePlaceHolders(Msg.BAD_JSDOC_TAG.format()), BAD_JSDOC_ANNOTATION)
.put(
Pattern.compile(
"^Keywords and reserved words are not allowed as unquoted property.*"),
INVALID_ES3_PROP_NAME)
.put(Pattern.compile("^Too many template parameters\n.*"), TOO_MANY_TEMPLATE_PARAMS)
// Type annotation warnings.
.put(
Pattern.compile(".*Type annotations should have curly braces.*"),
JSDOC_MISSING_BRACES_WARNING)
.put(Pattern.compile("Missing type declaration\\."), JSDOC_MISSING_TYPE_WARNING)
// Unresolved types that aren't forward declared.
.put(Pattern.compile(".*Unknown type.*"), UNRECOGNIZED_TYPE_ERROR)
.put(Pattern.compile(".*Unknown type.*\n.*"), UNRECOGNIZED_TYPE_ERROR)
// Unrecognized `typeof some.prop` errors
.put(Pattern.compile("^Missing type for `typeof` value.*"), UNRECOGNIZED_TYPEOF_ERROR)
// Import annotation errors.
.put(
Pattern.compile("^Bad type annotation. Import in typedef.*"),
JSDOC_IMPORT_TYPE_WARNING)
// Type annotation errors.
.put(Pattern.compile("^Bad type annotation.*"), TYPE_PARSE_ERROR)
// Parse tree too deep.
.put(Pattern.compile("Too deep recursion while parsing"), PARSE_TREE_TOO_DEEP)
// Old-style octal literals
.put(Pattern.compile("^Octal .*literal.*"), INVALID_OCTAL_LITERAL)
.put(Pattern.compile("^String continuations.*"), STRING_CONTINUATION)
.put(Pattern.compile("^This language feature is only supported for .*"), LANGUAGE_FEATURE)
.put(
Pattern.compile(
"^This language feature is not currently supported by the compiler:" + " .*"),
UNSUPPORTED_LANGUAGE_FEATURE)
.put(
Pattern.compile("Bounded generic semantics are currently still in development"),
UNSUPPORTED_BOUNDED_GENERIC_TYPES)
.put(Pattern.compile("^Bounded generic type error.*"), BOUNDED_GENERIC_TYPE_ERROR)
.buildOrThrow();
private final ErrorHandler internalReporter;
/**
* For each message such as "Not a good use of {0}", replace the place holder {0} with a wild card
* that matches all possible strings. Also put the any non-place-holder in quotes for regex
* matching later.
*/
private static Pattern replacePlaceHolders(String s) {
s = Pattern.quote(s);
return Pattern.compile(s.replaceAll("\\{\\d+\\}", "\\\\E.*\\\\Q"));
}
private RhinoErrorReporter(ErrorHandler internalReporter) {
this.internalReporter = internalReporter;
}
public static ErrorReporter forOldRhino(ErrorHandler internalReporter) {
return new OldRhinoErrorReporter(internalReporter);
}
void warningAtLine(String message, String sourceName, int line,
int lineOffset) {
internalReporter.report(
null, makeError(message, sourceName, line, lineOffset, CheckLevel.WARNING));
}
void errorAtLine(String message, String sourceName, int line,
int lineOffset) {
internalReporter.report(
null, makeError(message, sourceName, line, lineOffset, CheckLevel.ERROR));
}
protected static DiagnosticType mapError(String message) {
for (Entry entry : typeMap.entrySet()) {
if (entry.getKey().matcher(message).matches()) {
return entry.getValue();
}
}
return null;
}
private static JSError makeError(
String message, String sourceName, int line, int lineOffset, CheckLevel defaultLevel) {
// Try to see if the message is one of the rhino errors we want to
// expose as DiagnosticType by matching it with the regex key.
DiagnosticType type = mapError(message);
return (type != null)
? JSError.make(sourceName, line, lineOffset, type, message)
: JSError.make(sourceName, line, lineOffset, defaultLevel, PARSE_ERROR, message);
}
private static class OldRhinoErrorReporter extends RhinoErrorReporter
implements ErrorReporter {
private OldRhinoErrorReporter(ErrorHandler internalReporter) {
super(internalReporter);
}
@Override
public void error(String message, String sourceName, int line,
int lineOffset) {
super.errorAtLine(message, sourceName, line, lineOffset);
}
@Override
public void warning(String message, String sourceName, int line,
int lineOffset) {
super.warningAtLine(message, sourceName, line, lineOffset);
}
}
}