Hey everyone. Recently at the Scala Tooling Summit there was a large discussion around the topic of more structured diagnostics. You can also read the previous discussion that started this effort
here. Since there seems to be pretty widespread support in this effort I’d like to take a moment an outline what has been done up to this point, and outline a roadmap for this effort moving forward, specifically focusing on actionable diagnostics.
Where we’re at
There was originally an issue in Dotty tracking part of this work introducing the DiagnosticCode
and DiagnosticRelatedInformation
. As you can see in the issue, the DiagnosticCode
has been added all throughout the chain, and the DiagnosticRelatedInformation
has been introduced throughout the tool chain, but not yet added to the compiler. The work in that area will continue and be tracked on the existing issue, while this thread will outline the work set to be done regarding actionable diagnostics and utilizing the data
field.
What is an actionable diagnostic
An actionable diagnostic is a diagnostic that provides a “fix” for something that the user is experiencing. A great example of this already existing in Scala is when a user is using scala-cli and they have an outdated dependency. In your editor you’ll get an info diagnostic with a “fix” attached to it that they user can trigger to update their dependency. While this fix originates from scala-cli, the idea here would be for the compiler to offer fixes for things it knows how to fix. These would then be forwarded through the compiler → Build tool → BSP → editor chain. You can see an example of this working with the compiler and IntelliJ here. This was a POC done during the tooling summit to show the idea in action.
What’s next
At this point I’d like to outline the steps necessary to start emitting these types of fixes from the compiler. While the necessary things exist from BSP onwards already, we need to prepare the various build servers, sbt bridge, and compiler to start emitting and forwarding them.
Agreeing on a structure.
While scala-cli was already using their own structure of an LSP [TextEdit
(Specification), it was being used at the root level. In order to future proof this and allow for more potential fields under the data
key we decided to nest this under an edits
key. That key would contain an array of LSP WorkspaceEdit
s instead of TextEdit
s to further allow for more types of refactorings in the future such as new files being created, moved, or deleted. You can see this new structure in scala-cli and the changes necessary in Metals to handle this new structure here. While this structure works well for BSP onwards, it is quite a complex representations with lots of possibilities. The POC that was done at the summit used a TextEdit representation at the Problem
level and re-used the Patch
structure from the compiler. I think using the Patch
that already exists in the compiler to be wise, but the question then becomes whether or not TextEdit
really contains enough possibilities, or if the representation inside of Problem
should allow for more information.
Outlining the steps
- agree on the structure that belongs in
Problem
. - make the necessary additions to
Problem
. - once
Problem
is merged and released, update zinc to use it - once zinc is released update Dotty to use the latest sbt/zinc
- start utilizing the new
data
field inProblem
and having the compiler forward “fixes” - ensure that tools like Metals and IntelliJ are fully able to utilize these.
The Scala Center team is dedicated to providing regular and transparent
community updates about project plans & progress. In this forum we created a new
topic category to allow quicker orientation going forward: “Scala Center
Updates”. Even though all feedback is welcome, we keep the right to make
executive decisions about projects we lead. Overview of all our activities can
always be found at https://scala.epfl.ch/records.html
.