summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2017-01-07 01:30:38 -0800
committerSom Snytt <som.snytt@gmail.com>2017-01-08 01:07:22 -0800
commit939abf1c7062f8be4f84854bb44a8e146d14a07f (patch)
treec8c1c917462c545626cfe1430677115f7a7c347a
parent855492c928a795f175c6bb10ee6d4b23c871a123 (diff)
downloadscala-939abf1c7062f8be4f84854bb44a8e146d14a07f.tar.gz
scala-939abf1c7062f8be4f84854bb44a8e146d14a07f.tar.bz2
scala-939abf1c7062f8be4f84854bb44a8e146d14a07f.zip
SI-10120 Extra advice on unclosed char literal
Folks from other languages might mistakenly enclose a string in single quotes. Since this presents as a symbol literal followed by the unpaired single quote, we can add a syntax reminder. Also polish the wording for bad string interpolation.
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala19
-rw-r--r--test/files/neg/badtok-1.check5
-rw-r--r--test/files/neg/badtok-1.scala3
-rw-r--r--test/files/neg/t5856.check2
4 files changed, 21 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 54c604c072..2075901d31 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -532,6 +532,15 @@ 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))
@@ -545,16 +554,14 @@ trait Scanners extends ScannersCommon {
}
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 '.' =>
@@ -786,7 +793,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)))
diff --git a/test/files/neg/badtok-1.check b/test/files/neg/badtok-1.check
index 891fa12a55..5d5a8e1f35 100644
--- a/test/files/neg/badtok-1.check
+++ b/test/files/neg/badtok-1.check
@@ -7,4 +7,7 @@ badtok-1.scala:2: error: unclosed character literal
badtok-1.scala:6: error: empty character literal (use '\'' for single quote)
'''
^
-three errors found
+badtok-1.scala:9: error: unclosed character literal (or use " for string literal "abc")
+'abc'
+ ^
+four errors found
diff --git a/test/files/neg/badtok-1.scala b/test/files/neg/badtok-1.scala
index 40799c3c3d..cc7dc6cecc 100644
--- a/test/files/neg/badtok-1.scala
+++ b/test/files/neg/badtok-1.scala
@@ -4,3 +4,6 @@
// SI-10133
'''
+
+// SI-10120
+'abc'
diff --git a/test/files/neg/t5856.check b/test/files/neg/t5856.check
index 08a61bdc07..306cc04177 100644
--- a/test/files/neg/t5856.check
+++ b/test/files/neg/t5856.check
@@ -1,4 +1,4 @@
-t5856.scala:10: error: invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected
+t5856.scala:10: error: invalid string interpolation $", expected: $$, $identifier or ${expression}
val s9 = s"$"
^
t5856.scala:10: error: unclosed string literal