1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 495095 - Consider implicit conversions when guessing parameters

Change-Id: Ie8c24148b227c39c58c58db887a75337bb064a0a
This commit is contained in:
Nathan Ridge 2016-06-01 03:28:55 -04:00
parent bb8f775f99
commit fe88f1f305
2 changed files with 30 additions and 7 deletions

View file

@ -25,6 +25,9 @@ import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
@ -51,6 +54,11 @@ import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.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; import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
/** /**
@ -104,12 +112,13 @@ public class ParameterGuesser {
} }
} }
private Collection<Variable> evaluateVisibleMatches(IType expectedType, List<IBinding> suggestions) private Collection<Variable> evaluateVisibleMatches(IType expectedType, List<IBinding> suggestions,
IASTTranslationUnit ast)
throws CModelException { throws CModelException {
Set<Variable> res = new HashSet<>(); Set<Variable> res = new HashSet<>();
int size = suggestions.size(); int size = suggestions.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Variable variable = createVariable(suggestions.get(i), expectedType, i); Variable variable = createVariable(suggestions.get(i), expectedType, i, ast);
if (variable != null) { if (variable != null) {
if (fAlreadyMatchedNames.contains(variable.name)) { if (fAlreadyMatchedNames.contains(variable.name)) {
variable.alreadyMatched = true; variable.alreadyMatched = true;
@ -131,13 +140,15 @@ public class ParameterGuesser {
return null; return null;
} }
private Variable createVariable(IBinding element, IType enclosingType, int positionScore) private Variable createVariable(IBinding element, IType enclosingType, int positionScore,
IASTTranslationUnit ast)
throws CModelException { throws CModelException {
IType elementType = getType(element); IType elementType = getType(element);
String elementName = element.getName(); String elementName = element.getName();
if (elementType != null if (elementType != null
&& (elementType.toString().equals(enclosingType.toString()) && (elementType.toString().equals(enclosingType.toString())
|| elementType.isSameType(enclosingType) || elementType.isSameType(enclosingType)
|| isImplicitlyConvertible(enclosingType, elementType, ast)
|| isParent(elementType, enclosingType) || isParent(elementType, enclosingType)
|| isReferenceTo(enclosingType, elementType) || isReferenceTo(enclosingType, elementType)
|| isReferenceTo(elementType, enclosingType))) { || isReferenceTo(elementType, enclosingType))) {
@ -175,6 +186,18 @@ public class ParameterGuesser {
} }
return false; return false;
} }
private boolean isImplicitlyConvertible(IType orginType, IType candidateType, IASTNode point) {
try {
Cost cost = Conversions.checkImplicitConversionSequence(orginType, candidateType,
ValueCategory.LVALUE, UDCMode.ALLOWED, Context.ORDINARY, point);
if (cost.converts())
return true;
} catch (DOMException e) {
return false;
}
return false;
}
/** /**
* Returns true, if the parent type is a direct/indirect parent of the child type * Returns true, if the parent type is a direct/indirect parent of the child type
@ -267,9 +290,9 @@ public class ParameterGuesser {
* @return returns the name of the best match, or <code>null</code> if no match found * @return returns the name of the best match, or <code>null</code> if no match found
*/ */
public ICompletionProposal[] parameterProposals(IType expectedType, String paramName, Position pos, public ICompletionProposal[] parameterProposals(IType expectedType, String paramName, Position pos,
List<IBinding> suggestions, boolean isLastParameter) List<IBinding> suggestions, boolean isLastParameter, IASTTranslationUnit ast)
throws CModelException { throws CModelException {
List<Variable> typeMatches = new ArrayList<>(evaluateVisibleMatches(expectedType, suggestions)); List<Variable> typeMatches = new ArrayList<>(evaluateVisibleMatches(expectedType, suggestions, ast));
orderMatches(typeMatches, paramName); orderMatches(typeMatches, paramName);
ICompletionProposal[] ret = new ICompletionProposal[typeMatches.size()]; ICompletionProposal[] ret = new ICompletionProposal[typeMatches.size()];

View file

@ -294,7 +294,7 @@ public class ParameterGuessingProposal extends FunctionCompletionProposal {
boolean isLastParameter = i == count - 1; boolean isLastParameter = i == count - 1;
ArrayList<ICompletionProposal> allProposals = new ArrayList<>(); ArrayList<ICompletionProposal> allProposals = new ArrayList<>();
ICompletionProposal[] argumentProposals = guesser.parameterProposals(fParametersTypes[i], ICompletionProposal[] argumentProposals = guesser.parameterProposals(fParametersTypes[i],
paramName, position, fAssignableElements, isLastParameter); paramName, position, fAssignableElements, isLastParameter, ast);
allProposals.addAll(Arrays.asList(argumentProposals)); allProposals.addAll(Arrays.asList(argumentProposals));
fPositions[i] = position; fPositions[i] = position;
fChoices[i] = argumentProposals; fChoices[i] = argumentProposals;