Missing error messages
See original GitHub issueWe have a multitude of errors that need to be ported to the new scheme - you’ll find these under “Error Messages” below. But first, a tutorial:
HOWTO on creating new messages
Once you’ve identified an error you want to replace, you should decide what semantic information is needed in the message - i.e. the position, perhaps a tree or some types. For this example we’re going to be implementing the error message for the following error:
case class Foo // you're not allowed to have a case class without a single parameter list!
So we create a file with this and compile it using ./bin/dotc test.scala
. This gives us the error message:
case class Foo
^
case class needs to have at least one parameter list
So now we search the repository for “case class needs to have” - I do this with git grep -n "case class needs to have"
.
And now we find that in src/dotty/tools/dotc/ast/Desugar.scala
we have the following line:
ctx.error("case class needs to have at least one parameter list", cdef.pos)
Cool - now we know what to replace. So next step is to add a case class
to src/dotty/tools/dotc/reporting/diagnostic/messages.scala
. The case class that we add should extend Message
:
abstract class Message(val errorId: Int) {
/** 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
...
}
Now we name our case class something useful and give it a unique errorId
:
case class CaseClassMissingParamList() extends Message(4)
Since we can see that the call to ctx.error
took the position of a cdef: TypeDef
, we could perhaps use this in the constructor of our Message
?
case class CaseClassMissingParamList(cdef: untpd.TypeDef) extends Message(4)
It might also be that we’re going to be manipulating cdef
tree, as such we should pass a Context
to get all the implicit operations:
case class CaseClassMissingParamList(cdef: untpd.TypeDef)(implicit ctx: Context)
extends Message(4)
Alright! Now we can start adding things to our Messsage
:
case class CaseClassMissingParamList(cdef: untpd.TypeDef)(implicit ctx: Context)
extends Message(4) {
val kind = "Syntax" // this will be shown as a delimiter: "-- [E004] Syntax X -------"
// we can use the "hl" interpolator to give syntax highlighting to our message:
val msg =
hl"""|A ${"case class"} must have at least one parameter list"""
// not everything that is interpolated will be highlighted, for instance you can use
// colors like: Red("must") - this will get the red color.
val explanation =
hl"""|${cdef.name} ${Red("must")} have at least one parameter list, if you would rather
|have a singleton representation of ${cdef.name}, use a "${"case object"}".
|Or, add an explicit `()' as a parameter list to ${cdef.name}.""".stripMargin
}
Stable Identifier
So far, we’ve simplified the above cases a smidge, the error messages themselves actually don’t extend Message
by passing an integer. They should actually create an entry into the java enum defined in ErrorMessageID.java. This will enable us to have stable identifiers which helps tooling between the different compilers.
Now you replace the call to ctx.error(String)
with ctx.error(CaseClassMissingParamList(cdef))
- and you’re done with the implementation!
Tests
To test your solution, add a test to ErrorMessagesTests.scala. An example for TypeMismatch
is provided and documented.
Online documentation
We really want to have online documentation providing more detailed information on what went wrong. Currently the idea is to create markdown pages in the docs/docs
folder. Any contribution here would be greatly appreciated!
Things to keep in mind
- You’re creating a semantic object - this object will either be the output of the terminal or it could be used in an IDE, so make sure to include the relevant things. Typically:
Types
,Position
,Tree
- Name your error something easy to understand!
- If you think your error doesn’t need an explanation - that’s fine - just put
val explanation = ""
- If you find yourself not being able to manipulate trees - do you have the implicit context?
- “HALP!” - please post in our gitter channel: https://gitter.im/lampepfl/dotty or comment on this issue 😃
Missing Messages
Please comment below saying which messages you’d like to tackle.
Available
- Applications.scala:95 (@aesteve)
- Checking.scala:49
- Checking.scala:526 (@benkobalog)
- Checking.scala:533
- Checking.scala:539
- Checking.scala:555
- Checking.scala:565
- Checking.scala:576
- Checking.scala:583
- Checking.scala:602
- Checking.scala:622
- Checking.scala:628
- Checking.scala:646
- Checking.scala:648
- Checking.scala:692
- Checking.scala:702
- Checking.scala:716
- Docstrings.scala:30
- Namer.scala:222
- Namer.scala:258
- Namer.scala:1081
- Namer.scala:1105
- Parsers.scala:2266
- Parsers.scala:2438
- Parsers.scala:2456
- PatternMatcher.scala:911
- RefChecks.scala:694
- RefChecks.scala:698
- RefChecks.scala:874
- SymDenotations.scala:1964
- TypeAssigner.scala:34
- TypeAssigner.scala:208
- TypeAssigner.scala:233
- TypeAssigner.scala:299
- TypeAssigner.scala:314
- TypeAssigner.scala:356
- TypeAssigner.scala:358
- TypeAssigner.scala:416
- Typer.scala:174
- Typer.scala:196
- Typer.scala:355
- Typer.scala:411
- Typer.scala:866
- Typer.scala:1172 (@Wojtechnology)
- Typer.scala:1519
- Typer.scala:1572 (on hold)
- Typer.scala:1731
- Typer.scala:1924
- Typer.scala:2015
Contributors
Issue Analytics
- State:
- Created 7 years ago
- Reactions:48
- Comments:120 (96 by maintainers)
Top GitHub Comments
This is an awesome way of empowering people to contribute to the project. I think I’ll use this to contribute. Thanks a lot for writing this up @felixmulder!
The line numbers are out of date. To make it easier for others to find the referenced line even if the file changes, it would be a good idea to copy the lines here so others can ctrl-f to find the line.