Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael Istria2019-07-03 13:45:50 +0000
committerJeff Johnston2020-01-06 19:09:56 +0000
commitc80a0ed5358fd6caf3f92e129276abba94329c19 (patch)
tree6b88e5525863017d9fe1635cefbc516d1a9f9e91
parent192cfdece48b10c4d7193d82af0d9ba703e39502 (diff)
downloadeclipse.jdt.ui-c80a0ed5358fd6caf3f92e129276abba94329c19.tar.gz
eclipse.jdt.ui-c80a0ed5358fd6caf3f92e129276abba94329c19.tar.xz
eclipse.jdt.ui-c80a0ed5358fd6caf3f92e129276abba94329c19.zip
Bug 531061 - Asynchronous/non-blocking Java completion
Change-Id: I122f94304b3be477fd26df180cbdbcb0098508d8 Signed-off-by: Mickael Istria <mistria@redhat.com>
-rw-r--r--org.eclipse.jdt.text.tests/plugin.xml12
-rw-r--r--org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CheckUIThreadReactivityThread.java53
-rw-r--r--org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistAndThreadsTest.java144
-rw-r--r--org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/LongCompletionProposalComputer.java62
-rw-r--r--org.eclipse.jdt.ui/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.ui/pom.xml2
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java106
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java2
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties3
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java5
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java82
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java13
-rw-r--r--org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java4
13 files changed, 412 insertions, 78 deletions
diff --git a/org.eclipse.jdt.text.tests/plugin.xml b/org.eclipse.jdt.text.tests/plugin.xml
index 8931f92480..49a78dccb8 100644
--- a/org.eclipse.jdt.text.tests/plugin.xml
+++ b/org.eclipse.jdt.text.tests/plugin.xml
@@ -36,5 +36,15 @@
type="java.lang.Object">
</propertyTester>
</extension>
-
+ <extension
+ point="org.eclipse.jdt.ui.javaCompletionProposalComputer"
+ id="LongCompletionProposalComputer">
+ <javaCompletionProposalComputer
+ class="org.eclipse.jdt.text.tests.contentassist.LongCompletionProposalComputer"
+ categoryId="org.eclipse.jdt.ui.javaAllProposalCategory"
+ requiresUIThread="false">
+ <partition type="__dftl_partition_content_type"/>
+ <partition type="__java_string"/>
+ </javaCompletionProposalComputer>
+ </extension>
</plugin>
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CheckUIThreadReactivityThread.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CheckUIThreadReactivityThread.java
new file mode 100644
index 0000000000..cc14e27238
--- /dev/null
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/CheckUIThreadReactivityThread.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Red Hat Inc., and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jdt.text.tests.contentassist;
+
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This thread polls the display every 50milliseconds with a null UI operation
+ * request and computes how long it take for display to process the request.
+ * The time to handle request is time when display is busy doing other work, so
+ * it's actually a UI Freeze.
+ *
+ * This could be moved to SWT or other common place where we need to check
+ * UI Freezes and reused form there,
+ */
+public class CheckUIThreadReactivityThread extends Thread {
+
+ long pauseBetweenEachPing = 50;
+ final private Display fDisplay;
+
+ private long maxDuration;
+
+ public CheckUIThreadReactivityThread(Display display) {
+ fDisplay= display;
+ }
+
+ @Override
+ public void run() {
+ while (!isInterrupted()) {
+ long duration = System.currentTimeMillis();
+ fDisplay.syncExec(() -> {}); // do nothing, but in UI Thread
+ duration = System.currentTimeMillis() - duration;
+ maxDuration = Math.max(duration, maxDuration);
+ try {
+ sleep(pauseBetweenEachPing);
+ } catch (InterruptedException e) {
+ // nothing
+ }
+ }
+ }
+
+ public long getMaxDuration() {
+ return maxDuration;
+ }
+}
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistAndThreadsTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistAndThreadsTest.java
new file mode 100644
index 0000000000..2fc1067f73
--- /dev/null
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistAndThreadsTest.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Red Hat Inc., and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jdt.text.tests.contentassist;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+import org.junit.After;
+import org.junit.Test;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Widget;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jdt.ui.PreferenceConstants;
+import org.eclipse.jdt.ui.text.IJavaPartitions;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProcessor;
+
+public class ContentAssistAndThreadsTest extends AbstractCompletionTest {
+
+ @After
+ public void resetPreference() {
+ JavaPlugin.getDefault().getPreferenceStore().setToDefault(PreferenceConstants.CODEASSIST_NONUITHREAD_COMPUTATION);
+ }
+
+ @Test
+ public void testComputeCompletionInNonUIThread() throws Exception {
+ IJavaProject fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ JavaProjectHelper.addRTJar(fJProject1);
+ IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+ IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null);
+ ICompilationUnit cu= pack1.createCompilationUnit("Blah.java", "", true, new NullProgressMonitor());
+ JavaEditor part= (JavaEditor) JavaUI.openInEditor(cu);
+ ContentAssistant assistant= new ContentAssistant();
+ assistant.setDocumentPartitioning(IJavaPartitions.JAVA_PARTITIONING);
+ JavaCompletionProcessor javaProcessor= new JavaCompletionProcessor(part, assistant, getContentType());
+ AtomicReference<Throwable> exception = new AtomicReference<>();
+ List<IStatus> errors = new ArrayList<>();
+ JavaPlugin.getDefault().getLog().addLogListener((status, plugin) -> {
+ if (status.getSeverity() >= IStatus.WARNING) {
+ errors.add(status);
+ }
+ });
+ Thread thread = new Thread(() -> {
+ try {
+ javaProcessor.computeCompletionProposals(part.getViewer(), 0);
+ // a popup can be shown and block the thread in case of error
+ } catch (Exception e) {
+ exception.set(e);
+ }
+ });
+ thread.start();
+ thread.join();
+ if (exception.get() != null) {
+ exception.get().printStackTrace();
+ }
+ assertNull(exception.get());
+ assertEquals(Collections.emptyList(), errors);
+ }
+
+ @Test
+ public void testLongNonUIThreadContentAssistDoesntFreezeUI() throws Exception {
+ JavaPlugin.getDefault().getPreferenceStore().setValue(PreferenceConstants.CODEASSIST_NONUITHREAD_COMPUTATION, true);
+ IJavaProject fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
+ JavaProjectHelper.addRTJar(fJProject1);
+ IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+ IPackageFragment pack1= sourceFolder.createPackageFragment("test1", false, null);
+ ICompilationUnit cu= pack1.createCompilationUnit("Blah.java", LongCompletionProposalComputer.CONTENT_TRIGGER_STRING, true, new NullProgressMonitor());
+ JavaEditor part= (JavaEditor) JavaUI.openInEditor(cu);
+ final Set<Shell> beforeShells = Arrays.stream(part.getSite().getShell().getDisplay().getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
+ Display display= part.getViewer().getTextWidget().getDisplay();
+ ContentAssistAction action = (ContentAssistAction) part.getAction(ITextEditorActionConstants.CONTENT_ASSIST);
+ action.update();
+ CheckUIThreadReactivityThread thread = new CheckUIThreadReactivityThread(display);
+ thread.start();
+ display.asyncExec(() -> action.run()); // mustn't be synchronous or CheckUIThreadReactivityTest can miss it.
+ try {
+ assertTrue("Missing completion proposal", new org.eclipse.jdt.text.tests.performance.DisplayHelper() {
+ @Override
+ protected boolean condition() {
+ Set<Shell> newShells = Arrays.stream(part.getSite().getShell().getDisplay().getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
+ newShells.removeAll(beforeShells);
+ if (!newShells.isEmpty()) {
+ Table completionTable = findCompletionSelectionControl(newShells.iterator().next());
+ return Arrays.stream(completionTable.getItems()).map(TableItem::getText).anyMatch(LongCompletionProposalComputer.CONTENT_TRIGGER_STRING::equals);
+ }
+ return false;
+ }
+ }.waitForCondition(display, 3000));
+ } finally {
+ thread.interrupt();
+ }
+ assertTrue("UI was frozen for " + thread.getMaxDuration(), thread.getMaxDuration() < 1000);
+ }
+
+ private Table findCompletionSelectionControl(Widget control) {
+ if (control instanceof Table) {
+ return (Table)control;
+ } else if (control instanceof Composite) {
+ for (Widget child : ((Composite)control).getChildren()) {
+ Table res = findCompletionSelectionControl(child);
+ if (res != null) {
+ return res;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/LongCompletionProposalComputer.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/LongCompletionProposalComputer.java
new file mode 100644
index 0000000000..1dacabe983
--- /dev/null
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/LongCompletionProposalComputer.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Red Hat Inc., and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jdt.text.tests.contentassist;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+
+import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;
+import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+
+public class LongCompletionProposalComputer implements IJavaCompletionProposalComputer {
+
+ public static final String CONTENT_TRIGGER_STRING = "longCompletion";
+
+ @Override
+ public void sessionStarted() {
+ }
+
+ @Override
+ public List<ICompletionProposal> computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) {
+ if (context.getDocument().get().contains(CONTENT_TRIGGER_STRING)) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ JavaPlugin.log(e);
+ }
+ return Collections.singletonList(new CompletionProposal(CONTENT_TRIGGER_STRING, 0, 0, 0, null, CONTENT_TRIGGER_STRING, null, null));
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<IContextInformation> computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String getErrorMessage() {
+ return null;
+ }
+
+ @Override
+ public void sessionEnded() {
+ }
+
+}
diff --git a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
index a20ac02cfb..80123f900f 100644
--- a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.jdt.ui
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.ui; singleton:=true
-Bundle-Version: 3.20.100.qualifier
+Bundle-Version: 3.21.0.qualifier
Bundle-Activator: org.eclipse.jdt.internal.ui.JavaPlugin
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
diff --git a/org.eclipse.jdt.ui/pom.xml b/org.eclipse.jdt.ui/pom.xml
index 7d0bf4d14f..609886acbb 100644
--- a/org.eclipse.jdt.ui/pom.xml
+++ b/org.eclipse.jdt.ui/pom.xml
@@ -18,7 +18,7 @@
</parent>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.ui</artifactId>
- <version>3.20.100-SNAPSHOT</version>
+ <version>3.21.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
<code.ignoredWarnings>-warn:-deprecation,unavoidableGenericProblems</code.ignoredWarnings>
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java
index 8f753a99fa..8909196293 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java
@@ -20,6 +20,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
@@ -53,9 +54,7 @@ import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
-import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
@@ -92,12 +91,14 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
private static final Key PREF_EXCLUDED_CATEGORIES= getJDTUIKey(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES);
private static final Key PREF_CATEGORY_ORDER= getJDTUIKey(PreferenceConstants.CODEASSIST_CATEGORY_ORDER);
private static final Key PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC= getJDTCoreKey(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC);
+ private static final Key PREF_CODEASSIST_NONUITHREAD_COMPUTATION = getJDTUIKey(PreferenceConstants.CODEASSIST_NONUITHREAD_COMPUTATION);
private static Key[] getAllKeys() {
return new Key[] {
PREF_EXCLUDED_CATEGORIES,
PREF_CATEGORY_ORDER,
- PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC
+ PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC,
+ PREF_CODEASSIST_NONUITHREAD_COMPUTATION
};
}
@@ -108,8 +109,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
*/
@Override
public Image getColumnImage(Object element, int columnIndex) {
- if (columnIndex == 0)
+ if (columnIndex == 0) {
return ((ModelElement) element).getImage();
+ }
return null;
}
@@ -145,8 +147,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
*/
@Override
public Image getColumnImage(Object element, int columnIndex) {
- if (columnIndex == 0)
+ if (columnIndex == 0) {
return ((ModelElement) element).getImage();
+ }
return null;
}
@@ -220,8 +223,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
StringBuilder buf= new StringBuilder();
for (ModelElement item : fElements) {
boolean included= changed == item ? isInDefaultCategory : item.isInDefaultCategory();
- if (!included)
+ if (!included) {
buf.append(item.getId() + SEPARATOR);
+ }
}
String newValue= buf.toString();
@@ -257,8 +261,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
private int readOrderPreference(CompletionProposalCategory cat) {
for (String sortOrderId : getTokens(getValue(PREF_CATEGORY_ORDER), SEPARATOR)) {
String[] idAndRank= getTokens(sortOrderId, COLON);
- if (idAndRank[0].equals(cat.getId()))
+ if (idAndRank[0].equals(cat.getId())) {
return Integer.parseInt(idAndRank[1]);
+ }
}
return LIMIT - 1;
}
@@ -304,16 +309,18 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
return fPreferenceModel.readInclusionPreference(fCategory);
}
void setInDefaultCategory(boolean included) {
- if (included != isInDefaultCategory())
+ if (included != isInDefaultCategory()) {
fPreferenceModel.writeInclusionPreference(this, included);
+ }
}
String getId() {
return fCategory.getId();
}
int getRank() {
int rank= getInternalRank();
- if (rank > PreferenceModel.LIMIT)
+ if (rank > PreferenceModel.LIMIT) {
return rank - PreferenceModel.LIMIT;
+ }
return rank;
}
void moveUp() {
@@ -330,8 +337,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
}
void setSeparateCommand(boolean separate) {
- if (separate != isSeparateCommand())
+ if (separate != isSeparateCommand()) {
fPreferenceModel.writeOrderPreference(this, separate);
+ }
}
void update() {
@@ -387,6 +395,8 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
createFiller(composite, columns);
createParameterTimeoutControl(composite, columns);
+ createFiller(composite, columns);
+ createNonUIThreadControl(composite, columns);
updateControls();
if (fModel.elements.size() > 0) {
@@ -400,13 +410,30 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
return scrolled;
}
+ private void createNonUIThreadControl(Composite composite, int columns) {
+ PixelConverter pixelConverter= new PixelConverter(composite);
+ String str= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_nonUIThread;
+ Button checkbox = addCheckBox(composite, str, PREF_CODEASSIST_NONUITHREAD_COMPUTATION, new String[] { Boolean.TRUE.toString(), Boolean.FALSE.toString() }, pixelConverter.convertWidthInCharsToPixels(7));
+ checkbox.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, columns, 1));
+ CompletionProposalComputerRegistry registry= CompletionProposalComputerRegistry.getDefault();
+ if (registry.computingCompletionRequiresUIThread()) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(Messages.format(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_nonUIThread_computersRequiringUIThread, registry.getComputersRequiringUIThreadNames().map(name -> "* " + name).collect(Collectors.joining("\n")))); //$NON-NLS-1$ //$NON-NLS-2$
+ GridData layoutData= new GridData(GridData.FILL, GridData.FILL, true, false, columns, 1);
+ layoutData.horizontalIndent = 30;
+ label.setLayoutData(layoutData);
+ label.setEnabled(false);
+ }
+ }
+
private void createDefaultLabel(Composite composite, int h_span) {
final ICommandService commandSvc= PlatformUI.getWorkbench().getAdapter(ICommandService.class);
final Command command= commandSvc.getCommand(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
ParameterizedCommand pCmd= new ParameterizedCommand(command, null);
String key= getKeyboardShortcut(pCmd);
- if (key == null)
+ if (key == null) {
key= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_no_shortcut;
+ }
PixelConverter pixelConverter= new PixelConverter(composite);
int width= pixelConverter.convertWidthInCharsToPixels(40);
@@ -440,13 +467,10 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
keyColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_default_table_keybinding_column_title);
keyColumn.setResizable(false);
- fDefaultViewer.addCheckStateListener(new ICheckStateListener() {
- @Override
- public void checkStateChanged(CheckStateChangedEvent event) {
- boolean checked= event.getChecked();
- ModelElement element= (ModelElement) event.getElement();
- element.setInDefaultCategory(checked);
- }
+ fDefaultViewer.addCheckStateListener(event -> {
+ boolean checked= event.getChecked();
+ ModelElement element= (ModelElement) event.getElement();
+ element.setInDefaultCategory(checked);
});
fDefaultViewer.setContentProvider(ArrayContentProvider.getInstance());
@@ -460,9 +484,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
final int HEADER_MARGIN= 20;
int minNameWidth= computeWidth(table, nameColumn.getText()) + HEADER_MARGIN;
int minKeyWidth= computeWidth(table, keyColumn.getText()) + HEADER_MARGIN;
- for (int i= 0; i < fModel.elements.size(); i++) {
- minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(fModel.elements.get(i), 0)) + ICON_AND_CHECKBOX_WITH);
- minKeyWidth= Math.max(minKeyWidth, computeWidth(table, labelProvider.getColumnText(fModel.elements.get(i), 1)));
+ for (ModelElement element : fModel.elements) {
+ minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(element, 0)) + ICON_AND_CHECKBOX_WITH);
+ minKeyWidth= Math.max(minKeyWidth, computeWidth(table, labelProvider.getColumnText(element, 1)));
}
nameColumn.setWidth(minNameWidth);
@@ -530,19 +554,16 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
final int ICON_AND_CHECKBOX_WITH= 50;
final int HEADER_MARGIN= 20;
int minNameWidth= computeWidth(table, nameColumn.getText()) + HEADER_MARGIN;
- for (int i= 0; i < fModel.elements.size(); i++) {
- minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(fModel.elements.get(i), 0)) + ICON_AND_CHECKBOX_WITH);
+ for (ModelElement element : fModel.elements) {
+ minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(element, 0)) + ICON_AND_CHECKBOX_WITH);
}
nameColumn.setWidth(minNameWidth);
- fSeparateViewer.addCheckStateListener(new ICheckStateListener() {
- @Override
- public void checkStateChanged(CheckStateChangedEvent event) {
- boolean checked= event.getChecked();
- ModelElement element= (ModelElement) event.getElement();
- element.setSeparateCommand(checked);
- }
+ fSeparateViewer.addCheckStateListener(event -> {
+ boolean checked= event.getChecked();
+ ModelElement element= (ModelElement) event.getElement();
+ element.setSeparateCommand(checked);
});
table.addSelectionListener(new SelectionAdapter() {
@@ -651,10 +672,12 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
List<ModelElement> separateChecked= new ArrayList<>(size);
for (ModelElement element : fModel.elements) {
- if (element.isInDefaultCategory())
+ if (element.isInDefaultCategory()) {
defaultChecked.add(element);
- if (element.isSeparateCommand())
+ }
+ if (element.isSeparateCommand()) {
separateChecked.add(element);
+ }
}
fDefaultViewer.setCheckedElements(defaultChecked.toArray(new Object[defaultChecked.size()]));
@@ -680,9 +703,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
protected void validateSettings(Key changedKey, String oldValue, String newValue) {
if (changedKey == PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC) {
final StatusInfo status= new StatusInfo();
- if (newValue.length() == 0)
+ if (newValue.length() == 0) {
status.setError(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_emptyInput);
- else {
+ } else {
try {
int number= Integer.parseInt(newValue);
int min= 0;
@@ -716,8 +739,7 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
*/
@Override
public void dispose() {
- for (Iterator<Image> it= fImages.values().iterator(); it.hasNext();) {
- Image image= it.next();
+ for (Image image : fImages.values()) {
image.dispose();
}
@@ -725,8 +747,9 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
}
private int computeWidth(Control control, String name) {
- if (name == null)
+ if (name == null) {
return 0;
+ }
GC gc= new GC(control);
try {
gc.setFont(JFaceResources.getDialogFont());
@@ -760,21 +783,24 @@ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlo
fgLocalBindingManager.setBindings(bindingService.getBindings());
try {
Scheme activeScheme= bindingService.getActiveScheme();
- if (activeScheme != null)
+ if (activeScheme != null) {
fgLocalBindingManager.setActiveScheme(activeScheme);
+ }
} catch (NotDefinedException e) {
JavaPlugin.log(e);
}
TriggerSequence[] bindings= fgLocalBindingManager.getActiveBindingsDisregardingContextFor(command);
- if (bindings.length > 0)
+ if (bindings.length > 0) {
return bindings[0].format();
+ }
return null;
}
private Image getImage(ImageDescriptor imgDesc) {
- if (imgDesc == null)
+ if (imgDesc == null) {
return null;
+ }
Image img= fImages.get(imgDesc);
if (img == null) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java
index 20ea4a6a84..2dc67c88d5 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java
@@ -65,6 +65,8 @@ public final class PreferencesMessages extends NLS {
public static String CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_emptyInput;
public static String CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_invalidInput;
public static String CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_invalidRange;
+ public static String CodeAssistAdvancedConfigurationBlock_nonUIThread;
+ public static String CodeAssistAdvancedConfigurationBlock_nonUIThread_computersRequiringUIThread;
public static String ImportOrganizePreferencePage_title;
public static String ImportOrganizeConfigurationBlock_order_label;
public static String ImportOrganizeConfigurationBlock_other_static;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties
index 65522c1769..261b5953c8 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties
@@ -950,6 +950,9 @@ CodeAssistAdvancedConfigurationBlock_separate_table_category_column_title=Separa
CodeAssistAdvancedConfigurationBlock_Up=&Up
CodeAssistAdvancedConfigurationBlock_Down=D&own
CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout=&Timeout for fetching a parameter name from attached Javadoc (ms):
+CodeAssistAdvancedConfigurationBlock_nonUIThread=Do not block &UI Thread while computing completion proposals (does not affect open editors)
+CodeAssistAdvancedConfigurationBlock_nonUIThread_computersRequiringUIThread=\u26A0\uFE0F This setting will be ignored because the following contributions require UI Thread:\n\
+{0}
CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_emptyInput=Empty input.
CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_invalidInput=''{0}'' is not a valid input.
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java
index 33dd482a47..a892d355b2 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
+import java.util.stream.Stream;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
@@ -526,4 +527,8 @@ public final class CompletionProposalComputerRegistry {
public boolean computingCompletionRequiresUIThread() {
return fDescriptors.stream().anyMatch(CompletionProposalComputerDescriptor::requiresUIThread);
}
+
+ public Stream<String> getComputersRequiringUIThreadNames() {
+ return fDescriptors.stream().filter(CompletionProposalComputerDescriptor::requiresUIThread).map(CompletionProposalComputerDescriptor::getName);
+ }
}
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java
index c07448d1ae..7199d2f09f 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java
@@ -32,6 +32,7 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
@@ -110,8 +111,9 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
*/
@Override
public void assistSessionStarted(ContentAssistEvent event) {
- if (event.processor != ContentAssistProcessor.this)
+ if (event.processor != ContentAssistProcessor.this) {
return;
+ }
fIterationGesture= getIterationGesture();
KeySequence binding= getIterationBinding();
@@ -145,7 +147,7 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
/**
* Returns the categories that need to be notified when a session starts and ends.
- *
+ *
* @return the current categories
* @since 3.8.1
*/
@@ -155,14 +157,16 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
// Currently enabled categories for this session
if (fCategoryIteration != null) {
Iterator<List<CompletionProposalCategory>> it= fCategoryIteration.iterator();
- while (it.hasNext())
+ while (it.hasNext()) {
currentCategories.addAll(it.next());
+ }
}
// Backwards compatibility: notify all categories which have no enablement expression
for (CompletionProposalCategory cat : fCategories) {
- if (cat.getEnablementExpression() == null)
+ if (cat.getEnablementExpression() == null) {
currentCategories.add(cat);
+ }
}
return currentCategories;
@@ -173,8 +177,9 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
*/
@Override
public void assistSessionEnded(ContentAssistEvent event) {
- if (event.processor != ContentAssistProcessor.this)
+ if (event.processor != ContentAssistProcessor.this) {
return;
+ }
for (CompletionProposalCategory cat : getCategoriesToNotify()) {
cat.sessionEnded();
@@ -222,14 +227,7 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
*/
private static final String PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY= "EmptyDefaultAssistCategory"; //$NON-NLS-1$
- private static final Comparator<CompletionProposalCategory> ORDER_COMPARATOR= new Comparator<CompletionProposalCategory>() {
-
- @Override
- public int compare(CompletionProposalCategory d1, CompletionProposalCategory d2) {
- return d1.getSortOrder() - d2.getSortOrder();
- }
-
- };
+ private static final Comparator<CompletionProposalCategory> ORDER_COMPARATOR= (d1, d2) -> d1.getSortOrder() - d2.getSortOrder();
private final List<CompletionProposalCategory> fCategories;
private final String fPartition;
@@ -256,7 +254,7 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
* Flag indicating whether any completion engine associated with this processor requests
* resorting of its proposals after filtering is triggered. Filtering is, e.g., triggered when a
* user continues typing with an open completion window.
- *
+ *
* @since 3.8
*/
private boolean fNeedsSortingAfterFiltering;
@@ -292,10 +290,11 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
long collect= JavaPlugin.DEBUG_RESULT_COLLECTOR ? System.currentTimeMillis() : 0;
monitor.subTask(JavaTextMessages.ContentAssistProcessor_sorting_proposals);
- if (fNeedsSortingAfterFiltering)
+ if (fNeedsSortingAfterFiltering) {
setContentAssistSorter();
- else
+ } else {
proposals= sortProposals(proposals, monitor, context);
+ }
fNumberOfComputedResults= proposals.size();
long filter= JavaPlugin.DEBUG_RESULT_COLLECTOR ? System.currentTimeMillis() : 0;
@@ -334,11 +333,13 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
List<ICompletionProposal> computed= cat.computeCompletionProposals(context, fPartition, new SubProgressMonitor(monitor, 1));
proposals.addAll(computed);
needsSortingAfterFiltering= needsSortingAfterFiltering || (cat.isSortingAfterFilteringNeeded() && !computed.isEmpty());
- if (fErrorMessage == null)
+ if (fErrorMessage == null) {
fErrorMessage= cat.getErrorMessage();
+ }
}
- if (fNeedsSortingAfterFiltering && !needsSortingAfterFiltering)
+ if (fNeedsSortingAfterFiltering && !needsSortingAfterFiltering) {
fAssistant.setSorter(null);
+ }
fNeedsSortingAfterFiltering= needsSortingAfterFiltering;
return proposals;
}
@@ -388,8 +389,9 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
for (CompletionProposalCategory cat : providers) {
List<IContextInformation> computed= cat.computeContextInformation(context, fPartition, new SubProgressMonitor(monitor, 1));
proposals.addAll(computed);
- if (fErrorMessage == null)
+ if (fErrorMessage == null) {
fErrorMessage= cat.getErrorMessage();
+ }
}
return proposals;
@@ -442,10 +444,12 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
*/
@Override
public String getErrorMessage() {
- if (fErrorMessage != null)
+ if (fErrorMessage != null) {
return fErrorMessage;
- if (fNumberOfComputedResults > 0)
+ }
+ if (fNumberOfComputedResults > 0) {
return null;
+ }
return JavaUIMessages.JavaEditor_codeassist_noCompletions;
}
@@ -483,11 +487,17 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
}
private List<CompletionProposalCategory> getCategories() {
- if (fCategoryIteration == null)
+ if (fCategoryIteration == null) {
return fCategories;
+ }
int iteration= fRepetition % fCategoryIteration.size();
- fAssistant.setStatusMessage(createIterationMessage());
+ String iterationMessage = createIterationMessage();
+ if (Display.getCurrent() != null) {
+ fAssistant.setStatusMessage(iterationMessage);
+ } else {
+ Display.getDefault().asyncExec(() -> fAssistant.setStatusMessage(iterationMessage));
+ }
fAssistant.setEmptyMessage(createEmptyMessage());
fRepetition++;
@@ -515,9 +525,10 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
List<CompletionProposalCategory> included= getDefaultCategoriesUnchecked();
if (fComputerRegistry.hasUninstalledComputers(fPartition, included)) {
- if (informUserAboutEmptyDefaultCategory())
+ if (informUserAboutEmptyDefaultCategory()) {
// preferences were restored - recompute the default categories
included= getDefaultCategoriesUnchecked();
+ }
fComputerRegistry.resetUnistalledComputers();
}
@@ -527,15 +538,16 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
private List<CompletionProposalCategory> getDefaultCategoriesUnchecked() {
List<CompletionProposalCategory> included= new ArrayList<>();
for (CompletionProposalCategory category : fCategories) {
- if (checkDefaultEnablement(category))
+ if (checkDefaultEnablement(category)) {
included.add(category);
+ }
}
return included;
}
/**
* Determine whether the category is enabled by default.
- *
+ *
* @param category the category to check
* @return <code>true</code> if this category is enabled by default, <code>false</code>
* otherwise
@@ -620,8 +632,9 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
store.setToDefault(PreferenceConstants.CODEASSIST_CATEGORY_ORDER);
store.setToDefault(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES);
}
- if (settingsId == returnValue)
+ if (settingsId == returnValue) {
PreferencesUtil.createPreferenceDialogOn(shell, "org.eclipse.jdt.ui.preferences.CodeAssistPreferenceAdvanced", null, null).open(); //$NON-NLS-1$
+ }
fComputerRegistry.reload();
return true;
}
@@ -632,16 +645,17 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
private List<CompletionProposalCategory> getSeparateCategories() {
ArrayList<CompletionProposalCategory> sorted= new ArrayList<>();
for (CompletionProposalCategory category : fCategories) {
- if (checkSeparateEnablement(category))
+ if (checkSeparateEnablement(category)) {
sorted.add(category);
+ }
}
Collections.sort(sorted, ORDER_COMPARATOR);
return sorted;
}
-
+
/**
* Determine whether the category is enabled for separate use.
- *
+ *
* @param category the category to check
* @return <code>true</code> if this category is enabled for separate use, <code>false</code>
* otherwise
@@ -661,8 +675,9 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
private String getCategoryLabel(int repetition) {
int iteration= repetition % fCategoryIteration.size();
- if (iteration == 0)
+ if (iteration == 0) {
return JavaTextMessages.ContentAssistProcessor_defaultProposalCategory;
+ }
return toString(fCategoryIteration.get(iteration).get(0));
}
@@ -680,14 +695,15 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
private KeySequence getIterationBinding() {
final IBindingService bindingSvc= PlatformUI.getWorkbench().getAdapter(IBindingService.class);
TriggerSequence binding= bindingSvc.getBestActiveBindingFor(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
- if (binding instanceof KeySequence)
+ if (binding instanceof KeySequence) {
return (KeySequence) binding;
+ }
return null;
}
/**
* Sets the current proposal sorter into the content assistant.
- *
+ *
* @since 3.8
* @see ProposalSorterRegistry#getCurrentSorter() the sorter used if <code>true</code>
*/
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java
index c786b78460..5b0857b5a3 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java
@@ -2956,6 +2956,18 @@ public class PreferenceConstants {
public final static String FORMATTER_COMMENT_FORMATHTML= "comment_format_html"; //$NON-NLS-1$
/**
+ * A named preference that controls whether completion processors should be called from the non-UI thread,
+ * when they declare ability to work from non-UI Thread.
+ * <p>Completion processors can declare whether they
+ * require UI Thread or not in their extension description, see {@link org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerDescriptor#requiresUIThread()}.</p>
+ * <p>Value is of type <code>Boolean</code></p>
+ *
+ * @since 3.21
+ */
+ public static final String CODEASSIST_NONUITHREAD_COMPUTATION= "content_assist_noUIThread_computation"; //$NON-NLS-1$
+
+
+ /**
* A named preference that controls if the Java code assist gets auto activated.
* <p>
* Value is of type <code>Boolean</code>.
@@ -4087,6 +4099,7 @@ public class PreferenceConstants {
store.setDefault(PreferenceConstants.CODEASSIST_AUTOACTIVATION_DELAY, 0);
store.setDefault(PreferenceConstants.CODEASSIST_AUTOINSERT, true);
store.setDefault(PreferenceConstants.CODEASSIST_DISABLE_COMPLETION_PROPOSAL_TRIGGER_CHARS, false);
+ store.setDefault(PreferenceConstants.CODEASSIST_NONUITHREAD_COMPUTATION, false);
store.setDefault(PreferenceConstants.PREF_MIN_CHAIN_LENGTH, 2);
store.setDefault(PreferenceConstants.PREF_MAX_CHAIN_LENGTH, 4);
store.setDefault(PreferenceConstants.PREF_MAX_CHAINS, 20);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java
index 20ef33bec7..a6154dd513 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java
@@ -86,6 +86,7 @@ import org.eclipse.jdt.internal.ui.text.JavaReconciler;
import org.eclipse.jdt.internal.ui.text.PreferencesAdapter;
import org.eclipse.jdt.internal.ui.text.SingleTokenJavaScanner;
import org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionAssistant;
+import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistry;
import org.eclipse.jdt.internal.ui.text.java.ContentAssistProcessor;
import org.eclipse.jdt.internal.ui.text.java.JavaAutoIndentStrategy;
import org.eclipse.jdt.internal.ui.text.java.JavaCodeScanner;
@@ -434,8 +435,7 @@ public class JavaSourceViewerConfiguration extends TextSourceViewerConfiguration
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
if (getEditor() != null) {
-
- ContentAssistant assistant= new ContentAssistant();
+ ContentAssistant assistant= new ContentAssistant(fPreferenceStore.getBoolean(PreferenceConstants.CODEASSIST_NONUITHREAD_COMPUTATION) && !CompletionProposalComputerRegistry.getDefault().computingCompletionRequiresUIThread());
assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
assistant.setRestoreCompletionProposalSize(getSettings("completion_proposal_size")); //$NON-NLS-1$

Back to the top