mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 06:32:10 +02:00
Bug 430342 - Completion of template arguments.
Change-Id: Iaf1c43ce826f6676b941689f39fc81ea5e25daa8 Reviewed-on: https://git.eclipse.org/r/29440 Tested-by: Hudson CI Reviewed-by: Thomas Corbat <tcorbat@hsr.ch> Tested-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
parent
8649b65570
commit
875e21efb0
3 changed files with 133 additions and 34 deletions
|
@ -172,6 +172,16 @@ public class CompletionTests extends AbstractContentAssistTest {
|
|||
// namespace _B_331056 {
|
||||
// using ::_A_331056::Reference;
|
||||
// }
|
||||
//
|
||||
// template<typename T1, typename T2>
|
||||
// struct Specialization {
|
||||
// };
|
||||
// template<typename T2>
|
||||
// struct Specialization<int, T2> {
|
||||
// };
|
||||
// template<>
|
||||
// struct Specialization<int, int> {
|
||||
// };
|
||||
|
||||
public CompletionTests(String name) {
|
||||
super(name, true);
|
||||
|
@ -411,7 +421,7 @@ public class CompletionTests extends AbstractContentAssistTest {
|
|||
|
||||
//void C2::f() {T/*cursor*/
|
||||
public void testTypes_MethodScope() throws Exception {
|
||||
final String[] expected= { "T1", "T2", "T3", "TClass" };
|
||||
final String[] expected= { "T1", "T2", "T3", "TClass<typename T>" };
|
||||
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
|
||||
}
|
||||
|
||||
|
@ -1351,4 +1361,10 @@ public class CompletionTests extends AbstractContentAssistTest {
|
|||
final String[] expected = { "Cat", "meow(void)" };
|
||||
assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS);
|
||||
}
|
||||
|
||||
// void foo() { Spec/*cursor*/
|
||||
public void testTemplateSpecialization() throws Exception {
|
||||
final String[] expected = { "Specialization<typename T1, typename T2>" };
|
||||
assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS);
|
||||
}
|
||||
}
|
|
@ -210,21 +210,11 @@ public class CCompletionProposal implements ICCompletionProposal, ICompletionPro
|
|||
if (fTextViewer != null && string != null) {
|
||||
int index= string.indexOf("()"); //$NON-NLS-1$
|
||||
if (index != -1 && index + 1 == fCursorPosition) {
|
||||
int newOffset= fReplacementOffset + fCursorPosition;
|
||||
|
||||
LinkedPositionGroup group= new LinkedPositionGroup();
|
||||
group.addPosition(new LinkedPosition(document, newOffset, 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(')'));
|
||||
ui.setExitPosition(fTextViewer, newOffset + 1, 0, Integer.MAX_VALUE);
|
||||
ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER);
|
||||
ui.enter();
|
||||
addParameterListLinkedMode(document, ')');
|
||||
}
|
||||
index = string.indexOf("<>"); //$NON-NLS-1$
|
||||
if (index != -1 && index + 1 == fCursorPosition) {
|
||||
addParameterListLinkedMode(document, '>');
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException x) {
|
||||
|
@ -232,6 +222,24 @@ public class CCompletionProposal implements ICCompletionProposal, ICompletionPro
|
|||
}
|
||||
}
|
||||
|
||||
private void addParameterListLinkedMode(IDocument document, char endSymbol) throws BadLocationException {
|
||||
int newOffset= fReplacementOffset + fCursorPosition;
|
||||
|
||||
LinkedPositionGroup group= new LinkedPositionGroup();
|
||||
group.addPosition(new LinkedPosition(document, newOffset, 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(endSymbol));
|
||||
ui.setExitPosition(fTextViewer, newOffset + 1, 0, Integer.MAX_VALUE);
|
||||
ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER);
|
||||
ui.enter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to simplify tracking a reference position in a document.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2012 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
|
||||
|
@ -12,9 +12,11 @@
|
|||
* Sergey Prigogin (Google)
|
||||
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
|
||||
* Nathan Ridge
|
||||
* Thomas Corbat (IFS)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text.contentassist;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -56,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
|
@ -64,6 +67,10 @@ 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.ICPPTemplateNonTypeParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
@ -94,6 +101,10 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
|||
* @author Bryan Wilkinson
|
||||
*/
|
||||
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$;
|
||||
|
||||
/**
|
||||
* Default constructor is required (executable extension).
|
||||
*/
|
||||
|
@ -336,7 +347,8 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
|||
|| binding instanceof CImplicitFunction
|
||||
|| binding instanceof CImplicitTypedef
|
||||
|| binding instanceof CBuiltinVariable
|
||||
|| binding instanceof CBuiltinParameter)
|
||||
|| binding instanceof CBuiltinParameter
|
||||
|| binding instanceof ICPPClassTemplatePartialSpecialization)
|
||||
&& !(binding instanceof CPPImplicitMethod)) {
|
||||
return;
|
||||
}
|
||||
|
@ -375,26 +387,65 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
|||
return name.length == 0 || name[0] == '{';
|
||||
}
|
||||
|
||||
private void addProposalForClassTemplate(ICPPClassTemplate templateType, CContentAssistInvocationContext context,
|
||||
int baseRelevance, List<ICompletionProposal> proposals) {
|
||||
int relevance = getClassTypeRelevance(templateType);
|
||||
StringBuilder representation = new StringBuilder(templateType.getName());
|
||||
representation.append("<{0}>"); //$NON-NLS-1$
|
||||
|
||||
String representationString = MessageFormat.format(representation.toString(), ""); //$NON-NLS-1$
|
||||
|
||||
String templateParameterRepresentation = buildTemplateParameters(templateType);
|
||||
String displayString = MessageFormat.format(representation.toString(), templateParameterRepresentation);
|
||||
|
||||
CCompletionProposal proposal = createProposal(representationString, displayString, getImage(templateType),
|
||||
baseRelevance + relevance, context);
|
||||
|
||||
CProposalContextInformation info =
|
||||
new CProposalContextInformation(getImage(templateType), displayString, templateParameterRepresentation);
|
||||
info.setContextInformationPosition(context.getContextInformationOffset());
|
||||
proposal.setContextInformation(info);
|
||||
proposal.setCursorPosition(representationString.length() - 1);
|
||||
proposals.add(proposal);
|
||||
}
|
||||
|
||||
private String buildTemplateParameters(ICPPClassTemplate templateType) {
|
||||
ICPPTemplateParameter[] parameters = templateType.getTemplateParameters();
|
||||
StringBuilder representation = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
ICPPTemplateParameter parameter = parameters[i];
|
||||
if (i > 0) {
|
||||
representation.append(", "); //$NON-NLS-1$
|
||||
}
|
||||
if (parameter instanceof ICPPTemplateNonTypeParameter) {
|
||||
IType parameterType = ((ICPPTemplateNonTypeParameter) parameter).getType();
|
||||
String typeName = ASTTypeUtil.getType(parameterType);
|
||||
representation.append(typeName);
|
||||
} else if (parameter instanceof ICPPTemplateTypeParameter) {
|
||||
representation.append(TYPENAME);
|
||||
} else if (parameter instanceof ICPPTemplateTemplateParameter) {
|
||||
String templateParameterParameters = buildTemplateParameters((ICPPTemplateTemplateParameter) parameter);
|
||||
representation.append(MessageFormat.format(TEMPLATE_PARAMETER_PATTERN, templateParameterParameters));
|
||||
representation.append(templateParameterParameters);
|
||||
}
|
||||
if (parameter.isParameterPack()) {
|
||||
representation.append(ELLIPSIS);
|
||||
}
|
||||
representation.append(' ');
|
||||
representation.append(parameter.getName());
|
||||
}
|
||||
return representation.toString();
|
||||
}
|
||||
|
||||
private void handleClass(ICPPClassType classType, IASTCompletionContext astContext,
|
||||
CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) {
|
||||
if (context.isContextInformationStyle()) {
|
||||
ICPPConstructor[] constructors = classType.getConstructors();
|
||||
for (ICPPConstructor constructor : constructors) {
|
||||
handleFunction(constructor, context, baseRelevance, proposals);
|
||||
}
|
||||
addProposalsForConstructors(classType, context, baseRelevance, proposals);
|
||||
} else if (classType instanceof ICPPClassTemplate) {
|
||||
addProposalForClassTemplate((ICPPClassTemplate) classType, context, baseRelevance, proposals);
|
||||
} else {
|
||||
int relevance= 0;
|
||||
switch (classType.getKey()) {
|
||||
case ICPPClassType.k_class:
|
||||
relevance= RelevanceConstants.CLASS_TYPE_RELEVANCE;
|
||||
break;
|
||||
case ICompositeType.k_struct:
|
||||
relevance= RelevanceConstants.STRUCT_TYPE_RELEVANCE;
|
||||
break;
|
||||
case ICompositeType.k_union:
|
||||
relevance= RelevanceConstants.UNION_TYPE_RELEVANCE;
|
||||
break;
|
||||
}
|
||||
int relevance = getClassTypeRelevance(classType);
|
||||
if (astContext instanceof IASTName && !(astContext instanceof ICPPASTQualifiedName)) {
|
||||
IASTName name= (IASTName)astContext;
|
||||
if (name.getParent() instanceof IASTDeclarator) {
|
||||
|
@ -407,6 +458,30 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
|
|||
}
|
||||
}
|
||||
|
||||
private void addProposalsForConstructors(ICPPClassType classType,
|
||||
CContentAssistInvocationContext context, int baseRelevance, List<ICompletionProposal> proposals) {
|
||||
ICPPConstructor[] constructors = classType.getConstructors();
|
||||
for (ICPPConstructor constructor : constructors) {
|
||||
handleFunction(constructor, context, baseRelevance, proposals);
|
||||
}
|
||||
}
|
||||
|
||||
private int getClassTypeRelevance(ICPPClassType classType) {
|
||||
int relevance= 0;
|
||||
switch (classType.getKey()) {
|
||||
case ICPPClassType.k_class:
|
||||
relevance= RelevanceConstants.CLASS_TYPE_RELEVANCE;
|
||||
break;
|
||||
case ICompositeType.k_struct:
|
||||
relevance= RelevanceConstants.STRUCT_TYPE_RELEVANCE;
|
||||
break;
|
||||
case ICompositeType.k_union:
|
||||
relevance= RelevanceConstants.UNION_TYPE_RELEVANCE;
|
||||
break;
|
||||
}
|
||||
return relevance;
|
||||
}
|
||||
|
||||
private void handleFunction(IFunction function, CContentAssistInvocationContext context,
|
||||
int baseRelevance, List<ICompletionProposal> proposals) {
|
||||
Image image = getImage(function);
|
||||
|
|
Loading…
Add table
Reference in a new issue