blob: 22abd3e7c5c40c25e5e16ca6829a823514c007b3 [file] [log] [blame]
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* 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.turbine.diag;
import static com.google.common.base.MoreObjects.firstNonNull;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
/** A compilation error. */
public class TurbineError extends Error {
/** A diagnostic kind. */
public enum ErrorKind {
UNEXPECTED_INPUT("unexpected input: %c"),
UNEXPECTED_IDENTIFIER("unexpected identifier '%s'"),
UNEXPECTED_EOF("unexpected end of input"),
EXPECTED_TOKEN("expected token %s"),
INVALID_LITERAL("invalid literal: %s"),
UNEXPECTED_TYPE_PARAMETER("unexpected type parameter %s"),
SYMBOL_NOT_FOUND("symbol not found %s"),
TYPE_PARAMETER_QUALIFIER("type parameter used as type qualifier"),
UNEXPECTED_TOKEN("unexpected token: %s"),
INVALID_ANNOTATION_ARGUMENT("invalid annotation argument"),
CANNOT_RESOLVE("cannot resolve %s"),
EXPRESSION_ERROR("could not evaluate constant expression"),
CYCLIC_HIERARCHY("cycle in class hierarchy: %s"),
NOT_AN_ANNOTATION("%s is not an annotation"),
NONREPEATABLE_ANNOTATION("%s is not @Repeatable"),
DUPLICATE_DECLARATION("duplicate declaration of %s");
private final String message;
ErrorKind(String message) {
this.message = message;
}
String format(Object... args) {
return String.format(message, args);
}
}
/**
* Formats a diagnostic.
*
* @param source the source file
* @param position the diagnostic position
* @param kind the error kind
* @param args format args
*/
public static TurbineError format(
SourceFile source, int position, ErrorKind kind, Object... args) {
String path = firstNonNull(source.path(), "<>");
LineMap lineMap = LineMap.create(source.source());
int lineNumber = lineMap.lineNumber(position);
int column = lineMap.column(position);
String message = kind.format(args);
StringBuilder sb = new StringBuilder(path).append(":");
sb.append(lineNumber).append(": error: ");
sb.append(message.trim()).append(System.lineSeparator());
sb.append(CharMatcher.breakingWhitespace().trimTrailingFrom(lineMap.line(position)))
.append(System.lineSeparator());
sb.append(Strings.repeat(" ", column)).append('^');
String diagnostic = sb.toString();
return new TurbineError(kind, diagnostic);
}
final ErrorKind kind;
private TurbineError(ErrorKind kind, String diagnostic) {
super(diagnostic);
this.kind = kind;
}
/** The diagnostic kind. */
public ErrorKind kind() {
return kind;
}
}