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 "fileinprojectfinder.h"
|
||||||
|
|
||||||
|
#include "algorithm.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "hostosinfo.h"
|
#include "hostosinfo.h"
|
||||||
|
#include "qrcparser.h"
|
||||||
#include "qtcassert.h"
|
#include "qtcassert.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -102,6 +105,7 @@ void FileInProjectFinder::setProjectFiles(const FileNameList &projectFiles)
|
|||||||
|
|
||||||
m_projectFiles = projectFiles;
|
m_projectFiles = projectFiles;
|
||||||
m_cache.clear();
|
m_cache.clear();
|
||||||
|
m_qrcUrlFinder.setProjectFiles(projectFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileInProjectFinder::setSysroot(const FileName &sysroot)
|
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() << "...";
|
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();
|
QString originalPath = fileUrl.toLocalFile();
|
||||||
if (originalPath.isEmpty()) // e.g. qrc://
|
if (originalPath.isEmpty()) // e.g. qrc://
|
||||||
originalPath = fileUrl.path();
|
originalPath = fileUrl.path();
|
||||||
@@ -421,4 +432,34 @@ FileInProjectFinder::PathMappingNode::~PathMappingNode()
|
|||||||
qDeleteAll(children);
|
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
|
} // namespace Utils
|
||||||
|
@@ -29,11 +29,13 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QSharedPointer>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QUrl)
|
QT_FORWARD_DECLARE_CLASS(QUrl)
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
class QrcParser;
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT FileInProjectFinder
|
class QTCREATOR_UTILS_EXPORT FileInProjectFinder
|
||||||
{
|
{
|
||||||
@@ -73,6 +75,16 @@ private:
|
|||||||
int matchLength = 0;
|
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,
|
CacheEntry findInSearchPaths(const QString &filePath, FileHandler fileHandler,
|
||||||
DirectoryHandler directoryHandler) const;
|
DirectoryHandler directoryHandler) const;
|
||||||
static CacheEntry findInSearchPath(const QString &searchPath, const QString &filePath,
|
static CacheEntry findInSearchPath(const QString &searchPath, const QString &filePath,
|
||||||
@@ -93,6 +105,7 @@ private:
|
|||||||
PathMappingNode m_pathMapRoot;
|
PathMappingNode m_pathMapRoot;
|
||||||
|
|
||||||
mutable QHash<QString, CacheEntry> m_cache;
|
mutable QHash<QString, CacheEntry> m_cache;
|
||||||
|
QrcUrlFinder m_qrcUrlFinder;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
Reference in New Issue
Block a user