Skip to content

Commit

Permalink
Merge pull request #9536 from martijnhoekstra/escdollar3
Browse files Browse the repository at this point in the history
allow $ escaping double quotes in interpolations under -Xsource:3
  • Loading branch information
lrytz committed Mar 17, 2021
2 parents 1b98feb + 5126a0a commit ac73ea3
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 13 deletions.
10 changes: 6 additions & 4 deletions spec/01-lexical-syntax.md
Expand Up @@ -503,9 +503,10 @@ not processed, except for Unicode escapes.
#### Interpolated string

```ebnf
interpolatedString ::= alphaid ‘"’ {printableChar \ (‘"’ | ‘$’) | escape} ‘"’
interpolatedString ::= alphaid ‘"’ {printableChar \ (‘"’ | ‘$’) | escape} ‘"’
| alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘$’) | escape} {‘"’} ‘"""’
escape ::= ‘$$’
escape ::= ‘$$’
| ‘$"’
| ‘$’ id
| ‘$’ BlockExpr
alphaid ::= upper idrest
Expand All @@ -522,13 +523,14 @@ or multi-line (triple quote).
Inside a interpolated string none of the usual escape characters are interpreted
(except for unicode escapes) no matter whether the string literal is normal
(enclosed in single quotes) or multi-line (enclosed in triple quotes).
Instead, there are two new forms of dollar sign escape.
Instead, there are three new forms of dollar sign escape.
The most general form encloses an expression in `${` and `}`, i.e. `${expr}`.
The expression enclosed in the braces that follow the leading `$` character is of
syntactical category BlockExpr. Hence, it can contain multiple statements,
and newlines are significant. Single ‘$’-signs are not permitted in isolation
in a interpolated string. A single ‘$’-sign can still be obtained by doubling the ‘$’
character: ‘$$’.
character: ‘$$’. A single ‘"’-sign in a single quoted interpolation would end the
interpolation. A single ‘"’-sign can be obtained by the sequence ‘\$"’.

The simpler form consists of a ‘$’-sign followed by an identifier starting with
a letter and followed only by letters, digits, and underscore characters,
Expand Down
5 changes: 3 additions & 2 deletions spec/13-syntax-summary.md
Expand Up @@ -63,8 +63,9 @@ multiLineChars ::= {[‘"’] [‘"’] charNoDoubleQuote} {‘"’}
interpolatedString
::= alphaid ‘"’ {printableChar \ (‘"’ | ‘\$’) | escape} ‘"’
| alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘\$’) | escape} {‘"’} ‘"""’
escape ::= ‘\$\$’
| ‘\$’ id
escape ::= ‘\$\$’
| ‘\$"’
| ‘\$’ id
| ‘\$’ BlockExpr
alphaid ::= upper idrest
| varid
Expand Down
5 changes: 3 additions & 2 deletions src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
Expand Up @@ -912,7 +912,7 @@ trait Scanners extends ScannersCommon {
}
} else if (ch == '$') {
nextRawChar()
if (ch == '$') {
if (ch == '$' || ch == '"') {
putChar(ch)
nextRawChar()
getStringPart(multiLine)
Expand All @@ -938,7 +938,8 @@ trait Scanners extends ScannersCommon {
next.token = kwArray(idx)
}
} else {
syntaxError(s"invalid string interpolation $$$ch, expected: $$$$, $$identifier or $${expression}")
val expectations = "$$, $\", $identifier or ${expression}"
syntaxError(s"invalid string interpolation $$$ch, expected: $expectations")
}
} else {
val isUnclosedLiteral = (ch == SU || (!multiLine && (ch == CR || ch == LF)))
Expand Down
7 changes: 2 additions & 5 deletions test/files/neg/t5856.check
@@ -1,9 +1,6 @@
t5856.scala:10: error: invalid string interpolation $", expected: $$, $identifier or ${expression}
val s9 = s"$"
^
t5856.scala:10: error: unclosed string literal
val s9 = s"$"
^
^
t5856.scala:2: error: error in interpolated string: identifier or block expected
val s1 = s"$null"
^
Expand All @@ -28,4 +25,4 @@ t5856.scala:8: error: error in interpolated string: identifier or block expected
t5856.scala:9: error: error in interpolated string: identifier or block expected
val s8 = s"$super"
^
10 errors
9 errors
6 changes: 6 additions & 0 deletions test/files/run/interpolation.check
Expand Up @@ -30,3 +30,9 @@ Best price: 13.35

0
00
"everybody loves escaped quotes" is a common sentiment.
hi"$"
hi"$"
hi"$"
hi"$"
hi"$"
8 changes: 8 additions & 0 deletions test/files/run/interpolation.scala
Expand Up @@ -29,4 +29,12 @@ object Test extends App {
println(f"")
println(f"${0}")
println(f"${0}${0}")

println(s"$"everybody loves escaped quotes$" is a common sentiment.")
println(f"hi$"$$$"")
println(raw"hi$"$$$"")

println(s"""hi$"$$$"""")
println(f"""hi$"$$$"""")
println(raw"""hi$"$$$"""")
}

0 comments on commit ac73ea3

Please sign in to comment.