Skip to content

Commit e4b8fce

Browse files
committed
Change layout of ErrorMessages
1 parent 6d40d1d commit e4b8fce

File tree

7 files changed

+135
-120
lines changed

7 files changed

+135
-120
lines changed

src/dotty/tools/dotc/parsing/JavaParsers.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import scala.reflect.internal.util.Collections._
2929
object JavaParsers {
3030

3131
import ast.untpd._
32+
import reporting.ErrorMessages.Syntax._
3233

3334
class JavaParser(source: SourceFile)(implicit ctx: Context) extends ParserCommon(source) {
3435

src/dotty/tools/dotc/parsing/MarkupParsers.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import Utility._
3232
object MarkupParsers {
3333

3434
import ast.untpd._
35+
import reporting.ErrorMessages.Syntax._
3536

3637
case object MissingEndTagControl extends ControlThrowable {
3738
override def getMessage = "start tag was here: "

src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import ast.Trees._
1717
import Decorators._
1818
import StdNames._
1919
import util.Positions._
20-
import reporting.ErrorExplanations._
20+
import reporting.ErrorMessages._
2121
import Constants._
2222
import ScriptParsers._
2323
import scala.annotation.{tailrec, switch}
@@ -28,6 +28,7 @@ import Scanners.Comment
2828
object Parsers {
2929

3030
import ast.untpd._
31+
import reporting.ErrorMessages.Syntax._
3132

3233
case class OpInfo(operand: Tree, operator: Name, offset: Offset)
3334

@@ -87,7 +88,7 @@ object Parsers {
8788
/** Issue an error at given offset if beyond last error offset
8889
* and update lastErrorOffset.
8990
*/
90-
def syntaxError(expl: Explanation, offset: Int = in.offset): Unit =
91+
def syntaxError(expl: ErrorMessage, offset: Int = in.offset): Unit =
9192
if (offset > lastErrorOffset) {
9293
syntaxError(expl, Position(offset))
9394
lastErrorOffset = in.offset
@@ -96,7 +97,7 @@ object Parsers {
9697
/** Unconditionally issue an error at given position, without
9798
* updating lastErrorOffset.
9899
*/
99-
def syntaxError(expl: Explanation, pos: Position): Unit =
100+
def syntaxError(expl: ErrorMessage, pos: Position): Unit =
100101
ctx.explainError(expl, source atPos pos)
101102

102103
}
@@ -203,7 +204,7 @@ object Parsers {
203204
}
204205
}
205206

206-
def warning(msg: Explanation, offset: Int = in.offset) =
207+
def warning(msg: ErrorMessage, offset: Int = in.offset) =
207208
ctx.explainWarning(msg, source atPos Position(offset))
208209

209210
def deprecationWarning(msg: String, offset: Int = in.offset) =
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package dotty.tools
2+
package dotc
3+
package reporting
4+
5+
import dotc.core._
6+
import Contexts.Context, Decorators._, Symbols._
7+
import dotc.printing.SyntaxHighlighting._
8+
import util.{SourcePosition, NoSourcePosition}
9+
10+
object ErrorMessages {
11+
import dotc.ast.Trees._
12+
import dotc.ast.untpd
13+
14+
implicit class ShouldExplainCtx(val c: Context) extends AnyVal {
15+
def shouldExplain(expl: ErrorMessage): Boolean = {
16+
implicit val ctx = c
17+
expl match {
18+
case _: NoExplanation => false
19+
case expl if ctx.settings.explainerrors.value => true
20+
case _ => false
21+
}
22+
}
23+
}
24+
25+
trait ErrorMessage {
26+
def kind: String
27+
def msg: String
28+
def explanation: String
29+
}
30+
31+
case class NoExplanation(msg: String)(implicit val kind: String) extends ErrorMessage {
32+
val explanation = ""
33+
}
34+
35+
object Syntax {
36+
implicit val kind: String = "Syntax"
37+
implicit def stringToErrorMessage(s: String): ErrorMessage = NoExplanation(s)
38+
39+
abstract class EmptyCatchOrFinallyBlock(tryBody: untpd.Tree)(implicit ctx: Context, val kind: String) extends ErrorMessage {
40+
val explanation = {
41+
val tryString = tryBody match {
42+
case Block(Nil, untpd.EmptyTree) => "{}"
43+
case _ => tryBody.show
44+
}
45+
46+
val code1 =
47+
s"""|try $tryString catch {
48+
| case t: Throwable => ???
49+
|}""".stripMargin
50+
51+
val code2 =
52+
s"""|try $tryString finally {
53+
| // perform your cleanup here!
54+
|}""".stripMargin
55+
56+
hl"""|Explanation:
57+
|============
58+
|A ${"try"} expression should be followed by some mechanism to handle any exceptions
59+
|thrown. Typically a ${"catch"} expression follows the ${"try"} and pattern matches
60+
|on any expected exceptions. For example:
61+
|
62+
|$code1
63+
|
64+
|It is also possible to follow a ${"try"} immediately by a ${"finally"} - letting the
65+
|exception propagate - but still allowing for some clean up in ${"finally"}:
66+
|
67+
|$code2
68+
""".stripMargin
69+
}
70+
}
71+
72+
case class EmptyCatchBlock(tryBody: untpd.Tree)(implicit ctx: Context, override val kind: String)
73+
extends EmptyCatchOrFinallyBlock(tryBody) {
74+
val msg =
75+
hl"""The ${"catch"} block does not contain a valid expression, try adding a case like - `${"case e: Exception =>"}` to the block"""
76+
}
77+
78+
case class EmptyCatchAndFinallyBlock(tryBody: untpd.Tree)(implicit ctx: Context, override val kind: String)
79+
extends EmptyCatchOrFinallyBlock(tryBody) {
80+
val msg =
81+
hl"""A ${"try"} without ${"catch"} or ${"finally"} is equivalent to putting its body in a block; no exceptions are handled."""
82+
}
83+
}
84+
85+
object Type {
86+
implicit val kind: String = "Type"
87+
implicit def stringToErrorMessage(s: String): ErrorMessage = NoExplanation(s)
88+
89+
case class DuplicateBind(bind: untpd.Bind, tree: untpd.CaseDef)(implicit ctx: Context, val kind: String) extends ErrorMessage {
90+
val msg =
91+
em"duplicate pattern variable: `${bind.name}`"
92+
93+
val explanation = {
94+
val pat = tree.pat.show
95+
val guard = tree.guard match {
96+
case untpd.EmptyTree => ""
97+
case guard => s"if ${guard.show}"
98+
}
99+
100+
val body = tree.body match {
101+
case Block(Nil, untpd.EmptyTree) => ""
102+
case body => s" ${body.show}"
103+
}
104+
105+
val caseDef = s"case $pat$guard => $body"
106+
107+
hl"""|Explanation
108+
|===========
109+
|For each ${"case"} bound variable names have to be unique. In:
110+
|
111+
|$caseDef
112+
|
113+
|`${bind.name}` is not unique. Rename one of the binds!""".stripMargin
114+
}
115+
}
116+
}
117+
}

src/dotty/tools/dotc/reporting/Examples.scala

Lines changed: 0 additions & 106 deletions
This file was deleted.

src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import java.lang.System.currentTimeMillis
1313
import core.Mode
1414
import interfaces.Diagnostic.{ERROR, WARNING, INFO}
1515
import dotty.tools.dotc.core.Symbols.Symbol
16-
import ErrorExplanations._
16+
import ErrorMessages._
1717

1818
object Reporter {
1919
class Error(msgFn: => String, pos: SourcePosition) extends Diagnostic(msgFn, pos, ERROR)
@@ -96,10 +96,10 @@ trait Reporting { this: Context =>
9696
def warning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
9797
reporter.report(new Warning(msg, pos))
9898

99-
def explainWarning(expl: => Explanation, pos: SourcePosition = NoSourcePosition): Unit = {
100-
warning(expl.msg, pos)
101-
if (this.shouldExplain(expl))
102-
reporter.report(new Info(expl.explanation, NoSourcePosition))
99+
def explainWarning(err: => ErrorMessage, pos: SourcePosition = NoSourcePosition): Unit = {
100+
warning(err.msg, pos)
101+
if (this.shouldExplain(err))
102+
reporter.report(new Info(err.explanation, NoSourcePosition))
103103
}
104104

105105
def strictWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
@@ -111,10 +111,10 @@ trait Reporting { this: Context =>
111111
reporter.report(new Error(msg, pos))
112112
}
113113

114-
def explainError(expl: => Explanation, pos: SourcePosition = NoSourcePosition): Unit = {
115-
error(expl.msg, pos)
116-
if (this.shouldExplain(expl))
117-
reporter.report(new Info(expl.explanation, NoSourcePosition))
114+
def explainError(err: => ErrorMessage, pos: SourcePosition = NoSourcePosition): Unit = {
115+
error(err.msg, pos)
116+
if (this.shouldExplain(err))
117+
reporter.report(new Info(err.explanation, NoSourcePosition))
118118
}
119119

120120
def errorOrMigrationWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import NavigateAST._
3737
import transform.SymUtils._
3838
import language.implicitConversions
3939
import printing.SyntaxHighlighting._
40-
import reporting.ErrorExplanations._
40+
import reporting.ErrorMessages._
4141

4242
object Typer {
4343

@@ -65,6 +65,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
6565
import tpd.{cpy => _, _}
6666
import untpd.cpy
6767
import Dynamic.isDynamicMethod
68+
import reporting.ErrorMessages.Type._
6869

6970
/** A temporary data item valid for a single typed ident:
7071
* The set of all root import symbols that have been

0 commit comments

Comments
 (0)