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

0 commit comments

Comments
 (0)