diff --git a/compiler/src/dotty/tools/dotc/reporting/Message.scala b/compiler/src/dotty/tools/dotc/reporting/Message.scala index 84078cebe91f..0db5d355e963 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Message.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Message.scala @@ -51,7 +51,7 @@ abstract class Message(val errorId: ErrorMessageID) { self => * This will be printed as "$kind Error", "$kind Warning", etc, on the first * line of the message. */ - def kind: String + def kind: MessageKind /** The explanation should provide a detailed description of why the error * occurred and use examples from the user's own code to illustrate how to @@ -140,7 +140,7 @@ abstract class Message(val errorId: ErrorMessageID) { self => class NoExplanation(msgFn: => String) extends Message(ErrorMessageID.NoExplanationID) { def msg: String = msgFn def explain: String = "" - val kind: String = "" + val kind: MessageKind = MessageKind.NoKind override def toString(): String = msg } diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageKind.scala b/compiler/src/dotty/tools/dotc/reporting/MessageKind.scala new file mode 100644 index 000000000000..f039ed900a76 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/reporting/MessageKind.scala @@ -0,0 +1,41 @@ +package dotty.tools.dotc.reporting + +/** Message kinds that can be used in a Message. + * NOTE: Keep in mind that if you have a new message or a new ErrorMessageID + * that doesn't fit well into an existing kind, create a new one. + */ +enum MessageKind: + case NoKind + case Syntax + case Type + case TypeMismatch + case Naming + case Declaration + case NotFound + case PatternMatch + case Cyclic + case Reference + case DocComment + case LossyConversion + case PatternMatchExhaustivity + case MatchCaseUnreachable + case Compatibility + case PotentialIssue + + /** Human readable message that will end up being shown to the user. + * NOTE: This is only used in the situation where you have multiple words + * and don't want to rely on the default toString of the enum. + */ + def message: String = + this match + case NoKind => "No Kind" + case TypeMismatch => "Type Mismatch" + case NotFound => "Not Found" + case PatternMatch => "Pattern Match" + case DocComment => "Doc Comment" + case LossyConversion => "Lossy Conversion" + case PatternMatchExhaustivity => "Pattern Match Exhaustivity" + case MatchCaseUnreachable => "Match case Unreachable" + case PotentialIssue => "Potential Issue" + case kind => kind.toString +end MessageKind diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala index 4e68743802b1..a1d10d8e900f 100644 --- a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala +++ b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala @@ -172,13 +172,13 @@ trait MessageRendering { val realPos = pos.nonInlined val fileAndPos = posFileStr(realPos) val errId = - if (message.errorId ne ErrorMessageID.NoExplanationID) { + if (message.errorId ne ErrorMessageID.NoExplanationID) then val errorNumber = message.errorId.errorNumber s"[E${"0" * (3 - errorNumber.toString.length) + errorNumber}] " - } else "" + else "" val kind = - if (message.kind == "") diagnosticString - else s"${message.kind} $diagnosticString" + if (message.kind == MessageKind.NoKind) diagnosticString + else s"${message.kind.message} $diagnosticString" val title = if fileAndPos.isEmpty then s"$errId$kind:" // this happens in dotty.tools.repl.ScriptedTests // TODO add name of source or remove `:` (and update test files) else s"$errId$kind: $fileAndPos" diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 40a3e193546a..98bd91710a83 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -40,42 +40,42 @@ import transform.SymUtils._ */ abstract class SyntaxMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Syntax" + def kind = MessageKind.Syntax abstract class TypeMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Type" + def kind = MessageKind.Type trait ShowMatchTrace(tps: Type*)(using Context) extends Message: override def msgSuffix: String = matchReductionAddendum(tps*) abstract class TypeMismatchMsg(found: Type, expected: Type)(errorId: ErrorMessageID)(using Context) extends Message(errorId), ShowMatchTrace(found, expected): - def kind = "Type Mismatch" + def kind = MessageKind.TypeMismatch def explain = err.whyNoMatchStr(found, expected) override def canExplain = true abstract class NamingMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Naming" + def kind = MessageKind.Naming abstract class DeclarationMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Declaration" + def kind = MessageKind.Declaration /** A simple not found message (either for idents, or member selection. * Messages of this class are sometimes dropped in favor of other, more * specific messages. */ abstract class NotFoundMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Not Found" + def kind = MessageKind.NotFound def name: Name abstract class PatternMatchMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Pattern Match" + def kind = MessageKind.PatternMatch abstract class CyclicMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Cyclic" + def kind = MessageKind.Cyclic abstract class ReferenceMsg(errorId: ErrorMessageID) extends Message(errorId): - def kind = "Reference" + def kind = MessageKind.Reference abstract class EmptyCatchOrFinallyBlock(tryBody: untpd.Tree, errNo: ErrorMessageID)(using Context) extends SyntaxMsg(EmptyCatchOrFinallyBlockID) { @@ -638,7 +638,7 @@ import transform.SymUtils._ class ProperDefinitionNotFound()(using Context) extends Message(ProperDefinitionNotFoundID) { - def kind: String = "Doc Comment" + def kind = MessageKind.DocComment def msg = em"""Proper definition was not found in ${hl("@usecase")}""" def explain = { @@ -818,14 +818,14 @@ import transform.SymUtils._ class LossyWideningConstantConversion(sourceType: Type, targetType: Type)(using Context) extends Message(LossyWideningConstantConversionID): - def kind = "Lossy Conversion" + def kind = MessageKind.LossyConversion def msg = em"""|Widening conversion from $sourceType to $targetType loses precision. |Write `.to$targetType` instead.""".stripMargin def explain = "" class PatternMatchExhaustivity(uncoveredFn: => String, hasMore: Boolean)(using Context) extends Message(PatternMatchExhaustivityID) { - def kind = "Pattern Match Exhaustivity" + def kind = MessageKind.PatternMatchExhaustivity lazy val uncovered = uncoveredFn def msg = val addendum = if hasMore then "(More unmatched cases are elided)" else "" @@ -856,7 +856,7 @@ import transform.SymUtils._ class MatchCaseUnreachable()(using Context) extends Message(MatchCaseUnreachableID) { - def kind = "Match case Unreachable" + def kind = MessageKind.MatchCaseUnreachable def msg = "Unreachable case" def explain = "" } @@ -1783,7 +1783,7 @@ import transform.SymUtils._ class FailureToEliminateExistential(tp: Type, tp1: Type, tp2: Type, boundSyms: List[Symbol], classRoot: Symbol)(using Context) extends Message(FailureToEliminateExistentialID) { - def kind: String = "Compatibility" + def kind = MessageKind.Compatibility def msg = val originalType = ctx.printer.dclsText(boundSyms, "; ").show em"""An existential type that came from a Scala-2 classfile for $classRoot @@ -2228,7 +2228,7 @@ import transform.SymUtils._ class PureExpressionInStatementPosition(stat: untpd.Tree, val exprOwner: Symbol)(using Context) extends Message(PureExpressionInStatementPositionID) { - def kind = "Potential Issue" + def kind = MessageKind.PotentialIssue def msg = "A pure expression does nothing in statement position; you may be omitting necessary parentheses" def explain = em"""The pure expression $stat doesn't have any side effect and its result is not assigned elsewhere. diff --git a/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala b/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala index 12efc32ff1c5..deae96d4168f 100644 --- a/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala +++ b/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala @@ -16,7 +16,7 @@ class TestMessageLaziness extends DottyTest { } case class LazyError() extends Message(ErrorMessageID.LazyErrorId) { - val kind = "Test" + val kind = MessageKind.NoKind def msg = throw new Error("Didn't stay lazy.") def explain = "" } diff --git a/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala b/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala index dcbbcc015d41..c6ec06d0bb4e 100644 --- a/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala +++ b/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala @@ -120,7 +120,7 @@ object TestReporter { /** Prints the message with the given position indication in a simplified manner */ override def printMessageAndPos(dia: Diagnostic, extra: String)(using Context): Unit = { def report() = { - val msg = s"${dia.pos.line + 1}: " + dia.msg.kind + extra + val msg = s"${dia.pos.line + 1}: " + dia.msg.kind.message + extra val extraInfo = inlineInfo(dia.pos) writer.println(msg)