-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: Add support for Scala 3's Best Effort compilation #5219
Conversation
36844fd
to
ac5ede7
Compare
metals/src/main/scala/scala/meta/internal/metals/CompilerConfiguration.scala
Show resolved
Hide resolved
I updated the bloop version (I did not realize before that bloop is published after every merge, that's so cool) and added some comments in a few places. |
We can try on the next version 1.5.18-47-e7577874-SNAPSHOT |
I still did not manage to fix the MillServerCodeLensSuite test, but we might as well see how the rest are doing |
Curiously, MillServerCodeLensSuite doesn't use Bloop so everything should work the same. |
Yes, those are broken by this PR, by the changes I made to checking if there are any artifacts in classpath before allowing to use code lens (working on this now). I believe that everything caused by the bloop changes was fixed |
Looks like Mill issue might be unrelated. Somehow it started failing on main also 🤔 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I think we are almost finished. My plan for now is:
- Release bloop with all the changes (it includes some other improvements)
- Release metals
- Merge this change so that we can have a period of testing.
if (isSuccessful) { | ||
if (isSuccessful || isBestEffortCompilation) { | ||
// // For best effort even if we get errors, we can generate new betasty files | ||
// if (!isSuccessful && !isBestEffortCompilation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove the commented code?
val scalaVersion = "3.5.0-RC1" | ||
|
||
// implemented in bloop | ||
test("best-effort-error-diagnostics") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we could reuse some of the tests in CompilersLspSuite for outline? We would need to make it into a base suite and extends here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I did have to have them test different diagnostics for scala 3 and I also had to add saving after changes, before testing completions (but for scala-2s outline they should work identically). I could not make one of the test work (not sure why), so I moved it out of the base suite to an outline only one.
I already updated Bloop to 1.6.0, so you can rebase and we can merge after release |
* but semanticDB and betasty (and thus the META_INF directory) may still be produced. | ||
* We want to avoid creating run/test/debug code lens in those situations. | ||
*/ | ||
private def isNonMetaFileInClasspath( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we instead just check if the current build target is compiling? diagnostics.hasCompilationErrors(buildId)
should be faster than looking up filesystem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, but there is a case where a project may not produce any errors/diagnostics, but may be compiled based on betasty produced by a failing dependency. In that case we will still not get any artifacts there (outside of betasty/semanticdb), and trying to run will produce classpath errors.
Though now that I think about it, we could check diagnostics of every dependency of a project to guess if a project was compiled using betasty. I'll try doing that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reviewing my changes just now, I realized that I do the same thing in doctor, not sure why I didn't think to do this here too until now 😅
override val saveAfterChanges: Boolean = false | ||
override val scala3Diagnostics = false | ||
|
||
test("imports-for-non-compiling") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we open an issue to look into it later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (hopefully ok): #6593
} yield () | ||
} | ||
|
||
// Here we test wheater completion symbols persist after removing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Here we test wheater completion symbols persist after removing | |
// Here we test whether completion symbols persist after removing |
8f979b0
to
40dcd41
Compare
Looks like the tests are failing now, but this is expected since the test checks if the code lenses are kept when there are errors and maybe they shouldn't? At least not when the code is still not saved. I think we did it to avoid the code lenses popping in and out of existence thus moving the lines up and down. Maybe it's enough if it doesn't do that Let's change |
This PR is meant to add support for Best Effort compilation in metals, with a few additional considerations: * Some unnecessary options are replaced from bloop and set for PC * Previously, any project could be run from metals if semanticdb was able to be generated. This caused a somewhat weird UX for best effort. Now the build directory is explicitly checked for the existence of non META-INF files. * Previously, in metals doctor, compilation would be set as correct if a compilation did not produce any errors. However, with best effort compilation, the compiler may not find any additional errors, beyond the ones from its dependencies (meaning that a project that cannot actually be compiled, could show up as on that was compiling). A note about that was added in the doctor.
Now we check diagnostics of all transitive dependencies for errors, instead of checking the existence of non meta-inf files. Also the keep-after-error test now does not check for remaining code lens after saving.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thank you so much for overseeing this! |
Currently yes, it is a bit more complicated to set up than just adding a flag unfortunately |
Related to feature request: scalameta/metals-feature-requests#327
Related PRs
The dotty one explains the reasoning behind the Best Effort compilation feature in detail, while the bloop one implements most of the logic of how projects are managed with the best effort options. All of them are needed for this feature to work here.
Explanation
Best Effort is meant to be a set of Scala 3 compiler options that allow the errored, but typed programs, to be able to be serialized as a TASTy aligned format (Best Effort TASTy), to be able to reuse those trees in both the dependent projects, and in the presentation compiler. This will allow better handling of projects that do not compile, and all of the dependent ones.
Basically, we are able to obtain a separate directory from bloop, that holds Best Effort TASTy, and can use it in PC. At the same time, SemanticDB generation is left as-is, those are created in the build file generated by bloop. Most of the best effort handling is done by bloop, including correctly setting the classpath with best effort directories. Let me quickly explain a few situations concerning project compilation that could happen before, and what can happen now with these PRs (especially with how the bloop one works):
Before:
As of this PR:
Contents
Overall this PR is meant to add support for Best Effort compilation in metals, with a few additional considerations:
Integration tests were also added (probably too few for now).