-
Notifications
You must be signed in to change notification settings - Fork 874
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
Using LSP's ErrorProvider & another attempt at CompletionCollector #7579
Conversation
@@ -1032,7 +1032,10 @@ public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActio | |||
continue; | |||
} | |||
} | |||
Optional<Diagnostic> diag = diagnostics.stream().filter(d -> entry.getKey().equals(d.getCode().getLeft())).findFirst(); | |||
Optional<Diagnostic> diag = diagnostics.stream().filter(d -> { | |||
String code = d.getCode() != null ? d.getCode().getLeft() : null; |
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.
Unrelated to the core of this PR, but discovered at the same time. According to the LSP Spec code
field is optional. Need to check for null
.
Interesting. But I want the change in - new attempt 8356885 with additional fix in ea184f7. I tested the TypeScript editing on I can evaluate expressions while debugging and I see no |
the slightly concerning aspect of the last revert was that it caused multiple issues in seemingly unrelated areas - and was only noticed during manual testing. It broke auto completion in the debug expression eval window, in a maven properties editor and @matthiasblaesing found also something in typescript (don't know the details). This indicates that there is a hole in the unit test coverage. You can find the traces under the original PR #7505 (comment). |
Let's do more QA this time.
I believe ea184f7 eliminates the NPE. I never saw the |
I see failure in Check PR labels, but I am not sure why? There are LSP and VSCode Extension labels on this PR. |
The CI checks are all green now, but I'd rather wait for Matthias to confirm the behavior is better when he edits TypeScript. On the other hand, I'd like these |
workflow runs are like container images. If you start one, the state doesn't change (restarts) until you build a new image. New ones are built when they are freshly triggered (e.g PR sync). This is also mentioned on the short reviewer guide we have on the wiki which is linked in the log when the label validation fails. So my guess is that this is what happened but I wasn't there to observe it. Neil forced a fresh workflow run and everything is green.
you probably saw that I added the
ci:dev-build
|
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.
From a quick(!) look this should fix the NullPointerException
problem as the use site is now guarded.
The second exception is still there. And indeed (quote from #7505 (comment))
Context: This happens when I call for code completion in "Evaluate expression", which is now broken.
can still be used to reproduce.
SEVERE [org.openide.util.RequestProcessor]: Error in RequestProcessor org.netbeans.spi.editor.completion.support.AsyncCompletionTask
java.lang.AssertionError: AsyncCompletionTask: query=org.netbeans.modules.lsp.client.bindings.LspCompletionProviderImpl$1@5804552c: query.query(): Result set not finished by resultSet.finish()
at org.netbeans.spi.editor.completion.support.AsyncCompletionTask.run(AsyncCompletionTask.java:200)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1403)
at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
[catch] at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2018)
More detailed steps to reproduce:
- Build from the branch backing this PR
- Create a new maven project
- Create a new class
Dummy
with this content:
import java.util.List;
public class Dummy {
public static void main(String[] args) {
List<String> list = List.of("X");
}
}
- Place a break point inside
main
(line 5) - Run "Debug file" on this
- Go to "Evaluate Expression"
- Enter "List."
- Call completion Ctrl+Space
- Observe problem
You are hitting the codepath in LspCompletionProviderImpl.java
line 55.
Same file shows a new regression introduced by this. Before your change the unused variable "list" (line 5) is marked, but only slightly
now it is reported as a warning:
And I think the popup also shows, that the error is reported twice.
Thank you for the QA, Matthias.
This one is particularly tricky. Unlike #7505 and #7483 - there is no declarative registration for "hints" (am I right @jlahoda). As such it is hard to find out whether there is a better alternative to |
ab7bdc9
to
5366560
Compare
@@ -94,7 +95,9 @@ public class JavaErrorProvider implements ErrorProvider { | |||
@Override | |||
public List<? extends Diagnostic> computeErrors(Context context) { | |||
List<Diagnostic> result = new ArrayList<>(); | |||
|
|||
if (!GraphicsEnvironment.isHeadless()) { |
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.
The java.lsp.server
project is using isHeadless()
to detect whether the code is running in VSCode or in NetBeans IDE. Using it here to solve #7579 (comment) inquiry.
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 I would rather suggest to drop the @MimeRegistration
on this class, and register the class in nbcode
. A similar pattern is already used for numerous services. Although in this case, it may be necessary/better to create the registration manually in layer.xml
, for other services we do it by having a subclass in nbcode
with an appropriate registration annotation.
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.
This gives me bad vibes and is only a partial solution. I placed a breakpoint in ErrorProviderBridge#run
and I see three ErrorProvider
there:
org.netbeans.modules.java.hints.infrastructure.JavaErrorProvider
org.netbeans.modules.editor.hints.lsp.HintsDiagnosticsProvider
org.netbeans.modules.micronaut.symbol.MicronautSymbolErrorProvider
(1) is now handled by checking GraphicsEnvironment#isHeadless
, (2) ist explicitly filtered out by its name, (3) is retained.
This will become whac-a-mole because the interaction are not obvious. Would a different approach make sense where an autoloaded helper module, that depends on the modules, that provides the LSP implementation, provides the bridge only for that module? That way the interaction is easier to see and if necessary easy to drop.
I don't know the enso module name but assuming it is enso-lsp
, a module enso-lsp.nb
could be used to provide the integration limited to the enso type.
Thanks for the hint. With such an error identification, it is easy to fix it: 87523ab. Now the debugging experience looks as expected (I'd say): |
* | ||
* @author lahvac | ||
*/ | ||
@MimeRegistration(mimeType="text/x-java", service=ErrorProvider.class) |
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 letting me know. I believe both NetBeans as well as VSCode are working fine with the current state of this PR:
I am confident things are OK this time. Unless I hear objections, I plan to integrate early next week.
Hints are certainly tested, but I think they are tested via "unit tests". Such kind of tests can detect missing functionality of own module, but cannot detect extra functionality of completely different module. Such an integration test would need |
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.
This is still broken. The layer registration of JavaErrorProvider
in java.lsp.server
(added in 275ade6) restores the broken behavior, that should have been fixed by 512ee110f7865130c16a85d930a2217fcc4545a2
. I.e. the invalid error markers are back again.
I also see MicronautSymbolErrorProvider
in the java lookup and while currently there does not seem to be a provider that reports the same problems in NetBeans IDE, it might quickly turn up and cause similar problems as the JavaErrorManager.
275ade6
to
cba6ef2
Compare
The best way to break things is to test everything and then make additional commit...
Fixed by registering the provider only for tests, as was my intention to begin with. Please accept my apology for useless round of review. |
I can register |
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 my main pain points are fixed. I have two concerns remaining about the implementation, that make sense to me to fix before integration.
ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/ErrorProviderBridge.java
Outdated
Show resolved
Hide resolved
computeHints(ErrorProvider.Kind.ERRORS, p, "lsp:errors"); | ||
computeHints(ErrorProvider.Kind.HINTS, p, "lsp:hints"); |
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.
Do the runs with ErrorProvider.Kind.ERRORS
and and ErrorProvider.Kind.HINTS
yield disjunct sets of error sets? If not, what is the result for the user?
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.
The Enso error provider is only computing ERRORS
and returns empty array for HINTS
request.
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 would expect disjoint sets to be provided, which are then automatically merged, and the joint result is presented to the used. If a provider returns the same diagnostics from both queries, it will be duplicated for the user, I think.
The main purpose of this split is to show errors to the user quickly, and then take the time needed to compute the warnings.
In an ideal case, |
9ba53da
to
993677e
Compare
Looks like there are no doubled Micronaut warnings. Things look OK: In such case I rather leave Micronaut support untouched for now. |
Unless there are objections, I will merge tomorrow. |
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 sane to me. My concerns were addressed. Thank you.
One final request: Please squash the commits into logical unittests. We don't gain anything from intermediate states of the, if they are logically squashed, in the future have a change to understand the big picture not just one random fix.
… resolved.getDocumentation() can be null
993677e
to
557c823
Compare
computeHints(ErrorProvider.Kind.ERRORS, p, "lsp:errors"); | ||
computeHints(ErrorProvider.Kind.HINTS, p, "lsp:hints"); |
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 would expect disjoint sets to be provided, which are then automatically merged, and the joint result is presented to the used. If a provider returns the same diagnostics from both queries, it will be duplicated for the user, I think.
The main purpose of this split is to show errors to the user quickly, and then take the time needed to compute the warnings.
Revert PR #7579 ("Using LSP's ErrorProvider & another attempt at CompletionCollector")
Continuation of
Let's use ErrorProvider when available and display its hints in NetBeans.
The above picture shows errors provided by Enso IGV Plugin rev. 1.40.554 in NetBeans as proposed by enso-org/enso#10553