Describe the bug
When using a literal type annotation within a worksheet Metals shows an error such as "identifier expected but string constant found" for string literals and "identifier expected but integer constant found" for integer literals.
I noticed a similar issue https://github.com/scalameta/metals/issues/787 where exactly same kind of errors had been fixed for regular *.scala files. Indeed, Metals does not show any errors for literal type annotations in normal project files.
To Reproduce
Steps to reproduce the behavior:
val fortyTwo: 42 = 42 to a worksheetExpected behavior
No errors in the IDE.
Installation:
Thanks for reporting! I think this is an issue with the Scalameta parser, the sc dialect seem not to work with literal type annotations.
@kpbochenek Any idea if we can and should fix the dialect in Scalameta?
Also, I think everything will work in the worksheets, but Metals will show flaky issue.
We might need an additional worksheet dialect coming to think of it.
Also, I think everything will work in the worksheets, but Metals will show flaky issue.
Yep, exactly so. I updated the issue title to something more accurate since worksheet evaluation still works despite the reported error 馃檪
Right as you said worksheets and sbt share the same dialect which is problematic here.
build.sbt does not allow literal type annotations so a new dialect is needed here.
It should be probably enough to change this? (for Sbt dialect it is set to false)
// Are literal types allowed, i.e. is `val a : 42 = 42` legal or not?
allowLiteralTypes: Boolean,
Question: How are actually handling compilation of worksheets? Is there a special utility of scalac to say this is a worksheet and compile it or just do something custom like wrapping it with package object and trying to compile as normal file?
@kpbochenek Compilation is handled by mdoc, but parser errors are separate.
It should be probably enough to change this? (for Sbt dialect it is set to false)
I think so, will check it out!
private def parse(path: AbsolutePath): Option[Parsed[Source]] = {
dialect(path).map { d =>
val input = path.toInputFromBuffers(buffers)
d(input).parse[Source]
}
}
private def dialect(path: AbsolutePath): Option[Dialect] = {
Option(PathIO.extension(path.toNIO)).collect {
case "scala" => dialects.Scala
case "sbt" => dialects.Sbt1
case "sc" => dialects.Sbt1
}
}
I think I will wait until the Scala 3 PR is merged, since we are moving that class to mtags and the Scala veersion will be easier to access there.
It would be good to know how mdoc compiles those worksheets because that would mainly determine what dialect is best to use and in case of new dialect what rules should a new dialect have.
Most helpful comment
I think I will wait until the Scala 3 PR is merged, since we are moving that class to mtags and the Scala veersion will be easier to access there.