Skip to content

Commit

Permalink
Merge pull request #7714 from dbalek/dbalek/lsp-diags-computation-fix
Browse files Browse the repository at this point in the history
LSP: Prevent Document instance to be garbage collected between errors and hints computation.
  • Loading branch information
dbalek authored Sep 2, 2024
2 parents 09d4ffb + f2997ce commit a0a9c28
Showing 1 changed file with 11 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import com.sun.source.util.TreePathScanner;
import com.sun.source.util.Trees;
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
import java.io.File;
import java.io.FileNotFoundException;
import java.net.URI;
import java.net.URL;
Expand All @@ -48,7 +47,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -93,7 +91,6 @@
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.CodeActionKind;
import org.eclipse.lsp4j.CodeActionKindCapabilities;
import org.eclipse.lsp4j.CodeActionParams;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.CodeLensParams;
Expand All @@ -106,7 +103,6 @@
import org.eclipse.lsp4j.CompletionParams;
import org.eclipse.lsp4j.ConfigurationItem;
import org.eclipse.lsp4j.ConfigurationParams;
import org.eclipse.lsp4j.CreateFile;
import org.eclipse.lsp4j.DefinitionParams;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
Expand Down Expand Up @@ -202,16 +198,12 @@
import org.netbeans.modules.java.editor.base.fold.JavaElementFoldVisitor.FoldCreator;
import org.netbeans.modules.java.editor.base.semantic.ColoringAttributes;
import org.netbeans.modules.java.editor.base.semantic.MarkOccurrencesHighlighterBase;
import org.netbeans.modules.java.editor.codegen.GeneratorUtils;
import org.netbeans.modules.java.editor.base.semantic.SemanticHighlighterBase;
import org.netbeans.modules.java.editor.base.semantic.SemanticHighlighterBase.ErrorDescriptionSetter;
import org.netbeans.modules.java.editor.options.MarkOccurencesSettings;
import org.netbeans.modules.java.editor.overridden.ComputeOverriding;
import org.netbeans.modules.java.editor.overridden.ElementDescription;
import org.netbeans.modules.java.hints.OrganizeImports;
import org.netbeans.modules.java.hints.introduce.IntroduceFixBase;
import org.netbeans.modules.java.hints.introduce.IntroduceHint;
import org.netbeans.modules.java.hints.introduce.IntroduceKind;
import org.netbeans.modules.java.lsp.server.LspServerState;
import org.netbeans.modules.java.lsp.server.Utils;
import org.netbeans.modules.java.lsp.server.debugging.utils.ErrorUtilities;
Expand Down Expand Up @@ -243,7 +235,6 @@
import org.netbeans.modules.java.lsp.server.ui.AbstractJavaPlatformProviderOverride;
import org.netbeans.modules.parsing.impl.SourceAccessor;
import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.editor.hints.Fix;
import org.netbeans.spi.lsp.CallHierarchyProvider;
import org.netbeans.spi.lsp.CodeLensProvider;
import org.netbeans.spi.lsp.ErrorProvider;
Expand All @@ -264,8 +255,6 @@
import org.openide.util.NbBundle;
import org.openide.util.Pair;
import org.openide.util.RequestProcessor;
import org.openide.util.Union2;
import org.openide.util.Utilities;
import org.openide.util.WeakSet;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup;
Expand Down Expand Up @@ -1003,7 +992,7 @@ public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActio

ArrayList<Diagnostic> diagnostics = new ArrayList<>(params.getContext().getDiagnostics());
if (diagnostics.isEmpty()) {
diagnostics.addAll(computeDiags(params.getTextDocument().getUri(), startOffset, ErrorProvider.Kind.HINTS, documentVersion(doc)));
diagnostics.addAll(computeDiags(params.getTextDocument().getUri(), startOffset, ErrorProvider.Kind.HINTS, documentVersion(doc), null));
}

Map<String, org.netbeans.api.lsp.Diagnostic> id2Errors = new HashMap<>();
Expand Down Expand Up @@ -1908,11 +1897,12 @@ private void runDiagnosticTasks(String uri, boolean force) {
return BACKGROUND_TASKS.create(() -> {
Document originalDoc = server.getOpenedDocuments().getDocument(uri);
long originalVersion = documentVersion(originalDoc);
List<Diagnostic> errorDiags = computeDiags(u, -1, ErrorProvider.Kind.ERRORS, originalVersion);
AtomicReference<Document> docHolder = new AtomicReference<>(originalDoc);
List<Diagnostic> errorDiags = computeDiags(u, -1, ErrorProvider.Kind.ERRORS, originalVersion, docHolder);
if (documentVersion(originalDoc) == originalVersion) {
publishDiagnostics(uri, errorDiags);
BACKGROUND_TASKS.create(() -> {
List<Diagnostic> hintDiags = computeDiags(u, -1, ErrorProvider.Kind.HINTS, originalVersion);
List<Diagnostic> hintDiags = computeDiags(u, -1, ErrorProvider.Kind.HINTS, originalVersion, docHolder);
Document doc = server.getOpenedDocuments().getDocument(uri);
if (documentVersion(doc) == originalVersion) {
publishDiagnostics(uri, hintDiags);
Expand All @@ -1930,12 +1920,13 @@ CompletableFuture<List<Diagnostic>> computeDiagnostics(String uri, EnumSet<Error
try {
Document originalDoc = server.getOpenedDocuments().getDocument(uri);
long originalVersion = documentVersion(originalDoc);
AtomicReference<Document> docHolder = new AtomicReference<>(originalDoc);
List<Diagnostic> result = Collections.emptyList();
if (types.contains(ErrorProvider.Kind.ERRORS)) {
result = computeDiags(uri, -1, ErrorProvider.Kind.ERRORS, originalVersion);
result = computeDiags(uri, -1, ErrorProvider.Kind.ERRORS, originalVersion, docHolder);
}
if (types.contains(ErrorProvider.Kind.HINTS)) {
result = computeDiags(uri, -1, ErrorProvider.Kind.HINTS, originalVersion);
result = computeDiags(uri, -1, ErrorProvider.Kind.HINTS, originalVersion, docHolder);
}
r.complete(result);
} catch (ThreadDeath td) {
Expand All @@ -1962,7 +1953,7 @@ CompletableFuture<List<Diagnostic>> computeDiagnostics(String uri, EnumSet<Error
* @param orgV version of the document. or -1 to obtain the current version.
* @return complete list of diagnostics for the file.
*/
private List<Diagnostic> computeDiags(String uri, int offset, ErrorProvider.Kind errorKind, long orgV) {
private List<Diagnostic> computeDiags(String uri, int offset, ErrorProvider.Kind errorKind, long orgV, AtomicReference<Document> docHolder) {
List<Diagnostic> result = new ArrayList<>();
FileObject file = fromURI(uri);
if (file == null) {
Expand All @@ -1977,6 +1968,9 @@ private List<Diagnostic> computeDiags(String uri, int offset, ErrorProvider.Kind
String keyPrefix = key(errorKind);
EditorCookie ec = file.getLookup().lookup(EditorCookie.class);
Document doc = ec.openDocument();
if (docHolder != null) {
docHolder.set(doc);
}
long originalVersion = orgV != -1 ? orgV : documentVersion(doc);
Map<String, org.netbeans.api.lsp.Diagnostic> id2Errors = new HashMap<>();
Collection<? extends ErrorProvider> errorProviders = MimeLookup.getLookup(DocumentUtilities.getMimeType(doc))
Expand Down

0 comments on commit a0a9c28

Please sign in to comment.