Skip to content

Commit d60f6e3

Browse files
authored
Revert "SI-10133 Require escaped single quote char lit"
1 parent a8c4a54 commit d60f6e3

File tree

16 files changed

+76
-84
lines changed

16 files changed

+76
-84
lines changed

src/compiler/scala/tools/nsc/ast/parser/Scanners.scala

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -543,36 +543,24 @@ trait Scanners extends ScannersCommon {
543543
}
544544
fetchDoubleQuote()
545545
case '\'' =>
546-
def unclosedCharLit() = {
547-
val msg = "unclosed character literal"
548-
// previous token was Symbol contiguous with the orphan single quote at offset
549-
if (token == SYMBOLLIT && offset == lastOffset) {
550-
syntaxError(s"""$msg (or use " for string literal "$strVal")""")
551-
} else {
552-
syntaxError(msg)
553-
}
554-
}
555546
def fetchSingleQuote() = {
556547
nextChar()
557548
if (isIdentifierStart(ch))
558549
charLitOr(getIdentRest)
559550
else if (isOperatorPart(ch) && (ch != '\\'))
560551
charLitOr(getOperatorRest)
561-
else if (ch == '\'') {
562-
nextChar()
563-
val advice = if (ch == '\'') { do nextChar() while (ch == '\''); " (use '\\'' for single quote)" } else ""
564-
syntaxError(s"empty character literal${advice}")
565-
}
566552
else if (!isAtEnd && (ch != SU && ch != CR && ch != LF || isUnicodeEscape)) {
567553
getLitChar()
568-
if (ch != '\'') unclosedCharLit()
569-
else {
554+
if (ch == '\'') {
570555
nextChar()
571556
token = CHARLIT
572557
setStrVal()
558+
} else {
559+
syntaxError("unclosed character literal")
573560
}
574561
}
575-
else unclosedCharLit()
562+
else
563+
syntaxError("unclosed character literal")
576564
}
577565
fetchSingleQuote()
578566
case '.' =>
@@ -804,7 +792,7 @@ trait Scanners extends ScannersCommon {
804792
next.token = kwArray(idx)
805793
}
806794
} else {
807-
syntaxError(s"invalid string interpolation $$$ch, expected: $$$$, $$identifier or $${expression}")
795+
syntaxError("invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected")
808796
}
809797
} else {
810798
val isUnclosedLiteral = !isUnicodeEscape && (ch == SU || (!multiLine && (ch == CR || ch == LF)))
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2013 LAMP/EPFL
3+
* @author Paul Phillips
4+
*/
5+
6+
package scala.tools.nsc
7+
package interpreter
8+
9+
import util.stringFromWriter
10+
11+
class Formatting(indent: Int) {
12+
13+
private val indentation = " " * indent
14+
15+
private def indenting(code: String): Boolean = {
16+
/** Heuristic to avoid indenting and thereby corrupting """-strings and XML literals. */
17+
val tokens = List("\"\"\"", "</", "/>")
18+
val noIndent = (code contains "\n") && (tokens exists code.contains)
19+
20+
!noIndent
21+
}
22+
/** Indent some code by the width of the scala> prompt.
23+
* This way, compiler error messages read better.
24+
*/
25+
def indentCode(code: String) = stringFromWriter(str =>
26+
for (line <- code.lines) {
27+
if (indenting(code)) str print indentation
28+
str println line
29+
str.flush()
30+
}
31+
)
32+
}
33+
object Formatting {
34+
def forPrompt(prompt: String) = new Formatting(prompt.lines.toList.last.length)
35+
}

src/repl/scala/tools/nsc/interpreter/IMain.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,11 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
111111
try body finally label = saved
112112
}
113113

114+
// the expanded prompt but without color escapes and without leading newline, for purposes of indenting
115+
lazy val formatting = Formatting.forPrompt(replProps.promptText)
114116
lazy val reporter: ReplReporter = new ReplReporter(this)
115117

118+
import formatting.indentCode
116119
import reporter.{ printMessage, printUntruncatedMessage }
117120

118121
// This exists mostly because using the reporter too early leads to deadlock.
@@ -864,8 +867,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
864867
|${preambleHeader format lineRep.readName}
865868
|${envLines mkString (" ", ";\n ", ";\n")}
866869
|$importsPreamble
867-
|${toCompute}""".stripMargin
868-
def preambleLength = preamble.length - toCompute.length
870+
|${indentCode(toCompute)}""".stripMargin
871+
def preambleLength = preamble.length - toCompute.length - 1
869872

870873
val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this
871874

src/repl/scala/tools/nsc/interpreter/ReplReporter.scala

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ package interpreter
99
import reporters._
1010
import IMain._
1111

12-
import scala.reflect.internal.util.{OffsetPosition, Position}
12+
import scala.reflect.internal.util.Position
1313

1414
/** Like ReplGlobal, a layer for ensuring extra functionality.
1515
*/
@@ -40,25 +40,14 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i
4040
case INFO => RESET
4141
}
4242

43-
private val promptLength = replProps.promptText.lines.toList.last.length
44-
private val indentation = " " * promptLength
45-
46-
// colorized console labels
47-
override protected def clabel(severity: Severity): String = {
48-
val label0 = super.clabel(severity)
49-
if (replProps.colorOk) s"${severityColor(severity)}${label0}${RESET}" else label0
50-
}
51-
52-
// shift indentation for source text entered at prompt
5343
override def print(pos: Position, msg: String, severity: Severity) {
54-
val adjusted =
55-
if (pos.source.file.name == "<console>")
56-
new OffsetPosition(pos.source, pos.offset.getOrElse(0)) {
57-
override def lineContent = s"${indentation}${super.lineContent}"
58-
override def lineCaret = s"${indentation}${super.lineCaret}"
59-
}
60-
else pos
61-
super.print(adjusted, msg, severity)
44+
val prefix = (
45+
if (replProps.colorOk)
46+
severityColor(severity) + clabel(severity) + RESET
47+
else
48+
clabel(severity)
49+
)
50+
printMessage(pos, prefix + msg)
6251
}
6352

6453
override def printMessage(msg: String) {
@@ -74,8 +63,12 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i
7463
else Console.println("[init] " + msg)
7564
}
7665

77-
override def displayPrompt() = if (!intp.totalSilence) super.displayPrompt()
66+
override def displayPrompt() {
67+
if (intp.totalSilence) ()
68+
else super.displayPrompt()
69+
}
7870

7971
override def rerunWithDetails(setting: reflect.internal.settings.MutableSettings#Setting, name: String) =
8072
s"; for details, enable `:setting $name' or `:replay $name'"
73+
8174
}

test/files/jvm/interpreter.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,13 @@ scala> // both of the following should abort immediately:
278278

279279
scala> def x => y => z
280280
<console>:1: error: '=' expected but '=>' found.
281-
def x => y => z
282-
^
281+
def x => y => z
282+
^
283283

284284
scala> [1,2,3]
285285
<console>:1: error: illegal start of definition
286-
[1,2,3]
287-
^
286+
[1,2,3]
287+
^
288288

289289
scala>
290290

test/files/neg/badtok-1.check

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,4 @@ badtok-1.scala:2: error: unclosed character literal
44
badtok-1.scala:2: error: unclosed character literal
55
'42'
66
^
7-
badtok-1.scala:6: error: empty character literal (use '\'' for single quote)
8-
'''
9-
^
10-
badtok-1.scala:9: error: unclosed character literal (or use " for string literal "abc")
11-
'abc'
12-
^
13-
four errors found
7+
two errors found

test/files/neg/badtok-1.scala

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,2 @@
11
// bug 989
22
'42'
3-
4-
5-
// SI-10133
6-
'''
7-
8-
// SI-10120
9-
'abc'

test/files/neg/t5856.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
t5856.scala:10: error: invalid string interpolation $", expected: $$, $identifier or ${expression}
1+
t5856.scala:10: error: invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected
22
val s9 = s"$"
33
^
44
t5856.scala:10: error: unclosed string literal

test/files/run/reify_newimpl_22.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ scala> {
1515
}
1616
println(code.eval)
1717
}
18-
<console>:19: free term: Ident(TermName("x")) defined by res0 in <console>:18:7
18+
<console>:19: free term: Ident(TermName("x")) defined by res0 in <console>:18:14
1919
val code = reify {
2020
^
2121
2

test/files/run/reify_newimpl_23.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ scala> def foo[T]{
1414
}
1515
println(code.eval)
1616
}
17-
<console>:17: free type: Ident(TypeName("T")) defined by foo in <console>:16:9
17+
<console>:17: free type: Ident(TypeName("T")) defined by foo in <console>:16:16
1818
val code = reify {
1919
^
2020
foo: [T]=> Unit

test/files/run/reify_newimpl_25.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ scala> {
55
val tt = implicitly[TypeTag[x.type]]
66
println(tt)
77
}
8-
<console>:15: free term: Ident(TermName("x")) defined by res0 in <console>:14:7
8+
<console>:15: free term: Ident(TermName("x")) defined by res0 in <console>:14:14
99
val tt = implicitly[TypeTag[x.type]]
1010
^
1111
TypeTag[x.type]

test/files/run/reify_newimpl_26.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ scala> def foo[T]{
44
val tt = implicitly[WeakTypeTag[List[T]]]
55
println(tt)
66
}
7-
<console>:13: free type: Ident(TypeName("T")) defined by foo in <console>:11:9
7+
<console>:13: free type: Ident(TypeName("T")) defined by foo in <console>:11:16
88
val tt = implicitly[WeakTypeTag[List[T]]]
99
^
1010
foo: [T]=> Unit

test/files/run/repl-colon-type.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
scala> :type List[1, 2, 3]
33
<console>:1: error: identifier expected but integer literal found.
4-
List[1, 2, 3]
5-
^
4+
List[1, 2, 3]
5+
^
66

77
scala> :type List(1, 2, 3)
88
List[Int]
@@ -38,8 +38,8 @@ scala> :type protected lazy val f = 5
3838
Access to protected lazy value f not permitted because
3939
enclosing object $eval in package $line13 is not a subclass of
4040
object $iw where target is defined
41-
lazy val $result = f
42-
^
41+
lazy val $result = f
42+
^
4343

4444
scala> :type def f = 5
4545
=> Int

test/files/run/t8918-unary-ids.check

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,3 @@ Expected 41 lines, got 39
55
-Type in expressions to have them evaluated.
66
-Type :help for more information.
77

8-
@@ -14,4 +12,4 @@
9-
<console>:1: error: illegal start of simple expression
10-
-- if (true) 1 else 2
11-
- ^
12-
+ - if (true) 1 else 2
13-
+ ^
14-
15-
@@ -19,4 +17,4 @@
16-
<console>:1: error: ';' expected but integer literal found.
17-
-- - 1
18-
- ^
19-
+ - - 1
20-
+ ^
21-

test/files/run/t9170.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ object Y {
4848
def f[A](a: => A): Int at line 12 and
4949
def f[A](a: => Either[Exception,A]): Int at line 13
5050
have same type after erasure: (a: Function0)Int
51-
def f[A](a: => Either[Exception, A]) = 2
52-
^
51+
def f[A](a: => Either[Exception, A]) = 2
52+
^
5353
5454
scala> :quit"""
5555
}

test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class ScriptedTest {
9696
}
9797
@Test def `on compile error`(): Unit = {
9898
val engine = scripted
99-
val err = "not found: value foo in def f = foo at line number 11 at column number 9"
99+
val err = "not found: value foo in def f = foo at line number 11 at column number 16"
100100
assertThrows[ScriptException](engine.compile("def f = foo"), _ == err)
101101
}
102102
}

0 commit comments

Comments
 (0)