blob: 8b1f6567309f3abed64ec9c3ae9fcf886aa60552 (
plain) (
tree)
|
|
package dotty.tools
package dotc
package reporting
package diagnostic
import util.SourcePosition
import core.Contexts.Context
object Message {
/** This implicit conversion provides a fallback for error messages that have
* not yet been ported to the new scheme. Comment out this `implicit def` to
* see where old errors still exist
*/
implicit def toNoExplanation(str: String): Message =
new NoExplanation(str)
}
/** A `Message` contains all semantic information necessary to easily
* comprehend what caused the message to be logged. Each message can be turned
* into a `MessageContainer` which contains the log level and can later be
* consumed by a subclass of `Reporter`.
*
* @param errorId a unique number identifying the message, this will later be
* used to reference documentation online
*/
abstract class Message(val errorId: Int) { self =>
import messages._
/** The `msg` contains the diagnostic message e.g:
*
* > expected: String
* > found: Int
*
* This message wil be placed underneath the position given by the enclosing
* `MessageContainer`
*/
def msg: String
/** The kind of the error message is something like "Syntax" or "Type
* Mismatch"
*/
def kind: String
/** 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
* avoid these errors.
*/
def explanation: String
/** It is possible to map `msg` to add details, this is at the loss of
* precision since the type of the resulting `Message` won't be original
* extending class
*
* @return a `Message` with the mapped message
*/
def mapMsg(f: String => String) = new Message(errorId) {
val msg = f(self.msg)
val kind = self.kind
val explanation = self.explanation
}
/** Enclose this message in an `Error` container */
def error(pos: SourcePosition) =
new Error(self, pos)
/** Enclose this message in an `Warning` container */
def warning(pos: SourcePosition) =
new Warning(self, pos)
/** Enclose this message in an `Info` container */
def info(pos: SourcePosition) =
new Info(self, pos)
/** Enclose this message in an `FeatureWarning` container */
def featureWarning(pos: SourcePosition) =
new FeatureWarning(self, pos)
/** Enclose this message in an `UncheckedWarning` container */
def uncheckedWarning(pos: SourcePosition) =
new UncheckedWarning(self, pos)
/** Enclose this message in an `DeprecationWarning` container */
def deprecationWarning(pos: SourcePosition) =
new DeprecationWarning(self, pos)
/** Enclose this message in an `MigrationWarning` container */
def migrationWarning(pos: SourcePosition) =
new MigrationWarning(self, pos)
}
/** The fallback `Message` containing no explanation and having no `kind` */
class NoExplanation(val msg: String) extends Message(NoExplanation.ID) {
val explanation = ""
val kind = ""
}
/** The extractor for `NoExplanation` can be used to check whether any error
* lacks an explanation
*/
object NoExplanation {
final val ID = -1
def unapply(m: Message): Option[Message] =
if (m.explanation == "") Some(m)
else None
}
|