mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 01:15:29 +02:00
Fix for Bug 172723 - [Content Assist] Port DOMCompletionContributor to new extension point (patch by Bryan Wilkinson)
This commit is contained in:
parent
71355f9dc9
commit
4187ccb321
18 changed files with 546 additions and 909 deletions
|
@ -1320,7 +1320,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (LT(1) != IToken.tRPAREN)
|
||||
newInitializerExpressions = expression();
|
||||
|
||||
lastOffset = consume(IToken.tRPAREN).getEndOffset();
|
||||
if (LT(1) == IToken.tEOC) {
|
||||
lastOffset = consume().getEndOffset();
|
||||
} else {
|
||||
lastOffset = consume(IToken.tRPAREN).getEndOffset();
|
||||
}
|
||||
|
||||
if (templateIdScopes.size() > 0) {
|
||||
templateIdScopes.pop();
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ import org.eclipse.core.resources.IResource;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.text.contentassist.ContentAssistant;
|
||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||
import org.eclipse.jface.text.source.ISourceViewer;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
@ -43,13 +43,12 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
|
|||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
||||
import org.eclipse.cdt.ui.tests.text.EditorTestHelper;
|
||||
import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.CHelpProviderManager;
|
||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||
import org.eclipse.cdt.internal.ui.text.CHelpBookDescriptor;
|
||||
import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProcessor2;
|
||||
import org.eclipse.cdt.internal.ui.text.contentassist.CContentAssistProcessor;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -163,20 +162,20 @@ public class ContentAssistTests extends BaseUITestCase {
|
|||
fail("Failed to get working copy"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// call the CompletionProcessor
|
||||
// call the ContentAssistProcessor
|
||||
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||
FileEditorInput editorInput = new FileEditorInput(file);
|
||||
IEditorPart editorPart = page.openEditor(editorInput, "org.eclipse.cdt.ui.editor.CEditor");
|
||||
CEditor editor = (CEditor) editorPart ;
|
||||
IAction completionAction = editor.getAction("ContentAssistProposal");
|
||||
CCompletionProcessor2 completionProcessor = new CCompletionProcessor2(editorPart);
|
||||
ISourceViewer viewer= EditorTestHelper.getSourceViewer(editor);
|
||||
ICompletionProposal[] results = completionProcessor.computeCompletionProposals(viewer, offset); // (document, pos, wc, null);
|
||||
|
||||
return results ;
|
||||
String contentType = editor.getViewer().getDocument().getContentType(offset);
|
||||
ContentAssistant assistant = new ContentAssistant();
|
||||
CContentAssistProcessor processor = new CContentAssistProcessor(editor, assistant, contentType);
|
||||
return processor.computeCompletionProposals(editor.getViewer(), offset);
|
||||
}
|
||||
|
||||
public void _testBug69334() throws Exception {
|
||||
public void testBug69334() throws Exception {
|
||||
importFile( "test.h", "class Test{ public : Test( int ); }; \n" ); //$NON-NLS-1$//$NON-NLS-2$
|
||||
StringWriter writer = new StringWriter();
|
||||
writer.write( "#include \"test.h\" \n"); //$NON-NLS-1$
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Set;
|
|||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.jface.text.contentassist.ContentAssistant;
|
||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||
import org.eclipse.jface.text.source.ISourceViewer;
|
||||
import org.eclipse.jface.text.templates.TemplateProposal;
|
||||
|
@ -26,7 +27,6 @@ import org.eclipse.ui.texteditor.AbstractTextEditor;
|
|||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.parser.KeywordSetKey;
|
||||
import org.eclipse.cdt.core.parser.ParserFactory;
|
||||
|
@ -37,7 +37,7 @@ import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
|||
import org.eclipse.cdt.ui.tests.text.EditorTestHelper;
|
||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProcessor2;
|
||||
import org.eclipse.cdt.internal.ui.text.contentassist.CContentAssistProcessor;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -94,11 +94,13 @@ public abstract class AbstractCompletionTest extends BaseUITestCase {
|
|||
System.out.println("\n\n\n\n\nTesting "+this.getClass().getName());
|
||||
}
|
||||
|
||||
CCompletionProcessor2 completionProcessor = new CCompletionProcessor2(fEditor);
|
||||
// call the CompletionProcessor
|
||||
//Call the CContentAssistProcessor
|
||||
ISourceViewer sourceViewer= EditorTestHelper.getSourceViewer((AbstractTextEditor)fEditor);
|
||||
String contentType = sourceViewer.getDocument().getContentType(offset);
|
||||
ContentAssistant assistant = new ContentAssistant();
|
||||
CContentAssistProcessor processor = new CContentAssistProcessor(fEditor, assistant, contentType);
|
||||
long startTime= System.currentTimeMillis();
|
||||
ICompletionProposal[] results = completionProcessor.computeCompletionProposals(sourceViewer, offset);
|
||||
ICompletionProposal[] results = processor.computeCompletionProposals(sourceViewer, offset);
|
||||
long endTime= System.currentTimeMillis();
|
||||
assertTrue(results != null);
|
||||
|
||||
|
@ -107,8 +109,6 @@ public abstract class AbstractCompletionTest extends BaseUITestCase {
|
|||
Arrays.sort(expected);
|
||||
Arrays.sort(resultStrings);
|
||||
|
||||
checkCompletionNode(completionProcessor.getCurrentCompletionNode());
|
||||
|
||||
if (CTestPlugin.getDefault().isDebugging()) {
|
||||
System.out.println("Time (ms): " + (endTime-startTime));
|
||||
for (int i = 0; i < resultStrings.length; i++) {
|
||||
|
@ -147,15 +147,6 @@ public abstract class AbstractCompletionTest extends BaseUITestCase {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform additional checks on the ASTCompletionNode.
|
||||
*
|
||||
* @param currentCompletionNode
|
||||
*/
|
||||
protected void checkCompletionNode(ASTCompletionNode currentCompletionNode) {
|
||||
// no-op by default
|
||||
}
|
||||
|
||||
private String toString(String[] strings) {
|
||||
StringBuffer buf= new StringBuffer();
|
||||
for(int i=0; i< strings.length; i++){
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
|
||||
|
||||
public abstract class CompletionProposalsBaseTest extends AbstractCompletionTest {
|
||||
|
@ -95,15 +94,4 @@ public abstract class CompletionProposalsBaseTest extends AbstractCompletionTest
|
|||
assertCompletionResults(getCompletionPosition(), expected, false);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.cdt.ui.tests.text.contentassist2.AbstractCompletionTest#checkCompletionNode(org.eclipse.cdt.core.dom.ast.ASTCompletionNode)
|
||||
*/
|
||||
protected void checkCompletionNode(ASTCompletionNode currentCompletionNode) {
|
||||
assertNotNull("null completion node!", currentCompletionNode);
|
||||
// check the completion node
|
||||
String prefix = currentCompletionNode.getPrefix();
|
||||
assertEquals(getExpectedPrefix(), prefix);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Rational Software - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.ui.tests.text.contentassist2;
|
||||
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* @author hamer
|
||||
*
|
||||
* Testing Argument_Type completion kind , with No prefix
|
||||
* Bug#50642 : Wrong completion kind when declaring an argument type
|
||||
*
|
||||
*/
|
||||
public class CompletionTest_ArgumentType_NoPrefix extends CompletionProposalsBaseTest{
|
||||
private final String fileName = "CompletionTestStart17.cpp";
|
||||
private final String fileFullPath ="resources/contentassist/" + fileName;
|
||||
private final String headerFileName = "CompletionTestStart.h";
|
||||
private final String headerFileFullPath ="resources/contentassist/" + headerFileName;
|
||||
private final String expectedPrefix = "";
|
||||
private final String[] expectedResults = {
|
||||
"aClass",
|
||||
"anotherClass",
|
||||
"aNamespace",
|
||||
"anEnumeration",
|
||||
"AStruct",
|
||||
"xOtherClass",
|
||||
"xNamespace",
|
||||
"xEnumeration",
|
||||
"XStruct"
|
||||
};
|
||||
|
||||
public CompletionTest_ArgumentType_NoPrefix(String name) {
|
||||
super(name);
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=169860
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite= new TestSuite(CompletionTest_ArgumentType_NoPrefix.class.getName());
|
||||
suite.addTest(new CompletionTest_ArgumentType_NoPrefix("testCompletionProposals"));
|
||||
return suite;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getCompletionPosition()
|
||||
*/
|
||||
protected int getCompletionPosition() {
|
||||
return getBuffer().indexOf(" ") + 2;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedPrefix()
|
||||
*/
|
||||
protected String getExpectedPrefix() {
|
||||
return expectedPrefix;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedResultsValues()
|
||||
*/
|
||||
protected String[] getExpectedResultsValues() {
|
||||
return expectedResults;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileName()
|
||||
*/
|
||||
protected String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileFullPath()
|
||||
*/
|
||||
protected String getFileFullPath() {
|
||||
return fileFullPath;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileFullPath()
|
||||
*/
|
||||
protected String getHeaderFileFullPath() {
|
||||
return headerFileFullPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileName()
|
||||
*/
|
||||
protected String getHeaderFileName() {
|
||||
return headerFileName;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Rational Software - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.ui.tests.text.contentassist2;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* @author hamer
|
||||
*
|
||||
* Testing Argument_Type completion kind , with No prefix
|
||||
* Bug#50642 : Wrong completion kind when declaring an argument type
|
||||
*
|
||||
*/
|
||||
public class CompletionTest_ArgumentType_NoPrefix2 extends CompletionProposalsBaseTest{
|
||||
private final String fileName = "CompletionTestStart19.cpp";
|
||||
private final String fileFullPath ="resources/contentassist/" + fileName;
|
||||
private final String headerFileName = "CompletionTestStart.h";
|
||||
private final String headerFileFullPath ="resources/contentassist/" + headerFileName;
|
||||
private final String expectedPrefix = "";
|
||||
private final String[] expectedResults = {
|
||||
"aClass",
|
||||
"anotherClass",
|
||||
"aNamespace",
|
||||
"anEnumeration",
|
||||
"AStruct",
|
||||
"xOtherClass",
|
||||
"xNamespace",
|
||||
"xEnumeration",
|
||||
"XStruct",
|
||||
"ClassA"
|
||||
};
|
||||
|
||||
public CompletionTest_ArgumentType_NoPrefix2(String name) {
|
||||
super(name);
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=169860
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite= new TestSuite(CompletionTest_ArgumentType_NoPrefix2.class.getName());
|
||||
suite.addTest(new CompletionTest_ArgumentType_NoPrefix2("testCompletionProposals"));
|
||||
return suite;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getCompletionPosition()
|
||||
*/
|
||||
protected int getCompletionPosition() {
|
||||
return getBuffer().indexOf(" ") + 2;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedPrefix()
|
||||
*/
|
||||
protected String getExpectedPrefix() {
|
||||
return expectedPrefix;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedResultsValues()
|
||||
*/
|
||||
protected String[] getExpectedResultsValues() {
|
||||
return expectedResults;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileName()
|
||||
*/
|
||||
protected String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileFullPath()
|
||||
*/
|
||||
protected String getFileFullPath() {
|
||||
return fileFullPath;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileFullPath()
|
||||
*/
|
||||
protected String getHeaderFileFullPath() {
|
||||
return headerFileFullPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileName()
|
||||
*/
|
||||
protected String getHeaderFileName() {
|
||||
return headerFileName;
|
||||
}
|
||||
|
||||
}
|
|
@ -26,8 +26,6 @@ public class ContentAssist2TestSuite extends TestSuite {
|
|||
super("Tests in package org.eclipse.cdt.ui.tests.text.contentassist2");
|
||||
|
||||
addTest(CompletionTest_MemberReference_Arrow_Prefix2.suite());
|
||||
addTest(CompletionTest_ArgumentType_NoPrefix.suite());
|
||||
addTest(CompletionTest_ArgumentType_NoPrefix2.suite());
|
||||
addTest(CompletionTest_ArgumentType_Prefix.suite());
|
||||
addTest(CompletionTest_ArgumentType_Prefix2.suite());
|
||||
addTest(CompletionTest_ClassReference_NoPrefix.suite());
|
||||
|
|
|
@ -1478,10 +1478,6 @@
|
|||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.ui.completionContributors">
|
||||
<contributor
|
||||
class="org.eclipse.cdt.internal.ui.text.contentassist.DOMCompletionContributor"
|
||||
id="DOM"
|
||||
priority="1"/>
|
||||
<contributor
|
||||
class="org.eclipse.cdt.internal.ui.text.contentassist.KeywordCompletionContributor"
|
||||
id="Keywords"
|
||||
|
@ -1523,6 +1519,20 @@
|
|||
<proposalCategory
|
||||
icon="$nl$/icons/elcl16/wordassist_co.gif"/>
|
||||
</extension>
|
||||
<extension
|
||||
id="DOMCompletionProposalComputer"
|
||||
point="org.eclipse.cdt.ui.completionProposalComputer">
|
||||
<completionProposalComputer
|
||||
categoryId="org.eclipse.cdt.ui.parserProposalCategory"
|
||||
class="org.eclipse.cdt.internal.ui.text.contentassist.DOMCompletionProposalComputer">
|
||||
<partition
|
||||
type="__dftl_partition_content_type">
|
||||
</partition>
|
||||
<partition
|
||||
type="__c_preprocessor">
|
||||
</partition>
|
||||
</completionProposalComputer>
|
||||
</extension>
|
||||
|
||||
<!-- legacy completions (completionContributors) -->
|
||||
<extension
|
||||
|
@ -1808,4 +1818,5 @@
|
|||
class="org.eclipse.cdt.internal.ui.navigator.CNavigatorDragAdapterAssistant"
|
||||
viewerId="org.eclipse.ui.navigator.ProjectExplorer"/>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.InvalidRegistryObjectException;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformation;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
||||
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.CUIMessages;
|
||||
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
|
||||
import org.eclipse.cdt.internal.ui.text.CParameterListValidator;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class CCompletionProcessor2 implements IContentAssistProcessor {
|
||||
|
||||
private IEditorPart editor;
|
||||
private String errorMessage;
|
||||
|
||||
private char[] autoActivationChars;
|
||||
|
||||
// Property names
|
||||
private String assistPrefix = "CEditor.contentassist"; //$NON-NLS-1$
|
||||
private String noCompletions = assistPrefix + ".noCompletions"; //$NON-NLS-1$
|
||||
private ASTCompletionNode fCurrentCompletionNode;
|
||||
|
||||
public CCompletionProcessor2(IEditorPart editor) {
|
||||
this.editor = editor;
|
||||
fCurrentCompletionNode = null;
|
||||
}
|
||||
|
||||
public ICompletionProposal[] computeCompletionProposals(final ITextViewer viewer, int offset) {
|
||||
try {
|
||||
IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
|
||||
IIndex index = CCorePlugin.getIndexManager().getIndex(workingCopy.getCProject(),
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
|
||||
|
||||
try {
|
||||
index.acquireReadLock();
|
||||
} catch (InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String prefix = null;
|
||||
|
||||
if (workingCopy != null) {
|
||||
IPDOMManager manager = CCorePlugin.getPDOMManager();
|
||||
String indexerId = manager.getIndexerId(workingCopy.getCProject());
|
||||
int flags = ITranslationUnit.AST_SKIP_ALL_HEADERS;
|
||||
if (IPDOMManager.ID_NO_INDEXER.equals(indexerId)) {
|
||||
flags = 0;
|
||||
}
|
||||
fCurrentCompletionNode = workingCopy.getCompletionNode(index, flags, offset);
|
||||
|
||||
if (fCurrentCompletionNode != null)
|
||||
prefix = fCurrentCompletionNode.getPrefix();
|
||||
}
|
||||
|
||||
if (prefix == null)
|
||||
prefix = scanPrefix(viewer.getDocument(), offset);
|
||||
|
||||
errorMessage = CUIMessages.getString(noCompletions);
|
||||
|
||||
List proposals = new ArrayList();
|
||||
|
||||
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CUIPlugin.PLUGIN_ID, "completionContributors"); //$NON-NLS-1$
|
||||
if (point == null)
|
||||
return null;
|
||||
IExtension[] extensions = point.getExtensions();
|
||||
for (int i = 0; i < extensions.length; ++i) {
|
||||
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
|
||||
for (int j = 0; j < elements.length; ++j) {
|
||||
IConfigurationElement element = elements[j];
|
||||
if (!"contributor".equals(element.getName())) //$NON-NLS-1$
|
||||
continue;
|
||||
Object contribObject = element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
if (!(contribObject instanceof ICompletionContributor))
|
||||
continue;
|
||||
ICompletionContributor contributor = (ICompletionContributor)contribObject;
|
||||
contributor.contributeCompletionProposals(viewer, offset, workingCopy, fCurrentCompletionNode, prefix, proposals);
|
||||
}
|
||||
}
|
||||
|
||||
IProposalFilter filter = getCompletionFilter();
|
||||
ICCompletionProposal[] proposalsInput = (ICCompletionProposal[]) proposals.toArray(new ICCompletionProposal[proposals.size()]) ;
|
||||
ICCompletionProposal[] proposalsFiltered = filter.filterProposals(proposalsInput);
|
||||
|
||||
return proposalsFiltered;
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
errorMessage = e.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IProposalFilter getCompletionFilter() {
|
||||
IProposalFilter filter = null;
|
||||
try {
|
||||
IConfigurationElement filterElement = ProposalFilterPreferencesUtil.getPreferredFilterElement();
|
||||
if (null != filterElement) {
|
||||
Object contribObject = filterElement
|
||||
.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
if ((contribObject instanceof IProposalFilter)) {
|
||||
filter = (IProposalFilter) contribObject;
|
||||
}
|
||||
}
|
||||
} catch (InvalidRegistryObjectException e) {
|
||||
// No action required since we will be using the fail-safe default filter
|
||||
CUIPlugin.getDefault().log(e);
|
||||
} catch (CoreException e) {
|
||||
// No action required since we will be using the fail-safe default filter
|
||||
CUIPlugin.getDefault().log(e);
|
||||
}
|
||||
|
||||
if (null == filter) {
|
||||
// fail-safe default implementation
|
||||
filter = new DefaultProposalFilter();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
private String scanPrefix(IDocument document, int end) {
|
||||
try {
|
||||
int start = end;
|
||||
while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
|
||||
start--;
|
||||
|
||||
if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1)))
|
||||
start--;
|
||||
|
||||
return document.get(start, end - start);
|
||||
} catch (BadLocationException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IContextInformation[] computeContextInformation(ITextViewer viewer,
|
||||
int offset) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public char[] getCompletionProposalAutoActivationCharacters() {
|
||||
return autoActivationChars;
|
||||
}
|
||||
|
||||
public void setCompletionProposalAutoActivationCharacters(char[] autoActivationChars) {
|
||||
this.autoActivationChars = autoActivationChars;
|
||||
}
|
||||
|
||||
public char[] getContextInformationAutoActivationCharacters() {
|
||||
return null; // none
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public IContextInformationValidator getContextInformationValidator() {
|
||||
return new CParameterListValidator();
|
||||
}
|
||||
|
||||
public void orderProposalsAlphabetically(boolean order) {
|
||||
}
|
||||
|
||||
public void allowAddingIncludes(boolean allowAddingIncludes) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fCurrentCompletionNode
|
||||
*/
|
||||
public ASTCompletionNode getCurrentCompletionNode() {
|
||||
return fCurrentCompletionNode;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2006 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -667,29 +667,20 @@ public class CCompletionProposal implements ICCompletionProposal, ICompletionPro
|
|||
setReplacementLength(length);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return fDisplayString.hashCode()
|
||||
+ fReplacementString.hashCode()
|
||||
+ ((fContextInformation == null) ? 0 : fContextInformation.hashCode());
|
||||
return fIdString.hashCode();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
|
||||
/*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if(!(other instanceof CCompletionProposal))
|
||||
if(!(other instanceof ICCompletionProposal))
|
||||
return false;
|
||||
if(!(fDisplayString.equals(((CCompletionProposal)other).fDisplayString)))
|
||||
return false;
|
||||
if(!(fReplacementString.equals(((CCompletionProposal)other).fReplacementString)))
|
||||
return false;
|
||||
if((fContextInformation != null) && (((CCompletionProposal)other).fContextInformation != null) && (!(fContextInformation.equals(((CCompletionProposal)other).fContextInformation))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return fIdString.equalsIgnoreCase(((ICCompletionProposal)other).getIdString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -8,18 +8,28 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
|
||||
import org.eclipse.cdt.internal.ui.text.Symbols;
|
||||
|
||||
|
||||
/**
|
||||
* Describes the context of a content assist invocation in a C/C++ editor.
|
||||
|
@ -32,9 +42,16 @@ import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
|||
public class CContentAssistInvocationContext extends ContentAssistInvocationContext {
|
||||
|
||||
private final IEditorPart fEditor;
|
||||
private final boolean fIsCompletion;
|
||||
|
||||
private ITranslationUnit fTU= null;
|
||||
private boolean fTUComputed= false;
|
||||
|
||||
private int fParseOffset= -1;
|
||||
private boolean fParseOffsetComputed= false;
|
||||
private ASTCompletionNode fCN= null;
|
||||
private boolean fCNComputed= false;
|
||||
private IIndex fIndex = null;
|
||||
|
||||
/**
|
||||
* Creates a new context.
|
||||
*
|
||||
|
@ -42,10 +59,11 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
* @param offset the invocation offset
|
||||
* @param editor the editor that content assist is invoked in
|
||||
*/
|
||||
public CContentAssistInvocationContext(ITextViewer viewer, int offset, IEditorPart editor) {
|
||||
public CContentAssistInvocationContext(ITextViewer viewer, int offset, IEditorPart editor, boolean isCompletion) {
|
||||
super(viewer, offset);
|
||||
Assert.isNotNull(editor);
|
||||
fEditor= editor;
|
||||
fIsCompletion= isCompletion;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,11 +71,12 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
*
|
||||
* @param unit the translation unit in <code>document</code>
|
||||
*/
|
||||
public CContentAssistInvocationContext(ITranslationUnit unit) {
|
||||
public CContentAssistInvocationContext(ITranslationUnit unit, boolean isCompletion) {
|
||||
super();
|
||||
fTU= unit;
|
||||
fTUComputed= true;
|
||||
fEditor= null;
|
||||
fIsCompletion= isCompletion;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,6 +103,111 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
ITranslationUnit unit= getTranslationUnit();
|
||||
return unit == null ? null : unit.getCProject();
|
||||
}
|
||||
|
||||
public ASTCompletionNode getCompletionNode() {
|
||||
if (fCNComputed) return fCN;
|
||||
|
||||
fCNComputed = true;
|
||||
|
||||
ICProject proj= getProject();
|
||||
if (proj == null) return null;
|
||||
|
||||
try{
|
||||
fIndex = CCorePlugin.getIndexManager().getIndex(proj,
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
|
||||
|
||||
try {
|
||||
fIndex.acquireReadLock();
|
||||
} catch (InterruptedException e) {
|
||||
fIndex = null;
|
||||
}
|
||||
|
||||
IPDOMManager manager = CCorePlugin.getPDOMManager();
|
||||
String indexerId = manager.getIndexerId(proj);
|
||||
int flags = ITranslationUnit.AST_SKIP_ALL_HEADERS;
|
||||
if (fIndex == null || IPDOMManager.ID_NO_INDEXER.equals(indexerId)) {
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
fCN = fTU.getCompletionNode(fIndex, flags, getParseOffset());
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
|
||||
return fCN;
|
||||
}
|
||||
|
||||
public int getParseOffset() {
|
||||
if (!fParseOffsetComputed) {
|
||||
fParseOffsetComputed= true;
|
||||
if (fIsCompletion) {
|
||||
fParseOffset = guessCompletionPosition();
|
||||
} else {
|
||||
fParseOffset = guessContextInformationPosition();
|
||||
}
|
||||
}
|
||||
|
||||
return fParseOffset;
|
||||
}
|
||||
|
||||
protected int guessCompletionPosition() {
|
||||
final int contextPosition= getInvocationOffset();
|
||||
|
||||
CHeuristicScanner scanner= new CHeuristicScanner(getDocument());
|
||||
int bound= Math.max(-1, contextPosition - 200);
|
||||
|
||||
int pos= scanner.findNonWhitespaceBackward(contextPosition - 1, bound);
|
||||
if (pos == CHeuristicScanner.NOT_FOUND) return contextPosition;
|
||||
|
||||
int token= scanner.previousToken(pos, bound);
|
||||
|
||||
if (token == Symbols.TokenCOMMA) {
|
||||
pos= scanner.findOpeningPeer(pos, bound, '(', ')');
|
||||
if (pos == CHeuristicScanner.NOT_FOUND) return contextPosition;
|
||||
|
||||
token = scanner.previousToken(pos, bound);
|
||||
}
|
||||
|
||||
if (token == Symbols.TokenLPAREN) {
|
||||
pos= scanner.findNonWhitespaceBackward(pos - 1, bound);
|
||||
if (pos == CHeuristicScanner.NOT_FOUND) return contextPosition;
|
||||
|
||||
token= scanner.previousToken(pos, bound);
|
||||
|
||||
if (token == Symbols.TokenIDENT || token == Symbols.TokenGREATERTHAN) {
|
||||
return pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return contextPosition;
|
||||
}
|
||||
|
||||
protected int guessContextInformationPosition() {
|
||||
final int contextPosition= getInvocationOffset();
|
||||
|
||||
CHeuristicScanner scanner= new CHeuristicScanner(getDocument());
|
||||
int bound= Math.max(-1, contextPosition - 200);
|
||||
|
||||
// try the innermost scope of parentheses that looks like a method call
|
||||
int pos= contextPosition - 1;
|
||||
do {
|
||||
int paren= scanner.findOpeningPeer(pos, bound, '(', ')');
|
||||
if (paren == CHeuristicScanner.NOT_FOUND)
|
||||
break;
|
||||
paren= scanner.findNonWhitespaceBackward(paren - 1, bound);
|
||||
if (paren == CHeuristicScanner.NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
int token= scanner.previousToken(paren, bound);
|
||||
// next token must be a method name (identifier) or the closing angle of a
|
||||
// constructor call of a template type.
|
||||
if (token == Symbols.TokenIDENT || token == Symbols.TokenGREATERTHAN) {
|
||||
return paren + 1;
|
||||
}
|
||||
pos= paren;
|
||||
} while (true);
|
||||
|
||||
return contextPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the editor content assist is invoked in.
|
||||
|
@ -93,4 +217,15 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
public IEditorPart getEditor() {
|
||||
return fEditor;
|
||||
}
|
||||
|
||||
public boolean isContextInformationStyle() {
|
||||
return !fIsCompletion || (getParseOffset() != getInvocationOffset());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (fIndex != null) {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,19 +8,28 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.InvalidRegistryObjectException;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.jface.text.contentassist.ContentAssistant;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
||||
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
|
||||
import org.eclipse.cdt.internal.ui.text.CParameterListValidator;
|
||||
|
||||
/**
|
||||
|
@ -50,14 +59,49 @@ public class CContentAssistProcessor extends ContentAssistProcessor {
|
|||
* @see org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistProcessor#filterAndSort(java.util.List, org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
protected List filterAndSortProposals(List proposals, IProgressMonitor monitor, ContentAssistInvocationContext context) {
|
||||
return proposals;
|
||||
IProposalFilter filter = getCompletionFilter();
|
||||
ICCompletionProposal[] proposalsInput = (ICCompletionProposal[]) proposals.toArray(new ICCompletionProposal[proposals.size()]) ;
|
||||
ICCompletionProposal[] proposalsFiltered = filter.filterProposals(proposalsInput);
|
||||
|
||||
return Arrays.asList(proposalsFiltered);
|
||||
}
|
||||
|
||||
private IProposalFilter getCompletionFilter() {
|
||||
IProposalFilter filter = null;
|
||||
try {
|
||||
IConfigurationElement filterElement = ProposalFilterPreferencesUtil.getPreferredFilterElement();
|
||||
if (null != filterElement) {
|
||||
Object contribObject = filterElement
|
||||
.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
if ((contribObject instanceof IProposalFilter)) {
|
||||
filter = (IProposalFilter) contribObject;
|
||||
}
|
||||
}
|
||||
} catch (InvalidRegistryObjectException e) {
|
||||
// No action required since we will be using the fail-safe default filter
|
||||
CUIPlugin.getDefault().log(e);
|
||||
} catch (CoreException e) {
|
||||
// No action required since we will be using the fail-safe default filter
|
||||
CUIPlugin.getDefault().log(e);
|
||||
}
|
||||
|
||||
if (null == filter) {
|
||||
// fail-safe default implementation
|
||||
filter = new DefaultProposalFilter();
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
protected List filterAndSortContextInformation(List contexts,
|
||||
IProgressMonitor monitor) {
|
||||
return contexts;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistProcessor#createContext(org.eclipse.jface.text.ITextViewer, int)
|
||||
*/
|
||||
protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset) {
|
||||
return new CContentAssistInvocationContext(viewer, offset, fEditor);
|
||||
protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset, boolean isCompletion) {
|
||||
return new CContentAssistInvocationContext(viewer, offset, fEditor, isCompletion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
|
@ -206,29 +207,34 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
IProgressMonitor monitor= createProgressMonitor();
|
||||
monitor.beginTask(ContentAssistMessages.ContentAssistProcessor_computing_proposals, fCategories.size() + 1);
|
||||
|
||||
ContentAssistInvocationContext context= createContext(viewer, offset);
|
||||
long setup= DEBUG ? System.currentTimeMillis() : 0;
|
||||
ContentAssistInvocationContext context= createContext(viewer, offset, true);
|
||||
|
||||
monitor.subTask(ContentAssistMessages.ContentAssistProcessor_collecting_proposals);
|
||||
List proposals= collectProposals(viewer, offset, monitor, context);
|
||||
long collect= DEBUG ? System.currentTimeMillis() : 0;
|
||||
try {
|
||||
long setup= DEBUG ? System.currentTimeMillis() : 0;
|
||||
|
||||
monitor.subTask(ContentAssistMessages.ContentAssistProcessor_collecting_proposals);
|
||||
List proposals= collectProposals(viewer, offset, monitor, context);
|
||||
long collect= DEBUG ? System.currentTimeMillis() : 0;
|
||||
|
||||
monitor.subTask(ContentAssistMessages.ContentAssistProcessor_sorting_proposals);
|
||||
List filtered= filterAndSortProposals(proposals, monitor, context);
|
||||
fNumberOfComputedResults= filtered.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 (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$
|
||||
monitor.subTask(ContentAssistMessages.ContentAssistProcessor_sorting_proposals);
|
||||
List filtered= filterAndSortProposals(proposals, monitor, context);
|
||||
fNumberOfComputedResults= filtered.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 (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;
|
||||
} finally {
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void clearState() {
|
||||
|
@ -288,18 +294,22 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
|
||||
private List collectContextInformation(ITextViewer viewer, int offset, IProgressMonitor monitor) {
|
||||
List proposals= new ArrayList();
|
||||
ContentAssistInvocationContext context= createContext(viewer, offset);
|
||||
ContentAssistInvocationContext context= createContext(viewer, offset, false);
|
||||
|
||||
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));
|
||||
proposals.addAll(computed);
|
||||
if (fErrorMessage == null)
|
||||
fErrorMessage= cat.getErrorMessage();
|
||||
try {
|
||||
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));
|
||||
proposals.addAll(computed);
|
||||
if (fErrorMessage == null)
|
||||
fErrorMessage= cat.getErrorMessage();
|
||||
}
|
||||
|
||||
return proposals;
|
||||
} finally {
|
||||
context.dispose();
|
||||
}
|
||||
|
||||
return proposals;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -381,7 +391,7 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
|||
* @param offset the content assist offset
|
||||
* @return the context to be passed to the computers
|
||||
*/
|
||||
protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset) {
|
||||
protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset, boolean isCompletion) {
|
||||
return new ContentAssistInvocationContext(viewer, offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||
* Copyright (c) 2007 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.resource.ImageDescriptor;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.jface.text.TextUtilities;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
|
||||
|
@ -45,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
|
|||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||
|
@ -52,36 +50,41 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
||||
|
||||
public class DOMCompletionContributor implements ICompletionContributor {
|
||||
/**
|
||||
* Searches the DOM (both the AST and the index) for completion proposals.
|
||||
*
|
||||
* @author Bryan Wilkinson
|
||||
*/
|
||||
public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer {
|
||||
|
||||
public void contributeCompletionProposals(ITextViewer viewer,
|
||||
int offset,
|
||||
IWorkingCopy workingCopy,
|
||||
ASTCompletionNode completionNode,
|
||||
String prefix,
|
||||
List proposals) {
|
||||
/**
|
||||
* Default constructor is required (executable extension).
|
||||
*/
|
||||
public DOMCompletionProposalComputer() {
|
||||
}
|
||||
|
||||
protected List computeCompletionProposals(
|
||||
CContentAssistInvocationContext context,
|
||||
ASTCompletionNode completionNode, String prefix) {
|
||||
|
||||
List proposals = new ArrayList();
|
||||
|
||||
if (completionNode == null) {
|
||||
return;
|
||||
}
|
||||
if(inPreprocessorDirective(viewer.getDocument(), offset)) {
|
||||
if(inPreprocessorDirective(context)) {
|
||||
// add only macros
|
||||
addMacroProposals(viewer, offset, completionNode, prefix, proposals);
|
||||
addMacroProposals(context, prefix, proposals);
|
||||
} else {
|
||||
boolean handleMacros= false;
|
||||
IASTName[] names = completionNode.getNames();
|
||||
if (names == null || names.length == 0)
|
||||
// No names, not much we can do here
|
||||
return;
|
||||
return Collections.EMPTY_LIST;
|
||||
|
||||
// Find all bindings
|
||||
List allBindings = new ArrayList();
|
||||
|
@ -107,28 +110,15 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
|||
Iterator iBinding = allBindings.iterator();
|
||||
while (iBinding.hasNext()) {
|
||||
IBinding binding = (IBinding)iBinding.next();
|
||||
handleBinding(binding, completionNode, offset, viewer, proposals);
|
||||
handleBinding(binding, context, proposals);
|
||||
}
|
||||
|
||||
if (handleMacros) {
|
||||
addMacroProposals(viewer, offset, completionNode, prefix, proposals);
|
||||
addMacroProposals(context, prefix, proposals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addMacroProposals(ITextViewer viewer, int offset,
|
||||
ASTCompletionNode completionNode, String prefix, List proposals) {
|
||||
char[] prefixChars= prefix.toCharArray();
|
||||
IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions();
|
||||
if (macros != null)
|
||||
for (int i = 0; i < macros.length; ++i)
|
||||
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefixChars.length, prefixChars, false))
|
||||
handleMacro(macros[i], completionNode, offset, viewer, proposals);
|
||||
macros = completionNode.getTranslationUnit().getBuiltinMacroDefinitions();
|
||||
if (macros != null)
|
||||
for (int i = 0; i < macros.length; ++i)
|
||||
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefixChars.length, prefixChars, false))
|
||||
handleMacro(macros[i], completionNode, offset, viewer, proposals);
|
||||
|
||||
return proposals;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +128,10 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
|||
* @param offset the offset to check
|
||||
* @return <code>true</code> if offset is inside a preprocessor directive
|
||||
*/
|
||||
private boolean inPreprocessorDirective(IDocument doc, int offset) {
|
||||
private boolean inPreprocessorDirective(CContentAssistInvocationContext context) {
|
||||
IDocument doc = context.getViewer().getDocument();
|
||||
int offset = context.getParseOffset();
|
||||
|
||||
if (offset > 0 && offset == doc.getLength()) {
|
||||
--offset;
|
||||
}
|
||||
|
@ -150,17 +143,94 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void handleBinding(IBinding binding, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
||||
if (binding instanceof IFunction) {
|
||||
handleFunction((IFunction)binding, completionNode, offset, viewer, proposals);
|
||||
} else if (binding instanceof IVariable) {
|
||||
handleVariable((IVariable) binding, completionNode, offset, viewer, proposals);
|
||||
}
|
||||
else
|
||||
proposals.add(createProposal(binding.getName(), binding.getName(), getImage(binding), completionNode, offset, viewer));
|
||||
private void addMacroProposals(CContentAssistInvocationContext context, String prefix, List proposals) {
|
||||
char[] prefixChars= prefix.toCharArray();
|
||||
ASTCompletionNode completionNode = context.getCompletionNode();
|
||||
IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions();
|
||||
if (macros != null)
|
||||
for (int i = 0; i < macros.length; ++i)
|
||||
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefixChars.length, prefixChars, false))
|
||||
handleMacro(macros[i], context, proposals);
|
||||
macros = completionNode.getTranslationUnit().getBuiltinMacroDefinitions();
|
||||
if (macros != null)
|
||||
for (int i = 0; i < macros.length; ++i)
|
||||
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefixChars.length, prefixChars, false))
|
||||
handleMacro(macros[i], context, proposals);
|
||||
}
|
||||
|
||||
private void handleFunction(IFunction function, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
||||
private void handleMacro(IASTPreprocessorMacroDefinition macro, CContentAssistInvocationContext context, List proposals) {
|
||||
String macroName = macro.getName().toString();
|
||||
Image image = getImage(CElementImageProvider.getMacroImageDescriptor());
|
||||
|
||||
if (macro instanceof IASTPreprocessorFunctionStyleMacroDefinition) {
|
||||
IASTPreprocessorFunctionStyleMacroDefinition functionMacro = (IASTPreprocessorFunctionStyleMacroDefinition)macro;
|
||||
|
||||
StringBuffer repStringBuff = new StringBuffer();
|
||||
repStringBuff.append(macroName);
|
||||
repStringBuff.append('(');
|
||||
|
||||
StringBuffer args = new StringBuffer();
|
||||
|
||||
IASTFunctionStyleMacroParameter[] params = functionMacro.getParameters();
|
||||
if (params != null)
|
||||
for (int i = 0; i < params.length; ++i) {
|
||||
if (i > 0)
|
||||
args.append(", "); //$NON-NLS-1$
|
||||
args.append(params[i].getParameter());
|
||||
}
|
||||
String argString = args.toString();
|
||||
|
||||
StringBuffer descStringBuff = new StringBuffer(repStringBuff.toString());
|
||||
descStringBuff.append(argString);
|
||||
descStringBuff.append(')');
|
||||
|
||||
repStringBuff.append(')');
|
||||
String repString = repStringBuff.toString();
|
||||
String descString = descStringBuff.toString();
|
||||
|
||||
CCompletionProposal proposal = createProposal(repString, descString, image, context);
|
||||
if (!context.isContextInformationStyle()) {
|
||||
proposal.setCursorPosition(repString.length() - 1);
|
||||
}
|
||||
|
||||
if (argString.length() > 0) {
|
||||
CProposalContextInformation info = new CProposalContextInformation(image, descString, argString);
|
||||
info.setContextInformationPosition(context.getParseOffset());
|
||||
proposal.setContextInformation(info);
|
||||
}
|
||||
|
||||
proposals.add(proposal);
|
||||
} else
|
||||
proposals.add(createProposal(macroName, macroName, image, context));
|
||||
}
|
||||
|
||||
protected void handleBinding(IBinding binding, CContentAssistInvocationContext context, List proposals) {
|
||||
if (binding instanceof ICPPClassType) {
|
||||
handleClass((ICPPClassType) binding, context, proposals);
|
||||
} else if (binding instanceof IFunction) {
|
||||
handleFunction((IFunction)binding, context, proposals);
|
||||
} else if (binding instanceof IVariable) {
|
||||
handleVariable((IVariable) binding, context, proposals);
|
||||
} else {
|
||||
proposals.add(createProposal(binding.getName(), binding.getName(), getImage(binding), context));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleClass(ICPPClassType classType, CContentAssistInvocationContext context, List proposals) {
|
||||
if (context.isContextInformationStyle()) {
|
||||
try {
|
||||
ICPPConstructor[] constructors = classType.getConstructors();
|
||||
for (int i = 0; i < constructors.length; i++) {
|
||||
handleFunction(constructors[i], context, proposals);
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
} else {
|
||||
proposals.add(createProposal(classType.getName(), classType.getName(), getImage(classType), context));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFunction(IFunction function, CContentAssistInvocationContext context, List proposals) {
|
||||
Image image = getImage(function);
|
||||
|
||||
StringBuffer repStringBuff = new StringBuffer();
|
||||
|
@ -230,22 +300,21 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
|||
repStringBuff.append(')');
|
||||
String repString = repStringBuff.toString();
|
||||
|
||||
int repLength = completionNode.getLength();
|
||||
int repOffset = offset - repLength;
|
||||
CCompletionProposal proposal = new CCompletionProposal(repString, repOffset, repLength, image, dispString, idString, 1, viewer);
|
||||
|
||||
proposal.setCursorPosition(repString.length() - 1);
|
||||
CCompletionProposal proposal = createProposal(repString, dispString, idString, image, context);
|
||||
if (!context.isContextInformationStyle()) {
|
||||
proposal.setCursorPosition(repString.length() - 1);
|
||||
}
|
||||
|
||||
if (dispargString.length() > 0) {
|
||||
CProposalContextInformation info = new CProposalContextInformation(image, dispString, dispargString);
|
||||
info.setContextInformationPosition(offset);
|
||||
info.setContextInformationPosition(context.getParseOffset());
|
||||
proposal.setContextInformation(info);
|
||||
}
|
||||
|
||||
proposals.add(proposal);
|
||||
}
|
||||
|
||||
private void handleVariable(IVariable variable, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
||||
private void handleVariable(IVariable variable, CContentAssistInvocationContext context, List proposals) {
|
||||
StringBuffer repStringBuff = new StringBuffer();
|
||||
repStringBuff.append(variable.getName());
|
||||
|
||||
|
@ -269,61 +338,25 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
|||
|
||||
String repString = repStringBuff.toString();
|
||||
|
||||
int repLength = completionNode.getLength();
|
||||
int repOffset = offset - repLength;
|
||||
Image image = getImage(variable);
|
||||
CCompletionProposal proposal = new CCompletionProposal(repString, repOffset, repLength, image, dispString, idString, 1, viewer);
|
||||
CCompletionProposal proposal = createProposal(repString, dispString, idString, image, context);
|
||||
proposals.add(proposal);
|
||||
}
|
||||
|
||||
private void handleMacro(IASTPreprocessorMacroDefinition macro, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
||||
String macroName = macro.getName().toString();
|
||||
Image image = getImage(CElementImageProvider.getMacroImageDescriptor());
|
||||
|
||||
if (macro instanceof IASTPreprocessorFunctionStyleMacroDefinition) {
|
||||
IASTPreprocessorFunctionStyleMacroDefinition functionMacro = (IASTPreprocessorFunctionStyleMacroDefinition)macro;
|
||||
|
||||
StringBuffer repStringBuff = new StringBuffer();
|
||||
repStringBuff.append(macroName);
|
||||
repStringBuff.append('(');
|
||||
|
||||
StringBuffer args = new StringBuffer();
|
||||
|
||||
IASTFunctionStyleMacroParameter[] params = functionMacro.getParameters();
|
||||
if (params != null)
|
||||
for (int i = 0; i < params.length; ++i) {
|
||||
if (i > 0)
|
||||
args.append(", "); //$NON-NLS-1$
|
||||
args.append(params[i].getParameter());
|
||||
}
|
||||
String argString = args.toString();
|
||||
|
||||
StringBuffer descStringBuff = new StringBuffer(repStringBuff.toString());
|
||||
descStringBuff.append(argString);
|
||||
descStringBuff.append(')');
|
||||
|
||||
repStringBuff.append(')');
|
||||
String repString = repStringBuff.toString();
|
||||
String descString = descStringBuff.toString();
|
||||
|
||||
CCompletionProposal proposal = createProposal(repString, descString, image, completionNode, offset, viewer);
|
||||
proposal.setCursorPosition(repString.length() - 1);
|
||||
|
||||
if (argString.length() > 0) {
|
||||
CProposalContextInformation info = new CProposalContextInformation(image, descString, argString);
|
||||
info.setContextInformationPosition(offset);
|
||||
proposal.setContextInformation(info);
|
||||
}
|
||||
|
||||
proposals.add(proposal);
|
||||
} else
|
||||
proposals.add(createProposal(macroName, macroName, image, completionNode, offset, viewer));
|
||||
private CCompletionProposal createProposal(String repString, String dispString, Image image, CContentAssistInvocationContext context) {
|
||||
return createProposal(repString, dispString, null, image, context);
|
||||
}
|
||||
|
||||
private CCompletionProposal createProposal(String repString, String dispString, Image image, ASTCompletionNode completionNode, int offset, ITextViewer viewer) {
|
||||
int repLength = completionNode.getLength();
|
||||
int repOffset = offset - repLength;
|
||||
return new CCompletionProposal(repString, repOffset, repLength, image, dispString, 1, viewer);
|
||||
private CCompletionProposal createProposal(String repString, String dispString, String idString, Image image, CContentAssistInvocationContext context) {
|
||||
int parseOffset = context.getParseOffset();
|
||||
int invocationOffset = context.getInvocationOffset();
|
||||
boolean doReplacement = !context.isContextInformationStyle();
|
||||
|
||||
int repLength = doReplacement ? context.getCompletionNode().getLength() : 0;
|
||||
int repOffset = doReplacement ? parseOffset - repLength : invocationOffset;
|
||||
repString = doReplacement ? repString : ""; //$NON-NLS-1$
|
||||
|
||||
return new CCompletionProposal(repString, repOffset, repLength, image, dispString, idString, 1, context.getViewer());
|
||||
}
|
||||
|
||||
private Image getImage(ImageDescriptor desc) {
|
||||
|
@ -393,5 +426,4 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
|||
? CUIPlugin.getImageDescriptorRegistry().get( imageDescriptor )
|
||||
: null;
|
||||
}
|
||||
|
||||
}
|
|
@ -13,85 +13,27 @@
|
|||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformation;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformationExtension;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
|
||||
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
|
||||
import org.eclipse.cdt.internal.ui.text.Symbols;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
||||
|
||||
/**
|
||||
* A proposal computer wrapping the legacy {@link CCompletionProcessor2}.
|
||||
*
|
||||
* A proposal computer for handling the legacy extension from the
|
||||
* completionContributors extension point.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class LegacyCompletionProposalComputer implements ICompletionProposalComputer {
|
||||
|
||||
private static final class ContextInformationWrapper implements IContextInformation, IContextInformationExtension {
|
||||
|
||||
private final IContextInformation fContextInformation;
|
||||
private int fPosition;
|
||||
|
||||
public ContextInformationWrapper(IContextInformation contextInformation) {
|
||||
fContextInformation= contextInformation;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see IContextInformation#getContextDisplayString()
|
||||
*/
|
||||
public String getContextDisplayString() {
|
||||
return fContextInformation.getContextDisplayString();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see IContextInformation#getImage()
|
||||
*/
|
||||
public Image getImage() {
|
||||
return fContextInformation.getImage();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see IContextInformation#getInformationDisplayString()
|
||||
*/
|
||||
public String getInformationDisplayString() {
|
||||
return fContextInformation.getInformationDisplayString();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see IContextInformationExtension#getContextInformationPosition()
|
||||
*/
|
||||
public int getContextInformationPosition() {
|
||||
return fPosition;
|
||||
}
|
||||
|
||||
public void setContextInformationPosition(int position) {
|
||||
fPosition= position;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.jface.text.contentassist.IContextInformation#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof ContextInformationWrapper)
|
||||
return fContextInformation.equals(((ContextInformationWrapper) object).fContextInformation);
|
||||
else
|
||||
return fContextInformation.equals(object);
|
||||
}
|
||||
}
|
||||
|
||||
private CCompletionProcessor2 fCompletionProcessor;
|
||||
public class LegacyCompletionProposalComputer extends ParsingBasedProposalComputer {
|
||||
|
||||
/**
|
||||
* Default constructor is required (executable extension).
|
||||
|
@ -99,110 +41,34 @@ public class LegacyCompletionProposalComputer implements ICompletionProposalComp
|
|||
public LegacyCompletionProposalComputer() {
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) {
|
||||
if (context instanceof CContentAssistInvocationContext) {
|
||||
CContentAssistInvocationContext cContext= (CContentAssistInvocationContext)context;
|
||||
return internalComputeCompletionProposals(context.getInvocationOffset(), cContext, monitor);
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer#computeContextInformation(org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) {
|
||||
if (context instanceof CContentAssistInvocationContext) {
|
||||
CContentAssistInvocationContext cContext= (CContentAssistInvocationContext)context;
|
||||
int contextInformationPosition= guessContextInformationPosition(cContext);
|
||||
if (contextInformationPosition >= 0) {
|
||||
List result= addContextInformations(cContext, contextInformationPosition, monitor);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
protected int guessContextInformationPosition(ContentAssistInvocationContext context) {
|
||||
final int contextPosition= context.getInvocationOffset();
|
||||
protected List computeCompletionProposals(
|
||||
CContentAssistInvocationContext context,
|
||||
ASTCompletionNode completionNode, String prefix) throws CoreException {
|
||||
|
||||
IDocument document= context.getDocument();
|
||||
CHeuristicScanner scanner= new CHeuristicScanner(document);
|
||||
int bound= Math.max(-1, contextPosition - 200);
|
||||
ITextViewer viewer = context.getViewer();
|
||||
int offset = context.getInvocationOffset();
|
||||
IWorkingCopy workingCopy = context.getTranslationUnit().getWorkingCopy();
|
||||
|
||||
// try the innermost scope of parentheses that looks like a method call
|
||||
int pos= contextPosition - 1;
|
||||
do {
|
||||
int paren= scanner.findOpeningPeer(pos, bound, '(', ')');
|
||||
if (paren == CHeuristicScanner.NOT_FOUND)
|
||||
break;
|
||||
paren= scanner.findNonWhitespaceBackward(paren - 1, bound);
|
||||
if (paren == CHeuristicScanner.NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
int token= scanner.previousToken(paren, bound);
|
||||
// next token must be a method name (identifier) or the closing angle of a
|
||||
// constructor call of a template type.
|
||||
if (token == Symbols.TokenIDENT || token == Symbols.TokenGREATERTHAN) {
|
||||
return paren + 1;
|
||||
}
|
||||
pos= paren;
|
||||
} while (true);
|
||||
List proposals = new ArrayList();
|
||||
|
||||
return context.getInvocationOffset();
|
||||
}
|
||||
|
||||
private List addContextInformations(CContentAssistInvocationContext context, int offset, IProgressMonitor monitor) {
|
||||
List proposals= internalComputeCompletionProposals(offset, context, monitor);
|
||||
List result= new ArrayList(proposals.size());
|
||||
|
||||
for (Iterator it= proposals.iterator(); it.hasNext();) {
|
||||
ICompletionProposal proposal= (ICompletionProposal) it.next();
|
||||
IContextInformation contextInformation= proposal.getContextInformation();
|
||||
if (contextInformation != null) {
|
||||
ContextInformationWrapper wrapper= new ContextInformationWrapper(contextInformation);
|
||||
wrapper.setContextInformationPosition(offset);
|
||||
result.add(wrapper);
|
||||
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CUIPlugin.PLUGIN_ID, "completionContributors"); //$NON-NLS-1$
|
||||
if (point == null)
|
||||
return null;
|
||||
IExtension[] extensions = point.getExtensions();
|
||||
for (int i = 0; i < extensions.length; ++i) {
|
||||
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
|
||||
for (int j = 0; j < elements.length; ++j) {
|
||||
IConfigurationElement element = elements[j];
|
||||
if (!"contributor".equals(element.getName())) //$NON-NLS-1$
|
||||
continue;
|
||||
Object contribObject = element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
if (!(contribObject instanceof ICompletionContributor))
|
||||
continue;
|
||||
ICompletionContributor contributor = (ICompletionContributor)contribObject;
|
||||
contributor.contributeCompletionProposals(viewer, offset, workingCopy, completionNode, prefix, proposals);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
return proposals;
|
||||
}
|
||||
|
||||
private List internalComputeCompletionProposals(int offset, CContentAssistInvocationContext context, IProgressMonitor monitor) {
|
||||
IEditorPart editor= context.getEditor();
|
||||
if (editor != null) {
|
||||
fCompletionProcessor= new CCompletionProcessor2(editor);
|
||||
ICompletionProposal[] proposals= fCompletionProcessor.computeCompletionProposals(context.getViewer(), offset);
|
||||
if (proposals != null) {
|
||||
return Arrays.asList(proposals);
|
||||
}
|
||||
}
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer#getErrorMessage()
|
||||
*/
|
||||
public String getErrorMessage() {
|
||||
if (fCompletionProcessor != null) {
|
||||
return fCompletionProcessor.getErrorMessage();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer#sessionEnded()
|
||||
*/
|
||||
public void sessionEnded() {
|
||||
fCompletionProcessor= null;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer#sessionStarted()
|
||||
*/
|
||||
public void sessionStarted() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
|
||||
import org.eclipse.cdt.core.dom.IPDOMNode;
|
||||
import org.eclipse.cdt.core.dom.IPDOMVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IField;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
||||
|
||||
import org.eclipse.cdt.internal.core.CCoreInternals;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
* Completion contributor that looks up prefixes in the PDOM.
|
||||
*/
|
||||
public class PDOMCompletionContributor extends DOMCompletionContributor implements ICompletionContributor {
|
||||
|
||||
public void contributeCompletionProposals(
|
||||
final ITextViewer viewer,
|
||||
final int offset,
|
||||
final IWorkingCopy workingCopy,
|
||||
final ASTCompletionNode completionNode,
|
||||
final String prefix,
|
||||
final List proposals) {
|
||||
|
||||
if (completionNode == null)
|
||||
return;
|
||||
|
||||
// Return anyway
|
||||
if (completionNode != null)
|
||||
return;
|
||||
|
||||
try {
|
||||
PDOM pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(workingCopy.getCProject());
|
||||
IASTName[] names = completionNode.getNames();
|
||||
for (int i = 0; i < names.length; ++i) {
|
||||
IASTName name = names[i];
|
||||
IASTNode parent = name.getParent();
|
||||
if (parent instanceof IASTIdExpression || parent instanceof IASTNamedTypeSpecifier) {
|
||||
pdom.accept(new IPDOMVisitor() {
|
||||
public boolean visit(IPDOMNode node) throws CoreException {
|
||||
if (node instanceof PDOMLinkage)
|
||||
return true;
|
||||
|
||||
if (node instanceof PDOMBinding) {
|
||||
PDOMBinding binding = (PDOMBinding)node;
|
||||
if (binding.getName().startsWith(prefix)) {
|
||||
handleBinding(binding, completionNode, offset, viewer, proposals);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void leave(IPDOMNode node) throws CoreException {
|
||||
}
|
||||
});
|
||||
} else if (parent instanceof IASTFieldReference) {
|
||||
// Find the type the look at the fields
|
||||
IASTFieldReference fieldRef = (IASTFieldReference)parent;
|
||||
IASTExpression expression = fieldRef.getFieldOwner();
|
||||
IType type = expression.getExpressionType();
|
||||
if (type != null && type instanceof IBinding) {
|
||||
IBinding binding = (IBinding)type;
|
||||
PDOMLinkage linkage = pdom.getLinkage(name.getLinkage().getID());
|
||||
PDOMBinding pdomBinding = linkage.adaptBinding(binding);
|
||||
if (pdomBinding != null) {
|
||||
pdomBinding.accept(new IPDOMVisitor() {
|
||||
public boolean visit(IPDOMNode node) throws CoreException {
|
||||
if (node instanceof IField) {
|
||||
PDOMBinding binding = (PDOMBinding)node;
|
||||
if (binding.getName().startsWith(prefix))
|
||||
handleBinding(binding, completionNode, offset, viewer, proposals);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void leave(IPDOMNode node) throws CoreException {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CUIPlugin.getDefault().log(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformation;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer;
|
||||
|
||||
/**
|
||||
* The base class for any proposal computers that require a completion node in
|
||||
* order to determine its completion proposals.
|
||||
*
|
||||
* @author Bryan Wilkinson
|
||||
*/
|
||||
public abstract class ParsingBasedProposalComputer implements ICompletionProposalComputer {
|
||||
|
||||
private String fErrorMessage = null;
|
||||
|
||||
public List computeCompletionProposals(
|
||||
ContentAssistInvocationContext context, IProgressMonitor monitor) {
|
||||
try {
|
||||
if (context instanceof CContentAssistInvocationContext) {
|
||||
CContentAssistInvocationContext cContext = (CContentAssistInvocationContext) context;
|
||||
|
||||
ASTCompletionNode completionNode = cContext.getCompletionNode();
|
||||
if (completionNode == null) return Collections.EMPTY_LIST;
|
||||
String prefix = completionNode.getPrefix();
|
||||
if (prefix == null) {
|
||||
prefix = cContext.computeIdentifierPrefix().toString();
|
||||
}
|
||||
|
||||
return computeCompletionProposals(cContext, completionNode, prefix);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
fErrorMessage = e.toString();
|
||||
}
|
||||
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
protected abstract List computeCompletionProposals(
|
||||
CContentAssistInvocationContext context,
|
||||
ASTCompletionNode completionNode,
|
||||
String prefix) throws CoreException;
|
||||
|
||||
public List computeContextInformation(
|
||||
ContentAssistInvocationContext context, IProgressMonitor monitor) {
|
||||
List proposals= computeCompletionProposals(context, monitor);
|
||||
// remove duplicates
|
||||
proposals= new ArrayList(new LinkedHashSet(proposals));
|
||||
List result= new ArrayList();
|
||||
|
||||
for (Iterator it= proposals.iterator(); it.hasNext();) {
|
||||
ICompletionProposal proposal= (ICompletionProposal) it.next();
|
||||
IContextInformation contextInformation= proposal.getContextInformation();
|
||||
if (contextInformation != null) {
|
||||
result.add(contextInformation);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return fErrorMessage;
|
||||
}
|
||||
|
||||
public void sessionEnded() {
|
||||
}
|
||||
|
||||
public void sessionStarted() {
|
||||
fErrorMessage = null;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
* Bryan Wilkinson (QNX)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.ui.text.contentassist;
|
||||
|
||||
|
@ -145,6 +146,13 @@ public class ContentAssistInvocationContext {
|
|||
return fPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called upon completion of the content assist. Used to free any resources
|
||||
* used by the context.
|
||||
*/
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invocation contexts are equal if they describe the same context and are of the same type.
|
||||
* This implementation checks for <code>null</code> values and class equality. Subclasses
|
||||
|
|
Loading…
Add table
Reference in a new issue