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

... by keying on Utils::FileName

Task-number: QTCREATORBUG-12390
Change-Id: Ia98afb5a9160a7fd9225a2f9e02539ff3c35ae86
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Erik Verbruggen
2014-11-27 12:11:46 +01:00
committed by Erik Verbruggen
parent a8ece5e9b0
commit a48adcf9be
16 changed files with 141 additions and 78 deletions

View File

@@ -116,9 +116,9 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
m_snapshot = Snapshot();
} else {
// Remove changed files from the snapshot
QSet<QString> toRemove;
QSet<Utils::FileName> toRemove;
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.get(fileName).second != doc->editorRevision())
addFileAndDependencies(&toRemove, fileName);
@@ -131,7 +131,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
if (!toRemove.isEmpty()) {
invalidateSnapshot = true;
foreach (const QString &fileName, toRemove)
foreach (const Utils::FileName &fileName, toRemove)
m_snapshot.remove(fileName);
}
}
@@ -183,7 +183,7 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
m_snapshot = sourceProcessor.snapshot();
Snapshot newSnapshot = m_snapshot.simplified(document());
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());
}
m_snapshot = newSnapshot;
@@ -231,12 +231,12 @@ BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &fil
return 0;
}
void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<QString> *toRemove,
const QString &fileName) const
void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<Utils::FileName> *toRemove,
const Utils::FileName &fileName) const
{
toRemove->insert(fileName);
if (fileName != filePath()) {
QStringList deps = m_snapshot.filesDependingOn(fileName);
toRemove->unite(QSet<QString>::fromList(deps));
if (fileName != Utils::FileName::fromString(filePath())) {
Utils::FileNameList deps = m_snapshot.filesDependingOn(fileName);
toRemove->unite(QSet<Utils::FileName>::fromList(deps));
}
}

View File

@@ -65,7 +65,7 @@ public:
static BuiltinEditorDocumentParser *get(const QString &filePath);
private:
void addFileAndDependencies(QSet<QString> *toRemove, const QString &fileName) const;
void addFileAndDependencies(QSet<Utils::FileName> *toRemove, const Utils::FileName &fileName) const;
private:
QByteArray m_configFile;

View File

@@ -55,7 +55,7 @@ using namespace CppTools::Internal;
using namespace CppTools;
using namespace CPlusPlus;
static QByteArray getSource(const QString &fileName,
static QByteArray getSource(const Utils::FileName &fileName,
const WorkingCopy &workingCopy)
{
if (workingCopy.contains(fileName)) {
@@ -66,7 +66,7 @@ static QByteArray getSource(const QString &fileName,
QString error;
QTextCodec *defaultCodec = EditorManager::defaultTextCodec();
Utils::TextFileFormat::ReadResult result = Utils::TextFileFormat::readFile(
fileName, defaultCodec, &fileContents, &format, &error);
fileName.toString(), defaultCodec, &fileContents, &format, &error);
if (result != Utils::TextFileFormat::ReadSuccess)
qWarning() << "Could not read " << fileName << ". Error: " << error;
@@ -188,7 +188,7 @@ public:
future(future)
{ }
QList<Usage> operator()(const QString &fileName)
QList<Usage> operator()(const Utils::FileName &fileName)
{
QList<Usage> usages;
if (future->isPaused())
@@ -205,7 +205,7 @@ public:
Document::Ptr doc;
const QByteArray unpreprocessedSource = getSource(fileName, workingCopy);
if (symbolDocument && fileName == symbolDocument->fileName()) {
if (symbolDocument && fileName == Utils::FileName::fromString(symbolDocument->fileName())) {
doc = symbolDocument;
} else {
doc = snapshot.preprocessedDocument(unpreprocessedSource, fileName);
@@ -278,22 +278,24 @@ static void find_helper(QFutureInterface<Usage> &future,
const Snapshot snapshot = context.snapshot();
const QString sourceFile = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
QStringList files(sourceFile);
const Utils::FileName sourceFile = Utils::FileName::fromUtf8(symbol->fileName(),
symbol->fileNameLength());
Utils::FileNameList files(sourceFile);
if (symbol->isClass()
|| symbol->isForwardClassDeclaration()
|| (symbol->enclosingScope()
&& !symbol->isStatic()
&& symbol->enclosingScope()->isNamespace())) {
foreach (const Document::Ptr &doc, context.snapshot()) {
if (doc->fileName() == sourceFile)
const Snapshot snapshotFromContext = context.snapshot();
for (auto i = snapshotFromContext.begin(), ei = snapshotFromContext.end(); i != ei; ++i) {
if (i.key() == sourceFile)
continue;
Control *control = doc->control();
const Control *control = i.value()->control();
if (control->findIdentifier(symbolId->chars(), symbolId->size()))
files.append(doc->fileName());
files.append(i.key());
}
} else {
files += snapshot.filesDependingOn(sourceFile);
@@ -452,7 +454,8 @@ CPlusPlus::Symbol *CppFindReferences::findSymbol(const CppFindReferencesParamete
Document::Ptr newSymbolDocument = snapshot.document(symbolFile);
// document is not parsed and has no bindings yet, do it
QByteArray source = getSource(newSymbolDocument->fileName(), m_modelManager->workingCopy());
QByteArray source = getSource(Utils::FileName::fromString(newSymbolDocument->fileName()),
m_modelManager->workingCopy());
Document::Ptr doc =
snapshot.preprocessedDocument(source, newSymbolDocument->fileName());
doc->check();
@@ -543,7 +546,7 @@ public:
: workingCopy(workingCopy), snapshot(snapshot), macro(macro), future(future)
{ }
QList<Usage> operator()(const QString &fileName)
QList<Usage> operator()(const Utils::FileName &fileName)
{
QList<Usage> usages;
Document::Ptr doc = snapshot.document(fileName);
@@ -573,7 +576,7 @@ restart_search:
if (macro.name() == useMacro.name()) {
unsigned column;
const QString &lineSource = matchingLine(use.bytesBegin(), source, &column);
usages.append(Usage(fileName, lineSource, use.beginLine(), column,
usages.append(Usage(fileName.toString(), lineSource, use.beginLine(), column,
useMacro.nameToQString().size()));
}
}
@@ -614,8 +617,8 @@ static void findMacroUses_helper(QFutureInterface<Usage> &future,
const Snapshot snapshot,
const Macro macro)
{
const QString& sourceFile = macro.fileName();
QStringList files(sourceFile);
const Utils::FileName sourceFile = Utils::FileName::fromString(macro.fileName());
Utils::FileNameList files(sourceFile);
files += snapshot.filesDependingOn(sourceFile);
files.removeDuplicates();
@@ -662,7 +665,8 @@ void CppFindReferences::findMacroUses(const Macro &macro, const QString &replace
// add the macro definition itself
{
const QByteArray &source = getSource(macro.fileName(), workingCopy);
const QByteArray &source = getSource(Utils::FileName::fromString(macro.fileName()),
workingCopy);
unsigned column;
const QString line = FindMacroUsesInFile::matchingLine(macro.bytesOffset(), source,
&column);

View File

@@ -814,12 +814,12 @@ QList<ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) co
QList<ProjectPart::Ptr> CppModelManager::projectPartFromDependencies(const QString &fileName) const
{
QSet<ProjectPart::Ptr> parts;
const QStringList deps = snapshot().filesDependingOn(fileName);
const Utils::FileNameList deps = snapshot().filesDependingOn(fileName);
{
QMutexLocker locker(&d->m_projectMutex);
foreach (const QString &dep, deps)
parts.unite(QSet<ProjectPart::Ptr>::fromList(d->m_fileToProjectParts.value(dep)));
QMutexLocker locker(&d->m_projectMutex);
foreach (const Utils::FileName &dep, deps) {
parts.unite(QSet<ProjectPart::Ptr>::fromList(
d->m_fileToProjectParts.value(dep.toString())));
}
return parts.values();
@@ -963,7 +963,7 @@ void CppModelManager::GC()
}
Snapshot currentSnapshot = snapshot();
QSet<QString> reachableFiles;
QSet<Utils::FileName> reachableFiles;
// The configuration file is part of the project files, which is just fine.
// If single files are open, without any project, then there is no need to
// keep the configuration file around.
@@ -974,9 +974,10 @@ void CppModelManager::GC()
const QString file = todo.last();
todo.removeLast();
if (reachableFiles.contains(file))
const Utils::FileName fileName = Utils::FileName::fromString(file);
if (reachableFiles.contains(fileName))
continue;
reachableFiles.insert(file);
reachableFiles.insert(fileName);
if (Document::Ptr doc = currentSnapshot.document(file))
todo += doc->includedFiles();
@@ -986,12 +987,12 @@ void CppModelManager::GC()
QStringList notReachableFiles;
Snapshot newSnapshot;
for (Snapshot::const_iterator it = currentSnapshot.begin(); it != currentSnapshot.end(); ++it) {
const QString fileName = it.key();
const Utils::FileName &fileName = it.key();
if (reachableFiles.contains(fileName))
newSnapshot.insert(it.value());
else
notReachableFiles.append(fileName);
notReachableFiles.append(fileName.toString());
}
// Announce removing files and replace the snapshot

View File

@@ -195,9 +195,13 @@ void TypeHierarchyBuilder::buildDerived(TypeHierarchy *typeHierarchy,
QStringList TypeHierarchyBuilder::filesDependingOn(CPlusPlus::Symbol *symbol) const
{
QStringList deps;
if (!symbol)
return QStringList();
return deps;
const QString file = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
return QStringList() << file << _snapshot.filesDependingOn(file);
Utils::FileName file = Utils::FileName::fromUtf8(symbol->fileName(), symbol->fileNameLength());
deps << file.toString();
foreach (const Utils::FileName &fileName, _snapshot.filesDependingOn(file))
deps.append(fileName.toString());
return deps;
}