diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java index a2d924ffb94..99b9b83cbcb 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java @@ -12,15 +12,12 @@ * Markus Schorn (Wind River Systems) * Thomas Corbat (IFS) * Sergey Prigogin (Google) - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.contentassist2; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -52,7 +49,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProposal; import org.eclipse.cdt.internal.ui.text.contentassist.CContentAssistProcessor; import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference; -import org.eclipse.cdt.internal.ui.text.contentassist.ParameterGuessingProposal; import org.eclipse.cdt.internal.ui.text.contentassist.RelevanceConstants; public abstract class AbstractContentAssistTest extends BaseUITestCase { @@ -111,21 +107,8 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase { return CUIPlugin.getDefault().getPreferenceStore(); } - private class ContentAssistResult { - long startTime; - long endTime; - Object[] results; - - public ContentAssistResult(long startTime, long endTime, Object[] results) { - this.startTime = startTime; - this.endTime = endTime; - this.results = results; - } - } - - private ContentAssistResult invokeContentAssist(int offset, int length, - boolean isCompletion, boolean isTemplate, boolean filterResults) - throws Exception { + protected void assertContentAssistResults(int offset, int length, String[] expected, + boolean isCompletion, boolean isTemplate, boolean filterResults, CompareType compareType) throws Exception { if (CTestPlugin.getDefault().isDebugging()) { System.out.println("\n\n\n\n\nTesting " + this.getClass().getName()); } @@ -155,20 +138,12 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase { results= filterResults(results, isCode); } } - return new ContentAssistResult(startTime, endTime, results); - } - - protected void assertContentAssistResults(int offset, int length, - String[] expected, boolean isCompletion, boolean isTemplate, - boolean filterResults, CompareType compareType) throws Exception { - ContentAssistResult r = invokeContentAssist(offset, length, isCompletion, isTemplate, filterResults); - - String[] resultStrings= toStringArray(r.results, compareType); + String[] resultStrings= toStringArray(results, compareType); Arrays.sort(expected); Arrays.sort(resultStrings); if (CTestPlugin.getDefault().isDebugging()) { - System.out.println("Time: " + (r.endTime - r.startTime) + " ms"); + System.out.println("Time: " + (endTime - startTime) + " ms"); for (String proposal : resultStrings) { System.out.println("Result: " + proposal); } @@ -202,46 +177,6 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase { } } - protected void assertContentAssistResults(int offset, int length, Map expected, - boolean isCompletion, boolean isTemplate, boolean filterResults, CompareType compareType) - throws Exception { - ContentAssistResult r = invokeContentAssist(offset, length, isCompletion, isTemplate, filterResults); - Map resultMap = toMap(r.results, compareType); - - if (CTestPlugin.getDefault().isDebugging()) { - System.out.println("Time : " + (r.endTime - r.startTime) + " ms"); - for (String proposal : resultMap.keySet()) { - System.out.println("Result: " + proposal); - String[][] result = resultMap.get(proposal); - for (String[] row : result) { - for (String s : row) { - System.out.print(s + " "); - } - System.out.println(); - } - } - System.out.println(); - } - - for (String proposal : expected.keySet()) { - String[][] result = resultMap.get(proposal); - assertNotNull(result); - String[][] expectedGuesses = expected.get(proposal); - String exp = ""; - String guess = ""; - int minLength = expectedGuesses.length < result.length ? expectedGuesses.length : result.length; - for (int i = 0; i < minLength; i++) { - String[] tmp = expectedGuesses[i]; - Arrays.sort(tmp); - exp += toString(tmp) + "\n"; - tmp = result[i]; - Arrays.sort(tmp); - guess += toString(tmp) + "\n"; - } - assertEquals(exp, guess); - } - } - protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, CompareType compareType) throws Exception { assertContentAssistResults(offset, length, expected, isCompletion, isTemplate, true, compareType); } @@ -250,37 +185,6 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase { assertContentAssistResults(offset, 0, expected, isCompletion, false, compareType); } - private Map toMap(Object[] results, - CompareType compareType) { - Map resultsMap = new HashMap<>(); - for (Object result : results) { - switch (compareType) { - case REPLACEMENT: - if (result instanceof ParameterGuessingProposal) { - ParameterGuessingProposal proposal = (ParameterGuessingProposal) result; - String pName = proposal.getReplacementString(); - ICompletionProposal[][] pProposals = proposal - .getParametersGuesses(); - String[][] p; - if (pProposals != null) { - p = new String[pProposals.length][]; - for (int i = 0; i < pProposals.length; i++) { - p[i] = new String[pProposals[i].length]; - for (int j = 0; j < pProposals[i].length; j++) { - p[i][j] = pProposals[i][j].getDisplayString(); - } - } - } else { - p = new String[0][]; - } - resultsMap.put(pName, p); - } - break; - } - } - return resultsMap; - } - /** * Filter out template and keyword proposals. * @param results diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CPPParameterGuessingTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CPPParameterGuessingTests.java deleted file mode 100644 index 4b351fbbeb7..00000000000 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CPPParameterGuessingTests.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Mentor Graphics Corporation. - * 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: - * Mohamed Azab (Mentor Graphics) - Initial implementation. - *******************************************************************************/ -package org.eclipse.cdt.ui.tests.text.contentassist2; - -import java.util.HashMap; -import java.util.Map; - -import junit.framework.Test; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; - -import org.eclipse.cdt.core.testplugin.util.BaseTestCase; - -public class CPPParameterGuessingTests extends AbstractContentAssistTest { - private static final String HEADER_FILE_NAME = "PGTest.h"; - private static final String SOURCE_FILE_NAME = "PGTest.cpp"; - - // {PGTest.h} - // class aClass { - // public: - // int aField; - // void aMethod(char c); - // void aMethod(char c, int x); - // }; - // - // class bClass : aClass { - // }; - // - // void overload(int x, aClass a); - // void overload(int x, aClass* aPtr); - // int piab(aClass a, bClass b); - // templatevoid tFunc(T x, T y); - - public CPPParameterGuessingTests(String name) { - super(name, true); - } - - public static Test suite() { - return BaseTestCase.suite(CPPParameterGuessingTests.class, "_"); - } - - @Override - protected IFile setUpProjectContent(IProject project) throws Exception { - String headerContent = readTaggedComment(HEADER_FILE_NAME); - StringBuilder sourceContent = getContentsForTest(1)[0]; - sourceContent.insert(0, "#include \"" + HEADER_FILE_NAME + "\"\n"); - assertNotNull(createFile(project, HEADER_FILE_NAME, headerContent)); - return createFile(project, SOURCE_FILE_NAME, sourceContent.toString()); - } - - protected void assertParametersGuesses(Map expected) - throws Exception { - assertContentAssistResults(getBuffer().length() - 1, 0, expected, true, - false, false, CompareType.REPLACEMENT); - } - - // void foo(){ - // aClass* aTypePtr; - // bClass bTypeObj; - // piab( - public void testIndirectTypes() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("piab(*aTypePtr, bTypeObj)", new String[][] { { "*aTypePtr", "bTypeObj" }, - { "bTypeObj" } }); - assertParametersGuesses(resultsMap); - } - - // void foo(){ - // int intVal; - // aClass aTypeObj; - // overload( - public void testOverloadedFunction() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("overload(intVal, aTypeObj)", new String[][] { { "intVal" }, { "aTypeObj" } }); - resultsMap.put("overload(intVal, &aTypeObj)", - new String[][] { { "intVal" }, { "&aTypeObj" } }); - assertParametersGuesses(resultsMap); - } - - // void foo(){ - // aClass aTypeObj; - // tFunc ( - public void testTemplateFunction() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("tFunc (x, y)", new String[][] { { "x" }, - { "y" } }); - assertParametersGuesses(resultsMap); - } - - // struct container { - // aClass* aTypePtr; - // }; - // - // void foo(){ - // char charX, charY, charZ; - // container containerObj; - // containerObj.aTypePtr = new aClass(); - // containerObj.aTypePtr-> - public void testOverloadedMethod() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("aMethod(charZ)", new String[][] { { "charX", "charY", "charZ" } }); - resultsMap.put("aMethod(charZ, charY)", new String[][] { { "charX", "charY", "charZ" }, - { "charX", "charY", "charZ" } }); - assertParametersGuesses(resultsMap); - } - - // void testParameterNameMatching(int lngName, int shrt); - // - // void foo() { - // int lng; - // int shrtNameMatch; - // testParameter - public void testParameterNameMatching() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("testParameterNameMatching(lng, shrtNameMatch)", new String[][] { - { "lng", "shrtNameMatch" }, { "lng", "shrtNameMatch" } }); - assertParametersGuesses(resultsMap); - } - - // class cClass : bClass { - // public: - // cClass(int inCall) { - // char charX, charY; - // aClass:: - public void testInsideConstructor() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("aMethod(charY)", new String[][] { { "charX", "charY", "inCall" } }); - resultsMap.put("aMethod(charY, charX)", new String[][] { - { "charX", "charY", "inCall" }, { "charX", "charY", "inCall" } }); - assertParametersGuesses(resultsMap); - } -} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CParameterGuessingTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CParameterGuessingTests.java deleted file mode 100644 index 29155a9bd41..00000000000 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CParameterGuessingTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Mentor Graphics Corporation. - * 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: - * Mohamed Azab (Mentor Graphics) - Initial implementation. - *******************************************************************************/ -package org.eclipse.cdt.ui.tests.text.contentassist2; - -import java.util.HashMap; -import java.util.Map; - -import junit.framework.Test; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; - -import org.eclipse.cdt.core.testplugin.util.BaseTestCase; - -public class CParameterGuessingTests extends AbstractContentAssistTest { - private static final String HEADER_FILE_NAME = "PGTest_C.h"; - private static final String SOURCE_FILE_NAME = "PGTest_C.c"; - - // {PGTest_C.h} - // typedef struct aStruct { - // int a; - // int b; - // } aStruct; - // - // void ov1(int x, aStruct a); - // void ov2(int x, aStruct* aPtr); - // int funWith2ATypeObjectParams(aStruct a, aStruct b); - - public CParameterGuessingTests(String name) { - super(name, false); - } - - public static Test suite() { - return BaseTestCase.suite(CParameterGuessingTests.class, "_"); - } - - @Override - protected IFile setUpProjectContent(IProject project) throws Exception { - String headerContent = readTaggedComment(HEADER_FILE_NAME); - StringBuilder sourceContent = getContentsForTest(1)[0]; - sourceContent.insert(0, "#include \"" + HEADER_FILE_NAME + "\"\n"); - assertNotNull(createFile(project, HEADER_FILE_NAME, headerContent)); - return createFile(project, SOURCE_FILE_NAME, sourceContent.toString()); - } - - protected void assertParametersGuesses(Map expected) throws Exception { - assertContentAssistResults(getBuffer().length() - 1, 0, expected, true, - false, false, CompareType.REPLACEMENT); - } - - // void foo(){ - // aStruct* axPtr; - // aStruct ax; - // funWith2ATypeObjectParams( - public void testIndirectTypes() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("funWith2ATypeObjectParams(*axPtr, ax)", new String[][] { { "ax", "*axPtr" }, - { "ax", "*axPtr" } }); - assertParametersGuesses(resultsMap); - } - - // void foo(){ - // aStruct ax; - // ov - public void testMultipleFunctions() throws Exception { - Map resultsMap = new HashMap<>(); - resultsMap.put("ov1(x, ax)", new String[][] { { "x" }, { "ax" } }); - resultsMap.put("ov2(x, &ax)", new String[][] { { "x" }, { "&ax" } }); - assertParametersGuesses(resultsMap); - } -} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 50591e1d1a8..0b4a9689770 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2015 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2014 Wind River Systems, Inc. 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 @@ -15,7 +15,6 @@ * Nathan Ridge * Thomas Corbat (IFS) * Michael Woski - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.contentassist2; @@ -856,7 +855,7 @@ public class CompletionTests extends AbstractContentAssistTest { // Printer::/*cursor*/ public void testPrivateStaticMember_109480() throws Exception { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=109480 - final String[] expected= { "InitPrinter(port)", "port" }; + final String[] expected= { "InitPrinter()", "port" }; assertCompletionResults(fCursorOffset, expected, REPLACEMENT); } @@ -1262,7 +1261,7 @@ public class CompletionTests extends AbstractContentAssistTest { // } //}; public void testContentAssistInDeferredClassInstance_194592() throws Exception { - final String[] expected= { "add(tOther)" }; + final String[] expected= { "add()" }; assertCompletionResults(fCursorOffset, expected, REPLACEMENT); } @@ -1422,7 +1421,7 @@ public class CompletionTests extends AbstractContentAssistTest { // } // using N::f/*cursor*/ public void testUsingDeclaration_379631() throws Exception { - final String[] expected= { "foo()" }; + final String[] expected= { "foo;" }; assertCompletionResults(fCursorOffset, expected, REPLACEMENT); } @@ -1569,7 +1568,7 @@ public class CompletionTests extends AbstractContentAssistTest { // } // using N::fo/*cursor*/; public void testUsingCompletionWithFollowingSemicolon() throws Exception { - final String[] expected = { "foo()" }; + final String[] expected = { "foo" }; assertContentAssistResults(fCursorOffset, expected, true, REPLACEMENT); final String[] expectedInformation = { "null" }; assertContentAssistResults(fCursorOffset, expectedInformation, true, CONTEXT); @@ -1607,7 +1606,7 @@ public class CompletionTests extends AbstractContentAssistTest { setDisplayDefaultArguments(true); final String[] expectedDisplay = { "default_argument(int i = 23) : void" }; assertContentAssistResults(fCursorOffset, expectedDisplay, true, DISPLAY); - final String[] expectedReplacement = { "default_argument(i)" }; + final String[] expectedReplacement = { "default_argument()" }; assertContentAssistResults(fCursorOffset, expectedReplacement, true, REPLACEMENT); } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ContentAssist2TestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ContentAssist2TestSuite.java index 354cb986d25..7a064666c2d 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ContentAssist2TestSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/ContentAssist2TestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2015 Siemens AG and others. + * Copyright (c) 2006, 2007 Siemens AG and others. * All rights reserved. This content 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 @@ -9,7 +9,6 @@ * Norbert Ploett - Initial implementation * Bryan Wilkinson (QNX) * Andrew Ferguson (Symbian) - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.contentassist2; @@ -72,8 +71,6 @@ public class ContentAssist2TestSuite extends TestSuite { addTest(CompletionTests.suite()); addTest(CompletionTests_PlainC.suite()); addTest(ParameterHintTests.suite()); - addTest(CPPParameterGuessingTests.suite()); - addTest(CParameterGuessingTests.suite()); addTest(ShowCamelCasePreferenceTest.suite()); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java index bc88e56e1d4..5c7323936f6 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2015 QNX Software Systems and others. + * Copyright (c) 2007, 2014 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 @@ -13,7 +13,6 @@ * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) * Nathan Ridge * Thomas Corbat (IFS) - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. *******************************************************************************/ package org.eclipse.cdt.internal.ui.text.contentassist; @@ -29,7 +28,6 @@ import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.IEditorPart; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -96,7 +94,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.AccessContext; import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory; -import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider; /** @@ -110,22 +107,17 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer private static final String TEMPLATE_PARAMETER_PATTERN = "template<{0}> class"; //$NON-NLS-1$; private static final String TYPENAME = "typename"; //$NON-NLS-1$; private static final String ELLIPSIS = "..."; //$NON-NLS-1$; - private String fPrefix; - private ArrayList fAvailableElements; /** * Default constructor is required (executable extension). */ public DOMCompletionProposalComputer() { - fPrefix = ""; //$NON-NLS-1$ } @Override protected List computeCompletionProposals( CContentAssistInvocationContext context, IASTCompletionNode completionNode, String prefix) { - fPrefix = prefix; - initializeDefinedElements(context); List proposals = new ArrayList(); if (inPreprocessorDirective(context)) { @@ -595,116 +587,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer proposal.setContextInformation(info); } - /* - * The ParameterGuessingProposal will be active if the content assist is invoked before typing - * any parameters. Otherwise, the normal Parameter Hint Proposal will be added. - */ - if (isBeforeParameters(context)) { - proposals.add(ParameterGuessingProposal.createProposal(context, fAvailableElements, proposal, function, fPrefix)); - } else { - proposals.add(proposal); - } - } - - /** - * Returns true if the invocation is at the function name or before typing any parameters - */ - private boolean isBeforeParameters(CContentAssistInvocationContext context) { - /* - * Invocation offset and parse offset are the same if content assist is invoked while in the function - * name (i.e. before the '('). After that, the parse offset will indicate the end of the name part. If - * the diff. between them is zero, then we're still inside the function name part. - */ - int relativeOffset = context.getInvocationOffset() - context.getParseOffset(); - if (relativeOffset == 0) - return true; - int startOffset = context.getParseOffset(); - try { - String completePrefix = context.getDocument().get(startOffset, - context.getInvocationOffset() - startOffset); - if (completePrefix.trim().endsWith("(")) //$NON-NLS-1$ - return true; - } catch (BadLocationException e) { - return false; - } - return false; - } - - /** - * Initializes the list of defined elements at the start of the current statement. - */ - private void initializeDefinedElements(CContentAssistInvocationContext context) { - /* - * Get all defined elements before the start of the statement. - * ex1: int a = foo( - * ^ --> We don't want 'a' as a suggestion. - * ex2: char* foo(int a, int b) {return NULL;} - * void bar(char* name) {} - * ... - * bar( foo( - * ^ --> If this offset is used, the only defined name will be "bar(char*)". - */ - int startOffset = getStatementStartOffset(context.getDocument(), - context.getParseOffset() - fPrefix.length()); - fAvailableElements = new ArrayList<>(); - IASTCompletionNode node = null; - // Create a content assist context that points to the start of the statement. - CContentAssistInvocationContext newContext = new CContentAssistInvocationContext( - context.getViewer(), startOffset, getCEditor(), true, false); - try { - node = newContext.getCompletionNode(); - if (node != null) { - IASTName[] names = node.getNames(); - for (IASTName name : names) { - IASTCompletionContext astContext = name.getCompletionContext(); - if (astContext != null) { - IBinding[] bindings = astContext.findBindings(name, true); - if (bindings != null) { - AccessContext accessibilityContext = new AccessContext(name); - for (IBinding binding : bindings) { - if (accessibilityContext.isAccessible(binding)) - fAvailableElements.add(binding); - } - } - } - } - } - } finally { - newContext.dispose(); - } - } - - /** - * Returns the position after last semicolon or opening or closing brace before the given offset. - */ - private static int getStatementStartOffset(IDocument doc, int offset) { - if (offset != 0) { - String docPart; - try { - docPart = doc.get(0, offset); - int index = docPart.lastIndexOf(';'); - int tmpIndex = docPart.lastIndexOf('{'); - index = (index < tmpIndex) ? tmpIndex : index; - tmpIndex = docPart.lastIndexOf('}'); - index = (index < tmpIndex) ? tmpIndex : index; - return index + 1; - } catch (BadLocationException e) { - CUIPlugin.log(e); - } - } - return offset; - } - - /** - * Returns the currently active C/C++ editor, or null if it cannot be determined. - */ - private static CEditor getCEditor() { - IEditorPart part = CUIPlugin.getActivePage().getActiveEditor(); - if (part instanceof CEditor) { - return (CEditor) part; - } else { - return null; - } + proposals.add(proposal); } private boolean skipDefaultedParameter(IParameter param) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/FunctionCompletionProposal.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/FunctionCompletionProposal.java deleted file mode 100644 index c3381c6b9ad..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/FunctionCompletionProposal.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005, 2015 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 Corporation - initial API and implementation - * Tom Eicher - [content assist] prefix complete casted method proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=247547 - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. - *******************************************************************************/ -package org.eclipse.cdt.internal.ui.text.contentassist; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.link.ILinkedModeListener; -import org.eclipse.jface.text.link.LinkedModeModel; -import org.eclipse.jface.text.link.LinkedModeUI; -import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags; -import org.eclipse.jface.text.link.LinkedModeUI.IExitPolicy; -import org.eclipse.jface.text.link.LinkedPosition; -import org.eclipse.jface.text.link.LinkedPositionGroup; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.ui.texteditor.link.EditorLinkedModeUI; - -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.dom.ast.IFunction; -import org.eclipse.cdt.core.dom.ast.IParameter; -import org.eclipse.cdt.ui.CUIPlugin; - -/** - * This is a modified version of org.eclipse.jdt.internal.ui.text.java.JavaMethodCompletionProposal - * - * This class adds a linked mode function compilation proposal with exit policy. - */ -public class FunctionCompletionProposal extends CCompletionProposal { - private boolean fHasParametersComputed; - private boolean fHasParameters; - protected IParameter[] fFunctionParameters; - protected int fInvocationOffset; - protected int fParseOffset; - protected IASTTranslationUnit fTranslationUnit; - protected IDocument fDocument; - - public FunctionCompletionProposal(String replacementString, int replacementOffset, int replacementLength, - Image image, String displayString, String idString, int relevance, ITextViewer viewer, - IFunction function, int invocationOffset, int parseOffset, IASTTranslationUnit translationUnit, - IDocument document) { - super(replacementString, replacementOffset, replacementLength, image, displayString, idString, - relevance, viewer); - fFunctionParameters = function.getParameters(); - fInvocationOffset = invocationOffset; - fParseOffset = parseOffset; - fTranslationUnit = translationUnit; - fDocument = document; - } - - @Override - public void apply(IDocument document, char trigger, int offset) { - if (trigger == ' ' || trigger == '(') - trigger = '\0'; - super.apply(document, trigger, offset); - if (hasParameters()) { - setUpLinkedMode(document, ')'); - } else if (getReplacementString().endsWith(";")) { //$NON-NLS-1$ - setUpLinkedMode(document, ';'); - } - } - - /** - * Returns {@code true} if the method has any parameters, {@code true} if it has no parameters - */ - protected final boolean hasParameters() { - if (!fHasParametersComputed) { - fHasParametersComputed = true; - fHasParameters = computeHasParameters(); - } - return fHasParameters; - } - - private boolean computeHasParameters() { - return (fFunctionParameters != null && fFunctionParameters.length != 0); - } - - protected static class ExitPolicy implements IExitPolicy { - final char fExitCharacter; - - public ExitPolicy(char exitCharacter) { - fExitCharacter = exitCharacter; - } - - @Override - public ExitFlags doExit(LinkedModeModel environment, VerifyEvent event, int offset, int length) { - if (event.character == fExitCharacter) { - if (environment.anyPositionContains(offset)) { - return new ExitFlags(ILinkedModeListener.UPDATE_CARET, false); - } else { - return new ExitFlags(ILinkedModeListener.UPDATE_CARET, true); - } - } - - switch (event.character) { - case ';': - return new ExitFlags(ILinkedModeListener.NONE, true); - default: - return null; - } - } - } - - protected void setUpLinkedMode(IDocument document, char closingCharacter) { - if (fTextViewer != null) { - int exit = getReplacementOffset() + getReplacementString().length(); - try { - LinkedPositionGroup group = new LinkedPositionGroup(); - group.addPosition(new LinkedPosition(document, fInvocationOffset, 0, - LinkedPositionGroup.NO_STOP)); - - LinkedModeModel model = new LinkedModeModel(); - model.addGroup(group); - model.forceInstall(); - - LinkedModeUI ui = new EditorLinkedModeUI(model, fTextViewer); - ui.setSimpleMode(true); - ui.setExitPolicy(new ExitPolicy(closingCharacter)); - ui.setExitPosition(fTextViewer, exit, 0, Integer.MAX_VALUE); - ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER); - ui.enter(); - } catch (BadLocationException x) { - CUIPlugin.log(x); - } - } - } -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ParameterGuesser.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ParameterGuesser.java deleted file mode 100644 index 4ed782ab0d6..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ParameterGuesser.java +++ /dev/null @@ -1,431 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2015 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 Corporation - initial API and implementation - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. - *******************************************************************************/ -package org.eclipse.cdt.internal.ui.text.contentassist; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.contentassist.ICompletionProposal; -import org.eclipse.swt.graphics.Image; - -import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.ICompositeType; -import org.eclipse.cdt.core.dom.ast.IEnumeration; -import org.eclipse.cdt.core.dom.ast.IEnumerator; -import org.eclipse.cdt.core.dom.ast.IFunction; -import org.eclipse.cdt.core.dom.ast.IPointerType; -import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.IVariable; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; -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.ICPPField; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; -import org.eclipse.cdt.core.model.CModelException; -import org.eclipse.cdt.core.model.IField; -import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; -import org.eclipse.cdt.ui.CUIPlugin; - -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost; - -import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider; - -/** - * This class is based on org.eclipse.jdt.internal.ui.text.java.ParameterGuesser - * - * This class produces a logically-ordered list of applicable variables for later use as parameter guessing - * proposals for a function parameter. - */ -public class ParameterGuesser { - private IASTTranslationUnit fTranslationUnit; - private static final char[] NO_TRIGGERS = new char[0]; - private final Set fAlreadyMatchedNames; - - private final static class Variable { - /** - * Variable type. Used to choose the best guess based on scope (Local beats instance beats inherited - * beats global). - */ - public static final int LOCAL = 0; - public static final int FIELD = 1; - public static final int GLOBAL = 3; - - public final IType qualifiedTypeName; - public final String name; - public final int variableType; - public final int positionScore; - - public final char[] triggerChars; - public final ImageDescriptor descriptor; - - public boolean alreadyMatched; - - public Variable(IType qualifiedTypeName, String name, int variableType, int positionScore, - char[] triggerChars, ImageDescriptor descriptor) { - this.qualifiedTypeName = qualifiedTypeName; - this.name = name; - this.variableType = variableType; - this.positionScore = positionScore; - this.triggerChars = triggerChars; - this.descriptor = descriptor; - this.alreadyMatched = false; - } - - @Override - public String toString() { - StringBuilder buffer = new StringBuilder(); - buffer.append(qualifiedTypeName); - buffer.append(' '); - buffer.append(name); - buffer.append(" ("); //$NON-NLS-1$ - buffer.append(variableType); - buffer.append(')'); - - return buffer.toString(); - } - } - - /** - * Creates a parameter guesser - */ - public ParameterGuesser(IASTTranslationUnit translationUnit) { - fAlreadyMatchedNames = new HashSet(); - fTranslationUnit = translationUnit; - } - - private List evaluateVisibleMatches(IType expectedType, ArrayList suggestions) - throws CModelException { - ArrayList res = new ArrayList<>(); - int size = suggestions.size(); - for (int i = 0; i < size; i++) { - Variable variable = createVariable(suggestions.get(i), expectedType, i); - if (variable != null) { - if (fAlreadyMatchedNames.contains(variable.name)) { - variable.alreadyMatched = true; - } - res.add(variable); - } - } - return res; - } - - private boolean isAnonymousBinding(IBinding binding) { - char[] name = binding.getNameCharArray(); - return name.length == 0 || name[0] == '{'; - } - - protected IType getType(IBinding binding) { - if (!isAnonymousBinding(binding)) { - if (binding instanceof IVariable) { - return ((IVariable) binding).getType(); - } else { - return null; - } - } - return null; - } - - public Variable createVariable(IBinding element, IType enclosingType, int positionScore) - throws CModelException { - IType elementType = getType(element); - String elementName = element.getName(); - if (elementType != null - && (elementType.toString().equals(enclosingType.toString()) - || elementType.isSameType(enclosingType) || isParent(elementType, enclosingType) - || isAutomaticCasting(enclosingType, elementType) - || isReferenceTo(enclosingType, elementType) || isReferenceTo(elementType, - enclosingType))) { - int variableType = Variable.GLOBAL; - if (element instanceof ICPPField) { - variableType = Variable.FIELD; - - } else if (element instanceof IVariable) { - try { - if (element instanceof ICPPBinding && ((ICPPBinding) element).isGloballyQualified()) { - variableType = Variable.GLOBAL; - } else { - variableType = Variable.LOCAL; - } - } catch (DOMException e) { - } - } - - // Handle reference case - if (isReferenceTo(enclosingType, elementType)) - elementName = "&" + elementName; //$NON-NLS-1$ - else if (isReferenceTo(elementType, enclosingType)) - elementName = "*" + elementName; //$NON-NLS-1$ - return new Variable(elementType, elementName, variableType, positionScore, NO_TRIGGERS, - getImageDescriptor(element)); - } - return null; - } - - private boolean isReferenceTo(IType ref, IType val) { - if (ref instanceof IPointerType) { - IType ptr = ((IPointerType) ref).getType(); - if (ptr.toString().equals(val.toString()) || ptr.isSameType(val)) - return true; - } - return false; - } - - /** - * Returns true, if the parent type is a direct/indirect parent of the child type - */ - private boolean isParent(IType child, IType parent) { - if (child != null && parent != null && child instanceof ICPPClassType - && parent instanceof ICPPClassType) { - ICPPBase[] bases = ((ICPPClassType) child).getBases(); - for (ICPPBase base : bases) { - IType tmpType = base.getBaseClassType(); - if (tmpType.toString().equals(parent.toString()) || tmpType.isSameType(parent) - || isParent(tmpType, parent)) - return true; - } - } - return false; - } - - /** - * Returns true if the orginType can be automatically casted to the candidateType - */ - private boolean isAutomaticCasting(IType orginType, IType candidateType) { - try { - Cost cost = Conversions.checkImplicitConversionSequence(orginType, candidateType, - ValueCategory.LVALUE, UDCMode.ALLOWED, Context.ORDINARY, fTranslationUnit); - if (cost.converts()) - return true; - } catch (DOMException e) { - return false; - } - return false; - } - - private ImageDescriptor getImageDescriptor(IBinding binding) { - ImageDescriptor imageDescriptor = null; - - if (binding instanceof ITypedef) { - imageDescriptor = CElementImageProvider.getTypedefImageDescriptor(); - } else if (binding instanceof ICompositeType) { - if (((ICompositeType) binding).getKey() == ICPPClassType.k_class - || binding instanceof ICPPClassTemplate) - imageDescriptor = CElementImageProvider.getClassImageDescriptor(); - else if (((ICompositeType) binding).getKey() == ICompositeType.k_struct) - imageDescriptor = CElementImageProvider.getStructImageDescriptor(); - else if (((ICompositeType) binding).getKey() == ICompositeType.k_union) - imageDescriptor = CElementImageProvider.getUnionImageDescriptor(); - } else if (binding instanceof ICPPMethod) { - switch (((ICPPMethod) binding).getVisibility()) { - case ICPPMember.v_private: - imageDescriptor = CElementImageProvider.getMethodImageDescriptor(ASTAccessVisibility.PRIVATE); - break; - case ICPPMember.v_protected: - imageDescriptor = CElementImageProvider - .getMethodImageDescriptor(ASTAccessVisibility.PROTECTED); - break; - default: - imageDescriptor = CElementImageProvider.getMethodImageDescriptor(ASTAccessVisibility.PUBLIC); - break; - } - } else if (binding instanceof IFunction) { - imageDescriptor = CElementImageProvider.getFunctionImageDescriptor(); - } else if (binding instanceof ICPPField) { - switch (((ICPPField) binding).getVisibility()) { - case ICPPMember.v_private: - imageDescriptor = CElementImageProvider.getFieldImageDescriptor(ASTAccessVisibility.PRIVATE); - break; - case ICPPMember.v_protected: - imageDescriptor = CElementImageProvider - .getFieldImageDescriptor(ASTAccessVisibility.PROTECTED); - break; - default: - imageDescriptor = CElementImageProvider.getFieldImageDescriptor(ASTAccessVisibility.PUBLIC); - break; - } - } else if (binding instanceof IField) { - imageDescriptor = CElementImageProvider.getFieldImageDescriptor(ASTAccessVisibility.PUBLIC); - } else if (binding instanceof IVariable) { - imageDescriptor = CElementImageProvider.getVariableImageDescriptor(); - } else if (binding instanceof IEnumeration) { - imageDescriptor = CElementImageProvider.getEnumerationImageDescriptor(); - } else if (binding instanceof IEnumerator) { - imageDescriptor = CElementImageProvider.getEnumeratorImageDescriptor(); - } else if (binding instanceof ICPPNamespace) { - imageDescriptor = CElementImageProvider.getNamespaceImageDescriptor(); - } else if (binding instanceof ICPPFunctionTemplate) { - imageDescriptor = CElementImageProvider.getFunctionImageDescriptor(); - } else if (binding instanceof ICPPUsingDeclaration) { - IBinding[] delegates = ((ICPPUsingDeclaration) binding).getDelegates(); - if (delegates.length > 0) - return getImageDescriptor(delegates[0]); - } - return imageDescriptor; - } - - /** - * Returns the matches for the type and name argument, ordered by match quality. - * - * @param expectedType the qualified type of the parameter we are trying to match - * @param paramName the name of the parameter (used to find similarly named matches) - * @param pos the position - * @param suggestions the suggestions or null - * @param fillBestGuess true if the best guess should be filled in - * @param isLastParameter true iff this proposal is for the last parameter of a method - * @return returns the name of the best match, or null if no match found - */ - public ICompletionProposal[] parameterProposals(IType expectedType, String paramName, Position pos, - ArrayList suggestions, boolean fillBestGuess, boolean isLastParameter) - throws CModelException { - List typeMatches = evaluateVisibleMatches(expectedType, suggestions); - typeMatches = removeDuplicates(typeMatches); - orderMatches(typeMatches, paramName); - - ICompletionProposal[] ret = new ICompletionProposal[typeMatches.size()]; - int i = 0; - int replacementLength = 0; - for (Iterator it = typeMatches.iterator(); it.hasNext();) { - Variable v = it.next(); - if (i == 0) { - fAlreadyMatchedNames.add(v.name); - replacementLength = v.name.length(); - } - - String displayString = v.name; - - final char[] triggers; - if (isLastParameter) { - triggers = v.triggerChars; - } else { - triggers = new char[v.triggerChars.length + 1]; - System.arraycopy(v.triggerChars, 0, triggers, 0, v.triggerChars.length); - triggers[triggers.length - 1] = ','; - } - ret[i++] = new PositionBasedCompletionProposal(v.name, pos, replacementLength, - getImage(v.descriptor), displayString, null, null, triggers); - } - if (ret.length == 0) { - // Add the parameter name - return new ICompletionProposal[] { new PositionBasedCompletionProposal(paramName, pos, - replacementLength, null, paramName, null, null, - isLastParameter ? null : new char[] { ',' }) }; - } - return ret; - } - - private static class MatchComparator implements Comparator { - private String fParamName; - - MatchComparator(String paramName) { - fParamName = paramName; - } - - @Override - public int compare(Variable one, Variable two) { - return score(two) - score(one); - } - - private static String getLongestCommonSubstring(String first, String second) { - // Now only considering the case where shorter string is part of longer string. - // TODO: Use a more smart technique to get the common string (i.e. suffix tree). - String shorterStr = (first.length() < second.length()) ? first : second; - String longerStr = (first == shorterStr) ? second : first; - if (longerStr.contains(shorterStr)) { - return shorterStr; - } else { - return ""; //$NON-NLS-1$ - } - } - - /** - * The four order criteria as described below - put already used into bit 10, all others into bits - * 0-9, 11-20, 21-30; 31 is sign - always 0 - * - * @param v the variable - * @return the score for v - */ - private int score(Variable v) { - int variableScore = 100 - v.variableType; // since these are increasing with distance - int subStringScore = getLongestCommonSubstring(v.name, fParamName).length(); - // Substring scores under 60% are not considered. - // This prevents marginal matches like a - ba and false - isBool that will - // destroy the sort order. - int shorter = Math.min(v.name.length(), fParamName.length()); - if (subStringScore < 0.6 * shorter) - subStringScore = 0; - - int positionScore = v.positionScore; - int matchedScore = v.alreadyMatched ? 0 : 1; - - int score = variableScore << 21 | subStringScore << 11 | matchedScore << 10 | positionScore; - return score; - } - } - - /** - * Determines the best match of all possible type matches. The input into this method is all possible - * completions that match the type of the argument. The purpose of this method is to choose among them - * based on the following simple rules: - * - * 1) Local Variables > Instance/Class Variables > Inherited Instance/Class Variables - * - * 2) A longer case insensitive substring match will prevail - * - * 3) Variables that have not been used already during this completion will prevail over those that have - * already been used (this avoids the same String/int/char from being passed in for multiple arguments) - * - * 4) A better source position score will prevail (the declaration point of the variable, or - * "how close to the point of completion?" - * - * @param typeMatches - * the list of type matches - * @param paramName - * the parameter name - */ - private static void orderMatches(List typeMatches, String paramName) { - if (typeMatches != null) - Collections.sort(typeMatches, new MatchComparator(paramName)); - } - - /** - * Removes the duplicates from the list if any. - */ - private static List removeDuplicates(List typeMatches) { - HashSet set = new HashSet<>(); - set.addAll(typeMatches); - return Arrays.asList(set.toArray(new Variable[set.size()])); - } - - private Image getImage(ImageDescriptor descriptor) { - return (descriptor == null) ? null : CUIPlugin.getImageDescriptorRegistry().get(descriptor); - } -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ParameterGuessingProposal.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ParameterGuessingProposal.java deleted file mode 100644 index a0cd40513b6..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ParameterGuessingProposal.java +++ /dev/null @@ -1,408 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2015 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: - * Andrew McCullough - initial API and implementation - * IBM Corporation - general improvement and bug fixes, partial reimplementation - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. - *******************************************************************************/ -package org.eclipse.cdt.internal.ui.text.contentassist; - -import java.util.ArrayList; -import java.util.Arrays; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.BadPositionCategoryException; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IPositionUpdater; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.Region; -import org.eclipse.jface.text.contentassist.ICompletionProposal; -import org.eclipse.jface.text.link.ILinkedModeListener; -import org.eclipse.jface.text.link.InclusivePositionUpdater; -import org.eclipse.jface.text.link.LinkedModeModel; -import org.eclipse.jface.text.link.LinkedModeUI; -import org.eclipse.jface.text.link.LinkedModeUI.ExitFlags; -import org.eclipse.jface.text.link.LinkedPosition; -import org.eclipse.jface.text.link.LinkedPositionGroup; -import org.eclipse.jface.text.link.ProposalPosition; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.texteditor.link.EditorLinkedModeUI; - -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IFunction; -import org.eclipse.cdt.core.dom.ast.IParameter; -import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.ui.CUIPlugin; - -import org.eclipse.cdt.internal.ui.editor.CEditor; -import org.eclipse.cdt.internal.ui.editor.EditorHighlightingSynchronizer; - -/** - * This class is based on org.eclipse.jdt.internal.ui.text.java.ParameterGuessingProposal - * - * Extents the basic Function Compilation Proposal to add a linked mode for each of the function parameters - * with a list of suggestions for each parameter. - */ -public class ParameterGuessingProposal extends FunctionCompletionProposal { - private ICompletionProposal[][] fChoices; // initialized by guessParameters() - private Position[] fPositions; // initialized by guessParameters() - private boolean fReplacementStringComputed; - private IRegion fSelectedRegion; // initialized by apply() - private IPositionUpdater fUpdater; - private String fFullPrefix; // The string from the start of the statement to the invocation offset. - private char[][] fParametersNames; - private IType[] fParametersTypes; - private ArrayList fAssignableElemebts; - - public static ParameterGuessingProposal createProposal(CContentAssistInvocationContext context, - ArrayList availableElements, CCompletionProposal proposal, IFunction function, - String prefix) { - String replacement = getParametersList(function); - String fullPrefix = function.getName() + "("; //$NON-NLS-1$ - int replacementOffset = proposal.getReplacementOffset(); - int replacementLength = 0; - int invocationOffset = context.getInvocationOffset(); - int parseOffset = context.getParseOffset(); - IASTTranslationUnit translationUnit = context.getCompletionNode().getTranslationUnit(); - IDocument document = context.getDocument(); - /* - * Adjust the replacement offset, the replacement string and the replacement length for the case of - * invoking after '('. - The replacement offset will be calculated to point to the start of the - * function call statement, as in that case the proposal.getReplacementOffset() doesn't point to that. - * - The replacement string will contain the in-editor prefix instead of the function name only, to - * handle the case of C++ function templates. - The length will be updated after changing the - * replacement string. - */ - if (isInsideBracket(invocationOffset, parseOffset)) { - replacementOffset = parseOffset - prefix.length(); - try { - fullPrefix = document.get(replacementOffset, invocationOffset - replacementOffset); - replacement = fullPrefix + replacement + ")"; //$NON-NLS-1$ - } catch (BadLocationException e1) { - } - try { - // remove ')' from the replacement string if it is auto appended. - if (document.getChar(invocationOffset) == ')') - replacement = replacement.substring(0, replacement.length() - 1); - } catch (BadLocationException e) { - } - } else { - replacement = fullPrefix + replacement + ")"; //$NON-NLS-1$ - replacementOffset = proposal.getReplacementOffset(); - } - replacementLength = replacement.length(); - ParameterGuessingProposal ret = new ParameterGuessingProposal(replacement, replacementOffset, - replacementLength, proposal.getImage(), proposal.getDisplayString(), proposal.getIdString(), - proposal.getRelevance(), context.getViewer(), function, invocationOffset, parseOffset, - translationUnit, document); - ret.setContextInformation(proposal.getContextInformation()); - ret.fFullPrefix = fullPrefix; - /* - * Get all defined elements before the start of the statement. ex: int a = foo( ^ --> We don't want - * 'a' as a suggestion. ex2: char* foo(int a, int b) {return NULL;} void bar(char* name){} ... - * bar(foo( ^ --> If this offset is used, the only defined name will be "bar(char*)". - */ - ret.fAssignableElemebts = availableElements; - ret.getReplacementString(); - return ret; - } - - /** - * Returns a comma-separated list of parameters - */ - private static String getParametersList(IFunction method) { - StringBuilder params = new StringBuilder(); - for (IParameter param : method.getParameters()) { - if (params.length() != 0) - params.append(", "); //$NON-NLS-1$ - params.append(param.getName()); - } - return params.toString(); - } - - public ParameterGuessingProposal(String replacementString, int replacementOffset, int replacementLength, - Image image, String displayString, String idString, int relevance, ITextViewer viewer, - IFunction function, int invocationOffset, int parseOffset, IASTTranslationUnit translationUnit, - IDocument document) { - super(replacementString, replacementOffset, replacementLength, image, displayString, idString, - relevance, viewer, function, invocationOffset, parseOffset, translationUnit, document); - fParametersNames = getFunctionParametersNames(fFunctionParameters); - fParametersTypes = getFunctionParametersTypes(fFunctionParameters); - } - - /** - * Checks if the invocation of content assist was after open bracket. - */ - private static boolean isInsideBracket(int invocationOffset, int parseOffset) { - return invocationOffset - parseOffset != 0; - } - - /** - * {@inheritDoc} - */ - @Override - public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) { - if (isInsideBracket(fInvocationOffset, fParseOffset)) { - try { - return fDocument.get(getReplacementOffset(), fInvocationOffset - getReplacementOffset()); - } catch (BadLocationException e) { - } - } - return super.getPrefixCompletionText(document, completionOffset); - } - - @Override - public void apply(final IDocument document, char trigger, int offset) { - try { - super.apply(document, trigger, offset); - - int baseOffset = getReplacementOffset(); - String replacement = getReplacementString(); - - if (fPositions != null && fTextViewer != null) { - LinkedModeModel model = new LinkedModeModel(); - - for (int i = 0; i < fPositions.length; i++) { - LinkedPositionGroup group = new LinkedPositionGroup(); - int positionOffset = fPositions[i].getOffset(); - int positionLength = fPositions[i].getLength(); - - if (fChoices[i].length < 2) { - group.addPosition(new LinkedPosition(document, positionOffset, positionLength, - LinkedPositionGroup.NO_STOP)); - } else { - ensurePositionCategoryInstalled(document, model); - document.addPosition(getCategory(), fPositions[i]); - group.addPosition(new ProposalPosition(document, positionOffset, positionLength, - LinkedPositionGroup.NO_STOP, fChoices[i])); - } - model.addGroup(group); - } - - model.forceInstall(); - CEditor editor = getCEditor(); - if (editor != null) { - model.addLinkingListener(new EditorHighlightingSynchronizer(editor)); - } - - LinkedModeUI ui = new EditorLinkedModeUI(model, fTextViewer); - ui.setExitPosition(fTextViewer, baseOffset + replacement.length(), 0, Integer.MAX_VALUE); - // exit character can be either ')' or ';' - final char exitChar = replacement.charAt(replacement.length() - 1); - ui.setExitPolicy(new ExitPolicy(exitChar) { - @Override - public ExitFlags doExit(LinkedModeModel model2, VerifyEvent event, int offset2, int length) { - if (event.character == ',') { - for (int i = 0; i < fPositions.length - 1; i++) { // not for the last one - Position position = fPositions[i]; - if (position.offset <= offset2 - && offset2 + length <= position.offset + position.length) { - event.character = '\t'; - event.keyCode = SWT.TAB; - return null; - } - } - } else if (event.character == ')' && exitChar != ')') { - // exit from link mode when user is in the last ')' position. - Position position = fPositions[fPositions.length - 1]; - if (position.offset <= offset2 - && offset2 + length <= position.offset + position.length) { - return new ExitFlags(ILinkedModeListener.UPDATE_CARET, false); - } - } - return super.doExit(model2, event, offset2, length); - } - }); - ui.setCyclingMode(LinkedModeUI.CYCLE_WHEN_NO_PARENT); - ui.setDoContextInfo(true); - ui.enter(); - fSelectedRegion = ui.getSelectedRegion(); - } else { - fSelectedRegion = new Region(baseOffset + replacement.length(), 0); - } - - } catch (BadLocationException | BadPositionCategoryException e) { - ensurePositionCategoryRemoved(document); - CUIPlugin.log(e); - } - } - - @Override - public Point getSelection(IDocument document) { - if (fSelectedRegion == null) - return new Point(getReplacementOffset(), 0); - - return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength()); - } - - @Override - public String getReplacementString() { - if (!fReplacementStringComputed) { - String rep = computeReplacementString(); - setReplacementString(rep); - setReplacementLength(rep.length()); - fReplacementStringComputed = true; - } - return super.getReplacementString(); - } - - private String computeReplacementString() { - if (!hasParameters()) - return super.getReplacementString(); - - String replacement; - try { - replacement = computeGuessingCompletion(); - } catch (Exception x) { - fPositions = null; - fChoices = null; - CUIPlugin.log(x); - return super.getReplacementString(); - } - - return replacement; - } - - private String computeGuessingCompletion() throws Exception { - StringBuffer buffer = new StringBuffer(); - buffer.append(fFullPrefix); - setCursorPosition(buffer.length()); - - for (int i = 0; i < fFunctionParameters.length; i++) { - fParametersNames[i] = fFunctionParameters[i].getNameCharArray(); - } - - fChoices = guessParameters(fParametersNames); - int count = fChoices.length; - int replacementOffset = getReplacementOffset(); - - for (int i = 0; i < count; i++) { - if (i != 0) - buffer.append(", "); //$NON-NLS-1$ - - ICompletionProposal proposal = fChoices[i][0]; - String argument = proposal.getDisplayString(); - - Position position = fPositions[i]; - position.setOffset(replacementOffset + buffer.length()); - position.setLength(argument.length()); - - if (proposal instanceof CCompletionProposal) // handle the "unknown" case where we only insert a - // proposal. - ((CCompletionProposal) proposal).setReplacementOffset(replacementOffset + buffer.length()); - buffer.append(argument); - } - - buffer.append(")"); //$NON-NLS-1$ - - return buffer.toString(); - } - - private ICompletionProposal[][] guessParameters(char[][] parameterNames) throws Exception { - int count = parameterNames.length; - fPositions = new Position[count]; - fChoices = new ICompletionProposal[count][]; - - ParameterGuesser guesser = new ParameterGuesser(fTranslationUnit); - - for (int i = 0; i < count; i++) { - String paramName = new String(parameterNames[i]); - Position position = new Position(0, 0); - - boolean isLastParameter = i == count - 1; - ArrayList allProposals = new ArrayList(); - ICompletionProposal[] argumentProposals = guesser.parameterProposals(fParametersTypes[i], - paramName, position, fAssignableElemebts, true, isLastParameter); - allProposals.addAll(Arrays.asList(argumentProposals)); - fPositions[i] = position; - fChoices[i] = argumentProposals; - } - - return fChoices; - } - - private static IType[] getFunctionParametersTypes(IParameter[] functionParameters) { - IType[] ret = new IType[functionParameters.length]; - for (int i = 0; i < functionParameters.length; i++) { - ret[i] = functionParameters[i].getType(); - } - return ret; - } - - private static char[][] getFunctionParametersNames(IParameter[] functionParameters) { - char[][] parameterNames = new char[functionParameters.length][]; - for (int i = 0; i < functionParameters.length; i++) { - parameterNames[i] = functionParameters[i].getNameCharArray(); - } - return parameterNames; - } - - private void ensurePositionCategoryInstalled(final IDocument document, LinkedModeModel model) { - if (!document.containsPositionCategory(getCategory())) { - document.addPositionCategory(getCategory()); - fUpdater = new InclusivePositionUpdater(getCategory()); - document.addPositionUpdater(fUpdater); - - model.addLinkingListener(new ILinkedModeListener() { - @Override - public void left(LinkedModeModel environment, int flags) { - ensurePositionCategoryRemoved(document); - } - - @Override - public void suspend(LinkedModeModel environment) { - } - - @Override - public void resume(LinkedModeModel environment, int flags) { - } - }); - } - } - - private void ensurePositionCategoryRemoved(IDocument document) { - if (document.containsPositionCategory(getCategory())) { - try { - document.removePositionCategory(getCategory()); - } catch (BadPositionCategoryException e) { - // ignore - } - document.removePositionUpdater(fUpdater); - } - } - - private String getCategory() { - return "ParameterGuessingProposal_" + toString(); //$NON-NLS-1$ - } - - /** - * Returns the currently active C/C++ editor, or null if it cannot be determined. - */ - private static CEditor getCEditor() { - IEditorPart part = CUIPlugin.getActivePage().getActiveEditor(); - if (part instanceof CEditor) { - return (CEditor) part; - } else { - return null; - } - } - - /** - * Returns the guesses for each parameter - */ - public ICompletionProposal[][] getParametersGuesses() { - return fChoices; - } -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/PositionBasedCompletionProposal.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/PositionBasedCompletionProposal.java deleted file mode 100644 index bc809cc195f..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/PositionBasedCompletionProposal.java +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2015 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 Corporation - initial API and implementation - * Mohamed Azab (Mentor Graphics) - Bug 438549. Add mechanism for parameter guessing. - *******************************************************************************/ -package org.eclipse.cdt.internal.ui.text.contentassist; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.contentassist.ICompletionProposal; -import org.eclipse.jface.text.contentassist.ICompletionProposalExtension; -import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2; -import org.eclipse.jface.text.contentassist.IContextInformation; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; - -/** - * An enhanced implementation of the ICompletionProposal interface implementing all the extension interfaces. - * It uses a position to track its replacement offset and length. The position must be set up externally. - */ -public class PositionBasedCompletionProposal implements ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2 { - /** The string to be displayed in the completion proposal popup */ - private String fDisplayString; - /** The replacement string */ - private String fReplacementString; - /** The replacement position. */ - private Position fReplacementPosition; - /** The cursor position after this proposal has been applied */ - private int fCursorPosition; - /** The image to be displayed in the completion proposal popup */ - private Image fImage; - /** The context information of this proposal */ - private IContextInformation fContextInformation; - /** The additional info of this proposal */ - private String fAdditionalProposalInfo; - /** The trigger characters */ - private char[] fTriggerCharacters; - - /** - * Creates a new completion proposal based on the provided information. The replacement string is - * considered being the display string too. All remaining fields are set to null. - * - * @param replacementString the actual string to be inserted into the document - * @param replacementPosition the position of the text to be replaced - * @param cursorPosition the position of the cursor following the insert relative to replacementOffset - */ - public PositionBasedCompletionProposal(String replacementString, Position replacementPosition, int cursorPosition) { - this(replacementString, replacementPosition, cursorPosition, null, null, null, null, null); - } - - /** - * Creates a new completion proposal. All fields are initialized based on the provided information. - * - * @param replacementString the actual string to be inserted into the document - * @param replacementPosition the position of the text to be replaced - * @param cursorPosition the position of the cursor following the insert relative to replacementOffset - * @param image the image to display for this proposal - * @param displayString the string to be displayed for the proposal - * @param contextInformation the context information associated with this proposal - * @param additionalProposalInfo the additional information associated with this proposal - * @param triggers the trigger characters - */ - public PositionBasedCompletionProposal(String replacementString, Position replacementPosition, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, char[] triggers) { - Assert.isNotNull(replacementString); - Assert.isTrue(replacementPosition != null); - - fReplacementString= replacementString; - fReplacementPosition= replacementPosition; - fCursorPosition= cursorPosition; - fImage= image; - fDisplayString= displayString; - fContextInformation= contextInformation; - fAdditionalProposalInfo= additionalProposalInfo; - fTriggerCharacters= triggers; - } - - @Override - public void apply(IDocument document) { - try { - document.replace(fReplacementPosition.getOffset(), fReplacementPosition.getLength(), fReplacementString); - } catch (BadLocationException x) { - // ignore - } - } - - @Override - public Point getSelection(IDocument document) { - return new Point(fReplacementPosition.getOffset() + fCursorPosition, 0); - } - - @Override - public IContextInformation getContextInformation() { - return fContextInformation; - } - - @Override - public Image getImage() { - return fImage; - } - - @Override - public String getDisplayString() { - if (fDisplayString != null) - return fDisplayString; - return fReplacementString; - } - - @Override - public String getAdditionalProposalInfo() { - return fAdditionalProposalInfo; - } - - @Override - public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { - apply(viewer.getDocument()); - } - - @Override - public void selected(ITextViewer viewer, boolean smartToggle) { - } - - @Override - public void unselected(ITextViewer viewer) { - } - - @Override - public boolean validate(IDocument document, int offset, DocumentEvent event) { - try { - String content= document.get(fReplacementPosition.getOffset(), offset - fReplacementPosition.getOffset()); - if (fReplacementString.startsWith(content)) - return true; - } catch (BadLocationException e) { - // ignore concurrently modified document - } - return false; - } - - @Override - public void apply(IDocument document, char trigger, int offset) { - // not called any more - } - - @Override - public boolean isValidFor(IDocument document, int offset) { - // not called any more - return false; - } - - @Override - public char[] getTriggerCharacters() { - return fTriggerCharacters; - } - - @Override - public int getContextInformationPosition() { - return fReplacementPosition.getOffset(); - } -} -