diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-09-16 18:23:11 +0200 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2016-10-10 13:25:33 +0200 |
commit | 2764609bb17dfc8691d33fcc1c70a9891af59e70 (patch) | |
tree | cbb0c188a5fc83b7d91256502e4c4f42fd5fcd26 /src/dotty/tools/dotc/reporting/diagnostic | |
parent | 2b2cfe71aacb50e91d6956f0d4ee7d555537698a (diff) | |
download | dotty-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.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala | 62 | ||||
-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.scala | 63 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/diagnostic/tpe.scala | 47 |
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 + } + } +} |