Added support to complete function-call operators.

This commit is contained in:
Roberto Raggi
2009-10-16 12:22:33 +02:00
parent 30f355dac3
commit 8b514657cc
4 changed files with 102 additions and 35 deletions

View File

@@ -857,7 +857,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
}
if (! resolvedTypes.isEmpty()) {
if (m_completionOperator == T_LPAREN && completeConstructorOrFunction(resolvedTypes)) {
if (m_completionOperator == T_LPAREN && completeConstructorOrFunction(resolvedTypes, context)) {
return m_startPosition;
} else if ((m_completionOperator == T_DOT || m_completionOperator == T_ARROW) &&
@@ -884,16 +884,19 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
QTextCursor tc(edit->document());
tc.setPosition(index);
QString baseExpression = expressionUnderCursor(tc);
const QString baseExpression = expressionUnderCursor(tc);
// Resolve the type of this expression
QList<TypeOfExpression::Result> results =
typeOfExpression(baseExpression, thisDocument, lastVisibleSymbol, TypeOfExpression::Preprocess);
const QList<TypeOfExpression::Result> results =
typeOfExpression(baseExpression, thisDocument,
lastVisibleSymbol,
TypeOfExpression::Preprocess);
// If it's a class, add completions for the constructors
foreach (const TypeOfExpression::Result &result, results) {
if (result.first->isClassType()) {
if (completeConstructorOrFunction(results))
if (completeConstructorOrFunction(results, context))
return m_startPosition;
break;
}
@@ -905,12 +908,13 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
return -1;
}
bool CppCodeCompletion::completeConstructorOrFunction(const QList<TypeOfExpression::Result> &results)
bool CppCodeCompletion::completeConstructorOrFunction(const QList<TypeOfExpression::Result> &results,
const LookupContext &context)
{
QList<Function *> functions;
foreach (const TypeOfExpression::Result &result, results) {
FullySpecifiedType exprTy = result.first;
FullySpecifiedType exprTy = result.first.simplified();
if (Class *klass = exprTy->asClassType()) {
Name *className = klass->name();
@@ -940,8 +944,8 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<TypeOfExpressi
}
if (functions.isEmpty()) {
foreach (const TypeOfExpression::Result &p, results) {
FullySpecifiedType ty = p.first;
foreach (const TypeOfExpression::Result &result, results) {
FullySpecifiedType ty = result.first.simplified();
if (Function *fun = ty->asFunctionType()) {
@@ -950,10 +954,6 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<TypeOfExpressi
else if (! functions.isEmpty() && functions.first()->scope() != fun->scope())
continue; // skip fun, it's an hidden declaration.
Name *name = fun->name();
if (QualifiedNameId *q = fun->name()->asQualifiedNameId())
name = q->unqualifiedNameId();
bool newOverload = true;
foreach (Function *f, functions) {
@@ -967,7 +967,35 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<TypeOfExpressi
functions.append(fun);
}
}
}
if (functions.isEmpty()) {
ResolveExpression resolveExpression(context);
ResolveClass resolveClass;
Name *functionCallOp = context.control()->operatorNameId(OperatorNameId::FunctionCallOp);
foreach (const TypeOfExpression::Result &result, results) {
FullySpecifiedType ty = result.first.simplified();
if (NamedType *namedTy = ty->asNamedType()) {
const QList<Symbol *> classObjectCandidates = resolveClass(namedTy->name(), result, context);
foreach (Symbol *classObjectCandidate, classObjectCandidates) {
if (Class *klass = classObjectCandidate->asClass()) {
const QList<TypeOfExpression::Result> overloads =
resolveExpression.resolveMember(functionCallOp, klass,
namedTy->name());
foreach (const TypeOfExpression::Result &overloadResult, overloads) {
FullySpecifiedType overloadTy = overloadResult.first.simplified();
if (Function *funTy = overloadTy->asFunctionType())
functions.append(funTy);
}
}
}
}
}
}
if (! functions.isEmpty()) {