Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 117154 Details for
Bug 251156
[content assist] Asynchronous code completion [with patch]
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch (Version #3, fixes 1.4 incompatibility)
background_completion_patch.txt (text/plain), 88.74 KB, created by
Zorzella Mising name
on 2008-11-05 18:09:02 EST
(
hide
)
Description:
Patch (Version #3, fixes 1.4 incompatibility)
Filename:
MIME Type:
Creator:
Zorzella Mising name
Created:
2008-11-05 18:09:02 EST
Size:
88.74 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.ui >Index: ui/org/eclipse/jdt/internal/ui/text/java/ProposalSorterHandle.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ProposalSorterHandle.java,v >retrieving revision 1.10 >diff -u -r1.10 ProposalSorterHandle.java >--- ui/org/eclipse/jdt/internal/ui/text/java/ProposalSorterHandle.java 11 Sep 2008 11:59:38 -0000 1.10 >+++ ui/org/eclipse/jdt/internal/ui/text/java/ProposalSorterHandle.java 20 Oct 2008 23:16:13 -0000 >@@ -141,7 +141,7 @@ > * @throws InvalidRegistryObjectException if the extension is not valid any longer (e.g. due to > * plug-in unloading) > */ >- private synchronized AbstractProposalSorter getSorter() throws CoreException, InvalidRegistryObjectException { >+ synchronized AbstractProposalSorter getSorter() throws CoreException, InvalidRegistryObjectException { > if (fSorter == null && (fActivate || isPluginLoaded())) > fSorter= createSorter(); > return fSorter; >Index: ui/org/eclipse/jdt/internal/ui/text/java/HippieProposalComputer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/HippieProposalComputer.java,v >retrieving revision 1.5 >diff -u -r1.5 HippieProposalComputer.java >--- ui/org/eclipse/jdt/internal/ui/text/java/HippieProposalComputer.java 11 Sep 2008 11:59:37 -0000 1.5 >+++ ui/org/eclipse/jdt/internal/ui/text/java/HippieProposalComputer.java 20 Oct 2008 23:16:13 -0000 >@@ -15,6 +15,8 @@ > > import org.eclipse.core.runtime.IProgressMonitor; > >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.ui.texteditor.HippieProposalProcessor; > > import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; >@@ -39,14 +41,16 @@ > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, >+ Point selectedRange) { > return Arrays.asList(fProcessor.computeCompletionProposals(context.getViewer(), context.getInvocationOffset())); > } > > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeContextInformation(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, >+ Point selectedRange) { > return Arrays.asList(fProcessor.computeContextInformation(context.getViewer(), context.getInvocationOffset())); > } > >Index: ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProcessor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProcessor.java,v >retrieving revision 1.80 >diff -u -r1.80 JavaCompletionProcessor.java >--- ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProcessor.java 11 Sep 2008 11:59:38 -0000 1.80 >+++ ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProcessor.java 20 Oct 2008 23:16:13 -0000 >@@ -10,12 +10,17 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.text.java; > >+import java.util.Comparator; > import java.util.Hashtable; > import java.util.List; > >+import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.InvalidRegistryObjectException; > >-import org.eclipse.jface.text.ITextViewer; >+import org.eclipse.swt.graphics.Point; >+ >+import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.contentassist.ContentAssistant; > import org.eclipse.jface.text.contentassist.IContextInformationValidator; > >@@ -80,6 +85,16 @@ > return fValidator; > } > >+ public Comparator getComparator() { >+ try { >+ return ProposalSorterRegistry.getDefault().getCurrentSorter().getSorter(); >+ } catch (InvalidRegistryObjectException e) { >+ throw new RuntimeException(e); >+ } catch (CoreException e) { >+ throw new RuntimeException(e); >+ } >+ } >+ > /* > * @see org.eclipse.jdt.internal.ui.text.java.ContentAssistProcessor#filterAndSort(java.util.List, org.eclipse.core.runtime.IProgressMonitor) > */ >@@ -91,7 +106,7 @@ > /* > * @see org.eclipse.jdt.internal.ui.text.java.ContentAssistProcessor#createContext(org.eclipse.jface.text.ITextViewer, int) > */ >- protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset) { >- return new JavaContentAssistInvocationContext(viewer, offset, fEditor); >+ protected ContentAssistInvocationContext createContext(IDocument document, int offset, Point selectedRange) { >+ return new JavaContentAssistInvocationContext(document, offset, selectedRange, fEditor); > } > } >Index: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java,v >retrieving revision 1.20 >diff -u -r1.20 CompletionProposalComputerRegistry.java >--- ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java 13 Oct 2008 15:05:29 -0000 1.20 >+++ ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java 20 Oct 2008 23:16:13 -0000 >@@ -28,6 +28,7 @@ > import org.eclipse.swt.layout.GridData; > 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.core.runtime.CoreException; >@@ -428,7 +429,7 @@ > */ > void informUser(CompletionProposalComputerDescriptor descriptor, IStatus status) { > JavaPlugin.log(status); >- String title= JavaTextMessages.CompletionProposalComputerRegistry_error_dialog_title; >+ final String title= JavaTextMessages.CompletionProposalComputerRegistry_error_dialog_title; > CompletionProposalCategory category= descriptor.getCategory(); > IContributor culprit= descriptor.getContributor(); > Set affectedPlugins= getAffectedContributors(category, culprit); >@@ -440,24 +441,31 @@ > else > avoidHint= Messages.format(JavaTextMessages.CompletionProposalComputerRegistry_messageAvoidanceHintWithWarning, new Object[] {culpritName, category.getDisplayName(), toString(affectedPlugins)}); > >- String message= status.getMessage(); >+ final String message= status.getMessage(); >+ // We run this in an asyncExec, as we are not guaranteed to be running in >+ // the UI thread > // inlined from MessageDialog.openError >- MessageDialog dialog = new MessageDialog(JavaPlugin.getActiveWorkbenchShell(), title, null /* default image */, message, MessageDialog.ERROR, new String[] { IDialogConstants.OK_LABEL }, 0) { >- protected Control createCustomArea(Composite parent) { >- Link link= new Link(parent, SWT.NONE); >- link.setText(avoidHint); >- link.addSelectionListener(new SelectionAdapter() { >- public void widgetSelected(SelectionEvent e) { >- PreferencesUtil.createPreferenceDialogOn(getShell(), "org.eclipse.jdt.ui.preferences.CodeAssistPreferenceAdvanced", null, null).open(); //$NON-NLS-1$ >- } >- }); >- GridData gridData= new GridData(SWT.FILL, SWT.BEGINNING, true, false); >- gridData.widthHint= this.getMinimumMessageWidth(); >- link.setLayoutData(gridData); >- return link; >- } >- }; >- dialog.open(); >+ Display.getDefault().asyncExec(new Runnable() { >+ >+ public void run() { >+ MessageDialog dialog = new MessageDialog(JavaPlugin.getActiveWorkbenchShell(), title, null /* default image */, message, MessageDialog.ERROR, new String[] { IDialogConstants.OK_LABEL }, 0) { >+ protected Control createCustomArea(Composite parent) { >+ Link link= new Link(parent, SWT.NONE); >+ link.setText(avoidHint); >+ link.addSelectionListener(new SelectionAdapter() { >+ public void widgetSelected(SelectionEvent e) { >+ PreferencesUtil.createPreferenceDialogOn(getShell(), "org.eclipse.jdt.ui.preferences.CodeAssistPreferenceAdvanced", null, null).open(); //$NON-NLS-1$ >+ } >+ }); >+ GridData gridData= new GridData(SWT.FILL, SWT.BEGINNING, true, false); >+ gridData.widthHint= this.getMinimumMessageWidth(); >+ link.setLayoutData(gridData); >+ return link; >+ } >+ }; >+ dialog.open(); >+ } >+ }); > } > > /** >Index: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerDescriptor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerDescriptor.java,v >retrieving revision 1.17 >diff -u -r1.17 CompletionProposalComputerDescriptor.java >--- ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerDescriptor.java 11 Sep 2008 11:59:37 -0000 1.17 >+++ ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerDescriptor.java 20 Oct 2008 23:16:13 -0000 >@@ -30,6 +30,8 @@ > import org.eclipse.core.runtime.Platform; > import org.eclipse.core.runtime.Status; > >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.jface.text.IDocument; > > import org.eclipse.jdt.internal.corext.util.Messages; >@@ -298,10 +300,11 @@ > * > * @param context the invocation context passed on to the extension > * @param monitor the progress monitor passed on to the extension >+ * @param selectedRange TODO(doogle): COMMENT > * @return the list of computed completion proposals (element type: > * {@link org.eclipse.jface.text.contentassist.ICompletionProposal}) > */ >- public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > if (!isEnabled()) > return Collections.EMPTY_LIST; > >@@ -313,7 +316,7 @@ > > try { > PerformanceStats stats= startMeter(context, computer); >- List proposals= computer.computeCompletionProposals(context, monitor); >+ List proposals= computer.computeCompletionProposals(context, monitor, selectedRange); > stopMeter(stats, COMPUTE_COMPLETION_PROPOSALS); > > if (proposals != null) { >@@ -346,10 +349,11 @@ > * > * @param context the invocation context passed on to the extension > * @param monitor the progress monitor passed on to the extension >+ * @param selectedRange TODO(doogle): COMMENT > * @return the list of computed context information objects (element type: > * {@link org.eclipse.jface.text.contentassist.IContextInformation}) > */ >- public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > if (!isEnabled()) > return Collections.EMPTY_LIST; > >@@ -360,7 +364,7 @@ > return Collections.EMPTY_LIST; > > PerformanceStats stats= startMeter(context, computer); >- List proposals= computer.computeContextInformation(context, monitor); >+ List proposals= computer.computeContextInformation(context, monitor, selectedRange); > stopMeter(stats, COMPUTE_CONTEXT_INFORMATION); > > if (proposals != null) { >Index: ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProposalComputer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProposalComputer.java,v >retrieving revision 1.27 >diff -u -r1.27 JavaCompletionProposalComputer.java >--- ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProposalComputer.java 13 Oct 2008 14:13:46 -0000 1.27 >+++ ui/org/eclipse/jdt/internal/ui/text/java/JavaCompletionProposalComputer.java 20 Oct 2008 23:16:13 -0000 >@@ -21,7 +21,6 @@ > import org.eclipse.swt.widgets.Shell; > > import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.core.runtime.OperationCanceledException; > > import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.dialogs.MessageDialog; >@@ -48,7 +47,7 @@ > > /** > * Computes Java completion proposals and context infos. >- * >+ * > * @since 3.2 > */ > public class JavaCompletionProposalComputer implements IJavaCompletionProposalComputer { >@@ -104,15 +103,10 @@ > return fContextInformation.equals(object); > } > } >- >- private static final long JAVA_CODE_ASSIST_TIMEOUT= 500; // ms >- >+ > private String fErrorMessage; >- >- private final IProgressMonitor fTimeoutProgressMonitor; >- >+ > public JavaCompletionProposalComputer() { >- fTimeoutProgressMonitor= createTimeoutProgressMonitor(JAVA_CODE_ASSIST_TIMEOUT); > } > > protected int guessContextInformationPosition(ContentAssistInvocationContext context) { >@@ -143,8 +137,8 @@ > return contextPosition; > } > >- private List addContextInformations(JavaContentAssistInvocationContext context, int offset) { >- List proposals= internalComputeCompletionProposals(offset, context); >+ private List addContextInformations(JavaContentAssistInvocationContext context, int offset, Point selectedRange) { >+ List proposals= internalComputeCompletionProposals(offset, context, selectedRange); > List result= new ArrayList(proposals.size()); > List anonymousResult= new ArrayList(proposals.size()); > >@@ -160,22 +154,28 @@ > result.add(wrapper); > } > } >- >+ > if (result.size() == 0) > return anonymousResult; > return result; >- >+ > } > > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeContextInformation(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ > public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ // We assume this is running in the UI thread. >+ return computeContextInformation(context, monitor, context.getViewer().getSelectedRange()); >+ } >+ >+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, >+ Point selectedRange) { > if (context instanceof JavaContentAssistInvocationContext) { > JavaContentAssistInvocationContext javaContext= (JavaContentAssistInvocationContext) context; >- >+ > int contextInformationPosition= guessContextInformationPosition(javaContext); >- List result= addContextInformations(javaContext, contextInformationPosition); >+ List result= addContextInformations(javaContext, contextInformationPosition, selectedRange); > return result; > } > return Collections.EMPTY_LIST; >@@ -185,44 +185,50 @@ > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ > public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ // We assume this is running in the UI thread >+ Point selectedRange= context.getViewer().getSelectedRange(); >+ return computeCompletionProposals(context, monitor, selectedRange); >+ } >+ >+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, >+ Point selectedRange) { > if (context instanceof JavaContentAssistInvocationContext) { > JavaContentAssistInvocationContext javaContext= (JavaContentAssistInvocationContext) context; >- return internalComputeCompletionProposals(context.getInvocationOffset(), javaContext); >+ >+ return internalComputeCompletionProposals(context.getInvocationOffset(), javaContext, selectedRange); > } > return Collections.EMPTY_LIST; > } > >- private List internalComputeCompletionProposals(int offset, JavaContentAssistInvocationContext context) { >+ private List internalComputeCompletionProposals(int offset, JavaContentAssistInvocationContext context, >+ Point selectedRange) { > ICompilationUnit unit= context.getCompilationUnit(); > if (unit == null) > return Collections.EMPTY_LIST; >- >- ITextViewer viewer= context.getViewer(); >+ >+ final ITextViewer viewer= context.getViewer(); > > CompletionProposalCollector collector= createCollector(context); > collector.setInvocationContext(context); >- >+ > // Allow completions for unresolved types - since 3.3 > collector.setAllowsRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF, true); > collector.setAllowsRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT, true); > collector.setAllowsRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT, true); >- >+ > collector.setAllowsRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF, true); > collector.setAllowsRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT, true); > collector.setAllowsRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT, true); > > collector.setAllowsRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF, true); >- >- // Set the favorite list to propose static members - since 3.3 >+ >+ // Set the favorite list to propose static members - since 3.3 > collector.setFavoriteReferences(getFavoriteStaticMembers()); > > try { >- Point selection= viewer.getSelectedRange(); >- if (selection.y > 0) >- collector.setReplacementLength(selection.y); >- unit.codeComplete(offset, collector, fTimeoutProgressMonitor); >- } catch (OperationCanceledException x) { >- fErrorMessage= JavaTextMessages.CompletionProcessor_error_javaCompletion_took_too_long_message; >+ if (selectedRange.y > 0) >+ collector.setReplacementLength(selectedRange.y); >+ unit.codeComplete(offset, collector); > } catch (JavaModelException x) { > Shell shell= viewer.getTextWidget().getShell(); > if (x.isDoesNotExist() && !unit.getJavaProject().isOnClasspath(unit)) >@@ -232,7 +238,7 @@ > } > > ICompletionProposal[] javaProposals= collector.getJavaCompletionProposals(); >- int contextInformationOffset= guessMethodContextInformationPosition(context); >+ int contextInformationOffset= guessContextInformationPosition(context); > if (contextInformationOffset != offset) { > for (int i= 0; i < javaProposals.length; i++) { > if (javaProposals[i] instanceof JavaMethodCompletionProposal) { >@@ -241,7 +247,7 @@ > } > } > } >- >+ > List proposals= new ArrayList(Arrays.asList(javaProposals)); > if (proposals.size() == 0) { > String error= collector.getErrorMessage(); >@@ -252,39 +258,6 @@ > } > > /** >- * Returns a new progress monitor that get cancelled after the given timeout. >- * >- * @param timeout the timeout in ms >- * @return the progress monitor >- * @since 3.5 >- */ >- private IProgressMonitor createTimeoutProgressMonitor(final long timeout) { >- return new IProgressMonitor() { >- >- private long fEndTime; >- >- public void beginTask(String name, int totalWork) { >- fEndTime= System.currentTimeMillis() + timeout; >- } >- public boolean isCanceled() { >- return fEndTime <= System.currentTimeMillis(); >- } >- public void done() { >- } >- public void internalWorked(double work) { >- } >- public void setCanceled(boolean value) { >- } >- public void setTaskName(String name) { >- } >- public void subTask(String name) { >- } >- public void worked(int work) { >- } >- }; >- } >- >- /** > * Returns the array with favorite static members. > * > * @return the <code>String</code> array with with favorite static members >@@ -300,9 +273,9 @@ > > /** > * Creates the collector used to get proposals from core. >- * >+ * > * @param context the context >- * @return the collector >+ * @return the collector > */ > protected CompletionProposalCollector createCollector(JavaContentAssistInvocationContext context) { > if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES)) >Index: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java,v >retrieving revision 1.17 >diff -u -r1.17 CompletionProposalCategory.java >--- ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java 11 Oct 2008 09:58:47 -0000 1.17 >+++ ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java 20 Oct 2008 23:16:13 -0000 >@@ -27,6 +27,8 @@ > import org.eclipse.core.runtime.Status; > import org.eclipse.core.runtime.SubProgressMonitor; > >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.jface.action.LegacyActionTools; > import org.eclipse.jface.resource.ImageDescriptor; > >@@ -251,17 +253,18 @@ > * @param context the invocation context passed on to the extension > * @param partition the partition type where to invocation occurred > * @param monitor the progress monitor passed on to the extension >+ * @param selectedRange TODO(doogle) COMMENT > * @return the list of computed completion proposals (element type: > * {@link org.eclipse.jface.text.contentassist.ICompletionProposal}) > */ >- public List computeCompletionProposals(ContentAssistInvocationContext context, String partition, SubProgressMonitor monitor) { >+ public List computeCompletionProposals(ContentAssistInvocationContext context, String partition, SubProgressMonitor monitor, Point selectedRange) { > fLastError= null; > List result= new ArrayList(); > List descriptors= new ArrayList(fRegistry.getProposalComputerDescriptors(partition)); > for (Iterator it= descriptors.iterator(); it.hasNext();) { > CompletionProposalComputerDescriptor desc= (CompletionProposalComputerDescriptor) it.next(); > if (desc.getCategory() == this) >- result.addAll(desc.computeCompletionProposals(context, monitor)); >+ result.addAll(desc.computeCompletionProposals(context, monitor, selectedRange)); > if (fLastError == null && desc.getErrorMessage() != null) > fLastError= desc.getErrorMessage(); > } >@@ -276,17 +279,18 @@ > * @param context the invocation context passed on to the extension > * @param partition the partition type where to invocation occurred > * @param monitor the progress monitor passed on to the extension >+ * @param selectedRange TODO(doogle) COMMENT > * @return the list of computed context information objects (element type: > * {@link org.eclipse.jface.text.contentassist.IContextInformation}) > */ >- public List computeContextInformation(ContentAssistInvocationContext context, String partition, SubProgressMonitor monitor) { >+ public List computeContextInformation(ContentAssistInvocationContext context, String partition, SubProgressMonitor monitor, Point selectedRange) { > fLastError= null; > List result= new ArrayList(); > List descriptors= new ArrayList(fRegistry.getProposalComputerDescriptors(partition)); > for (Iterator it= descriptors.iterator(); it.hasNext();) { > CompletionProposalComputerDescriptor desc= (CompletionProposalComputerDescriptor) it.next(); > if (desc.getCategory() == this && (isIncluded() || isSeparateCommand())) >- result.addAll(desc.computeContextInformation(context, monitor)); >+ result.addAll(desc.computeContextInformation(context, monitor, selectedRange)); > if (fLastError == null) > fLastError= desc.getErrorMessage(); > } >Index: ui/org/eclipse/jdt/internal/ui/text/java/AbstractTemplateCompletionProposalComputer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/AbstractTemplateCompletionProposalComputer.java,v >retrieving revision 1.6 >diff -u -r1.6 AbstractTemplateCompletionProposalComputer.java >--- ui/org/eclipse/jdt/internal/ui/text/java/AbstractTemplateCompletionProposalComputer.java 11 Sep 2008 11:59:37 -0000 1.6 >+++ ui/org/eclipse/jdt/internal/ui/text/java/AbstractTemplateCompletionProposalComputer.java 20 Oct 2008 23:16:13 -0000 >@@ -17,6 +17,8 @@ > > import org.eclipse.core.runtime.IProgressMonitor; > >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.jdt.core.ICompilationUnit; > > import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; >@@ -46,7 +48,7 @@ > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > if (!(context instanceof JavaContentAssistInvocationContext)) > return Collections.EMPTY_LIST; > >@@ -60,7 +62,7 @@ > return Collections.EMPTY_LIST; > > fEngine.reset(); >- fEngine.complete(javaContext.getViewer(), javaContext.getInvocationOffset(), unit); >+ fEngine.complete(javaContext.getDocument(), selectedRange, javaContext.getInvocationOffset(), unit); > > TemplateProposal[] templateProposals= fEngine.getResults(); > List result= new ArrayList(Arrays.asList(templateProposals)); >@@ -101,7 +103,7 @@ > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeContextInformation(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > return Collections.EMPTY_LIST; > } > >Index: ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java,v >retrieving revision 1.25 >diff -u -r1.25 ContentAssistProcessor.java >--- ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java 13 Oct 2008 09:35:10 -0000 1.25 >+++ ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java 20 Oct 2008 23:16:13 -0000 >@@ -11,6 +11,7 @@ > package org.eclipse.jdt.internal.ui.text.java; > > import java.util.ArrayList; >+import java.util.Collection; > import java.util.Collections; > import java.util.Comparator; > import java.util.Iterator; >@@ -19,6 +20,7 @@ > import org.eclipse.swt.SWT; > import org.eclipse.swt.events.SelectionAdapter; > import org.eclipse.swt.events.SelectionEvent; >+import org.eclipse.swt.graphics.Point; > import org.eclipse.swt.layout.GridData; > import org.eclipse.swt.layout.GridLayout; > import org.eclipse.swt.widgets.Button; >@@ -41,17 +43,20 @@ > import org.eclipse.jface.preference.IPreferenceStore; > import org.eclipse.jface.resource.JFaceResources; > >+import org.eclipse.jface.text.DocumentEvent; >+import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.ITextViewer; > import org.eclipse.jface.text.contentassist.ContentAssistEvent; > import org.eclipse.jface.text.contentassist.ContentAssistant; > import org.eclipse.jface.text.contentassist.ICompletionListener; > import org.eclipse.jface.text.contentassist.ICompletionListenerExtension; > import org.eclipse.jface.text.contentassist.ICompletionProposal; >-import org.eclipse.jface.text.contentassist.IContentAssistProcessor; >+import org.eclipse.jface.text.contentassist.IContentAssistProcessor2; > import org.eclipse.jface.text.contentassist.IContentAssistantExtension2; > import org.eclipse.jface.text.contentassist.IContentAssistantExtension3; > import org.eclipse.jface.text.contentassist.IContextInformation; > import org.eclipse.jface.text.contentassist.IContextInformationValidator; >+import org.eclipse.jface.text.contentassist.ProposalList; > > import org.eclipse.ui.PlatformUI; > import org.eclipse.ui.dialogs.PreferencesUtil; >@@ -87,7 +92,7 @@ > * > * @since 3.2 > */ >-public class ContentAssistProcessor implements IContentAssistProcessor { >+public class ContentAssistProcessor implements IContentAssistProcessor2 { > > > /** >@@ -228,10 +233,71 @@ > fAssistant.addCompletionListener(new CompletionListener()); > } > >+ // TODO(doogle): Should this be cleaned up? Extracted? >+ private static class NoOpProposalList implements ProposalList { >+ >+ private List backingList = new ArrayList(); >+ >+ public void add(ICompletionProposal proposal) { >+ backingList.add(proposal); >+ } >+ >+ public void addAll(Collection arg) { >+ backingList.addAll(arg); >+ } >+ >+ public List asList() { >+ return backingList; >+ } >+ >+ public int size() { >+ return backingList.size(); >+ } >+ >+ public void dispose() { >+ // Do nothing >+ } >+ >+ public final Collection asCollection() { >+ return null; >+ } >+ >+ public void filter(IDocument document, int offset, DocumentEvent event) { >+ // TODO Auto-generated method stub >+ >+ } >+ >+ public synchronized void resetAndFilter(IDocument document, int offset, DocumentEvent event) { >+ } >+ >+ } >+ >+ /** >+ * @deprecated >+ */ >+ public final ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { >+ NoOpProposalList noOpProposalList= new NoOpProposalList(); >+ computeCompletionProposals(noOpProposalList, viewer.getDocument(), viewer.getSelectedRange(), offset); >+ IProgressMonitor monitor= createProgressMonitor(); >+ ContentAssistInvocationContext context= createContext(viewer.getDocument(), offset, viewer.getSelectedRange()); >+ List result= filterAndSortProposals(noOpProposalList.asList(), monitor, context); >+ return (ICompletionProposal[]) result.toArray(new ICompletionProposal[result.size()]); >+ } >+ >+ public Comparator getComparator() { >+ return new Comparator() { >+ public int compare(Object a, Object b) { >+ ICompletionProposal x = (ICompletionProposal) a; >+ ICompletionProposal y = (ICompletionProposal) b; >+ return x.getDisplayString().compareTo(y.getDisplayString()); >+ } >+ }; >+ } >+ > /* > * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int) > */ >- public final ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { >+ public void computeCompletionProposals(ProposalList partial, IDocument document, Point selectedRange, int offset) { > long start= DEBUG ? System.currentTimeMillis() : 0; > > clearState(); >@@ -239,29 +305,25 @@ > IProgressMonitor monitor= createProgressMonitor(); > monitor.beginTask(JavaTextMessages.ContentAssistProcessor_computing_proposals, fCategories.size() + 1); > >- ContentAssistInvocationContext context= createContext(viewer, offset); >+ ContentAssistInvocationContext context= createContext(document, offset, selectedRange); > long setup= DEBUG ? System.currentTimeMillis() : 0; > > monitor.subTask(JavaTextMessages.ContentAssistProcessor_collecting_proposals); >- List proposals= collectProposals(viewer, offset, monitor, context); >+ collectProposals(partial, document, selectedRange, offset, monitor, context); > long collect= DEBUG ? System.currentTimeMillis() : 0; > > monitor.subTask(JavaTextMessages.ContentAssistProcessor_sorting_proposals); >- List filtered= filterAndSortProposals(proposals, monitor, context); >- fNumberOfComputedResults= filtered.size(); >+ fNumberOfComputedResults= partial.size(); > long filter= DEBUG ? System.currentTimeMillis() : 0; >- >- ICompletionProposal[] result= (ICompletionProposal[]) filtered.toArray(new ICompletionProposal[filtered.size()]); >+ > monitor.done(); > > if (DEBUG) { >- System.err.println("Code Assist Stats (" + result.length + " proposals)"); //$NON-NLS-1$ //$NON-NLS-2$ >+ System.err.println("Code Assist Stats (" + partial.size() + " proposals)"); //$NON-NLS-1$ //$NON-NLS-2$ > System.err.println("Code Assist (setup):\t" + (setup - start) ); //$NON-NLS-1$ > System.err.println("Code Assist (collect):\t" + (collect - setup) ); //$NON-NLS-1$ > System.err.println("Code Assist (sort):\t" + (filter - collect) ); //$NON-NLS-1$ > } >- >- return result; > } > > private void clearState() { >@@ -278,18 +340,25 @@ > * @param context the code assist invocation context > * @return the list of proposals > */ >- private List collectProposals(ITextViewer viewer, int offset, IProgressMonitor monitor, ContentAssistInvocationContext context) { >- List proposals= new ArrayList(); >+ private void collectProposals(final ProposalList partial, IDocument document, final Point selectedRange, int offset, final IProgressMonitor monitor, final ContentAssistInvocationContext context) { > List providers= getCategories(); >+ Thread[] allThreads = new Thread[providers.size()]; >+ int i=0; > for (Iterator it= providers.iterator(); it.hasNext();) { >- CompletionProposalCategory cat= (CompletionProposalCategory) it.next(); >- List computed= cat.computeCompletionProposals(context, fPartition, new SubProgressMonitor(monitor, 1)); >- proposals.addAll(computed); >- if (fErrorMessage == null) >- fErrorMessage= cat.getErrorMessage(); >+ // TODO(doogle): We can test to see whether we launch on the background by examining >+ // the descriptors >+ final CompletionProposalCategory cat= (CompletionProposalCategory) it.next(); >+ allThreads[i] = new Thread() { >+ public void run() { >+ List computed= cat.computeCompletionProposals(context, fPartition, new SubProgressMonitor(monitor, 1), selectedRange); >+ partial.addAll(computed); >+ if (fErrorMessage == null) >+ fErrorMessage= cat.getErrorMessage(); >+ } >+ }; >+ allThreads[i].start(); >+ i++; > } >- >- return proposals; > } > > /** >@@ -317,7 +386,8 @@ > monitor.beginTask(JavaTextMessages.ContentAssistProcessor_computing_contexts, fCategories.size() + 1); > > monitor.subTask(JavaTextMessages.ContentAssistProcessor_collecting_contexts); >- List proposals= collectContextInformation(viewer, offset, monitor); >+ // TODO(doogle): We might need to add a separate code path here as well. >+ List proposals= collectContextInformation(viewer, offset, monitor, viewer.getSelectedRange()); > > monitor.subTask(JavaTextMessages.ContentAssistProcessor_sorting_contexts); > List filtered= filterAndSortContextInformation(proposals, monitor); >@@ -328,14 +398,14 @@ > return result; > } > >- private List collectContextInformation(ITextViewer viewer, int offset, IProgressMonitor monitor) { >+ private List collectContextInformation(ITextViewer viewer, int offset, IProgressMonitor monitor, Point selectedRange) { > List proposals= new ArrayList(); >- ContentAssistInvocationContext context= createContext(viewer, offset); >+ ContentAssistInvocationContext context= createContext(viewer.getDocument(), offset, selectedRange); > > List providers= getCategories(); > for (Iterator it= providers.iterator(); it.hasNext();) { > CompletionProposalCategory cat= (CompletionProposalCategory) it.next(); >- List computed= cat.computeContextInformation(context, fPartition, new SubProgressMonitor(monitor, 1)); >+ List computed= cat.computeContextInformation(context, fPartition, new SubProgressMonitor(monitor, 1), selectedRange); > proposals.addAll(computed); > if (fErrorMessage == null) > fErrorMessage= cat.getErrorMessage(); >@@ -419,12 +489,12 @@ > * Creates the context that is passed to the completion proposal > * computers. > * >- * @param viewer the viewer that content assist is invoked on >+ * @param document TODO bblarklujehfasdkljhawrg > * @param offset the content assist offset > * @return the context to be passed to the computers > */ >- protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset) { >- return new ContentAssistInvocationContext(viewer, offset); >+ protected ContentAssistInvocationContext createContext(IDocument document, int offset, Point selectedRange) { >+ return new ContentAssistInvocationContext(document, offset, selectedRange); > } > > private List getCategories() { >Index: ui/org/eclipse/jdt/ui/text/java/ContentAssistInvocationContext.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/java/ContentAssistInvocationContext.java,v >retrieving revision 1.7 >diff -u -r1.7 ContentAssistInvocationContext.java >--- ui/org/eclipse/jdt/ui/text/java/ContentAssistInvocationContext.java 11 Sep 2008 11:59:37 -0000 1.7 >+++ ui/org/eclipse/jdt/ui/text/java/ContentAssistInvocationContext.java 20 Oct 2008 23:16:13 -0000 >@@ -12,6 +12,8 @@ > > import org.eclipse.core.runtime.Assert; > >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.ITextViewer; >@@ -35,6 +37,7 @@ > /* state */ > private final ITextViewer fViewer; > private final IDocument fDocument; >+ private final Point fSelectedRange; > private final int fOffset; > > /* cached additional info */ >@@ -60,6 +63,7 @@ > Assert.isNotNull(viewer); > fViewer= viewer; > fDocument= null; >+ fSelectedRange= null; > fOffset= offset; > } > >@@ -68,6 +72,7 @@ > */ > protected ContentAssistInvocationContext() { > fDocument= null; >+ fSelectedRange= null; > fViewer= null; > fOffset= -1; > } >@@ -78,11 +83,12 @@ > * @param document the document that content assist is invoked in > * @param offset the offset into the document where content assist is invoked at > */ >- public ContentAssistInvocationContext(IDocument document, int offset) { >+ public ContentAssistInvocationContext(IDocument document, int offset, Point selectedRange) { > Assert.isNotNull(document); > Assert.isTrue(offset >= 0); > fViewer= null; > fDocument= document; >+ fSelectedRange= selectedRange; > fOffset= offset; > } > >Index: ui/org/eclipse/jdt/ui/text/java/IJavaCompletionProposalComputer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/java/IJavaCompletionProposalComputer.java,v >retrieving revision 1.4 >diff -u -r1.4 IJavaCompletionProposalComputer.java >--- ui/org/eclipse/jdt/ui/text/java/IJavaCompletionProposalComputer.java 11 Sep 2008 11:59:37 -0000 1.4 >+++ ui/org/eclipse/jdt/ui/text/java/IJavaCompletionProposalComputer.java 20 Oct 2008 23:16:13 -0000 >@@ -14,6 +14,8 @@ > > import org.eclipse.core.runtime.IProgressMonitor; > >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.jface.text.contentassist.ICompletionProposal; > import org.eclipse.jface.text.contentassist.IContextInformation; > >@@ -42,7 +44,7 @@ > * invocation, i.e. there is no need for the receiver to spawn a sub monitor. > * @return a list of completion proposals (element type: {@link ICompletionProposal}) > */ >- List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor); >+ List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange); > > /** > * Returns context information objects valid at the given invocation context. >@@ -52,7 +54,7 @@ > * invocation, i.e. there is no need for the receiver to spawn a sub monitor. > * @return a list of context information objects (element type: {@link IContextInformation}) > */ >- List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor); >+ List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange); > > /** > * Returns the reason why this computer was unable to produce any completion proposals or >Index: ui/org/eclipse/jdt/ui/text/java/JavaContentAssistInvocationContext.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/java/JavaContentAssistInvocationContext.java,v >retrieving revision 1.18 >diff -u -r1.18 JavaContentAssistInvocationContext.java >--- ui/org/eclipse/jdt/ui/text/java/JavaContentAssistInvocationContext.java 11 Sep 2008 11:59:37 -0000 1.18 >+++ ui/org/eclipse/jdt/ui/text/java/JavaContentAssistInvocationContext.java 20 Oct 2008 23:16:13 -0000 >@@ -12,6 +12,9 @@ > > import org.eclipse.core.runtime.Assert; > >+import org.eclipse.swt.graphics.Point; >+ >+import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.ITextViewer; > > import org.eclipse.ui.IEditorPart; >@@ -36,17 +39,17 @@ > * <p> > * Clients may use but not subclass this class. > * </p> >- * >+ * > * @since 3.2 >- * >+ * > * @noextend This class is not intended to be subclassed by clients. > */ > public class JavaContentAssistInvocationContext extends ContentAssistInvocationContext { > private final IEditorPart fEditor; >- >+ > private ICompilationUnit fCU= null; > private boolean fCUComputed= false; >- >+ > private CompletionProposalLabelProvider fLabelProvider; > private CompletionProposalCollector fCollector; > private RHSHistory fRHSHistory; >@@ -57,7 +60,7 @@ > > /** > * Creates a new context. >- * >+ * > * @param viewer the viewer used by the editor > * @param offset the invocation offset > * @param editor the editor that content assist is invoked in >@@ -67,10 +70,23 @@ > Assert.isNotNull(editor); > fEditor= editor; > } >- >+ >+ /** >+ * Creates a new context. >+ * >+ * @param document the document blah blah >+ * @param offset the invocation offset >+ * @param editor the editor that content assist is invoked in >+ */ >+ public JavaContentAssistInvocationContext(IDocument document, int offset, Point selectedRange, IEditorPart editor) { >+ super(document, offset, selectedRange); >+ Assert.isNotNull(editor); >+ fEditor= editor; >+ } >+ > /** > * Creates a new context. >- * >+ * > * @param unit the compilation unit in <code>document</code> > */ > public JavaContentAssistInvocationContext(ICompilationUnit unit) { >@@ -79,11 +95,11 @@ > fCUComputed= true; > fEditor= null; > } >- >+ > /** > * Returns the compilation unit that content assist is invoked in, <code>null</code> if there > * is none. >- * >+ * > * @return the compilation unit that content assist is invoked in, possibly <code>null</code> > */ > public ICompilationUnit getCompilationUnit() { >@@ -99,18 +115,18 @@ > } > return fCU; > } >- >+ > /** > * Returns the project of the compilation unit that content assist is invoked in, > * <code>null</code> if none. >- * >+ * > * @return the current java project, possibly <code>null</code> > */ > public IJavaProject getProject() { > ICompilationUnit unit= getCompilationUnit(); > return unit == null ? null : unit.getJavaProject(); > } >- >+ > /** > * Returns the keyword proposals that are available in this context, possibly none. > * <p> >@@ -118,7 +134,7 @@ > * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete} > * on the compilation unit. > * </p> >- * >+ * > * @return the available keyword proposals > */ > public IJavaCompletionProposal[] getKeywordProposals() { >@@ -131,7 +147,7 @@ > computeKeywordsAndContext(); > } > } >- >+ > return fKeywordProposals; > } > >@@ -143,7 +159,7 @@ > * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete} > * on the compilation unit. > * </p> >- * >+ * > * @return the core completion context if available, <code>null</code> otherwise > */ > public CompletionContext getCoreContext() { >@@ -167,17 +183,17 @@ > * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete} > * on the compilation unit. > * </p> >- * >+ * > * @param qualifiedTypeName the type name of the type of interest > * @return a relevance in [0.0, 1.0] based on previous content assist invocations > */ > public float getHistoryRelevance(String qualifiedTypeName) { > return getRHSHistory().getRank(qualifiedTypeName); > } >- >+ > /** > * Returns the content assist type history for the expected type. >- * >+ * > * @return the content assist type history for the expected type > */ > private RHSHistory getRHSHistory() { >@@ -195,7 +211,7 @@ > } > return fRHSHistory; > } >- >+ > /** > * Returns the expected type if any, <code>null</code> otherwise. > * <p> >@@ -203,7 +219,7 @@ > * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete} > * on the compilation unit. > * </p> >- * >+ * > * @return the expected type if any, <code>null</code> otherwise > */ > public IType getExpectedType() { >@@ -225,10 +241,10 @@ > } > return fType; > } >- >+ > /** > * Returns a label provider that can be used to compute proposal labels. >- * >+ * > * @return a label provider that can be used to compute proposal labels > */ > public CompletionProposalLabelProvider getLabelProvider() { >@@ -241,7 +257,7 @@ > > return fLabelProvider; > } >- >+ > /** > * Sets the collector, which is used to access the compilation unit, the core context and the > * label provider. This is a performance optimization: {@link IJavaCompletionProposalComputer}s >@@ -250,18 +266,18 @@ > * which in turn calls this method. This allows the invocation context to retrieve the core > * context and keyword proposals from the existing collector, instead of computing theses values > * itself via {@link #computeKeywordsAndContext()}. >- * >+ * > * @param collector the collector > */ > void setCollector(CompletionProposalCollector collector) { > fCollector= collector; > } >- >+ > /** > * Fallback to retrieve a core context and keyword proposals when no collector is available. > * Runs code completion on the cu and collects keyword proposals. {@link #fKeywordProposals} is > * non-<code>null</code> after this call. >- * >+ * > * @since 3.3 > */ > private void computeKeywordsAndContext() { >@@ -271,10 +287,10 @@ > fKeywordProposals= new IJavaCompletionProposal[0]; > return; > } >- >+ > CompletionProposalCollector collector= new CompletionProposalCollector(cu, true); > collector.setIgnored(CompletionProposal.KEYWORD, false); >- >+ > try { > cu.codeComplete(getInvocationOffset(), collector); > if (fCoreContext == null) >@@ -289,7 +305,7 @@ > fKeywordProposals= new IJavaCompletionProposal[0]; > } > } >- >+ > /* > * Implementation note: There is no need to override hashCode and equals, as we only add cached > * values shared across one assist invocation. >Index: ui/org/eclipse/jdt/internal/ui/text/javadoc/LegacyJavadocCompletionProposalComputer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/LegacyJavadocCompletionProposalComputer.java,v >retrieving revision 1.9 >diff -u -r1.9 LegacyJavadocCompletionProposalComputer.java >--- ui/org/eclipse/jdt/internal/ui/text/javadoc/LegacyJavadocCompletionProposalComputer.java 11 Sep 2008 11:59:35 -0000 1.9 >+++ ui/org/eclipse/jdt/internal/ui/text/javadoc/LegacyJavadocCompletionProposalComputer.java 20 Oct 2008 23:16:13 -0000 >@@ -76,7 +76,7 @@ > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeContextInformation(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > if (context instanceof JavaContentAssistInvocationContext) { > JavaContentAssistInvocationContext javaContext= (JavaContentAssistInvocationContext) context; > >@@ -107,17 +107,16 @@ > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > if (context instanceof JavadocContentAssistInvocationContext) { > JavadocContentAssistInvocationContext javaContext= (JavadocContentAssistInvocationContext) context; > > ICompilationUnit cu= javaContext.getCompilationUnit(); > int offset= javaContext.getInvocationOffset(); > int length= javaContext.getSelectionLength(); >- Point selection= javaContext.getViewer().getSelectedRange(); >- if (selection.y > 0) { >- offset= selection.x; >- length= selection.y; >+ if (selectedRange.y > 0) { >+ offset= selectedRange.x; >+ length= selectedRange.y; > } > > ArrayList result= new ArrayList(); >Index: ui/org/eclipse/jdt/internal/ui/text/javadoc/HTMLTagCompletionProposalComputer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/javadoc/HTMLTagCompletionProposalComputer.java,v >retrieving revision 1.6 >diff -u -r1.6 HTMLTagCompletionProposalComputer.java >--- ui/org/eclipse/jdt/internal/ui/text/javadoc/HTMLTagCompletionProposalComputer.java 11 Sep 2008 11:59:35 -0000 1.6 >+++ ui/org/eclipse/jdt/internal/ui/text/javadoc/HTMLTagCompletionProposalComputer.java 20 Oct 2008 23:16:13 -0000 >@@ -15,12 +15,13 @@ > import java.util.Collections; > import java.util.List; > >-import org.eclipse.swt.graphics.Image; >- > import org.eclipse.core.runtime.IProgressMonitor; > > import org.eclipse.core.resources.IFile; > >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.jface.viewers.StyledString; > > import org.eclipse.jface.text.BadLocationException; >@@ -119,15 +120,15 @@ > } > return pos; > } >- >+ > /* > * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#computeCompletionProposals(org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > * @since 3.2 > */ >- public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > if (!(context instanceof JavadocContentAssistInvocationContext)) > return Collections.EMPTY_LIST; >- >+ > JavadocContentAssistInvocationContext docContext= (JavadocContentAssistInvocationContext) context; > int flags= docContext.getFlags(); > fCurrentPos= docContext.getInvocationOffset(); >@@ -164,7 +165,7 @@ > int word1Begin= findCharBeforeWord(fDocument, lineBeginPos, fCurrentPos); > if (word1Begin == fCurrentPos) > return; >- >+ > char firstChar= fDocument.getChar(word1Begin); > if (firstChar == '<') { > String prefix= fDocument.get(word1Begin, fCurrentPos - word1Begin); >@@ -224,12 +225,12 @@ > proposal.setTriggerCharacters( new char[] { '>' }); > return proposal; > } >- >+ > /* > * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#computeContextInformation(org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > * @since 3.2 > */ >- public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > return Collections.EMPTY_LIST; > } > >Index: ui/org/eclipse/jdt/internal/ui/text/spelling/WordCompletionProposalComputer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/spelling/WordCompletionProposalComputer.java,v >retrieving revision 1.8 >diff -u -r1.8 WordCompletionProposalComputer.java >--- ui/org/eclipse/jdt/internal/ui/text/spelling/WordCompletionProposalComputer.java 11 Sep 2008 11:59:52 -0000 1.8 >+++ ui/org/eclipse/jdt/internal/ui/text/spelling/WordCompletionProposalComputer.java 20 Oct 2008 23:16:13 -0000 >@@ -18,14 +18,16 @@ > > import org.eclipse.core.runtime.IProgressMonitor; > >+import org.eclipse.swt.graphics.Point; >+ > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.DocumentEvent; > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.IRegion; > > import org.eclipse.jdt.ui.PreferenceConstants; >-import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; > import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer; >+import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; > > import org.eclipse.jdt.internal.ui.JavaPlugin; > import org.eclipse.jdt.internal.ui.JavaPluginImages; >@@ -54,38 +56,38 @@ > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > if (contributes()) { > try { > IDocument document= context.getDocument(); > final int offset= context.getInvocationOffset(); >- >+ > final IRegion region= document.getLineInformationOfOffset(offset); > final String content= document.get(region.getOffset(), region.getLength()); >- >+ > int index= offset - region.getOffset() - 1; > while (index >= 0 && Character.isLetter(content.charAt(index))) > index--; >- >+ > final int start= region.getOffset() + index + 1; > final String candidate= content.substring(index + 1, offset - region.getOffset()); >- >+ > if (candidate.length() > 0) { >- >+ > final ISpellCheckEngine engine= SpellCheckEngine.getInstance(); > final ISpellChecker checker= engine.getSpellChecker(); >- >+ > if (checker != null) { >- >+ > final List proposals= new ArrayList(checker.getProposals(candidate, Character.isUpperCase(candidate.charAt(0)))); > final List result= new ArrayList(proposals.size()); >- >+ > for (Iterator it= proposals.iterator(); it.hasNext();) { > RankedWordProposal word= (RankedWordProposal) it.next(); > String text= word.getText(); > if (text.startsWith(candidate)) > word.setRank(word.getRank() + PREFIX_RANK_SHIFT); >- >+ > result.add(new JavaCompletionProposal(text, start, candidate.length(), JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_RENAME), text, word.getRank()) { > /* > * @see org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal#validate(org.eclipse.jface.text.IDocument, int, org.eclipse.jface.text.DocumentEvent) >@@ -95,7 +97,7 @@ > } > }); > } >- >+ > return result; > } > } >@@ -114,7 +116,7 @@ > /* > * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeContextInformation(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor) > */ >- public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { >+ public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor, Point selectedRange) { > return Collections.EMPTY_LIST; > } > >Index: ui/org/eclipse/jdt/internal/ui/text/template/contentassist/TemplateEngine.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/template/contentassist/TemplateEngine.java,v >retrieving revision 1.22 >diff -u -r1.22 TemplateEngine.java >--- ui/org/eclipse/jdt/internal/ui/text/template/contentassist/TemplateEngine.java 11 Sep 2008 11:59:55 -0000 1.22 >+++ ui/org/eclipse/jdt/internal/ui/text/template/contentassist/TemplateEngine.java 20 Oct 2008 23:16:13 -0000 >@@ -24,7 +24,6 @@ > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.IRegion; >-import org.eclipse.jface.text.ITextViewer; > import org.eclipse.jface.text.Position; > import org.eclipse.jface.text.Region; > import org.eclipse.jface.text.templates.GlobalTemplateVariables; >@@ -95,21 +94,20 @@ > * @param viewer the text viewer > * @param completionPosition the context position in the document of the text viewer > * @param compilationUnit the compilation unit (may be <code>null</code>) >+ * @param selectedRange TODO(doogle): DOCUMENT > */ >- public void complete(ITextViewer viewer, int completionPosition, ICompilationUnit compilationUnit) { >- IDocument document= viewer.getDocument(); >- >+ //TODO(doogle): completionPosition is not necessary anymore (it's selectedRange.x) >+ public void complete(final IDocument document, Point selectedRange, int completionPosition, ICompilationUnit compilationUnit) { > if (!(fContextType instanceof CompilationUnitContextType)) > return; > >- Point selection= viewer.getSelectedRange(); >- Position position= new Position(completionPosition, selection.y); >+ Position position= new Position(completionPosition, selectedRange.y); > > // remember selected text > String selectedText= null; >- if (selection.y != 0) { >+ if (selectedRange.y != 0) { > try { >- selectedText= document.get(selection.x, selection.y); >+ selectedText= document.get(selectedRange.x, selectedRange.y); > document.addPosition(position); > fPositions.put(document, position); > } catch (BadLocationException e) {} >@@ -123,7 +121,7 @@ > > Template[] templates= JavaPlugin.getDefault().getTemplateStore().getTemplates(); > >- if (selection.y == 0) { >+ if (selectedRange.y == 0) { > for (int i= 0; i != templates.length; i++) { > Template template= templates[i]; > if (context.canEvaluate(template)) { >@@ -135,7 +133,7 @@ > if (context.getKey().length() == 0) > context.setForceEvaluation(true); > >- boolean multipleLinesSelected= areMultipleLinesSelected(viewer); >+ boolean multipleLinesSelected= areMultipleLinesSelected(document, selectedRange); > > for (int i= 0; i != templates.length; i++) { > Template template= templates[i]; >@@ -164,17 +162,11 @@ > * @return <code>true</code> if one or multiple lines are selected > * @since 2.1 > */ >- private boolean areMultipleLinesSelected(ITextViewer viewer) { >- if (viewer == null) >- return false; >- >- Point s= viewer.getSelectedRange(); >+ private boolean areMultipleLinesSelected(IDocument document, Point s) { > if (s.y == 0) > return false; > > try { >- >- IDocument document= viewer.getDocument(); > int startLine= document.getLineOfOffset(s.x); > int endLine= document.getLineOfOffset(s.x + s.y); > IRegion line= document.getLineInformation(startLine); >#P org.eclipse.jface.text >Index: src/org/eclipse/jface/text/contentassist/ContentAssistant.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java,v >retrieving revision 1.96 >diff -u -r1.96 ContentAssistant.java >--- src/org/eclipse/jface/text/contentassist/ContentAssistant.java 11 Sep 2008 11:58:23 -0000 1.96 >+++ src/org/eclipse/jface/text/contentassist/ContentAssistant.java 20 Oct 2008 23:16:15 -0000 >@@ -12,11 +12,33 @@ > *******************************************************************************/ > package org.eclipse.jface.text.contentassist; > >+import java.util.Arrays; > import java.util.HashMap; > import java.util.Iterator; > import java.util.Map; > import java.util.Map.Entry; > >+import org.eclipse.core.commands.IHandler; >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.core.runtime.ListenerList; >+import org.eclipse.jface.bindings.keys.KeySequence; >+import org.eclipse.jface.contentassist.IContentAssistSubjectControl; >+import org.eclipse.jface.contentassist.ISubjectControlContentAssistProcessor; >+import org.eclipse.jface.dialogs.IDialogSettings; >+import org.eclipse.jface.preference.JFacePreferences; >+import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.IDocument; >+import org.eclipse.jface.text.IDocumentExtension3; >+import org.eclipse.jface.text.IEventConsumer; >+import org.eclipse.jface.text.IInformationControlCreator; >+import org.eclipse.jface.text.ITextViewer; >+import org.eclipse.jface.text.IViewportListener; >+import org.eclipse.jface.text.IWidgetTokenKeeper; >+import org.eclipse.jface.text.IWidgetTokenKeeperExtension; >+import org.eclipse.jface.text.IWidgetTokenOwner; >+import org.eclipse.jface.text.IWidgetTokenOwnerExtension; >+import org.eclipse.jface.text.TextUtilities; >+import org.eclipse.jface.util.Geometry; > import org.eclipse.swt.SWT; > import org.eclipse.swt.SWTError; > import org.eclipse.swt.custom.VerifyKeyListener; >@@ -44,31 +66,6 @@ > import org.eclipse.swt.widgets.Shell; > import org.eclipse.swt.widgets.Widget; > >-import org.eclipse.core.commands.IHandler; >- >-import org.eclipse.core.runtime.Assert; >-import org.eclipse.core.runtime.ListenerList; >- >-import org.eclipse.jface.bindings.keys.KeySequence; >-import org.eclipse.jface.contentassist.IContentAssistSubjectControl; >-import org.eclipse.jface.contentassist.ISubjectControlContentAssistProcessor; >-import org.eclipse.jface.dialogs.IDialogSettings; >-import org.eclipse.jface.preference.JFacePreferences; >-import org.eclipse.jface.util.Geometry; >- >-import org.eclipse.jface.text.BadLocationException; >-import org.eclipse.jface.text.IDocument; >-import org.eclipse.jface.text.IDocumentExtension3; >-import org.eclipse.jface.text.IEventConsumer; >-import org.eclipse.jface.text.IInformationControlCreator; >-import org.eclipse.jface.text.ITextViewer; >-import org.eclipse.jface.text.IViewportListener; >-import org.eclipse.jface.text.IWidgetTokenKeeper; >-import org.eclipse.jface.text.IWidgetTokenKeeperExtension; >-import org.eclipse.jface.text.IWidgetTokenOwner; >-import org.eclipse.jface.text.IWidgetTokenOwnerExtension; >-import org.eclipse.jface.text.TextUtilities; >- > > /** > * The standard implementation of the <code>IContentAssistant</code> interface. Usually, clients >@@ -1749,7 +1746,7 @@ > * @return a content-assist processor or <code>null</code> if none exists > * @since 3.0 > */ >- private IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) { >+ IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) { > try { > > IDocument document= viewer.getDocument(); >@@ -1799,18 +1796,14 @@ > * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) > * @since 3.0 > */ >- ICompletionProposal[] computeCompletionProposals(IContentAssistSubjectControl contentAssistSubjectControl, int offset) { >+ void computeCompletionProposals(ProposalList computedProposals, IContentAssistSubjectControl contentAssistSubjectControl, int offset) { > fLastErrorMessage= null; > >- ICompletionProposal[] result= null; >- > IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset); > if (p instanceof ISubjectControlContentAssistProcessor) { >- result= ((ISubjectControlContentAssistProcessor) p).computeCompletionProposals(contentAssistSubjectControl, offset); >+ computedProposals.addAll(Arrays.asList(((ISubjectControlContentAssistProcessor) p).computeCompletionProposals(contentAssistSubjectControl, offset))); > fLastErrorMessage= p.getErrorMessage(); > } >- >- return result; > } > > /** >@@ -1822,18 +1815,18 @@ > * @return an array of completion proposals or <code>null</code> if no proposals are possible > * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) > */ >- ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) { >+ void computeCompletionProposals(ProposalList partial, ITextViewer viewer, Point selectedRange, int offset) { > fLastErrorMessage= null; > >- ICompletionProposal[] result= null; >- > IContentAssistProcessor p= getProcessor(viewer, offset); > if (p != null) { >- result= p.computeCompletionProposals(viewer, offset); >+ if (p instanceof IContentAssistProcessor2) { >+ ((IContentAssistProcessor2) p).computeCompletionProposals(partial, viewer.getDocument(), selectedRange, offset); >+ } else { >+ partial.addAll(Arrays.asList(p.computeCompletionProposals(viewer, offset))); >+ } > fLastErrorMessage= p.getErrorMessage(); > } >- >- return result; > } > > /** >@@ -2218,12 +2211,13 @@ > > /** > * Fires a session restart event to all registered {@link ICompletionListener}s. >+ * @param selectedRange TODO(doogle): DOCUMENT > * > * @since 3.4 > */ >- void fireSessionRestartEvent() { >+ void fireSessionRestartEvent(Point selectedRange) { > if (fContentAssistSubjectControlAdapter != null) { >- IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, fContentAssistSubjectControlAdapter.getSelectedRange().x); >+ IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, selectedRange.x); > ContentAssistEvent event= new ContentAssistEvent(this, processor); > Object[] listeners= fCompletionListeners.getListeners(); > for (int i= 0; i < listeners.length; i++) { >Index: src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java,v >retrieving revision 1.152 >diff -u -r1.152 CompletionProposalPopup.java >--- src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java 11 Sep 2008 11:58:23 -0000 1.152 >+++ src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java 20 Oct 2008 23:16:14 -0000 >@@ -12,7 +12,11 @@ > package org.eclipse.jface.text.contentassist; > > import java.util.ArrayList; >+import java.util.Collection; >+import java.util.Comparator; >+import java.util.Iterator; > import java.util.List; >+import java.util.TreeSet; > > import org.eclipse.swt.SWT; > import org.eclipse.swt.custom.BusyIndicator; >@@ -302,10 +306,11 @@ > private List fDocumentEvents= new ArrayList(); > /** Listener filling the document event queue. */ > private IDocumentListener fDocumentListener; >- /** The filter list of proposals. */ >- private ICompletionProposal[] fFilteredProposals; >+ /** TODO(doogle): DELETE The filter list of proposals. */ >+ private ProposalList fFilteredProposals; > /** The computed list of proposals. */ >- private ICompletionProposal[] fComputedProposals; >+ // List ICompletionProposal >+ private ProposalList fComputedProposals; > /** The offset for which the proposals have been computed. */ > private int fInvocationOffset; > /** The offset for which the computed proposals have been filtered. */ >@@ -362,12 +367,22 @@ > if (!Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) > return; > >- int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x; >- ICompletionProposal[] proposals= null; >+ final Point selectedRange= fContentAssistSubjectControlAdapter.getSelectedRange(); >+ final int offset= selectedRange.x; > try { > if (offset > -1) { >- DocumentEvent event= TextUtilities.mergeProcessedDocumentEvents(fDocumentEvents); >- proposals= computeFilteredProposals(offset, event); >+ final DocumentEvent event= TextUtilities.mergeProcessedDocumentEvents(fDocumentEvents); >+ if (event.getLength() > 0 && (event.getText().length() == 0)) { >+ if (event.getOffset() < fInvocationOffset) { >+ hide(); >+ showProposals(true); >+ return; >+ } >+ >+ fComputedProposals.resetAndFilter(event.fDocument, offset, event); >+ } else { >+ fComputedProposals.filter(event.fDocument, offset, event); >+ } > } > } catch (BadLocationException x) { > } finally { >@@ -375,10 +390,12 @@ > } > fFilterOffset= offset; > >- if (proposals != null && proposals.length > 0) >+ /* >+ if (proposals != null && proposals.size() > 0) > setProposals(proposals, fIsFilteredSubset); > else > hide(); >+ */ > } > }; > /** >@@ -426,6 +443,7 @@ > * @since 3.4 > */ > private boolean fIsColoredLabelsSupportEnabled= false; >+ private Point fSelectedRange; > > > /** >@@ -482,15 +500,25 @@ > > fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x; > fFilterOffset= fInvocationOffset; >+ fSelectedRange = fViewer.getSelectedRange(); > fLastCompletionOffset= fFilterOffset; >- fComputedProposals= computeProposals(fInvocationOffset); >- >- int count= (fComputedProposals == null ? 0 : fComputedProposals.length); >- if (count == 0 && hideWhenNoProposals(autoActivated)) >- return; >- >- if (count == 1 && !autoActivated && canAutoInsert(fComputedProposals[0])) { >- insertProposal(fComputedProposals[0], (char) 0, 0, fInvocationOffset); >+ >+// fComputedProposals= computeProposals(fInvocationOffset); >+ IContentAssistProcessor processor = fContentAssistant.getProcessor(fViewer, fFilterOffset); >+ if (processor instanceof IContentAssistProcessor2) { >+ fComputedProposals= new DefaultProposalList(((IContentAssistProcessor2) processor).getComparator()); >+ } else { >+ fComputedProposals= new DefaultProposalList(); >+ } >+ >+ int count= (fComputedProposals == null ? 0 : fComputedProposals.size()); >+// if (count == 0 && hideWhenNoProposals(autoActivated)) >+// return; >+ >+ // TODO(doogle): We do not handle the case where only a single completion is found >+ if (count == 1 && !autoActivated && >+ canAutoInsert((ICompletionProposal) fComputedProposals.asList().get(0))) { >+ insertProposal((ICompletionProposal) fComputedProposals.asList().get(0), (char) 0, 0, fInvocationOffset); > hide(); > } else { > createProposalSelector(); >@@ -504,8 +532,210 @@ > handleRepeatedInvocation(); > } > >+ new Thread() { >+ public void run() { >+ computeProposals(fComputedProposals, fInvocationOffset); >+ } >+ }.start(); >+ > return getErrorMessage(); > } >+ >+ private class DefaultProposalList implements ProposalList { >+ >+ /** >+ * A subset of the proposals originally used to create the >+ * DefaultProposalList, after being filtered. >+ */ >+ private final class FilteredProposalList { >+ >+ private final IDocument document; >+ private final int offset; >+ private final DocumentEvent event; >+ private final Collection proposals; >+ >+ public FilteredProposalList(IDocument document, int offset, DocumentEvent event) { >+ this.document = document; >+ this.offset = offset; >+ this.event = event; >+ // TODO(doogle): This needs to inherit the comparator so that >+ // sorting across categories >+ this.proposals = new ArrayList(); >+ } >+ >+ public FilteredProposalList(final Collection proposals) { >+ this.document = null; >+ this.offset = -1; >+ this.event = null; >+ this.proposals = proposals; >+ } >+ >+ /** >+ * If this proposal matches against this proposal bag, then add it >+ * to the proposals for this entry. >+ * >+ * @param proposal The proposal to possibly add; may be >+ * <code>null</code>. >+ * @return <code>true</code> if the proposal matches the filter for >+ * this entry; <code>false</code> otherwise. >+ */ >+ public final boolean maybeAdd(final ICompletionProposal proposal) { >+ if (validate(proposal)) { >+ proposals.add(proposal); >+ return true; >+ } >+ return false; >+ } >+ >+ /** >+ * Validates the proposal against the offsets recorded in this entry. >+ * @param proposal The proposal to check; may be <code>null</code>. >+ * @return <code>true</code> if the proposal matches the filter; >+ * <code>false</code> otherwise. >+ */ >+ private final boolean validate(final ICompletionProposal proposal) { >+ if (document == null || event == null) { >+ return true; >+ } >+ >+ if (proposal instanceof ICompletionProposalExtension2) { >+ ICompletionProposalExtension2 p = (ICompletionProposalExtension2) proposal; >+ return p.validate(document, offset, event); >+ } >+ >+ if (proposal instanceof ICompletionProposalExtension) { >+ ICompletionProposalExtension p = (ICompletionProposalExtension) proposal; >+ return p.isValidFor(document, offset); >+ } >+ >+ // TODO(doogle) >+ throw new UnsupportedOperationException("Monkeys!!!"); //$NON-NLS-1$ >+ >+ // TODO(doogle): This is how the legacy code works. At every key event, it needs >+ // to compute the whole list from scratch. Likely this is so that >+ // the completion proposals contain accurate offset information, as >+ // the core ICompletionProposal interface has not facility for >+ // updating offsets. >+ // restore original behavior >+// fInvocationOffset= offset; >+// fContentAssistant.fireSessionRestartEvent(selectedRange); >+// computeProposals(fComputedProposals, fInvocationOffset); >+// return fComputedProposals; >+ } >+ } >+ >+ private final class Updater implements Runnable { >+ >+ private final Collection backing; >+ >+ public Updater(Collection backing) { >+ this.backing = backing; >+ } >+ >+ public void run() { >+ while (!isDisposed) { >+ try { >+ Thread.sleep(300); >+ if (!isDirtyAndClear()) { >+ continue; >+ } >+ } catch (InterruptedException e) { >+ throw new RuntimeException(e); >+ } >+ if (fProposalShell != null) { >+ fProposalShell.getDisplay().asyncExec(new Runnable(){ >+ public void run() { >+ setProposals(DefaultProposalList.this, false); >+ } >+ }); >+ } else { >+ System.out.println("BAD MONKEYS IN THE CODE"); //$NON-NLS-1$ >+ } >+ } >+ } >+ } >+ >+ private final Collection originalProposals; >+ //TODO: properly support the comparator in all cases >+ private final Comparator backingComparator; >+ >+ private FilteredProposalList proposalBag; >+ private boolean isDisposed = false; >+ private boolean isDirty = false; >+ >+ public void dispose() { >+ this.isDisposed = true; >+ } >+ >+ public DefaultProposalList() { >+ this(null); >+ } >+ >+ public DefaultProposalList(Comparator comparator) { >+ this.backingComparator = comparator; >+ originalProposals = new TreeSet(comparator); >+ proposalBag = new FilteredProposalList(originalProposals); >+ new Thread(new Updater(originalProposals), "UpdaterThread").start(); //$NON-NLS-1$ >+ } >+ >+ public synchronized void add(ICompletionProposal proposal) { >+ if ((originalProposals.size() == 1) && >+ (originalProposals.iterator().next() == fEmptyProposal)) { >+ originalProposals.clear(); >+ } >+ originalProposals.add(proposal); >+ proposalBag.maybeAdd(proposal); >+ makeDirty(); >+ } >+ >+ public synchronized void addAll(Collection arg) { >+ Iterator iterator = arg.iterator(); >+ while(iterator.hasNext()) { >+ add((ICompletionProposal) iterator.next()); >+ } >+ } >+ >+ private synchronized boolean isDirtyAndClear() { >+ boolean result = isDirty; >+ isDirty = false; >+ return result; >+ } >+ >+ private synchronized void makeDirty() { >+ isDirty = true; >+ } >+ >+ public synchronized List asList() { >+ List result = new ArrayList(); >+ result.addAll(asCollection()); >+ return result; >+ } >+ >+ public synchronized int size() { >+ return asCollection().size(); >+ } >+ >+ public synchronized void filter(IDocument document, int offset, >+ DocumentEvent event) { >+ FilteredProposalList temp = new FilteredProposalList(document, offset, event); >+ final Iterator itr = asCollection().iterator(); >+ proposalBag = temp; >+ while (itr.hasNext()) { >+ temp.maybeAdd((ICompletionProposal) itr.next()); >+ } >+ makeDirty(); >+ } >+ >+ public synchronized void resetAndFilter(IDocument document, int offset, >+ DocumentEvent event) { >+ proposalBag = new FilteredProposalList(originalProposals); >+ filter(document, offset, event); >+ } >+ >+ public Collection asCollection() { >+ return proposalBag.proposals; >+ } >+ } > > /** > * Hides the popup and returns <code>true</code> if the popup is configured >@@ -536,8 +766,7 @@ > */ > private void handleRepeatedInvocation() { > if (fContentAssistant.isRepeatedInvocationMode()) { >- fComputedProposals= computeProposals(fFilterOffset); >- setProposals(fComputedProposals, false); >+ computeProposals(fComputedProposals, fFilterOffset); > } > } > >@@ -548,10 +777,10 @@ > * @param offset the offset > * @return the completion proposals available at this offset > */ >- private ICompletionProposal[] computeProposals(int offset) { >+ private void computeProposals(ProposalList computedProposals, int offset) { > if (fContentAssistSubjectControl != null) >- return fContentAssistant.computeCompletionProposals(fContentAssistSubjectControl, offset); >- return fContentAssistant.computeCompletionProposals(fViewer, offset); >+ fContentAssistant.computeCompletionProposals(computedProposals, fContentAssistSubjectControl, offset); >+ fContentAssistant.computeCompletionProposals(computedProposals, fViewer, fSelectedRange, offset); > } > > /** >@@ -816,9 +1045,18 @@ > TableItem item= (TableItem) event.item; > int index= fProposalTable.indexOf(item); > >- if (0 <= index && index < fFilteredProposals.length) { >- ICompletionProposal current= fFilteredProposals[index]; >- >+ // TODO(doogle): This is an ugly hack to work around the fact that >+ // the ProposalBag is not an indexed collection. >+ // I iterate forward while counting the index back to >+ // zero. >+ final Collection proposals = fComputedProposals.asCollection(); >+ final Iterator itr = proposals.iterator(); >+ ICompletionProposal current = null; >+ while (itr.hasNext() && index >= 0) { >+ current = (ICompletionProposal) itr.next(); >+ index--; >+ } >+ if (current != null) { > String displayString; > StyleRange[] styleRanges= null; > if (fIsColoredLabelsSupportEnabled && current instanceof ICompletionProposalExtension6) { >@@ -857,9 +1095,9 @@ > return null; > > int i= fProposalTable.getSelectionIndex(); >- if (fFilteredProposals == null || i < 0 || i >= fFilteredProposals.length) >+ if (fFilteredProposals == null || i < 0 || i >= fFilteredProposals.size()) > return null; >- return fFilteredProposals[i]; >+ return (ICompletionProposal) fFilteredProposals.asList().get(i); > } > > /** >@@ -1061,8 +1299,14 @@ > fLastProposal= null; > } > >- fFilteredProposals= null; >- fComputedProposals= null; >+ if (fFilteredProposals != null) { >+ fFilteredProposals.dispose(); >+ fFilteredProposals = null; >+ } >+ if (fComputedProposals != null) { >+ fComputedProposals.dispose(); >+ fComputedProposals= null; >+ } > > fContentAssistant.possibleCompletionsClosed(); > } >@@ -1083,8 +1327,14 @@ > * not cleared, but the proposals that are not in the passed array > * are removed from the displayed set > */ >- private void setProposals(ICompletionProposal[] proposals, boolean isFilteredSubset) { >- ICompletionProposal[] oldProposals= fFilteredProposals; >+ private void setProposals(ProposalList proposals, boolean isFilteredSubset) { >+ // If the dialog has been closed, but threads are still processing, we need to make >+ // sure not to set the proposals on a disposed table. >+ if (fProposalTable.isDisposed()) { >+ return; >+ } >+ >+ ProposalList oldProposals= fFilteredProposals; > ICompletionProposal oldProposal= getSelectedProposal(); // may trigger filtering and a reentrant call to setProposals() > if (oldProposals != fFilteredProposals) // reentrant call was first - abort > return; >@@ -1092,15 +1342,15 @@ > if (Helper.okToUse(fProposalTable)) { > if (oldProposal instanceof ICompletionProposalExtension2 && fViewer != null) > ((ICompletionProposalExtension2) oldProposal).unselected(fViewer); >- >- if (proposals == null || proposals.length == 0) { >+ >+ if (proposals == null || proposals.size() == 0) { > fEmptyProposal.fOffset= fFilterOffset; > fEmptyProposal.fDisplayString= fEmptyMessage != null ? fEmptyMessage : JFaceTextMessages.getString("CompletionProposalPopup.no_proposals"); //$NON-NLS-1$ >- proposals= new ICompletionProposal[] { fEmptyProposal }; >+ proposals.add(fEmptyProposal); > } > > fFilteredProposals= proposals; >- final int newLen= proposals.length; >+ final int newLen= proposals.size(); > if (USE_VIRTUAL) { > fProposalTable.setItemCount(newLen); > fProposalTable.clearAll(); >@@ -1108,9 +1358,10 @@ > fProposalTable.setRedraw(false); > fProposalTable.setItemCount(newLen); > TableItem[] items= fProposalTable.getItems(); >- for (int i= 0; i < items.length; i++) { >+ final Iterator itr = proposals.asCollection().iterator(); >+ for (int i= 0; i < items.length && itr.hasNext(); i++) { >+ ICompletionProposal proposal= (ICompletionProposal) itr.next(); > TableItem item= items[i]; >- ICompletionProposal proposal= proposals[i]; > item.setText(proposal.getDisplayString()); > item.setImage(proposal.getImage()); > item.setData(proposal); >@@ -1337,12 +1588,16 @@ > if (oldProposal instanceof ICompletionProposalExtension2 && fViewer != null) > ((ICompletionProposalExtension2) oldProposal).unselected(fViewer); > >- if (fFilteredProposals == null) { >+ if (fComputedProposals == null) { > fireSelectionEvent(null, smartToggle); > return; > } >- >- ICompletionProposal proposal= fFilteredProposals[index]; >+ >+ List proposals = fComputedProposals.asList(); >+ if (proposals.size() == 0) { >+ return; >+ } >+ ICompletionProposal proposal= (ICompletionProposal) proposals.get(index); > if (proposal instanceof ICompletionProposalExtension2 && fViewer != null) > ((ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle); > >@@ -1408,74 +1663,6 @@ > } > > /** >- * Computes the subset of already computed proposals that are still valid for >- * the given offset. >- * >- * @param offset the offset >- * @param event the merged document event >- * @return the set of filtered proposals >- * @since 3.0 >- */ >- private ICompletionProposal[] computeFilteredProposals(int offset, DocumentEvent event) { >- >- if (offset == fInvocationOffset && event == null) { >- fIsFilteredSubset= false; >- return fComputedProposals; >- } >- >- if (offset < fInvocationOffset) { >- fIsFilteredSubset= false; >- fInvocationOffset= offset; >- fContentAssistant.fireSessionRestartEvent(); >- fComputedProposals= computeProposals(fInvocationOffset); >- return fComputedProposals; >- } >- >- ICompletionProposal[] proposals; >- if (offset < fFilterOffset) { >- proposals= fComputedProposals; >- fIsFilteredSubset= false; >- } else { >- proposals= fFilteredProposals; >- fIsFilteredSubset= true; >- } >- >- if (proposals == null) { >- fIsFilteredSubset= false; >- return null; >- } >- >- IDocument document= fContentAssistSubjectControlAdapter.getDocument(); >- int length= proposals.length; >- List filtered= new ArrayList(length); >- for (int i= 0; i < length; i++) { >- >- if (proposals[i] instanceof ICompletionProposalExtension2) { >- >- ICompletionProposalExtension2 p= (ICompletionProposalExtension2) proposals[i]; >- if (p.validate(document, offset, event)) >- filtered.add(p); >- >- } else if (proposals[i] instanceof ICompletionProposalExtension) { >- >- ICompletionProposalExtension p= (ICompletionProposalExtension) proposals[i]; >- if (p.isValidFor(document, offset)) >- filtered.add(p); >- >- } else { >- // restore original behavior >- fIsFilteredSubset= false; >- fInvocationOffset= offset; >- fContentAssistant.fireSessionRestartEvent(); >- fComputedProposals= computeProposals(fInvocationOffset); >- return fComputedProposals; >- } >- } >- >- return (ICompletionProposal[]) filtered.toArray(new ICompletionProposal[filtered.size()]); >- } >- >- /** > * Requests the proposal shell to take focus. > * > * @since 3.0 >@@ -1536,14 +1723,14 @@ > fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x; > fFilterOffset= fInvocationOffset; > fLastCompletionOffset= fFilterOffset; >- fFilteredProposals= computeProposals(fInvocationOffset); >+ computeProposals(fComputedProposals, fInvocationOffset); > >- int count= (fFilteredProposals == null ? 0 : fFilteredProposals.length); >+ int count= (fFilteredProposals == null ? 0 : fFilteredProposals.size()); > if (count == 0 && hideWhenNoProposals(false)) > return; >- >- if (count == 1 && canAutoInsert(fFilteredProposals[0])) { >- insertProposal(fFilteredProposals[0], (char) 0, 0, fInvocationOffset); >+ >+ if (count == 1 && canAutoInsert((ICompletionProposal) fFilteredProposals.asList().get(0))) { >+ insertProposal((ICompletionProposal) fFilteredProposals.asList().get(0), (char) 0, 0, fInvocationOffset); > hide(); > } else { > ensureDocumentListenerInstalled(); >@@ -1575,9 +1762,9 @@ > private boolean completeCommonPrefix() { > > // 0: insert single proposals >- if (fFilteredProposals.length == 1) { >- if (canAutoInsert(fFilteredProposals[0])) { >- insertProposal(fFilteredProposals[0], (char) 0, 0, fFilterOffset); >+ if (fFilteredProposals.size() == 1) { >+ if (canAutoInsert((ICompletionProposal) fFilteredProposals.asList().get(0))) { >+ insertProposal((ICompletionProposal) fFilteredProposals.asList().get(0), (char) 0, 0, fFilterOffset); > hide(); > return true; > } >@@ -1601,9 +1788,9 @@ > StringBuffer wrongCasePostfix= null; > List wrongCase= new ArrayList(); > >- for (int i= 0; i < fFilteredProposals.length; i++) { >- ICompletionProposal proposal= fFilteredProposals[i]; >- >+ for (int i= 0; i < fFilteredProposals.size(); i++) { >+ ICompletionProposal proposal= (ICompletionProposal) fFilteredProposals.asList().get(i); >+ > if (!(proposal instanceof ICompletionProposalExtension3)) > return false; > >@@ -1752,10 +1939,17 @@ > * @param message the new caption > * @since 3.2 > */ >- void setMessage(String message) { >+ void setMessage(final String message) { > Assert.isNotNull(message); >- if (isActive() && fMessageText != null) >- fMessageText.setText(message + " "); //$NON-NLS-1$ >+ if (isActive() && fMessageText != null) { >+ fMessageText.getDisplay().asyncExec(new Runnable() { >+ public void run() { >+ if (fMessageText != null) { >+ fMessageText.setText(message + " "); //$NON-NLS-1$ >+ } >+ } >+ }); >+ } > } > > /** >Index: src/org/eclipse/jface/text/contentassist/ProposalList.java >=================================================================== >RCS file: src/org/eclipse/jface/text/contentassist/ProposalList.java >diff -N src/org/eclipse/jface/text/contentassist/ProposalList.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/text/contentassist/ProposalList.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,75 @@ >+/** >+ * >+ */ >+package org.eclipse.jface.text.contentassist; >+ >+import java.util.Collection; >+import java.util.List; >+ >+import org.eclipse.jface.text.DocumentEvent; >+import org.eclipse.jface.text.IDocument; >+ >+// TODO(doogle): DOCUMENT. Also, remove unnecessary members. >+/** >+ * An abstraction on the list of proposals presented in the Content Assist >+ * popup. >+ * >+ * <p>A single instance of this class can be created, and then filtered upon. The >+ * current (filtered) list of proposals can be gotten by calling >+ * {@link #asCollection()} >+ */ >+public interface ProposalList { >+ >+ /** >+ * Adds a proposal to this list >+ */ >+ void add(ICompletionProposal proposal); >+ >+ /** >+ * Adds all the proposals to this list >+ */ >+ void addAll(Collection/* <ICompletionProposal> */arg); >+ >+ /** >+ * Futher filters the current list of proposals based on the given document, >+ * offset and event. This method does not handle moving the insertion point >+ * back (e.g. typing "delete"). To do that, use >+ * {@link #resetAndFilter(IDocument, int, DocumentEvent)}. >+ * >+ * <p>After calling this method, this list is guaranteed to either be the >+ * same or a subset of what it was before. >+ */ >+ //TODO: I think we can easily consolidate this method and the >+ // resetAndFilter. Do we want to? >+ void filter(IDocument document, int offset, DocumentEvent event); >+ >+ /** >+ * This resets the proposal list based on the original collection of >+ * proposals, and then applies a filter. >+ */ >+ void resetAndFilter(IDocument document, int offset, DocumentEvent event); >+ >+ /** >+ * Destroy any resources that need to be cleaned up. This method must be >+ * called by the user of this list before dropped the last reference to it. >+ */ >+ void dispose(); >+ >+ /** >+ * Returns the list of proposals as a Collection. This is the preferred way >+ * to get to the current list of filtered proposals. >+ */ >+ Collection asCollection(); >+ >+ /** >+ * @return the same contents as {@link #asCollection()}, but as a List >+ */ >+ // TODO(doogle): ideally, all the code that calls this could be changed to >+ // work against Collection. >+ List asList(); >+ >+ /** >+ * @return asCollection().size() >+ */ >+ int size(); >+} >Index: src/org/eclipse/jface/text/contentassist/IContentAssistProcessor2.java >=================================================================== >RCS file: src/org/eclipse/jface/text/contentassist/IContentAssistProcessor2.java >diff -N src/org/eclipse/jface/text/contentassist/IContentAssistProcessor2.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/text/contentassist/IContentAssistProcessor2.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,16 @@ >+package org.eclipse.jface.text.contentassist; >+ >+import java.util.Comparator; >+ >+import org.eclipse.jface.text.IDocument; >+import org.eclipse.swt.graphics.Point; >+ >+// TODO(doogle): DOCUMENT >+public interface IContentAssistProcessor2 extends IContentAssistProcessor { >+ >+ Comparator getComparator(); >+ >+ void computeCompletionProposals(ProposalList partial, >+ IDocument document, Point selectedRange, int offset); >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 251156
:
115426
|
115646
| 117154 |
119701