-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add unsafe RawPresentationCompiler implementation #24133
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
Conversation
…iver will now check for Thread.isInterrupted cancellation
| LabelPart(": ") :: toLabelParts(tpe, pos), | ||
| InlayHintKind.Type, | ||
| ) | ||
| .addDefinition(adjustedPos.start) |
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.
It was removed out of sudden in Scala 2 presentation compiler, I believe it is no longer necessary as we're deduplicating inlay hints during add
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 think it wasn't actually doing anything anymore
| | | ||
| |def test/*: (path : String<<java/lang/String#>>, num : Int<<scala/Int#>>, line : Int<<scala/Int#>>)*/ = | ||
| | hello ++/*[Tuple1<<scala/Tuple1#>>["line"], Tuple1<<scala/Tuple1#>>[Int<<scala/Int#>>]]*/ (line = 1)/*(using refl<<scala/`<:<`.refl().>>)*//*[Tuple1<<scala/Tuple1#>>[Int<<scala/Int#>>]]*/ | ||
| | hello ++/*[Tuple1<<scala/Tuple1#>>["line"], Tuple1<<scala/Tuple1#>>[Int<<scala/Int#>>]]*/ (line = 1)/*[Tuple1<<scala/Tuple1#>>[Int<<scala/Int#>>]]*//*(using refl<<scala/`<:<`.refl().>>)*/ |
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.
Caused by mtags version bump
KacperFKorban
left a comment
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.
Looks good to me. (Just "Comment", since I don't feel "in the loop" enough to understand the context of these changes)
| } | ||
|
|
||
| tree match |
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.
TLDR: I think that it's fine to patch only the necessary changes for now, but this should probably be refactored (similarly as Scala 2 code) soon-ish.
The refactor in the Scala 2 PC was meant to allow for more than one "case" to be executed here. This isn't a problem yet, since scalameta/metals#7815 hasn't been ported yet. Though one could make an argument that this problem appeared before and was "hacked" my merging implementations for two inlay hint types.
The idea behind the refactor is:
- We move the logic from the branches in this match into private methods on appropriate Inlay-Hint-providing-objects.
- Afterwards, this method is simplified to a
foldLeftthrough all the cases. - Every Inlay-Hint-providing-objects returns its inlay hints in separation, and we merge them together for every tree.
- Afterwards, they can be deduplicated (right now only for InferredType) – this separates generation and deduplication.
I think that a similar refactor should be done here as well, though it maybe shouldn't be part of this PR.
presentation-compiler/src/main/dotty/tools/pc/RawScalaPresentationCompiler.scala
Show resolved
Hide resolved
presentation-compiler/src/main/dotty/tools/pc/DiagnosticProvider.scala
Outdated
Show resolved
Hide resolved
presentation-compiler/src/main/dotty/tools/pc/RawScalaPresentationCompiler.scala
Show resolved
Hide resolved
| class DiagnosticProvider(driver: InteractiveDriver, params: VirtualFileParams): | ||
|
|
||
| def diagnostics(): List[lsp4j.Diagnostic] = | ||
| val diags = driver.run(params.uri().nn, params.text().nn) |
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.
We should check if diagnotics are expected via params.shouldReturnDiagnostics()
I added it recently, will be available in the new metals
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.
Can you tell me the scenario in which you don't want to return diags ?
LSP always sends request after keypress in following order:
didChange -> completion -> inlayHints
It will be compiled by completion or inlay hints anyway so it doesn't matter, and getting diagnostics is a free operation in terms of computations.
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 was thinking of cases where people would want to switch between the two modes.
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.
Ok, I see it, it would be very easy to control this on lsp level though but yeah. We can add it for simplicity.
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 don't see this param to be accessible
tgodzik
left a comment
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.
Great work, some minor last comments, but we should be good to include this in 3.8.0
presentation-compiler/src/main/dotty/tools/pc/DiagnosticProvider.scala
Outdated
Show resolved
Hide resolved
presentation-compiler/src/main/dotty/tools/pc/DiagnosticProvider.scala
Outdated
Show resolved
Hide resolved
|
Looks like DiagnosticProviderSuite is failing, might just be on windows |
I'm fixing it, it will fail everywhere because I didn't override shouldReturnDiags in tests |
tgodzik
left a comment
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!
`RawPresentationCompiler` is a direct, unsafe way to access presentation compiler interface provided in scalameta/metals#7841 It is up to the consumer to guarantee thread safety and sequential request processing. This solves many issues with the current `PresentationCompiler` interface but most important are: - We now have control where and how each presentation compiler method is run. Before it was always run on a `SingleThreadExecutor` created by the `PresentationCompiler`. The original behavior will stay with the standard `ScalaPresentationCompiler` interface. (There is another PR that refactors that part), - If there was bug in scheduler all versions were affected, On top of that this PR implements all things that will work out of the box: - Diagnostic provider - trivial implementation, previously not possible to LIFO task used by `Scala3CompilerAccess`. Will be super useful e.g for Scastie which will become a consumer of this new raw API. - `InteractiveDriver` compilation cancellation by checking Thread.interrupted(). Future changes are required to make it work with safe `ScalaPresentationCompiler` and `CancelTokens`. Here we can omit the cancel token support for now, because we would check for `Thread.interrupted()` along the `cancelToken.isCancelled` anyway, and we can now easily interrupt it from e.g `IO.interruptible` Those changes were adapted from my other PR's that required adjustment of `Scala3CompilerAccess` but I don't think it is ready / I'm not happy with current state of that refactor. In the future we should think of replacing the implementation of `ScalaPresentationCompiler` to use `RawPresentationCompiler` as underlying impl and just call it in safe way. The implementation was tested on the actual LSP server and it works fine.
`RawPresentationCompiler` is a direct, unsafe way to access presentation compiler interface provided in scalameta/metals#7841 It is up to the consumer to guarantee thread safety and sequential request processing. This solves many issues with the current `PresentationCompiler` interface but most important are: - We now have control where and how each presentation compiler method is run. Before it was always run on a `SingleThreadExecutor` created by the `PresentationCompiler`. The original behavior will stay with the standard `ScalaPresentationCompiler` interface. (There is another PR that refactors that part), - If there was bug in scheduler all versions were affected, On top of that this PR implements all things that will work out of the box: - Diagnostic provider - trivial implementation, previously not possible to LIFO task used by `Scala3CompilerAccess`. Will be super useful e.g for Scastie which will become a consumer of this new raw API. - `InteractiveDriver` compilation cancellation by checking Thread.interrupted(). Future changes are required to make it work with safe `ScalaPresentationCompiler` and `CancelTokens`. Here we can omit the cancel token support for now, because we would check for `Thread.interrupted()` along the `cancelToken.isCancelled` anyway, and we can now easily interrupt it from e.g `IO.interruptible` Those changes were adapted from my other PR's that required adjustment of `Scala3CompilerAccess` but I don't think it is ready / I'm not happy with current state of that refactor. In the future we should think of replacing the implementation of `ScalaPresentationCompiler` to use `RawPresentationCompiler` as underlying impl and just call it in safe way. The implementation was tested on the actual LSP server and it works fine. [Cherry-picked 582366c][modified]
`RawPresentationCompiler` is a direct, unsafe way to access presentation compiler interface provided in scalameta/metals#7841 It is up to the consumer to guarantee thread safety and sequential request processing. This solves many issues with the current `PresentationCompiler` interface but most important are: - We now have control where and how each presentation compiler method is run. Before it was always run on a `SingleThreadExecutor` created by the `PresentationCompiler`. The original behavior will stay with the standard `ScalaPresentationCompiler` interface. (There is another PR that refactors that part), - If there was bug in scheduler all versions were affected, On top of that this PR implements all things that will work out of the box: - Diagnostic provider - trivial implementation, previously not possible to LIFO task used by `Scala3CompilerAccess`. Will be super useful e.g for Scastie which will become a consumer of this new raw API. - `InteractiveDriver` compilation cancellation by checking Thread.interrupted(). Future changes are required to make it work with safe `ScalaPresentationCompiler` and `CancelTokens`. Here we can omit the cancel token support for now, because we would check for `Thread.interrupted()` along the `cancelToken.isCancelled` anyway, and we can now easily interrupt it from e.g `IO.interruptible` Those changes were adapted from my other PR's that required adjustment of `Scala3CompilerAccess` but I don't think it is ready / I'm not happy with current state of that refactor. In the future we should think of replacing the implementation of `ScalaPresentationCompiler` to use `RawPresentationCompiler` as underlying impl and just call it in safe way. The implementation was tested on the actual LSP server and it works fine.
`RawPresentationCompiler` is a direct, unsafe way to access presentation compiler interface provided in scalameta/metals#7841 It is up to the consumer to guarantee thread safety and sequential request processing. This solves many issues with the current `PresentationCompiler` interface but most important are: - We now have control where and how each presentation compiler method is run. Before it was always run on a `SingleThreadExecutor` created by the `PresentationCompiler`. The original behavior will stay with the standard `ScalaPresentationCompiler` interface. (There is another PR that refactors that part), - If there was bug in scheduler all versions were affected, On top of that this PR implements all things that will work out of the box: - Diagnostic provider - trivial implementation, previously not possible to LIFO task used by `Scala3CompilerAccess`. Will be super useful e.g for Scastie which will become a consumer of this new raw API. - `InteractiveDriver` compilation cancellation by checking Thread.interrupted(). Future changes are required to make it work with safe `ScalaPresentationCompiler` and `CancelTokens`. Here we can omit the cancel token support for now, because we would check for `Thread.interrupted()` along the `cancelToken.isCancelled` anyway, and we can now easily interrupt it from e.g `IO.interruptible` Those changes were adapted from my other PR's that required adjustment of `Scala3CompilerAccess` but I don't think it is ready / I'm not happy with current state of that refactor. In the future we should think of replacing the implementation of `ScalaPresentationCompiler` to use `RawPresentationCompiler` as underlying impl and just call it in safe way. The implementation was tested on the actual LSP server and it works fine. [Cherry-picked 582366c][modified]
`RawPresentationCompiler` is a direct, unsafe way to access presentation compiler interface provided in scalameta/metals#7841 It is up to the consumer to guarantee thread safety and sequential request processing. This solves many issues with the current `PresentationCompiler` interface but most important are: - We now have control where and how each presentation compiler method is run. Before it was always run on a `SingleThreadExecutor` created by the `PresentationCompiler`. The original behavior will stay with the standard `ScalaPresentationCompiler` interface. (There is another PR that refactors that part), - If there was bug in scheduler all versions were affected, On top of that this PR implements all things that will work out of the box: - Diagnostic provider - trivial implementation, previously not possible to LIFO task used by `Scala3CompilerAccess`. Will be super useful e.g for Scastie which will become a consumer of this new raw API. - `InteractiveDriver` compilation cancellation by checking Thread.interrupted(). Future changes are required to make it work with safe `ScalaPresentationCompiler` and `CancelTokens`. Here we can omit the cancel token support for now, because we would check for `Thread.interrupted()` along the `cancelToken.isCancelled` anyway, and we can now easily interrupt it from e.g `IO.interruptible` Those changes were adapted from my other PR's that required adjustment of `Scala3CompilerAccess` but I don't think it is ready / I'm not happy with current state of that refactor. In the future we should think of replacing the implementation of `ScalaPresentationCompiler` to use `RawPresentationCompiler` as underlying impl and just call it in safe way. The implementation was tested on the actual LSP server and it works fine.
`RawPresentationCompiler` is a direct, unsafe way to access presentation compiler interface provided in scalameta/metals#7841 It is up to the consumer to guarantee thread safety and sequential request processing. This solves many issues with the current `PresentationCompiler` interface but most important are: - We now have control where and how each presentation compiler method is run. Before it was always run on a `SingleThreadExecutor` created by the `PresentationCompiler`. The original behavior will stay with the standard `ScalaPresentationCompiler` interface. (There is another PR that refactors that part), - If there was bug in scheduler all versions were affected, On top of that this PR implements all things that will work out of the box: - Diagnostic provider - trivial implementation, previously not possible to LIFO task used by `Scala3CompilerAccess`. Will be super useful e.g for Scastie which will become a consumer of this new raw API. - `InteractiveDriver` compilation cancellation by checking Thread.interrupted(). Future changes are required to make it work with safe `ScalaPresentationCompiler` and `CancelTokens`. Here we can omit the cancel token support for now, because we would check for `Thread.interrupted()` along the `cancelToken.isCancelled` anyway, and we can now easily interrupt it from e.g `IO.interruptible` Those changes were adapted from my other PR's that required adjustment of `Scala3CompilerAccess` but I don't think it is ready / I'm not happy with current state of that refactor. In the future we should think of replacing the implementation of `ScalaPresentationCompiler` to use `RawPresentationCompiler` as underlying impl and just call it in safe way. The implementation was tested on the actual LSP server and it works fine.
RawPresentationCompileris a direct, unsafe way to access presentation compiler interface provided inscalameta/metals#7841
It is up to the consumer to guarantee thread safety and sequential request processing.
This solves many issues with the current
PresentationCompilerinterface but most important are:SingleThreadExecutorcreated by thePresentationCompiler. The original behavior will stay with the standardScalaPresentationCompilerinterface. (There is another PR that refactors that part),On top of that this PR implements all things that will work out of the box:
Scala3CompilerAccess. Will be super useful e.g for Scastie which will become a consumer of this new raw API.InteractiveDrivercompilation cancellation by checking Thread.interrupted(). Future changes are required to make it work with safeScalaPresentationCompilerandCancelTokens. Here we can omit the cancel token support for now, because we would check forThread.interrupted()along thecancelToken.isCancelledanyway, and we can now easily interrupt it from e.gIO.interruptibleThose changes were adapted from my other PR's that required adjustment of
Scala3CompilerAccessbut I don't think it is ready / I'm not happy with current state of that refactor.In the future we should think of replacing the implementation of
ScalaPresentationCompilerto useRawPresentationCompileras underlying impl and just call it in safe way.The implementation was tested on the actual LSP server and it works fine.