Skip to content

Commit 18df5bb

Browse files
committed
fix: Abort completion computations when encountering a BadLocationException
1 parent b1253f9 commit 18df5bb

3 files changed

Lines changed: 31 additions & 27 deletions

File tree

org.eclipse.lsp4e/src/org/eclipse/lsp4e/LSPEclipseUtils.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,18 +245,15 @@ public static CompletionParams toCompletionParams(URI fileUri, int offset, IDocu
245245
Position start = toPosition(offset, document);
246246
final var param = new CompletionParams();
247247
if (document.getLength() > 0) {
248-
try {
249-
int positionCharacterOffset = offset > 0 ? offset-1 : offset;
250-
String positionCharacter = document.get(positionCharacterOffset, 1);
251-
if (Chars.contains(completionTriggerChars, positionCharacter.charAt(0))) {
252-
param.setContext(new CompletionContext(CompletionTriggerKind.TriggerCharacter, positionCharacter));
253-
} else {
254-
// According to LSP 3.17 specification: the triggerCharacter in CompletionContext is undefined if
255-
// triggerKind != CompletionTriggerKind.TriggerCharacter
256-
param.setContext(new CompletionContext(CompletionTriggerKind.Invoked));
257-
}
258-
} catch (BadLocationException e) {
259-
LanguageServerPlugin.logError(e);
248+
int positionCharacterOffset = offset > 0 ? offset - 1 : offset;
249+
String positionCharacter = document.get(positionCharacterOffset, 1);
250+
if (Chars.contains(completionTriggerChars, positionCharacter.charAt(0))) {
251+
param.setContext(new CompletionContext(CompletionTriggerKind.TriggerCharacter, positionCharacter));
252+
} else {
253+
// According to LSP 3.17 specification: the triggerCharacter in
254+
// CompletionContext is undefined if
255+
// triggerKind != CompletionTriggerKind.TriggerCharacter
256+
param.setContext(new CompletionContext(CompletionTriggerKind.Invoked));
260257
}
261258
}
262259
param.setPosition(start);

org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/completion/LSCompletionProposal.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,9 @@ public int getRankScore() {
234234
rankScore = CompletionProposalTools.getScoreOfFilterMatch(getDocumentFilter(),
235235
getFilterString());
236236
} catch (BadLocationException e) {
237-
LanguageServerPlugin.logError(e);
237+
// Document was changed while we computed completion proposals, which made the
238+
// offset invalid. We can stop any further computation as the result will be
239+
// discarded anyway.
238240
rankScore = -1;
239241
}
240242
this.rankScore = rankScore;
@@ -257,7 +259,9 @@ public int getRankCategory() {
257259
rankCategory = CompletionProposalTools.getCategoryOfFilterMatch(getDocumentFilter(),
258260
getFilterString());
259261
} catch (BadLocationException e) {
260-
LanguageServerPlugin.logError(e);
262+
// Document was changed while we computed completion proposals, which made the
263+
// offset invalid. We can stop any further computation as the result will be
264+
// discarded anyway.
261265
rankCategory = CompletionProposalTools.CATEGORY_NO_MATCH;
262266
}
263267
this.rankCategory = rankCategory;
@@ -442,27 +446,25 @@ private void updateCompletionItem(@Nullable CompletionItem resolvedItem) {
442446

443447
@Override
444448
public int getPrefixCompletionStart(IDocument document, int completionOffset) {
445-
Either<TextEdit, InsertReplaceEdit> textEdit = item.getTextEdit();
446-
if (textEdit != null) {
447-
try {
449+
try {
450+
Either<TextEdit, InsertReplaceEdit> textEdit = item.getTextEdit();
451+
if (textEdit != null) {
448452
return LSPEclipseUtils.toOffset(getTextEditRange().getStart(), document);
449-
} catch (BadLocationException e) {
450-
LanguageServerPlugin.logError(e);
451453
}
452-
}
453-
final String insertText = getInsertText();
454-
final int insertTextLength = insertText.length();
455-
try {
456-
String subDoc = document.get(
457-
Math.max(0, completionOffset - insertTextLength),
454+
455+
final String insertText = getInsertText();
456+
final int insertTextLength = insertText.length();
457+
String subDoc = document.get(Math.max(0, completionOffset - insertTextLength),
458458
Math.min(insertTextLength, completionOffset));
459459
for (int i = 0; i < insertTextLength && i < completionOffset; i++) {
460460
if (insertText.regionMatches(true, 0, subDoc, i, subDoc.length() - i)) {
461461
return completionOffset - subDoc.substring(i).length();
462462
}
463463
}
464464
} catch (BadLocationException e) {
465-
LanguageServerPlugin.logError(e);
465+
// Document was changed while we computed completion proposals, which made the
466+
// offset invalid. We can stop any further computation as the result will be
467+
// discarded anyway.
466468
}
467469
return completionOffset;
468470
}

org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/completion/LSContentAssistProcessor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,12 @@ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int
127127
try {
128128
param = LSPEclipseUtils.toCompletionParams(uri, offset, document, this.completionTriggerChars);
129129
} catch (BadLocationException e) {
130-
LanguageServerPlugin.logError(e);
130+
// Document was changed while we computed completion proposals, which made the
131+
// offset invalid. We can stop any further computation as the result will be
132+
// discarded anyway.
133+
134+
// TODO don't even create error proposal and just return NO_COMPLETION_PROPOSALS,
135+
// because the result will be discarded anyway?
131136
this.errorMessage = createErrorMessage(offset, e);
132137
return createErrorProposal(offset, e);
133138
}

0 commit comments

Comments
 (0)