diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 15d6833ab4e7..880aa5179371 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -303,10 +303,8 @@ public class CodeCompletionHandlerBase { CompletionServiceImpl.assertPhase(CompletionPhase.NoCompletion.getClass()); } - final Semaphore freezeSemaphore = new Semaphore(); - freezeSemaphore.down(); final CompletionProgressIndicator indicator = new CompletionProgressIndicator(editor, initContext.getCaret(), - parameters, this, freezeSemaphore, + parameters, this, initContext.getOffsetMap(), hostOffsets, hasModifiers, lookup); Disposer.register(indicator, hostCopyOffsets.getOffsets()); Disposer.register(indicator, context.getOffsetMap()); @@ -320,20 +318,18 @@ public class CodeCompletionHandlerBase { return; } - if (freezeSemaphore.waitFor(ourAutoInsertItemTimeout)) { - if (!indicator.isRunning() && !indicator.isCanceled()) { // the completion is really finished, now we may auto-insert or show lookup - try { - indicator.getLookup().refreshUi(true, false); - } - catch (Exception e) { - CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); - LOG.error(e); - return; - } - - completionFinished(indicator, hasModifiers); + if (indicator.blockingWaitForFinish(ourAutoInsertItemTimeout)) { + try { + indicator.getLookup().refreshUi(true, false); + } + catch (Exception e) { + CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion); + LOG.error(e); return; } + + completionFinished(indicator, hasModifiers); + return; } CompletionServiceImpl.setCompletionPhase(new CompletionPhase.BgCalculation(indicator)); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 63903e022e72..3a42980f2d4b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -107,7 +107,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myQueue.setMergingTimeSpan(ourShowPopupGroupingTime); } }; - private final Semaphore myFreezeSemaphore; + private final Semaphore myFreezeSemaphore = new Semaphore(1); + private final Semaphore myFinishSemaphore = new Semaphore(1); private final OffsetMap myOffsetMap; private final Set>> myRestartingPrefixConditions = ContainerUtil.newConcurrentSet(); private final LookupAdapter myLookupListener = new LookupAdapter() { @@ -139,7 +140,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement @NotNull Caret caret, CompletionParameters parameters, CodeCompletionHandlerBase handler, - Semaphore freezeSemaphore, final OffsetMap offsetMap, OffsetsInFile hostOffsets, boolean hasModifiers, @@ -148,7 +148,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement myCaret = caret; myParameters = parameters; myHandler = handler; - myFreezeSemaphore = freezeSemaphore; myOffsetMap = offsetMap; myHostOffsets = hostOffsets; myLookup = lookup; @@ -514,12 +513,25 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement StatisticsUpdate.cancelLastCompletionStatisticsUpdate(); } + boolean blockingWaitForFinish(int timeout) { + if (ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup) { + assert myFinishSemaphore.waitFor(100 * 1000) : "Too long completion"; + return true; + } + if (myFreezeSemaphore.waitFor(timeout)) { + // the completion is really finished, now we may auto-insert or show lookup + return !isRunning() && !isCanceled(); + } + return false; + } + @Override public void stop() { super.stop(); myQueue.cancelAllUpdates(); myFreezeSemaphore.up(); + myFinishSemaphore.up(); GuiUtils.invokeLaterIfNeeded(() -> { final CompletionPhase phase = CompletionServiceImpl.getCompletionPhase(); @@ -773,7 +785,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement void startCompletion(final CompletionInitializationContext initContext) { - boolean sync = ApplicationManager.getApplication().isUnitTestMode() && !CompletionAutoPopupHandler.ourTestingAutopopup; + boolean sync = ApplicationManager.getApplication().isWriteAccessAllowed(); myStrategy = sync ? new SyncCompletion() : new AsyncCompletion(); myStrategy.startThread(ProgressWrapper.wrap(this), this::scheduleAdvertising); final WeighingDelegate weigher = myStrategy.delegateWeighing(this);