Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java')
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java170
1 files changed, 112 insertions, 58 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java
index b1a02d8a193..26f260d4ac4 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java
@@ -21,6 +21,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
import org.eclipse.osgi.util.NLS;
@@ -148,79 +149,132 @@ class AsyncCompletionProposalPopup extends CompletionProposalPopup {
fFilterOffset= fInvocationOffset;
fLastCompletionOffset= fFilterOffset;
// start invocation of processors as Futures, and make them populate the proposals upon completion
- List<ICompletionProposal> computedProposals = Collections.synchronizedList(new ArrayList<>());
fFutures= buildCompletionFuturesOrJobs(fInvocationOffset);
- List<CompletableFuture<Void>> populateFutures = new ArrayList<>(fFutures.size());
- for (CompletableFuture<List<ICompletionProposal>> future : fFutures) {
- populateFutures.add(future.thenAccept(proposals ->
- computedProposals.addAll(proposals)
- ));
- }
+ runFutures(fInvocationOffset, null, true, autoActivated, true);
+ } else {
+ fLastCompletionOffset= fFilterOffset;
+ handleRepeatedInvocation();
+ }
- long requestBeginningTimestamp = System.currentTimeMillis();
- long stillRemainingThreeshold = MAX_WAIT_IN_MS;
- for (CompletableFuture<?> future : populateFutures) {
- try {
- future.get(stillRemainingThreeshold, TimeUnit.MILLISECONDS);
- } catch (TimeoutException | ExecutionException | InterruptedException ex) {
- // future failed or took more time than we want to wait
- }
- stillRemainingThreeshold = MAX_WAIT_IN_MS - (System.currentTimeMillis() - requestBeginningTimestamp);
- if (stillRemainingThreeshold < 0) {
- // we already spent too much time (more than MAX_WAIT_IN_MS), stop waiting.
- break;
- }
+ return getErrorMessage();
+ }
+
+ @Override
+ void handleRepeatedInvocation() {
+ cancelFutures();
+ fFutures= buildCompletionFuturesOrJobs(fInvocationOffset);
+ runFutures(fInvocationOffset, null, false, false, false);
+ }
+
+ private List<ICompletionProposal> runFutures(int offset, Consumer<List<ICompletionProposal>> callback, boolean createSelector, boolean autoActivated, boolean autoInsert) {
+ List<ICompletionProposal> computedProposals= Collections.synchronizedList(new ArrayList<>());
+ List<CompletableFuture<Void>> populateFutures= new ArrayList<>(fFutures.size());
+ for (CompletableFuture<List<ICompletionProposal>> future : fFutures) {
+ populateFutures.add(future.thenAccept(proposals -> computedProposals.addAll(proposals)));
+ }
+
+ long requestBeginningTimestamp= System.currentTimeMillis();
+ long stillRemainingThreeshold= MAX_WAIT_IN_MS;
+ for (CompletableFuture<?> future : populateFutures) {
+ try {
+ future.get(stillRemainingThreeshold, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException | ExecutionException | InterruptedException ex) {
+ // future failed or took more time than we want to wait
}
- fComputedProposals = computedProposals;
- if (stillRemainingThreeshold > 0) { // everything ready in time, go synchronous
- int count= computedProposals.size();
- if (count == 0 && hideWhenNoProposals(autoActivated))
- return null;
-
- if (count == 1 && !autoActivated && canAutoInsert(computedProposals.get(0))) {
- insertProposal(computedProposals.get(0), (char) 0, 0, fInvocationOffset);
- hide();
- } else {
+ stillRemainingThreeshold= MAX_WAIT_IN_MS - (System.currentTimeMillis() - requestBeginningTimestamp);
+ if (stillRemainingThreeshold < 0) {
+ // we already spent too much time (more than MAX_WAIT_IN_MS), stop waiting.
+ break;
+ }
+ }
+ fComputedProposals= computedProposals;
+ if (stillRemainingThreeshold > 0) { // everything ready in time, go synchronous
+ int count= computedProposals.size();
+ if (count == 0 && hideWhenNoProposals(autoActivated))
+ return computedProposals;
+
+ if (autoInsert && count == 1 && !autoActivated && canAutoInsert(computedProposals.get(0))) {
+ insertProposal(computedProposals.get(0), (char) 0, 0, offset);
+ hide();
+ } else {
+ if (createSelector) {
createProposalSelector();
+ }
+ if (callback != null) {
+ callback.accept(computedProposals);
+ } else {
setProposals(computedProposals, false);
displayProposals();
}
- } else { // processors took too much time, go asynchronous
+ }
+ } else { // processors took too much time, go asynchronous
+ if (createSelector) {
createProposalSelector();
- ComputingProposal computingProposal= new ComputingProposal(fInvocationOffset, fFutures.size());
- computedProposals.add(0, computingProposal);
- fComputedProposals = computedProposals;
- setProposals(fComputedProposals, false);
- Set<CompletableFuture<Void>> remaining = Collections.synchronizedSet(new HashSet<>(populateFutures));
- for (CompletableFuture<Void> populateFuture : populateFutures) {
- populateFuture.thenRun(() -> {
- remaining.removeIf(CompletableFuture::isDone);
- computingProposal.setRemaining(remaining.size());
- if (remaining.isEmpty()) {
- computedProposals.remove(computingProposal);
- }
- List<ICompletionProposal> newProposals = new ArrayList<>(computedProposals);
- fComputedProposals = newProposals;
- Display.getDefault().asyncExec(() -> {
- if (!autoActivated && remaining.isEmpty() && newProposals.size() == 1 && canAutoInsert(newProposals.get(0))) {
- if (Helper.okToUse(fProposalShell)) {
- insertProposal(newProposals.get(0), (char) 0, 0, fInvocationOffset);
- hide();
- }
- return;
+ }
+ ComputingProposal computingProposal= new ComputingProposal(offset, fFutures.size());
+ computedProposals.add(0, computingProposal);
+ setProposals(fComputedProposals, false);
+ Set<CompletableFuture<Void>> remaining= Collections.synchronizedSet(new HashSet<>(populateFutures));
+ for (CompletableFuture<Void> populateFuture : populateFutures) {
+ populateFuture.thenRun(() -> {
+ remaining.removeIf(CompletableFuture::isDone);
+ computingProposal.setRemaining(remaining.size());
+ if (remaining.isEmpty()) {
+ computedProposals.remove(computingProposal);
+ }
+ List<ICompletionProposal> newProposals= new ArrayList<>(computedProposals);
+ fComputedProposals= newProposals;
+ Display.getDefault().asyncExec(() -> {
+ if (autoInsert && !autoActivated && remaining.isEmpty() && newProposals.size() == 1 && canAutoInsert(newProposals.get(0))) {
+ if (Helper.okToUse(fProposalShell)) {
+ insertProposal(newProposals.get(0), (char) 0, 0, offset);
+ hide();
}
+ return;
+ }
+ if (remaining.isEmpty() && callback != null) {
+ callback.accept(newProposals);
+ } else {
setProposals(newProposals, false);
displayProposals();
- });
+ }
});
- }
- displayProposals();
+ });
}
- } else {
- fLastCompletionOffset= fFilterOffset;
- handleRepeatedInvocation();
+ displayProposals();
+ }
+ return computedProposals;
+ }
+
+ @Override
+ public String incrementalComplete() {
+ cancelFutures();
+ if (Helper.okToUse(fProposalShell) && fFilteredProposals != null) {
+ return super.incrementalComplete();
}
+ final Control control= fContentAssistSubjectControlAdapter.getControl();
+
+ if (fKeyListener == null)
+ fKeyListener= new ProposalSelectionListener();
+
+ if (!Helper.okToUse(fProposalShell) && !control.isDisposed())
+ fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener);
+ fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+ fFilterOffset= fInvocationOffset;
+ fLastCompletionOffset= fFilterOffset;
+
+ fFutures= buildCompletionFuturesOrJobs(fInvocationOffset);
+ fFilteredProposals= runFutures(fInvocationOffset, (List<ICompletionProposal> proposals) -> {
+ ensureDocumentListenerInstalled();
+ if (proposals.size() > 0 && completeCommonPrefix()) {
+ hide();
+ } else {
+ fFilteredProposals= proposals;
+ setProposals(proposals, false);
+ displayProposals();
+ }
+ }, true, false, true);
return getErrorMessage();
}

Back to the top