Merge remote-tracking branch 'origin/8.0'

Change-Id: Iea4fd2949f5d5345802e2e7d9283d72c6c55f69f
This commit is contained in:
hjk
2022-08-03 10:52:13 +02:00
16 changed files with 180 additions and 65 deletions

View File

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

View File

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

View File

@@ -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 &macro) bool isQuickTestMacro(const QByteArray &macro)
{ {
static const QByteArrayList valid = {"QUICK_TEST_MAIN", "QUICK_TEST_OPENGL_MAIN",
"QUICK_TEST_MAIN_WITH_SETUP"};
return valid.contains(macro); return valid.contains(macro);
} }

View File

@@ -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 &macro : macros) { for (const CPlusPlus::Document::MacroUse &macro : 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())

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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