forked from qt-creator/qt-creator
FileInProjectFinder: Proper lookup of qrc URLs
Parse the project's qrc files to map a qrc URL to the actual file in the project, rather than employing a heuristic. Fixes: QTCREATORBUG-20207 Change-Id: I4fc9e11c20a36e9d477bb3dc43a787d81e067886 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -24,8 +24,11 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "fileinprojectfinder.h"
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "fileutils.h"
|
||||
#include "hostosinfo.h"
|
||||
#include "qrcparser.h"
|
||||
#include "qtcassert.h"
|
||||
|
||||
#include <QDebug>
|
||||
@@ -102,6 +105,7 @@ void FileInProjectFinder::setProjectFiles(const FileNameList &projectFiles)
|
||||
|
||||
m_projectFiles = projectFiles;
|
||||
m_cache.clear();
|
||||
m_qrcUrlFinder.setProjectFiles(projectFiles);
|
||||
}
|
||||
|
||||
void FileInProjectFinder::setSysroot(const FileName &sysroot)
|
||||
@@ -140,6 +144,13 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const
|
||||
{
|
||||
qCDebug(finderLog) << "FileInProjectFinder: trying to find file" << fileUrl.toString() << "...";
|
||||
|
||||
if (fileUrl.scheme() == "qrc" || fileUrl.toString().startsWith(':')) {
|
||||
const QString result = m_qrcUrlFinder.find(fileUrl);
|
||||
if (success)
|
||||
*success = !result.isEmpty();
|
||||
return result;
|
||||
}
|
||||
|
||||
QString originalPath = fileUrl.toLocalFile();
|
||||
if (originalPath.isEmpty()) // e.g. qrc://
|
||||
originalPath = fileUrl.path();
|
||||
@@ -421,4 +432,34 @@ FileInProjectFinder::PathMappingNode::~PathMappingNode()
|
||||
qDeleteAll(children);
|
||||
}
|
||||
|
||||
QString FileInProjectFinder::QrcUrlFinder::find(const QUrl &fileUrl) const
|
||||
{
|
||||
QString result;
|
||||
const auto fileIt = m_fileCache.constFind(fileUrl);
|
||||
if (fileIt != m_fileCache.cend())
|
||||
return fileIt.value();
|
||||
for (const FileName &f : m_allQrcFiles) {
|
||||
QrcParser::Ptr &qrcParser = m_parserCache[f];
|
||||
if (!qrcParser)
|
||||
qrcParser = QrcParser::parseQrcFile(f.toString(), QString());
|
||||
if (!qrcParser->isValid())
|
||||
continue;
|
||||
QStringList hits;
|
||||
qrcParser->collectFilesAtPath(QrcParser::normalizedQrcFilePath(fileUrl.toString()), &hits);
|
||||
if (!hits.empty()) {
|
||||
result = hits.first();
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_fileCache.insert(fileUrl, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileInProjectFinder::QrcUrlFinder::setProjectFiles(const FileNameList &projectFiles)
|
||||
{
|
||||
m_allQrcFiles = filtered(projectFiles, [](const FileName &f) { return f.endsWith(".qrc"); });
|
||||
m_fileCache.clear();
|
||||
m_parserCache.clear();
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -29,11 +29,13 @@
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QSharedPointer>
|
||||
#include <QStringList>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QUrl)
|
||||
|
||||
namespace Utils {
|
||||
class QrcParser;
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT FileInProjectFinder
|
||||
{
|
||||
@@ -73,6 +75,16 @@ private:
|
||||
int matchLength = 0;
|
||||
};
|
||||
|
||||
class QrcUrlFinder {
|
||||
public:
|
||||
QString find(const QUrl &fileUrl) const;
|
||||
void setProjectFiles(const FileNameList &projectFiles);
|
||||
private:
|
||||
FileNameList m_allQrcFiles;
|
||||
mutable QHash<QUrl, QString> m_fileCache;
|
||||
mutable QHash<FileName, QSharedPointer<QrcParser>> m_parserCache;
|
||||
};
|
||||
|
||||
CacheEntry findInSearchPaths(const QString &filePath, FileHandler fileHandler,
|
||||
DirectoryHandler directoryHandler) const;
|
||||
static CacheEntry findInSearchPath(const QString &searchPath, const QString &filePath,
|
||||
@@ -93,6 +105,7 @@ private:
|
||||
PathMappingNode m_pathMapRoot;
|
||||
|
||||
mutable QHash<QString, CacheEntry> m_cache;
|
||||
QrcUrlFinder m_qrcUrlFinder;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
Reference in New Issue
Block a user