C++: Fix "reference" file in symbol finder

Througout the initial review the singleton was transformed into an
ordinary class, but a error was introduced: The "reference" file was
incorrectly assumed to be the editors file, which is wrong, since
it should be the declaration file.

Change-Id: Iad3e25a690fa8bd07a18184b24b10f8dea965332
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
This commit is contained in:
Leandro Melo
2012-01-23 16:08:01 +01:00
parent 17425c50f3
commit b97b45a341
8 changed files with 66 additions and 56 deletions

View File

@@ -420,7 +420,7 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
, m_firstRenameChange(false) , m_firstRenameChange(false)
, m_objcEnabled(false) , m_objcEnabled(false)
, m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings()) , m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings())
, m_symbolFinder(new CppTools::SymbolFinder(QString())) , m_symbolFinder(new CppTools::SymbolFinder)
{ {
m_initialized = false; m_initialized = false;
qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo"); qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo");
@@ -864,9 +864,7 @@ void CPPEditorWidget::onContentsChanged(int position, int charsRemoved, int char
} }
void CPPEditorWidget::updateFileName() void CPPEditorWidget::updateFileName()
{ {}
m_symbolFinder.reset(new CppTools::SymbolFinder(file()->fileName()));
}
void CPPEditorWidget::jumpToOutlineElement(int) void CPPEditorWidget::jumpToOutlineElement(int)
{ {
@@ -2258,9 +2256,9 @@ void CPPEditorWidget::applyDeclDefLinkChanges(bool jumpToMatch)
updateFunctionDeclDefLink(); updateFunctionDeclDefLink();
} }
CppTools::SymbolFinder *CPPEditorWidget::symbolFinder() const QSharedPointer<CppTools::SymbolFinder> CPPEditorWidget::symbolFinder() const
{ {
return m_symbolFinder.data(); return m_symbolFinder;
} }
void CPPEditorWidget::abortDeclDefLink() void CPPEditorWidget::abortDeclDefLink()

View File

@@ -50,7 +50,6 @@
#include <QtCore/QFutureWatcher> #include <QtCore/QFutureWatcher>
#include <QtCore/QModelIndex> #include <QtCore/QModelIndex>
#include <QtCore/QVector> #include <QtCore/QVector>
#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QComboBox; class QComboBox;
@@ -202,7 +201,7 @@ public:
QSharedPointer<FunctionDeclDefLink> declDefLink() const; QSharedPointer<FunctionDeclDefLink> declDefLink() const;
void applyDeclDefLinkChanges(bool jumpToMatch); void applyDeclDefLinkChanges(bool jumpToMatch);
CppTools::SymbolFinder *symbolFinder() const; QSharedPointer<CppTools::SymbolFinder> symbolFinder() const;
Q_SIGNALS: Q_SIGNALS:
void outlineModelIndexChanged(const QModelIndex &index); void outlineModelIndexChanged(const QModelIndex &index);
@@ -337,7 +336,7 @@ private:
QSharedPointer<FunctionDeclDefLink> m_declDefLink; QSharedPointer<FunctionDeclDefLink> m_declDefLink;
CppTools::CommentsSettings m_commentsSettings; CppTools::CommentsSettings m_commentsSettings;
QScopedPointer<CppTools::SymbolFinder> m_symbolFinder; QSharedPointer<CppTools::SymbolFinder> m_symbolFinder;
}; };

View File

@@ -164,17 +164,15 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio
// find the matching decl/def symbol // find the matching decl/def symbol
Symbol *target = 0; Symbol *target = 0;
CppTools::SymbolFinder finder;
if (FunctionDefinitionAST *funcDef = link->sourceDeclaration->asFunctionDefinition()) { if (FunctionDefinitionAST *funcDef = link->sourceDeclaration->asFunctionDefinition()) {
QList<Declaration *> nameMatch, argumentCountMatch, typeMatch; QList<Declaration *> nameMatch, argumentCountMatch, typeMatch;
CppTools::SymbolFinder finder(funcDef->symbol->fileName(), funcDef->symbol->fileNameLength());
finder.findMatchingDeclaration(LookupContext(link->sourceDocument, snapshot), finder.findMatchingDeclaration(LookupContext(link->sourceDocument, snapshot),
funcDef->symbol, funcDef->symbol,
&typeMatch, &argumentCountMatch, &nameMatch); &typeMatch, &argumentCountMatch, &nameMatch);
if (!typeMatch.isEmpty()) if (!typeMatch.isEmpty())
target = typeMatch.first(); target = typeMatch.first();
} else if (link->sourceDeclaration->asSimpleDeclaration()) { } else if (link->sourceDeclaration->asSimpleDeclaration()) {
CppTools::SymbolFinder finder(link->sourceFunctionDeclarator->symbol->fileName(),
link->sourceFunctionDeclarator->symbol->fileNameLength());
target = finder.findMatchingDefinition(link->sourceFunctionDeclarator->symbol, snapshot, true); target = finder.findMatchingDefinition(link->sourceFunctionDeclarator->symbol, snapshot, true);
} }
if (!target) { if (!target) {

View File

@@ -1553,7 +1553,7 @@ private:
{ {
Q_ASSERT(fwdClass != 0); Q_ASSERT(fwdClass != 0);
CppTools::SymbolFinder symbolFinder(fwdClass->fileName(), fwdClass->fileNameLength()); CppTools::SymbolFinder symbolFinder;
if (Class *k = if (Class *k =
symbolFinder.findMatchingClassDeclaration(fwdClass, symbolFinder.findMatchingClassDeclaration(fwdClass,
assistInterface()->snapshot())) { assistInterface()->snapshot())) {

View File

@@ -517,8 +517,7 @@ static InsertionLocation nextToSurroundingDefinitions(Declaration *declaration,
} }
// find the declaration's definition // find the declaration's definition
CppTools::SymbolFinder symbolFinder(surroundingFunctionDecl->fileName(), CppTools::SymbolFinder symbolFinder;
surroundingFunctionDecl->fileNameLength());
Symbol *definition = symbolFinder.findMatchingDefinition(surroundingFunctionDecl, Symbol *definition = symbolFinder.findMatchingDefinition(surroundingFunctionDecl,
changes.snapshot()); changes.snapshot());
if (!definition) if (!definition)
@@ -559,7 +558,7 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition(
if (!declaration) if (!declaration)
return result; return result;
CppTools::SymbolFinder symbolFinder(declaration->fileName(), declaration->fileNameLength()); CppTools::SymbolFinder symbolFinder;
if (Symbol *s = symbolFinder.findMatchingDefinition(declaration, if (Symbol *s = symbolFinder.findMatchingDefinition(declaration,
m_refactoringChanges.snapshot(), m_refactoringChanges.snapshot(),
true)) { true)) {

View File

@@ -63,13 +63,9 @@ public:
} // end of anonymous namespace } // end of anonymous namespace
static const int kMaxSize = 2;
SymbolFinder::SymbolFinder(const QString &referenceFileName) SymbolFinder::SymbolFinder()
: m_referenceFile(referenceFileName)
{}
SymbolFinder::SymbolFinder(const char *referenceFileName, unsigned referenceFileLength)
: m_referenceFile(QString::fromUtf8(referenceFileName, referenceFileLength))
{} {}
// strict means the returned symbol has to match exactly, // strict means the returned symbol has to match exactly,
@@ -82,7 +78,6 @@ Symbol *SymbolFinder::findMatchingDefinition(Symbol *declaration,
return 0; return 0;
QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength()); QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength());
Q_ASSERT(declFile == m_referenceFile);
Document::Ptr thisDocument = snapshot.document(declFile); Document::Ptr thisDocument = snapshot.document(declFile);
if (! thisDocument) { if (! thisDocument) {
@@ -97,10 +92,10 @@ Symbol *SymbolFinder::findMatchingDefinition(Symbol *declaration,
return 0; return 0;
} }
foreach (const QString &fileName, fileIterationOrder(snapshot)) { foreach (const QString &fileName, fileIterationOrder(declFile, snapshot)) {
Document::Ptr doc = snapshot.document(fileName); Document::Ptr doc = snapshot.document(fileName);
if (!doc) { if (!doc) {
clear(fileName); clearCache(declFile, fileName);
continue; continue;
} }
@@ -187,12 +182,11 @@ Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Sna
return 0; return 0;
QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength()); QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength());
Q_ASSERT(declFile == m_referenceFile);
foreach (const QString &file, fileIterationOrder(snapshot)) { foreach (const QString &file, fileIterationOrder(declFile, snapshot)) {
Document::Ptr doc = snapshot.document(file); Document::Ptr doc = snapshot.document(file);
if (!doc) { if (!doc) {
clear(file); clearCache(declFile, file);
continue; continue;
} }
@@ -289,41 +283,63 @@ QList<Declaration *> SymbolFinder::findMatchingDeclaration(const LookupContext &
return result; return result;
} }
#include <QtCore/QThread> QStringList SymbolFinder::fileIterationOrder(const QString &referenceFile, const Snapshot &snapshot)
QStringList SymbolFinder::fileIterationOrder(const Snapshot &snapshot)
{ {
if (m_filePriorityCache.isEmpty()) { if (m_filePriorityCache.contains(referenceFile)) {
foreach (const Document::Ptr &doc, snapshot) checkCacheConsistency(referenceFile, snapshot);
insert(doc->fileName());
} else { } else {
checkCacheConsistency(snapshot); foreach (Document::Ptr doc, snapshot)
insertCache(referenceFile, doc->fileName());
} }
return m_filePriorityCache.values(); trackCacheUse(referenceFile);
return m_filePriorityCache.value(referenceFile).values();
} }
void SymbolFinder::checkCacheConsistency(const Snapshot &snapshot) void SymbolFinder::checkCacheConsistency(const QString &referenceFile, const Snapshot &snapshot)
{ {
// We only check for "new" files, which which are in the snapshot but not in the cache. // We only check for "new" files, which which are in the snapshot but not in the cache.
// The counterpart validation for "old" files is done when one tries to access the // The counterpart validation for "old" files is done when one tries to access the
// corresponding document and notices it's now null. // corresponding document and notices it's now null.
const QSet<QString> &meta = m_fileMetaCache.value(referenceFile);
foreach (const Document::Ptr &doc, snapshot) { foreach (const Document::Ptr &doc, snapshot) {
if (!m_fileMetaCache.contains(doc->fileName())) if (!meta.contains(doc->fileName()))
insert(doc->fileName()); insertCache(referenceFile, doc->fileName());
} }
} }
void SymbolFinder::clear(const QString &comparingFile) void SymbolFinder::clearCache(const QString &referenceFile, const QString &comparingFile)
{ {
m_filePriorityCache.remove(computeKey(m_referenceFile, comparingFile), comparingFile); m_filePriorityCache[referenceFile].remove(computeKey(referenceFile, comparingFile),
m_fileMetaCache.remove(comparingFile); comparingFile);
m_fileMetaCache[referenceFile].remove(comparingFile);
} }
void SymbolFinder::insert(const QString &comparingFile) void SymbolFinder::insertCache(const QString &referenceFile, const QString &comparingFile)
{ {
// We want an ordering such that the documents with the most common path appear first. // We want an ordering such that the documents with the most common path appear first.
m_filePriorityCache.insert(computeKey(m_referenceFile, comparingFile), comparingFile); m_filePriorityCache[referenceFile].insert(computeKey(referenceFile, comparingFile),
m_fileMetaCache.insert(comparingFile); comparingFile);
m_fileMetaCache[referenceFile].insert(comparingFile);
}
void SymbolFinder::trackCacheUse(const QString &referenceFile)
{
if (!m_recent.isEmpty()) {
if (m_recent.last() == referenceFile)
return;
m_recent.removeOne(referenceFile);
}
m_recent.append(referenceFile);
// We don't want this to grow too much.
if (m_recent.size() > kMaxSize) {
const QString &oldest = m_recent.front();
m_filePriorityCache.remove(oldest);
m_fileMetaCache.remove(oldest);
}
} }
int SymbolFinder::computeKey(const QString &referenceFile, const QString &comparingFile) int SymbolFinder::computeKey(const QString &referenceFile, const QString &comparingFile)

View File

@@ -8,7 +8,6 @@
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QQueue>
#include <QtCore/QMultiMap> #include <QtCore/QMultiMap>
#include <QtCore/QSet> #include <QtCore/QSet>
@@ -17,8 +16,7 @@ namespace CppTools {
class CPPTOOLS_EXPORT SymbolFinder class CPPTOOLS_EXPORT SymbolFinder
{ {
public: public:
SymbolFinder(const QString &referenceFileName); SymbolFinder();
SymbolFinder(const char *referenceFileName, unsigned referenceFileLength);
CPlusPlus::Symbol *findMatchingDefinition(CPlusPlus::Symbol *symbol, CPlusPlus::Symbol *findMatchingDefinition(CPlusPlus::Symbol *symbol,
const CPlusPlus::Snapshot &snapshot, const CPlusPlus::Snapshot &snapshot,
@@ -37,17 +35,20 @@ public:
CPlusPlus::Function *functionType); CPlusPlus::Function *functionType);
private: private:
QStringList fileIterationOrder(const CPlusPlus::Snapshot &snapshot); QStringList fileIterationOrder(const QString &referenceFile,
const CPlusPlus::Snapshot &snapshot);
void checkCacheConsistency(const CPlusPlus::Snapshot &snapshot); void checkCacheConsistency(const QString &referenceFile, const CPlusPlus::Snapshot &snapshot);
void clear(const QString &comparingFile); void clearCache(const QString &referenceFile, const QString &comparingFile);
void insert(const QString &comparingFile); void insertCache(const QString &referenceFile, const QString &comparingFile);
void trackCacheUse(const QString &referenceFile);
static int computeKey(const QString &referenceFile, const QString &comparingFile); static int computeKey(const QString &referenceFile, const QString &comparingFile);
QMultiMap<int, QString> m_filePriorityCache; QHash<QString, QMultiMap<int, QString> > m_filePriorityCache;
QSet<QString> m_fileMetaCache; QHash<QString, QSet<QString> > m_fileMetaCache;
QString m_referenceFile; QStringList m_recent;
}; };
} // namespace CppTools } // namespace CppTools

View File

@@ -274,8 +274,7 @@ static Document::Ptr findDefinition(Function *functionDeclaration, int *line)
{ {
if (CppModelManagerInterface *cppModelManager = CppModelManagerInterface::instance()) { if (CppModelManagerInterface *cppModelManager = CppModelManagerInterface::instance()) {
const Snapshot snapshot = cppModelManager->snapshot(); const Snapshot snapshot = cppModelManager->snapshot();
CppTools::SymbolFinder symbolFinder(functionDeclaration->fileName(), CppTools::SymbolFinder symbolFinder;
functionDeclaration->fileNameLength());
if (Symbol *def = symbolFinder.findMatchingDefinition(functionDeclaration, snapshot)) { if (Symbol *def = symbolFinder.findMatchingDefinition(functionDeclaration, snapshot)) {
if (line) if (line)
*line = def->line(); *line = def->line();