diff options
45 files changed, 359 insertions, 70 deletions
diff --git a/src/libs/clangsupport/filecontainer.cpp b/src/libs/clangsupport/filecontainer.cpp index 7f95e4b1d4..0f6f8288c9 100644 --- a/src/libs/clangsupport/filecontainer.cpp +++ b/src/libs/clangsupport/filecontainer.cpp @@ -36,6 +36,7 @@ QDebug operator<<(QDebug debug, const FileContainer &container) debug.nospace() << "FileContainer(" << container.filePath << ", " << container.compilationArguments << ", " + << container.headerPaths << ", " << container.documentRevision << ", " << container.textCodecName; diff --git a/src/libs/clangsupport/filecontainer.h b/src/libs/clangsupport/filecontainer.h index 16beff0bac..4f9595f5ba 100644 --- a/src/libs/clangsupport/filecontainer.h +++ b/src/libs/clangsupport/filecontainer.h @@ -53,11 +53,13 @@ public: FileContainer(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, const Utf8String &unsavedFileContent = Utf8String(), bool hasUnsavedFileContent = false, quint32 documentRevision = 0) : filePath(filePath), compilationArguments(compilationArguments), + headerPaths(headerPaths), unsavedFileContent(unsavedFileContent), documentRevision(documentRevision), hasUnsavedFileContent(hasUnsavedFileContent) @@ -66,9 +68,11 @@ public: FileContainer(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, quint32 documentRevision) : filePath(filePath), compilationArguments(compilationArguments), + headerPaths(headerPaths), documentRevision(documentRevision), hasUnsavedFileContent(false) { @@ -78,6 +82,7 @@ public: { out << container.filePath; out << container.compilationArguments; + out << container.headerPaths; out << container.unsavedFileContent; out << container.textCodecName; out << container.documentRevision; @@ -90,6 +95,7 @@ public: { in >> container.filePath; in >> container.compilationArguments; + in >> container.headerPaths; in >> container.unsavedFileContent; in >> container.textCodecName; in >> container.documentRevision; @@ -106,6 +112,7 @@ public: public: Utf8String filePath; Utf8StringVector compilationArguments; + Utf8StringVector headerPaths; Utf8String unsavedFileContent; Utf8String textCodecName; quint32 documentRevision = 0; diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp index 34a363407a..48b6de9959 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -374,9 +374,8 @@ void BackendCommunicator::documentsChangedWithRevisionCheck(Core::IDocument *doc const auto textDocument = qobject_cast<TextDocument*>(document); const auto filePath = textDocument->filePath().toString(); - documentsChangedWithRevisionCheck(FileContainer(filePath, - Utf8StringVector(), - textDocument->document()->revision())); + documentsChangedWithRevisionCheck( + FileContainer(filePath, {}, {}, textDocument->document()->revision())); } void BackendCommunicator::updateChangeContentStartPosition(const QString &filePath, int position) diff --git a/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri b/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri index 4d4bb22639..a7ef679399 100644 --- a/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri +++ b/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri @@ -7,7 +7,8 @@ SOURCES += \ $$PWD/clangcompletioncontextanalyzer.cpp \ $$PWD/clangdiagnosticfilter.cpp \ $$PWD/clangfixitoperation.cpp \ - $$PWD/clanghighlightingresultreporter.cpp + $$PWD/clanghighlightingresultreporter.cpp \ + $$PWD/clanguiheaderondiskmanager.cpp HEADERS += \ $$PWD/clangactivationsequencecontextprocessor.h \ @@ -17,4 +18,5 @@ HEADERS += \ $$PWD/clangdiagnosticfilter.h \ $$PWD/clangfixitoperation.h \ $$PWD/clanghighlightingresultreporter.h \ - $$PWD/clangisdiagnosticrelatedtolocation.h + $$PWD/clangisdiagnosticrelatedtolocation.h \ + $$PWD/clanguiheaderondiskmanager.h diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 959e90d22c..0738aa8e70 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -56,6 +56,7 @@ #include <cplusplus/CppDocument.h> +#include <utils/algorithm.h> #include <utils/textutils.h> #include <utils/qtcassert.h> #include <utils/runextensions.h> @@ -614,7 +615,7 @@ void ClangEditorDocumentProcessor::updateBackendDocument(CppTools::ProjectPart & const QStringList compilationArguments = projectPartOptions + fileOptions.options(); m_communicator.documentsOpened( - {fileContainerWithOptionsAndDocumentContent(compilationArguments)}); + {fileContainerWithOptionsAndDocumentContent(compilationArguments, projectPart.headerPaths)}); ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision()); } @@ -672,10 +673,18 @@ ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer( } ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithOptionsAndDocumentContent( - const QStringList &compilationArguments) const + const QStringList &compilationArguments, const ProjectExplorer::HeaderPaths headerPaths) const { + auto theHeaderPaths + = ::Utils::transform<QVector>(headerPaths, [](const ProjectExplorer::HeaderPath path) { + return Utf8String(QDir::toNativeSeparators(path.path)); + }); + theHeaderPaths << QDir::toNativeSeparators( + ClangModelManagerSupport::instance()->dummyUiHeaderOnDiskDirPath()); + return ClangBackEnd::FileContainer(filePath(), Utf8StringVector(compilationArguments), + theHeaderPaths, textDocument()->toPlainText(), true, revision()); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 9229a60132..78d777ddfa 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -124,7 +124,8 @@ private: const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic); ClangBackEnd::FileContainer simpleFileContainer(const QByteArray &codecName = QByteArray()) const; ClangBackEnd::FileContainer fileContainerWithOptionsAndDocumentContent( - const QStringList &compilationArguments) const; + const QStringList &compilationArguments, + const ProjectExplorer::HeaderPaths headerPaths) const; ClangBackEnd::FileContainer fileContainerWithDocumentContent() const; private: diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index b3ac6005df..ee6f984767 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -56,6 +56,7 @@ #include <QApplication> #include <QMenu> #include <QTextBlock> +#include <QTimer> using namespace ClangCodeModel; using namespace ClangCodeModel::Internal; @@ -317,7 +318,10 @@ void ClangModelManagerSupport::onAbstractEditorSupportContentsUpdated(const QStr { QTC_ASSERT(!filePath.isEmpty(), return); - const QString mappedPath = m_uiHeaderOnDiskManager.createIfNeeded(filePath); + if (content.size() == 0) + return; // Generation not yet finished. + + const QString mappedPath = m_uiHeaderOnDiskManager.write(filePath, content); m_communicator.unsavedFilesUpdated(mappedPath, content, 0); } diff --git a/src/plugins/clangcodemodel/clanguiheaderondiskmanager.cpp b/src/plugins/clangcodemodel/clanguiheaderondiskmanager.cpp index d08d3a5519..d17f69ed50 100644 --- a/src/plugins/clangcodemodel/clanguiheaderondiskmanager.cpp +++ b/src/plugins/clangcodemodel/clanguiheaderondiskmanager.cpp @@ -38,13 +38,13 @@ UiHeaderOnDiskManager::UiHeaderOnDiskManager() : m_temporaryDir("clang-uiheader- QTC_CHECK(m_temporaryDir.isValid()); } -QString UiHeaderOnDiskManager::createIfNeeded(const QString &filePath) +QString UiHeaderOnDiskManager::write(const QString &filePath, const QByteArray &content) { const QString mappedPath = mapPath(filePath); - if (!QFileInfo::exists(mappedPath)) { - const bool fileCreated = QFile(mappedPath).open(QFile::WriteOnly); // touch file - QTC_CHECK(fileCreated); - } + QFile file(mappedPath); + const bool fileCreated = file.open(QFile::WriteOnly); + const qint64 bytesWritten = file.write(content); + QTC_CHECK(fileCreated && bytesWritten != -1); return mappedPath; } diff --git a/src/plugins/clangcodemodel/clanguiheaderondiskmanager.h b/src/plugins/clangcodemodel/clanguiheaderondiskmanager.h index dd90054d73..a244fdb178 100644 --- a/src/plugins/clangcodemodel/clanguiheaderondiskmanager.h +++ b/src/plugins/clangcodemodel/clanguiheaderondiskmanager.h @@ -36,7 +36,7 @@ class UiHeaderOnDiskManager public: UiHeaderOnDiskManager(); - QString createIfNeeded(const QString &filePath); + QString write(const QString &filePath, const QByteArray &content); QString remove(const QString &filePath); QString mapPath(const QString &filePath) const; diff --git a/src/tools/clangbackend/source/clangcodemodelserver.cpp b/src/tools/clangbackend/source/clangcodemodelserver.cpp index 619ea1c6a3..e82766cf5e 100644 --- a/src/tools/clangbackend/source/clangcodemodelserver.cpp +++ b/src/tools/clangbackend/source/clangcodemodelserver.cpp @@ -28,11 +28,13 @@ #include "clangdocuments.h" #include "clangdocumentsuspenderresumer.h" #include "clangfilesystemwatcher.h" +#include "clangupdateannotationsjob.h" #include "codecompleter.h" #include "diagnosticset.h" #include "tokenprocessor.h" #include "clangexceptions.h" #include "skippedsourceranges.h" +#include "unsavedfile.h" #include <clangsupport/clangsupportdebugutils.h> #include <clangsupport/clangcodemodelservermessages.h> @@ -42,7 +44,9 @@ #include <QCoreApplication> #include <QDebug> +#include <QFileInfo> #include <QLoggingCategory> +#include <QDir> Q_LOGGING_CATEGORY(serverLog, "qtc.clangbackend.server", QtWarningMsg); @@ -97,7 +101,10 @@ void ClangCodeModelServer::documentsOpened(const ClangBackEnd::DocumentsOpenedMe std::vector<Document> createdDocuments = documents.create(toCreate); for (auto &document : createdDocuments) { document.setDirtyIfDependencyIsMet(document.filePath()); - documentProcessors().create(document); + DocumentProcessor processor = documentProcessors().create(document); + processor.jobs().setJobFinishedCallback([this](const Jobs::RunningJob &a, IAsyncJob *b) { + onJobFinished(a, b); + }); } const std::vector<Document> resetDocuments_ = resetDocuments(toReset); @@ -163,6 +170,7 @@ void ClangCodeModelServer::unsavedFilesUpdated(const UnsavedFilesUpdatedMessage try { unsavedFiles.createOrUpdate(message.fileContainers); documents.updateDocumentsWithChangedDependencies(message.fileContainers); + resetDocumentsWithUnresolvedIncludes(documents.documents()); updateAnnotationsTimer.start(updateAnnotationsTimeOutInMs); } catch (const std::exception &exception) { @@ -393,6 +401,14 @@ void ClangCodeModelServer::processSuspendResumeJobs(const std::vector<Document> } } +void ClangCodeModelServer::onJobFinished(const Jobs::RunningJob &jobRecord, IAsyncJob *job) +{ + if (jobRecord.jobRequest.type == JobRequest::Type::UpdateAnnotations) { + const auto updateJob = static_cast<UpdateAnnotationsJob *>(job); + resetDocumentsWithUnresolvedIncludes({updateJob->pinnedDocument()}); + } +} + void ClangCodeModelServer::categorizeFileContainers(const QVector<FileContainer> &fileContainers, QVector<FileContainer> &toCreate, DocumentResetInfos &toReset) const @@ -432,6 +448,49 @@ std::vector<Document> ClangCodeModelServer::resetDocuments(const DocumentResetIn return newDocuments; } +static bool isDocumentWithUnresolvedIncludesFixable(const Document &document, + const UnsavedFiles &unsavedFiles) +{ + for (uint i = 0; i < unsavedFiles.count(); ++i) { + const UnsavedFile &unsavedFile = unsavedFiles.at(i); + const Utf8String unsavedFilePath = QDir::cleanPath(unsavedFile.filePath()); + + for (const Utf8String &unresolvedPath : document.unresolvedFilePaths()) { + const QString documentDir = QFileInfo(document.filePath()).absolutePath(); + const QString candidate = QDir::cleanPath(documentDir + "/" + unresolvedPath.toString()); + + if (Utf8String(candidate) == unsavedFilePath) + return true; + + for (const Utf8String &headerPath : document.headerPaths()) { + Utf8String candidate = headerPath; + candidate.append(QStringLiteral("/")); + candidate.append(unresolvedPath); + candidate = QDir::cleanPath(candidate); + if (candidate == unsavedFilePath) + return true; + } + } + } + + return false; +} + +void ClangCodeModelServer::resetDocumentsWithUnresolvedIncludes( + const std::vector<Document> &documents) +{ + DocumentResetInfos toReset; + + for (const Document &document : documents) { + if (document.unresolvedFilePaths().isEmpty()) + continue; + if (isDocumentWithUnresolvedIncludesFixable(document, unsavedFiles)) + toReset << DocumentResetInfo{document, document.fileContainer()}; + } + + resetDocuments(toReset); +} + void ClangCodeModelServer::setUpdateAnnotationsTimeOutInMsForTestsOnly(int value) { updateAnnotationsTimeOutInMs = value; diff --git a/src/tools/clangbackend/source/clangcodemodelserver.h b/src/tools/clangbackend/source/clangcodemodelserver.h index 7379aafe33..14fefadcf2 100644 --- a/src/tools/clangbackend/source/clangcodemodelserver.h +++ b/src/tools/clangbackend/source/clangcodemodelserver.h @@ -83,10 +83,13 @@ private: void processTimerForVisibleButNotCurrentDocuments(); void processSuspendResumeJobs(const std::vector<Document> &documents); + void onJobFinished(const Jobs::RunningJob &jobRecord, IAsyncJob *job); + void categorizeFileContainers(const QVector<FileContainer> &fileContainers, QVector<FileContainer> &toCreate, DocumentResetInfos &toReset) const; std::vector<Document> resetDocuments(const DocumentResetInfos &infos); + void resetDocumentsWithUnresolvedIncludes(const std::vector<Document> &documents); void addAndRunUpdateJobs(std::vector<Document> documents); diff --git a/src/tools/clangbackend/source/clangdocument.cpp b/src/tools/clangbackend/source/clangdocument.cpp index 067864e60f..672c902854 100644 --- a/src/tools/clangbackend/source/clangdocument.cpp +++ b/src/tools/clangbackend/source/clangdocument.cpp @@ -51,6 +51,7 @@ class DocumentData public: DocumentData(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, Documents &documents); ~DocumentData(); @@ -59,10 +60,12 @@ public: const Utf8String filePath; const Utf8StringVector compilationArguments; + const Utf8StringVector headerPaths; TranslationUnits translationUnits; QSet<Utf8String> dependedFilePaths; + QSet<Utf8String> unresolvedFilePaths; uint documentRevision = 0; @@ -80,10 +83,12 @@ public: DocumentData::DocumentData(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, Documents &documents) : documents(documents), filePath(filePath), compilationArguments(compilationArguments), + headerPaths(headerPaths), translationUnits(filePath), isDirtyChangeTimePoint(Clock::now()) { @@ -97,10 +102,12 @@ DocumentData::~DocumentData() Document::Document(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, Documents &documents, FileExistsCheck fileExistsCheck) : d(std::make_shared<DocumentData>(filePath, compilationArguments, + headerPaths, documents)) { if (fileExistsCheck == FileExistsCheck::Check) @@ -164,12 +171,20 @@ Utf8StringVector Document::compilationArguments() const return d->compilationArguments; } +Utf8StringVector Document::headerPaths() const +{ + checkIfNull(); + + return d->headerPaths; +} + FileContainer Document::fileContainer() const { checkIfNull(); return FileContainer(d->filePath, d->compilationArguments, + d->headerPaths, Utf8String(), false, d->documentRevision); @@ -330,6 +345,20 @@ void Document::incorporateUpdaterResult(const TranslationUnitUpdateResult &resul } } +const QSet<Utf8String> Document::unresolvedFilePaths() const +{ + checkIfNull(); + + return d->unresolvedFilePaths; +} + +void Document::setUnresolvedFilePaths(const QSet<Utf8String> &unresolved) +{ + checkIfNull(); + + d->unresolvedFilePaths = unresolved; +} + TranslationUnit Document::translationUnit(PreferredTranslationUnit preferredTranslationUnit) const { checkIfNull(); diff --git a/src/tools/clangbackend/source/clangdocument.h b/src/tools/clangbackend/source/clangdocument.h index 90f5dd71b2..bb2eb42ab4 100644 --- a/src/tools/clangbackend/source/clangdocument.h +++ b/src/tools/clangbackend/source/clangdocument.h @@ -61,6 +61,7 @@ public: Document() = default; Document(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, Documents &documents, FileExistsCheck fileExistsCheck = FileExistsCheck::Check); ~Document(); @@ -80,6 +81,7 @@ public: Utf8String filePath() const; Utf8StringVector compilationArguments() const; + Utf8StringVector headerPaths() const; FileContainer fileContainer() const; uint documentRevision() const; @@ -106,6 +108,9 @@ public: TranslationUnitUpdateInput createUpdateInput() const; void incorporateUpdaterResult(const TranslationUnitUpdateResult &result) const; + const QSet<Utf8String> unresolvedFilePaths() const; + void setUnresolvedFilePaths(const QSet<Utf8String> &unresolved); + TranslationUnit translationUnit(PreferredTranslationUnit preferredTranslationUnit = PreferredTranslationUnit::RecentlyParsed) const; TranslationUnits &translationUnits() const; diff --git a/src/tools/clangbackend/source/clangdocumentjob.h b/src/tools/clangbackend/source/clangdocumentjob.h index 7808286ce0..d9b71d3a43 100644 --- a/src/tools/clangbackend/source/clangdocumentjob.h +++ b/src/tools/clangbackend/source/clangdocumentjob.h @@ -37,6 +37,9 @@ namespace ClangBackEnd { template<class Result> class DocumentJob : public AsyncJob<Result> { +public: + Document pinnedDocument() const { return m_pinnedDocument; } + protected: bool acquireDocument() { diff --git a/src/tools/clangbackend/source/clangdocumentprocessor.cpp b/src/tools/clangbackend/source/clangdocumentprocessor.cpp index e50195dbdb..dd390c6ba6 100644 --- a/src/tools/clangbackend/source/clangdocumentprocessor.cpp +++ b/src/tools/clangbackend/source/clangdocumentprocessor.cpp @@ -76,6 +76,11 @@ DocumentProcessor::DocumentProcessor(const Document &document, { } +Jobs &DocumentProcessor::jobs() const +{ + return d->jobs; +} + JobRequest DocumentProcessor::createJobRequest( JobRequest::Type type, PreferredTranslationUnit preferredTranslationUnit) const diff --git a/src/tools/clangbackend/source/clangdocumentprocessor.h b/src/tools/clangbackend/source/clangdocumentprocessor.h index e4b4985446..7de2664322 100644 --- a/src/tools/clangbackend/source/clangdocumentprocessor.h +++ b/src/tools/clangbackend/source/clangdocumentprocessor.h @@ -47,6 +47,8 @@ public: UnsavedFiles &unsavedFiles, ClangCodeModelClientInterface &client); + Jobs &jobs() const; + JobRequest createJobRequest(JobRequest::Type type, PreferredTranslationUnit preferredTranslationUnit = PreferredTranslationUnit::RecentlyParsed) const; diff --git a/src/tools/clangbackend/source/clangdocumentprocessors.cpp b/src/tools/clangbackend/source/clangdocumentprocessors.cpp index b4d4fbcdbd..951e4ef7a1 100644 --- a/src/tools/clangbackend/source/clangdocumentprocessors.cpp +++ b/src/tools/clangbackend/source/clangdocumentprocessors.cpp @@ -84,6 +84,8 @@ void DocumentProcessors::reset(const Document &oldDocument, const Document &newD [](const JobRequest &job) { return job.isTakeOverable(); }); + const Jobs::JobFinishedCallback jobFinishedCallback + = processor(oldDocument).jobs().jobFinishedCallback(); // Remove current processor remove(oldDocument); @@ -92,6 +94,7 @@ void DocumentProcessors::reset(const Document &oldDocument, const Document &newD DocumentProcessor newProcessor = create(newDocument); for (const JobRequest &job : jobsForNewProcessor) newProcessor.addJob(job); + newProcessor.jobs().setJobFinishedCallback(jobFinishedCallback); } JobRequests DocumentProcessors::process() diff --git a/src/tools/clangbackend/source/clangdocuments.cpp b/src/tools/clangbackend/source/clangdocuments.cpp index 83178f3d62..7b274d7755 100644 --- a/src/tools/clangbackend/source/clangdocuments.cpp +++ b/src/tools/clangbackend/source/clangdocuments.cpp @@ -206,6 +206,7 @@ Document Documents::createDocument(const FileContainer &fileContainer) documents_.emplace_back(fileContainer.filePath, fileContainer.compilationArguments, + fileContainer.headerPaths, *this, checkIfFileExists); diff --git a/src/tools/clangbackend/source/clangjobs.cpp b/src/tools/clangbackend/source/clangjobs.cpp index 9e33788da3..572bb9bde3 100644 --- a/src/tools/clangbackend/source/clangjobs.cpp +++ b/src/tools/clangbackend/source/clangjobs.cpp @@ -121,6 +121,11 @@ JobRequests Jobs::stop() return queuedJobs; } +Jobs::JobFinishedCallback Jobs::finishedCallback() const +{ + return m_jobFinishedCallback; +} + JobRequests Jobs::runJobs(const JobRequests &jobsRequests) { JobRequests jobsStarted; @@ -165,7 +170,7 @@ void Jobs::onJobFinished(IAsyncJob *asyncJob) if (m_jobFinishedCallback) { const RunningJob runningJob = m_running.value(asyncJob); - m_jobFinishedCallback(runningJob); + m_jobFinishedCallback(runningJob, asyncJob); } m_running.remove(asyncJob); diff --git a/src/tools/clangbackend/source/clangjobs.h b/src/tools/clangbackend/source/clangjobs.h index 5d5b2d460c..3b4966a8e1 100644 --- a/src/tools/clangbackend/source/clangjobs.h +++ b/src/tools/clangbackend/source/clangjobs.h @@ -50,7 +50,7 @@ public: }; using RunningJobs = QHash<IAsyncJob *, RunningJob>; - using JobFinishedCallback = std::function<void(RunningJob)>; + using JobFinishedCallback = std::function<void(RunningJob, IAsyncJob *)>; public: Jobs(Documents &documents, @@ -72,6 +72,7 @@ public: JobRequests process(); JobRequests stop(); + JobFinishedCallback finishedCallback() const; void setJobFinishedCallback(const JobFinishedCallback &jobFinishedCallback); public /*for tests*/: diff --git a/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp index ac9a1dfb85..07d50a1411 100644 --- a/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp +++ b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp @@ -58,7 +58,7 @@ void SupportiveTranslationUnitInitializer::startInitializing() m_document.translationUnits().createAndAppend(); - m_jobs.setJobFinishedCallback([this](const Jobs::RunningJob &runningJob) { + m_jobs.setJobFinishedCallback([this](const Jobs::RunningJob &runningJob, IAsyncJob *) { checkIfParseJobFinished(runningJob); }); addJob(JobRequest::Type::ParseSupportiveTranslationUnit); @@ -69,7 +69,8 @@ void SupportiveTranslationUnitInitializer::startInitializing() void SupportiveTranslationUnitInitializer::abort() { - m_jobs.setJobFinishedCallback(Jobs::JobFinishedCallback()); + if (m_document.translationUnits().size() > 1) + m_jobs.setJobFinishedCallback(Jobs::JobFinishedCallback()); m_state = State::Aborted; } diff --git a/src/tools/clangbackend/source/clangupdateannotationsjob.cpp b/src/tools/clangbackend/source/clangupdateannotationsjob.cpp index 6d836633d7..5a28d64ac2 100644 --- a/src/tools/clangbackend/source/clangupdateannotationsjob.cpp +++ b/src/tools/clangbackend/source/clangupdateannotationsjob.cpp @@ -31,8 +31,30 @@ #include <utils/qtcassert.h> +#include <QRegularExpression> + namespace ClangBackEnd { +// TODO: Add libclang API for this. +static QSet<Utf8String> unresolvedFilePaths(const QVector<DiagnosticContainer> &diagnostics) +{ + // We expect something like: + // fatal error: 'ops.h' file not found + QRegularExpression re("'(.*)' file not found"); + QSet<Utf8String> unresolved; + + for (const DiagnosticContainer &diagnostic : diagnostics) { + if (diagnostic.severity == DiagnosticSeverity::Fatal + && diagnostic.category == Utf8StringLiteral("Lexical or Preprocessor Issue")) { + const QString path = re.match(diagnostic.text).captured(1); + if (!path.isEmpty()) + unresolved << path; + } + } + + return unresolved; +} + IAsyncJob::AsyncPrepareResult UpdateAnnotationsJob::prepareAsyncRun() { const JobRequest jobRequest = context().jobRequest; @@ -53,6 +75,9 @@ IAsyncJob::AsyncPrepareResult UpdateAnnotationsJob::prepareAsyncRun() asyncResult.diagnostics, asyncResult.tokenInfos, asyncResult.skippedSourceRanges); + asyncResult.unresolvedFilePaths.unite( + unresolvedFilePaths({asyncResult.firstHeaderErrorDiagnostic})); + asyncResult.unresolvedFilePaths.unite(unresolvedFilePaths(asyncResult.diagnostics)); return asyncResult; }); @@ -66,6 +91,8 @@ void UpdateAnnotationsJob::finalizeAsyncRun() const AsyncResult result = asyncResult(); m_pinnedDocument.incorporateUpdaterResult(result.updateResult); + m_pinnedDocument.setUnresolvedFilePaths(result.unresolvedFilePaths); + context().client->annotations(AnnotationsMessage(m_pinnedFileContainer, result.diagnostics, result.firstHeaderErrorDiagnostic, diff --git a/src/tools/clangbackend/source/clangupdateannotationsjob.h b/src/tools/clangbackend/source/clangupdateannotationsjob.h index 8c0f89f430..8a813586ea 100644 --- a/src/tools/clangbackend/source/clangupdateannotationsjob.h +++ b/src/tools/clangbackend/source/clangupdateannotationsjob.h @@ -31,11 +31,15 @@ #include <clangsupport/tokeninfocontainer.h> #include <clangsupport/sourcerangecontainer.h> +#include <QSet> +#include <QVector> + namespace ClangBackEnd { struct UpdateAnnotationsJobResult { TranslationUnitUpdateResult updateResult; + QSet<Utf8String> unresolvedFilePaths; ClangBackEnd::DiagnosticContainer firstHeaderErrorDiagnostic; QVector<ClangBackEnd::DiagnosticContainer> diagnostics; diff --git a/tests/unit/unittest/clangcodecompleteresults-test.cpp b/tests/unit/unittest/clangcodecompleteresults-test.cpp index b95e1db266..30356a3744 100644 --- a/tests/unit/unittest/clangcodecompleteresults-test.cpp +++ b/tests/unit/unittest/clangcodecompleteresults-test.cpp @@ -56,7 +56,8 @@ TEST(ClangCodeCompleteResultsSlowTest, GetData) ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Document document(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), - Utf8StringVector(), + {}, + {}, documents); Utf8String nativeFilePath = FilePath::toNativeSeparators(document.filePath()); document.parse(); @@ -85,7 +86,8 @@ TEST(ClangCodeCompleteResultsSlowTest, MoveClangCodeCompleteResults) ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Document document(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), - Utf8StringVector(), + {}, + {}, documents); Utf8String nativeFilePath = FilePath::toNativeSeparators(document.filePath()); document.parse(); diff --git a/tests/unit/unittest/clangcodemodelserver-test.cpp b/tests/unit/unittest/clangcodemodelserver-test.cpp index ea0be4a618..c74e2a96d8 100644 --- a/tests/unit/unittest/clangcodemodelserver-test.cpp +++ b/tests/unit/unittest/clangcodemodelserver-test.cpp @@ -37,7 +37,10 @@ #include <clangcodemodelservermessages.h> +#include <clangcodemodel/clanguiheaderondiskmanager.h> + #include <utils/algorithm.h> +#include <utils/temporarydirectory.h> #include <QCoreApplication> #include <QFile> @@ -119,11 +122,13 @@ protected: int expectedAnnotationsMessages = AnnotationJobsMultiplier); void openDocument(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, int expectedAnnotationsMessages = AnnotationJobsMultiplier); void openDocuments(int expectedAnnotationsMessages); void openDocumentWithUnsavedContent(const Utf8String &filePath, const Utf8String &content); void closeDocument(const Utf8String &filePath); + void updateUnsavedFile(const Utf8String &filePath, const Utf8String &fileContent); void updateUnsavedContent(const Utf8String &filePath, const Utf8String &fileContent, quint32 revisionNumber); @@ -172,6 +177,8 @@ protected: const Utf8String aFilePath = Utf8StringLiteral("afile.cpp"); const Utf8String anExistingFilePath = Utf8StringLiteral(TESTDATA_DIR"/complete_translationunit_parse_error.cpp"); + + const Utf8String uicMainPath = Utf8StringLiteral(TESTDATA_DIR"/uicmain.cpp"); }; using ClangCodeModelServerSlowTest = ClangCodeModelServer; @@ -428,6 +435,52 @@ TEST_F(ClangCodeModelServerSlowTest, TakeOverJobsOnDocumentChange) updateVisibilty(filePathC, filePathC); // Enable processing jobs } +TEST_F(ClangCodeModelServerSlowTest, UicHeaderAvailableBeforeParse) +{ + // Write ui file + ClangCodeModel::Internal::UiHeaderOnDiskManager uiManager; + const QByteArray content = "class UicObject{};"; + const QString uiHeaderFilePath = uiManager.write("uicheader.h", content); + + // Open document + openDocument(uicMainPath, + {Utf8StringLiteral("-I"), Utf8String(uiManager.directoryPath())}, + {uiManager.directoryPath()}, + AnnotationJobsMultiplier); + updateVisibilty(uicMainPath, uicMainPath); + ASSERT_TRUE(waitUntilAllJobsFinished()); + + // Check + ASSERT_THAT(documents.document(uicMainPath).dependedFilePaths(), + Contains(uiHeaderFilePath)); +} + +TEST_F(ClangCodeModelServerSlowTest, UicHeaderAvailableAfterParse) +{ + ClangCodeModel::Internal::UiHeaderOnDiskManager uiManager; + const QString uiHeaderFilePath = uiManager.mapPath("uicheader.h"); + + // Open document + openDocument(uicMainPath, + {Utf8StringLiteral("-I"), Utf8String(uiManager.directoryPath())}, + {uiManager.directoryPath()}, + 2 * AnnotationJobsMultiplier); + updateVisibilty(uicMainPath, uicMainPath); + ASSERT_TRUE(waitUntilAllJobsFinished()); + ASSERT_THAT(documents.document(uicMainPath).dependedFilePaths(), + Not(Contains(uiHeaderFilePath))); + + // Write ui file and notify backend + const QByteArray content = "class UicObject{};"; + uiManager.write("uicheader.h", content); + updateUnsavedFile(Utf8String(uiHeaderFilePath), Utf8String::fromByteArray(content)); + + // Check + ASSERT_TRUE(waitUntilAllJobsFinished()); + ASSERT_THAT(documents.document(uicMainPath).dependedFilePaths(), + Contains(uiHeaderFilePath)); +} + void ClangCodeModelServer::SetUp() { clangServer.setClient(&mockClangCodeModelClient); @@ -454,14 +507,15 @@ bool ClangCodeModelServer::waitUntilAllJobsFinished(int timeOutInMs) void ClangCodeModelServer::openDocument(const Utf8String &filePath, int expectedAnnotationsMessages) { - openDocument(filePath, {}, expectedAnnotationsMessages); + openDocument(filePath, {}, {}, expectedAnnotationsMessages); } void ClangCodeModelServer::openDocument(const Utf8String &filePath, const Utf8StringVector &compilationArguments, + const Utf8StringVector &headerPaths, int expectedAnnotationsMessages) { - const FileContainer fileContainer(filePath, compilationArguments); + const FileContainer fileContainer(filePath, compilationArguments, headerPaths); const DocumentsOpenedMessage message({fileContainer}, filePath, {filePath}); expectAnnotations(expectedAnnotationsMessages); @@ -608,7 +662,7 @@ void ClangCodeModelServer::requestAnnotations(const Utf8String &filePath) void ClangCodeModelServer::requestReferences(quint32 documentRevision) { - const FileContainer fileContainer{filePathC, Utf8StringVector(), documentRevision}; + const FileContainer fileContainer{filePathC, {}, {}, documentRevision}; const RequestReferencesMessage message{fileContainer, 3, 9}; clangServer.requestReferences(message); @@ -616,7 +670,7 @@ void ClangCodeModelServer::requestReferences(quint32 documentRevision) void ClangCodeModelServer::requestFollowSymbol(quint32 documentRevision) { - const FileContainer fileContainer{filePathC, Utf8StringVector(), documentRevision}; + const FileContainer fileContainer{filePathC, {}, {}, documentRevision}; const RequestFollowSymbolMessage message{fileContainer, 43, 9}; clangServer.requestFollowSymbol(message); @@ -647,7 +701,7 @@ void ClangCodeModelServer::updateUnsavedContent(const Utf8String &filePath, void ClangCodeModelServer::removeUnsavedFile(const Utf8String &filePath) { - const FileContainer fileContainer(filePath, Utf8StringVector(), 74); + const FileContainer fileContainer(filePath, {}, {}, 74); const DocumentsChangedMessage message({fileContainer}); clangServer.documentsChanged(message); @@ -661,6 +715,15 @@ void ClangCodeModelServer::closeDocument(const Utf8String &filePath) clangServer.documentsClosed(message); } +void ClangCodeModelServer::updateUnsavedFile(const Utf8String &filePath, + const Utf8String &fileContent) +{ + const FileContainer fileContainer(filePath, fileContent, true, 0); + const UnsavedFilesUpdatedMessage message({fileContainer}); + + clangServer.unsavedFilesUpdated(message); +} + void ClangCodeModelServer::openDocumentAndWaitForFinished( const Utf8String &filePath, int expectedAnnotationsMessages) { diff --git a/tests/unit/unittest/clangdocument-test.cpp b/tests/unit/unittest/clangdocument-test.cpp index cf7b7dcb9d..26a4ab1bfd 100644 --- a/tests/unit/unittest/clangdocument-test.cpp +++ b/tests/unit/unittest/clangdocument-test.cpp @@ -100,15 +100,17 @@ TEST_F(Document, DefaultDocumentIsNotIntact) TEST_F(Document, ThrowExceptionForNonExistingFilePath) { - ASSERT_THROW(::Document(Utf8StringLiteral("file.cpp"), Utf8StringVector(), - documents), + ASSERT_THROW(::Document(Utf8StringLiteral("file.cpp"), {}, {}, documents), ClangBackEnd::DocumentFileDoesNotExistException); } TEST_F(Document, ThrowNoExceptionForNonExistingFilePathIfDoNotCheckIfFileExistsIsSet) { - ASSERT_NO_THROW(::Document(Utf8StringLiteral("file.cpp"), Utf8StringVector(), - documents, ::Document::FileExistsCheck::DoNotCheck)); + ASSERT_NO_THROW(::Document(Utf8StringLiteral("file.cpp"), + {}, + {}, + documents, + ::Document::FileExistsCheck::DoNotCheck)); } TEST_F(Document, DocumentIsValid) @@ -342,7 +344,7 @@ void Document::SetUp() QTemporaryFile temporaryFile; EXPECT_TRUE(temporaryFile.open()); EXPECT_TRUE(temporaryFile.write(readContentFromDocumentFile())); - ::Document document(temporaryFile.fileName(), Utf8StringVector(), documents); + ::Document document(temporaryFile.fileName(), {}, {}, documents); return document; } diff --git a/tests/unit/unittest/clangdocuments-test.cpp b/tests/unit/unittest/clangdocuments-test.cpp index 3597df810d..71a2ebed80 100644 --- a/tests/unit/unittest/clangdocuments-test.cpp +++ b/tests/unit/unittest/clangdocuments-test.cpp @@ -99,7 +99,7 @@ TEST_F(Documents, DoNotThrowForAddingNonExistingFileWithUnsavedContent) TEST_F(Documents, Add) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); documents.create({fileContainer}); @@ -109,8 +109,8 @@ TEST_F(Documents, Add) TEST_F(Documents, CreateWithUnsavedContentSetsDependenciesDirty) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer fileContainerWithUnsavedContent(otherFilePath, Utf8StringVector(), Utf8String(), true, 2u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer fileContainerWithUnsavedContent(otherFilePath, {}, {}, Utf8String(), true, 2u); auto dependentDocument = documents.create({fileContainer}).at(0); dependentDocument.setDependedFilePaths(QSet<Utf8String>() << filePath << otherFilePath); @@ -121,7 +121,7 @@ TEST_F(Documents, CreateWithUnsavedContentSetsDependenciesDirty) TEST_F(Documents, AddAndTestCreatedTranslationUnit) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); auto createdDocuments = documents.create({fileContainer}); @@ -130,7 +130,7 @@ TEST_F(Documents, AddAndTestCreatedTranslationUnit) TEST_F(Documents, ThrowForCreatingAnExistingDocument) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); documents.create({fileContainer}); ASSERT_THROW(documents.create({fileContainer}), ClangBackEnd::DocumentAlreadyExistsException); @@ -138,15 +138,15 @@ TEST_F(Documents, ThrowForCreatingAnExistingDocument) TEST_F(Documents, ThrowForUpdatingANonExistingDocument) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); ASSERT_THROW(documents.update({fileContainer}), ClangBackEnd::DocumentDoesNotExistException); } TEST_F(Documents, UpdateSingle) { - ClangBackEnd::FileContainer createFileContainer(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer updateFileContainer(filePath, Utf8StringVector(), 75u); + ClangBackEnd::FileContainer createFileContainer(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer updateFileContainer(filePath, {}, {}, 75u); documents.create({createFileContainer}); documents.update({updateFileContainer}); @@ -156,8 +156,8 @@ TEST_F(Documents, UpdateSingle) TEST_F(Documents, UpdateReturnsUpdatedDocument) { - ClangBackEnd::FileContainer createFileContainer(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer updateFileContainer(filePath, Utf8StringVector(), 75u); + ClangBackEnd::FileContainer createFileContainer(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer updateFileContainer(filePath, {}, {}, 75u); documents.create({createFileContainer}); const std::vector<Document> updatedDocuments = documents.update({updateFileContainer}); @@ -169,9 +169,9 @@ TEST_F(Documents, UpdateReturnsUpdatedDocument) // TODO: Does this test still makes sense? TEST_F(Documents, UpdateMultiple) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer fileContainerWithOtherProject(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer updatedFileContainer(filePath, Utf8StringVector(), 75u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer fileContainerWithOtherProject(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer updatedFileContainer(filePath, {}, {}, 75u); documents.create({fileContainer, fileContainerWithOtherProject}); documents.update({updatedFileContainer}); @@ -181,8 +181,8 @@ TEST_F(Documents, UpdateMultiple) TEST_F(DocumentsSlowTest, UpdateUnsavedFileAndCheckForReparse) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer headerContainer(headerPath, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer headerContainer(headerPath, {}, {}, 74u); ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, Utf8String(), true, 75u); documents.create({fileContainer, headerContainer}); Document document = documents.document(filePath); @@ -195,8 +195,8 @@ TEST_F(DocumentsSlowTest, UpdateUnsavedFileAndCheckForReparse) TEST_F(DocumentsSlowTest, RemoveFileAndCheckForReparse) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer headerContainer(headerPath, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer headerContainer(headerPath, {}, {}, 74u); ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, Utf8String(), true, 75u); documents.create({fileContainer, headerContainer}); Document document = documents.document(filePath); @@ -209,7 +209,7 @@ TEST_F(DocumentsSlowTest, RemoveFileAndCheckForReparse) TEST_F(Documents, DontGetNewerFileContainerIfRevisionIsTheSame) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); documents.create({fileContainer}); auto newerFileContainers = documents.newerFileContainers({fileContainer}); @@ -219,8 +219,8 @@ TEST_F(Documents, DontGetNewerFileContainerIfRevisionIsTheSame) TEST_F(Documents, GetNewerFileContainerIfRevisionIsDifferent) { - ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringVector(), 74u); - ClangBackEnd::FileContainer newerContainer(filePath, Utf8StringVector(), 75u); + ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); + ClangBackEnd::FileContainer newerContainer(filePath, {}, {}, 75u); documents.create({fileContainer}); auto newerFileContainers = documents.newerFileContainers({newerContainer}); @@ -256,7 +256,7 @@ TEST_F(Documents, RemoveAllValidIfExceptionIsThrown) ClangBackEnd::DocumentDoesNotExistException); ASSERT_THAT(documents.documents(), - Not(Contains(Document(filePath, Utf8StringVector(), documents)))); + Not(Contains(Document(filePath, {}, {}, documents)))); } TEST_F(Documents, HasDocument) diff --git a/tests/unit/unittest/clangfollowsymbol-test.cpp b/tests/unit/unittest/clangfollowsymbol-test.cpp index d4dabfbf87..628aa07618 100644 --- a/tests/unit/unittest/clangfollowsymbol-test.cpp +++ b/tests/unit/unittest/clangfollowsymbol-test.cpp @@ -114,8 +114,8 @@ public: ClangBackEnd::Documents documents{unsavedFiles}; Utf8StringVector compilationArguments{ TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")})}; - Document document = {sourceFilePath, compilationArguments, documents}; - Document headerDocument = {headerFilePath, compilationArguments, documents}; + Document document = {sourceFilePath, compilationArguments, {}, documents}; + Document headerDocument = {headerFilePath, compilationArguments, {}, documents}; QVector<Utf8String> deps{sourceFilePath, cursorPath}; }; diff --git a/tests/unit/unittest/clangreferencescollector-test.cpp b/tests/unit/unittest/clangreferencescollector-test.cpp index 177fc6d856..acf7c42ac3 100644 --- a/tests/unit/unittest/clangreferencescollector-test.cpp +++ b/tests/unit/unittest/clangreferencescollector-test.cpp @@ -60,6 +60,7 @@ struct Data { ClangBackEnd::Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR"/references.cpp"), TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")}), + {}, documents}; }; diff --git a/tests/unit/unittest/clangtooltipinfo-test.cpp b/tests/unit/unittest/clangtooltipinfo-test.cpp index 520af95f67..baca6cb623 100644 --- a/tests/unit/unittest/clangtooltipinfo-test.cpp +++ b/tests/unit/unittest/clangtooltipinfo-test.cpp @@ -85,6 +85,7 @@ struct Data { ClangBackEnd::Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR "/tooltipinfo.cpp"), {Utf8StringLiteral("-std=c++14")}, + {}, documents}; UnitTest::RunDocumentParse _1{document}; }; diff --git a/tests/unit/unittest/clangupdateannotationsjob-test.cpp b/tests/unit/unittest/clangupdateannotationsjob-test.cpp index 53a593973d..0bcd5a67c0 100644 --- a/tests/unit/unittest/clangupdateannotationsjob-test.cpp +++ b/tests/unit/unittest/clangupdateannotationsjob-test.cpp @@ -97,7 +97,7 @@ TEST_F(UpdateAnnotationsJobSlowTest, DontSendAnnotationsIfDocumentRevisionChange ASSERT_TRUE(waitUntilJobFinished(job)); } -TEST_F(UpdateAnnotationsJobSlowTest, UpdatesTranslationUnit) +TEST_F(UpdateAnnotationsJobSlowTest, UpdatesDependendFilePaths) { const QSet<Utf8String> dependendOnFilesBefore = document.dependedFilePaths(); job.setContext(jobContext); @@ -109,4 +109,16 @@ TEST_F(UpdateAnnotationsJobSlowTest, UpdatesTranslationUnit) ASSERT_THAT(dependendOnFilesBefore, Not(document.dependedFilePaths())); } +TEST_F(UpdateAnnotationsJobSlowTest, UpdatesUnresolvedFilePaths) +{ + const QSet<Utf8String> unresolvedBefore = document.unresolvedFilePaths(); + job.setContext(jobContext); + job.prepareAsyncRun(); + + job.runAsync(); + ASSERT_TRUE(waitUntilJobFinished(job)); + + ASSERT_THAT(unresolvedBefore, Not(document.unresolvedFilePaths())); +} + } // anonymous diff --git a/tests/unit/unittest/codecompleter-test.cpp b/tests/unit/unittest/codecompleter-test.cpp index 539afba9b6..ec865aacbd 100644 --- a/tests/unit/unittest/codecompleter-test.cpp +++ b/tests/unit/unittest/codecompleter-test.cpp @@ -109,119 +109,139 @@ protected: QString targetHeaderPath{includeDirectory.path() + QStringLiteral("/complete_target_header.h")}; ClangBackEnd::FileContainer mainFileContainer{Utf8StringLiteral(TESTDATA_DIR "/complete_completer_main.cpp"), - Utf8StringVector{includePathArgument}}; + Utf8StringVector{includePathArgument}, + {}}; ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; ClangBackEnd::Document document; QScopedPointer<ClangBackEnd::CodeCompleter> completer; ClangBackEnd::FileContainer unsavedMainFileContainer{mainFileContainer.filePath, {includePathArgument}, + {}, readFileContent("/complete_completer_main_unsaved.cpp"), true}; ClangBackEnd::FileContainer unsavedTargetHeaderFileContainer{targetHeaderPath, {includePathArgument}, + {}, readFileContent("/complete_target_header_unsaved.h"), true}; ClangBackEnd::FileContainer arrowFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_arrow.cpp"), {includePathArgument}, + {}, readFileContent("/complete_arrow.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withDotArrowCorrectionForPointer.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerBeforeTyping{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerAfterTyping{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withDotArrowCorrectionForPointer_afterTyping.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerInitial{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withDotArrowCorrectionForPointerInitial.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerUpdated{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withDotArrowCorrectionForPointerUpdated.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForObjectFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForObject.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withNoDotArrowCorrectionForObject.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForFloatFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForFloat.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withNoDotArrowCorrectionForFloat.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForObjectWithArrowOperatortFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForDotDotFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForDotDot.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withNoDotArrowCorrectionForDotDot.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForArrowDotFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForArrowDot.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withNoDotArrowCorrectionForArrowDot.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForOnlyDotFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForOnlyDot.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withNoDotArrowCorrectionForOnlyDot.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForColonColonFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForColonColon.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withNoDotArrowCorrectionForColonColon.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForForwardDeclaredClassPointer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp"), true }; ClangBackEnd::FileContainer globalCompletionAfterForwardDeclaredClassPointer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp"), true }; ClangBackEnd::FileContainer smartPointerCompletion{ Utf8StringLiteral(TESTDATA_DIR"/complete_smartpointer.cpp"), {includePathArgument}, + {}, readFileContent("/complete_smartpointer.cpp"), true }; ClangBackEnd::FileContainer completionsOrder{ Utf8StringLiteral(TESTDATA_DIR"/completions_order.cpp"), {includePathArgument}, + {}, readFileContent("/completions_order.cpp"), true }; diff --git a/tests/unit/unittest/codecompletionsextractor-test.cpp b/tests/unit/unittest/codecompletionsextractor-test.cpp index 7907ef8737..3e493ab44b 100644 --- a/tests/unit/unittest/codecompletionsextractor-test.cpp +++ b/tests/unit/unittest/codecompletionsextractor-test.cpp @@ -149,14 +149,14 @@ protected: ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Utf8StringVector compilationArguments{TestEnvironment::addPlatformArguments()}; - Document functionDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"), compilationArguments, documents}; - Document functionOverloadDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_functionoverload.cpp"), compilationArguments, documents}; - Document variableDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp"), compilationArguments, documents}; - Document classDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_class.cpp"), compilationArguments, documents}; - Document namespaceDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_namespace.cpp"), compilationArguments, documents}; - Document enumerationDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_enumeration.cpp"), compilationArguments, documents}; - Document constructorDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_constructor.cpp"), compilationArguments, documents}; - Document briefCommentDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_brief_comment.cpp"), compilationArguments, documents}; + Document functionDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"), compilationArguments, {}, documents}; + Document functionOverloadDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_functionoverload.cpp"), compilationArguments, {}, documents}; + Document variableDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp"), compilationArguments, {}, documents}; + Document classDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_class.cpp"), compilationArguments, {}, documents}; + Document namespaceDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_namespace.cpp"), compilationArguments, {}, documents}; + Document enumerationDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_enumeration.cpp"), compilationArguments, {}, documents}; + Document constructorDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_constructor.cpp"), compilationArguments, {}, documents}; + Document briefCommentDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_brief_comment.cpp"), compilationArguments, {}, documents}; }; using CodeCompletionsExtractorSlowTest = CodeCompletionsExtractor; @@ -610,6 +610,7 @@ TEST_F(CodeCompletionsExtractorSlowTest, UnsavedFile) { Document document(Utf8String::fromUtf8(TESTDATA_DIR "/complete_extractor_function.cpp"), compilationArguments, + {}, documents); unsavedFiles.createOrUpdate( {unsavedDataFileContainer(TESTDATA_DIR "/complete_extractor_function.cpp", @@ -629,6 +630,7 @@ TEST_F(CodeCompletionsExtractorSlowTest, ChangeUnsavedFile) { Document document(Utf8String::fromUtf8(TESTDATA_DIR "/complete_extractor_function.cpp"), compilationArguments, + {}, documents); unsavedFiles.createOrUpdate( {unsavedDataFileContainer(TESTDATA_DIR "/complete_extractor_function.cpp", @@ -652,6 +654,7 @@ TEST_F(CodeCompletionsExtractorSlowTest, ArgumentDefinition) Document variableDocument{Utf8StringLiteral(TESTDATA_DIR "/complete_extractor_variable.cpp"), {Utf8StringLiteral("-DArgumentDefinition"), Utf8StringLiteral("-std=gnu++14")}, + {}, documents}; ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); @@ -668,6 +671,7 @@ TEST_F(CodeCompletionsExtractorSlowTest, NoArgumentDefinition) { Document variableDocument{Utf8StringLiteral(TESTDATA_DIR "/complete_extractor_variable.cpp"), {Utf8StringLiteral("-std=gnu++14")}, + {}, documents}; ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); diff --git a/tests/unit/unittest/cursor-test.cpp b/tests/unit/unittest/cursor-test.cpp index 20e985043b..06a8af9965 100644 --- a/tests/unit/unittest/cursor-test.cpp +++ b/tests/unit/unittest/cursor-test.cpp @@ -64,6 +64,7 @@ struct Data { Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/cursor.cpp")}; Document document{filePath, TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), + {}, documents}; TranslationUnit translationUnit{filePath, filePath, diff --git a/tests/unit/unittest/data/translationunits.cpp b/tests/unit/unittest/data/translationunits.cpp index d1165e73da..8ab60b10e1 100644 --- a/tests/unit/unittest/data/translationunits.cpp +++ b/tests/unit/unittest/data/translationunits.cpp @@ -1,4 +1,5 @@ #include "translationunits.h" +#include "some/unresolved/file.h" void function() { diff --git a/tests/unit/unittest/data/uicmain.cpp b/tests/unit/unittest/data/uicmain.cpp new file mode 100644 index 0000000000..7739b1027b --- /dev/null +++ b/tests/unit/unittest/data/uicmain.cpp @@ -0,0 +1,3 @@ +#include "uicheader.h" + +static UicObject o; diff --git a/tests/unit/unittest/diagnostic-test.cpp b/tests/unit/unittest/diagnostic-test.cpp index be9f9f7f83..fac44162cd 100644 --- a/tests/unit/unittest/diagnostic-test.cpp +++ b/tests/unit/unittest/diagnostic-test.cpp @@ -88,6 +88,7 @@ protected: ClangBackEnd::Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnostic.cpp"), TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), + {}, documents}; UnitTest::RunDocumentParse _1{document}; DiagnosticSet diagnosticSet{document.translationUnit().diagnostics()}; diff --git a/tests/unit/unittest/diagnosticset-test.cpp b/tests/unit/unittest/diagnosticset-test.cpp index 8c8d336747..f37d00e13f 100644 --- a/tests/unit/unittest/diagnosticset-test.cpp +++ b/tests/unit/unittest/diagnosticset-test.cpp @@ -67,9 +67,11 @@ protected: TestEnvironment::addPlatformArguments({Utf8StringLiteral("-pedantic")})}; Document document{Utf8StringLiteral(TESTDATA_DIR "/diagnostic_diagnosticset.cpp"), compilationArguments, + {}, documents}; Document documentMainFile{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnosticset_mainfile.cpp"), compilationArguments, + {}, documents}; protected: diff --git a/tests/unit/unittest/fixit-test.cpp b/tests/unit/unittest/fixit-test.cpp index 08c41766c1..0063dc27fc 100644 --- a/tests/unit/unittest/fixit-test.cpp +++ b/tests/unit/unittest/fixit-test.cpp @@ -70,7 +70,8 @@ struct Data ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_semicolon_fixit.cpp"), - Utf8StringVector(), + {}, + {}, documents}; UnitTest::RunDocumentParse _1{document}; TranslationUnit translationUnit{document.translationUnit()}; diff --git a/tests/unit/unittest/highlightingresultreporter-test.cpp b/tests/unit/unittest/highlightingresultreporter-test.cpp index a9fa277ef3..29803783b1 100644 --- a/tests/unit/unittest/highlightingresultreporter-test.cpp +++ b/tests/unit/unittest/highlightingresultreporter-test.cpp @@ -51,6 +51,7 @@ struct Data { Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR "/highlightingmarks.cpp"), TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")}), + Utf8StringVector(), documents}; }; diff --git a/tests/unit/unittest/skippedsourceranges-test.cpp b/tests/unit/unittest/skippedsourceranges-test.cpp index 396e0eec06..083f795ec9 100644 --- a/tests/unit/unittest/skippedsourceranges-test.cpp +++ b/tests/unit/unittest/skippedsourceranges-test.cpp @@ -90,8 +90,8 @@ struct Data { ClangBackEnd::Documents documents{unsavedFiles}; Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/skippedsourceranges.cpp"); Utf8StringVector compilationArguments{TestEnvironment::addPlatformArguments( - {Utf8StringLiteral("-std=c++11"), Utf8StringLiteral("-DBLAH")})}; - Document document{filePath, compilationArguments, documents}; + {Utf8StringLiteral("-std=c++11"), {}, Utf8StringLiteral("-DBLAH")})}; + Document document{filePath, compilationArguments, {}, documents}; TranslationUnit translationUnit{filePath, filePath, document.translationUnit().cxIndex(), diff --git a/tests/unit/unittest/sourcelocation-test.cpp b/tests/unit/unittest/sourcelocation-test.cpp index f2e8c90868..101ba2d6c8 100644 --- a/tests/unit/unittest/sourcelocation-test.cpp +++ b/tests/unit/unittest/sourcelocation-test.cpp @@ -51,7 +51,8 @@ struct Data { ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{unsavedFiles}; Document document{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_source_location.cpp"), - Utf8StringVector(), + {}, + {}, documents}; UnitTest::RunDocumentParse _1{document}; DiagnosticSet diagnosticSet{document.translationUnit().diagnostics()}; diff --git a/tests/unit/unittest/sourcerange-test.cpp b/tests/unit/unittest/sourcerange-test.cpp index daa3fa4994..c66b9854db 100644 --- a/tests/unit/unittest/sourcerange-test.cpp +++ b/tests/unit/unittest/sourcerange-test.cpp @@ -76,6 +76,7 @@ struct Data { Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_source_range.cpp")}; Document document{filePath, {TestEnvironment::addPlatformArguments({Utf8StringLiteral("-pedantic")})}, + {}, documents}; UnitTest::RunDocumentParse _1{document}; TranslationUnit translationUnit{filePath, diff --git a/tests/unit/unittest/token-test.cpp b/tests/unit/unittest/token-test.cpp index 6dd30cadf4..3f7c39ea5f 100644 --- a/tests/unit/unittest/token-test.cpp +++ b/tests/unit/unittest/token-test.cpp @@ -56,7 +56,7 @@ struct Data { Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/token.cpp")}; Utf8StringVector compilationArguments{ TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++11")})}; - Document document{filePath, compilationArguments, documents}; + Document document{filePath, compilationArguments, {}, documents}; TranslationUnit translationUnit{filePath, filePath, document.translationUnit().cxIndex(), diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp index a9cc385a24..2935a85381 100644 --- a/tests/unit/unittest/tokenprocessor-test.cpp +++ b/tests/unit/unittest/tokenprocessor-test.cpp @@ -131,6 +131,7 @@ struct Data { TestEnvironment::addPlatformArguments( {Utf8StringLiteral("-std=c++14"), Utf8StringLiteral("-I" TESTDATA_DIR)}), + {}, documents}; TranslationUnit translationUnit{filePath, filePath, |