diff options
author | cushon <cushon@google.com> | 2018-10-10 17:11:56 -0700 |
---|---|---|
committer | Liam Miller-Cushon <cushon@google.com> | 2018-10-17 20:45:30 -0700 |
commit | 74070a25d15bd74e71fac5a8392d39cdaa9a953e (patch) | |
tree | 8196c712edfbd5bd89282e545b086aa72196056a | |
parent | b767eadd89c6c94f75d3ffeb49850665a712fe9b (diff) | |
download | turbine-74070a25d15bd74e71fac5a8392d39cdaa9a953e.tar.gz |
Improve diagnostics for empty and unterminated char literals
MOE_MIGRATED_REVID=216620223
-rw-r--r-- | java/com/google/turbine/diag/TurbineError.java | 2 | ||||
-rw-r--r-- | java/com/google/turbine/parse/StreamLexer.java | 18 | ||||
-rw-r--r-- | javatests/com/google/turbine/parse/ParseErrorTest.java | 32 |
3 files changed, 45 insertions, 7 deletions
diff --git a/java/com/google/turbine/diag/TurbineError.java b/java/com/google/turbine/diag/TurbineError.java index 01c6c48..f9ddcd5 100644 --- a/java/com/google/turbine/diag/TurbineError.java +++ b/java/com/google/turbine/diag/TurbineError.java @@ -34,6 +34,8 @@ public class TurbineError extends Error { UNEXPECTED_IDENTIFIER("unexpected identifier '%s'"), UNEXPECTED_EOF("unexpected end of input"), UNTERMINATED_STRING("unterminated string literal"), + UNTERMINATED_CHARACTER_LITERAL("unterminated char literal"), + EMPTY_CHARACTER_LITERAL("empty char literal"), EXPECTED_TOKEN("expected token %s"), INVALID_LITERAL("invalid literal: %s"), UNEXPECTED_TYPE_PARAMETER("unexpected type parameter %s"), diff --git a/java/com/google/turbine/parse/StreamLexer.java b/java/com/google/turbine/parse/StreamLexer.java index c108332..74b0ce8 100644 --- a/java/com/google/turbine/parse/StreamLexer.java +++ b/java/com/google/turbine/parse/StreamLexer.java @@ -339,19 +339,23 @@ public class StreamLexer implements Lexer { { eat(); char value; - if (ch == '\\') { - eat(); - value = escape(); - } else { - value = ch; - eat(); + switch (ch) { + case '\\': + eat(); + value = escape(); + break; + case '\'': + throw error(ErrorKind.EMPTY_CHARACTER_LITERAL); + default: + value = ch; + eat(); } if (ch == '\'') { saveValue(String.valueOf(value)); eat(); return Token.CHAR_LITERAL; } - throw error(ErrorKind.UNEXPECTED_INPUT, ch); + throw error(ErrorKind.UNTERMINATED_CHARACTER_LITERAL); } case '"': diff --git a/javatests/com/google/turbine/parse/ParseErrorTest.java b/javatests/com/google/turbine/parse/ParseErrorTest.java index 30ff061..53864ef 100644 --- a/javatests/com/google/turbine/parse/ParseErrorTest.java +++ b/javatests/com/google/turbine/parse/ParseErrorTest.java @@ -170,6 +170,38 @@ public class ParseErrorTest { } } + @Test + public void emptyChar() { + String input = "class T { char c = ''; }"; + try { + Parser.parse(input); + fail("expected parsing to fail"); + } catch (TurbineError e) { + assertThat(e.getMessage()) + .isEqualTo( + lines( + "<>:1: error: empty char literal", // + "class T { char c = ''; }", + " ^")); + } + } + + @Test + public void unterminatedChar() { + String input = "class T { char c = '; }"; + try { + Parser.parse(input); + fail("expected parsing to fail"); + } catch (TurbineError e) { + assertThat(e.getMessage()) + .isEqualTo( + lines( + "<>:1: error: unterminated char literal", // + "class T { char c = '; }", + " ^")); + } + } + private static String lines(String... lines) { return Joiner.on(System.lineSeparator()).join(lines); } |