mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
while collecting completion variants, don't depend on global state containing CompletionProgressIndicator
This commit is contained in:
+13
-5
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -31,17 +32,20 @@ public final class CompletionParameters {
|
||||
@Nullable private final Editor myEditor;
|
||||
private final int myOffset;
|
||||
private final int myInvocationCount;
|
||||
private final CompletionProcess myProcess;
|
||||
|
||||
CompletionParameters(@NotNull final PsiElement position, @NotNull final PsiFile originalFile,
|
||||
@NotNull CompletionType completionType, int offset, final int invocationCount, @Nullable Editor editor) {
|
||||
@NotNull CompletionType completionType, int offset, int invocationCount, @Nullable Editor editor,
|
||||
@NotNull CompletionProcess process) {
|
||||
PsiUtilCore.ensureValid(position);
|
||||
assert position.getTextRange().containsOffset(offset) : position;
|
||||
myPosition = position;
|
||||
assert position.isValid();
|
||||
myOriginalFile = originalFile;
|
||||
myCompletionType = completionType;
|
||||
myOffset = offset;
|
||||
myInvocationCount = invocationCount;
|
||||
myEditor = editor;
|
||||
myProcess = process;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -51,12 +55,12 @@ public final class CompletionParameters {
|
||||
|
||||
@NotNull
|
||||
public CompletionParameters withType(@NotNull CompletionType type) {
|
||||
return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount, myEditor);
|
||||
return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount, myEditor, myProcess);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompletionParameters withInvocationCount(int newCount) {
|
||||
return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount, myEditor);
|
||||
return new CompletionParameters(myPosition, myOriginalFile, myCompletionType, myOffset, newCount, myEditor, myProcess);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -99,7 +103,7 @@ public final class CompletionParameters {
|
||||
|
||||
@NotNull
|
||||
public CompletionParameters withPosition(@NotNull PsiElement element, int offset) {
|
||||
return new CompletionParameters(element, myOriginalFile, myCompletionType, offset, myInvocationCount, myEditor);
|
||||
return new CompletionParameters(element, myOriginalFile, myCompletionType, offset, myInvocationCount, myEditor, myProcess);
|
||||
}
|
||||
|
||||
public boolean isExtendedCompletion() {
|
||||
@@ -124,4 +128,8 @@ public final class CompletionParameters {
|
||||
return myEditor != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompletionProcess getProcess() {
|
||||
return myProcess;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-26
@@ -75,7 +75,7 @@ public class CodeCompletionHandlerBase {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CodeCompletionHandlerBase");
|
||||
private static final Key<Boolean> CARET_PROCESSED = Key.create("CodeCompletionHandlerBase.caretProcessed");
|
||||
|
||||
@NotNull private final CompletionType myCompletionType;
|
||||
@NotNull final CompletionType completionType;
|
||||
final boolean invokedExplicitly;
|
||||
final boolean synchronous;
|
||||
final boolean autopopup;
|
||||
@@ -97,7 +97,7 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
|
||||
public CodeCompletionHandlerBase(@NotNull CompletionType completionType, boolean invokedExplicitly, boolean autopopup, boolean synchronous) {
|
||||
myCompletionType = completionType;
|
||||
this.completionType = completionType;
|
||||
this.invokedExplicitly = invokedExplicitly;
|
||||
this.autopopup = autopopup;
|
||||
this.synchronous = synchronous;
|
||||
@@ -151,7 +151,7 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
|
||||
CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
|
||||
boolean repeated = phase.indicator != null && phase.indicator.isRepeatedInvocation(myCompletionType, editor);
|
||||
boolean repeated = phase.indicator != null && phase.indicator.isRepeatedInvocation(completionType, editor);
|
||||
/*
|
||||
if (repeated && isAutocompleteCommonPrefixOnInvocation() && phase.fillInCommonPrefix()) {
|
||||
return;
|
||||
@@ -168,7 +168,7 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass(), CompletionPhase.CommittingDocuments.class);
|
||||
|
||||
if (invocationCount > 1 && myCompletionType == CompletionType.BASIC) {
|
||||
if (invocationCount > 1 && completionType == CompletionType.BASIC) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.SECOND_BASIC_COMPLETION);
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ public class CodeCompletionHandlerBase {
|
||||
|
||||
private CompletionInitializationContext runContributorsBeforeCompletion(Editor editor, PsiFile psiFile, int invocationCount, @NotNull Caret caret) {
|
||||
final Ref<CompletionContributor> current = Ref.create(null);
|
||||
CompletionInitializationContext context = new CompletionInitializationContext(editor, caret, psiFile, myCompletionType, invocationCount) {
|
||||
CompletionInitializationContext context = new CompletionInitializationContext(editor, caret, psiFile, completionType, invocationCount) {
|
||||
CompletionContributor dummyIdentifierChanger;
|
||||
|
||||
@Override
|
||||
@@ -290,7 +290,6 @@ public class CodeCompletionHandlerBase {
|
||||
|
||||
CompletionContext context = createCompletionContext(initContext.getFile(), hostCopyOffsets);
|
||||
LookupImpl lookup = obtainLookup(editor, initContext.getProject());
|
||||
CompletionParameters parameters = createCompletionParameters(invocationCount, context, editor);
|
||||
|
||||
CompletionPhase phase = CompletionServiceImpl.getCompletionPhase();
|
||||
if (phase instanceof CompletionPhase.CommittingDocuments) {
|
||||
@@ -302,9 +301,9 @@ public class CodeCompletionHandlerBase {
|
||||
CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass());
|
||||
}
|
||||
|
||||
final CompletionProgressIndicator indicator = new CompletionProgressIndicator(editor, initContext.getCaret(),
|
||||
parameters, this,
|
||||
initContext.getOffsetMap(), hostOffsets, hasModifiers, lookup);
|
||||
CompletionProgressIndicator indicator = new CompletionProgressIndicator(editor, initContext.getCaret(),
|
||||
invocationCount, context, this,
|
||||
initContext.getOffsetMap(), hostOffsets, hasModifiers, lookup);
|
||||
Disposer.register(indicator, hostCopyOffsets.getOffsets());
|
||||
Disposer.register(indicator, context.getOffsetMap());
|
||||
Disposer.register(indicator, translator);
|
||||
@@ -343,23 +342,6 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
}
|
||||
|
||||
private CompletionParameters createCompletionParameters(int invocationCount,
|
||||
final CompletionContext newContext, Editor editor) {
|
||||
final int offset = newContext.getStartOffset();
|
||||
final PsiFile fileCopy = newContext.file;
|
||||
PsiFile originalFile = fileCopy.getOriginalFile();
|
||||
final PsiElement insertedElement = findCompletionPositionLeaf(newContext, offset, fileCopy, originalFile);
|
||||
insertedElement.putUserData(CompletionContext.COMPLETION_CONTEXT_KEY, newContext);
|
||||
return new CompletionParameters(insertedElement, originalFile, myCompletionType, offset, invocationCount, editor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiElement findCompletionPositionLeaf(CompletionContext newContext, int offset, PsiFile fileCopy, PsiFile originalFile) {
|
||||
final PsiElement insertedElement = newContext.file.findElementAt(offset);
|
||||
CompletionAssertions.assertCompletionPositionPsiConsistent(newContext, offset, fileCopy, originalFile, insertedElement);
|
||||
return insertedElement;
|
||||
}
|
||||
|
||||
private AutoCompletionDecision shouldAutoComplete(final CompletionProgressIndicator indicator, List<LookupElement> items) {
|
||||
if (!invokedExplicitly) {
|
||||
return AutoCompletionDecision.SHOW_LOOKUP;
|
||||
|
||||
+22
-14
@@ -56,10 +56,7 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ReferenceRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.ui.GuiUtils;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.util.Alarm;
|
||||
@@ -136,26 +133,21 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
private final int myStartCaret;
|
||||
private CompletionThreadingBase myStrategy;
|
||||
|
||||
public CompletionProgressIndicator(final Editor editor,
|
||||
@NotNull Caret caret,
|
||||
CompletionParameters parameters,
|
||||
CodeCompletionHandlerBase handler,
|
||||
final OffsetMap offsetMap,
|
||||
OffsetsInFile hostOffsets,
|
||||
boolean hasModifiers,
|
||||
LookupImpl lookup) {
|
||||
CompletionProgressIndicator(Editor editor, @NotNull Caret caret, int invocationCount, CompletionContext context,
|
||||
CodeCompletionHandlerBase handler, OffsetMap offsetMap, OffsetsInFile hostOffsets,
|
||||
boolean hasModifiers, LookupImpl lookup) {
|
||||
myEditor = editor;
|
||||
myCaret = caret;
|
||||
myParameters = parameters;
|
||||
myHandler = handler;
|
||||
myOffsetMap = offsetMap;
|
||||
myHostOffsets = hostOffsets;
|
||||
myLookup = lookup;
|
||||
myStartCaret = myEditor.getCaretModel().getOffset();
|
||||
myParameters = createCompletionParameters(invocationCount, context, editor);
|
||||
|
||||
myAdvertiserChanges.offer(() -> myLookup.getAdvertiser().clearAdvertisements());
|
||||
|
||||
myArranger = new CompletionLookupArranger(parameters, this);
|
||||
myArranger = new CompletionLookupArranger(myParameters, this);
|
||||
myLookup.setArranger(myArranger);
|
||||
|
||||
myLookup.addLookupListener(myLookupListener);
|
||||
@@ -178,6 +170,22 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
}
|
||||
}
|
||||
|
||||
private CompletionParameters createCompletionParameters(int invocationCount, CompletionContext context, Editor editor) {
|
||||
int offset = context.getStartOffset();
|
||||
PsiFile fileCopy = context.file;
|
||||
PsiFile originalFile = fileCopy.getOriginalFile();
|
||||
PsiElement insertedElement = findCompletionPositionLeaf(context, offset, fileCopy, originalFile);
|
||||
insertedElement.putUserData(CompletionContext.COMPLETION_CONTEXT_KEY, context);
|
||||
return new CompletionParameters(insertedElement, originalFile, myHandler.completionType, offset, invocationCount, editor, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiElement findCompletionPositionLeaf(CompletionContext context, int offset, PsiFile fileCopy, PsiFile originalFile) {
|
||||
PsiElement insertedElement = context.file.findElementAt(offset);
|
||||
CompletionAssertions.assertCompletionPositionPsiConsistent(context, offset, fileCopy, originalFile, insertedElement);
|
||||
return insertedElement;
|
||||
}
|
||||
|
||||
public void itemSelected(@Nullable LookupElement lookupItem, char completionChar) {
|
||||
boolean dispose = lookupItem == null;
|
||||
finishCompletionProcess(dispose);
|
||||
|
||||
+6
-8
@@ -15,15 +15,15 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class CompletionThreadingBase implements CompletionThreading {
|
||||
protected final static ThreadLocal<Boolean> ourIsInBatchUpdate = ThreadLocal.withInitial(() -> Boolean.FALSE);
|
||||
|
||||
public static void withBatchUpdate(Runnable runnable) {
|
||||
if (ourIsInBatchUpdate.get().booleanValue()) {
|
||||
public static void withBatchUpdate(Runnable runnable, CompletionProcess process) {
|
||||
if (ourIsInBatchUpdate.get().booleanValue() || !(process instanceof CompletionProgressIndicator)) {
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
@@ -32,10 +32,8 @@ public abstract class CompletionThreadingBase implements CompletionThreading {
|
||||
ourIsInBatchUpdate.set(Boolean.TRUE);
|
||||
runnable.run();
|
||||
ProgressManager.checkCanceled();
|
||||
final CompletionProgressIndicator currentIndicator = CompletionServiceImpl.getCompletionService().getCurrentCompletion();
|
||||
if(currentIndicator == null) throw new ProcessCanceledException();
|
||||
CompletionThreadingBase threading = currentIndicator.getCompletionThreading();
|
||||
assert threading != null;
|
||||
CompletionProgressIndicator currentIndicator = (CompletionProgressIndicator)process;
|
||||
CompletionThreadingBase threading = Objects.requireNonNull(currentIndicator.getCompletionThreading());
|
||||
threading.flushBatchResult(currentIndicator);
|
||||
} finally {
|
||||
ourIsInBatchUpdate.set(Boolean.FALSE);
|
||||
|
||||
+10
-14
@@ -110,13 +110,9 @@ public final class CompletionServiceImpl extends CompletionService {
|
||||
@Nullable
|
||||
private final CompletionResultSetImpl myOriginal;
|
||||
|
||||
|
||||
public CompletionResultSetImpl(final Consumer<CompletionResult> consumer, final int lengthOfTextBeforePosition,
|
||||
final PrefixMatcher prefixMatcher,
|
||||
CompletionContributor contributor,
|
||||
CompletionParameters parameters,
|
||||
@NotNull CompletionSorterImpl sorter,
|
||||
@Nullable CompletionResultSetImpl original) {
|
||||
CompletionResultSetImpl(Consumer<CompletionResult> consumer, int lengthOfTextBeforePosition, PrefixMatcher prefixMatcher,
|
||||
CompletionContributor contributor, CompletionParameters parameters,
|
||||
@NotNull CompletionSorterImpl sorter, @Nullable CompletionResultSetImpl original) {
|
||||
super(prefixMatcher, consumer, contributor);
|
||||
myLengthOfTextBeforePosition = lengthOfTextBeforePosition;
|
||||
myParameters = parameters;
|
||||
@@ -126,7 +122,7 @@ public final class CompletionServiceImpl extends CompletionService {
|
||||
|
||||
@Override
|
||||
public void addAllElements(@NotNull Iterable<? extends LookupElement> elements) {
|
||||
CompletionThreadingBase.withBatchUpdate(() -> super.addAllElements(elements));
|
||||
CompletionThreadingBase.withBatchUpdate(() -> super.addAllElements(elements), myParameters.getProcess());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,17 +187,17 @@ public final class CompletionServiceImpl extends CompletionService {
|
||||
|
||||
@Override
|
||||
public void restartCompletionOnPrefixChange(ElementPattern<String> prefixCondition) {
|
||||
final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion();
|
||||
if (indicator != null) {
|
||||
indicator.addWatchedPrefix(myLengthOfTextBeforePosition - getPrefixMatcher().getPrefix().length(), prefixCondition);
|
||||
CompletionProcess process = myParameters.getProcess();
|
||||
if (process instanceof CompletionProgressIndicator) {
|
||||
((CompletionProgressIndicator)process).addWatchedPrefix(myLengthOfTextBeforePosition - getPrefixMatcher().getPrefix().length(), prefixCondition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restartCompletionWhenNothingMatches() {
|
||||
final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion();
|
||||
if (indicator != null) {
|
||||
indicator.getLookup().setStartCompletionWhenNothingMatches(true);
|
||||
CompletionProcess process = myParameters.getProcess();
|
||||
if (process instanceof CompletionProgressIndicator) {
|
||||
((CompletionProgressIndicator)process).getLookup().setStartCompletionWhenNothingMatches(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user