// Copyright (c) 2011, David J. Pearce (djp@ecs.vuw.ac.nz)
// All rights reserved.
//
// This software may be modified and distributed under the terms
// of the BSD license. See the LICENSE file for details.
package wyil.util;
import wyil.lang.Type;
/**
* <p>
* Contains global constants mapping syntax errors to their error messages. The
* purpose of this class is bring all syntax error messages into one place, such
* that:
* </p>
* <ol>
* <li>It's easy to change error messages, and be sure the changes are applied
* universally.</li>
* <li>It's easy to reflect on the set of all error messages, and perhaps find
* ways to improve them.</li>
* </ol>
* <p>
* In short, error message reporting is done poorly by modern compilers and it
* would be nice to do a better job!
* </p>
*
* @author David J. Pearce
*
*/
public class ErrorMessages {
private static class Msg {
String msg;
public Msg(String msg) {
this.msg = msg;
}
}
private static final class MsgWithNoParams extends Msg {
public MsgWithNoParams(String msg) {
super(msg);
}
}
private static final class MsgWithStringParam extends Msg {
public MsgWithStringParam(String msg) {
super(msg);
}
}
private static final class MsgWithTypeParam extends Msg {
public MsgWithTypeParam(String msg) {
super(msg);
}
}
private static final class MsgWithTypeParams extends Msg {
public MsgWithTypeParams(String msg) {
super(msg);
}
}
public static final MsgWithNoParams CYCLIC_CONSTANT_DECLARATION = new MsgWithNoParams("cyclic constant expression");
public static final MsgWithNoParams INVALID_CONSTANT_EXPRESSION = new MsgWithNoParams("invalid constant expression");
public static final MsgWithNoParams INVALID_BOOLEAN_EXPRESSION = new MsgWithNoParams("invalid boolean expression");
public static final MsgWithNoParams INVALID_NUMERIC_EXPRESSION = new MsgWithNoParams("invalid numeric expression");
public static final MsgWithNoParams INVALID_UNARY_EXPRESSION = new MsgWithNoParams("invalid unary expression");
public static final MsgWithNoParams INVALID_BINARY_EXPRESSION = new MsgWithNoParams("invalid binary expression");
public static final MsgWithNoParams INVALID_ARRAY_EXPRESSION = new MsgWithNoParams("invalid array expression");
public static final MsgWithNoParams INVALID_LVAL_EXPRESSION = new MsgWithNoParams("invalid assignment expression");
public static final MsgWithNoParams INVALID_TUPLE_LVAL = new MsgWithNoParams("invalid tuple lval");
public static final MsgWithNoParams INVALID_FILE_ACCESS = new MsgWithNoParams("invalid file access");
public static final MsgWithNoParams INVALID_PACKAGE_ACCESS = new MsgWithNoParams("invalid package access");
public static final MsgWithNoParams BREAK_OUTSIDE_SWITCH_OR_LOOP = new MsgWithNoParams("break outside switch or loop");
public static final MsgWithNoParams CONTINUE_OUTSIDE_LOOP = new MsgWithNoParams("continue outside loop");
public static final MsgWithStringParam RESOLUTION_ERROR = new MsgWithStringParam("unable to resolve name ($0)");
public static final MsgWithNoParams UNKNOWN_VARIABLE = new MsgWithNoParams("unknown variable");
public static final MsgWithNoParams UNKNOWN_FUNCTION_OR_METHOD = new MsgWithNoParams("unknown function or method");
public static final MsgWithNoParams VARIABLE_POSSIBLY_UNITIALISED = new MsgWithNoParams("variable may be uninitialised");
public static final MsgWithStringParam VARIABLE_ALREADY_DEFINED = new MsgWithStringParam("variable $0 already defined");
public static final MsgWithNoParams DUPLICATE_DEFAULT_LABEL = new MsgWithNoParams("duplicate default label");
public static final MsgWithNoParams DUPLICATE_CASE_LABEL = new MsgWithNoParams("duplicate case label");
public static final MsgWithNoParams DEAD_CODE = new MsgWithNoParams("dead-code encountered (i.e. this statement has no effect)");
public static final MsgWithNoParams UNREACHABLE_CODE = new MsgWithNoParams("unreachable code encountered (i.e. execution can never reach this statement)");
public static final MsgWithNoParams ALLOCATION_NOT_PERMITTED = new MsgWithNoParams("object allocation not permitted");
public static final MsgWithNoParams REFERENCE_NOT_PERMITTED = new MsgWithNoParams("reference not permitted");
public static final MsgWithNoParams METHODCALL_NOT_PERMITTED = new MsgWithNoParams("method invocation not permitted");
public static final MsgWithNoParams REFERENCE_ACCESS_NOT_PERMITTED = new MsgWithNoParams("dereference not permitted");
public static final MsgWithTypeParams SUBTYPE_ERROR = new MsgWithTypeParams("expected type $0, found $1");
public static final MsgWithTypeParams INCOMPARABLE_OPERANDS = new MsgWithTypeParams("incomparable operands: $0 and $1");
public static final MsgWithTypeParam RECORD_TYPE_REQUIRED = new MsgWithTypeParam("record required, got: $0");
public static final MsgWithTypeParam REFERENCE_TYPE_REQUIRED = new MsgWithTypeParam("reference required, got: $0");
public static final MsgWithTypeParam FUNCTION_OR_METHOD_TYPE_REQUIRED = new MsgWithTypeParam("function or method required, got: $0");
public static final MsgWithStringParam RECORD_MISSING_FIELD = new MsgWithStringParam("record has no field named $0");
public static final MsgWithNoParams RETURN_FROM_VOID = new MsgWithNoParams("cannot return value from method with void return type");
public static final MsgWithNoParams MISSING_RETURN_VALUE = new MsgWithNoParams("missing return value");
public static final MsgWithNoParams BRANCH_ALWAYS_TAKEN = new MsgWithNoParams("branch always taken");
public static final MsgWithTypeParams AMBIGUOUS_COERCION = new MsgWithTypeParams("ambiguous coercion (from $0 to $1)");
/**
* Return the error message for an error with no parameters.
*
* @param kind
* @param data
* @return
*/
public static String errorMessage(MsgWithNoParams msg) {
return msg.msg;
}
/**
* Return the error message for an error with a single string parameter.
*
* @param kind
* @param data
* @return
*/
public static String errorMessage(MsgWithStringParam msg, String param) {
return msg.msg.replaceAll("\\$0",param);
}
/**
* Return the error message for an error with a single type parameter.
*
* @param kind
* @param data
* @return
*/
public static String errorMessage(MsgWithTypeParam msg, Type t1) {
return msg.msg.replaceAll("\\$0",t1.toString());
}
/**
* Return the error message for an error with two type parameters.
*
* @param kind
* @param data
* @return
*/
public static String errorMessage(MsgWithTypeParams msg, Type t1, Type t2) {
return msg.msg.replaceAll("\\$0",t1.toString()).replaceAll("\\$1",t2.toString());
}
}