diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2017-02-20 14:20:10 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-20 14:20:10 -0800 |
commit | 023a96afe30d04e6de771d0676b85b0889b89a37 (patch) | |
tree | 27a9342ae392a21bffad4c717f39d47bed5ac718 /src/compiler/scala/tools | |
parent | e21ab425880b7c3fa4cca3c9503045823d250025 (diff) | |
parent | 05cc3e2271d2c2226ded33bef5a03f0c70c6f66d (diff) | |
download | scala-023a96afe30d04e6de771d0676b85b0889b89a37.tar.gz scala-023a96afe30d04e6de771d0676b85b0889b89a37.tar.bz2 scala-023a96afe30d04e6de771d0676b85b0889b89a37.zip |
Merge pull request #5629 from som-snytt/issue/10120-quote-err
SI-10133 Require escaped single quote char lit
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 3ed1570c1c..d72002f0a7 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -543,24 +543,36 @@ trait Scanners extends ScannersCommon { } fetchDoubleQuote() case '\'' => + def unclosedCharLit() = { + val msg = "unclosed character literal" + // previous token was Symbol contiguous with the orphan single quote at offset + if (token == SYMBOLLIT && offset == lastOffset) { + syntaxError(s"""$msg (or use " for string literal "$strVal")""") + } else { + syntaxError(msg) + } + } def fetchSingleQuote() = { nextChar() if (isIdentifierStart(ch)) charLitOr(getIdentRest) else if (isOperatorPart(ch) && (ch != '\\')) charLitOr(getOperatorRest) + else if (ch == '\'') { + nextChar() + val advice = if (ch == '\'') { do nextChar() while (ch == '\''); " (use '\\'' for single quote)" } else "" + syntaxError(s"empty character literal${advice}") + } else if (!isAtEnd && (ch != SU && ch != CR && ch != LF || isUnicodeEscape)) { getLitChar() - if (ch == '\'') { + if (ch != '\'') unclosedCharLit() + else { nextChar() token = CHARLIT setStrVal() - } else { - syntaxError("unclosed character literal") } } - else - syntaxError("unclosed character literal") + else unclosedCharLit() } fetchSingleQuote() case '.' => @@ -792,7 +804,7 @@ trait Scanners extends ScannersCommon { next.token = kwArray(idx) } } else { - syntaxError("invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected") + syntaxError(s"invalid string interpolation $$$ch, expected: $$$$, $$identifier or $${expression}") } } else { val isUnclosedLiteral = !isUnicodeEscape && (ch == SU || (!multiLine && (ch == CR || ch == LF))) |