From c30c29063109c160378db26a3c70b5302740486d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 18 Oct 2013 12:42:46 +0200 Subject: [PATCH] Avoid holding on lots of data with C++ Find Usages The snapshots at the moment of search were held as long as the corresponding search result panel was kept, to allow mapping of the old symbol to the corresponding symbol in the new snapshot. Now we just save the file name and ID of the old symbol. Change-Id: Iaf3c9ca27ec2b788f142bd0dd6b86e34e66d5c8b Reviewed-by: Erik Verbruggen --- src/plugins/cpptools/cppfindreferences.cpp | 218 +++++++++++---------- src/plugins/cpptools/cppfindreferences.h | 11 +- 2 files changed, 117 insertions(+), 112 deletions(-) diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 4e5957ca45b..2bd90a60594 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -72,6 +72,97 @@ static QByteArray getSource(const QString &fileName, } } +static QByteArray typeId(Symbol *symbol) +{ + if (symbol->asEnum()) { + return QByteArray("e"); + } else if (symbol->asFunction()) { + return QByteArray("f"); + } else if (symbol->asNamespace()) { + return QByteArray("n"); + } else if (symbol->asTemplate()) { + return QByteArray("t"); + } else if (symbol->asNamespaceAlias()) { + return QByteArray("na"); + } else if (symbol->asClass()) { + return QByteArray("c"); + } else if (symbol->asBlock()) { + return QByteArray("b"); + } else if (symbol->asUsingNamespaceDirective()) { + return QByteArray("u"); + } else if (symbol->asUsingDeclaration()) { + return QByteArray("ud"); + } else if (symbol->asDeclaration()) { + QByteArray temp("d,"); + Overview pretty; + temp.append(pretty.prettyType(symbol->type()).toLatin1()); + return temp; + } else if (symbol->asArgument()) { + return QByteArray("a"); + } else if (symbol->asTypenameArgument()) { + return QByteArray("ta"); + } else if (symbol->asBaseClass()) { + return QByteArray("bc"); + } else if (symbol->asForwardClassDeclaration()) { + return QByteArray("fcd"); + } else if (symbol->asQtPropertyDeclaration()) { + return QByteArray("qpd"); + } else if (symbol->asQtEnum()) { + return QByteArray("qe"); + } else if (symbol->asObjCBaseClass()) { + return QByteArray("ocbc"); + } else if (symbol->asObjCBaseProtocol()) { + return QByteArray("ocbp"); + } else if (symbol->asObjCClass()) { + return QByteArray("occ"); + } else if (symbol->asObjCForwardClassDeclaration()) { + return QByteArray("ocfd"); + } else if (symbol->asObjCProtocol()) { + return QByteArray("ocp"); + } else if (symbol->asObjCForwardProtocolDeclaration()) { + return QByteArray("ocfpd"); + } else if (symbol->asObjCMethod()) { + return QByteArray("ocm"); + } else if (symbol->asObjCPropertyDeclaration()) { + return QByteArray("ocpd"); + } + return QByteArray("unknown"); +} + +static QByteArray idForSymbol(Symbol *symbol) +{ + QByteArray uid(typeId(symbol)); + if (const Identifier *id = symbol->identifier()) { + uid.append("|"); + uid.append(QByteArray(id->chars(), id->size())); + } else if (Scope *scope = symbol->enclosingScope()) { + // add the index of this symbol within its enclosing scope + // (counting symbols without identifier of the same type) + int count = 0; + Scope::iterator it = scope->firstMember(); + while (it != scope->lastMember() && *it != symbol) { + Symbol *val = *it; + ++it; + if (val->identifier() || typeId(val) != uid) + continue; + ++count; + } + uid.append(QString::number(count).toLocal8Bit()); + } + return uid; +} + +static QList fullIdForSymbol(Symbol *symbol) +{ + QList uid; + Symbol *current = symbol; + do { + uid.prepend(idForSymbol(current)); + current = current->enclosingScope(); + } while (current); + return uid; +} + namespace { class ProcessFile: public std::unary_function > @@ -246,10 +337,10 @@ void CppFindReferences::findUsages(CPlusPlus::Symbol *symbol, search->setSearchAgainSupported(true); connect(search, SIGNAL(searchAgainRequested()), this, SLOT(searchAgain())); CppFindReferencesParameters parameters; - parameters.context = context; - parameters.symbol = symbol; + parameters.symbolId = fullIdForSymbol(symbol); + parameters.symbolFileName = QByteArray(symbol->fileName()); search->setUserData(qVariantFromValue(parameters)); - findAll_helper(search); + findAll_helper(search, symbol, context); } void CppFindReferences::renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context, @@ -262,10 +353,10 @@ void CppFindReferences::renameUsages(CPlusPlus::Symbol *symbol, const CPlusPlus: } } -void CppFindReferences::findAll_helper(Find::SearchResult *search) +void CppFindReferences::findAll_helper(Find::SearchResult *search, CPlusPlus::Symbol *symbol, + const CPlusPlus::LookupContext &context) { - CppFindReferencesParameters parameters = search->userData().value(); - if (!(parameters.symbol && parameters.symbol->identifier())) { + if (!(symbol && symbol->identifier())) { search->finishSearch(false); return; } @@ -276,8 +367,7 @@ void CppFindReferences::findAll_helper(Find::SearchResult *search) Find::SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus); const CppModelManagerInterface::WorkingCopy workingCopy = _modelManager->workingCopy(); QFuture result; - result = QtConcurrent::run(&find_helper, workingCopy, - parameters.context, this, parameters.symbol); + result = QtConcurrent::run(&find_helper, workingCopy, context, this, symbol); createWatcher(result, search); FutureProgress *progress = ProgressManager::addTask(result, tr("Searching"), @@ -303,92 +393,13 @@ void CppFindReferences::searchAgain() CppFindReferencesParameters parameters = search->userData().value(); Snapshot snapshot = CppModelManagerInterface::instance()->snapshot(); search->restart(); - if (!findSymbol(¶meters, snapshot)) { + LookupContext context; + Symbol *symbol = findSymbol(parameters, snapshot, &context); + if (!symbol) { search->finishSearch(false); return; } - search->setUserData(qVariantFromValue(parameters)); - findAll_helper(search); -} - -static QByteArray typeId(Symbol *symbol) -{ - if (symbol->asEnum()) { - return QByteArray("e"); - } else if (symbol->asFunction()) { - return QByteArray("f"); - } else if (symbol->asNamespace()) { - return QByteArray("n"); - } else if (symbol->asTemplate()) { - return QByteArray("t"); - } else if (symbol->asNamespaceAlias()) { - return QByteArray("na"); - } else if (symbol->asClass()) { - return QByteArray("c"); - } else if (symbol->asBlock()) { - return QByteArray("b"); - } else if (symbol->asUsingNamespaceDirective()) { - return QByteArray("u"); - } else if (symbol->asUsingDeclaration()) { - return QByteArray("ud"); - } else if (symbol->asDeclaration()) { - QByteArray temp("d,"); - Overview pretty; - temp.append(pretty.prettyType(symbol->type()).toLatin1()); - return temp; - } else if (symbol->asArgument()) { - return QByteArray("a"); - } else if (symbol->asTypenameArgument()) { - return QByteArray("ta"); - } else if (symbol->asBaseClass()) { - return QByteArray("bc"); - } else if (symbol->asForwardClassDeclaration()) { - return QByteArray("fcd"); - } else if (symbol->asQtPropertyDeclaration()) { - return QByteArray("qpd"); - } else if (symbol->asQtEnum()) { - return QByteArray("qe"); - } else if (symbol->asObjCBaseClass()) { - return QByteArray("ocbc"); - } else if (symbol->asObjCBaseProtocol()) { - return QByteArray("ocbp"); - } else if (symbol->asObjCClass()) { - return QByteArray("occ"); - } else if (symbol->asObjCForwardClassDeclaration()) { - return QByteArray("ocfd"); - } else if (symbol->asObjCProtocol()) { - return QByteArray("ocp"); - } else if (symbol->asObjCForwardProtocolDeclaration()) { - return QByteArray("ocfpd"); - } else if (symbol->asObjCMethod()) { - return QByteArray("ocm"); - } else if (symbol->asObjCPropertyDeclaration()) { - return QByteArray("ocpd"); - } - return QByteArray("unknown"); -} - -static QByteArray idForSymbol(Symbol *symbol) -{ - QByteArray uid(typeId(symbol)); - if (const Identifier *id = symbol->identifier()) { - uid.append("|"); - uid.append(QByteArray(id->chars(), id->size())); - } else if (Scope *scope = symbol->enclosingScope()) { - // add the index of this symbol within its enclosing scope - // (counting symbols without identifier of the same type) - int count = 0; - Scope::iterator it = scope->firstMember(); - while (it != scope->lastMember() && *it != symbol) { - Symbol *val = *it; - ++it; - if (val->identifier() || typeId(val) != uid) - continue; - ++count; - } - uid.append(QString::number(count).toLocal8Bit()); - } - return uid; + findAll_helper(search, symbol, context); } namespace { @@ -430,12 +441,13 @@ private: }; } -bool CppFindReferences::findSymbol(CppFindReferencesParameters *parameters, - const Snapshot &snapshot) +CPlusPlus::Symbol *CppFindReferences::findSymbol(const CppFindReferencesParameters ¶meters, + const Snapshot &snapshot, LookupContext *context) { - QString symbolFile = QLatin1String(parameters->symbol->fileName()); + QTC_ASSERT(context, return 0); + QString symbolFile = QLatin1String(parameters.symbolFileName); if (!snapshot.contains(symbolFile)) - return false; + return 0; Document::Ptr newSymbolDocument = snapshot.document(symbolFile); // document is not parsed and has no bindings yet, do it @@ -444,22 +456,14 @@ bool CppFindReferences::findSymbol(CppFindReferencesParameters *parameters, snapshot.preprocessedDocument(source, newSymbolDocument->fileName()); doc->check(); - // construct id of old symbol - QList uid; - Symbol *current = parameters->symbol; - do { - uid.prepend(idForSymbol(current)); - current = current->enclosingScope(); - } while (current); // find matching symbol in new document and return the new parameters - SymbolFinder finder(uid); + SymbolFinder finder(parameters.symbolId); finder.accept(doc->globalNamespace()); if (finder.result()) { - parameters->symbol = finder.result(); - parameters->context = LookupContext(doc, snapshot); - return true; + *context = LookupContext(doc, snapshot); + return finder.result(); } - return false; + return 0; } void CppFindReferences::displayResults(int first, int last) diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h index 13f2da5fc69..c902ed0a852 100644 --- a/src/plugins/cpptools/cppfindreferences.h +++ b/src/plugins/cpptools/cppfindreferences.h @@ -54,8 +54,8 @@ namespace Internal { class CppFindReferencesParameters { public: - CPlusPlus::LookupContext context; - CPlusPlus::Symbol *symbol; + QList symbolId; + QByteArray symbolFileName; }; class CppFindReferences: public QObject @@ -92,12 +92,13 @@ private: const QString &replacement, bool replace); void findMacroUses(const CPlusPlus::Macro ¯o, const QString &replacement, bool replace); - void findAll_helper(Find::SearchResult *search); + void findAll_helper(Find::SearchResult *search, CPlusPlus::Symbol *symbol, + const CPlusPlus::LookupContext &context); CPlusPlus::DependencyTable dependencyTable() const; void setDependencyTable(const CPlusPlus::DependencyTable &newTable); void createWatcher(const QFuture &future, Find::SearchResult *search); - bool findSymbol(CppFindReferencesParameters *parameters, - const CPlusPlus::Snapshot &snapshot); + CPlusPlus::Symbol *findSymbol(const CppFindReferencesParameters ¶meters, + const CPlusPlus::Snapshot &snapshot, CPlusPlus::LookupContext *context); private: QPointer _modelManager;