Commit a48adcf9 authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Erik Verbruggen

C++: handle case-insensitive file names in the CPlusPlus::Snapshot

... by keying on Utils::FileName

Task-number: QTCREATORBUG-12390
Change-Id: Ia98afb5a9160a7fd9225a2f9e02539ff3c35ae86
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@theqtcompany.com>
parent a8ece5e9
...@@ -741,17 +741,17 @@ bool Snapshot::isEmpty() const ...@@ -741,17 +741,17 @@ bool Snapshot::isEmpty() const
return _documents.isEmpty(); return _documents.isEmpty();
} }
Snapshot::const_iterator Snapshot::find(const QString &fileName) const Snapshot::const_iterator Snapshot::find(const Utils::FileName &fileName) const
{ {
return _documents.find(fileName); return _documents.find(fileName);
} }
void Snapshot::remove(const QString &fileName) void Snapshot::remove(const Utils::FileName &fileName)
{ {
_documents.remove(fileName); _documents.remove(fileName);
} }
bool Snapshot::contains(const QString &fileName) const bool Snapshot::contains(const Utils::FileName &fileName) const
{ {
return _documents.contains(fileName); return _documents.contains(fileName);
} }
...@@ -759,15 +759,15 @@ bool Snapshot::contains(const QString &fileName) const ...@@ -759,15 +759,15 @@ bool Snapshot::contains(const QString &fileName) const
void Snapshot::insert(Document::Ptr doc) void Snapshot::insert(Document::Ptr doc)
{ {
if (doc) { if (doc) {
_documents.insert(doc->fileName(), doc); _documents.insert(Utils::FileName::fromString(doc->fileName()), doc);
m_deps.files.clear(); // Will trigger re-build when accessed. m_deps.files.clear(); // Will trigger re-build when accessed.
} }
} }
Document::Ptr Snapshot::preprocessedDocument(const QByteArray &source, Document::Ptr Snapshot::preprocessedDocument(const QByteArray &source,
const QString &fileName) const const Utils::FileName &fileName) const
{ {
Document::Ptr newDoc = Document::create(fileName); Document::Ptr newDoc = Document::create(fileName.toString());
if (Document::Ptr thisDocument = document(fileName)) { if (Document::Ptr thisDocument = document(fileName)) {
newDoc->_revision = thisDocument->_revision; newDoc->_revision = thisDocument->_revision;
newDoc->_editorRevision = thisDocument->_editorRevision; newDoc->_editorRevision = thisDocument->_editorRevision;
...@@ -821,7 +821,7 @@ QList<Snapshot::IncludeLocation> Snapshot::includeLocationsOfDocument(const QStr ...@@ -821,7 +821,7 @@ QList<Snapshot::IncludeLocation> Snapshot::includeLocationsOfDocument(const QStr
return result; return result;
} }
QStringList Snapshot::filesDependingOn(const QString &fileName) const Utils::FileNameList Snapshot::filesDependingOn(const Utils::FileName &fileName) const
{ {
updateDependencyTable(); updateDependencyTable();
return m_deps.filesDependingOn(fileName); return m_deps.filesDependingOn(fileName);
...@@ -850,7 +850,7 @@ void Snapshot::allIncludesForDocument_helper(const QString &fileName, QSet<QStri ...@@ -850,7 +850,7 @@ void Snapshot::allIncludesForDocument_helper(const QString &fileName, QSet<QStri
} }
} }
Document::Ptr Snapshot::document(const QString &fileName) const Document::Ptr Snapshot::document(const Utils::FileName &fileName) const
{ {
return _documents.value(fileName); return _documents.value(fileName);
} }
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include <cplusplus/PreprocessorClient.h> #include <cplusplus/PreprocessorClient.h>
#include <cplusplus/DependencyTable.h> #include <cplusplus/DependencyTable.h>
#include <utils/fileutils.h>
#include <QSharedPointer> #include <QSharedPointer>
#include <QDateTime> #include <QDateTime>
#include <QHash> #include <QHash>
...@@ -395,7 +397,7 @@ private: ...@@ -395,7 +397,7 @@ private:
class CPLUSPLUS_EXPORT Snapshot class CPLUSPLUS_EXPORT Snapshot
{ {
typedef QHash<QString, Document::Ptr> Base; typedef QHash<Utils::FileName, Document::Ptr> Base;
public: public:
Snapshot(); Snapshot();
...@@ -409,20 +411,32 @@ public: ...@@ -409,20 +411,32 @@ public:
bool isEmpty() const; bool isEmpty() const;
void insert(Document::Ptr doc); // ### remove void insert(Document::Ptr doc); // ### remove
void remove(const QString &fileName); // ### remove void remove(const Utils::FileName &fileName); // ### remove
void remove(const QString &fileName)
{ remove(Utils::FileName::fromString(fileName)); }
const_iterator begin() const { return _documents.begin(); } const_iterator begin() const { return _documents.begin(); }
const_iterator end() const { return _documents.end(); } const_iterator end() const { return _documents.end(); }
bool contains(const QString &fileName) const; bool contains(const Utils::FileName &fileName) const;
Document::Ptr document(const QString &fileName) const; bool contains(const QString &fileName) const
{ return contains(Utils::FileName::fromString(fileName)); }
Document::Ptr document(const Utils::FileName &fileName) const;
Document::Ptr document(const QString &fileName) const
{ return document(Utils::FileName::fromString(fileName)); }
const_iterator find(const QString &fileName) const; const_iterator find(const Utils::FileName &fileName) const;
const_iterator find(const QString &fileName) const
{ return find(Utils::FileName::fromString(fileName)); }
Snapshot simplified(Document::Ptr doc) const; Snapshot simplified(Document::Ptr doc) const;
Document::Ptr preprocessedDocument(const QByteArray &source, Document::Ptr preprocessedDocument(const QByteArray &source,
const QString &fileName) const; const Utils::FileName &fileName) const;
Document::Ptr preprocessedDocument(const QByteArray &source,
const QString &fileName) const
{ return preprocessedDocument(source, Utils::FileName::fromString(fileName)); }
Document::Ptr documentFromSource(const QByteArray &preprocessedDocument, Document::Ptr documentFromSource(const QByteArray &preprocessedDocument,
const QString &fileName) const; const QString &fileName) const;
...@@ -430,7 +444,9 @@ public: ...@@ -430,7 +444,9 @@ public:
QSet<QString> allIncludesForDocument(const QString &fileName) const; QSet<QString> allIncludesForDocument(const QString &fileName) const;
QList<IncludeLocation> includeLocationsOfDocument(const QString &fileName) const; QList<IncludeLocation> includeLocationsOfDocument(const QString &fileName) const;
QStringList filesDependingOn(const QString &fileName) const; Utils::FileNameList filesDependingOn(const Utils::FileName &fileName) const;
Utils::FileNameList filesDependingOn(const QString &fileName) const
{ return filesDependingOn(Utils::FileName::fromString(fileName)); }
void updateDependencyTable() const; void updateDependencyTable() const;
bool operator==(const Snapshot &other) const; bool operator==(const Snapshot &other) const;
......
...@@ -34,13 +34,14 @@ ...@@ -34,13 +34,14 @@
using namespace CPlusPlus; using namespace CPlusPlus;
QStringList DependencyTable::filesDependingOn(const QString &fileName) const Utils::FileNameList DependencyTable::filesDependingOn(const Utils::FileName &fileName) const
{ {
Utils::FileNameList deps;
int index = fileIndex.value(fileName, -1); int index = fileIndex.value(fileName, -1);
if (index == -1) if (index == -1)
return QStringList(); return deps;
QStringList deps;
for (int i = 0; i < files.size(); ++i) { for (int i = 0; i < files.size(); ++i) {
const QBitArray &bits = includeMap.at(i); const QBitArray &bits = includeMap.at(i);
...@@ -53,7 +54,6 @@ QStringList DependencyTable::filesDependingOn(const QString &fileName) const ...@@ -53,7 +54,6 @@ QStringList DependencyTable::filesDependingOn(const QString &fileName) const
void DependencyTable::build(const Snapshot &snapshot) void DependencyTable::build(const Snapshot &snapshot)
{ {
includesPerFile.clear();
files.clear(); files.clear();
fileIndex.clear(); fileIndex.clear();
includes.clear(); includes.clear();
...@@ -71,15 +71,14 @@ void DependencyTable::build(const Snapshot &snapshot) ...@@ -71,15 +71,14 @@ void DependencyTable::build(const Snapshot &snapshot)
} }
for (int i = 0; i < files.size(); ++i) { for (int i = 0; i < files.size(); ++i) {
const QString fileName = files.at(i); const Utils::FileName &fileName = files.at(i);
if (Document::Ptr doc = snapshot.document(files.at(i))) { if (Document::Ptr doc = snapshot.document(fileName)) {
QBitArray bitmap(files.size()); QBitArray bitmap(files.size());
QList<int> directIncludes; QList<int> directIncludes;
const QStringList documentIncludes = doc->includedFiles(); const QStringList documentIncludes = doc->includedFiles();
includesPerFile.insert(fileName, documentIncludes);
foreach (const QString &includedFile, documentIncludes) { foreach (const QString &includedFile, documentIncludes) {
int index = fileIndex.value(includedFile); int index = fileIndex.value(Utils::FileName::fromString(includedFile));
if (index == -1) if (index == -1)
continue; continue;
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <cplusplus/CPlusPlusForwardDeclarations.h> #include <cplusplus/CPlusPlusForwardDeclarations.h>
#include <utils/fileutils.h>
#include <QBitArray> #include <QBitArray>
#include <QHash> #include <QHash>
#include <QString> #include <QString>
...@@ -48,11 +50,10 @@ class CPLUSPLUS_EXPORT DependencyTable ...@@ -48,11 +50,10 @@ class CPLUSPLUS_EXPORT DependencyTable
private: private:
friend class Snapshot; friend class Snapshot;
void build(const Snapshot &snapshot); void build(const Snapshot &snapshot);
QStringList filesDependingOn(const QString &fileName) const; Utils::FileNameList filesDependingOn(const Utils::FileName &fileName) const;
QHash<QString, QStringList> includesPerFile; QVector<Utils::FileName> files;
QVector<QString> files; QHash<Utils::FileName, int> fileIndex;
QHash<QString, int> fileIndex;
QHash<int, QList<int> > includes; QHash<int, QList<int> > includes;
QVector<QBitArray> includeMap; QVector<QBitArray> includeMap;
}; };
......
...@@ -53,8 +53,8 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QByteArray &source) ...@@ -53,8 +53,8 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QByteArray &source)
_merged.insert(fileName); _merged.insert(fileName);
for (Snapshot::const_iterator i = _snapshot.begin(), ei = _snapshot.end(); i != ei; ++i) { for (Snapshot::const_iterator i = _snapshot.begin(), ei = _snapshot.end(); i != ei; ++i) {
if (isInjectedFile(i.key())) if (isInjectedFile(i.key().toString()))
mergeEnvironment(i.key()); mergeEnvironment(i.key().toString());
} }
foreach (const Document::Include &i, doc->resolvedIncludes()) foreach (const Document::Include &i, doc->resolvedIncludes())
......
...@@ -624,6 +624,13 @@ FileName FileName::fromUserInput(const QString &filename) ...@@ -624,6 +624,13 @@ FileName FileName::fromUserInput(const QString &filename)
return FileName(clean); return FileName(clean);
} }
/// Constructs a FileName from \a fileName, which is encoded as UTF-8.
/// \a fileName is not checked for validity.
FileName FileName::fromUtf8(const char *filename, int filenameSize)
{
return FileName(QString::fromUtf8(filename, filenameSize));
}
FileName::FileName(const QString &string) FileName::FileName(const QString &string)
: QString(string) : QString(string)
{ {
...@@ -726,6 +733,25 @@ QTextStream &operator<<(QTextStream &s, const FileName &fn) ...@@ -726,6 +733,25 @@ QTextStream &operator<<(QTextStream &s, const FileName &fn)
return s << fn.toString(); return s << fn.toString();
} }
int FileNameList::removeDuplicates()
{
QSet<FileName> seen;
int removed = 0;
for (int i = 0; i < size(); ) {
const FileName &fn = at(i);
if (seen.contains(fn)) {
removeAt(i);
++removed;
} else {
seen.insert(fn);
++i;
}
}
return removed;
}
static bool isFileDrop(const QMimeData *d, QList<FileDropSupport::FileSpec> *files = 0) static bool isFileDrop(const QMimeData *d, QList<FileDropSupport::FileSpec> *files = 0)
{ {
// internal drop // internal drop
......
...@@ -70,6 +70,7 @@ public: ...@@ -70,6 +70,7 @@ public:
static FileName fromString(const QString &filename, const QString &defaultExtension); static FileName fromString(const QString &filename, const QString &defaultExtension);
static FileName fromLatin1(const QByteArray &filename); static FileName fromLatin1(const QByteArray &filename);
static FileName fromUserInput(const QString &filename); static FileName fromUserInput(const QString &filename);
static FileName fromUtf8(const char *filename, int filenameSize = -1);
QString toString() const; QString toString() const;
QString toUserOutput() const; QString toUserOutput() const;
bool exists() const; bool exists() const;
...@@ -104,6 +105,17 @@ private: ...@@ -104,6 +105,17 @@ private:
QTCREATOR_UTILS_EXPORT QTextStream &operator<<(QTextStream &s, const FileName &fn); QTCREATOR_UTILS_EXPORT QTextStream &operator<<(QTextStream &s, const FileName &fn);
class QTCREATOR_UTILS_EXPORT FileNameList : public QList<FileName>
{
public:
inline FileNameList() { }
inline explicit FileNameList(const FileName &i) { append(i); }
inline FileNameList(const FileNameList &l) : QList<FileName>(l) { }
inline FileNameList(const QList<FileName> &l) : QList<FileName>(l) { }
int removeDuplicates();
};
class QTCREATOR_UTILS_EXPORT FileUtils { class QTCREATOR_UTILS_EXPORT FileUtils {
public: public:
static bool removeRecursively(const FileName &filePath, QString *error = 0); static bool removeRecursively(const FileName &filePath, QString *error = 0);
......
...@@ -641,7 +641,7 @@ void Parser::resetData(const CPlusPlus::Snapshot &snapshot) ...@@ -641,7 +641,7 @@ void Parser::resetData(const CPlusPlus::Snapshot &snapshot)
CPlusPlus::Snapshot::const_iterator cur = snapshot.begin(); CPlusPlus::Snapshot::const_iterator cur = snapshot.begin();
CPlusPlus::Snapshot::const_iterator end = snapshot.end(); CPlusPlus::Snapshot::const_iterator end = snapshot.end();
for (; cur != end; ++cur) for (; cur != end; ++cur)
d->documentList[cur.key()] = cur.value(); d->documentList[cur.key().toString()] = cur.value();
d->docLocker.unlock(); d->docLocker.unlock();
......
...@@ -341,7 +341,7 @@ void CppIncludeHierarchyModel::buildHierarchyIncludedBy_helper(const QString &fi ...@@ -341,7 +341,7 @@ void CppIncludeHierarchyModel::buildHierarchyIncludedBy_helper(const QString &fi
cyclic->insert(filePath); cyclic->insert(filePath);
Snapshot::const_iterator citEnd = snapshot.end(); Snapshot::const_iterator citEnd = snapshot.end();
for (Snapshot::const_iterator cit = snapshot.begin(); cit != citEnd; ++cit) { for (Snapshot::const_iterator cit = snapshot.begin(); cit != citEnd; ++cit) {
const QString filePathFromSnapshot = cit.key(); const QString filePathFromSnapshot = cit.key().toString();
Document::Ptr doc = cit.value(); Document::Ptr doc = cit.value();
foreach (const Document::Include &includeFile, doc->resolvedIncludes()) { foreach (const Document::Include &includeFile, doc->resolvedIncludes()) {
const QString includedFilePath = includeFile.resolvedFileName(); const QString includedFilePath = includeFile.resolvedFileName();
......
...@@ -1907,12 +1907,13 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa ...@@ -1907,12 +1907,13 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
Snapshot localForwardHeaders = forwardHeaders; Snapshot localForwardHeaders = forwardHeaders;
localForwardHeaders.insert(interface.snapshot().document(info->fileName())); localForwardHeaders.insert(interface.snapshot().document(info->fileName()));
QStringList headerAndItsForwardingHeaders; Utils::FileNameList headerAndItsForwardingHeaders;
headerAndItsForwardingHeaders << info->fileName(); headerAndItsForwardingHeaders << Utils::FileName::fromString(info->fileName());
headerAndItsForwardingHeaders += localForwardHeaders.filesDependingOn(info->fileName()); headerAndItsForwardingHeaders += localForwardHeaders.filesDependingOn(info->fileName());
foreach (const QString &header, headerAndItsForwardingHeaders) { foreach (const Utils::FileName &header, headerAndItsForwardingHeaders) {
const QString include = findShortestInclude(currentDocumentFilePath, header, const QString include = findShortestInclude(currentDocumentFilePath,
header.toString(),
headerPaths); headerPaths);
if (include.size() > 2) { if (include.size() > 2) {
const QString headerFileName = QFileInfo(info->fileName()).fileName(); const QString headerFileName = QFileInfo(info->fileName()).fileName();
......
...@@ -116,9 +116,9 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy) ...@@ -116,9 +116,9 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
m_snapshot = Snapshot(); m_snapshot = Snapshot();
} else { } else {
// Remove changed files from the snapshot // Remove changed files from the snapshot
QSet<QString> toRemove; QSet<Utils::FileName> toRemove;
foreach (const Document::Ptr &doc, m_snapshot) { foreach (const Document::Ptr &doc, m_snapshot) {
QString fileName = doc->fileName(); const Utils::FileName fileName = Utils::FileName::fromString(doc->fileName());
if (workingCopy.contains(fileName)) { if (workingCopy.contains(fileName)) {
if (workingCopy.get(fileName).second != doc->editorRevision()) if (workingCopy.get(fileName).second != doc->editorRevision())
addFileAndDependencies(&toRemove, fileName); addFileAndDependencies(&toRemove, fileName);
...@@ -131,7 +131,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy) ...@@ -131,7 +131,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
if (!toRemove.isEmpty()) { if (!toRemove.isEmpty()) {
invalidateSnapshot = true; invalidateSnapshot = true;
foreach (const QString &fileName, toRemove) foreach (const Utils::FileName &fileName, toRemove)
m_snapshot.remove(fileName); m_snapshot.remove(fileName);
} }
} }
...@@ -183,7 +183,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy) ...@@ -183,7 +183,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
m_snapshot = sourceProcessor.snapshot(); m_snapshot = sourceProcessor.snapshot();
Snapshot newSnapshot = m_snapshot.simplified(document()); Snapshot newSnapshot = m_snapshot.simplified(document());
for (Snapshot::const_iterator i = m_snapshot.begin(), ei = m_snapshot.end(); i != ei; ++i) { for (Snapshot::const_iterator i = m_snapshot.begin(), ei = m_snapshot.end(); i != ei; ++i) {
if (Client::isInjectedFile(i.key())) if (Client::isInjectedFile(i.key().toString()))
newSnapshot.insert(i.value()); newSnapshot.insert(i.value());
} }
m_snapshot = newSnapshot; m_snapshot = newSnapshot;
...@@ -231,12 +231,12 @@ BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &fil ...@@ -231,12 +231,12 @@ BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &fil
return 0; return 0;
} }
void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<QString> *toRemove, void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<Utils::FileName> *toRemove,
const QString &fileName) const const Utils::FileName &fileName) const
{ {
toRemove->insert(fileName); toRemove->insert(fileName);
if (fileName != filePath()) { if (fileName != Utils::FileName::fromString(filePath())) {
QStringList deps = m_snapshot.filesDependingOn(fileName); Utils::FileNameList deps = m_snapshot.filesDependingOn(fileName);
toRemove->unite(QSet<QString>::fromList(deps)); toRemove->unite(QSet<Utils::FileName>::fromList(deps));
} }
} }
...@@ -65,7 +65,7 @@ public: ...@@ -65,7 +65,7 @@ public:
static BuiltinEditorDocumentParser *get(const QString &filePath); static BuiltinEditorDocumentParser *get(const QString &filePath);
private: private:
void addFileAndDependencies(QSet<QString> *toRemove, const QString &fileName) const; void addFileAndDependencies(QSet<Utils::FileName> *toRemove, const Utils::FileName &fileName) const;
private: private:
QByteArray m_configFile; QByteArray m_configFile;
......
...@@ -55,7 +55,7 @@ using namespace CppTools::Internal; ...@@ -55,7 +55,7 @@ using namespace CppTools::Internal;
using namespace CppTools; using namespace CppTools;
using namespace CPlusPlus; using namespace CPlusPlus;
static QByteArray getSource(const QString &fileName, static QByteArray getSource(const Utils::FileName &fileName,
const WorkingCopy &workingCopy) const WorkingCopy &workingCopy)
{ {
if (workingCopy.contains(fileName)) { if (workingCopy.contains(fileName)) {
...@@ -66,7 +66,7 @@ static QByteArray getSource(const QString &fileName, ...@@ -66,7 +66,7 @@ static QByteArray getSource(const QString &fileName,
QString error; QString error;
QTextCodec *defaultCodec = EditorManager::defaultTextCodec(); QTextCodec *defaultCodec = EditorManager::defaultTextCodec();
Utils::TextFileFormat::ReadResult result = Utils::TextFileFormat::readFile( Utils::TextFileFormat::ReadResult result = Utils::TextFileFormat::readFile(
fileName, defaultCodec, &fileContents, &format, &error); fileName.toString(), defaultCodec, &fileContents, &format, &error);
if (result != Utils::TextFileFormat::ReadSuccess) if (result != Utils::TextFileFormat::ReadSuccess)
qWarning() << "Could not read " << fileName << ". Error: " << error; qWarning() << "Could not read " << fileName << ". Error: " << error;
...@@ -188,7 +188,7 @@ public: ...@@ -188,7 +188,7 @@ public:
future(future) future(future)
{ } { }
QList<Usage> operator()(const QString &fileName) QList<Usage> operator()(const Utils::FileName &fileName)
{ {
QList<Usage> usages; QList<Usage> usages;
if (future->isPaused()) if (future->isPaused())
...@@ -205,7 +205,7 @@ public: ...@@ -205,7 +205,7 @@ public:
Document::Ptr doc; Document::Ptr doc;
const QByteArray unpreprocessedSource = getSource(fileName, workingCopy); const QByteArray unpreprocessedSource = getSource(fileName, workingCopy);
if (symbolDocument && fileName == symbolDocument->fileName()) { if (symbolDocument && fileName == Utils::FileName::fromString(symbolDocument->fileName())) {
doc = symbolDocument; doc = symbolDocument;
} else { } else {
doc = snapshot.preprocessedDocument(unpreprocessedSource, fileName); doc = snapshot.preprocessedDocument(unpreprocessedSource, fileName);
...@@ -278,22 +278,24 @@ static void find_helper(QFutureInterface<Usage> &future, ...@@ -278,22 +278,24 @@ static void find_helper(QFutureInterface<Usage> &future,
const Snapshot snapshot = context.snapshot(); const Snapshot snapshot = context.snapshot();
const QString sourceFile = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()); const Utils::FileName sourceFile = Utils::FileName::fromUtf8(symbol->fileName(),
QStringList files(sourceFile); symbol->fileNameLength());
Utils::FileNameList files(sourceFile);
if (symbol->isClass() if (symbol->isClass()
|| symbol->isForwardClassDeclaration() || symbol->isForwardClassDeclaration()
|| (symbol->enclosingScope() || (symbol->enclosingScope()
&& !symbol->isStatic() && !symbol->isStatic()
&& symbol->enclosingScope()->isNamespace())) { && symbol->enclosingScope()->isNamespace())) {
foreach (const Document::Ptr &doc, context.snapshot()) { const Snapshot snapshotFromContext = context.snapshot();
if (doc->fileName() == sourceFile) for (auto i = snapshotFromContext.begin(), ei = snapshotFromContext.end(); i != ei; ++i) {
if (i.key() == sourceFile)
continue; continue;
Control *control = doc->control(); const Control *control = i.value()->control();
if (control->findIdentifier(symbolId->chars(), symbolId->size())) if (control->findIdentifier(symbolId->chars(), symbolId->size()))
files.append(doc->fileName()); files.append(i.key());
} }