mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 06:32:10 +02:00
Bug 379631 - code-completion of functions in using-declarations
Change-Id: Ifae9e0e790629e03c1ad93988ea535e42373d448 Reviewed-on: https://git.eclipse.org/r/9066 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
032c010a82
commit
d159cd9545
3 changed files with 97 additions and 13 deletions
|
@ -12,10 +12,9 @@
|
||||||
* IBM Corporation
|
* IBM Corporation
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
|
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui.tests.text.contentassist2;
|
package org.eclipse.cdt.ui.tests.text.contentassist2;import java.io.File;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -28,6 +27,7 @@ import org.eclipse.jface.text.IDocument;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.testplugin.TestScannerProvider;
|
import org.eclipse.cdt.core.testplugin.TestScannerProvider;
|
||||||
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||||
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of code completion tests.
|
* A collection of code completion tests.
|
||||||
|
@ -1365,4 +1365,13 @@ public class CompletionTests extends AbstractContentAssistTest {
|
||||||
final String[] expected= { "__builtin_va_arg(ap, type)" };
|
final String[] expected= { "__builtin_va_arg(ap, type)" };
|
||||||
assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS);
|
assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// namespace N {
|
||||||
|
// void foo(int);
|
||||||
|
// }
|
||||||
|
// using N::f/*cursor*/
|
||||||
|
public void testUsingDeclaration_Bug379631() throws Exception {
|
||||||
|
final String[] expected= { "foo;" };
|
||||||
|
assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2010 IBM Corporation and others.
|
* Copyright (c) 2000, 2012 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
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Sergey Prigogin, Google
|
* Sergey Prigogin, Google
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text;
|
package org.eclipse.cdt.internal.ui.text;
|
||||||
|
|
||||||
|
@ -1202,4 +1203,31 @@ public final class CHeuristicScanner implements Symbols {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simplified interface to CHeuristicScanner's
|
||||||
|
* nextToken() and previousToken() methods.
|
||||||
|
*/
|
||||||
|
public static class TokenStream {
|
||||||
|
private CHeuristicScanner fScanner;
|
||||||
|
private int fPos;
|
||||||
|
private final int fDocumentLength;
|
||||||
|
|
||||||
|
public TokenStream(IDocument document, int startPos) {
|
||||||
|
fScanner = new CHeuristicScanner(document);
|
||||||
|
fPos = startPos;
|
||||||
|
fDocumentLength = document.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextToken() {
|
||||||
|
int result = fScanner.nextToken(fPos, fDocumentLength);
|
||||||
|
fPos = fScanner.getPosition();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int previousToken() {
|
||||||
|
int result = fScanner.previousToken(fPos, 0);
|
||||||
|
fPos = fScanner.getPosition();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007, 2011 QNX Software Systems and others.
|
* Copyright (c) 2007, 2012 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
|
||||||
|
@ -11,6 +11,7 @@
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
|
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||||
|
|
||||||
|
@ -83,6 +84,8 @@ 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.dom.parser.cpp.semantics.AccessContext;
|
||||||
import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
|
import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.Symbols;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,7 +94,6 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
||||||
* @author Bryan Wilkinson
|
* @author Bryan Wilkinson
|
||||||
*/
|
*/
|
||||||
public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer {
|
public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor is required (executable extension).
|
* Default constructor is required (executable extension).
|
||||||
*/
|
*/
|
||||||
|
@ -152,6 +154,40 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
||||||
return proposals;
|
return proposals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the invocation offset is inside a using-declaration.
|
||||||
|
*
|
||||||
|
* @param context the invocation context
|
||||||
|
* @return {@code true} if the invocation offset is inside a using-declaration
|
||||||
|
*/
|
||||||
|
private boolean inUsingDeclaration(CContentAssistInvocationContext context) {
|
||||||
|
IDocument doc = context.getDocument();
|
||||||
|
int offset = context.getInvocationOffset();
|
||||||
|
|
||||||
|
// Look at the tokens preceding the invocation offset.
|
||||||
|
CHeuristicScanner.TokenStream tokenStream = new CHeuristicScanner.TokenStream(doc, offset);
|
||||||
|
int token = tokenStream.previousToken();
|
||||||
|
|
||||||
|
// There may be a partially typed identifier which is being completed.
|
||||||
|
if (token == Symbols.TokenIDENT)
|
||||||
|
token = tokenStream.previousToken();
|
||||||
|
|
||||||
|
// Before that, there may be any number of "namespace::" token pairs.
|
||||||
|
while (token == Symbols.TokenDOUBLECOLON) {
|
||||||
|
token = tokenStream.previousToken();
|
||||||
|
if (token == Symbols.TokenUSING) { // there could also be a leading "::" for global namespace
|
||||||
|
return true;
|
||||||
|
} else if (token != Symbols.TokenIDENT) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
token = tokenStream.previousToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before that, there must be a "using" token.
|
||||||
|
return token == Symbols.TokenUSING;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether the invocation offset is inside or before the preprocessor directive keyword.
|
* Test whether the invocation offset is inside or before the preprocessor directive keyword.
|
||||||
*
|
*
|
||||||
|
@ -377,10 +413,11 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
||||||
|
|
||||||
StringBuilder repStringBuff = new StringBuilder();
|
StringBuilder repStringBuff = new StringBuilder();
|
||||||
repStringBuff.append(function.getName());
|
repStringBuff.append(function.getName());
|
||||||
|
|
||||||
repStringBuff.append('(');
|
repStringBuff.append('(');
|
||||||
|
|
||||||
StringBuilder dispargs = new StringBuilder(); // for the dispargString
|
StringBuilder dispargs = new StringBuilder(); // for the dispargString
|
||||||
StringBuilder idargs = new StringBuilder(); // for the idargString
|
StringBuilder idargs = new StringBuilder(); // for the idargString
|
||||||
boolean hasArgs = true;
|
boolean hasArgs = true;
|
||||||
String returnTypeStr = null;
|
String returnTypeStr = null;
|
||||||
IParameter[] params = function.getParameters();
|
IParameter[] params = function.getParameters();
|
||||||
|
@ -388,12 +425,12 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
||||||
for (int i = 0; i < params.length; ++i) {
|
for (int i = 0; i < params.length; ++i) {
|
||||||
IType paramType = params[i].getType();
|
IType paramType = params[i].getType();
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
dispargs.append(',');
|
dispargs.append(',');
|
||||||
idargs.append(',');
|
idargs.append(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
dispargs.append(ASTTypeUtil.getType(paramType, false));
|
dispargs.append(ASTTypeUtil.getType(paramType, false));
|
||||||
idargs.append(ASTTypeUtil.getType(paramType, false));
|
idargs.append(ASTTypeUtil.getType(paramType, false));
|
||||||
String paramName = params[i].getName();
|
String paramName = params[i].getName();
|
||||||
if (paramName != null && paramName.length() > 0) {
|
if (paramName != null && paramName.length() > 0) {
|
||||||
dispargs.append(' ');
|
dispargs.append(' ');
|
||||||
|
@ -439,7 +476,17 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
||||||
idStringBuff.append(')');
|
idStringBuff.append(')');
|
||||||
String idString = idStringBuff.toString();
|
String idString = idStringBuff.toString();
|
||||||
|
|
||||||
repStringBuff.append(')');
|
// In a using declaration, emitting parentheses after the function
|
||||||
|
// name is useless, since the user will just have to delete them.
|
||||||
|
// Instead, emitting a semicolon is useful.
|
||||||
|
boolean inUsingDeclaration = inUsingDeclaration(context);
|
||||||
|
if (inUsingDeclaration) {
|
||||||
|
repStringBuff.setLength(repStringBuff.length() - 1); // Remove opening parenthesis
|
||||||
|
repStringBuff.append(';');
|
||||||
|
} else {
|
||||||
|
repStringBuff.append(')');
|
||||||
|
}
|
||||||
|
|
||||||
String repString = repStringBuff.toString();
|
String repString = repStringBuff.toString();
|
||||||
|
|
||||||
final int relevance = function instanceof ICPPMethod ?
|
final int relevance = function instanceof ICPPMethod ?
|
||||||
|
@ -447,7 +494,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
||||||
CCompletionProposal proposal = createProposal(repString, dispString, idString,
|
CCompletionProposal proposal = createProposal(repString, dispString, idString,
|
||||||
context.getCompletionNode().getLength(), image, baseRelevance + relevance, context);
|
context.getCompletionNode().getLength(), image, baseRelevance + relevance, context);
|
||||||
if (!context.isContextInformationStyle()) {
|
if (!context.isContextInformationStyle()) {
|
||||||
int cursorPosition = hasArgs ? (repString.length() - 1) : repString.length();
|
int cursorPosition = (!inUsingDeclaration && hasArgs) ? (repString.length() - 1) : repString.length();
|
||||||
proposal.setCursorPosition(cursorPosition);
|
proposal.setCursorPosition(cursorPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue