1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 456293 - Completion of destructor name

Change-Id: I53422b1daf693e8ab6c0ad64857e8b07c970444c
This commit is contained in:
Nathan Ridge 2017-01-11 02:12:42 -05:00
parent 0a23da7e56
commit 7023f59741
2 changed files with 48 additions and 21 deletions

View file

@ -1379,6 +1379,17 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected = { "Waldo(const Waldo &)", "Waldo(int, int)" }; final String[] expected = { "Waldo(const Waldo &)", "Waldo(int, int)" };
assertCompletionResults(fCursorOffset, expected, ID); assertCompletionResults(fCursorOffset, expected, ID);
} }
// struct Waldo {
// ~Waldo();
// };
// Waldo::~/*cursor*/
public void testDestructorDefinition_456293() throws Exception {
final String[] expectedDisplay = { "~Waldo(void)" };
assertContentAssistResults(fCursorOffset, expectedDisplay, true, DISPLAY);
final String[] expectedReplacement = { "Waldo()" };
assertContentAssistResults(fCursorOffset, expectedReplacement, true, REPLACEMENT);
}
// template <typename T> struct vector { // template <typename T> struct vector {
// typedef T value_type; // typedef T value_type;

View file

@ -355,9 +355,9 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
handleClass((ICPPClassType) binding, astContext, cContext, baseRelevance, proposals); handleClass((ICPPClassType) binding, astContext, cContext, baseRelevance, proposals);
} else if (binding instanceof IFunction) { } else if (binding instanceof IFunction) {
handleFunction((IFunction) binding, cContext, baseRelevance, proposals); handleFunction((IFunction) binding, astContext, cContext, baseRelevance, proposals);
} else if (binding instanceof IVariable) { } else if (binding instanceof IVariable) {
handleVariable((IVariable) binding, cContext, baseRelevance, proposals); handleVariable((IVariable) binding, astContext, cContext, baseRelevance, proposals);
} else if (!cContext.isContextInformationStyle()) { } else if (!cContext.isContextInformationStyle()) {
if (binding instanceof ITypedef) { if (binding instanceof ITypedef) {
proposals.add(createProposal(name, name, getImage(binding), proposals.add(createProposal(name, name, getImage(binding),
@ -464,7 +464,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
private void handleClass(ICPPClassType classType, IASTCompletionContext astContext, private void handleClass(ICPPClassType classType, IASTCompletionContext astContext,
CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) { CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) {
if (context.isContextInformationStyle() && context.isAfterOpeningParenthesis()) { if (context.isContextInformationStyle() && context.isAfterOpeningParenthesis()) {
addProposalsForConstructors(classType, context, baseRelevance, proposals); addProposalsForConstructors(classType, astContext, context, baseRelevance, proposals);
} else if (classType instanceof ICPPClassTemplate) { } else if (classType instanceof ICPPClassTemplate) {
addProposalForClassTemplate((ICPPClassTemplate) classType, context, baseRelevance, proposals); addProposalForClassTemplate((ICPPClassTemplate) classType, context, baseRelevance, proposals);
} else { } else {
@ -485,11 +485,11 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
} }
} }
private void addProposalsForConstructors(ICPPClassType classType, private void addProposalsForConstructors(ICPPClassType classType, IASTCompletionContext astContext,
CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) { CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) {
ICPPConstructor[] constructors = classType.getConstructors(); ICPPConstructor[] constructors = classType.getConstructors();
for (ICPPConstructor constructor : constructors) { for (ICPPConstructor constructor : constructors) {
handleFunction(constructor, context, baseRelevance, proposals); handleFunction(constructor, astContext, context, baseRelevance, proposals);
} }
} }
@ -509,14 +509,30 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
return relevance; return relevance;
} }
private void handleFunction(IFunction function, CContentAssistInvocationContext context, private String getFunctionNameForReplacement(IFunction function, IASTCompletionContext astContext) {
int baseRelevance, List<ICompletionProposal> proposals) { // If we are completiong a destructor name ...
if (function instanceof ICPPMethod && ((ICPPMethod) function).isDestructor()) {
if (astContext instanceof IASTName) {
char[] simpleId = ((IASTName) astContext).getLastName().getSimpleID();
// .. and the invocation site already contains the '~' ...
if (simpleId.length > 0 && simpleId[0] == '~') {
// ... then do not include the '~' in the replacement string.
// As far as the completion proposal computer is concerned, the '~' is not part
// of the prefix, so including it in the replacement would mean getting a second
// '~' in the resulting code.
return function.getName().substring(1);
}
}
}
return function.getName();
}
private void handleFunction(IFunction function, IASTCompletionContext astContext,
CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) {
Image image = getImage(function); Image image = getImage(function);
StringBuilder repStringBuff = new StringBuilder(); StringBuilder repStringBuff = new StringBuilder();
repStringBuff.append(function.getName()); repStringBuff.append(getFunctionNameForReplacement(function, astContext));
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
@ -577,7 +593,8 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
String dispArgString = dispArgs.toString(); String dispArgString = dispArgs.toString();
String idArgString = idArgs.toString(); String idArgString = idArgs.toString();
String contextDispargString = hasArgs ? dispArgString : null; String contextDispargString = hasArgs ? dispArgString : null;
StringBuilder dispStringBuff = new StringBuilder(repStringBuff); StringBuilder dispStringBuff = new StringBuilder(function.getName());
dispStringBuff.append('(');
dispStringBuff.append(dispArgString); dispStringBuff.append(dispArgString);
dispStringBuff.append(')'); dispStringBuff.append(')');
if (returnTypeStr != null && !returnTypeStr.isEmpty()) { if (returnTypeStr != null && !returnTypeStr.isEmpty()) {
@ -586,7 +603,8 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
} }
String dispString = dispStringBuff.toString(); String dispString = dispStringBuff.toString();
StringBuilder idStringBuff = new StringBuilder(repStringBuff); StringBuilder idStringBuff = new StringBuilder(function.getName());
idStringBuff.append('(');
idStringBuff.append(idArgString); idStringBuff.append(idArgString);
idStringBuff.append(')'); idStringBuff.append(')');
String idString = idStringBuff.toString(); String idString = idStringBuff.toString();
@ -595,13 +613,11 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
// name is useless, since the user will just have to delete them. // name is useless, since the user will just have to delete them.
// Instead, emitting a semicolon is useful. // Instead, emitting a semicolon is useful.
boolean inUsingDeclaration = context.isInUsingDirective(); boolean inUsingDeclaration = context.isInUsingDirective();
if (inUsingDeclaration) { if (!inUsingDeclaration) {
repStringBuff.setLength(repStringBuff.length() - 1); // Remove opening parenthesis repStringBuff.append('(');
if (!context.isFollowedBySemicolon()) {
repStringBuff.append(';');
}
} else {
repStringBuff.append(')'); repStringBuff.append(')');
} else if (!context.isFollowedBySemicolon()) {
repStringBuff.append(';');
} }
String repString = repStringBuff.toString(); String repString = repStringBuff.toString();
@ -753,8 +769,8 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
return !isDisplayDefaultedParameters() && param instanceof ICPPParameter && ((ICPPParameter)param).hasDefaultValue(); return !isDisplayDefaultedParameters() && param instanceof ICPPParameter && ((ICPPParameter)param).hasDefaultValue();
} }
private void handleVariable(IVariable variable, CContentAssistInvocationContext context, private void handleVariable(IVariable variable, IASTCompletionContext astContext,
int baseRelevance, List<ICompletionProposal> proposals) { CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) {
if (context.isContextInformationStyle()) { if (context.isContextInformationStyle()) {
IType t = variable.getType(); IType t = variable.getType();
t= unwindTypedefs(t); t= unwindTypedefs(t);
@ -763,7 +779,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
IASTTranslationUnit ast = context.getCompletionNode().getTranslationUnit(); IASTTranslationUnit ast = context.getCompletionNode().getTranslationUnit();
ICPPConstructor[] constructors = ClassTypeHelper.getConstructors(classType, ast); ICPPConstructor[] constructors = ClassTypeHelper.getConstructors(classType, ast);
for (ICPPConstructor constructor : constructors) { for (ICPPConstructor constructor : constructors) {
handleFunction(constructor, context, baseRelevance, proposals); handleFunction(constructor, astContext, context, baseRelevance, proposals);
} }
} }
return; return;