From 80415bd14ed472733929a38e3fce054bd4a5eab9 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Tue, 19 Sep 2017 11:10:32 +0200 Subject: [PATCH 1/5] Revert "SearchResultWidget: Disable replace button if replace text is unchanged" The Refactor -> Convert to Camel Case quickfix calls setReplacementText() with the replacement text already, in contrast to the other search and refactoring functions, which pass the search text. Therefore, the replace button is disabled wrongly in that case. This reverts commit e75f5958737f3a302508d3e72aed4e4672a43557. Task-number: QTCREATORBUG-18947 Change-Id: I906a58f65a88cce42d2da6431e59b88fae4ec45a Reviewed-by: Eike Ziller --- .../coreplugin/find/searchresultwidget.cpp | 15 ++------------- src/plugins/coreplugin/find/searchresultwidget.h | 2 -- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/plugins/coreplugin/find/searchresultwidget.cpp b/src/plugins/coreplugin/find/searchresultwidget.cpp index 3db6a08f26a..9eee8dee632 100644 --- a/src/plugins/coreplugin/find/searchresultwidget.cpp +++ b/src/plugins/coreplugin/find/searchresultwidget.cpp @@ -210,8 +210,6 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) : this, &SearchResultWidget::handleReplaceButton); connect(m_replaceButton, &QAbstractButton::clicked, this, &SearchResultWidget::handleReplaceButton); - connect(m_replaceTextEdit, &QLineEdit::textChanged, - this, &SearchResultWidget::handleReplaceEditTextChanged); } SearchResultWidget::~SearchResultWidget() @@ -306,7 +304,6 @@ void SearchResultWidget::setSupportsReplace(bool replaceSupported, const QString void SearchResultWidget::setTextToReplace(const QString &textToReplace) { - m_replaceText = textToReplace; m_replaceTextEdit->setText(textToReplace); } @@ -409,6 +406,7 @@ void SearchResultWidget::goToPrevious() void SearchResultWidget::restart() { m_replaceTextEdit->setEnabled(false); + m_replaceButton->setEnabled(false); m_searchResultTreeView->clear(); m_count = 0; Id sizeWarningId(SIZE_WARNING_ID); @@ -418,7 +416,6 @@ void SearchResultWidget::restart() m_searchAgainButton->setVisible(false); m_messageWidget->setVisible(false); updateMatchesFoundLabel(); - handleReplaceEditTextChanged(); emit restarted(); } @@ -439,6 +436,7 @@ void SearchResultWidget::finishSearch(bool canceled) m_infoBar.removeInfo(sizeWarningId); m_infoBar.enableInfo(sizeWarningId); m_replaceTextEdit->setEnabled(m_count > 0); + m_replaceButton->setEnabled(m_count > 0); m_preserveCaseCheck->setEnabled(m_count > 0); m_cancelButton->setVisible(false); m_messageWidget->setVisible(canceled); @@ -463,15 +461,6 @@ void SearchResultWidget::cancelAfterSizeWarning() emit paused(false); } -void SearchResultWidget::handleReplaceEditTextChanged() -{ - const bool enabled = m_replaceTextEdit->text() != m_replaceText; - m_replaceButton->setEnabled(enabled); - m_replaceButton->setToolTip(enabled - ? QString() - : tr("Cannot replace because replacement text is unchanged.")); -} - void SearchResultWidget::handleJumpToSearchResult(const SearchResultItem &item) { emit activated(item); diff --git a/src/plugins/coreplugin/find/searchresultwidget.h b/src/plugins/coreplugin/find/searchresultwidget.h index bf4b9055440..5309ed69e1e 100644 --- a/src/plugins/coreplugin/find/searchresultwidget.h +++ b/src/plugins/coreplugin/find/searchresultwidget.h @@ -115,7 +115,6 @@ private: void setShowReplaceUI(bool visible); void continueAfterSizeWarning(); void cancelAfterSizeWarning(); - void handleReplaceEditTextChanged(); QList checkedItems() const; void updateMatchesFoundLabel(); @@ -142,7 +141,6 @@ private: bool m_isShowingReplaceUI = false; bool m_searchAgainSupported = false; bool m_replaceSupported = false; - QString m_replaceText; }; } // Internal From a627f4eef73fa80abc91863fbebd8ce28e73bfb4 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 17 Sep 2017 17:16:12 +0300 Subject: [PATCH 2/5] Dumpers: Print readable output in tests Change-Id: I32864c9c1b8fe60b5b01423f68e63a3c00b936f8 Reviewed-by: hjk --- tests/auto/debugger/tst_dumpers.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 91af07f8f13..a7a9d7b9317 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1035,7 +1035,7 @@ void tst_Dumpers::initTestCase() ok = debugger.waitForFinished(); QVERIFY(ok); QByteArray output = debugger.readAllStandardOutput(); - //qDebug() << "stdout: " << output; + //qDebug().noquote() << "stdout: " << output; bool usePython = !output.contains("Python scripting is not supported in this copy of GDB"); qDebug() << "Python : " << (usePython ? "ok" : "*** not ok ***"); qDebug() << "Dumper dir : " << DUMPERDIR; @@ -1404,11 +1404,11 @@ void tst_Dumpers::dumper() error = make.readAllStandardError(); //qDebug() << "stdout: " << output; if (make.exitCode()) { - qDebug() << error; + qDebug().noquote() << error; qDebug() << "\n------------------ CODE --------------------"; - qDebug() << fullCode; + qDebug().noquote() << fullCode; qDebug() << "\n------------------ CODE --------------------"; - qDebug() << "Project file: " << proFile.fileName(); + qDebug().noquote() << "Project file: " << proFile.fileName(); } if (data.neededDwarfVersion.isRestricted) { @@ -1574,7 +1574,7 @@ void tst_Dumpers::dumper() if (m_debuggerEngine == GdbEngine) { int posDataStart = output.indexOf("data="); if (posDataStart == -1) { - qDebug() << "NO \"data=\" IN OUTPUT: " << output; + qDebug().noquote() << "NO \"data=\" IN OUTPUT: " << output; QVERIFY(posDataStart != -1); } contents = output.mid(posDataStart); @@ -1586,7 +1586,7 @@ void tst_Dumpers::dumper() //qDebug() << "FOUND NS: " << context.nameSpace; } else if (m_debuggerEngine == LldbEngine) { - //qDebug() << "GOT OUTPUT: " << output; + //qDebug().noquote() << "GOT OUTPUT: " << output; int pos = output.indexOf("data=[{"); QVERIFY(pos != -1); output = output.mid(pos); @@ -1594,7 +1594,7 @@ void tst_Dumpers::dumper() int posNameSpaceStart = output.indexOf("@NS@"); if (posNameSpaceStart == -1) - qDebug() << "OUTPUT: " << output; + qDebug().noquote() << "OUTPUT: " << output; QVERIFY(posNameSpaceStart != -1); posNameSpaceStart += sizeof("@NS@") - 1; int posNameSpaceEnd = output.indexOf("@", posNameSpaceStart); @@ -1610,7 +1610,7 @@ void tst_Dumpers::dumper() QByteArray locals("|script|"); int localsBeginPos = output.indexOf(locals, output.indexOf(localsAnswerStart)); if (localsBeginPos == -1) - qDebug() << "OUTPUT: " << output; + qDebug().noquote() << "OUTPUT: " << output; QVERIFY(localsBeginPos != -1); do { const int msgStart = localsBeginPos + locals.length(); @@ -1741,8 +1741,8 @@ void tst_Dumpers::dumper() break; qDebug() << "MSG: " << fullOutput.mid(pos1, pos2 - pos1 - 1); } - qDebug() << "CONTENTS : " << contents; - qDebug() << "FULL OUTPUT : " << fullOutput.data(); + qDebug().noquote() << "CONTENTS : " << contents; + qDebug().noquote() << "FULL OUTPUT : " << fullOutput.data(); qDebug() << "Qt VERSION : " << QString::number(context.qtVersion, 16); if (m_debuggerEngine != CdbEngine) qDebug() << "GCC VERSION : " << context.gccVersion; From 0bf27af0a718887248229b9693de16f150a38bf3 Mon Sep 17 00:00:00 2001 From: Serhii Moroz Date: Fri, 18 Aug 2017 18:58:51 +0300 Subject: [PATCH 3/5] TextEditor: Fix blockSelection painting in "Text Wrapping" mode Change-Id: I1ba4587ce4f8e88a1c81c5ac3c9d6dac582bd71f Reviewed-by: Christian Stenger Reviewed-by: Eike Ziller --- src/plugins/texteditor/texteditor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 06f02615eba..f237c0f7ed8 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -4298,7 +4298,6 @@ void TextEditorWidget::paintEvent(QPaintEvent *e) for (int i = line.lineNumber() + 1; i < eline.lineNumber(); ++i) { rr = layout->lineAt(i).naturalTextRect(); rr.moveTop(rr.top() + r.top()); - rr.setLeft(r.left() + x); painter.fillRect(rr, palette().highlight()); } From 76006a1353f1282a940bf80a523b93ead7beae93 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 19 Sep 2017 14:36:21 +0200 Subject: [PATCH 4/5] C++: Fix crash with invalid raw string literal While parsing a document Bind::asStringLiteral() Token::spell() was called for a raw string literal token with a Token::literal nullptr. This is due scanRawStringLiteral() not properly aborting for invalid/incomplete code and that the code paths handling multi-line-raw-strings were not limited to the highlighting case. Address both cases. Task-number: QTCREATORBUG-18941 Change-Id: I489d288ccbd7b59be396dada846613ff555436cf Reviewed-by: Eike Ziller Reviewed-by: Orgad Shaneh --- src/libs/3rdparty/cplusplus/Lexer.cpp | 16 ++++++++++------ tests/auto/cplusplus/lexer/tst_lexer.cpp | 8 ++++++++ tests/auto/cplusplus/misc/tst_misc.cpp | 13 +++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp index e62c9412a4e..079ae0ca6e6 100644 --- a/src/libs/3rdparty/cplusplus/Lexer.cpp +++ b/src/libs/3rdparty/cplusplus/Lexer.cpp @@ -211,7 +211,7 @@ void Lexer::scan_helper(Token *tok) _state = 0; scanCppComment(originalKind); return; - } else if (isRawStringLiteral(s._tokenKind)) { + } else if (!control() && isRawStringLiteral(s._tokenKind)) { tok->f.kind = s._tokenKind; if (scanUntilRawStringLiteralEndSimple()) _state = 0; @@ -755,13 +755,17 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint) yyinp(); } else if (_yychar == ')') { yyinp(); - if (delimLength == -1) - break; + if (delimLength == -1) { + tok->f.kind = T_ERROR; + return; + } closingDelimCandidate = _currentChar; } else { if (delimLength == -1) { - if (_yychar == '\\' || std::isspace(_yychar)) - break; + if (_yychar == '\\' || std::isspace(_yychar)) { + tok->f.kind = T_ERROR; + return; + } yyinp(); } else { if (!closingDelimCandidate) { @@ -804,7 +808,7 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint) else tok->f.kind = T_RAW_STRING_LITERAL; - if (!closed) + if (!control() && !closed) s._tokenKind = tok->f.kind; } diff --git a/tests/auto/cplusplus/lexer/tst_lexer.cpp b/tests/auto/cplusplus/lexer/tst_lexer.cpp index a2c415d33c2..1721efaedd6 100644 --- a/tests/auto/cplusplus/lexer/tst_lexer.cpp +++ b/tests/auto/cplusplus/lexer/tst_lexer.cpp @@ -366,6 +366,14 @@ void tst_SimpleLexer::literals_data() << T_RAW_STRING_LITERAL ; QTest::newRow("raw-string-literals") << source << expectedTokenKindList; + + source = "R\"\\" ; + expectedTokenKindList = TokenKindList() << T_ERROR; + QTest::newRow("invalid-raw-string-literals1") << source << expectedTokenKindList; + + source = "R\")" ; + expectedTokenKindList = TokenKindList() << T_ERROR; + QTest::newRow("invalid-raw-string-literals2") << source << expectedTokenKindList; } void tst_SimpleLexer::preprocessor() diff --git a/tests/auto/cplusplus/misc/tst_misc.cpp b/tests/auto/cplusplus/misc/tst_misc.cpp index aff5a12ce0b..808408df407 100644 --- a/tests/auto/cplusplus/misc/tst_misc.cpp +++ b/tests/auto/cplusplus/misc/tst_misc.cpp @@ -48,6 +48,8 @@ private slots: void astPathOnGeneratedTokens(); void typeMatcher(); + + void doNotCrashForInvalidRawString(); }; void tst_Misc::diagnosticClient_error() @@ -266,5 +268,16 @@ void tst_Misc::typeMatcher() } } +void tst_Misc::doNotCrashForInvalidRawString() +{ + const QByteArray src("\n" + "void f() { enum { Size = sizeof(R\"[^\\s]+([^]+)*\") }; }" + "}\n" + ); + Document::Ptr doc = Document::create("crash"); + doc->setUtf8Source(src); + doc->check(); +} + QTEST_MAIN(tst_Misc) #include "tst_misc.moc" From 846d89811a72f96909ad137fb973983f568c3643 Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Tue, 19 Sep 2017 12:37:56 +0200 Subject: [PATCH 5/5] Fix unstoppable debugger For some reason sometimes a user stop request with lldb can trigger a spontaneous stop, avoiding the debugger to stop correctly. This change fix the issue by emitting the correct states from lldbbridge.py. Change-Id: Ib8a2f4875824f4fff426b2d5e0fc4a79ce48c68e Reviewed-by: hjk --- share/qtcreator/debugger/lldbbridge.py | 6 ++---- src/plugins/debugger/lldb/lldbengine.cpp | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 9c85907f9a9..968572bb4d3 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1240,9 +1240,7 @@ class Dumper(DumperBase): if not skipEventReporting: self.eventState = state if state == lldb.eStateExited: - if self.isShuttingDown_: - self.reportState("inferiorshutdownok") - else: + if not self.isShuttingDown_: self.reportState("inferiorexited") self.report('exited={status="%s",desc="%s"}' % (self.process.GetExitStatus(), self.process.GetExitDescription())) @@ -1272,7 +1270,7 @@ class Dumper(DumperBase): return if self.isInterrupting_: self.isInterrupting_ = False - self.reportState("stopped") + self.reportState("inferiorstopok") elif self.ignoreStops > 0: self.ignoreStops -= 1 self.process.Continue() diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index a844d982481..256f3ce4eeb 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -910,6 +910,8 @@ void LldbEngine::handleStateNotification(const GdbMi &reportedState) } } else if (newState == "inferiorstopok") { notifyInferiorStopOk(); + if (!isDying()) + updateAll(); } else if (newState == "inferiorstopfailed") notifyInferiorStopFailed(); else if (newState == "inferiorill")