diff options
Diffstat (limited to 'src')
4 files changed, 40 insertions, 59 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 3ed1570c1c..d72002f0a7 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -543,24 +543,36 @@ 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)) charLitOr(getIdentRest) else if (isOperatorPart(ch) && (ch != '\\')) charLitOr(getOperatorRest) + else if (ch == '\'') { + nextChar() + val advice = if (ch == '\'') { do nextChar() while (ch == '\''); " (use '\\'' for single quote)" } else "" + syntaxError(s"empty character literal${advice}") + } 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 '.' => @@ -792,7 +804,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/src/repl/scala/tools/nsc/interpreter/Formatting.scala b/src/repl/scala/tools/nsc/interpreter/Formatting.scala deleted file mode 100644 index 4a9548730a..0000000000 --- a/src/repl/scala/tools/nsc/interpreter/Formatting.scala +++ /dev/null @@ -1,35 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips - */ - -package scala.tools.nsc -package interpreter - -import util.stringFromWriter - -class Formatting(indent: Int) { - - private val indentation = " " * indent - - private def indenting(code: String): Boolean = { - /** Heuristic to avoid indenting and thereby corrupting """-strings and XML literals. */ - val tokens = List("\"\"\"", "</", "/>") - val noIndent = (code contains "\n") && (tokens exists code.contains) - - !noIndent - } - /** Indent some code by the width of the scala> prompt. - * This way, compiler error messages read better. - */ - def indentCode(code: String) = stringFromWriter(str => - for (line <- code.lines) { - if (indenting(code)) str print indentation - str println line - str.flush() - } - ) -} -object Formatting { - def forPrompt(prompt: String) = new Formatting(prompt.lines.toList.last.length) -} diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index a351d2da95..2ae3b207b7 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -111,11 +111,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends try body finally label = saved } - // the expanded prompt but without color escapes and without leading newline, for purposes of indenting - lazy val formatting = Formatting.forPrompt(replProps.promptText) lazy val reporter: ReplReporter = new ReplReporter(this) - import formatting.indentCode import reporter.{ printMessage, printUntruncatedMessage } // This exists mostly because using the reporter too early leads to deadlock. @@ -867,8 +864,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends |${preambleHeader format lineRep.readName} |${envLines mkString (" ", ";\n ", ";\n")} |$importsPreamble - |${indentCode(toCompute)}""".stripMargin - def preambleLength = preamble.length - toCompute.length - 1 + |${toCompute}""".stripMargin + def preambleLength = preamble.length - toCompute.length val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this diff --git a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala index 3a0b69f41e..b01d242d44 100644 --- a/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala +++ b/src/repl/scala/tools/nsc/interpreter/ReplReporter.scala @@ -9,7 +9,7 @@ package interpreter import reporters._ import IMain._ -import scala.reflect.internal.util.Position +import scala.reflect.internal.util.{OffsetPosition, Position} /** Like ReplGlobal, a layer for ensuring extra functionality. */ @@ -40,14 +40,25 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i case INFO => RESET } + private val promptLength = replProps.promptText.lines.toList.last.length + private val indentation = " " * promptLength + + // colorized console labels + override protected def clabel(severity: Severity): String = { + val label0 = super.clabel(severity) + if (replProps.colorOk) s"${severityColor(severity)}${label0}${RESET}" else label0 + } + + // shift indentation for source text entered at prompt override def print(pos: Position, msg: String, severity: Severity) { - val prefix = ( - if (replProps.colorOk) - severityColor(severity) + clabel(severity) + RESET - else - clabel(severity) - ) - printMessage(pos, prefix + msg) + val adjusted = + if (pos.source.file.name == "<console>") + new OffsetPosition(pos.source, pos.offset.getOrElse(0)) { + override def lineContent = s"${indentation}${super.lineContent}" + override def lineCaret = s"${indentation}${super.lineCaret}" + } + else pos + super.print(adjusted, msg, severity) } override def printMessage(msg: String) { @@ -63,12 +74,8 @@ class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.i else Console.println("[init] " + msg) } - override def displayPrompt() { - if (intp.totalSilence) () - else super.displayPrompt() - } + override def displayPrompt() = if (!intp.totalSilence) super.displayPrompt() override def rerunWithDetails(setting: reflect.internal.settings.MutableSettings#Setting, name: String) = s"; for details, enable `:setting $name' or `:replay $name'" - } |