Skip to content

Fix error position and msg for expression expected #5693

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ object Parsers {
def sourcePos(off: Int = in.offset): SourcePosition =
source atPos Position(off)

/** in.offset, except if this is at a new line, in which case `lastOffset` is preferred. */
def expectedOffset: Int = {
val current = sourcePos(in.offset)
val last = sourcePos(in.lastOffset)
if (current.line != last.line) in.lastOffset else in.offset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I experienced two weird behaviors in vscode related to zero-length diagnostics microsoft/vscode#66482 and end-of-line diagnostics microsoft/vscode#66481 making the current diagnostics render like this

screenshot 2019-01-14 at 16 37 01

I was hoping they would render like this instead

screenshot 2019-01-14 at 14 48 01

It might be worth reverting the special handling of end-of-line diagnostics, but I'm not sure.

}

/* ------------- ERROR HANDLING ------------------------------------------- */
/** The offset where the last syntax error was reported, or if a skip to a
* safepoint occurred afterwards, the offset of the safe point.
Expand All @@ -116,7 +123,7 @@ object Parsers {
*/
def syntaxError(msg: => Message, offset: Int = in.offset): Unit =
if (offset > lastErrorOffset) {
val length = if (in.name != null) in.name.show.length else 0
val length = if (offset == in.offset && in.name != null) in.name.show.length else 0
syntaxError(msg, Position(offset, offset + length))
lastErrorOffset = in.offset
}
Expand Down Expand Up @@ -275,13 +282,13 @@ object Parsers {
/** If at end of file, issue an incompleteInputError.
* Otherwise issue a syntax error and skip to next safe point.
*/
def syntaxErrorOrIncomplete(msg: => Message): Unit =
def syntaxErrorOrIncomplete(msg: => Message, offset: Int = in.offset): Unit =
if (in.token == EOF) incompleteInputError(msg)
else {
syntaxError(msg)
syntaxError(msg, offset)
skip()
lastErrorOffset = in.offset
} // DEBUG
}

/** Consume one token of the specified type, or
* signal an error if it is not there.
Expand Down Expand Up @@ -1456,7 +1463,7 @@ object Parsers {
case _ =>
if (isLiteral) literal()
else {
syntaxErrorOrIncomplete(IllegalStartSimpleExpr(tokenString(in.token)))
syntaxErrorOrIncomplete(IllegalStartSimpleExpr(tokenString(in.token)), expectedOffset)
errorTermTree
}
}
Expand Down Expand Up @@ -1748,7 +1755,7 @@ object Parsers {
case _ =>
if (isLiteral) literal(inPattern = true)
else {
syntaxErrorOrIncomplete(IllegalStartOfSimplePattern())
syntaxErrorOrIncomplete(IllegalStartOfSimplePattern(), expectedOffset)
errorTermTree
}
}
Expand Down
16 changes: 3 additions & 13 deletions compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -569,19 +569,9 @@ object messages {
case class IllegalStartSimpleExpr(illegalToken: String)(implicit ctx: Context)
extends Message(IllegalStartSimpleExprID) {
val kind: String = "Syntax"
val msg: String = "Illegal start of simple expression"
val msg: String = "expression expected"
val explanation: String = {
hl"""|An expression yields a value. In the case of the simple expression, this error
|commonly occurs when there's a missing parenthesis or brace. The reason being
|that a simple expression is one of the following:
|
|- Block
|- Expression in parenthesis
|- Identifier
|- Object creation
|- Literal
|
|which cannot start with ${Red(illegalToken)}."""
hl"""|An expression cannot start with ${Red(illegalToken)}."""
}
}

Expand Down Expand Up @@ -932,7 +922,7 @@ object messages {
case class IllegalStartOfSimplePattern()(implicit ctx: Context)
extends Message(IllegalStartOfSimplePatternID) {
val kind: String = "Syntax"
val msg: String = "Illegal start of simple pattern"
val msg: String = "pattern expected"
val explanation: String = {
val sipCode =
"""def f(x: Int, y: Int) = x match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class DiagnosticsTest {
| Nil.map(x => x).filter(x$m1 =>$m2)
|$m3}""".withSource
.diagnostics(m1,
(m2 to m3, "Illegal start of simple expression", Error, Some(IllegalStartSimpleExprID)),
(m2 to m3, "expression expected", Error, Some(IllegalStartSimpleExprID)),
(m1 to m1, """Found: Null
|Required: Boolean""".stripMargin, Error, Some(TypeMismatchID))
)
Expand Down
16 changes: 16 additions & 0 deletions tests/neg/errpos.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
object Test {
val x = // error: expression expected
val y = 2 // error: ';' expected

val z = // error: expression expected

// ...
val a = 3 // error: ';' expected

val b = type // error: expression expected (on "type")

1 match {
case // error: pattern expected
case 2 => ""
}
}