CplusPlus: Pass FilePath to Preprocessor::run()

... and update caller sides.

Change-Id: I6a107e4a7fd9f7123cdc6f141da202845bcbbb66
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2022-11-24 13:37:39 +01:00
parent 89f4381964
commit 9a8d34ecf8
12 changed files with 81 additions and 98 deletions

View File

@@ -50,16 +50,15 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc,
return preprocessed;
}
void FastPreprocessor::sourceNeeded(int line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes)
void FastPreprocessor::sourceNeeded(int line, const FilePath &filePath, IncludeType mode,
const FilePaths &initialIncludes)
{
Q_UNUSED(initialIncludes)
Q_ASSERT(_currentDoc);
FilePath filePath = FilePath::fromString(fileName);
if (_addIncludesToCurrentDoc) {
// CHECKME: Is that cleanPath needed?
const FilePath cleanPath = filePath.cleanPath();
_currentDoc->addIncludeFile(Document::Include(fileName, cleanPath, line, mode));
_currentDoc->addIncludeFile(Document::Include(filePath.toString(), cleanPath, line, mode));
}
mergeEnvironment(filePath);
}

View File

@@ -36,8 +36,8 @@ public:
bool mergeDefinedMacrosOfDocument = false);
// CPlusPlus::Client
virtual void sourceNeeded(int line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes = QStringList());
virtual void sourceNeeded(int line, const Utils::FilePath &filePath, IncludeType mode,
const Utils::FilePaths &initialIncludes = {});
virtual void macroAdded(const Macro &);

View File

@@ -5,13 +5,11 @@
#include <cplusplus/CPlusPlusForwardDeclarations.h>
#include <utils/filepath.h>
#include <QStringList>
#include <QVector>
QT_BEGIN_NAMESPACE
class QByteArray;
QT_END_NAMESPACE
namespace CPlusPlus {
class ByteArrayRef;
@@ -74,8 +72,7 @@ public:
virtual void startExpandingMacro(int bytesOffset, int utf16charsOffset,
int line, const Macro &macro,
const QVector<MacroArgumentReference> &actuals
= QVector<MacroArgumentReference>()) = 0;
const QVector<MacroArgumentReference> &actuals = {}) = 0;
virtual void stopExpandingMacro(int bytesOffset, const Macro &macro) = 0; // TODO: ?!
/// Mark the given macro name as the include guard for the current file.
@@ -85,8 +82,8 @@ public:
virtual void startSkippingBlocks(int utf16charsOffset) = 0;
virtual void stopSkippingBlocks(int utf16charsOffset) = 0;
virtual void sourceNeeded(int line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes = QStringList()) = 0;
virtual void sourceNeeded(int line, const Utils::FilePath &fileName, IncludeType mode,
const Utils::FilePaths &initialIncludes = {}) = 0;
static inline bool isInjectedFile(const QString &fileName)
{

View File

@@ -1687,7 +1687,7 @@ void Preprocessor::handleIncludeDirective(PPToken *tk, bool includeNext)
if (m_client) {
QString inc = QString::fromUtf8(included.constData() + 1, included.size() - 2);
m_client->sourceNeeded(line, inc, mode);
m_client->sourceNeeded(line, FilePath::fromString(inc), mode);
}
}

View File

@@ -187,18 +187,18 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
sourceProcessor.setWorkingCopy(workingCopy);
sourceProcessor.setHeaderPaths(state.headerPaths);
sourceProcessor.setLanguageFeatures(features);
sourceProcessor.run(configurationFileName.path());
sourceProcessor.run(configurationFileName);
if (baseConfig.usePrecompiledHeaders) {
for (const QString &precompiledHeader : std::as_const(state.precompiledHeaders))
sourceProcessor.run(precompiledHeader);
sourceProcessor.run(FilePath::fromString(precompiledHeader));
}
if (!baseState.editorDefines.isEmpty())
sourceProcessor.run(CppModelManager::editorConfigurationFileName().path());
sourceProcessor.run(CppModelManager::editorConfigurationFileName());
QStringList includedFiles = state.includedFiles;
if (baseConfig.usePrecompiledHeaders)
includedFiles << state.precompiledHeaders;
includedFiles.removeDuplicates();
sourceProcessor.run(filePath().toString(), includedFiles);
sourceProcessor.run(filePath(), transform(includedFiles, &FilePath::fromString));
state.snapshot = sourceProcessor.snapshot();
Snapshot newSnapshot = state.snapshot.simplified(state.snapshot.document(filePath()));
for (Snapshot::const_iterator i = state.snapshot.begin(), ei = state.snapshot.end(); i != ei; ++i) {

View File

@@ -200,9 +200,9 @@ void index(QFutureInterface<void> &indexingFuture,
const bool isSourceFile = i < sourceCount;
if (isSourceFile) {
(void) sourceProcessor->run(conf.path());
sourceProcessor->run(conf);
} else if (!processingHeaders) {
(void) sourceProcessor->run(conf.path());
sourceProcessor->run(conf);
processingHeaders = true;
}
@@ -212,7 +212,7 @@ void index(QFutureInterface<void> &indexingFuture,
? fallbackHeaderPaths
: parts.first()->headerPaths;
sourceProcessor->setHeaderPaths(headerPaths);
sourceProcessor->run(fileName);
sourceProcessor->run(FilePath::fromString(fileName));
indexingFuture.setProgressValue(files.size() - sourceProcessor->todo().size());

View File

@@ -63,18 +63,18 @@ inline QByteArray generateFingerPrint(const QList<CPlusPlus::Macro> &definedMacr
return hash.result();
}
inline Message messageNoSuchFile(Document::Ptr &document, const QString &fileName, unsigned line)
inline Message messageNoSuchFile(Document::Ptr &document, const FilePath &filePath, unsigned line)
{
const QString text = QCoreApplication::translate(
"CppSourceProcessor", "%1: No such file or directory").arg(fileName);
"CppSourceProcessor", "%1: No such file or directory").arg(filePath.displayName());
return Message(Message::Warning, document->filePath(), line, /*column =*/ 0, text);
}
inline Message messageNoFileContents(Document::Ptr &document, const QString &fileName,
inline Message messageNoFileContents(Document::Ptr &document, const FilePath &filePath,
unsigned line)
{
const QString text = QCoreApplication::translate(
"CppSourceProcessor", "%1: Could not get file contents").arg(fileName);
"CppSourceProcessor", "%1: Could not get file contents").arg(filePath.displayName());
return Message(Message::Warning, document->filePath(), line, /*column =*/ 0, text);
}
@@ -117,7 +117,7 @@ void CppSourceProcessor::setHeaderPaths(const ProjectExplorer::HeaderPaths &head
if (path.type == HeaderPathType::Framework )
addFrameworkPath(path);
else
m_headerPaths.append({cleanPath(path.path), path.type});
m_headerPaths.append({path.path, path.type});
}
}
@@ -141,7 +141,7 @@ void CppSourceProcessor::addFrameworkPath(const ProjectExplorer::HeaderPath &fra
// in the frameworks we're linking against. If we would have that, then we could
// add only those private frameworks.
const auto cleanFrameworkPath = ProjectExplorer::HeaderPath::makeFramework(
cleanPath(frameworkPath.path));
frameworkPath.path);
if (!m_headerPaths.contains(cleanFrameworkPath))
m_headerPaths.append(cleanFrameworkPath);
@@ -164,10 +164,10 @@ void CppSourceProcessor::setTodo(const QSet<QString> &files)
m_todo = files;
}
void CppSourceProcessor::run(const QString &fileName,
const QStringList &initialIncludes)
void CppSourceProcessor::run(const FilePath &filePath,
const FilePaths &initialIncludes)
{
sourceNeeded(0, fileName, IncludeGlobal, initialIncludes);
sourceNeeded(0, filePath, IncludeGlobal, initialIncludes);
}
void CppSourceProcessor::removeFromCache(const FilePath &filePath)
@@ -224,80 +224,70 @@ bool CppSourceProcessor::checkFile(const FilePath &absoluteFilePath) const
return absoluteFilePath.isReadableFile();
}
QString CppSourceProcessor::cleanPath(const QString &path)
{
QString result = QDir::cleanPath(path);
const QChar slash(QLatin1Char('/'));
if (!result.endsWith(slash))
result.append(slash);
return result;
}
/// Resolve the given file name to its absolute path w.r.t. the include type.
QString CppSourceProcessor::resolveFile(const QString &fileName, IncludeType type)
FilePath CppSourceProcessor::resolveFile(const FilePath &filePath, IncludeType type)
{
if (isInjectedFile(fileName))
return fileName;
if (isInjectedFile(filePath.path()))
return filePath;
const FilePath filePath = FilePath::fromString(fileName);
if (filePath.isAbsolutePath())
return checkFile(filePath) ? fileName : QString();
return checkFile(filePath) ? filePath : FilePath();
if (m_currentDoc) {
if (type == IncludeLocal) {
const QFileInfo currentFileInfo = m_currentDoc->filePath().toFileInfo();
const QString path = cleanPath(currentFileInfo.absolutePath()) + fileName;
if (checkFile(FilePath::fromString(path)))
const FilePath currentFilePath = m_currentDoc->filePath();
const FilePath path = currentFilePath.resolvePath("../" + filePath.path());
if (checkFile(path))
return path;
// Fall through! "16.2 Source file inclusion" from the standard states to continue
// searching as if this would be a global include.
} else if (type == IncludeNext) {
const QFileInfo currentFileInfo = m_currentDoc->filePath().toFileInfo();
const QString currentDirPath = cleanPath(currentFileInfo.dir().path());
const FilePath currentFilePath = m_currentDoc->filePath();
const FilePath currentDirPath = currentFilePath.parentDir();
auto headerPathsEnd = m_headerPaths.end();
auto headerPathsIt = m_headerPaths.begin();
for (; headerPathsIt != headerPathsEnd; ++headerPathsIt) {
if (headerPathsIt->path == currentDirPath) {
if (headerPathsIt->path == currentDirPath.path()) {
++headerPathsIt;
return resolveFile_helper(fileName, headerPathsIt);
return resolveFile_helper(filePath, headerPathsIt);
}
}
}
}
QHash<QString, QString>::ConstIterator it = m_fileNameCache.constFind(fileName);
const auto it = m_fileNameCache.constFind(filePath);
if (it != m_fileNameCache.constEnd())
return it.value();
const QString fn = resolveFile_helper(fileName, m_headerPaths.begin());
const FilePath fn = resolveFile_helper(filePath, m_headerPaths.begin());
if (!fn.isEmpty())
m_fileNameCache.insert(fileName, fn);
m_fileNameCache.insert(filePath, fn);
return fn;
}
QString CppSourceProcessor::resolveFile_helper(const QString &fileName,
FilePath CppSourceProcessor::resolveFile_helper(const FilePath &filePath,
ProjectExplorer::HeaderPaths::Iterator headerPathsIt)
{
const QString fileName = filePath.path();
auto headerPathsEnd = m_headerPaths.end();
const int index = fileName.indexOf(QLatin1Char('/'));
for (; headerPathsIt != headerPathsEnd; ++headerPathsIt) {
if (!headerPathsIt->path.isNull()) {
QString path;
FilePath path;
if (headerPathsIt->type == ProjectExplorer::HeaderPathType::Framework) {
if (index == -1)
continue;
path = headerPathsIt->path + fileName.left(index)
+ QLatin1String(".framework/Headers/") + fileName.mid(index + 1);
path = FilePath::fromString(headerPathsIt->path).pathAppended(fileName.left(index)
+ QLatin1String(".framework/Headers/") + fileName.mid(index + 1));
} else {
path = headerPathsIt->path + fileName;
path = FilePath::fromString(headerPathsIt->path) / fileName;
}
const FilePath filePath = FilePath::fromString(path);
if (m_workingCopy.contains(filePath) || checkFile(filePath))
if (m_workingCopy.contains(path) || checkFile(path))
return path;
}
}
return QString();
return {};
}
void CppSourceProcessor::macroAdded(const CPlusPlus::Macro &macro)
@@ -388,7 +378,7 @@ void CppSourceProcessor::mergeEnvironment(Document::Ptr doc)
if (Document::Ptr includedDoc = m_snapshot.document(includedFile))
mergeEnvironment(includedDoc);
else if (!m_included.contains(includedFile))
run(includedFile.toString());
run(includedFile);
}
m_env.addMacros(doc->definedMacros());
@@ -406,34 +396,33 @@ void CppSourceProcessor::stopSkippingBlocks(int utf16charsOffset)
m_currentDoc->stopSkippingBlocks(utf16charsOffset);
}
void CppSourceProcessor::sourceNeeded(int line, const QString &fileName, IncludeType type,
const QStringList &initialIncludes)
void CppSourceProcessor::sourceNeeded(int line, const FilePath &filePath, IncludeType type,
const FilePaths &initialIncludes)
{
if (fileName.isEmpty())
if (filePath.isEmpty())
return;
const QString absoluteFileName = QDir::cleanPath(resolveFile(fileName, type));
const FilePath absoluteFilePath = FilePath::fromString(absoluteFileName);
const FilePath absoluteFilePath = resolveFile(filePath, type);
if (m_currentDoc) {
m_currentDoc->addIncludeFile(Document::Include(fileName, absoluteFilePath, line, type));
if (absoluteFileName.isEmpty()) {
m_currentDoc->addDiagnosticMessage(messageNoSuchFile(m_currentDoc, fileName, line));
m_currentDoc->addIncludeFile(Document::Include(filePath.toString(), absoluteFilePath, line, type));
if (absoluteFilePath.isEmpty()) {
m_currentDoc->addDiagnosticMessage(messageNoSuchFile(m_currentDoc, filePath, line));
return;
}
}
if (m_included.contains(absoluteFilePath))
return; // We've already seen this file.
if (!isInjectedFile(absoluteFileName))
if (!isInjectedFile(absoluteFilePath.path()))
m_included.insert(absoluteFilePath);
// Already in snapshot? Use it!
if (Document::Ptr document = m_snapshot.document(absoluteFileName)) {
if (Document::Ptr document = m_snapshot.document(absoluteFilePath)) {
mergeEnvironment(document);
return;
}
const QFileInfo info(absoluteFileName);
const QFileInfo info = absoluteFilePath.toFileInfo();
if (fileSizeExceedsLimit(info, m_fileSizeLimitInMb))
return; // TODO: Add diagnostic message
@@ -442,7 +431,7 @@ void CppSourceProcessor::sourceNeeded(int line, const QString &fileName, Include
QByteArray contents;
const bool gotFileContents = getFileContents(absoluteFilePath, &contents, &editorRevision);
if (m_currentDoc && !gotFileContents) {
m_currentDoc->addDiagnosticMessage(messageNoFileContents(m_currentDoc, fileName, line));
m_currentDoc->addDiagnosticMessage(messageNoFileContents(m_currentDoc, filePath, line));
return;
}
@@ -451,9 +440,9 @@ void CppSourceProcessor::sourceNeeded(int line, const QString &fileName, Include
Document::Ptr document = Document::create(absoluteFilePath);
document->setEditorRevision(editorRevision);
document->setLanguageFeatures(m_languageFeatures);
for (const QString &include : initialIncludes) {
m_included.insert(FilePath::fromString(include));
Document::Include inc(include, FilePath::fromString(include), 0, IncludeLocal);
for (const FilePath &include : initialIncludes) {
m_included.insert(include);
Document::Include inc(include.toString(), include, 0, IncludeLocal);
document->addIncludeFile(inc);
}
if (info.exists())
@@ -473,7 +462,7 @@ void CppSourceProcessor::sourceNeeded(int line, const QString &fileName, Include
switchCurrentDocument(previousDocument);
mergeEnvironment(globalDocument);
m_snapshot.insert(globalDocument);
m_todo.remove(absoluteFileName);
m_todo.remove(absoluteFilePath.toString());
return;
}
@@ -487,7 +476,7 @@ void CppSourceProcessor::sourceNeeded(int line, const QString &fileName, Include
m_documentFinished(document);
m_snapshot.insert(document);
m_todo.remove(absoluteFileName);
m_todo.remove(absoluteFilePath.toString());
switchCurrentDocument(previousDocument);
}

View File

@@ -31,8 +31,6 @@ public:
using DocumentCallback = std::function<void (const CPlusPlus::Document::Ptr &)>;
public:
static QString cleanPath(const QString &path);
CppSourceProcessor(const CPlusPlus::Snapshot &snapshot, DocumentCallback documentFinished);
~CppSourceProcessor() override;
@@ -45,7 +43,7 @@ public:
void setFileSizeLimitInMb(int fileSizeLimitInMb);
void setTodo(const QSet<QString> &files);
void run(const QString &fileName, const QStringList &initialIncludes = QStringList());
void run(const Utils::FilePath &filePath, const Utils::FilePaths &initialIncludes = {});
void removeFromCache(const Utils::FilePath &filePath);
void resetEnvironment();
@@ -62,8 +60,8 @@ private:
bool getFileContents(const Utils::FilePath &absoluteFilePath, QByteArray *contents,
unsigned *revision) const;
bool checkFile(const Utils::FilePath &absoluteFilePath) const;
QString resolveFile(const QString &fileName, IncludeType type);
QString resolveFile_helper(const QString &fileName,
Utils::FilePath resolveFile(const Utils::FilePath &filePath, IncludeType type);
Utils::FilePath resolveFile_helper(const Utils::FilePath &filePath,
ProjectExplorer::HeaderPaths::Iterator headerPathsIt);
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
@@ -83,8 +81,8 @@ private:
void markAsIncludeGuard(const QByteArray &macroName) override;
void startSkippingBlocks(int utf16charsOffset) override;
void stopSkippingBlocks(int utf16charsOffset) override;
void sourceNeeded(int line, const QString &fileName, IncludeType type,
const QStringList &initialIncludes) override;
void sourceNeeded(int line, const Utils::FilePath &filePath, IncludeType type,
const Utils::FilePaths &initialIncludes) override;
private:
CPlusPlus::Snapshot m_snapshot;
@@ -99,7 +97,7 @@ private:
CPlusPlus::Document::Ptr m_currentDoc;
QSet<QString> m_todo;
QSet<QString> m_processed;
QHash<QString, QString> m_fileNameCache;
QHash<Utils::FilePath, Utils::FilePath> m_fileNameCache;
int m_fileSizeLimitInMb = -1;
QTextCodec *m_defaultCodec;
};

View File

@@ -45,7 +45,7 @@ public:
CppModelManager::createSourceProcessor());
sourceProcessor->setHeaderPaths({ProjectExplorer::HeaderPath::makeUser(
TestIncludePaths::directoryOfTestFile())});
sourceProcessor->run(filePath.toString());
sourceProcessor->run(filePath);
Document::Ptr document = m_cmm->document(filePath);
return document;
@@ -180,7 +180,7 @@ void SourceProcessorTest::testIncludeNext()
{
const Core::Tests::TestDataDir data(
_(SRCDIR "/../../../tests/auto/cplusplus/preprocessor/data/include_next-data/"));
const QString mainFilePath = data.file(QLatin1String("main.cpp"));
const FilePath mainFilePath = data.filePath(QLatin1String("main.cpp"));
const QString customHeaderPath = data.directory(QLatin1String("customIncludePath"));
const QString systemHeaderPath = data.directory(QLatin1String("systemIncludePath"));

View File

@@ -516,7 +516,7 @@ static QList<Include> includesForSource(const FilePath &filePath)
QScopedPointer<CppSourceProcessor> sourceProcessor(CppModelManager::createSourceProcessor());
sourceProcessor->setHeaderPaths({ProjectExplorer::HeaderPath::makeUser(
TestIncludePaths::globalIncludePath())});
sourceProcessor->run(filePath.toString());
sourceProcessor->run(filePath);
Document::Ptr document = cmm->document(filePath);
return document->resolvedIncludes();

View File

@@ -1,4 +1,4 @@
add_qtc_test(tst_cplusplus_preprocessor
DEPENDS CppEditor
DEPENDS CppEditor Utils
SOURCES tst_preprocessor.cpp
)

View File

@@ -152,12 +152,12 @@ public:
virtual void stopSkippingBlocks(int utf16charsOffset)
{ m_skippedBlocks.last().end = utf16charsOffset; }
virtual void sourceNeeded(int line, const QString &includedFileName, IncludeType mode,
const QStringList &initialIncludes = QStringList())
virtual void sourceNeeded(int line, const Utils::FilePath &includedFileName, IncludeType mode,
const Utils::FilePaths &initialIncludes = {})
{
Q_UNUSED(initialIncludes)
#if 1
m_recordedIncludes.append(Include(includedFileName, mode, line));
m_recordedIncludes.append(Include(includedFileName.toString(), mode, line));
Q_UNUSED(m_env)
Q_UNUSED(m_includeDepth)
#else