Clang: Fix unresolved #includes for ui_*.h headers

...with an extra parse.

Previously, the creation of an e.g. "Qt Widgets Application" from the
wizard could show code model errors in mainwindow.cpp. Depending on
timing issues, the first error is either

  1. 'ui_mainwindow.h' file not found (QTCREATORBUG-15187)
    The parse happened before the in-memory ui_mainwindow.h was
    generated by uic. The file system watcher can't help here as the
    #include was not resolved successfully. And libclang's reparse does
    not handle this case (it would need to remember all failed #include
    stats...).
    ==> Detect this case with the help of the include paths and trigger
    a full parse.

  2. or: allocation of incomplete type... (QTCREATORBUG-15187)
    The parse happened after the generation of the in-memory
    ui_mainwindow.h, but before the clangbackend received the unsaved
    file.
    ==> Fix this by also writing the content of the unsaved file to our
    behind-the-scenes-created ui_mainwindow.h.

Fixes: QTCREATORBUG-15187
Fixes: QTCREATORBUG-17002
Change-Id: I4f3a81adaa3d604746977a402c29f83fbc5b0e44
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Nikolai Kosjar
2018-10-19 10:20:27 +02:00
parent 91ed30ffac
commit d52ac9a708
45 changed files with 359 additions and 70 deletions

View File

@@ -36,6 +36,7 @@ QDebug operator<<(QDebug debug, const FileContainer &container)
debug.nospace() << "FileContainer("
<< container.filePath << ", "
<< container.compilationArguments << ", "
<< container.headerPaths << ", "
<< container.documentRevision << ", "
<< container.textCodecName;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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

View File

@@ -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());

View File

@@ -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:

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;

View File

@@ -37,6 +37,9 @@ namespace ClangBackEnd {
template<class Result>
class DocumentJob : public AsyncJob<Result>
{
public:
Document pinnedDocument() const { return m_pinnedDocument; }
protected:
bool acquireDocument()
{

View File

@@ -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

View File

@@ -47,6 +47,8 @@ public:
UnsavedFiles &unsavedFiles,
ClangCodeModelClientInterface &client);
Jobs &jobs() const;
JobRequest createJobRequest(JobRequest::Type type,
PreferredTranslationUnit preferredTranslationUnit
= PreferredTranslationUnit::RecentlyParsed) const;

View File

@@ -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()

View File

@@ -206,6 +206,7 @@ Document Documents::createDocument(const FileContainer &fileContainer)
documents_.emplace_back(fileContainer.filePath,
fileContainer.compilationArguments,
fileContainer.headerPaths,
*this,
checkIfFileExists);

View File

@@ -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);

View File

@@ -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*/:

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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;

View File

@@ -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();

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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};
};

View File

@@ -60,6 +60,7 @@ struct Data {
ClangBackEnd::Documents documents{unsavedFiles};
Document document{Utf8StringLiteral(TESTDATA_DIR"/references.cpp"),
TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")}),
{},
documents};
};

View File

@@ -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};
};

View File

@@ -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

View File

@@ -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
};

View File

@@ -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));

View File

@@ -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,

View File

@@ -1,4 +1,5 @@
#include "translationunits.h"
#include "some/unresolved/file.h"
void function()
{

View File

@@ -0,0 +1,3 @@
#include "uicheader.h"
static UicObject o;

View File

@@ -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()};

View File

@@ -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:

View File

@@ -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()};

View File

@@ -51,6 +51,7 @@ struct Data {
Documents documents{unsavedFiles};
Document document{Utf8StringLiteral(TESTDATA_DIR "/highlightingmarks.cpp"),
TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14")}),
Utf8StringVector(),
documents};
};

View File

@@ -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(),

View File

@@ -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()};

View File

@@ -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,

View File

@@ -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(),

View File

@@ -131,6 +131,7 @@ struct Data {
TestEnvironment::addPlatformArguments(
{Utf8StringLiteral("-std=c++14"),
Utf8StringLiteral("-I" TESTDATA_DIR)}),
{},
documents};
TranslationUnit translationUnit{filePath,
filePath,