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)
if self.type.code in (TypeCode.Reference, TypeCode.RValueReference):
return self.dereference().extractField(field)
#DumperBase.warn('FIELD: %s ' % field)
#DumperBase.warn('FIELD: %s ' % (field,))
val = self.dumper.Value(self.dumper)
val.name = field.name
val.isBaseClass = field.isBase
@@ -3227,10 +3227,7 @@ class DumperBase():
lbyte = ldata[i]
else:
lbyte = ldata[fieldOffset + fieldSize - 1 - i]
if sys.version_info[0] >= 3:
data += lbyte
else:
data += ord(lbyte)
data += ord(lbyte)
data = data >> fieldBitpos
data = data & ((1 << fieldBitsize) - 1)
val.lvalue = data

View File

@@ -652,6 +652,13 @@ def qdump__QKeyEvent(d, value):
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):
# 9fc0965 and a373ffcd change the layout of the private structure
qtVersion = d.qtVersion()

View File

@@ -35,11 +35,10 @@ namespace Autotest {
namespace Internal {
namespace QuickTestUtils {
static const QByteArrayList valid = {"QUICK_TEST_MAIN", "QUICK_TEST_OPENGL_MAIN",
"QUICK_TEST_MAIN_WITH_SETUP"};
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);
}

View File

@@ -126,7 +126,7 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
const Utils::FilePath filePath = Utils::FilePath::fromString(doc->fileName());
for (const CPlusPlus::Document::MacroUse &macro : macros) {
if (!macro.isFunctionLike())
if (!macro.isFunctionLike() || macro.arguments().isEmpty())
continue;
const QByteArray name = macro.macro().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
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath);
if (document.isNull())

View File

@@ -651,6 +651,14 @@ DiagnosticManager *ClangdClient::createDiagnosticManager()
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
{
return new CppEditor::CppRefactoringChangesData(

View File

@@ -145,6 +145,8 @@ private:
const CustomInspectorTabs createCustomInspectorTabs() override;
TextEditor::RefactoringChangesData *createRefactoringChangesBackend() const override;
LanguageClient::DiagnosticManager *createDiagnosticManager() override;
bool referencesShadowFile(const TextEditor::TextDocument *doc,
const Utils::FilePath &candidate) override;
class Private;
class VirtualFunctionAssistProcessor;

View File

@@ -418,16 +418,18 @@ void ClangModelManagerSupport::updateLanguageClient(
bool hasDocuments = false;
const ClangdSettings settings(ClangdProjectSettings(project).settings());
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
const Client * const currentClient = LanguageClientManager::clientForDocument(doc);
Client * const currentClient = LanguageClientManager::clientForDocument(doc);
if (!settings.sizeIsOkay(doc->filePath()))
continue;
const Project * const docProject = SessionManager::projectForFile(doc->filePath());
if (currentClient && currentClient->project()
&& currentClient->project() != project) {
&& currentClient->project() != project
&& currentClient->project() == docProject) {
continue;
}
if (const Project * const docProject
= SessionManager::projectForFile(doc->filePath());
!docProject || docProject == project) {
if (!docProject || docProject == project) {
if (currentClient)
currentClient->closeDocument(doc);
LanguageClientManager::openDocumentWithClient(doc, client);
hasDocuments = true;
}
@@ -532,15 +534,18 @@ void ClangModelManagerSupport::claimNonProjectSources(ClangdClient *client)
if (!client)
return;
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
if (Client * const currentClient = LanguageClientManager::clientForDocument(doc);
currentClient && currentClient->state() == Client::Initialized
Client * const currentClient = LanguageClientManager::clientForDocument(doc);
if (currentClient && currentClient->state() == Client::Initialized
&& (currentClient == client || currentClient->project())) {
continue;
}
if (!ClangdSettings::instance().sizeIsOkay(doc->filePath()))
continue;
if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath()))
if (!ProjectExplorer::SessionManager::projectForFile(doc->filePath())) {
if (currentClient)
currentClient->closeDocument(doc);
LanguageClientManager::openDocumentWithClient(doc, client);
}
}
}

View File

@@ -136,7 +136,7 @@ void CompilationDatabaseTests::testFilterEmptyFlags()
void CompilationDatabaseTests::testFilterFromFilename()
{
QCOMPARE(filterFromFileName(QStringList{"-o", "foo.o"}, "foo"), QStringList{"-o"});
QCOMPARE(filterFromFileName(QStringList{"-o", "foo.o"}, "foo.c"), QStringList());
}
void CompilationDatabaseTests::testFilterArguments()
@@ -169,8 +169,10 @@ void CompilationDatabaseTests::testFilterArguments()
"c++",
QString("--sysroot=") + (HostOsInfo::isWindowsHost()
? "C:\\sysroot\\embedded" : "/opt/sysroot/embedded"),
"C:\\qt-creator\\src\\plugins\\cpptools\\compileroptionsbuilder.cpp"},
"compileroptionsbuilder");
QLatin1String(HostOsInfo::isWindowsHost()
? "C:\\qt-creator\\src\\plugins\\cpptools\\compileroptionsbuilder.cpp"
: "/opt/qt-creator/src/plugins/cpptools/compileroptionsbuilder.cpp")},
"compileroptionsbuilder.cpp");
testData.getFilteredFlags();
@@ -241,7 +243,7 @@ void CompilationDatabaseTests::testFilterCommand()
testData.fileName = "SemaCodeComplete.cpp";
testData.workingDir = "C:/build-qt_llvm-msvc2017_64bit-Debug";
testData.flags = filterFromFileName(testData.getSplitCommandLine(kCmakeCommand),
"SemaCodeComplete");
"SemaCodeComplete.cpp");
testData.getFilteredFlags();
if (Utils::HostOsInfo::isWindowsHost()) {
@@ -278,7 +280,7 @@ void CompilationDatabaseTests::testFileKindDifferentFromExtension2()
void CompilationDatabaseTests::testSkipOutputFiles()
{
CompilationDatabaseUtilsTestData testData;
testData.flags = filterFromFileName(QStringList{"-o", "foo.o"}, "foo");
testData.flags = filterFromFileName(QStringList{"-o", "foo.o"}, "foo.cpp");
QVERIFY(testData.getFilteredFlags().isEmpty());
}

View File

@@ -84,14 +84,24 @@ static CppEditor::ProjectFile::Kind fileKindFromString(QString flag)
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;
result.reserve(flags.size());
for (const QString &flag : flags) {
if (!flag.contains(baseName))
result.push_back(flag);
bool skipNext = false;
for (int i = 0; i < flags.size(); ++i) {
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;

View File

@@ -177,7 +177,7 @@ static QStringList jsonObjectFlags(const QJsonObject &object, QSet<QString> &fla
return flags;
}
static FilePath jsonObjectFilename(const QJsonObject &object)
static FilePath jsonObjectFilePath(const QJsonObject &object)
{
const QString workingDir = QDir::cleanPath(object["directory"].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 Utils::FilePath fileName = jsonObjectFilename(object);
const Utils::FilePath filePath = jsonObjectFilePath(object);
const QStringList flags = filterFromFileName(jsonObjectFlags(object, flagsCache),
fileName.baseName());
result.push_back({flags, fileName, object["directory"].toString()});
filePath.fileName());
result.push_back({flags, filePath, object["directory"].toString()});
objectStart = m_projectFileContents.indexOf('{', objectEnd + 1);
objectEnd = m_projectFileContents.indexOf('}', objectStart + 1);

View File

@@ -485,10 +485,15 @@ void DocumentModelPrivate::removeAllSuspendedEntries(PinnedFileRemovalPolicy pin
if (pinnedFileRemovalPolicy == DoNotRemovePinnedFiles && entry->pinned)
continue;
const FilePath fixedPath = DocumentManager::filePathKey(entry->fileName(),
DocumentManager::ResolveLinks);
int row = i + 1/*<no document>*/;
d->beginRemoveRows(QModelIndex(), row, row);
delete d->m_entries.takeAt(i);
d->endRemoveRows();
if (!fixedPath.isEmpty())
d->m_entryByFixedPath.remove(fixedPath);
}
QSet<QString> displayNames;
for (DocumentModel::Entry *entry : qAsConst(d->m_entries)) {

View File

@@ -263,6 +263,12 @@ public:
void sendOpenNotification(const FilePath &filePath, const QString &mimeType,
const QString &content, int version);
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();
@@ -276,7 +282,9 @@ public:
// Used for build system artifacts (e.g. UI headers) that Qt Creator "live-generates" ahead of
// 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;
QMap<Utils::FilePath, int> m_documentVersions;
@@ -577,10 +585,12 @@ void Client::openDocument(TextEditor::TextDocument *document)
}
const FilePath &filePath = document->filePath();
if (d->m_shadowDocuments.contains(filePath)) {
d->sendCloseNotification(filePath);
const auto shadowIt = d->m_shadowDocuments.find(filePath);
if (shadowIt != d->m_shadowDocuments.end()) {
d->closeShadowDocument(shadowIt);
emit shadowDocumentSwitched(filePath);
}
d->openRequiredShadowDocuments(document);
const QString method(DidOpenTextDocumentNotification::methodName);
if (Utils::optional<bool> registered = d->m_dynamicCapabilities.isRegistered(method)) {
@@ -647,6 +657,7 @@ void Client::closeDocument(TextEditor::TextDocument *document)
{
deactivateDocument(document);
d->m_postponedDocuments.remove(document);
d->m_documentsToUpdate.erase(document);
if (d->m_openedDocument.remove(document) != 0) {
handleDocumentClosed(document);
if (d->m_state == Initialized)
@@ -655,12 +666,20 @@ void Client::closeDocument(TextEditor::TextDocument *document)
if (d->m_state != Initialized)
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())
return;
d->sendOpenNotification(document->filePath(), document->mimeType(), shadowIt.value(),
++d->m_documentVersions[document->filePath()]);
emit shadowDocumentSwitched(document->filePath());
QTC_CHECK(shadowIt.value().second.isEmpty());
bool isReferenced = false;
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)
@@ -870,6 +889,22 @@ void ClientPrivate::sendCloseNotification(const FilePath &filePath)
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
{
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)
{
QTC_ASSERT(reachable(), return);
const auto it = d->m_shadowDocuments.find(filePath);
const bool isNew = it == d->m_shadowDocuments.end();
if (isNew)
d->m_shadowDocuments.insert(filePath, content);
else
it.value() = content;
auto shadowIt = d->m_shadowDocuments.find(filePath);
if (shadowIt == d->m_shadowDocuments.end()) {
shadowIt = d->m_shadowDocuments.insert(filePath, {content, {}});
} else {
shadowIt.value().first = 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))
return;
const auto uri = DocumentUri::fromFilePath(filePath);
if (isNew) {
const QString mimeType = mimeTypeForFile(filePath, MimeMatchMode::MatchExtension).name();
d->sendOpenNotification(filePath, mimeType, content, 0);
for (auto docIt = d->m_openedDocument.cbegin(); docIt != d->m_openedDocument.cend(); ++docIt) {
if (referencesShadowFile(docIt.key(), filePath))
d->openShadowDocument(docIt.key(), shadowIt);
}
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)
@@ -912,10 +948,27 @@ void Client::removeShadowDocument(const Utils::FilePath &filePath)
const auto it = d->m_shadowDocuments.find(filePath);
if (it == d->m_shadowDocuments.end())
return;
if (!it.value().second.isEmpty())
d->closeShadowDocument(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;
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)
@@ -947,6 +1000,7 @@ void Client::documentContentsSaved(TextEditor::TextDocument *document)
return;
DidSaveTextDocumentParams params(
TextDocumentIdentifier(DocumentUri::fromFilePath(document->filePath())));
d->openRequiredShadowDocuments(document);
if (includeText)
params.setText(document->plainText());
sendMessage(DidSaveTextDocumentNotification(params), SendDocUpdates::Send, Schedule::Now);
@@ -1970,6 +2024,14 @@ QTextCursor Client::adjustedCursorForHighlighting(const QTextCursor &cursor,
return cursor;
}
bool Client::referencesShadowFile(const TextEditor::TextDocument *doc,
const Utils::FilePath &candidate)
{
Q_UNUSED(doc)
Q_UNUSED(candidate)
return false;
}
} // namespace LanguageClient
#include <client.moc>

View File

@@ -226,6 +226,8 @@ private:
virtual void handleDocumentOpened(TextEditor::TextDocument *) {}
virtual QTextCursor adjustedCursorForHighlighting(const QTextCursor &cursor,
TextEditor::TextDocument *doc);
virtual bool referencesShadowFile(const TextEditor::TextDocument *doc,
const Utils::FilePath &candidate);
};
} // namespace LanguageClient

View File

@@ -138,6 +138,8 @@ bool MaterialBrowserView::isMaterial(const ModelNode &node) const
void MaterialBrowserView::modelAboutToBeDetached(Model *model)
{
m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport);
AbstractView::modelAboutToBeDetached(model);
}

View File

@@ -50,16 +50,7 @@ TimelineForm::TimelineForm(QWidget *parent)
connect(ui->expressionBindingLineEdit, &QLineEdit::editingFinished, [this]() {
QTC_ASSERT(m_timeline.isValid(), return );
static QString lastString;
const QString bindingText = ui->expressionBindingLineEdit->text();
if (bindingText == lastString)
return;
lastString = bindingText;
if (bindingText.isEmpty()) {
ui->animation->setChecked(true);
try {

View File

@@ -6121,6 +6121,29 @@ void tst_Dumpers::dumper_data()
+ 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")
<< Data("#include <QByteArray>\n"
"struct Function\n"