mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-12 18:55:38 +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)
|
if (LT(1) != IToken.tRPAREN)
|
||||||
newInitializerExpressions = expression();
|
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) {
|
if (templateIdScopes.size() > 0) {
|
||||||
templateIdScopes.pop();
|
templateIdScopes.pop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
import org.eclipse.jface.action.IAction;
|
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.contentassist.ICompletionProposal;
|
||||||
import org.eclipse.jface.text.source.ISourceViewer;
|
|
||||||
import org.eclipse.ui.IEditorPart;
|
import org.eclipse.ui.IEditorPart;
|
||||||
import org.eclipse.ui.IWorkbenchPage;
|
import org.eclipse.ui.IWorkbenchPage;
|
||||||
import org.eclipse.ui.PlatformUI;
|
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.model.IWorkingCopy;
|
||||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||||
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
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.ui.text.ICHelpInvocationContext;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.CHelpProviderManager;
|
import org.eclipse.cdt.internal.ui.CHelpProviderManager;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||||
import org.eclipse.cdt.internal.ui.text.CHelpBookDescriptor;
|
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
|
* @author aniefer
|
||||||
|
@ -163,20 +162,20 @@ public class ContentAssistTests extends BaseUITestCase {
|
||||||
fail("Failed to get working copy"); //$NON-NLS-1$
|
fail("Failed to get working copy"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
// call the CompletionProcessor
|
// call the ContentAssistProcessor
|
||||||
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||||
FileEditorInput editorInput = new FileEditorInput(file);
|
FileEditorInput editorInput = new FileEditorInput(file);
|
||||||
IEditorPart editorPart = page.openEditor(editorInput, "org.eclipse.cdt.ui.editor.CEditor");
|
IEditorPart editorPart = page.openEditor(editorInput, "org.eclipse.cdt.ui.editor.CEditor");
|
||||||
CEditor editor = (CEditor) editorPart ;
|
CEditor editor = (CEditor) editorPart ;
|
||||||
IAction completionAction = editor.getAction("ContentAssistProposal");
|
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$
|
importFile( "test.h", "class Test{ public : Test( int ); }; \n" ); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
writer.write( "#include \"test.h\" \n"); //$NON-NLS-1$
|
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.IFile;
|
||||||
import org.eclipse.core.resources.IProject;
|
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.contentassist.ICompletionProposal;
|
||||||
import org.eclipse.jface.text.source.ISourceViewer;
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
import org.eclipse.jface.text.templates.TemplateProposal;
|
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.ui.texteditor.ITextEditor;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
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.model.ICProject;
|
||||||
import org.eclipse.cdt.core.parser.KeywordSetKey;
|
import org.eclipse.cdt.core.parser.KeywordSetKey;
|
||||||
import org.eclipse.cdt.core.parser.ParserFactory;
|
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.tests.text.EditorTestHelper;
|
||||||
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
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());
|
System.out.println("\n\n\n\n\nTesting "+this.getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
CCompletionProcessor2 completionProcessor = new CCompletionProcessor2(fEditor);
|
//Call the CContentAssistProcessor
|
||||||
// call the CompletionProcessor
|
|
||||||
ISourceViewer sourceViewer= EditorTestHelper.getSourceViewer((AbstractTextEditor)fEditor);
|
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();
|
long startTime= System.currentTimeMillis();
|
||||||
ICompletionProposal[] results = completionProcessor.computeCompletionProposals(sourceViewer, offset);
|
ICompletionProposal[] results = processor.computeCompletionProposals(sourceViewer, offset);
|
||||||
long endTime= System.currentTimeMillis();
|
long endTime= System.currentTimeMillis();
|
||||||
assertTrue(results != null);
|
assertTrue(results != null);
|
||||||
|
|
||||||
|
@ -107,8 +109,6 @@ public abstract class AbstractCompletionTest extends BaseUITestCase {
|
||||||
Arrays.sort(expected);
|
Arrays.sort(expected);
|
||||||
Arrays.sort(resultStrings);
|
Arrays.sort(resultStrings);
|
||||||
|
|
||||||
checkCompletionNode(completionProcessor.getCurrentCompletionNode());
|
|
||||||
|
|
||||||
if (CTestPlugin.getDefault().isDebugging()) {
|
if (CTestPlugin.getDefault().isDebugging()) {
|
||||||
System.out.println("Time (ms): " + (endTime-startTime));
|
System.out.println("Time (ms): " + (endTime-startTime));
|
||||||
for (int i = 0; i < resultStrings.length; i++) {
|
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) {
|
private String toString(String[] strings) {
|
||||||
StringBuffer buf= new StringBuffer();
|
StringBuffer buf= new StringBuffer();
|
||||||
for(int i=0; i< strings.length; i++){
|
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.NullProgressMonitor;
|
||||||
import org.eclipse.core.runtime.Path;
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
|
||||||
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
|
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
|
||||||
|
|
||||||
public abstract class CompletionProposalsBaseTest extends AbstractCompletionTest {
|
public abstract class CompletionProposalsBaseTest extends AbstractCompletionTest {
|
||||||
|
@ -95,15 +94,4 @@ public abstract class CompletionProposalsBaseTest extends AbstractCompletionTest
|
||||||
assertCompletionResults(getCompletionPosition(), expected, false);
|
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");
|
super("Tests in package org.eclipse.cdt.ui.tests.text.contentassist2");
|
||||||
|
|
||||||
addTest(CompletionTest_MemberReference_Arrow_Prefix2.suite());
|
addTest(CompletionTest_MemberReference_Arrow_Prefix2.suite());
|
||||||
addTest(CompletionTest_ArgumentType_NoPrefix.suite());
|
|
||||||
addTest(CompletionTest_ArgumentType_NoPrefix2.suite());
|
|
||||||
addTest(CompletionTest_ArgumentType_Prefix.suite());
|
addTest(CompletionTest_ArgumentType_Prefix.suite());
|
||||||
addTest(CompletionTest_ArgumentType_Prefix2.suite());
|
addTest(CompletionTest_ArgumentType_Prefix2.suite());
|
||||||
addTest(CompletionTest_ClassReference_NoPrefix.suite());
|
addTest(CompletionTest_ClassReference_NoPrefix.suite());
|
||||||
|
|
|
@ -1478,10 +1478,6 @@
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
<extension
|
||||||
point="org.eclipse.cdt.ui.completionContributors">
|
point="org.eclipse.cdt.ui.completionContributors">
|
||||||
<contributor
|
|
||||||
class="org.eclipse.cdt.internal.ui.text.contentassist.DOMCompletionContributor"
|
|
||||||
id="DOM"
|
|
||||||
priority="1"/>
|
|
||||||
<contributor
|
<contributor
|
||||||
class="org.eclipse.cdt.internal.ui.text.contentassist.KeywordCompletionContributor"
|
class="org.eclipse.cdt.internal.ui.text.contentassist.KeywordCompletionContributor"
|
||||||
id="Keywords"
|
id="Keywords"
|
||||||
|
@ -1523,6 +1519,20 @@
|
||||||
<proposalCategory
|
<proposalCategory
|
||||||
icon="$nl$/icons/elcl16/wordassist_co.gif"/>
|
icon="$nl$/icons/elcl16/wordassist_co.gif"/>
|
||||||
</extension>
|
</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) -->
|
<!-- legacy completions (completionContributors) -->
|
||||||
<extension
|
<extension
|
||||||
|
@ -1808,4 +1818,5 @@
|
||||||
class="org.eclipse.cdt.internal.ui.navigator.CNavigatorDragAdapterAssistant"
|
class="org.eclipse.cdt.internal.ui.navigator.CNavigatorDragAdapterAssistant"
|
||||||
viewerId="org.eclipse.ui.navigator.ProjectExplorer"/>
|
viewerId="org.eclipse.ui.navigator.ProjectExplorer"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
</plugin>
|
</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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -667,29 +667,20 @@ public class CCompletionProposal implements ICCompletionProposal, ICompletionPro
|
||||||
setReplacementLength(length);
|
setReplacementLength(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
* @see java.lang.Object#hashCode()
|
* @see java.lang.Object#hashCode()
|
||||||
*/
|
*/
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return fDisplayString.hashCode()
|
return fIdString.hashCode();
|
||||||
+ fReplacementString.hashCode()
|
|
||||||
+ ((fContextInformation == null) ? 0 : fContextInformation.hashCode());
|
|
||||||
}
|
}
|
||||||
/* (non-Javadoc)
|
|
||||||
|
/*
|
||||||
* @see java.lang.Object#equals(java.lang.Object)
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if(!(other instanceof CCompletionProposal))
|
if(!(other instanceof ICCompletionProposal))
|
||||||
return false;
|
return false;
|
||||||
if(!(fDisplayString.equals(((CCompletionProposal)other).fDisplayString)))
|
return fIdString.equalsIgnoreCase(((ICCompletionProposal)other).getIdString());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,28 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Bryan Wilkinson (QNX)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.Assert;
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
import org.eclipse.ui.IEditorPart;
|
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.ICProject;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
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.
|
* 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 {
|
public class CContentAssistInvocationContext extends ContentAssistInvocationContext {
|
||||||
|
|
||||||
private final IEditorPart fEditor;
|
private final IEditorPart fEditor;
|
||||||
|
private final boolean fIsCompletion;
|
||||||
|
|
||||||
private ITranslationUnit fTU= null;
|
private ITranslationUnit fTU= null;
|
||||||
private boolean fTUComputed= false;
|
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.
|
* Creates a new context.
|
||||||
*
|
*
|
||||||
|
@ -42,10 +59,11 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
||||||
* @param offset the invocation offset
|
* @param offset the invocation offset
|
||||||
* @param editor the editor that content assist is invoked in
|
* @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);
|
super(viewer, offset);
|
||||||
Assert.isNotNull(editor);
|
Assert.isNotNull(editor);
|
||||||
fEditor= editor;
|
fEditor= editor;
|
||||||
|
fIsCompletion= isCompletion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,11 +71,12 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
||||||
*
|
*
|
||||||
* @param unit the translation unit in <code>document</code>
|
* @param unit the translation unit in <code>document</code>
|
||||||
*/
|
*/
|
||||||
public CContentAssistInvocationContext(ITranslationUnit unit) {
|
public CContentAssistInvocationContext(ITranslationUnit unit, boolean isCompletion) {
|
||||||
super();
|
super();
|
||||||
fTU= unit;
|
fTU= unit;
|
||||||
fTUComputed= true;
|
fTUComputed= true;
|
||||||
fEditor= null;
|
fEditor= null;
|
||||||
|
fIsCompletion= isCompletion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,6 +103,111 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
||||||
ITranslationUnit unit= getTranslationUnit();
|
ITranslationUnit unit= getTranslationUnit();
|
||||||
return unit == null ? null : unit.getCProject();
|
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.
|
* Get the editor content assist is invoked in.
|
||||||
|
@ -93,4 +217,15 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
||||||
public IEditorPart getEditor() {
|
public IEditorPart getEditor() {
|
||||||
return fEditor;
|
return fEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isContextInformationStyle() {
|
||||||
|
return !fIsCompletion || (getParseOffset() != getInvocationOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
if (fIndex != null) {
|
||||||
|
fIndex.releaseReadLock();
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,28 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Bryan Wilkinson (QNX)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
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.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.InvalidRegistryObjectException;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
import org.eclipse.jface.text.contentassist.ContentAssistant;
|
import org.eclipse.jface.text.contentassist.ContentAssistant;
|
||||||
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
|
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
|
||||||
import org.eclipse.ui.IEditorPart;
|
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.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;
|
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)
|
* @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) {
|
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)
|
* @see org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistProcessor#createContext(org.eclipse.jface.text.ITextViewer, int)
|
||||||
*/
|
*/
|
||||||
protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset) {
|
protected ContentAssistInvocationContext createContext(ITextViewer viewer, int offset, boolean isCompletion) {
|
||||||
return new CContentAssistInvocationContext(viewer, offset, fEditor);
|
return new CContentAssistInvocationContext(viewer, offset, fEditor, isCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Bryan Wilkinson (QNX)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||||
|
|
||||||
|
@ -206,29 +207,34 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
||||||
IProgressMonitor monitor= createProgressMonitor();
|
IProgressMonitor monitor= createProgressMonitor();
|
||||||
monitor.beginTask(ContentAssistMessages.ContentAssistProcessor_computing_proposals, fCategories.size() + 1);
|
monitor.beginTask(ContentAssistMessages.ContentAssistProcessor_computing_proposals, fCategories.size() + 1);
|
||||||
|
|
||||||
ContentAssistInvocationContext context= createContext(viewer, offset);
|
ContentAssistInvocationContext context= createContext(viewer, offset, true);
|
||||||
long setup= DEBUG ? System.currentTimeMillis() : 0;
|
|
||||||
|
|
||||||
monitor.subTask(ContentAssistMessages.ContentAssistProcessor_collecting_proposals);
|
try {
|
||||||
List proposals= collectProposals(viewer, offset, monitor, context);
|
long setup= DEBUG ? System.currentTimeMillis() : 0;
|
||||||
long collect= 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);
|
monitor.subTask(ContentAssistMessages.ContentAssistProcessor_sorting_proposals);
|
||||||
List filtered= filterAndSortProposals(proposals, monitor, context);
|
List filtered= filterAndSortProposals(proposals, monitor, context);
|
||||||
fNumberOfComputedResults= filtered.size();
|
fNumberOfComputedResults= filtered.size();
|
||||||
long filter= DEBUG ? System.currentTimeMillis() : 0;
|
long filter= DEBUG ? System.currentTimeMillis() : 0;
|
||||||
|
|
||||||
ICompletionProposal[] result= (ICompletionProposal[]) filtered.toArray(new ICompletionProposal[filtered.size()]);
|
ICompletionProposal[] result= (ICompletionProposal[]) filtered.toArray(new ICompletionProposal[filtered.size()]);
|
||||||
monitor.done();
|
monitor.done();
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
System.err.println("Code Assist Stats (" + result.length + " proposals)"); //$NON-NLS-1$ //$NON-NLS-2$
|
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 (setup):\t" + (setup - start) ); //$NON-NLS-1$
|
||||||
System.err.println("Code Assist (collect):\t" + (collect - setup) ); //$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$
|
System.err.println("Code Assist (sort):\t" + (filter - collect) ); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
context.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearState() {
|
private void clearState() {
|
||||||
|
@ -288,18 +294,22 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
|
||||||
|
|
||||||
private List collectContextInformation(ITextViewer viewer, int offset, IProgressMonitor monitor) {
|
private List collectContextInformation(ITextViewer viewer, int offset, IProgressMonitor monitor) {
|
||||||
List proposals= new ArrayList();
|
List proposals= new ArrayList();
|
||||||
ContentAssistInvocationContext context= createContext(viewer, offset);
|
ContentAssistInvocationContext context= createContext(viewer, offset, false);
|
||||||
|
|
||||||
List providers= getCategories();
|
try {
|
||||||
for (Iterator it= providers.iterator(); it.hasNext();) {
|
List providers= getCategories();
|
||||||
CompletionProposalCategory cat= (CompletionProposalCategory) it.next();
|
for (Iterator it= providers.iterator(); it.hasNext();) {
|
||||||
List computed= cat.computeContextInformation(context, fPartition, new SubProgressMonitor(monitor, 1));
|
CompletionProposalCategory cat= (CompletionProposalCategory) it.next();
|
||||||
proposals.addAll(computed);
|
List computed= cat.computeContextInformation(context, fPartition, new SubProgressMonitor(monitor, 1));
|
||||||
if (fErrorMessage == null)
|
proposals.addAll(computed);
|
||||||
fErrorMessage= cat.getErrorMessage();
|
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
|
* @param offset the content assist offset
|
||||||
* @return the context to be passed to the computers
|
* @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);
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* QNX - Initial API and implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
|
||||||
* Bryan Wilkinson (QNX)
|
|
||||||
* Markus Schorn (Wind River Systems)
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jface.resource.ImageDescriptor;
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
|
||||||
import org.eclipse.jface.text.TextUtilities;
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
import org.eclipse.swt.graphics.Image;
|
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.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
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.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.ICPPDelegate;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
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.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
|
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.ast.ASTAccessVisibility;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
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,
|
* Default constructor is required (executable extension).
|
||||||
IWorkingCopy workingCopy,
|
*/
|
||||||
ASTCompletionNode completionNode,
|
public DOMCompletionProposalComputer() {
|
||||||
String prefix,
|
}
|
||||||
List proposals) {
|
|
||||||
|
protected List computeCompletionProposals(
|
||||||
|
CContentAssistInvocationContext context,
|
||||||
|
ASTCompletionNode completionNode, String prefix) {
|
||||||
|
|
||||||
|
List proposals = new ArrayList();
|
||||||
|
|
||||||
if (completionNode == null) {
|
if(inPreprocessorDirective(context)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(inPreprocessorDirective(viewer.getDocument(), offset)) {
|
|
||||||
// add only macros
|
// add only macros
|
||||||
addMacroProposals(viewer, offset, completionNode, prefix, proposals);
|
addMacroProposals(context, prefix, proposals);
|
||||||
} else {
|
} else {
|
||||||
boolean handleMacros= false;
|
boolean handleMacros= false;
|
||||||
IASTName[] names = completionNode.getNames();
|
IASTName[] names = completionNode.getNames();
|
||||||
if (names == null || names.length == 0)
|
if (names == null || names.length == 0)
|
||||||
// No names, not much we can do here
|
// No names, not much we can do here
|
||||||
return;
|
return Collections.EMPTY_LIST;
|
||||||
|
|
||||||
// Find all bindings
|
// Find all bindings
|
||||||
List allBindings = new ArrayList();
|
List allBindings = new ArrayList();
|
||||||
|
@ -107,28 +110,15 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
Iterator iBinding = allBindings.iterator();
|
Iterator iBinding = allBindings.iterator();
|
||||||
while (iBinding.hasNext()) {
|
while (iBinding.hasNext()) {
|
||||||
IBinding binding = (IBinding)iBinding.next();
|
IBinding binding = (IBinding)iBinding.next();
|
||||||
handleBinding(binding, completionNode, offset, viewer, proposals);
|
handleBinding(binding, context, proposals);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handleMacros) {
|
if (handleMacros) {
|
||||||
addMacroProposals(viewer, offset, completionNode, prefix, proposals);
|
addMacroProposals(context, prefix, proposals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,7 +128,10 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
* @param offset the offset to check
|
* @param offset the offset to check
|
||||||
* @return <code>true</code> if offset is inside a preprocessor directive
|
* @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()) {
|
if (offset > 0 && offset == doc.getLength()) {
|
||||||
--offset;
|
--offset;
|
||||||
}
|
}
|
||||||
|
@ -150,17 +143,94 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleBinding(IBinding binding, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
private void addMacroProposals(CContentAssistInvocationContext context, String prefix, List proposals) {
|
||||||
if (binding instanceof IFunction) {
|
char[] prefixChars= prefix.toCharArray();
|
||||||
handleFunction((IFunction)binding, completionNode, offset, viewer, proposals);
|
ASTCompletionNode completionNode = context.getCompletionNode();
|
||||||
} else if (binding instanceof IVariable) {
|
IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions();
|
||||||
handleVariable((IVariable) binding, completionNode, offset, viewer, proposals);
|
if (macros != null)
|
||||||
}
|
for (int i = 0; i < macros.length; ++i)
|
||||||
else
|
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefixChars.length, prefixChars, false))
|
||||||
proposals.add(createProposal(binding.getName(), binding.getName(), getImage(binding), completionNode, offset, viewer));
|
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);
|
Image image = getImage(function);
|
||||||
|
|
||||||
StringBuffer repStringBuff = new StringBuffer();
|
StringBuffer repStringBuff = new StringBuffer();
|
||||||
|
@ -230,22 +300,21 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
repStringBuff.append(')');
|
repStringBuff.append(')');
|
||||||
String repString = repStringBuff.toString();
|
String repString = repStringBuff.toString();
|
||||||
|
|
||||||
int repLength = completionNode.getLength();
|
CCompletionProposal proposal = createProposal(repString, dispString, idString, image, context);
|
||||||
int repOffset = offset - repLength;
|
if (!context.isContextInformationStyle()) {
|
||||||
CCompletionProposal proposal = new CCompletionProposal(repString, repOffset, repLength, image, dispString, idString, 1, viewer);
|
proposal.setCursorPosition(repString.length() - 1);
|
||||||
|
}
|
||||||
proposal.setCursorPosition(repString.length() - 1);
|
|
||||||
|
|
||||||
if (dispargString.length() > 0) {
|
if (dispargString.length() > 0) {
|
||||||
CProposalContextInformation info = new CProposalContextInformation(image, dispString, dispargString);
|
CProposalContextInformation info = new CProposalContextInformation(image, dispString, dispargString);
|
||||||
info.setContextInformationPosition(offset);
|
info.setContextInformationPosition(context.getParseOffset());
|
||||||
proposal.setContextInformation(info);
|
proposal.setContextInformation(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
proposals.add(proposal);
|
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();
|
StringBuffer repStringBuff = new StringBuffer();
|
||||||
repStringBuff.append(variable.getName());
|
repStringBuff.append(variable.getName());
|
||||||
|
|
||||||
|
@ -269,61 +338,25 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
|
|
||||||
String repString = repStringBuff.toString();
|
String repString = repStringBuff.toString();
|
||||||
|
|
||||||
int repLength = completionNode.getLength();
|
|
||||||
int repOffset = offset - repLength;
|
|
||||||
Image image = getImage(variable);
|
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);
|
proposals.add(proposal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMacro(IASTPreprocessorMacroDefinition macro, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
private CCompletionProposal createProposal(String repString, String dispString, Image image, CContentAssistInvocationContext context) {
|
||||||
String macroName = macro.getName().toString();
|
return createProposal(repString, dispString, null, image, context);
|
||||||
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, ASTCompletionNode completionNode, int offset, ITextViewer viewer) {
|
private CCompletionProposal createProposal(String repString, String dispString, String idString, Image image, CContentAssistInvocationContext context) {
|
||||||
int repLength = completionNode.getLength();
|
int parseOffset = context.getParseOffset();
|
||||||
int repOffset = offset - repLength;
|
int invocationOffset = context.getInvocationOffset();
|
||||||
return new CCompletionProposal(repString, repOffset, repLength, image, dispString, 1, viewer);
|
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) {
|
private Image getImage(ImageDescriptor desc) {
|
||||||
|
@ -393,5 +426,4 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
? CUIPlugin.getImageDescriptorRegistry().get( imageDescriptor )
|
? CUIPlugin.getImageDescriptorRegistry().get( imageDescriptor )
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,85 +13,27 @@
|
||||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.core.runtime.IConfigurationElement;
|
||||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
import org.eclipse.core.runtime.IExtension;
|
||||||
import org.eclipse.jface.text.contentassist.IContextInformation;
|
import org.eclipse.core.runtime.IExtensionPoint;
|
||||||
import org.eclipse.jface.text.contentassist.IContextInformationExtension;
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
import org.eclipse.ui.IEditorPart;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
|
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer;
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
|
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
||||||
import org.eclipse.cdt.internal.ui.text.Symbols;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A proposal computer wrapping the legacy {@link CCompletionProcessor2}.
|
* A proposal computer for handling the legacy extension from the
|
||||||
*
|
* completionContributors extension point.
|
||||||
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class LegacyCompletionProposalComputer implements ICompletionProposalComputer {
|
public class LegacyCompletionProposalComputer extends ParsingBasedProposalComputer {
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor is required (executable extension).
|
* Default constructor is required (executable extension).
|
||||||
|
@ -99,110 +41,34 @@ public class LegacyCompletionProposalComputer implements ICompletionProposalComp
|
||||||
public LegacyCompletionProposalComputer() {
|
public LegacyCompletionProposalComputer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
protected List computeCompletionProposals(
|
||||||
* @see org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
|
CContentAssistInvocationContext context,
|
||||||
*/
|
ASTCompletionNode completionNode, String prefix) throws CoreException {
|
||||||
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();
|
|
||||||
|
|
||||||
IDocument document= context.getDocument();
|
ITextViewer viewer = context.getViewer();
|
||||||
CHeuristicScanner scanner= new CHeuristicScanner(document);
|
int offset = context.getInvocationOffset();
|
||||||
int bound= Math.max(-1, contextPosition - 200);
|
IWorkingCopy workingCopy = context.getTranslationUnit().getWorkingCopy();
|
||||||
|
|
||||||
// try the innermost scope of parentheses that looks like a method call
|
List proposals = new ArrayList();
|
||||||
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 context.getInvocationOffset();
|
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CUIPlugin.PLUGIN_ID, "completionContributors"); //$NON-NLS-1$
|
||||||
}
|
if (point == null)
|
||||||
|
return null;
|
||||||
private List addContextInformations(CContentAssistInvocationContext context, int offset, IProgressMonitor monitor) {
|
IExtension[] extensions = point.getExtensions();
|
||||||
List proposals= internalComputeCompletionProposals(offset, context, monitor);
|
for (int i = 0; i < extensions.length; ++i) {
|
||||||
List result= new ArrayList(proposals.size());
|
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
|
||||||
|
for (int j = 0; j < elements.length; ++j) {
|
||||||
for (Iterator it= proposals.iterator(); it.hasNext();) {
|
IConfigurationElement element = elements[j];
|
||||||
ICompletionProposal proposal= (ICompletionProposal) it.next();
|
if (!"contributor".equals(element.getName())) //$NON-NLS-1$
|
||||||
IContextInformation contextInformation= proposal.getContextInformation();
|
continue;
|
||||||
if (contextInformation != null) {
|
Object contribObject = element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||||
ContextInformationWrapper wrapper= new ContextInformationWrapper(contextInformation);
|
if (!(contribObject instanceof ICompletionContributor))
|
||||||
wrapper.setContextInformationPosition(offset);
|
continue;
|
||||||
result.add(wrapper);
|
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:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Bryan Wilkinson (QNX)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui.text.contentassist;
|
package org.eclipse.cdt.ui.text.contentassist;
|
||||||
|
|
||||||
|
@ -145,6 +146,13 @@ public class ContentAssistInvocationContext {
|
||||||
return fPrefix;
|
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.
|
* 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
|
* This implementation checks for <code>null</code> values and class equality. Subclasses
|
||||||
|
|
Loading…
Add table
Reference in a new issue