summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@nokia.com>2010-03-17 12:34:29 +0100
committerErik Verbruggen <erik.verbruggen@nokia.com>2010-03-17 14:20:17 +0100
commit1cc5e1fe01d83ead385ec14411e744b6cd145c85 (patch)
tree2756facd84b1919e59b70335634518beee1f09f0
parent6ed0cd5d32febfce07ae43d6d67624a46ce2fa82 (diff)
downloadqt-creator-1cc5e1fe01d83ead385ec14411e744b6cd145c85.tar.gz
Put the include depenency table into a separate class, and cache it when possible.
-rw-r--r--src/libs/cplusplus/CppDocument.cpp106
-rw-r--r--src/libs/cplusplus/CppDocument.h7
-rw-r--r--src/libs/cplusplus/DependencyTable.cpp150
-rw-r--r--src/libs/cplusplus/DependencyTable.h65
-rw-r--r--src/libs/cplusplus/cplusplus-lib.pri2
-rw-r--r--src/plugins/cpptools/cppfindreferences.cpp23
-rw-r--r--src/plugins/cpptools/cppfindreferences.h3
7 files changed, 239 insertions, 117 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 3cc8b36a60..3a5e21198e 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -570,109 +570,3 @@ void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const
}
}
}
-
-QStringList Snapshot::filesDependingOn(const QString &fileName) const
-{
- const int N = size();
- QVector<QString> files(N);
- QHash<QString, int> fileIndex;
- QHash<int, QList<int> > includes;
- QVector<QBitArray> includeMap(N);
-
- dependency_helper(files, fileIndex, includes, includeMap);
-
- int index = fileIndex.value(fileName, -1);
- if (index == -1) {
- qWarning() << fileName << "not in the snapshot";
- return QStringList();
- }
-
- QStringList deps;
- for (int i = 0; i < files.size(); ++i) {
- const QBitArray &bits = includeMap.at(i);
-
- if (bits.testBit(index))
- deps.append(files.at(i));
- }
-
- return deps;
-}
-
-QHash<QString, QStringList> Snapshot::dependencyTable() const
-{
- const int N = size();
- QVector<QString> files(N);
- QHash<QString, int> fileIndex;
- QHash<int, QList<int> > includes;
- QVector<QBitArray> includeMap(N);
-
- dependency_helper(files, fileIndex, includes, includeMap);
-
- QHash<QString, QStringList> depMap;
-
- for (int index = 0; index < files.size(); ++index) {
- QStringList deps;
- for (int i = 0; i < files.size(); ++i) {
- const QBitArray &bits = includeMap.at(i);
-
- if (bits.testBit(index))
- deps.append(files.at(i));
- }
- depMap[files.at(index)] = deps;
- }
-
- return depMap;
-}
-
-void Snapshot::dependency_helper(QVector<QString> &files,
- QHash<QString, int> &fileIndex,
- QHash<int, QList<int> > &includes,
- QVector<QBitArray> &includeMap) const
-{
- int i = 0;
- for (const_iterator it = begin(); it != end(); ++it, ++i) {
- files[i] = it.key();
- fileIndex[it.key()] = i;
- }
-
- for (int i = 0; i < files.size(); ++i) {
- if (Document::Ptr doc = document(files.at(i))) {
- QBitArray bitmap(files.size());
- QList<int> directIncludes;
-
- foreach (const QString &includedFile, doc->includedFiles()) {
- int index = fileIndex.value(includedFile);
-
- if (index == -1)
- continue;
- else if (! directIncludes.contains(index))
- directIncludes.append(index);
-
- bitmap.setBit(index, true);
- }
-
- includeMap[i] = bitmap;
- includes[i] = directIncludes;
- }
- }
-
- bool changed;
-
- do {
- changed = false;
-
- for (int i = 0; i < files.size(); ++i) {
- QBitArray bitmap = includeMap.value(i);
- QBitArray previousBitmap = bitmap;
-
- foreach (int includedFileIndex, includes.value(i)) {
- bitmap |= includeMap.value(includedFileIndex);
- }
-
- if (bitmap != previousBitmap) {
- includeMap[i] = bitmap;
- changed = true;
- }
- }
- } while (changed);
-}
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index c96db61f4b..6a9a1e302d 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -365,15 +365,8 @@ public:
QSharedPointer<NamespaceBinding> globalNamespaceBinding(Document::Ptr doc) const;
- QStringList filesDependingOn(const QString &fileName) const;
- QHash<QString, QStringList> dependencyTable() const;
-
private:
void simplified_helper(Document::Ptr doc, Snapshot *snapshot) const;
- void dependency_helper(QVector<QString> &files,
- QHash<QString, int> &fileIndex,
- QHash<int, QList<int> > &includes,
- QVector<QBitArray> &includeMap) const;
private:
_Base _documents;
diff --git a/src/libs/cplusplus/DependencyTable.cpp b/src/libs/cplusplus/DependencyTable.cpp
new file mode 100644
index 0000000000..20871e5b52
--- /dev/null
+++ b/src/libs/cplusplus/DependencyTable.cpp
@@ -0,0 +1,150 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "DependencyTable.h"
+#include "CppDocument.h"
+
+#include <QtCore/QDebug>
+
+using namespace CPlusPlus;
+
+QStringList DependencyTable::filesDependingOn(const QString &fileName) const
+{
+ int index = fileIndex.value(fileName, -1);
+ if (index == -1) {
+ qWarning() << fileName << "not in the snapshot";
+ return QStringList();
+ }
+
+ QStringList deps;
+ for (int i = 0; i < files.size(); ++i) {
+ const QBitArray &bits = includeMap.at(i);
+
+ if (bits.testBit(index))
+ deps.append(files.at(i));
+ }
+
+ return deps;
+}
+
+QHash<QString, QStringList> DependencyTable::dependencyTable() const
+{
+ QHash<QString, QStringList> depMap;
+
+ for (int index = 0; index < files.size(); ++index) {
+ QStringList deps;
+ for (int i = 0; i < files.size(); ++i) {
+ const QBitArray &bits = includeMap.at(i);
+
+ if (bits.testBit(index))
+ deps.append(files.at(i));
+ }
+ depMap[files.at(index)] = deps;
+ }
+
+ return depMap;
+}
+
+bool DependencyTable::isValidFor(const Snapshot &snapshot) const
+{
+ const int documentCount = snapshot.size();
+ if (documentCount != files.size()
+ || documentCount != includesPerFile.size()
+ || documentCount != includeMap.size())
+ return false;
+
+ for (Snapshot::const_iterator it = snapshot.begin(); it != snapshot.end(); ++it) {
+ QHash<QString, QStringList>::const_iterator i = includesPerFile.find(it.key());
+ if (i == includesPerFile.end())
+ return false;
+
+ if (i.value() != it.value()->includedFiles())
+ return false;
+ }
+
+ return true;
+}
+
+void DependencyTable::build(const Snapshot &snapshot)
+{
+ const int documentCount = snapshot.size();
+ files.resize(documentCount);
+ includeMap.resize(documentCount);
+
+ int i = 0;
+ for (Snapshot::const_iterator it = snapshot.begin(); it != snapshot.end();
+ ++it, ++i) {
+ files[i] = it.key();
+ fileIndex[it.key()] = i;
+ }
+
+ for (int i = 0; i < files.size(); ++i) {
+ const QString fileName = files.at(i);
+ if (Document::Ptr doc = snapshot.document(files.at(i))) {
+ QBitArray bitmap(files.size());
+ QList<int> directIncludes;
+ const QStringList documentIncludes = doc->includedFiles();
+ includesPerFile.insert(fileName, documentIncludes);
+
+ foreach (const QString &includedFile, documentIncludes) {
+ int index = fileIndex.value(includedFile);
+
+ if (index == -1)
+ continue;
+ else if (! directIncludes.contains(index))
+ directIncludes.append(index);
+
+ bitmap.setBit(index, true);
+ }
+
+ includeMap[i] = bitmap;
+ includes[i] = directIncludes;
+ }
+ }
+
+ bool changed;
+
+ do {
+ changed = false;
+
+ for (int i = 0; i < files.size(); ++i) {
+ QBitArray bitmap = includeMap.value(i);
+ QBitArray previousBitmap = bitmap;
+
+ foreach (int includedFileIndex, includes.value(i)) {
+ bitmap |= includeMap.value(includedFileIndex);
+ }
+
+ if (bitmap != previousBitmap) {
+ includeMap[i] = bitmap;
+ changed = true;
+ }
+ }
+ } while (changed);
+}
diff --git a/src/libs/cplusplus/DependencyTable.h b/src/libs/cplusplus/DependencyTable.h
new file mode 100644
index 0000000000..97b34c4e59
--- /dev/null
+++ b/src/libs/cplusplus/DependencyTable.h
@@ -0,0 +1,65 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEPENDENCYTABLE_H
+#define DEPENDENCYTABLE_H
+
+#include <CPlusPlusForwardDeclarations.h>
+
+#include <QtCore/QBitArray>
+#include <QtCore/QHash>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+namespace CPlusPlus {
+
+class Snapshot;
+
+class CPLUSPLUS_EXPORT DependencyTable
+{
+public:
+ bool isValidFor(const Snapshot &snapshot) const;
+
+ QStringList filesDependingOn(const QString &fileName) const;
+ QHash<QString, QStringList> dependencyTable() const;
+
+ void build(const Snapshot &snapshot);
+
+private:
+ QHash<QString, QStringList> includesPerFile;
+ QVector<QString> files;
+ QHash<QString, int> fileIndex;
+ QHash<int, QList<int> > includes;
+ QVector<QBitArray> includeMap;
+};
+
+} // namespace CPlusPlus
+
+#endif // DEPENDENCYTABLE_H
diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri
index 611fadf0ac..c5d4ff0383 100644
--- a/src/libs/cplusplus/cplusplus-lib.pri
+++ b/src/libs/cplusplus/cplusplus-lib.pri
@@ -40,6 +40,7 @@ HEADERS += \
$$PWD/GenTemplateInstance.h \
$$PWD/FindUsages.h \
$$PWD/CheckUndefinedSymbols.h \
+ $$PWD/DependencyTable.h \
$$PWD/PreprocessorClient.h \
$$PWD/PreprocessorEnvironment.h \
$$PWD/Macro.h \
@@ -64,6 +65,7 @@ SOURCES += \
$$PWD/GenTemplateInstance.cpp \
$$PWD/FindUsages.cpp \
$$PWD/CheckUndefinedSymbols.cpp \
+ $$PWD/DependencyTable.cpp \
$$PWD/PreprocessorClient.cpp \
$$PWD/PreprocessorEnvironment.cpp \
$$PWD/FastPreprocessor.cpp \
diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp
index e714fa28ab..3a034b0a85 100644
--- a/src/plugins/cpptools/cppfindreferences.cpp
+++ b/src/plugins/cpptools/cppfindreferences.cpp
@@ -178,6 +178,7 @@ static void find_helper(QFutureInterface<Usage> &future,
const CppTools::CppModelManagerInterface::WorkingCopy workingCopy,
Snapshot snapshot,
Document::Ptr symbolDocument,
+ DependencyTable dependencyTable,
Symbol *symbol)
{
QTime tm;
@@ -200,7 +201,7 @@ static void find_helper(QFutureInterface<Usage> &future,
files.append(doc->fileName());
}
} else {
- files += snapshot.filesDependingOn(sourceFile);
+ files += dependencyTable.filesDependingOn(sourceFile);
}
files.removeDuplicates();
//qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size();
@@ -215,6 +216,15 @@ static void find_helper(QFutureInterface<Usage> &future,
future.setProgressValue(files.size());
}
+void CppFindReferences::updateDependencyTable(const Snapshot &snapshot)
+{
+ if (!m_deps.isValidFor(snapshot)) {
+ DependencyTable newDeps;
+ newDeps.build(snapshot);
+ m_deps = newDeps;
+ }
+}
+
void CppFindReferences::findUsages(Document::Ptr symbolDocument, Symbol *symbol)
{
Find::SearchResult *search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchOnly);
@@ -255,9 +265,11 @@ void CppFindReferences::findAll_helper(Document::Ptr symbolDocument, Symbol *sym
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
+ updateDependencyTable(snapshot);
+
QFuture<Usage> result;
- result = QtConcurrent::run(&find_helper, workingCopy, snapshot, symbolDocument, symbol);
+ result = QtConcurrent::run(&find_helper, workingCopy, snapshot, symbolDocument, m_deps, symbol);
m_watcher.setFuture(result);
Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."),
@@ -375,11 +387,12 @@ public:
static void findMacroUses_helper(QFutureInterface<Usage> &future,
const CppTools::CppModelManagerInterface::WorkingCopy workingCopy,
const Snapshot snapshot,
+ DependencyTable dependencyTable,
const Macro macro)
{
const QString& sourceFile = macro.fileName();
QStringList files(sourceFile);
- files += snapshot.filesDependingOn(sourceFile);
+ files += dependencyTable.filesDependingOn(sourceFile);
files.removeDuplicates();
future.setProgressRange(0, files.size());
@@ -411,8 +424,10 @@ void CppFindReferences::findMacroUses(const Macro &macro)
source.mid(macro.offset(), macro.length()), 0, macro.length());
}
+ updateDependencyTable(snapshot);
+
QFuture<Usage> result;
- result = QtConcurrent::run(&findMacroUses_helper, workingCopy, snapshot, macro);
+ result = QtConcurrent::run(&findMacroUses_helper, workingCopy, snapshot, m_deps, macro);
m_watcher.setFuture(result);
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h
index 74ede972e2..eae46c289a 100644
--- a/src/plugins/cpptools/cppfindreferences.h
+++ b/src/plugins/cpptools/cppfindreferences.h
@@ -36,6 +36,7 @@
#include <QtCore/QFutureWatcher>
#include <utils/filesearch.h>
#include <cplusplus/CppDocument.h>
+#include <cplusplus/DependencyTable.h>
#include <cplusplus/FindUsages.h>
namespace Find {
@@ -77,11 +78,13 @@ private Q_SLOTS:
private:
void findAll_helper(CPlusPlus::Document::Ptr symbolDocument, CPlusPlus::Symbol *symbol);
+ void updateDependencyTable(const CPlusPlus::Snapshot &snapshot);
private:
QPointer<CppModelManagerInterface> _modelManager;
Find::SearchResultWindow *_resultWindow;
QFutureWatcher<CPlusPlus::Usage> m_watcher;
+ CPlusPlus::DependencyTable m_deps;
};
} // end of namespace Internal