summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus
diff options
context:
space:
mode:
authorLeandro Melo <leandro.melo@nokia.com>2012-01-20 14:43:21 +0100
committerLeandro Melo <leandro.melo@nokia.com>2012-01-23 11:34:44 +0100
commit466ea4842cf3c84d1aaf43e717cbc66838c63f14 (patch)
treed63cf59727eaeb1daee76de38055d0233561714e /src/libs/cplusplus
parent271ec63a100681151c235d6d75e3121f3c22f4c7 (diff)
downloadqt-creator-466ea4842cf3c84d1aaf43e717cbc66838c63f14.tar.gz
C++: Improve file accuracy when finding symbols
This patch introduces a priority-based mechanism when searching for certains symbols in the snapshot. The priority corresponds to how similar the file path from the "reference" symbol is to the file path from the "candidate" symbol. This solves a variety of issues when matching "equivalent" symbols but that are in another file/project, such as when following a function declaration, a forward class declaration, or adding a definition through a quickfix. There's now a symbol finder which will compute the "best" search order and cache the most recent results. A consequence is that following symbols in some cases is slower, but not apparently significatly. Note: The "find" functions were moved from the Snapshot to the new SymbolFinder class. Task-number: QTCREATORBUG-6697 Task-number: QTCREATORBUG-6792 Change-Id: Ia518f014275fec1f4d0cb3224bd4e06a9df6d557 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r--src/libs/cplusplus/CppDocument.cpp236
-rw-r--r--src/libs/cplusplus/CppDocument.h12
2 files changed, 0 insertions, 248 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 0886416e48..46586aa597 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -717,239 +717,3 @@ void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const
}
}
-namespace {
-class FindMatchingDefinition: public SymbolVisitor
-{
- Symbol *_declaration;
- const OperatorNameId *_oper;
- QList<Function *> _result;
-
-public:
- FindMatchingDefinition(Symbol *declaration)
- : _declaration(declaration)
- , _oper(0)
- {
- if (_declaration->name())
- _oper = _declaration->name()->asOperatorNameId();
- }
-
- QList<Function *> result() const { return _result; }
-
- using SymbolVisitor::visit;
-
- virtual bool visit(Function *fun)
- {
- if (_oper) {
- if (const Name *name = fun->unqualifiedName()) {
- if (_oper->isEqualTo(name))
- _result.append(fun);
- }
- } else if (const Identifier *id = _declaration->identifier()) {
- if (id->isEqualTo(fun->identifier()))
- _result.append(fun);
- }
-
- return false;
- }
-
- virtual bool visit(Block *)
- {
- return false;
- }
-};
-} // end of anonymous namespace
-
-// strict means the returned symbol has to match exactly,
-// including argument count and argument types
-Symbol *Snapshot::findMatchingDefinition(Symbol *declaration, bool strict) const
-{
- if (!declaration)
- return 0;
-
- Document::Ptr thisDocument = document(QString::fromUtf8(declaration->fileName(), declaration->fileNameLength()));
- if (! thisDocument) {
- qWarning() << "undefined document:" << declaration->fileName();
- return 0;
- }
-
- Function *declarationTy = declaration->type()->asFunctionType();
- if (! declarationTy) {
- qWarning() << "not a function:" << declaration->fileName() << declaration->line() << declaration->column();
- return 0;
- }
-
- foreach (Document::Ptr doc, *this) {
- const Identifier *id = declaration->identifier();
- if (id && ! doc->control()->findIdentifier(id->chars(),
- id->size()))
- continue;
- if (!id) {
- if (!declaration->name())
- continue;
- const OperatorNameId *oper = declaration->name()->asOperatorNameId();
- if (!oper)
- continue;
- if (!doc->control()->findOperatorNameId(oper->kind()))
- continue;
- }
-
- FindMatchingDefinition candidates(declaration);
- candidates.accept(doc->globalNamespace());
-
- const QList<Function *> result = candidates.result();
- if (! result.isEmpty()) {
- LookupContext context(doc, *this);
-
- QList<Function *> viableFunctions;
-
- ClassOrNamespace *enclosingType = context.lookupType(declaration);
- if (! enclosingType)
- continue; // nothing to do
-
- foreach (Function *fun, result) {
- const QList<LookupItem> declarations = context.lookup(fun->name(), fun->enclosingScope());
- if (declarations.isEmpty())
- continue;
-
- const LookupItem best = declarations.first();
- if (enclosingType == context.lookupType(best.declaration()))
- viableFunctions.append(fun);
- }
-
- if (viableFunctions.isEmpty())
- continue;
-
- else if (! strict && viableFunctions.length() == 1)
- return viableFunctions.first();
-
- Function *best = 0;
-
- foreach (Function *fun, viableFunctions) {
- if (! (fun->unqualifiedName() && fun->unqualifiedName()->isEqualTo(declaration->unqualifiedName())))
- continue;
- else if (fun->argumentCount() == declarationTy->argumentCount()) {
- if (! strict && ! best)
- best = fun;
-
- unsigned argc = 0;
- for (; argc < declarationTy->argumentCount(); ++argc) {
- Symbol *arg = fun->argumentAt(argc);
- Symbol *otherArg = declarationTy->argumentAt(argc);
- if (! arg->type().isEqualTo(otherArg->type()))
- break;
- }
-
- if (argc == declarationTy->argumentCount())
- best = fun;
- }
- }
-
- if (strict && ! best)
- continue;
-
- if (! best)
- best = viableFunctions.first();
- return best;
- }
- }
-
- return 0;
-}
-
-Class *Snapshot::findMatchingClassDeclaration(Symbol *declaration) const
-{
- if (! declaration->identifier())
- return 0;
-
- foreach (Document::Ptr doc, *this) {
- if (! doc->control()->findIdentifier(declaration->identifier()->chars(),
- declaration->identifier()->size()))
- continue;
-
- LookupContext context(doc, *this);
-
- ClassOrNamespace *type = context.lookupType(declaration);
- if (!type)
- continue;
-
- foreach (Symbol *s, type->symbols()) {
- if (Class *c = s->asClass())
- return c;
- }
- }
-
- return 0;
-}
-
-void CPlusPlus::findMatchingDeclaration(const LookupContext &context,
- Function *functionType,
- QList<Declaration *> *typeMatch,
- QList<Declaration *> *argumentCountMatch,
- QList<Declaration *> *nameMatch)
-{
- Scope *enclosingScope = functionType->enclosingScope();
- while (! (enclosingScope->isNamespace() || enclosingScope->isClass()))
- enclosingScope = enclosingScope->enclosingScope();
- Q_ASSERT(enclosingScope != 0);
-
- const Name *functionName = functionType->name();
- if (! functionName)
- return; // anonymous function names are not valid c++
-
- ClassOrNamespace *binding = 0;
- const QualifiedNameId *qName = functionName->asQualifiedNameId();
- if (qName) {
- if (qName->base())
- binding = context.lookupType(qName->base(), enclosingScope);
- else
- binding = context.globalNamespace();
- functionName = qName->name();
- }
-
- if (!binding) { // declaration for a global function
- binding = context.lookupType(enclosingScope);
-
- if (!binding)
- return;
- }
-
- const Identifier *funcId = functionName->identifier();
- if (!funcId) // E.g. operator, which we might be able to handle in the future...
- return;
-
- 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())
- continue;
- else if (! funcId->isEqualTo(s->identifier()))
- continue;
- else if (! s->type()->isFunctionType())
- continue;
- else 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);
- }
- }
- }
- }
-}
-
-QList<Declaration *> CPlusPlus::findMatchingDeclaration(const LookupContext &context, Function *functionType)
-{
- QList<Declaration *> result;
- QList<Declaration *> nameMatch, argumentCountMatch, typeMatch;
- findMatchingDeclaration(context, functionType, &typeMatch, &argumentCountMatch, &nameMatch);
- result.append(typeMatch);
- result.append(argumentCountMatch);
- result.append(nameMatch);
- return result;
-}
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index fdd7544777..33447a4969 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -381,9 +381,6 @@ public:
Document::Ptr documentFromSource(const QByteArray &preprocessedCode,
const QString &fileName) const;
- Symbol *findMatchingDefinition(Symbol *symbol, bool strict = false) const;
- Class *findMatchingClassDeclaration(Symbol *symbol) const;
-
private:
void simplified_helper(Document::Ptr doc, Snapshot *snapshot) const;
@@ -391,15 +388,6 @@ private:
_Base _documents;
};
-void CPLUSPLUS_EXPORT findMatchingDeclaration(
- const LookupContext &context,
- Function *functionType,
- QList<Declaration *> *typeMatch,
- QList<Declaration *> *argumentCountMatch,
- QList<Declaration *> *nameMatch);
-QList<Declaration *> CPLUSPLUS_EXPORT findMatchingDeclaration(
- const LookupContext &context, Function *functionType);
-
} // namespace CPlusPlus
#endif // CPLUSPLUS_CPPDOCUMENT_H