Commit c30c2906 authored by Eike Ziller's avatar Eike Ziller
Browse files

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: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent 155567a0
......@@ -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<QByteArray> fullIdForSymbol(Symbol *symbol)
{
QList<QByteArray> uid;
Symbol *current = symbol;
do {
uid.prepend(idForSymbol(current));
current = current->enclosingScope();
} while (current);
return uid;
}
namespace {
class ProcessFile: public std::unary_function<QString, QList<Usage> >
......@@ -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<CppFindReferencesParameters>();
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<Usage> 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<CppFindReferencesParameters>();
Snapshot snapshot = CppModelManagerInterface::instance()->snapshot();
search->restart();
if (!findSymbol(&parameters, 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 &parameters,
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<QByteArray> 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)
......
......@@ -54,8 +54,8 @@ namespace Internal {
class CppFindReferencesParameters
{
public:
CPlusPlus::LookupContext context;
CPlusPlus::Symbol *symbol;
QList<QByteArray> symbolId;
QByteArray symbolFileName;
};
class CppFindReferences: public QObject
......@@ -92,12 +92,13 @@ private:
const QString &replacement, bool replace);
void findMacroUses(const CPlusPlus::Macro &macro, 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<CPlusPlus::Usage> &future, Find::SearchResult *search);
bool findSymbol(CppFindReferencesParameters *parameters,
const CPlusPlus::Snapshot &snapshot);
CPlusPlus::Symbol *findSymbol(const CppFindReferencesParameters &parameters,
const CPlusPlus::Snapshot &snapshot, CPlusPlus::LookupContext *context);
private:
QPointer<CppModelManagerInterface> _modelManager;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment