MagicScriptError.java 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package org.ssssssss.script;
  2. import org.ssssssss.script.parsing.Span;
  3. import org.ssssssss.script.parsing.TokenStream;
  4. /**
  5. * All errors reported by the library go through the static functions of this class.
  6. */
  7. public class MagicScriptError {
  8. /**
  9. * <p>
  10. * Create an error message based on the provided message and stream, highlighting the line on which the error happened. If the
  11. * stream has more tokens, the next token will be highlighted. Otherwise the end of the source of the stream will be
  12. * highlighted.
  13. * </p>
  14. *
  15. * <p>
  16. * Throws a {@link RuntimeException}
  17. * </p>
  18. */
  19. public static void error(String message, TokenStream stream) {
  20. if (stream.hasMore()) {
  21. error(message, stream.consume().getSpan());
  22. } else {
  23. error(message, stream.getPrev().getSpan());
  24. }
  25. }
  26. /**
  27. * Create an error message based on the provided message and location, highlighting the location in the line on which the
  28. * error happened. Throws a {@link ScriptException}
  29. **/
  30. public static void error(String message, Span location, Throwable cause) {
  31. Span.Line line = location.getLine();
  32. String errorMessage = "Script Error : " + message + "\n\n";
  33. errorMessage += line.getText();
  34. errorMessage += "\n";
  35. int errorStart = location.getStart() - line.getStart();
  36. int errorEnd = errorStart + location.getText().length() - 1;
  37. for (int i = 0, n = line.getText().length(); i < n; i++) {
  38. boolean useTab = line.getText().charAt(i) == '\t';
  39. errorMessage += i >= errorStart && i <= errorEnd ? "^" : useTab ? "\t" : " ";
  40. }
  41. if (cause == null) {
  42. throw new ScriptException(errorMessage, message, line);
  43. } else {
  44. throw new ScriptException(errorMessage, message, cause, line);
  45. }
  46. }
  47. /**
  48. * Create an error message based on the provided message and location, highlighting the location in the line on which the
  49. * error happened. Throws a {@link ScriptException}
  50. **/
  51. public static void error(String message, Span location) {
  52. error(message, location, null);
  53. }
  54. public static class DebugTimeoutException extends RuntimeException{
  55. public DebugTimeoutException() {
  56. super("debug超时");
  57. }
  58. public DebugTimeoutException(Throwable cause) {
  59. super(cause);
  60. }
  61. }
  62. public static class ScriptException extends RuntimeException {
  63. private static final long serialVersionUID = 1L;
  64. private final String errorMessage;
  65. private final String simpleMessage;
  66. private final Span.Line line;
  67. public ScriptException(String errorMessage, String simpleMessage, Span.Line line) {
  68. super(errorMessage);
  69. this.errorMessage = errorMessage;
  70. this.simpleMessage = simpleMessage;
  71. this.line = line;
  72. }
  73. public ScriptException(String errorMessage, Span.Line line) {
  74. this(errorMessage, errorMessage, line);
  75. }
  76. public ScriptException(String errorMessage) {
  77. this(errorMessage, errorMessage, null);
  78. }
  79. public ScriptException(String message, String simpleMessage, Throwable cause, Span.Line line) {
  80. super(message, cause);
  81. this.simpleMessage = simpleMessage;
  82. this.errorMessage = message;
  83. this.line = line;
  84. }
  85. public String getSimpleMessage() {
  86. return simpleMessage;
  87. }
  88. public Span.Line getLine() {
  89. return line;
  90. }
  91. @Override
  92. public String getMessage() {
  93. StringBuilder builder = new StringBuilder();
  94. if (getCause() == null || getCause() == this) {
  95. return super.getMessage();
  96. }
  97. builder.append(errorMessage, 0, errorMessage.indexOf('\n'));
  98. builder.append("\n");
  99. Throwable cause = getCause();
  100. while (cause != null && cause != this) {
  101. if (cause instanceof ScriptException) {
  102. ScriptException ex = (ScriptException) cause;
  103. if (ex.getCause() == null || ex.getCause() == ex) {
  104. builder.append(ex.errorMessage);
  105. } else {
  106. builder.append(ex.errorMessage, 0, ex.errorMessage.indexOf('\n'));
  107. }
  108. builder.append("\n");
  109. }
  110. cause = cause.getCause();
  111. }
  112. return builder.toString();
  113. }
  114. }
  115. public static class StringLiteralException extends RuntimeException {
  116. private static final long serialVersionUID = 1L;
  117. }
  118. }