From 9c4b0d0402559921d4f36e9ebdd1af9a818fdde7 Mon Sep 17 00:00:00 2001 From: Dominik Gruntz Date: Tue, 17 Jul 2012 15:38:58 +0200 Subject: [PATCH] SI-5856 enables use of $this in string interpolation This pull request fixes SI-5856. The scanner has been modified to return the correct token if keywords appear in $-expressions. The parser has been modified to issue an error and to only accept $, $this and $block. --- .../scala/tools/nsc/ast/parser/Parsers.scala | 7 ++++- .../scala/tools/nsc/ast/parser/Scanners.scala | 6 +++- test/files/neg/t5856.check | 31 +++++++++++++++++++ test/files/neg/t5856.scala | 11 +++++++ test/files/run/t5856.scala | 10 ++++++ 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 test/files/neg/t5856.check create mode 100644 test/files/neg/t5856.scala create mode 100644 test/files/run/t5856.scala diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 3232bde3b47e..656c0fa79a74 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1169,7 +1169,12 @@ self => if (inPattern) dropAnyBraces(pattern()) else { if (in.token == IDENTIFIER) atPos(in.offset)(Ident(ident())) - else expr() + else if(in.token == LBRACE) expr() + else if(in.token == THIS) { in.nextToken(); atPos(in.offset)(This(tpnme.EMPTY)) } + else { + syntaxErrorOrIncomplete("error in interpolated string: identifier or block expected", true) + EmptyTree + } } } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 6ba273b8eaf1..db04aedf2960 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -729,8 +729,12 @@ trait Scanners extends ScannersCommon { next.token = IDENTIFIER next.name = newTermName(cbuf.toString) cbuf.clear() + val idx = next.name.start - kwOffset + if (idx >= 0 && idx < kwArray.length) { + next.token = kwArray(idx) + } } else { - syntaxError("invalid string interpolation") + syntaxError("invalid string interpolation: $$, $ident or $block expected") } } else { val isUnclosedLiteral = !isUnicodeEscape && (ch == SU || (!multiLine && (ch == CR || ch == LF))) diff --git a/test/files/neg/t5856.check b/test/files/neg/t5856.check new file mode 100644 index 000000000000..d42bcdb524c4 --- /dev/null +++ b/test/files/neg/t5856.check @@ -0,0 +1,31 @@ +t5856.scala:10: error: invalid string interpolation: $$, $ident or $block expected + 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" + ^ +t5856.scala:3: error: error in interpolated string: identifier or block expected + val s2 = s"$false" + ^ +t5856.scala:4: error: error in interpolated string: identifier or block expected + val s3 = s"$true" + ^ +t5856.scala:5: error: error in interpolated string: identifier or block expected + val s4 = s"$yield" + ^ +t5856.scala:6: error: error in interpolated string: identifier or block expected + val s5 = s"$return" + ^ +t5856.scala:7: error: error in interpolated string: identifier or block expected + val s6 = s"$new" + ^ +t5856.scala:8: error: error in interpolated string: identifier or block expected + val s7 = s"$s1 $null $super" + ^ +t5856.scala:9: error: error in interpolated string: identifier or block expected + val s8 = s"$super" + ^ +10 errors found diff --git a/test/files/neg/t5856.scala b/test/files/neg/t5856.scala new file mode 100644 index 000000000000..2ceee590af55 --- /dev/null +++ b/test/files/neg/t5856.scala @@ -0,0 +1,11 @@ +object Test { + val s1 = s"$null" + val s2 = s"$false" + val s3 = s"$true" + val s4 = s"$yield" + val s5 = s"$return" + val s6 = s"$new" + val s7 = s"$s1 $null $super" + val s8 = s"$super" + val s9 = s"$" +} \ No newline at end of file diff --git a/test/files/run/t5856.scala b/test/files/run/t5856.scala new file mode 100644 index 000000000000..d1e9bd6e5853 --- /dev/null +++ b/test/files/run/t5856.scala @@ -0,0 +1,10 @@ +object Test extends App { + override def toString = "Test" + + assert(s"$this" == "Test") + assert(s"$this$this" == "TestTest") + assert(s"$this$$" == "Test$") + assert(s"$this.##" == "Test.##") + assert(s"$this.toString" == "Test.toString") + assert(s"$this=THIS" == "Test=THIS") +} \ No newline at end of file