diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 69b0e48271a4aa39752a2833e2ba161ced317f1e..3940103785113e28d16daf07c9366a8a3bab2020 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -40,9 +40,9 @@ #include <AST.h> #include <Scope.h> -#include <QByteArray> -#include <QFile> -#include <QtDebug> +#include <QtCore/QByteArray> +#include <QtCore/QBitArray> +#include <QtCore/QtDebug> using namespace CPlusPlus; @@ -419,3 +419,78 @@ void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const } } } + +QStringList Snapshot::dependsOn(const QString &fileName) const +{ + const int n = size(); + + QVector<QString> files(n); + QHash<QString, int> fileIndex; + QHash<int, QList<int> > includes; + + QMapIterator<QString, Document::Ptr> it(*this); + for (int i = 0; it.hasNext(); ++i) { + it.next(); + files[i] = it.key(); + fileIndex[it.key()] = i; + } + + int index = fileIndex.value(fileName, -1); + if (index == -1) { + qWarning() << fileName << "not in the snapshot"; + return QStringList(); + } + + QVector<QBitArray> includeMap(files.size()); + + for (int i = 0; i < files.size(); ++i) { + if (Document::Ptr doc = value(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); + + 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; +} diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 4f1c96629dd555919ee57ab5bc4decfe0d5e287f..109be8e362e6c8e38362362502b1104f1732bf45 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -291,6 +291,8 @@ public: QSharedPointer<NamespaceBinding> globalNamespaceBinding(Document::Ptr doc) const; + QStringList dependsOn(const QString &fileName) const; + void insert(Document::Ptr doc); using _Base::insert;