CppEditor: fix "follow symbol under cursor" for operators

Like for functions we can call attemptFuncDeclDef for operators. The
check for function names has been enhanced to take operators into
account.
For the switch from definition to declaration
SymbolFinder::findMatchingDeclaration has been enriched with operator
knowledge.

Task-number: QTCREATORBUG-7485

Change-Id: I29eebee337e26c8bf67dc8b4a15c43883045589d
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
Joerg Bornemann
2013-09-16 12:50:13 +02:00
parent c8393b10fd
commit 321ac6cc51
4 changed files with 151 additions and 14 deletions

View File

@@ -244,6 +244,24 @@ Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Sna
return 0;
}
static void findDeclarationOfSymbol(Symbol *s,
Function *functionType,
QList<Declaration *> *typeMatch,
QList<Declaration *> *argumentCountMatch,
QList<Declaration *> *nameMatch)
{
if (Declaration *decl = s->asDeclaration()) {
if (Function *declFunTy = decl->type()->asFunctionType()) {
if (functionType->isEqualTo(declFunTy))
typeMatch->prepend(decl);
else if (functionType->argumentCount() == declFunTy->argumentCount())
argumentCountMatch->prepend(decl);
else
nameMatch->append(decl);
}
}
}
void SymbolFinder::findMatchingDeclaration(const LookupContext &context,
Function *functionType,
QList<Declaration *> *typeMatch,
@@ -280,26 +298,33 @@ void SymbolFinder::findMatchingDeclaration(const LookupContext &context,
}
const Identifier *funcId = functionName->identifier();
if (!funcId) // E.g. operator, which we might be able to handle in the future...
return;
OperatorNameId::Kind operatorNameId = OperatorNameId::InvalidOp;
if (!funcId) {
if (!qName)
return;
const OperatorNameId * const onid = qName->name()->asOperatorNameId();
if (!onid)
return;
operatorNameId = onid->kind();
}
foreach (Symbol *s, binding->symbols()) {
Scope *scope = s->asScope();
if (!scope)
continue;
for (Symbol *s = scope->find(funcId); s; s = s->next()) {
if (!s->name() || !funcId->isEqualTo(s->identifier()) || !s->type()->isFunctionType())
continue;
if (Declaration *decl = s->asDeclaration()) {
if (Function *declFunTy = decl->type()->asFunctionType()) {
if (functionType->isEqualTo(declFunTy))
typeMatch->prepend(decl);
else if (functionType->argumentCount() == declFunTy->argumentCount())
argumentCountMatch->prepend(decl);
else
nameMatch->append(decl);
}
if (funcId) {
for (Symbol *s = scope->find(funcId); s; s = s->next()) {
if (!s->name() || !funcId->isEqualTo(s->identifier()) || !s->type()->isFunctionType())
continue;
findDeclarationOfSymbol(s, functionType, typeMatch, argumentCountMatch, nameMatch);
}
} else {
for (Symbol *s = scope->find(operatorNameId); s; s = s->next()) {
if (!s->name() || !s->type()->isFunctionType())
continue;
findDeclarationOfSymbol(s, functionType, typeMatch, argumentCountMatch, nameMatch);
}
}
}