diff options
author | Eike Ziller <eike.ziller@theqtcompany.com> | 2015-08-20 13:23:06 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@theqtcompany.com> | 2015-08-20 13:23:13 +0200 |
commit | 8eaaef96aa55c10f00b429c3e6ade8d8be568141 (patch) | |
tree | 33ff4239b1523d5f145d0ec5681716859f276e4c | |
parent | 2f781ac28083bc06b549ce69335b4c7901cde61d (diff) | |
parent | 0173c638537e9a53a439ec4be5a9ab7b10a27a79 (diff) | |
download | qt-creator-8eaaef96aa55c10f00b429c3e6ade8d8be568141.tar.gz |
Merge remote-tracking branch 'origin/3.5'
Change-Id: I65968dd02ea6bdd15f304ae567dd0c02238e6949
51 files changed, 340 insertions, 165 deletions
diff --git a/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/package.xml.in b/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/package.xml.in index 682fd720b9..32089ef2bb 100644 --- a/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/package.xml.in +++ b/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/package.xml.in @@ -17,4 +17,5 @@ <UserInterface>associatecommonfiletypesform.ui</UserInterface> <UserInterface>launchqtcreatorcheckboxform.ui</UserInterface> </UserInterfaces> + <StartMenuDir>Qt Creator {version}</StartMenuDir> </Package> diff --git a/doc/src/analyze/cpu-usage-analyzer.qdoc b/doc/src/analyze/cpu-usage-analyzer.qdoc index 095cc7fe4c..8025f47159 100644 --- a/doc/src/analyze/cpu-usage-analyzer.qdoc +++ b/doc/src/analyze/cpu-usage-analyzer.qdoc @@ -198,14 +198,14 @@ As the Perf tool only provides periodic samples, the CPU Usage Analyzer cannot determine the exact time when a function was called or when it - returned. You can, however, see exactly when a sample was taken on the + returned. You can, however, see exactly when a sample was taken in the second row of each thread. The CPU Usage Analyzer assumes that if the same - function is present in the same place in the call chain in multiple samples - on a row, then this represents a single call to the respective function. - This is, of course, a simplification. Also, there may be other functions - being called between the samples taken, which do not show up in the profile - data. However, statistically, the data is likely to show the functions that - spend the most CPU time most prominently. + function is present at the same place in the call chain in multiple + consecutive samples, then this represents a single call to the respective + function. This is, of course, a simplification. Also, there may be other + functions being called between the samples taken, which do not show up in + the profile data. However, statistically, the data is likely to show the + functions that spend the most CPU time most prominently. If a function without debug information is encountered, further unwinding of the stack may fail. Unwinding will also fail if a QML or JavaScript @@ -254,7 +254,7 @@ Start Board and SILICA Architect Tibidabo, are correctly set up for profiling in the dwarf mode. For other devices, check whether Perf can read back its own data in a sensible way by checking the output of - \c {perf report} or \c {perf script} in the recorded Perf data files. + \c {perf report} or \c {perf script} for the recorded Perf data files. \section1 Troubleshooting diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 5eca62fdda..418b28ac19 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -569,7 +569,7 @@ class DumperBase: elided, shown = self.computeLimit(size, limit) return elided, self.readMemory(data, shown) - def putStdStringHelper(self, data, size, charSize, displayFormat = AutomaticFormat): + def putCharArrayHelper(self, data, size, charSize, displayFormat = AutomaticFormat): bytelen = size * charSize elided, shown = self.computeLimit(bytelen, self.displayStringLimit) mem = self.readMemory(data, shown) @@ -587,7 +587,6 @@ class DumperBase: encodingType = Hex8EncodedLittleEndian displayType = DisplayUtf16String - self.putNumChild(0) self.putValue(mem, encodingType, elided=elided) if displayFormat == SeparateLatin1StringFormat \ @@ -811,7 +810,7 @@ class DumperBase: code = (None, "b", "H", None, "I")[tsize] base = toInteger(p) blob = self.extractBlob(base, maximum).toBytes() - for i in xrange(0, int(maximum / tsize)): + for i in xrange(0, maximum, tsize): t = struct.unpack_from(code, blob, i)[0] if t == 0: return 0, i, self.hexencode(blob[:i]) @@ -826,7 +825,7 @@ class DumperBase: def putItemCount(self, count, maximum = 1000000000): # This needs to override the default value, so don't use 'put' directly. if count > maximum: - self.putSpeciaValue(SpecialMinimumItemCountValue, maximum) + self.putSpecialValue(SpecialMinimumItemCountValue, maximum) else: self.putSpecialValue(SpecialItemCountValue, count) self.putNumChild(count) @@ -917,18 +916,10 @@ class DumperBase: arrayByteSize = int(s[s.find('[')+1:s.find(']')]) * ts; n = int(arrayByteSize / ts) - if displayFormat != RawFormat: - if innerTypeName == "char": - # Use Latin1 as default for char []. - blob = self.readMemory(self.addressOf(value), arrayByteSize) - self.putValue(blob, Hex2EncodedLatin1) - elif innerTypeName == "wchar_t": - blob = self.readMemory(self.addressOf(value), arrayByteSize) - if innerType.sizeof == 2: - self.putValue(blob, Hex4EncodedLittleEndian) - else: - self.putValue(blob, Hex8EncodedLittleEndian) - elif p: + if displayFormat != RawFormat and p: + if innerTypeName == "char" or innerTypeName == "wchar_t": + self.putCharArrayHelper(p, n, ts, self.currentItemFormat()) + else: self.tryPutSimpleFormattedPointer(p, arrayType, innerTypeName, displayFormat, arrayByteSize) self.putNumChild(n) @@ -1661,7 +1652,6 @@ class DumperBase: with TopLevelItem(self, iname): self.put('iname="%s",' % iname) - self.put('name="%s",' % exp) self.put('wname="%s",' % escapedExp) try: value = self.parseAndEvaluate(exp) diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index b2047d867b..fb45f2ce86 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -155,7 +155,7 @@ class PlainDumper: if isinstance(val, str): d.putValue(val) else: # Assuming LazyString - d.putStdStringHelper(val.address, val.length, val.type.sizeof) + d.putCharArrayHelper(val.address, val.length, val.type.sizeof) d.putNumChild(len(children)) if d.isExpanded(): @@ -812,6 +812,14 @@ class Dumper(DumperBase): def qtVersion(self): try: + # Only available with Qt 5.3+ + qtversion = int(gdb.parse_and_eval("((void**)&qtHookData)[2]")) + self.qtVersion = lambda: qtversion + return qtversion + except: + pass + + try: version = self.qtVersionString() (major, minor, patch) = version[version.find('"')+1:version.rfind('"')].split('.') qtversion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index f9befc4c3c..6987065c2a 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1592,18 +1592,27 @@ class Dumper(DumperBase): self.reportToken(args) addr = args.get('address', 0) if addr: - error = self.currentThread().RunToAddress(addr) + # Does not seem to hit anything on Linux: + # self.currentThread().RunToAddress(addr) + bp = self.target.BreakpointCreateByAddress(addr) + if bp.GetNumLocations() == 0: + self.target.BreakpointDelete(bp.GetID()) + self.reportStatus("No target location found.") + self.reportLocation(frame) + return + bp.SetOneShot(True) + self.process.Continue() else: frame = self.currentFrame() file = args['file'] line = int(args['line']) error = self.currentThread().StepOverUntil(frame, lldb.SBFileSpec(file), line) - if error.GetType(): - self.reportState("running") - self.reportState("stopped") - self.reportError(error) - else: - self.reportData() + if error.GetType(): + self.reportState("running") + self.reportState("stopped") + self.reportError(error) + else: + self.reportData() def executeJumpToLocation(self, args): self.reportToken(args) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 62c188c736..41f515e542 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -58,7 +58,7 @@ def qform__QByteArray(): def qdump__QByteArray(d, value): data, size, alloc = d.byteArrayData(value) - d.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 100) + d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000)) d.putNumChild(size) elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit) displayFormat = d.currentItemFormat() @@ -79,7 +79,7 @@ def qdump__QByteArray(d, value): def qdump__QByteArrayData(d, value): data, size, alloc = d.byteArrayDataHelper(d.addressOf(value)) - d.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 100) + d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000)) d.putValue(d.readMemory(data, size), Hex2EncodedLatin1) d.putNumChild(1) if d.isExpanded(): @@ -280,7 +280,7 @@ def qdump__QDateTime(d, value): tz = "" else: idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr] - tz = d.encodeByteArrayHelper(d.extractPointer(idBase), limit=100) + elided, tz = d.encodeByteArrayHelper(d.extractPointer(idBase), limit=100) d.putValue("%s/%s/%s/%s/%s" % (msecs, spec, offset, tz, status), DateTimeInternal) else: @@ -2609,11 +2609,11 @@ def qdumpHelper__QJsonArray(d, data, array): array is passed as integer pointer to the QJsonPrivate::Base object. """ - if d.isNull(data): - n = 0 - else: + if data: # The 'length' part of the _dummy member: n = qdumpHelper_qle_cutBits(d.extractUInt(array + 4), 1, 31) + else: + n = 0 d.putItemCount(n) d.putNumChild(1) @@ -2634,11 +2634,11 @@ def qdumpHelper__QJsonObject(d, data, obj): obj is passed as integer pointer to the QJsonPrivate::Base object. """ - if d.isNull(data): - n = 0 - else: + if data: # The 'length' part of the _dummy member: n = qdumpHelper_qle_cutBits(d.extractUInt(obj + 4), 1, 31) + else: + n = 0 d.putItemCount(n) d.putNumChild(1) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index d37edc150a..60c271ebcd 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -419,7 +419,7 @@ def qdump__std__stringHelper1(d, value, charSize, format): refcount = int(sizePtr[-1]) & 0xffffffff d.check(refcount >= -1) # Can be -1 accoring to docs. d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) - d.putStdStringHelper(sizePtr, size, charSize, format) + d.putCharArrayHelper(sizePtr, size, charSize, format) def qdump__std__stringHelper1__QNX(d, value, charSize, format): size = value['_Mysize'] @@ -433,7 +433,7 @@ def qdump__std__stringHelper1__QNX(d, value, charSize, format): refcount = int(sizePtr[-1]) d.check(refcount >= -1) # Can be -1 accoring to docs. d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) - d.putStdStringHelper(sizePtr, size, charSize, format) + d.putCharArrayHelper(sizePtr, size, charSize, format) def qdump__std____1__string(d, value): @@ -447,7 +447,7 @@ def qdump__std____1__string(d, value): # Short/internal. size = firstByte / 2 data = base + 1 - d.putStdStringHelper(data, size, 1, d.currentItemFormat()) + d.putCharArrayHelper(data, size, 1, d.currentItemFormat()) d.putType("std::string") @@ -462,7 +462,7 @@ def qdump__std____1__wstring(d, value): # Short/internal. size = firstByte / 2 data = base + 4 - d.putStdStringHelper(data, size, 4) + d.putCharArrayHelper(data, size, 4) d.putType("std::xxwstring") diff --git a/src/app/main.cpp b/src/app/main.cpp index d2fa179bdd..3e9a523823 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -292,10 +292,13 @@ static inline QSettings *userSettings() int main(int argc, char **argv) { +#if (QT_VERSION < QT_VERSION_CHECK(5, 6, 0)) if (Utils::HostOsInfo().isWindowsHost() && !qEnvironmentVariableIsSet("QT_DEVICE_PIXEL_RATIO")) { qputenv("QT_DEVICE_PIXEL_RATIO", "auto"); } +#endif // < Qt 5.6 + QLoggingCategory::setFilterRules(QLatin1String("qtc.*.debug=false")); #ifdef Q_OS_MAC // increase the number of file that can be opened in Qt Creator. diff --git a/src/libs/qmldebug/qmldebugclient.cpp b/src/libs/qmldebug/qmldebugclient.cpp index d0f4782eb2..2f5b7976cd 100644 --- a/src/libs/qmldebug/qmldebugclient.cpp +++ b/src/libs/qmldebug/qmldebugclient.cpp @@ -191,7 +191,7 @@ void QmlDebugConnectionPrivate::readyRead() emit q->opened(); } - while (protocol->packetsAvailable()) { + while (protocol && protocol->packetsAvailable()) { QPacket pack = protocol->read(); QString name; pack >> name; diff --git a/src/libs/qtcreatorcdbext/containers.cpp b/src/libs/qtcreatorcdbext/containers.cpp index f2cde38d4d..ed7d13d837 100644 --- a/src/libs/qtcreatorcdbext/containers.cpp +++ b/src/libs/qtcreatorcdbext/containers.cpp @@ -1104,6 +1104,7 @@ AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int ty } if (!size) return AbstractSymbolGroupNodePtrVector(); + node->addFlags(SymbolGroupNode::PreSortedChildren); const unsigned maxArraySize = ExtensionContext::instance().parameters().maxArraySize; if (size > maxArraySize) size = maxArraySize; diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp index 6f3e902a89..a4f39dd41f 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp @@ -168,7 +168,7 @@ bool AbstractSymbolGroupNode::accept(SymbolGroupNodeVisitor &visitor, break; case SymbolGroupNodeVisitor::VisitContinue: { AbstractSymbolGroupNodePtrVector c = children(); - if (visitor.sortChildrenAlphabetically()) { + if (visitor.sortChildrenAlphabetically() && !testFlags(SymbolGroupNode::PreSortedChildren)) { std::sort(c.begin(), c.end(), [](AbstractSymbolGroupNode *a, AbstractSymbolGroupNode *b) { return a->name() < b->name(); }); diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.h b/src/libs/qtcreatorcdbext/symbolgroupnode.h index 3fbbedd7ea..9d49869dba 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.h +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.h @@ -230,7 +230,8 @@ public: AdditionalSymbol = 0x20, // Introduced by addSymbol, should not be visible Obscured = 0x40, // Symbol is obscured by (for example) fake container children ComplexDumperOk = 0x80, - WatchNode = 0x100 + WatchNode = 0x100, + PreSortedChildren = 0x200 }; ~SymbolGroupNode(); diff --git a/src/libs/sqlite/sqlitedatabaseconnection.cpp b/src/libs/sqlite/sqlitedatabaseconnection.cpp index a73d2c105e..c973c2584c 100644 --- a/src/libs/sqlite/sqlitedatabaseconnection.cpp +++ b/src/libs/sqlite/sqlitedatabaseconnection.cpp @@ -38,6 +38,8 @@ #include <QDebug> #ifdef Q_OS_LINUX +#include <cerrno> +#include <cstring> #include <sys/resource.h> #include <sys/syscall.h> #include <sys/types.h> diff --git a/src/libs/ssh/sshoutgoingpacket.cpp b/src/libs/ssh/sshoutgoingpacket.cpp index 7a4a66f853..dc3b916f2f 100644 --- a/src/libs/ssh/sshoutgoingpacket.cpp +++ b/src/libs/ssh/sshoutgoingpacket.cpp @@ -112,9 +112,12 @@ void SshOutgoingPacket::generateServiceRequest(const QByteArray &service) void SshOutgoingPacket::generateUserAuthByPasswordRequestPacket(const QByteArray &user, const QByteArray &service, const QByteArray &pwd) { - init(SSH_MSG_USERAUTH_REQUEST).appendString(user).appendString(service) - .appendString("password").appendBool(false).appendString(pwd) - .finalize(); + init(SSH_MSG_USERAUTH_REQUEST).appendString(user).appendString(service); + if (pwd.isEmpty()) + appendString("none"); // RFC 4252, 5.2 + else + appendString("password").appendBool(false).appendString(pwd); + finalize(); } void SshOutgoingPacket::generateUserAuthByPublicKeyRequestPacket(const QByteArray &user, diff --git a/src/plugins/baremetal/baremetalruncontrolfactory.cpp b/src/plugins/baremetal/baremetalruncontrolfactory.cpp index 8a4cb36278..4221465923 100644 --- a/src/plugins/baremetal/baremetalruncontrolfactory.cpp +++ b/src/plugins/baremetal/baremetalruncontrolfactory.cpp @@ -146,7 +146,7 @@ RunControl *BareMetalRunControlFactory::create( if (p->startupMode() == GdbServerProvider::StartupOnNetwork) sp.remoteSetupNeeded = true; - DebuggerRunControl *runControl = createDebuggerRunControl(sp, rc, errorMessage); + DebuggerRunControl *runControl = createDebuggerRunControl(sp, rc, errorMessage, mode); if (runControl && sp.remoteSetupNeeded) { const auto debugSupport = new BareMetalDebugSupport(dev, runControl); Q_UNUSED(debugSupport); diff --git a/src/plugins/baremetal/defaultgdbserverprovider.cpp b/src/plugins/baremetal/defaultgdbserverprovider.cpp index e76b3b60ef..8b1f3ef029 100644 --- a/src/plugins/baremetal/defaultgdbserverprovider.cpp +++ b/src/plugins/baremetal/defaultgdbserverprovider.cpp @@ -59,6 +59,29 @@ DefaultGdbServerProvider::DefaultGdbServerProvider(const DefaultGdbServerProvide { } +quint16 DefaultGdbServerProvider::port() const +{ + return m_port; +} + +void DefaultGdbServerProvider::setPort(const quint16 &port) +{ + m_port = port; +} + +QString DefaultGdbServerProvider::host() const +{ + return m_host; +} + +void DefaultGdbServerProvider::setHost(const QString &host) +{ + if (m_host == host) + return; + m_host = host; + providerUpdated(); +} + QString DefaultGdbServerProvider::typeDisplayName() const { return DefaultGdbServerProviderFactory::tr("Default"); @@ -183,8 +206,8 @@ void DefaultGdbServerProviderConfigWidget::applyImpl() auto p = static_cast<DefaultGdbServerProvider *>(provider()); Q_ASSERT(p); - p->m_host = m_hostWidget->host(); - p->m_port = m_hostWidget->port(); + p->setHost(m_hostWidget->host()); + p->setPort(m_hostWidget->port()); p->setInitCommands(m_initCommandsTextEdit->toPlainText()); p->setResetCommands(m_resetCommandsTextEdit->toPlainText()); } diff --git a/src/plugins/baremetal/defaultgdbserverprovider.h b/src/plugins/baremetal/defaultgdbserverprovider.h index 53379d4409..f3a13be169 100644 --- a/src/plugins/baremetal/defaultgdbserverprovider.h +++ b/src/plugins/baremetal/defaultgdbserverprovider.h @@ -56,6 +56,12 @@ public: bool isValid() const; + QString host() const; + void setHost(const QString &host); + + quint16 port() const; + void setPort(const quint16 &port); + private: explicit DefaultGdbServerProvider(); explicit DefaultGdbServerProvider(const DefaultGdbServerProvider &); diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index bff0c4577e..eadb4a37ce 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -100,10 +100,7 @@ QList<AssistProposalItem *> toAssistProposalItems(const CodeCompletions &complet items.insert(name, item); item->setText(name); item->setOrder(ccr.priority()); - - if (ccr.completionKind() == CodeCompletion::KeywordCompletionKind) - item->setDetail(CompletionChunksToTextConverter::convertToToolTip(ccr.chunks())); - + item->setDetail(CompletionChunksToTextConverter::convertToToolTip(ccr.chunks())); item->setCodeCompletion(ccr); } diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index f0f68030fc..9ceb6a208d 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -44,7 +44,7 @@ #include <QDir> #include <QFile> #include <QLoggingCategory> -#include <QRegExp> +#include <QRegularExpression> #include <QSet> #include <QString> @@ -154,8 +154,9 @@ private: // We already provide a custom clang include path matching the used libclang version, // so better ignore the clang include paths from the system as this might lead to an // unfavorable order with regard to include_next. - static QRegExp clangIncludeDir(QLatin1String(".*/lib/clang/\\d+\\.\\d+\\.\\d+/include")); - if (clangIncludeDir.exactMatch(path)) + static QRegularExpression clangIncludeDir( + QLatin1String("\\A.*/lib/clang/\\d+\\.\\d+(\\.\\d+)?/include\\z")); + if (clangIncludeDir.match(path).hasMatch()) return true; return false; diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 215c434d69..5c30f4a0c7 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -623,15 +623,33 @@ public: ProposalModel proposal; }; -bool hasItem(ProposalModel model, const QByteArray &text) +int indexOfItemWithText(ProposalModel model, const QByteArray &text) { if (!model) - return false; + return -1; for (int i = 0, size = model->size(); i < size; ++i) { const QString itemText = model->text(i); if (itemText == QString::fromUtf8(text)) - return true; + return i; + } + + return -1; +} + +bool hasItem(ProposalModel model, const QByteArray &text) +{ + return indexOfItemWithText(model, text) != -1; +} + +bool hasItem(ProposalModel model, const QByteArray &text, const QByteArray &detail) +{ + const int index = indexOfItemWithText(model, text); + if (index != -1 && index < model->size()) { + TextEditor::IAssistProposalModel *imodel = model.data(); + const auto genericModel = static_cast<TextEditor::GenericProposalModel *>(imodel); + const auto itemDetail = genericModel->detail(index); + return itemDetail == QString::fromUtf8(detail); } return false; @@ -844,10 +862,10 @@ void ClangCodeCompletionTest::testCompleteGlobals() { ProjectLessCompletionTest t("globalCompletion.cpp"); - QVERIFY(hasItem(t.proposal, "globalVariable")); - QVERIFY(hasItem(t.proposal, "globalFunction")); - QVERIFY(hasItem(t.proposal, "GlobalClass")); - QVERIFY(hasItem(t.proposal, "class")); // Keyword + QVERIFY(hasItem(t.proposal, "globalVariable", "int globalVariable")); + QVERIFY(hasItem(t.proposal, "globalFunction", "void globalFunction ()")); + QVERIFY(hasItem(t.proposal, "GlobalClass", "GlobalClass")); + QVERIFY(hasItem(t.proposal, "class", "class")); // Keyword QVERIFY(hasSnippet(t.proposal, "class")); // Snippet } diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index 5e34817d42..e0473082d3 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -33,6 +33,7 @@ #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> +#include <utils/algorithm.h> #include <utils/hostosinfo.h> #include <utils/fancylineedit.h> #include <utils/qtcassert.h> @@ -64,6 +65,20 @@ namespace Internal { static QPointer<SettingsDialog> m_instance = 0; +bool optionsPageLessThan(const IOptionsPage *p1, const IOptionsPage *p2) +{ + if (p1->category() != p2->category()) + return p1->category().alphabeticallyBefore(p2->category()); + return p1->id().alphabeticallyBefore(p2->id()); +} + +static inline QList<IOptionsPage*> sortedOptionsPages() +{ + QList<IOptionsPage*> rc = ExtensionSystem::PluginManager::getObjects<IOptionsPage>(); + qStableSort(rc.begin(), rc.end(), optionsPageLessThan); + return rc; +} + // ----------- Category model class Category @@ -104,12 +119,14 @@ public: void setPages(const QList<IOptionsPage*> &pages, const QList<IOptionsPageProvider *> &providers); + void ensurePages(Category *category); const QList<Category*> &categories() const { return m_categories; } private: Category *findCategoryById(Id id); QList<Category*> m_categories; + QSet<Id> m_pageIds; QIcon m_emptyIcon; }; @@ -155,9 +172,13 @@ void CategoryModel::setPages(const QList<IOptionsPage*> &pages, // Clear any previous categories qDeleteAll(m_categories); m_categories.clear(); + m_pageIds.clear(); // Put the pages in categories foreach (IOptionsPage *page, pages) { + QTC_ASSERT(!m_pageIds.contains(page->id()), + qWarning("duplicate options page id '%s'", qPrintable(page->id().toString()))); + m_pageIds.insert(page->id()); const Id categoryId = page->category(); Category *category = findCategoryById(categoryId); if (!category) { @@ -191,9 +212,31 @@ void CategoryModel::setPages(const QList<IOptionsPage*> &pages, category->providers.append(provider); } + Utils::sort(m_categories, [](const Category *c1, const Category *c2) { + return c1->id.alphabeticallyBefore(c2->id); + }); endResetModel(); } +void CategoryModel::ensurePages(Category *category) +{ + if (!category->providerPagesCreated) { + QList<IOptionsPage *> createdPages; + foreach (const IOptionsPageProvider *provider, category->providers) + createdPages += provider->pages(); + + // check for duplicate ids + foreach (IOptionsPage *page, createdPages) { + QTC_ASSERT(!m_pageIds.contains(page->id()), + qWarning("duplicate options page id '%s'", qPrintable(page->id().toString()))); + } + + category->pages += createdPages; + category->providerPagesCreated = true; + qStableSort(category->pages.begin(), category->pages.end(), optionsPageLessThan); + } +} + Category *CategoryModel::findCategoryById(Id id) { for (int i = 0; i < m_categories.size(); ++i) { @@ -359,21 +402,6 @@ private: // ----------- SettingsDialog -// Helpers to sort by category. id -bool optionsPageLessThan(const IOptionsPage *p1, const IOptionsPage *p2) -{ - if (p1->category() != p2->category()) - return p1->category().alphabeticallyBefore(p2->category()); - return p1->id().alphabeticallyBefore(p2->id()); -} - -static inline QList<IOptionsPage*> sortedOptionsPages() -{ - QList<IOptionsPage*> rc = ExtensionSystem::PluginManager::getObjects<IOptionsPage>(); - qStableSort(rc.begin(), rc.end(), optionsPageLessThan); - return rc; -} - SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), m_pages(sortedOptionsPages()), @@ -540,14 +568,8 @@ void SettingsDialog::ensureCategoryWidget(Category *category) { if (category->tabWidget != 0) return; - if (!category->providerPagesCreated) { - foreach (const IOptionsPageProvider *provider, category->providers) - category->pages += provider->pages(); - category->providerPagesCreated = true; - } - - qStableSort(category->pages.begin(), category->pages.end(), optionsPageLessThan); + m_model->ensurePages(category); QTabWidget *tabWidget = new QTabWidget; for (int j = 0; j < category->pages.size(); ++j) { IOptionsPage *page = category->pages.at(j); diff --git a/src/plugins/cpaster/fileshareprotocolsettingspage.cpp b/src/plugins/cpaster/fileshareprotocolsettingspage.cpp index e0d46ea838..0805483a8d 100644 --- a/src/plugins/cpaster/fileshareprotocolsettingspage.cpp +++ b/src/plugins/cpaster/fileshareprotocolsettingspage.cpp @@ -99,7 +99,7 @@ FileShareProtocolSettingsPage::FileShareProtocolSettingsPage(const QSharedPointe QObject *parent) : Core::IOptionsPage(parent), m_settings(s), m_widget(0) { - setId("X.FileSharePaster"); + setId("X.CodePaster.FileSharePaster"); setDisplayName(tr("Fileshare")); setCategory(Constants::CPASTER_SETTINGS_CATEGORY); setDisplayCategory(QCoreApplication::translate("CodePaster", Constants::CPASTER_SETTINGS_TR_CATEGORY)); diff --git a/src/plugins/cpaster/settingspage.cpp b/src/plugins/cpaster/settingspage.cpp index a391ffb366..aa32cf3587 100644 --- a/src/plugins/cpaster/settingspage.cpp +++ b/src/plugins/cpaster/settingspage.cpp @@ -70,7 +70,7 @@ Settings SettingsWidget::settings() SettingsPage::SettingsPage(const QSharedPointer<Settings> &settings) : m_settings(settings), m_widget(0) { - setId("A.General"); + setId("A.CodePaster.General"); setDisplayName(tr("General")); setCategory(Constants::CPASTER_SETTINGS_CATEGORY); setDisplayCategory(QCoreApplication::translate("CodePaster", diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index cbc04f6a67..962afeddd0 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -514,6 +514,21 @@ void CppEditorPlugin::test_quickfix_data() "}\n" ); + // Checks: Do not crash on incomplete case statetement. + QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( + "enum E {};\n" + "void f(E o)\n" + "{\n" + " @switch (o)\n" + " {\n" + " case\n" + " }\n" + "}\n" + ) << _( + "" + ); + // Checks: // 1. If the name does not start with ("m_" or "_") and does not // end with "_", we are forced to prefix the getter with "get". diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 736638ef92..ff1c151afb 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -2212,11 +2212,13 @@ public: bool preVisit(AST *ast) { if (CaseStatementAST *cs = ast->asCaseStatement()) { foundCaseStatementLevel = true; - if (ExpressionAST *expression = cs->expression->asIdExpression()) { - QList<LookupItem> candidates = typeOfExpression(expression, document, scope); - if (!candidates .isEmpty() && candidates.first().declaration()) { - Symbol *decl = candidates.first().declaration(); - values << prettyPrint.prettyName(LookupContext::fullyQualifiedName(decl)); + if (ExpressionAST *csExpression = cs->expression) { + if (ExpressionAST *expression = csExpression->asIdExpression()) { + QList<LookupItem> candidates = typeOfExpression(expression, document, scope); + if (!candidates.isEmpty() && candidates.first().declaration()) { + Symbol *decl = candidates.first().declaration(); + values << prettyPrint.prettyName(LookupContext::fullyQualifiedName(decl)); + } } } return true; diff --git a/src/plugins/cpptools/cpptoolsconstants.h b/src/plugins/cpptools/cpptoolsconstants.h index 2b2bf859a9..d6130297f2 100644 --- a/src/plugins/cpptools/cpptoolsconstants.h +++ b/src/plugins/cpptools/cpptoolsconstants.h @@ -56,11 +56,11 @@ const char CPPTOOLS_SORT_EDITOR_DOCUMENT_OUTLINE[] = "SortedMethodOverview"; const char CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY[] = "ModelManagerSupporters"; const char CPPTOOLS_MODEL_MANAGER_PCH_USAGE[] = "PCHUsage"; -const char CPP_CODE_STYLE_SETTINGS_ID[] = "A.Code Style"; +const char CPP_CODE_STYLE_SETTINGS_ID[] = "A.Cpp.Code Style"; const char CPP_CODE_STYLE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "Code Style"); -const char CPP_FILE_SETTINGS_ID[] = "B.File Naming"; +const char CPP_FILE_SETTINGS_ID[] = "B.Cpp.File Naming"; const char CPP_FILE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "File Naming"); -const char CPP_CODE_MODEL_SETTINGS_ID[] = "C.Code Model"; +const char CPP_CODE_MODEL_SETTINGS_ID[] = "C.Cpp.Code Model"; const char CPP_CODE_MODEL_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "Code Model"); const char CPP_SETTINGS_CATEGORY[] = "I.C++"; const char CPP_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("CppTools", "C++"); diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp index 5631ee4f8c..f4e82dee12 100644 --- a/src/plugins/debugger/cdb/cdboptionspage.cpp +++ b/src/plugins/debugger/cdb/cdboptionspage.cpp @@ -202,7 +202,7 @@ QStringList CdbOptionsPageWidget::breakEvents() const CdbOptionsPage::CdbOptionsPage() { - setId("F.Cda"); + setId("F.Debugger.Cda"); setDisplayName(tr("CDB")); setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY); setDisplayCategory(QCoreApplication::translate("Debugger", @@ -281,7 +281,7 @@ CdbPathsPageWidget::CdbPathsPageWidget(QWidget *parent) : CdbPathsPage::CdbPathsPage() : m_widget(0) { - setId("F.Cdb"); + setId("F.Debugger.Cdb"); setDisplayName(tr("CDB Paths")); setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY); setDisplayCategory(QCoreApplication::translate("Debugger", diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp index 2e7e17ea19..aada5d7c33 100644 --- a/src/plugins/debugger/commonoptionspage.cpp +++ b/src/plugins/debugger/commonoptionspage.cpp @@ -339,7 +339,7 @@ QString CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(const char *functio LocalsAndExpressionsOptionsPage::LocalsAndExpressionsOptionsPage() { - setId("Z.LocalsAndExpressions"); + setId("Z.Debugger.LocalsAndExpressions"); //: '&&' will appear as one (one is marking keyboard shortcut) setDisplayName(QCoreApplication::translate("Debugger", "Locals && Expressions")); setCategory(DEBUGGER_SETTINGS_CATEGORY); diff --git a/src/plugins/debugger/debuggerinternalconstants.h b/src/plugins/debugger/debuggerinternalconstants.h index 290edbde3f..823bf00aff 100644 --- a/src/plugins/debugger/debuggerinternalconstants.h +++ b/src/plugins/debugger/debuggerinternalconstants.h @@ -36,7 +36,7 @@ namespace Debugger { namespace Constants { -const char DEBUGGER_COMMON_SETTINGS_ID[] = "A.Common"; +const char DEBUGGER_COMMON_SETTINGS_ID[] = "A.Debugger.General"; const char DEBUGGER_SETTINGS_CATEGORY[] = "O.Debugger"; const char DEBUGGER_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Debugger", "Debugger"); const char DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON[] = ":/debugger/images/category_debug.png"; diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index cea3191f7c..194f8a159c 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -2356,6 +2356,8 @@ ConsoleItem *QmlEnginePrivate::constructLogItemTree(ConsoleItem *parent, void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &properties) { QTC_ASSERT(parent, return); + LookupItems itemsToLookup; + foreach (const QVariant &property, properties) { QmlV8ObjectData propertyData = extractData(property); auto item = new WatchItem; @@ -2377,15 +2379,20 @@ void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &pro item->id = propertyData.handle; item->type = propertyData.type; item->value = propertyData.value.toString(); - item->setHasChildren(propertyData.properties.count()); + if (item->type.isEmpty()) + itemsToLookup.insert(propertyData.handle, {item->iname, item->name}); + item->setHasChildren(propertyData.properties.count() > 0); parent->appendChild(item); } - if (boolSetting(SortStructMembers)) + if (boolSetting(SortStructMembers)) { parent->sortChildren([](const TreeItem *item1, const TreeItem *item2) -> bool { return static_cast<const WatchItem *>(item1)->name - < static_cast<const WatchItem *>(item2)->name; + < static_cast<const WatchItem *>(item2)->name; }); + } + + lookup(itemsToLookup); } void QmlEnginePrivate::handleExecuteDebuggerCommand(const QVariantMap &response) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 80d59291fa..a5c6a414d6 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -882,7 +882,7 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role case Qt::EditRole: switch (idx.column()) { case 0: { - m_handler->watchExpression(value.toString().trimmed()); + m_handler->updateWatchExpression(item, value.toString().trimmed().toUtf8()); break; } case 1: // Change value @@ -933,6 +933,9 @@ Qt::ItemFlags WatchItem::flags(int column) const const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled; const Qt::ItemFlags editable = notEditable | Qt::ItemIsEditable; + if (state == InferiorUnrunnable) + return notEditable; + if (isWatcher()) { if (state != InferiorStopOk && state != DebuggerNotReady @@ -946,13 +949,13 @@ Qt::ItemFlags WatchItem::flags(int column) const // FIXME: Forcing types is not implemented yet. //if (idx.column() == 2) // return editable; // Watcher types can be set by force. - if (column == 1 && valueEditable) + if (column == 1 && valueEditable && !elided) return editable; // Watcher values are sometimes editable. } } else if (isLocal()) { if (state != InferiorStopOk && !engine->hasCapability(AddWatcherWhileRunningCapability)) return Qt::ItemFlags(); - if (column == 1 && valueEditable) + if (column == 1 && valueEditable && !elided) return editable; // Locals values are sometimes editable. } else if (isInspect()) { if (column == 1 && valueEditable) @@ -1278,6 +1281,30 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name) if (m_model->m_engine->state() == DebuggerNotReady) { item->setAllUnneeded(); item->setValue(QString(QLatin1Char(' '))); + item->update(); + } else { + m_model->m_engine->updateItem(item->iname); + } + updateWatchersWindow(); +} + +void WatchHandler::updateWatchExpression(WatchItem *item, const QByteArray &newExp) +{ + if (newExp.isEmpty()) + return; + + if (item->exp != newExp) { + theWatcherNames.insert(newExp, theWatcherNames.value(item->exp)); + theWatcherNames.remove(item->exp); + item->exp = newExp; + item->name = QString::fromUtf8(item->exp); + } + + saveWatchers(); + if (m_model->m_engine->state() == DebuggerNotReady) { + item->setAllUnneeded(); + item->setValue(QString(QLatin1Char(' '))); + item->update(); } else { m_model->m_engine->updateItem(item->iname); } diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 412b84666f..094ffaf3de 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -112,6 +112,7 @@ public: void cleanup(); void watchExpression(const QString &exp, const QString &name = QString()); + void updateWatchExpression(WatchItem *item, const QByteArray &newExp); void watchVariable(const QString &exp); Q_SLOT void clearWatches(); diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index a50d76e991..47e83a41b1 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -751,6 +751,8 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev) QMenu formatMenu(tr("Change Value Display Format")); if (mi0.isValid()) fillFormatMenu(&formatMenu, mi0); + else + formatMenu.setEnabled(false); QMenu memoryMenu(tr("Open Memory Editor")); QAction actOpenMemoryEditAtObjectAddress(0); @@ -809,6 +811,9 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev) breakpointMenu.addAction(&actSetWatchpointAtObjectAddress); breakpointMenu.addAction(&actSetWatchpointAtPointerAddress); breakpointMenu.addAction(&actSetWatchpointAtExpression); + breakpointMenu.setEnabled(actSetWatchpointAtObjectAddress.isEnabled() + || actSetWatchpointAtPointerAddress.isEnabled() + || actSetWatchpointAtExpression.isEnabled()); QAction actCopy(tr("Copy View Contents to Clipboard"), 0); QAction actCopyValue(tr("Copy Value to Clipboard"), 0); diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 1cb4c0f041..9b7aa2ef73 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -111,9 +111,9 @@ namespace Internal { const char INSTALL_HANDLER[] = "TextEditor.FakeVimHandler"; const char SETTINGS_CATEGORY[] = "D.FakeVim"; const char SETTINGS_CATEGORY_FAKEVIM_ICON[] = ":/fakevim/images/category_fakevim.png"; -const char SETTINGS_ID[] = "A.General"; -const char SETTINGS_EX_CMDS_ID[] = "B.ExCommands"; -const char SETTINGS_USER_CMDS_ID[] = "C.UserCommands"; +const char SETTINGS_ID[] = "A.FakeVim.General"; +const char SETTINGS_EX_CMDS_ID[] = "B.FakeVim.ExCommands"; +const char SETTINGS_USER_CMDS_ID[] = "C.FakeVim.UserCommands"; typedef QLatin1String _; class MiniBuffer : public QStackedWidget diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp index 2c2e129cf8..ee68ed5dfa 100644 --- a/src/plugins/git/branchdialog.cpp +++ b/src/plugins/git/branchdialog.cpp @@ -316,8 +316,7 @@ void BranchDialog::diff() QString fullName = m_model->fullName(selectedIndex(), true); if (fullName.isEmpty()) return; - // Do not pass working dir by reference since it might change - GitPlugin::instance()->client()->diffBranch(QString(m_repository), fullName); + GitPlugin::instance()->client()->diffBranch(m_repository, fullName); } void BranchDialog::log() @@ -325,8 +324,7 @@ void BranchDialog::log() QString branchName = m_model->fullName(selectedIndex(), true); if (branchName.isEmpty()) return; - // Do not pass working dir by reference since it might change - GitPlugin::instance()->client()->log(QString(m_repository), QString(), false, QStringList(branchName)); + GitPlugin::instance()->client()->log(m_repository, QString(), false, QStringList(branchName)); } void BranchDialog::reset() diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 8997a388b5..ad8944a712 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -743,6 +743,9 @@ void GitClient::requestReload(const QString &documentId, const QString &source, const QString &title, std::function<DiffEditorController *(IDocument *)> factory) const { + // Creating document might change the referenced source. Store a copy and use it. + const QString sourceCopy = source; + IDocument *document = DiffEditorController::findOrCreateDocument(documentId, title); QTC_ASSERT(document, return); DiffEditorController *controller = factory(document); @@ -753,7 +756,7 @@ void GitClient::requestReload(const QString &documentId, const QString &source, connect(controller, &DiffEditorController::requestInformationForCommit, this, &GitClient::branchesForCommit); - VcsBasePlugin::setSource(document, source); + VcsBasePlugin::setSource(document, sourceCopy); EditorManager::activateEditorForDocument(document); controller->requestReload(); } @@ -843,19 +846,21 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName, msgArg = args.first(); else msgArg = workingDirectory; + // Creating document might change the referenced workingDirectory. Store a copy and use it. + const QString workingDir = workingDirectory; const QString title = tr("Git Log \"%1\"").arg(msgArg); const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; - const QString sourceFile = VcsBaseEditor::getSource(workingDirectory, fileName); + const QString sourceFile = VcsBaseEditor::getSource(workingDir, fileName); VcsBaseEditorWidget *editor = createVcsEditor(editorId, title, sourceFile, codecFor(CodecLogOutput), "logTitle", msgArg); if (!editor->configurationWidget()) { auto *argWidget = new GitLogArgumentsWidget(settings()); connect(argWidget, &VcsBaseEditorParameterWidget::commandExecutionRequested, - [=]() { this->log(workingDirectory, fileName, enableAnnotationContextMenu, args); }); + [=]() { this->log(workingDir, fileName, enableAnnotationContextMenu, args); }); editor->setConfigurationWidget(argWidget); } editor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); - editor->setWorkingDirectory(workingDirectory); + editor->setWorkingDirectory(workingDir); QStringList arguments; arguments << QLatin1String("log") << QLatin1String(noColorOption) @@ -874,7 +879,7 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName, if (!fileName.isEmpty()) arguments << QLatin1String("--follow") << QLatin1String("--") << fileName; - vcsExec(workingDirectory, arguments, editor); + vcsExec(workingDir, arguments, editor); } void GitClient::reflog(const QString &workingDirectory) diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp index b604a6bec9..3842f7fb32 100644 --- a/src/plugins/projectexplorer/abi.cpp +++ b/src/plugins/projectexplorer/abi.cpp @@ -512,7 +512,8 @@ Abi Abi::abiFromTargetTriplet(const QString &triple) if (flavor == Abi::UnknownFlavor) flavor = Abi::FreeBsdFlavor; format = Abi::ElfFormat; - } else if (p == QLatin1String("mingw32") || p == QLatin1String("win32") || p == QLatin1String("mingw32msvc")) { + } else if (p == QLatin1String("mingw32") || p == QLatin1String("win32") + || p == QLatin1String("mingw32msvc") || p == QLatin1String("msys")) { arch = Abi::X86Architecture; os = Abi::WindowsOS; flavor = Abi::WindowsMSysFlavor; @@ -752,7 +753,9 @@ Abi Abi::hostAbi() #if defined (Q_OS_WIN) os = WindowsOS; -#if _MSC_VER == 1800 +#if _MSC_VER == 1900 + subos = WindowsMsvc2015Flavor; +#elif _MSC_VER == 1800 subos = WindowsMsvc2013Flavor; #elif _MSC_VER == 1700 subos = WindowsMsvc2012Flavor; @@ -1075,6 +1078,10 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet_data() << int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor) << int(Abi::PEFormat) << 0; + QTest::newRow("x86_64-pc-msys") << int(Abi::X86Architecture) + << int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor) + << int(Abi::PEFormat) << 64; + QTest::newRow("mingw32") << int(Abi::X86Architecture) << int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor) << int(Abi::PEFormat) << 0; diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index 13a85a8c5f..a926efc45c 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -58,7 +58,6 @@ #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/icore.h> #include <coreplugin/id.h> -#include <coreplugin/infobar.h> #include <coreplugin/modemanager.h> #include <extensionsystem/pluginmanager.h> @@ -112,7 +111,6 @@ QmlJSEditorWidget::QmlJSEditorWidget() { m_outlineCombo = 0; m_contextPane = 0; - m_firstSementicInfo = true; m_findReferences = new FindReferences(this); setLanguageSettingsId(QmlJSTools::Constants::QML_JS_SETTINGS_ID); @@ -949,16 +947,6 @@ void QmlJSEditorWidget::semanticInfoUpdated(const SemanticInfo &semanticInfo) } } - if (m_firstSementicInfo) { - m_firstSementicInfo = false; - if (semanticInfo.document->language() == Dialect::QmlQtQuick2Ui) { - InfoBarEntry info(Id(Constants::QML_UI_FILE_WARNING), - tr("This file should only be edited in <b>Design</b> mode.")); - info.setCustomButtonInfo(tr("Switch Mode"), []() { ModeManager::activateMode(Core::Constants::MODE_DESIGN); }); - textDocument()->infoBar()->addInfo(info); - } - } - updateUses(); } diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h index b27029cd17..5701d823f1 100644 --- a/src/plugins/qmljseditor/qmljseditor.h +++ b/src/plugins/qmljseditor/qmljseditor.h @@ -139,8 +139,6 @@ private: int m_oldCursorPosition; FindReferences *m_findReferences; - - bool m_firstSementicInfo; }; diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp index cf81dd9a4f..5452de327e 100644 --- a/src/plugins/qmljseditor/qmljseditordocument.cpp +++ b/src/plugins/qmljseditor/qmljseditordocument.cpp @@ -37,6 +37,10 @@ #include "qmljssemanticinfoupdater.h" #include "qmloutlinemodel.h" +#include <coreplugin/coreconstants.h> +#include <coreplugin/infobar.h> +#include <coreplugin/modemanager.h> + #include <qmljstools/qmljsindenter.h> #include <qmljstools/qmljsmodelmanager.h> #include <qmljstools/qmljsqtstylecodeformatter.h> @@ -520,6 +524,19 @@ void QmlJSEditorDocumentPrivate::acceptNewSemanticInfo(const SemanticInfo &seman m_outlineModelNeedsUpdate = true; m_semanticHighlightingNecessary = true; + if (m_firstSementicInfo) { + m_firstSementicInfo = false; + if (semanticInfo.document->language() == Dialect::QmlQtQuick2Ui + && !q->infoBar()->containsInfo(Core::Id(Constants::QML_UI_FILE_WARNING))) { + Core::InfoBarEntry info(Core::Id(Constants::QML_UI_FILE_WARNING), + tr("This file should only be edited in <b>Design</b> mode.")); + info.setCustomButtonInfo(tr("Switch Mode"), []() { + Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN); + }); + q->infoBar()->addInfo(info); + } + } + emit q->semanticInfoUpdated(m_semanticInfo); // calls triggerPendingUpdates as necessary } diff --git a/src/plugins/qmljseditor/qmljseditordocument_p.h b/src/plugins/qmljseditor/qmljseditordocument_p.h index d3c41d93ef..174578a0b3 100644 --- a/src/plugins/qmljseditor/qmljseditordocument_p.h +++ b/src/plugins/qmljseditor/qmljseditordocument_p.h @@ -75,6 +75,7 @@ public: Internal::SemanticHighlighter *m_semanticHighlighter; bool m_semanticHighlightingNecessary; bool m_outlineModelNeedsUpdate; + bool m_firstSementicInfo = true; QTimer m_updateOutlineModelTimer; Internal::QmlOutlineModel *m_outlineModel; }; diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp index 9ca77f9898..032eaec4a0 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp @@ -42,6 +42,7 @@ #include <projectexplorer/kitinformation.h> #include <utils/qtcassert.h> +#include <utils/qtcprocess.h> #include <qmldebug/qmloutputparser.h> #include <qmldebug/qmldebugcommandlinearguments.h> @@ -85,6 +86,14 @@ AnalyzerStartParameters RemoteLinuxAnalyzeSupport::startParameters(const RunConf params.sysroot = SysRootKitInformation::sysRoot(runConfig->target()->kit()).toString(); params.analyzerHost = params.connParams.host; + auto rc = qobject_cast<const AbstractRemoteLinuxRunConfiguration *>(runConfig); + QTC_ASSERT(rc, return params); + + params.debuggee = rc->remoteExecutableFilePath(); + params.debuggeeArgs = Utils::QtcProcess::Arguments::createUnixArgs(rc->arguments()).toString(); + params.workingDirectory = rc->workingDirectory(); + params.environment = rc->environment(); + return params; } diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp index 3053e39027..53c4647f05 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp @@ -106,7 +106,7 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Co } DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc); - DebuggerRunControl * const runControl = createDebuggerRunControl(params, runConfig, errorMessage); + DebuggerRunControl * const runControl = createDebuggerRunControl(params, runConfig, errorMessage, mode); if (!runControl) return 0; LinuxDeviceDebugSupport * const debugSupport = diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp index e6f19ee6db..925881a451 100644 --- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp +++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp @@ -34,6 +34,7 @@ #include <utils/faketooltip.h> #include <utils/hostosinfo.h> +#include <utils/qtcassert.h> #include <QDebug> #include <QApplication> @@ -201,7 +202,8 @@ bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e) d->m_escapePressed = true; e->accept(); } - if (d->m_model->size() > 1) { + QTC_CHECK(d->m_model); + if (d->m_model && d->m_model->size() > 1) { QKeyEvent *ke = static_cast<QKeyEvent*>(e); if (ke->key() == Qt::Key_Up) { previousPage(); @@ -220,10 +222,13 @@ bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e) emit explicitlyAborted(); return false; } else if (ke->key() == Qt::Key_Up || ke->key() == Qt::Key_Down) { - if (d->m_model->size() > 1) + QTC_CHECK(d->m_model); + if (d->m_model && d->m_model->size() > 1) return false; } - d->m_assistant->notifyChange(); + QTC_CHECK(d->m_assistant); + if (d->m_assistant) + d->m_assistant->notifyChange(); } break; case QEvent::WindowDeactivate: diff --git a/src/plugins/vcsbase/vcsbaseconstants.h b/src/plugins/vcsbase/vcsbaseconstants.h index d3620760df..506f278af8 100644 --- a/src/plugins/vcsbase/vcsbaseconstants.h +++ b/src/plugins/vcsbase/vcsbaseconstants.h @@ -39,7 +39,7 @@ namespace Constants { const char VCS_SETTINGS_CATEGORY[] = "V.Version Control"; const char VCS_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("VcsBase", "Version Control"); const char SETTINGS_CATEGORY_VCS_ICON[] = ":/vcsbase/images/category_vcs.png"; -const char VCS_COMMON_SETTINGS_ID[] = "A.Common"; +const char VCS_COMMON_SETTINGS_ID[] = "A.VCS.General"; const char VCS_COMMON_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("VcsBase", "General"); // Ids for sort order (wizards and preferences) diff --git a/src/shared/qbs b/src/shared/qbs -Subproject bca958c3f55ca73b7cc9cf09317b192a2dec1bc +Subproject 0abd1f7b723335df7a24da3e5194f8050dc635b diff --git a/src/tools/clangbackend/ipcsource/unsavedfiles.cpp b/src/tools/clangbackend/ipcsource/unsavedfiles.cpp index 609b3490ed..90f9e2c796 100644 --- a/src/tools/clangbackend/ipcsource/unsavedfiles.cpp +++ b/src/tools/clangbackend/ipcsource/unsavedfiles.cpp @@ -30,6 +30,7 @@ #include "unsavedfiles.h" +#include <algorithm> #include <cstring> namespace ClangBackEnd { @@ -154,12 +155,12 @@ void UnsavedFiles::updateCXUnsavedFileWithFileContainer(const FileContainer &fil void UnsavedFiles::removeCXUnsavedFile(const FileContainer &fileContainer) { const Utf8String filePath = fileContainer.filePath(); - auto removeBeginIterator = std::remove_if(d->cxUnsavedFiles.begin(), + auto removeBeginIterator = std::partition(d->cxUnsavedFiles.begin(), d->cxUnsavedFiles.end(), - [filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath == cxUnsavedFile.Filename; }); + [filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath != cxUnsavedFile.Filename; }); std::for_each(removeBeginIterator, d->cxUnsavedFiles.end(), UnsavedFiles::deleteCXUnsavedFile); - d->cxUnsavedFiles.erase( removeBeginIterator, d->cxUnsavedFiles.end()); + d->cxUnsavedFiles.erase(removeBeginIterator, d->cxUnsavedFiles.end()); } void UnsavedFiles::addOrUpdateCXUnsavedFile(const FileContainer &fileContainer) @@ -182,6 +183,4 @@ void UnsavedFiles::updateLastChangeTimePoint() d->lastChangeTimePoint = std::chrono::steady_clock::now(); } - } // namespace ClangBackEnd - diff --git a/tests/auto/debugger/offsets.pro b/tests/auto/debugger/offsets.pro index f3eef5c31a..b021596f0e 100644 --- a/tests/auto/debugger/offsets.pro +++ b/tests/auto/debugger/offsets.pro @@ -3,6 +3,8 @@ include(../qttest.pri) QT += core-private +CONFIG -= c++11 # Fails to build with boost (due to #define private public) + exists(/usr/include/boost/unordered/unordered_set.hpp) { DEFINES += HAS_BOOST } diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 3263ad00b2..4e86a343db 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1857,7 +1857,7 @@ void tst_Dumpers::dumper_data() "pain.drawLine(2, 2, 130, 130);\n" "pain.end();\n" "QPixmap pm = QPixmap::fromImage(im);\n" - "unused(&pm);\n") + "unused(&app, &pm);\n") + GuiProfile() @@ -3860,7 +3860,7 @@ void tst_Dumpers::dumper_data() + Check("l0", "<0 items>", "std::list<int>") - + Check("l1", "<>1000 items>", "std::list<int>") + + Check("l1", "<at least 1000 items>", "std::list<int>") + Check("l1.0", "[0]", "0", "int") + Check("l1.1", "[1]", "1", "int") + Check("l1.999", "[999]", "999", "int") @@ -4613,7 +4613,9 @@ void tst_Dumpers::dumper_data() "unused(&s, &t, &w);\n") + CheckType("s", "char [5]") + + Check("s.0", "[0]", "97", "char") + CheckType("t", "char [6]") + + Check("t.0", "[0]", "97", "char") + CheckType("w", "wchar_t [4]"); @@ -5812,7 +5814,7 @@ void tst_Dumpers::dumper_data() "pol.append(QPointF(2, 4));\n" "pol.append(QPointF(1, 4));\n" "QGraphicsPolygonItem *p = sc.addPolygon(pol);\n" - "unused(&p);\n") + "unused(&app, &p);\n") + GuiProfile() + Check("pol", "<5 items>", "@QPolygonF") + Check("p", "<5 items>", "@QGraphicsPolygonItem"); diff --git a/tests/system/suite_editors/tst_modify_readonly/test.py b/tests/system/suite_editors/tst_modify_readonly/test.py index 60be9d04f5..3c891bf910 100644 --- a/tests/system/suite_editors/tst_modify_readonly/test.py +++ b/tests/system/suite_editors/tst_modify_readonly/test.py @@ -106,9 +106,8 @@ def testSaveChangesAndMakeWritable(modifiedFiles, readOnlyFiles): "window=':WritePermissions_Core::Internal::ReadOnlyFilesDialog'}") items = map(os.path.expanduser, map(os.path.join, dumpItems(filesTree.model(), column=4), dumpItems(filesTree.model(), column=3))) - difference = set(readOnlyFiles) ^ set(items) - test.verify(len(difference) == 0, "Verifying whether all modified files without write " - "permission are listed.") + test.compare(set(readOnlyFiles), set(items), + "Verifying whether all modified files without write permission are listed.") clickButton("{text='Change Permission' type='QPushButton' visible='1' unnamed='1' " "window=':WritePermissions_Core::Internal::ReadOnlyFilesDialog'}") except: diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py index 06f033ce32..965152901d 100644 --- a/tests/system/suite_general/tst_default_settings/test.py +++ b/tests/system/suite_general/tst_default_settings/test.py @@ -82,8 +82,10 @@ def __checkBuildAndRun__(): clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Qt Versions") __iterateTree__(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget", __qtFunc__, foundQt, qmakePath) + test.verify(not qmakePath or len(foundQt) == 1, + "Was qmake from %s autodetected? Found %s" % (qmakePath, foundQt)) if foundQt: - foundQt = foundQt[0] + foundQt = foundQt[0] # qmake from "which" should be used in kits # check kits clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Kits") __iterateTree__(":BuildAndRun_QTreeView", __kitFunc__, foundQt, foundCompilerNames) @@ -126,12 +128,16 @@ def __dbgFunc__(it, foundDbg): foundDbg.append(str(pathLineEdit.text)) def __qtFunc__(it, foundQt, qmakePath): - foundQt.append(it) qtPath = str(waitForObject(":QtSupport__Internal__QtVersionManager.qmake_QLabel").text) if platform.system() in ('Microsoft', 'Windows'): qtPath = qtPath.lower() qmakePath = qmakePath.lower() - test.compare(qtPath, qmakePath, "Verifying found and expected Qt version are equal.") + test.verify(os.path.isfile(qtPath) and os.access(qtPath, os.X_OK), + "Verifying found Qt (%s) is executable." % qtPath) + # Two Qt versions will be found when using qtchooser: QTCREATORBUG-14697 + # Only add qmake from "which" to list + if qtPath == qmakePath: + foundQt.append(it) try: errorLabel = findObject(":QtSupport__Internal__QtVersionManager.errorLabel.QLabel") test.warning("Detected error or warning: '%s'" % errorLabel.text) @@ -222,7 +228,8 @@ def __getExpectedDebuggers__(): for debugger in ["gdb", "lldb"]: result.extend(findAllFilesInPATH(debugger)) if platform.system() == 'Linux': - result.extend(findAllFilesInPATH("lldb-*")) + result.extend(filter(lambda s: not ("lldb-platform" in s or "lldb-gdbserver" in s), + findAllFilesInPATH("lldb-*"))) if platform.system() == 'Darwin': xcodeLLDB = getOutputFromCmdline("xcrun --find lldb").strip("\n") if xcodeLLDB and os.path.exists(xcodeLLDB) and xcodeLLDB not in result: @@ -292,12 +299,8 @@ def __compareDebuggers__(foundDebuggers, expectedDebuggers): else: foundSet = set(foundDebuggers) expectedSet = set(expectedDebuggers) - if not (test.verify(not foundSet.symmetric_difference(expectedSet), - "Verifying expected and found debuggers match.")): - test.log("Found debuggers: %s" % foundDebuggers, - "Expected debuggers: %s" % expectedDebuggers) - return False - return True + return test.compare(foundSet, expectedSet, + "Verifying expected and found debuggers match.") def __lowerStrs__(iterable): for it in iterable: |