aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/reporting/diagnostic
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-09-16 18:23:11 +0200
committerFelix Mulder <felix.mulder@gmail.com>2016-10-10 13:25:33 +0200
commit2764609bb17dfc8691d33fcc1c70a9891af59e70 (patch)
treecbb0c188a5fc83b7d91256502e4c4f42fd5fcd26 /src/dotty/tools/dotc/reporting/diagnostic
parent2b2cfe71aacb50e91d6956f0d4ee7d555537698a (diff)
downloaddotty-2764609bb17dfc8691d33fcc1c70a9891af59e70.tar.gz
dotty-2764609bb17dfc8691d33fcc1c70a9891af59e70.tar.bz2
dotty-2764609bb17dfc8691d33fcc1c70a9891af59e70.zip
Complete better structure to diagnostic messages
Diffstat (limited to 'src/dotty/tools/dotc/reporting/diagnostic')
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/Message.scala7
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala62
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/messages.scala (renamed from src/dotty/tools/dotc/reporting/diagnostic/basic.scala)2
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/syntax.scala63
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/tpe.scala47
5 files changed, 174 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/Message.scala b/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
index 90ebf11a2..d7cfa2e2b 100644
--- a/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
+++ b/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
@@ -4,6 +4,7 @@ package reporting
package diagnostic
import util.SourcePosition
+import core.Contexts.Context
import java.util.Optional
@@ -55,9 +56,3 @@ class Message(
override def toString = s"$getClass at $pos: $message"
override def getMessage() = message
}
-
-object NoExplanation {
- def unapply(m: Message): Option[Message] =
- if (m.explanation == "") Some(m)
- else None
-}
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala b/src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala
new file mode 100644
index 000000000..d74099f4f
--- /dev/null
+++ b/src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala
@@ -0,0 +1,62 @@
+package dotty.tools
+package dotc
+package reporting
+package diagnostic
+
+import util.{SourcePosition, NoSourcePosition}
+import core.Contexts.Context
+
+object MessageCreator {
+ implicit class DiagnosticContext(val c: Context) extends AnyVal {
+ def shouldExplain(msg: MessageCreator): Boolean = {
+ implicit val ctx: Context = c
+ msg match {
+ case NoExplanation(_) => false
+ case _ => ctx.settings.explain.value
+ }
+ }
+ }
+
+ implicit def toNoExplanation(str: String) =
+ new NoExplanation(str)
+}
+
+trait MessageCreator {
+ import messages._
+
+ def msg: String
+ def kind: String
+ def explanation: String
+
+ def error(pos: SourcePosition) =
+ new Error(msg, pos, kind, explanation)
+
+ def warning(pos: SourcePosition) =
+ new Warning(msg, pos, kind, explanation)
+
+ def info(pos: SourcePosition) =
+ new Info(msg, pos, kind, explanation)
+
+ def featureWarnign(pos: SourcePosition) =
+ new FeatureWarning(msg, pos, kind, explanation)
+
+ def uncheckedWarning(pos: SourcePosition) =
+ new UncheckedWarning(msg, pos, kind, explanation)
+
+ def deprecationWarning(pos: SourcePosition) =
+ new DeprecationWarning(msg, pos, kind, explanation)
+
+ def migrationWarning(pos: SourcePosition) =
+ new MigrationWarning(msg, pos, kind, explanation)
+}
+
+class NoExplanation(val msg: String) extends MessageCreator {
+ val explanation = ""
+ val kind = ""
+}
+
+object NoExplanation {
+ def unapply(m: MessageCreator): Option[MessageCreator] =
+ if (m.explanation == "") Some(m)
+ else None
+}
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/basic.scala b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 2da986d89..382e9a295 100644
--- a/src/dotty/tools/dotc/reporting/diagnostic/basic.scala
+++ b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -9,7 +9,7 @@ import util.{SourcePosition, NoSourcePosition}
import config.Settings.Setting
import interfaces.Diagnostic.{ERROR, WARNING, INFO}
-object basic {
+object messages {
class Error(
msgFn: => String,
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/syntax.scala b/src/dotty/tools/dotc/reporting/diagnostic/syntax.scala
new file mode 100644
index 000000000..675cacbed
--- /dev/null
+++ b/src/dotty/tools/dotc/reporting/diagnostic/syntax.scala
@@ -0,0 +1,63 @@
+package dotty.tools
+package dotc
+package reporting
+package diagnostic
+
+import dotc.core._
+import Contexts.Context, Decorators._, Symbols._
+import dotc.printing.SyntaxHighlighting._
+import util.{SourcePosition, NoSourcePosition}
+
+object syntax {
+ import dotc.ast.Trees._
+ import dotc.ast.untpd
+
+ abstract class EmptyCatchOrFinallyBlock(tryBody: untpd.Tree)(implicit ctx: Context) extends MessageCreator {
+ val explanation = {
+ val tryString = tryBody match {
+ case Block(Nil, untpd.EmptyTree) => "{}"
+ case _ => tryBody.show
+ }
+
+ val code1 =
+ s"""|try $tryString catch {
+ | case t: Throwable => ???
+ |}""".stripMargin
+
+ val code2 =
+ s"""|try $tryString finally {
+ | // perform your cleanup here!
+ |}""".stripMargin
+
+ hl"""|Explanation:
+ |============
+ |A ${"try"} expression should be followed by some mechanism to handle any exceptions
+ |thrown. Typically a ${"catch"} expression follows the ${"try"} and pattern matches
+ |on any expected exceptions. For example:
+ |
+ |$code1
+ |
+ |It is also possible to follow a ${"try"} immediately by a ${"finally"} - letting the
+ |exception propagate - but still allowing for some clean up in ${"finally"}:
+ |
+ |$code2
+ """.stripMargin
+ }
+ }
+
+ class EmptyCatchBlock(tryBody: untpd.Tree)(implicit ctx: Context)
+ extends EmptyCatchOrFinallyBlock(tryBody) {
+ val kind = "Syntax"
+ val msg =
+ hl"""|The ${"catch"} block does not contain a valid expression, try
+ |adding a case like - `${"case e: Exception =>"}` to the block""".stripMargin
+ }
+
+ case class EmptyCatchAndFinallyBlock(tryBody: untpd.Tree)(implicit ctx: Context)
+ extends EmptyCatchOrFinallyBlock(tryBody) {
+ val kind = "Syntax"
+ val msg =
+ hl"""|A ${"try"} without ${"catch"} or ${"finally"} is equivalent to putting
+ |its body in a block; no exceptions are handled.""".stripMargin
+ }
+}
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/tpe.scala b/src/dotty/tools/dotc/reporting/diagnostic/tpe.scala
new file mode 100644
index 000000000..4aa24c440
--- /dev/null
+++ b/src/dotty/tools/dotc/reporting/diagnostic/tpe.scala
@@ -0,0 +1,47 @@
+package dotty.tools
+package dotc
+package reporting
+package diagnostic
+
+import dotc.core._
+import Contexts.Context, Decorators._, Symbols._
+import dotc.printing.SyntaxHighlighting._
+import util.{SourcePosition, NoSourcePosition}
+
+object tpe {
+ import dotc.ast.Trees._
+ import dotc.ast.untpd
+
+ class DuplicateBind(
+ bind: untpd.Bind,
+ tree: untpd.CaseDef
+ )(implicit ctx: Context) extends MessageCreator {
+ val kind = "Naming"
+
+ val msg =
+ em"duplicate pattern variable: `${bind.name}`"
+
+ val explanation = {
+ val pat = tree.pat.show
+ val guard = tree.guard match {
+ case untpd.EmptyTree => ""
+ case guard => s"if ${guard.show}"
+ }
+
+ val body = tree.body match {
+ case Block(Nil, untpd.EmptyTree) => ""
+ case body => s" ${body.show}"
+ }
+
+ val caseDef = s"case $pat$guard => $body"
+
+ hl"""|Explanation
+ |===========
+ |For each ${"case"} bound variable names have to be unique. In:
+ |
+ |$caseDef
+ |
+ |`${bind.name}` is not unique. Rename one of the bound variables!""".stripMargin
+ }
+ }
+}