forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/8.0'
Change-Id: Iea4fd2949f5d5345802e2e7d9283d72c6c55f69f
This commit is contained in:
@@ -3198,7 +3198,7 @@ class DumperBase():
|
|||||||
return self.cast(self.type.ltarget).extractField(field)
|
return self.cast(self.type.ltarget).extractField(field)
|
||||||
if self.type.code in (TypeCode.Reference, TypeCode.RValueReference):
|
if self.type.code in (TypeCode.Reference, TypeCode.RValueReference):
|
||||||
return self.dereference().extractField(field)
|
return self.dereference().extractField(field)
|
||||||
#DumperBase.warn('FIELD: %s ' % field)
|
#DumperBase.warn('FIELD: %s ' % (field,))
|
||||||
val = self.dumper.Value(self.dumper)
|
val = self.dumper.Value(self.dumper)
|
||||||
val.name = field.name
|
val.name = field.name
|
||||||
val.isBaseClass = field.isBase
|
val.isBaseClass = field.isBase
|
||||||
@@ -3227,10 +3227,7 @@ class DumperBase():
|
|||||||
lbyte = ldata[i]
|
lbyte = ldata[i]
|
||||||
else:
|
else:
|
||||||
lbyte = ldata[fieldOffset + fieldSize - 1 - i]
|
lbyte = ldata[fieldOffset + fieldSize - 1 - i]
|
||||||
if sys.version_info[0] >= 3:
|
data += ord(lbyte)
|
||||||
data += lbyte
|
|
||||||
else:
|
|
||||||
data += ord(lbyte)
|
|
||||||
data = data >> fieldBitpos
|
data = data >> fieldBitpos
|
||||||
data = data & ((1 << fieldBitsize) - 1)
|
data = data & ((1 << fieldBitsize) - 1)
|
||||||
val.lvalue = data
|
val.lvalue = data
|
||||||
|
|||||||
@@ -652,6 +652,13 @@ def qdump__QKeyEvent(d, value):
|
|||||||
d.putFields(value, dumpBase=True)
|
d.putFields(value, dumpBase=True)
|
||||||
|
|
||||||
|
|
||||||
|
def qdump__QKeySequence(d, value):
|
||||||
|
dd = d.extractPointer(value)
|
||||||
|
_, k0, k1, k2, k3 = d.split('iiiii', dd)
|
||||||
|
d.putValue("(0x%x, 0x%x, 0x%x, 0x%x)" % (k0, k1, k2, k3));
|
||||||
|
d.putPlainChildren(value)
|
||||||
|
|
||||||
|
|
||||||
def qdump__QFile(d, value):
|
def qdump__QFile(d, value):
|
||||||
# 9fc0965 and a373ffcd change the layout of the private structure
|
# 9fc0965 and a373ffcd change the layout of the private structure
|
||||||
qtVersion = d.qtVersion()
|
qtVersion = d.qtVersion()
|
||||||
|
|||||||
@@ -35,11 +35,10 @@ namespace Autotest {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
namespace QuickTestUtils {
|
namespace QuickTestUtils {
|
||||||
|
|
||||||
static const QByteArrayList valid = {"QUICK_TEST_MAIN", "QUICK_TEST_OPENGL_MAIN",
|
|
||||||
"QUICK_TEST_MAIN_WITH_SETUP"};
|
|
||||||
|
|
||||||
bool isQuickTestMacro(const QByteArray ¯o)
|
bool isQuickTestMacro(const QByteArray ¯o)
|
||||||
{
|
{
|
||||||
|
static const QByteArrayList valid = {"QUICK_TEST_MAIN", "QUICK_TEST_OPENGL_MAIN",
|
||||||
|
"QUICK_TEST_MAIN_WITH_SETUP"};
|
||||||
return valid.contains(macro);
|
return valid.contains(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
|
|||||||
const Utils::FilePath filePath = Utils::FilePath::fromString(doc->fileName());
|
const Utils::FilePath filePath = Utils::FilePath::fromString(doc->fileName());
|
||||||
|
|
||||||
for (const CPlusPlus::Document::MacroUse ¯o : macros) {
|
for (const CPlusPlus::Document::MacroUse ¯o : macros) {
|
||||||
if (!macro.isFunctionLike())
|
if (!macro.isFunctionLike() || macro.arguments().isEmpty())
|
||||||
continue;
|
continue;
|
||||||
const QByteArray name = macro.macro().name();
|
const QByteArray name = macro.macro().name();
|
||||||
if (QuickTestUtils::isQuickTestMacro(name)) {
|
if (QuickTestUtils::isQuickTestMacro(name)) {
|
||||||
@@ -137,7 +137,7 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const QByteArray &fileContent = getFileContent(filePath);
|
const QByteArray fileContent = getFileContent(filePath);
|
||||||
// check for using quick_test_main() directly
|
// check for using quick_test_main() directly
|
||||||
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath);
|
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath);
|
||||||
if (document.isNull())
|
if (document.isNull())
|
||||||
|
|||||||
@@ -651,6 +651,14 @@ DiagnosticManager *ClangdClient::createDiagnosticManager()
|
|||||||
return diagnosticManager;
|
return diagnosticManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClangdClient::referencesShadowFile(const TextEditor::TextDocument *doc,
|
||||||
|
const Utils::FilePath &candidate)
|
||||||
|
{
|
||||||
|
const QRegularExpression includeRex("#include.*" + candidate.fileName() + R"([>"])");
|
||||||
|
const QTextCursor includePos = doc->document()->find(includeRex);
|
||||||
|
return !includePos.isNull();
|
||||||
|
}
|
||||||
|
|
||||||
RefactoringChangesData *ClangdClient::createRefactoringChangesBackend() const
|
RefactoringChangesData *ClangdClient::createRefactoringChangesBackend() const
|
||||||
{
|
{
|
||||||
return new CppEditor::CppRefactoringChangesData(
|
return new CppEditor::CppRefactoringChangesData(
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ private:
|
|||||||
const CustomInspectorTabs createCustomInspectorTabs() override;
|
const CustomInspectorTabs createCustomInspectorTabs() override;
|
||||||
TextEditor::RefactoringChangesData *createRefactoringChangesBackend() const override;
|
TextEditor::RefactoringChangesData *createRefactoringChangesBackend() const override;
|
||||||
LanguageClient::DiagnosticManager *createDiagnosticManager() override;
|
LanguageClient::DiagnosticManager *createDiagnosticManager() override;
|
||||||
|
bool referencesShadowFile(const TextEditor::TextDocument *doc,
|
||||||
|
const Utils::FilePath &candidate) override;
|
||||||
|
|
||||||
class Private;
|
class Private;
|
||||||
class VirtualFunctionAssistProcessor;
|
class VirtualFunctionAssistProcessor;
|
||||||
|
|||||||
@@ -418,16 +418,18 @@ void ClangModelManagerSupport::updateLanguageClient(
|
|||||||
bool hasDocuments = false;
|
bool hasDocuments = false;
|
||||||
const ClangdSettings settings(ClangdProjectSettings(project).settings());
|
const ClangdSettings settings(ClangdProjectSettings(project).settings());
|
||||||
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
|
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
|
||||||
const Client * const currentClient = LanguageClientManager::clientForDocument(doc);
|
Client * const currentClient = LanguageClientManager::clientForDocument(doc);
|
||||||
if (!settings.sizeIsOkay(doc->filePath()))
|
if (!settings.sizeIsOkay(doc->filePath()))
|
||||||
continue;
|
continue;
|
||||||
|
const Project * const docProject = SessionManager::projectForFile(doc->filePath());
|
||||||
if (currentClient && currentClient->project()
|
if (currentClient && currentClient->project()
|
||||||
&& currentClient->project() != project) {
|
&& currentClient->project() != project
|
||||||
|
&& currentClient->project() == docProject) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (const Project * const docProject
|
if (!docProject || docProject == project) {
|
||||||
= SessionManager::projectForFile(doc->filePath());
|
if (currentClient)
|
||||||
!docProject || docProject == project) {
|
currentClient->closeDocument(doc);
|
||||||
LanguageClientManager::openDocumentWithClient(doc, client);
|
LanguageClientManager::openDocumentWithClient(doc, client);
|
||||||
hasDocuments = true;
|
hasDocuments = true;
|
||||||
}
|
}
|
||||||
@@ -532,15 +534,18 @@ void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client)
|
|||||||
if (!client)
|
if (!client)
|
||||||
return;
|
return;
|
||||||
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
|
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
|
||||||
if (Client * const currentClient = LanguageClientManager::clientForDocument(doc);
|
Client * const currentClient = LanguageClientManager::clientForDocument(doc);
|
||||||
currentClient && currentClient->state() == Client::Initialized
|
if (currentClient && currentClient->state() == Client::Initialized
|
||||||
&& (currentClient == client || currentClient->project())) {
|
&& (currentClient == client || currentClient->project())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!ClangdSettings::instance().sizeIsOkay(doc->filePath()))
|
if (!ClangdSettings::instance().sizeIsOkay(doc->filePath()))
|
||||||
continue;
|
continue;
|
||||||
if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath()))
|
if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath())) {
|
||||||
|
if (currentClient)
|
||||||
|
currentClient->closeDocument(doc);
|
||||||
LanguageClientManager::openDocumentWithClient(doc, client);
|
LanguageClientManager::openDocumentWithClient(doc, client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ void CompilationDatabaseTests::testFilterEmptyFlags()
|
|||||||
|
|
||||||
void CompilationDatabaseTests::testFilterFromFilename()
|
void CompilationDatabaseTests::testFilterFromFilename()
|
||||||
{
|
{
|
||||||
QCOMPARE(filterFromFileName(QStringList{"-o", "foo.o"}, "foo"), QStringList{"-o"});
|
QCOMPARE(filterFromFileName(QStringList{"-o", "foo.o"}, "foo.c"), QStringList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilationDatabaseTests::testFilterArguments()
|
void CompilationDatabaseTests::testFilterArguments()
|
||||||
@@ -169,8 +169,10 @@ void CompilationDatabaseTests::testFilterArguments()
|
|||||||
"c++",
|
"c++",
|
||||||
QString("--sysroot=") + (HostOsInfo::isWindowsHost()
|
QString("--sysroot=") + (HostOsInfo::isWindowsHost()
|
||||||
? "C:\\sysroot\\embedded" : "/opt/sysroot/embedded"),
|
? "C:\\sysroot\\embedded" : "/opt/sysroot/embedded"),
|
||||||
"C:\\qt-creator\\src\\plugins\\cpptools\\compileroptionsbuilder.cpp"},
|
QLatin1String(HostOsInfo::isWindowsHost()
|
||||||
"compileroptionsbuilder");
|
? "C:\\qt-creator\\src\\plugins\\cpptools\\compileroptionsbuilder.cpp"
|
||||||
|
: "/opt/qt-creator/src/plugins/cpptools/compileroptionsbuilder.cpp")},
|
||||||
|
"compileroptionsbuilder.cpp");
|
||||||
|
|
||||||
testData.getFilteredFlags();
|
testData.getFilteredFlags();
|
||||||
|
|
||||||
@@ -241,7 +243,7 @@ void CompilationDatabaseTests::testFilterCommand()
|
|||||||
testData.fileName = "SemaCodeComplete.cpp";
|
testData.fileName = "SemaCodeComplete.cpp";
|
||||||
testData.workingDir = "C:/build-qt_llvm-msvc2017_64bit-Debug";
|
testData.workingDir = "C:/build-qt_llvm-msvc2017_64bit-Debug";
|
||||||
testData.flags = filterFromFileName(testData.getSplitCommandLine(kCmakeCommand),
|
testData.flags = filterFromFileName(testData.getSplitCommandLine(kCmakeCommand),
|
||||||
"SemaCodeComplete");
|
"SemaCodeComplete.cpp");
|
||||||
testData.getFilteredFlags();
|
testData.getFilteredFlags();
|
||||||
|
|
||||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
if (Utils::HostOsInfo::isWindowsHost()) {
|
||||||
@@ -278,7 +280,7 @@ void CompilationDatabaseTests::testFileKindDifferentFromExtension2()
|
|||||||
void CompilationDatabaseTests::testSkipOutputFiles()
|
void CompilationDatabaseTests::testSkipOutputFiles()
|
||||||
{
|
{
|
||||||
CompilationDatabaseUtilsTestData testData;
|
CompilationDatabaseUtilsTestData testData;
|
||||||
testData.flags = filterFromFileName(QStringList{"-o", "foo.o"}, "foo");
|
testData.flags = filterFromFileName(QStringList{"-o", "foo.o"}, "foo.cpp");
|
||||||
|
|
||||||
QVERIFY(testData.getFilteredFlags().isEmpty());
|
QVERIFY(testData.getFilteredFlags().isEmpty());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,14 +84,24 @@ static CppEditor::ProjectFile::Kind fileKindFromString(QString flag)
|
|||||||
return ProjectFile::Unclassified;
|
return ProjectFile::Unclassified;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList filterFromFileName(const QStringList &flags, QString baseName)
|
QStringList filterFromFileName(const QStringList &flags, QString fileName)
|
||||||
{
|
{
|
||||||
baseName.append('.'); // to match name.c, name.o, etc.
|
|
||||||
QStringList result;
|
QStringList result;
|
||||||
result.reserve(flags.size());
|
result.reserve(flags.size());
|
||||||
for (const QString &flag : flags) {
|
bool skipNext = false;
|
||||||
if (!flag.contains(baseName))
|
for (int i = 0; i < flags.size(); ++i) {
|
||||||
result.push_back(flag);
|
const QString &flag = flags.at(i);
|
||||||
|
if (skipNext) {
|
||||||
|
skipNext = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (FilePath::fromUserInput(flag).fileName() == fileName)
|
||||||
|
continue;
|
||||||
|
if (flag == "-o" || flag.startsWith("/Fo")) {
|
||||||
|
skipNext = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.push_back(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ static QStringList jsonObjectFlags(const QJsonObject &object, QSet<QString> &fla
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FilePath jsonObjectFilename(const QJsonObject &object)
|
static FilePath jsonObjectFilePath(const QJsonObject &object)
|
||||||
{
|
{
|
||||||
const QString workingDir = QDir::cleanPath(object["directory"].toString());
|
const QString workingDir = QDir::cleanPath(object["directory"].toString());
|
||||||
FilePath fileName = FilePath::fromString(QDir::cleanPath(object["file"].toString()));
|
FilePath fileName = FilePath::fromString(QDir::cleanPath(object["file"].toString()));
|
||||||
@@ -204,10 +204,10 @@ std::vector<DbEntry> CompilationDbParser::readJsonObjects() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QJsonObject object = document.object();
|
const QJsonObject object = document.object();
|
||||||
const Utils::FilePath fileName = jsonObjectFilename(object);
|
const Utils::FilePath filePath = jsonObjectFilePath(object);
|
||||||
const QStringList flags = filterFromFileName(jsonObjectFlags(object, flagsCache),
|
const QStringList flags = filterFromFileName(jsonObjectFlags(object, flagsCache),
|
||||||
fileName.baseName());
|
filePath.fileName());
|
||||||
result.push_back({flags, fileName, object["directory"].toString()});
|
result.push_back({flags, filePath, object["directory"].toString()});
|
||||||
|
|
||||||
objectStart = m_projectFileContents.indexOf('{', objectEnd + 1);
|
objectStart = m_projectFileContents.indexOf('{', objectEnd + 1);
|
||||||
objectEnd = m_projectFileContents.indexOf('}', objectStart + 1);
|
objectEnd = m_projectFileContents.indexOf('}', objectStart + 1);
|
||||||
|
|||||||
@@ -485,10 +485,15 @@ void DocumentModelPrivate::removeAllSuspendedEntries(PinnedFileRemovalPolicy pin
|
|||||||
if (pinnedFileRemovalPolicy == DoNotRemovePinnedFiles && entry->pinned)
|
if (pinnedFileRemovalPolicy == DoNotRemovePinnedFiles && entry->pinned)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const FilePath fixedPath = DocumentManager::filePathKey(entry->fileName(),
|
||||||
|
DocumentManager::ResolveLinks);
|
||||||
int row = i + 1/*<no document>*/;
|
int row = i + 1/*<no document>*/;
|
||||||
d->beginRemoveRows(QModelIndex(), row, row);
|
d->beginRemoveRows(QModelIndex(), row, row);
|
||||||
delete d->m_entries.takeAt(i);
|
delete d->m_entries.takeAt(i);
|
||||||
d->endRemoveRows();
|
d->endRemoveRows();
|
||||||
|
|
||||||
|
if (!fixedPath.isEmpty())
|
||||||
|
d->m_entryByFixedPath.remove(fixedPath);
|
||||||
}
|
}
|
||||||
QSet<QString> displayNames;
|
QSet<QString> displayNames;
|
||||||
for (DocumentModel::Entry *entry : qAsConst(d->m_entries)) {
|
for (DocumentModel::Entry *entry : qAsConst(d->m_entries)) {
|
||||||
|
|||||||
@@ -263,6 +263,12 @@ public:
|
|||||||
void sendOpenNotification(const FilePath &filePath, const QString &mimeType,
|
void sendOpenNotification(const FilePath &filePath, const QString &mimeType,
|
||||||
const QString &content, int version);
|
const QString &content, int version);
|
||||||
void sendCloseNotification(const FilePath &filePath);
|
void sendCloseNotification(const FilePath &filePath);
|
||||||
|
void openRequiredShadowDocuments(const TextEditor::TextDocument *doc);
|
||||||
|
void closeRequiredShadowDocuments(const TextEditor::TextDocument *doc);
|
||||||
|
|
||||||
|
using ShadowDocIterator = QMap<FilePath, QPair<QString, QList<const TextEditor::TextDocument *>>>::iterator;
|
||||||
|
void openShadowDocument(const TextEditor::TextDocument *requringDoc, ShadowDocIterator shadowIt);
|
||||||
|
void closeShadowDocument(ShadowDocIterator docIt);
|
||||||
|
|
||||||
bool reset();
|
bool reset();
|
||||||
|
|
||||||
@@ -276,7 +282,9 @@ public:
|
|||||||
|
|
||||||
// Used for build system artifacts (e.g. UI headers) that Qt Creator "live-generates" ahead of
|
// Used for build system artifacts (e.g. UI headers) that Qt Creator "live-generates" ahead of
|
||||||
// the build.
|
// the build.
|
||||||
QMap<FilePath, QString> m_shadowDocuments;
|
// The Value is the file content + the documents that require the shadow file to be open
|
||||||
|
// (empty <=> shadow document is not open).
|
||||||
|
QMap<FilePath, QPair<QString, QList<const TextEditor::TextDocument *>>> m_shadowDocuments;
|
||||||
|
|
||||||
QSet<TextEditor::TextDocument *> m_postponedDocuments;
|
QSet<TextEditor::TextDocument *> m_postponedDocuments;
|
||||||
QMap<Utils::FilePath, int> m_documentVersions;
|
QMap<Utils::FilePath, int> m_documentVersions;
|
||||||
@@ -577,10 +585,12 @@ void Client::openDocument(TextEditor::TextDocument *document)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FilePath &filePath = document->filePath();
|
const FilePath &filePath = document->filePath();
|
||||||
if (d->m_shadowDocuments.contains(filePath)) {
|
const auto shadowIt = d->m_shadowDocuments.find(filePath);
|
||||||
d->sendCloseNotification(filePath);
|
if (shadowIt != d->m_shadowDocuments.end()) {
|
||||||
|
d->closeShadowDocument(shadowIt);
|
||||||
emit shadowDocumentSwitched(filePath);
|
emit shadowDocumentSwitched(filePath);
|
||||||
}
|
}
|
||||||
|
d->openRequiredShadowDocuments(document);
|
||||||
|
|
||||||
const QString method(DidOpenTextDocumentNotification::methodName);
|
const QString method(DidOpenTextDocumentNotification::methodName);
|
||||||
if (Utils::optional<bool> registered = d->m_dynamicCapabilities.isRegistered(method)) {
|
if (Utils::optional<bool> registered = d->m_dynamicCapabilities.isRegistered(method)) {
|
||||||
@@ -647,6 +657,7 @@ void Client::closeDocument(TextEditor::TextDocument *document)
|
|||||||
{
|
{
|
||||||
deactivateDocument(document);
|
deactivateDocument(document);
|
||||||
d->m_postponedDocuments.remove(document);
|
d->m_postponedDocuments.remove(document);
|
||||||
|
d->m_documentsToUpdate.erase(document);
|
||||||
if (d->m_openedDocument.remove(document) != 0) {
|
if (d->m_openedDocument.remove(document) != 0) {
|
||||||
handleDocumentClosed(document);
|
handleDocumentClosed(document);
|
||||||
if (d->m_state == Initialized)
|
if (d->m_state == Initialized)
|
||||||
@@ -655,12 +666,20 @@ void Client::closeDocument(TextEditor::TextDocument *document)
|
|||||||
|
|
||||||
if (d->m_state != Initialized)
|
if (d->m_state != Initialized)
|
||||||
return;
|
return;
|
||||||
const auto shadowIt = d->m_shadowDocuments.constFind(document->filePath());
|
d->closeRequiredShadowDocuments(document);
|
||||||
|
const auto shadowIt = d->m_shadowDocuments.find(document->filePath());
|
||||||
if (shadowIt == d->m_shadowDocuments.constEnd())
|
if (shadowIt == d->m_shadowDocuments.constEnd())
|
||||||
return;
|
return;
|
||||||
d->sendOpenNotification(document->filePath(), document->mimeType(), shadowIt.value(),
|
QTC_CHECK(shadowIt.value().second.isEmpty());
|
||||||
++d->m_documentVersions[document->filePath()]);
|
bool isReferenced = false;
|
||||||
emit shadowDocumentSwitched(document->filePath());
|
for (auto it = d->m_openedDocument.cbegin(); it != d->m_openedDocument.cend(); ++it) {
|
||||||
|
if (referencesShadowFile(it.key(), shadowIt.key())) {
|
||||||
|
d->openShadowDocument(it.key(), shadowIt);
|
||||||
|
isReferenced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isReferenced)
|
||||||
|
emit shadowDocumentSwitched(document->filePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPrivate::updateCompletionProvider(TextEditor::TextDocument *document)
|
void ClientPrivate::updateCompletionProvider(TextEditor::TextDocument *document)
|
||||||
@@ -870,6 +889,22 @@ void ClientPrivate::sendCloseNotification(const FilePath &filePath)
|
|||||||
Client::SendDocUpdates::Ignore);
|
Client::SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientPrivate::openRequiredShadowDocuments(const TextEditor::TextDocument *doc)
|
||||||
|
{
|
||||||
|
for (auto it = m_shadowDocuments.begin(); it != m_shadowDocuments.end(); ++it) {
|
||||||
|
if (!it.value().second.contains(doc) && q->referencesShadowFile(doc, it.key()))
|
||||||
|
openShadowDocument(doc, it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientPrivate::closeRequiredShadowDocuments(const TextEditor::TextDocument *doc)
|
||||||
|
{
|
||||||
|
for (auto it = m_shadowDocuments.begin(); it != m_shadowDocuments.end(); ++it) {
|
||||||
|
if (it.value().second.removeOne(doc) && it.value().second.isEmpty())
|
||||||
|
closeShadowDocument(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Client::documentOpen(const TextEditor::TextDocument *document) const
|
bool Client::documentOpen(const TextEditor::TextDocument *document) const
|
||||||
{
|
{
|
||||||
return d->m_openedDocument.contains(const_cast<TextEditor::TextDocument *>(document));
|
return d->m_openedDocument.contains(const_cast<TextEditor::TextDocument *>(document));
|
||||||
@@ -887,24 +922,25 @@ TextEditor::TextDocument *Client::documentForFilePath(const Utils::FilePath &fil
|
|||||||
void Client::setShadowDocument(const Utils::FilePath &filePath, const QString &content)
|
void Client::setShadowDocument(const Utils::FilePath &filePath, const QString &content)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(reachable(), return);
|
QTC_ASSERT(reachable(), return);
|
||||||
const auto it = d->m_shadowDocuments.find(filePath);
|
auto shadowIt = d->m_shadowDocuments.find(filePath);
|
||||||
const bool isNew = it == d->m_shadowDocuments.end();
|
if (shadowIt == d->m_shadowDocuments.end()) {
|
||||||
if (isNew)
|
shadowIt = d->m_shadowDocuments.insert(filePath, {content, {}});
|
||||||
d->m_shadowDocuments.insert(filePath, content);
|
} else {
|
||||||
else
|
shadowIt.value().first = content;
|
||||||
it.value() = content;
|
if (!shadowIt.value().second.isEmpty()) {
|
||||||
|
VersionedTextDocumentIdentifier docId(DocumentUri::fromFilePath(filePath));
|
||||||
|
docId.setVersion(++d->m_documentVersions[filePath]);
|
||||||
|
const DidChangeTextDocumentParams params(docId, content);
|
||||||
|
sendMessage(DidChangeTextDocumentNotification(params), SendDocUpdates::Ignore);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (documentForFilePath(filePath))
|
if (documentForFilePath(filePath))
|
||||||
return;
|
return;
|
||||||
const auto uri = DocumentUri::fromFilePath(filePath);
|
for (auto docIt = d->m_openedDocument.cbegin(); docIt != d->m_openedDocument.cend(); ++docIt) {
|
||||||
if (isNew) {
|
if (referencesShadowFile(docIt.key(), filePath))
|
||||||
const QString mimeType = mimeTypeForFile(filePath, MimeMatchMode::MatchExtension).name();
|
d->openShadowDocument(docIt.key(), shadowIt);
|
||||||
d->sendOpenNotification(filePath, mimeType, content, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VersionedTextDocumentIdentifier docId(uri);
|
|
||||||
docId.setVersion(++d->m_documentVersions[filePath]);
|
|
||||||
const DidChangeTextDocumentParams params(docId, content);
|
|
||||||
sendMessage(DidChangeTextDocumentNotification(params), SendDocUpdates::Ignore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::removeShadowDocument(const Utils::FilePath &filePath)
|
void Client::removeShadowDocument(const Utils::FilePath &filePath)
|
||||||
@@ -912,10 +948,27 @@ void Client::removeShadowDocument(const Utils::FilePath &filePath)
|
|||||||
const auto it = d->m_shadowDocuments.find(filePath);
|
const auto it = d->m_shadowDocuments.find(filePath);
|
||||||
if (it == d->m_shadowDocuments.end())
|
if (it == d->m_shadowDocuments.end())
|
||||||
return;
|
return;
|
||||||
|
if (!it.value().second.isEmpty())
|
||||||
|
d->closeShadowDocument(it);
|
||||||
d->m_shadowDocuments.erase(it);
|
d->m_shadowDocuments.erase(it);
|
||||||
if (documentForFilePath(filePath))
|
}
|
||||||
|
|
||||||
|
void ClientPrivate::openShadowDocument(const TextEditor::TextDocument *requringDoc,
|
||||||
|
ShadowDocIterator shadowIt)
|
||||||
|
{
|
||||||
|
shadowIt.value().second << requringDoc;
|
||||||
|
if (shadowIt.value().second.size() > 1)
|
||||||
return;
|
return;
|
||||||
d->sendCloseNotification(filePath);
|
const auto uri = DocumentUri::fromFilePath(shadowIt.key());
|
||||||
|
const QString mimeType = mimeTypeForFile(shadowIt.key(), MimeMatchMode::MatchExtension).name();
|
||||||
|
sendOpenNotification(shadowIt.key(), mimeType, shadowIt.value().first,
|
||||||
|
++m_documentVersions[shadowIt.key()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientPrivate::closeShadowDocument(ShadowDocIterator shadowIt)
|
||||||
|
{
|
||||||
|
sendCloseNotification(shadowIt.key());
|
||||||
|
shadowIt.value().second.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::documentContentsSaved(TextEditor::TextDocument *document)
|
void Client::documentContentsSaved(TextEditor::TextDocument *document)
|
||||||
@@ -947,6 +1000,7 @@ void Client::documentContentsSaved(TextEditor::TextDocument *document)
|
|||||||
return;
|
return;
|
||||||
DidSaveTextDocumentParams params(
|
DidSaveTextDocumentParams params(
|
||||||
TextDocumentIdentifier(DocumentUri::fromFilePath(document->filePath())));
|
TextDocumentIdentifier(DocumentUri::fromFilePath(document->filePath())));
|
||||||
|
d->openRequiredShadowDocuments(document);
|
||||||
if (includeText)
|
if (includeText)
|
||||||
params.setText(document->plainText());
|
params.setText(document->plainText());
|
||||||
sendMessage(DidSaveTextDocumentNotification(params), SendDocUpdates::Send, Schedule::Now);
|
sendMessage(DidSaveTextDocumentNotification(params), SendDocUpdates::Send, Schedule::Now);
|
||||||
@@ -1970,6 +2024,14 @@ QTextCursor Client::adjustedCursorForHighlighting(const QTextCursor &cursor,
|
|||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::referencesShadowFile(const TextEditor::TextDocument *doc,
|
||||||
|
const Utils::FilePath &candidate)
|
||||||
|
{
|
||||||
|
Q_UNUSED(doc)
|
||||||
|
Q_UNUSED(candidate)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace LanguageClient
|
} // namespace LanguageClient
|
||||||
|
|
||||||
#include <client.moc>
|
#include <client.moc>
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ private:
|
|||||||
virtual void handleDocumentOpened(TextEditor::TextDocument *) {}
|
virtual void handleDocumentOpened(TextEditor::TextDocument *) {}
|
||||||
virtual QTextCursor adjustedCursorForHighlighting(const QTextCursor &cursor,
|
virtual QTextCursor adjustedCursorForHighlighting(const QTextCursor &cursor,
|
||||||
TextEditor::TextDocument *doc);
|
TextEditor::TextDocument *doc);
|
||||||
|
virtual bool referencesShadowFile(const TextEditor::TextDocument *doc,
|
||||||
|
const Utils::FilePath &candidate);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LanguageClient
|
} // namespace LanguageClient
|
||||||
|
|||||||
@@ -138,6 +138,8 @@ bool MaterialBrowserView::isMaterial(const ModelNode &node) const
|
|||||||
|
|
||||||
void MaterialBrowserView::modelAboutToBeDetached(Model *model)
|
void MaterialBrowserView::modelAboutToBeDetached(Model *model)
|
||||||
{
|
{
|
||||||
|
m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport);
|
||||||
|
|
||||||
AbstractView::modelAboutToBeDetached(model);
|
AbstractView::modelAboutToBeDetached(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,16 +50,7 @@ TimelineForm::TimelineForm(QWidget *parent)
|
|||||||
connect(ui->expressionBindingLineEdit, &QLineEdit::editingFinished, [this]() {
|
connect(ui->expressionBindingLineEdit, &QLineEdit::editingFinished, [this]() {
|
||||||
QTC_ASSERT(m_timeline.isValid(), return );
|
QTC_ASSERT(m_timeline.isValid(), return );
|
||||||
|
|
||||||
|
|
||||||
static QString lastString;
|
|
||||||
|
|
||||||
const QString bindingText = ui->expressionBindingLineEdit->text();
|
const QString bindingText = ui->expressionBindingLineEdit->text();
|
||||||
|
|
||||||
if (bindingText == lastString)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lastString = bindingText;
|
|
||||||
|
|
||||||
if (bindingText.isEmpty()) {
|
if (bindingText.isEmpty()) {
|
||||||
ui->animation->setChecked(true);
|
ui->animation->setChecked(true);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -6121,6 +6121,29 @@ void tst_Dumpers::dumper_data()
|
|||||||
+ Check("watch.1.12", "s.front", "13", "unsigned int") % GdbEngine;
|
+ Check("watch.1.12", "s.front", "13", "unsigned int") % GdbEngine;
|
||||||
|
|
||||||
|
|
||||||
|
QTest::newRow("Bitfield2")
|
||||||
|
<< Data("#include <QList>\n\n"
|
||||||
|
"struct Entry\n"
|
||||||
|
"{\n"
|
||||||
|
" Entry(bool x) : enabled(x) {}\n"
|
||||||
|
" bool enabled : 1;\n"
|
||||||
|
" bool autorepeat : 1;\n"
|
||||||
|
" signed int id;\n"
|
||||||
|
"};\n",
|
||||||
|
|
||||||
|
"QList<Entry> list;\n"
|
||||||
|
"list.append(Entry(true));\n"
|
||||||
|
"list.append(Entry(false));\n",
|
||||||
|
|
||||||
|
"&list")
|
||||||
|
|
||||||
|
+ CoreProfile()
|
||||||
|
+ Check("list.0.enabled", "1", "bool : 1") % NoCdbEngine
|
||||||
|
+ Check("list.0.enabled", "1", "bool") % CdbEngine
|
||||||
|
+ Check("list.1.enabled", "0", "bool : 1") % NoCdbEngine
|
||||||
|
+ Check("list.1.enabled", "0", "bool") % CdbEngine;
|
||||||
|
|
||||||
|
|
||||||
QTest::newRow("Function")
|
QTest::newRow("Function")
|
||||||
<< Data("#include <QByteArray>\n"
|
<< Data("#include <QByteArray>\n"
|
||||||
"struct Function\n"
|
"struct Function\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user