diff --git a/doc/images/qtcreator-kits.png b/doc/images/qtcreator-kits.png index ad7c6017174..15243c74a4f 100644 Binary files a/doc/images/qtcreator-kits.png and b/doc/images/qtcreator-kits.png differ diff --git a/doc/src/android/deploying-android.qdoc b/doc/src/android/deploying-android.qdoc index b9602e0ced3..6024ec0ba65 100644 --- a/doc/src/android/deploying-android.qdoc +++ b/doc/src/android/deploying-android.qdoc @@ -53,6 +53,8 @@ To copy Qt libraries and files to the project directory and to bundle them as part of the APK, select the \gui {Bundle Qt libraries in APK} option. + \note Android 5 devices support only this option. + \section1 Using Ministro to Install Qt Libraries To minimize the size of your APK, you can package the application with an diff --git a/doc/src/overview/creator-advanced.qdoc b/doc/src/overview/creator-advanced.qdoc index d3767fd756f..6c73d81ffcd 100644 --- a/doc/src/overview/creator-advanced.qdoc +++ b/doc/src/overview/creator-advanced.qdoc @@ -53,8 +53,9 @@ \li \l{Using Other Build Systems} \QC is integrated with cross-platform systems for build automation: - qmake and CMake. In addition, you can import generic projects that - do not use qmake or CMake, and specify that \QC ignores your build + qmake, Qbs, CMake, and Autotools. In addition, you can import + generic projects that do not use those systems, and specify that \QC + ignores your build system. \li \l{Using Command Line Options} diff --git a/doc/src/overview/creator-getting-started.qdoc b/doc/src/overview/creator-getting-started.qdoc index 0a1b407f593..80549b923c2 100644 --- a/doc/src/overview/creator-getting-started.qdoc +++ b/doc/src/overview/creator-getting-started.qdoc @@ -34,6 +34,7 @@ \row \li \inlineimage creator-gs-01.png \li \inlineimage creator-gs-02.png + \li \inlineimage creator_advanceduse.png \row \li \b {\l{IDE Overview}} @@ -44,9 +45,17 @@ If you have not used \QC before, and want to become familiar with the parts of the user interface, go to \l{User Interface}. + \li \b {\l{Configuring Qt Creator}} + + To make \QC behave more like your favorite code editor or IDE, + you can change the settings for keyboard shortcuts, color + schemes, generic highlighting, code snippets, and version + control systems. For an overview of the options you have, go to + \l{Configuring Qt Creator}. \row \li \inlineimage creator-gs-03.png \li \inlineimage creator-gs-04.png + \li \row \li \b {\l{Building and Running an Example}} @@ -59,6 +68,7 @@ Now you are ready to start developing your own applications. Pick a tutorial to follow in \l{Tutorials}. To start developing for mobile devices, select \l{Creating a Mobile Application}. + \li \endtable */ diff --git a/doc/src/projects/creator-projects-creating.qdoc b/doc/src/projects/creator-projects-creating.qdoc index 5eebf271190..926770cdb65 100644 --- a/doc/src/projects/creator-projects-creating.qdoc +++ b/doc/src/projects/creator-projects-creating.qdoc @@ -50,7 +50,7 @@ the necessary files for you. You can add your own custom wizards to standardize the way subprojects and classes are added to a project. - The wizards create projects that use the Qt build tool, qmake. It is a + Most wizards create projects that use the Qt build tool, qmake. It is a cross-platform system for build automation that helps simplify the build process for development projects across different platforms. qmake automates the generation of build configurations so that only a few lines @@ -59,9 +59,11 @@ You can modify the build and run settings for qmake projects in the \gui Projects mode. - Alternatively, you can use the CMake build automation system and set up the - projects manually. In addition, you can import projects as - \e {generic projects} that do not use qmake or CMake. This enables you to + You can use wizards also to create plain C or C++ projects that use Qbs or + CMake, but do not use the Qt library. + + In addition, you can import projects as \e {generic projects} that do not + use qmake, Qbs, or CMake. This enables you to use \QC as a code editor and to fully control the steps and commands used to build the project. @@ -196,8 +198,7 @@ \li Plain C or C++ Project (Qbs Build) Plain C or C++ project that uses Qbs but does not use the Qt - library. This project type is listed if the experimental Qbs - plugin has been enabled in \gui Help > \gui {About Plugins}. + library. \endlist diff --git a/doc/src/projects/creator-projects-other.qdoc b/doc/src/projects/creator-projects-other.qdoc index b363458c971..86848e00931 100644 --- a/doc/src/projects/creator-projects-other.qdoc +++ b/doc/src/projects/creator-projects-other.qdoc @@ -30,7 +30,7 @@ \title Using Other Build Systems - \QC project wizards create projects that are configured to use qmake. Most + Most \QC project wizards create projects that are configured to use qmake. Most of the instructions in this manual apply to using qmake. However, \QC is also integrated to other build systems, as described in the the following sections: diff --git a/doc/src/projects/creator-projects-settings-build.qdoc b/doc/src/projects/creator-projects-settings-build.qdoc index d4c4709d4ff..e0da2a7fe9a 100644 --- a/doc/src/projects/creator-projects-settings-build.qdoc +++ b/doc/src/projects/creator-projects-settings-build.qdoc @@ -181,6 +181,27 @@ development PCs. To share settings, incorporate them into the build system. For example, if you use qmake, make the changes in the \c{.pro} file. + \section2 Batch Editing + + To modify environment variable values for build or run environments, + select \gui {Batch Edit} in the build or run settings and enter environment + variables in the \gui {Edit Environment} dialog. + + To remove a variable value from the environment, enter the variable name. + For example, \c TEST sets the value of the \c TEST variable empty when + building or running the project. + + To add a variable value to the environment, enter the variable name and + value, separated by the equals sign. For example, the following line + prepends \c /opt/bin to the existing PATH: + + \c {PATH=/opt/bin:${PATH}} + + To add or remove several variables, place them on separate lines. The order + is important. If you remove a value on a line, you cannot refer to it on the + following lines. However, you can remove a value after you have referred to + it on an earlier line. + \section2 Clearing the System Environment To build with a clean system environment, select the \gui {Clear system diff --git a/doc/src/projects/creator-projects-settings-run.qdoc b/doc/src/projects/creator-projects-settings-run.qdoc index 5ffc53a4c84..b2e072dcb8a 100644 --- a/doc/src/projects/creator-projects-settings-run.qdoc +++ b/doc/src/projects/creator-projects-settings-run.qdoc @@ -82,6 +82,9 @@ fetches information about the \gui {Device Environment} from the device. Usually, it does not make sense to edit the device environment. + To modify the environment variable values for the run environment, select + \gui {Batch Edit}. For more information, see \l{Batch Editing}. + \section1 Specifying a Custom Executable to Run If you use CMake or the generic project type in \QC, or want diff --git a/doc/src/projects/creator-projects-targets.qdoc b/doc/src/projects/creator-projects-targets.qdoc index ea9e9c605f1..3b6926d48cb 100644 --- a/doc/src/projects/creator-projects-targets.qdoc +++ b/doc/src/projects/creator-projects-targets.qdoc @@ -91,6 +91,11 @@ if they are installed on the development PC, but were not detected automatically. For more information, see \l{Adding Compilers}. + \li In the \gui Environment field, select \gui Change to modify + environment variable values for build and run environments in + the \gui {Edit Environment Changes} dialog. For more information + about how to add and remove variable values, see \l{Batch Editing}. + \li In the \gui Debugger field, select the debugger to debug the project on the target platform. \QC automatically detects available debuggers and displays a suitable debugger in the field. You can diff --git a/doc/src/qtquick/qtquick-modules-with-plugins.qdoc b/doc/src/qtquick/qtquick-modules-with-plugins.qdoc index cc0586bed0b..99ee6b328dd 100644 --- a/doc/src/qtquick/qtquick-modules-with-plugins.qdoc +++ b/doc/src/qtquick/qtquick-modules-with-plugins.qdoc @@ -91,13 +91,20 @@ correctly from QML modules, the emulation layer must be built with the same Qt version as the QML modules. - By default, the emulation layer is provided by \QC and built with the same + By default, a fallback emulation layer is provided by \QC and built with the same Qt version as \QC. Therefore, your QML modules will mostly not work out of the box. To use an emulation layer that is built with the Qt - configured in the build and run kit for the project, deselect the - \gui {Always use the QML emulation layer provided by Qt Creator} check box. + configured in the build and run kit for the project, select \gui Tools > + \gui Options > \gui {Qt Quick} > \gui {Qt Quick Designer} > + \gui {Use QML emulation layer which is built by the selected Qt} radio button. \QC builds the emulation layer when you select the \gui Design mode. + A plugin should behave differently depending on whether it is run by the + emulation layer or an application. For example, animations should not be run + in the \gui Design mode. You can use the value of the QML_PUPPET_MODE + environment variable to check whether the plugin is currently being run + by an application or edited in the \gui Design mode. + */ diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 7e4d4e5c811..6a381f9f81a 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -920,7 +920,6 @@ class Dumper(DumperBase): return False def putItem(self, value, tryDynamic=True): - #value = value.GetDynamicValue(lldb.eDynamicCanRunTarget) typeName = value.GetType().GetUnqualifiedType().GetName() if self.isGoodLldb: value.SetPreferDynamicValue(tryDynamic) @@ -965,10 +964,11 @@ class Dumper(DumperBase): realType = value.GetType() if hasattr(realType, 'GetCanonicalType'): baseType = realType.GetCanonicalType() - baseValue = value.Cast(baseType.unqualified()) - self.putItem(baseValue) - self.putBetterType(realType) - return + if baseType != realType: + baseValue = value.Cast(baseType.unqualified()) + self.putItem(baseValue) + self.putBetterType(realType) + return # Our turf now. if self.isGoodLldb: @@ -986,11 +986,24 @@ class Dumper(DumperBase): # References if value.GetType().IsReferenceType(): - origType = value.GetTypeName(); type = value.GetType().GetDereferencedType().unqualified() - addr = int(value) & 0xFFFFFFFFFFFFFFFF - self.putItem(value.CreateValueFromAddress(None, addr, type)) - self.putBetterType(origType) + addr = value.GetValueAsUnsigned() + #warn("FROM: %s" % value) + #warn("ADDR: 0x%x" % addr) + #warn("TYPE: %s" % type) + # Works: + #item = self.currentThread().GetSelectedFrame().EvaluateExpression( + # "(%s*)0x%x" % (type, addr)).Dereference() + # Works: + item = value.CreateValueFromExpression(None, + "(%s*)0x%x" % (type, addr), lldb.SBExpressionOptions()).Dereference() + # Does not work: + #item = value.CreateValueFromAddress(None, addr, type) + # Does not work: + #item = value.Cast(type.GetPointerType()).Dereference() + #warn("TOOO: %s" % item) + self.putItem(item) + self.putBetterType(value.GetTypeName()) return # Pointers @@ -1534,7 +1547,6 @@ class Dumper(DumperBase): def selectThread(self, args): self.process.SetSelectedThreadByID(args['id']) self.reportData() - self.reportStack() def requestModuleSymbols(self, frame): self.handleCommand("target module list " + frame) diff --git a/share/qtcreator/generic-highlighter/xml.xml b/share/qtcreator/generic-highlighter/xml.xml index 3d92a563cd1..6bf68177513 100644 --- a/share/qtcreator/generic-highlighter/xml.xml +++ b/share/qtcreator/generic-highlighter/xml.xml @@ -134,7 +134,7 @@ - + diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 14bcfed4730..7788cc509bf 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -540,6 +540,10 @@ Do you want to uninstall the existing package next time? API Level of device is: %1. Уровень API устройства: %1. + + Android 5 devices are incompatible with deploying Qt to a temporary directory. + Устройства на базе Android 5 не поддерживают установку Qt во временный каталог. + Incompatible devices Несовместимые устройства @@ -857,6 +861,14 @@ Do you want to uninstall the existing package next time? Failed to forward C++ debugging ports. Не удалось пробросить порты отладки С++. + + Failed to forward ping pong ports. Reason: %1. + Не удалось пробросить порты ping pong: %1. + + + Failed to forward ping pong ports. + Не удалось пробросить порты ping pong. + Failed to forward QML debugging ports. Reason: %1. Не удалось пробросить порты отладки QML: %1. @@ -869,6 +881,10 @@ Do you want to uninstall the existing package next time? Failed to start the activity. Reason: %1. Не удалось запустить activity: %1. + + Failed to contact debugging port. + Не удалось подключиться к порту отладки. + "%1" terminated. «%1» завершён. @@ -1032,10 +1048,6 @@ Install an SDK of at least API version %1. Certificate alias: Алиас сертификата: - - Signing an APK that uses "Deploy local Qt libraries" is not allowed - Подписывание APK, использующего локальные библиотеки Qt, запрещено - Application Приложение @@ -1090,6 +1102,12 @@ The APK will not be usable on any other device. Deploy local Qt libraries to temporary directory Устанавливать Qt во временный каталог + + Signing an APK that uses "Deploy local Qt libraries" is not allowed. +Deploying local Qt libraries is incompatible with Android 5 + Подписывание APK, использующего локальные библиотеки Qt, запрещено. +Установка локальных библиотек Qt не поддерживается на Android 5 + AndroidConfig @@ -4200,10 +4218,6 @@ This wizard will guide you through the essential steps to deploy a ready-to-go d Meta+C,Meta+P Meta+C,Meta+P - - Paste Clipboard... - Вставить из буфера обмена... - Fetch Snippet... Получить фрагмент... @@ -10017,14 +10031,6 @@ This feature is only available for GDB. Populate source file view automatically Автоматически заполнять представление исходных текстов - - Close temporary views on debugger exit - Закрывать временные обзоры при завершении отладчика - - - Stopping and stepping in the debugger will automatically open source or disassembler views associated with the current location. Select this option to automatically close them when the debugger exits. - Остановка и пошаговая отладка автоматически открывают обзор исходников или дизассемблера соответствующий текущему положению. Включение этого параметра приведёт к их автоматическому закрытию при завершении отладки. - Switch to previous mode on debugger exit Переключаться в предыдущий режим при завершении отладчика @@ -10053,6 +10059,26 @@ This feature is only available for GDB. Show QML object tree Показывать дерево объектов QML + + Stopping and stepping in the debugger will automatically open views associated with the current location. + Остановка и пошаговая отладка автоматически открывают обзор кода соответствующий текущему положению. + + + Close temporary source views on debugger exit + Закрывать временные обзоры кода при завершении отладки + + + Select this option to close automatically opened source views when the debugger exits. + Включение закрытия автоматически открытых обзоров исходников при завершении отладки. + + + Close temporary memory views on debugger exit + Закрывать временные обзоры памяти при завершении отладки + + + Select this option to close automatically opened memory views when the debugger exits. + Включение закрытия автоматически открытых обзоров памяти при завершении отладки. + Set breakpoints using a full absolute path Задавать полный путь к точкам останова @@ -19862,6 +19888,10 @@ Ids must begin with a lowercase letter. The process terminated with exit code %1. Процесс завершился с кодом %1. + + [Only %1 MB of output shown] + [Отображено только %1 МБ вывода] + The commit message check failed. Do you want to submit this change list? Проверки сообщения о фиксации завершилась с ошибкой. Отправить указанные изменения? @@ -23166,6 +23196,17 @@ to project "%2". Сделать по умолчанию + + ProjectExplorer::LineEditValidator + + Line Edit Validator Expander + Расширитель валидатора строкового редактора + + + The text edit input to fix up. + Данные для исправления в текстовом редакторе. + + ProjectExplorer::LocalEnvironmentAspect diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp index 63ad5f40ff4..1642d9d024b 100644 --- a/src/libs/qmljs/qmljsplugindumper.cpp +++ b/src/libs/qmljs/qmljsplugindumper.cpp @@ -93,10 +93,10 @@ void PluginDumper::scheduleMaybeRedumpBuiltins(const QmlJS::ModelManagerInterfac void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info, bool force) { - if (info.qmlDumpPath.isEmpty() || (info.qtImportsPath.isEmpty() && info.qtQmlPath.isEmpty())) + const QString baseImportsPath = info.qtQmlPath.isEmpty() ? info.qtImportsPath : info.qtQmlPath; + if (info.qmlDumpPath.isEmpty() || baseImportsPath.isEmpty()) return; - const QString baseImportsPath = info.qtQmlPath.isEmpty() ? info.qtImportsPath : info.qtQmlPath; const QString importsPath = QDir::cleanPath(baseImportsPath); if (m_runningQmldumps.values().contains(importsPath)) return; @@ -109,7 +109,7 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec return; } builtinInfo = LibraryInfo(LibraryInfo::Found); - m_modelManager->updateLibraryInfo(info.qtImportsPath, builtinInfo); + m_modelManager->updateLibraryInfo(baseImportsPath, builtinInfo); // prefer QTDIR/qml/builtins.qmltypes if available const QString builtinQmltypesPath = baseImportsPath + QLatin1String("/builtins.qmltypes"); diff --git a/src/libs/ssh/sshchannel.cpp b/src/libs/ssh/sshchannel.cpp index 35a6c51ed8c..5ed65605af8 100644 --- a/src/libs/ssh/sshchannel.cpp +++ b/src/libs/ssh/sshchannel.cpp @@ -137,11 +137,11 @@ void AbstractSshChannel::flushSendBuffer() void AbstractSshChannel::handleOpenSuccess(quint32 remoteChannelId, quint32 remoteWindowSize, quint32 remoteMaxPacketSize) { - switch (m_state) { + const ChannelState oldState = m_state; + switch (oldState) { + case CloseRequested: // closeChannel() was called while we were in SessionRequested state case SessionRequested: break; // Ok, continue. - case CloseRequested: - return; // Late server reply; we requested a channel close in the meantime. default: throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, "Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet."); @@ -163,7 +163,10 @@ void AbstractSshChannel::handleOpenSuccess(quint32 remoteChannelId, m_remoteWindowSize = remoteWindowSize; m_remoteMaxPacketSize = remoteMaxPacketSize; setChannelState(SessionEstablished); - handleOpenSuccessInternal(); + if (oldState == CloseRequested) + closeChannel(); + else + handleOpenSuccessInternal(); } void AbstractSshChannel::handleOpenFailure(const QString &reason) @@ -260,8 +263,12 @@ void AbstractSshChannel::closeChannel() setChannelState(Closed); } else { setChannelState(CloseRequested); - m_sendFacility.sendChannelEofPacket(m_remoteChannel); - m_sendFacility.sendChannelClosePacket(m_remoteChannel); + if (m_remoteChannel != NoChannel) { + m_sendFacility.sendChannelEofPacket(m_remoteChannel); + m_sendFacility.sendChannelClosePacket(m_remoteChannel); + } else { + QSSH_ASSERT(m_state == SessionRequested); + } } } } diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index 08d80644db8..84b918d96fe 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -31,6 +31,7 @@ #include "sshremoteprocess.h" #include "sshremoteprocess_p.h" +#include "ssh_global.h" #include "sshincomingpacket_p.h" #include "sshsendfacility_p.h" @@ -85,6 +86,7 @@ SshRemoteProcess::SshRemoteProcess(quint32 channelId, Internal::SshSendFacility SshRemoteProcess::~SshRemoteProcess() { + QSSH_ASSERT(d->channelState() != Internal::AbstractSshChannel::SessionEstablished); close(); delete d; } diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 7c7823a3d82..e7ded2e40b5 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -160,6 +160,11 @@ CppTools::BaseEditorDocumentParser *ClangEditorDocumentProcessor::parser() return &m_parser; } +CPlusPlus::Snapshot ClangEditorDocumentProcessor::snapshot() +{ + return m_builtinProcessor.snapshot(); +} + bool ClangEditorDocumentProcessor::isParserRunning() const { return m_parserWatcher.isRunning(); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 0ceed0b10f4..7d24ffd9fd2 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -37,7 +37,6 @@ #include #include - #include namespace ClangCodeModel { @@ -55,6 +54,7 @@ public: void semanticRehighlight(bool force) Q_DECL_OVERRIDE; CppTools::SemanticInfo recalculateSemanticInfo() Q_DECL_OVERRIDE; CppTools::BaseEditorDocumentParser *parser() Q_DECL_OVERRIDE; + CPlusPlus::Snapshot snapshot() Q_DECL_OVERRIDE; bool isParserRunning() const Q_DECL_OVERRIDE; private slots: diff --git a/src/plugins/coreplugin/editormanager/documentmodel.cpp b/src/plugins/coreplugin/editormanager/documentmodel.cpp index 27d79aef993..8c2825a06cf 100644 --- a/src/plugins/coreplugin/editormanager/documentmodel.cpp +++ b/src/plugins/coreplugin/editormanager/documentmodel.cpp @@ -330,8 +330,10 @@ QList DocumentModel::openedDocuments() IDocument *DocumentModel::documentForFilePath(const QString &filePath) { - Entry *e = Utils::findOrDefault(d->m_entries, Utils::equal(&Entry::fileName, filePath)); - return e ? e->document : 0; + const int index = d->indexOfFilePath(filePath); + if (index < 0) + return 0; + return d->m_entries.at(index)->document; } QList DocumentModel::editorsForFilePath(const QString &filePath) diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp index d95680c6c55..9a3811cc2da 100644 --- a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp +++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include @@ -1365,8 +1365,8 @@ void CppCodeModelInspectorDialog::refresh() if (editor) { const QString editorFilePath = editor->document()->filePath(); editorDocument = cmmi->editorDocument(editorFilePath); - if (auto *builtinDocumentParser = BuiltinEditorDocumentParser::get(editorFilePath)) { - const CPlusPlus::Snapshot editorSnapshot = builtinDocumentParser->snapshot(); + if (auto *documentProcessor = BaseEditorDocumentProcessor::get(editorFilePath)) { + const CPlusPlus::Snapshot editorSnapshot = documentProcessor->snapshot(); m_snapshotInfos->append(SnapshotInfo(editorSnapshot, SnapshotInfo::EditorSnapshot)); const QString editorSnapshotTitle = QString::fromLatin1("Current Editor's Snapshot (%1 Documents)") diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index ffb9d2c9547..927d4ff9a0c 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -182,6 +182,7 @@ private slots: void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_veryFirstIncludeCppStyleCommentOnTop(); void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_veryFirstIncludeCStyleCommentOnTop(); void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_checkQSomethingInQtIncludePaths(); + void test_quickfix_AddIncludeForUndefinedIdentifier_noDoubleQtHeaderInclude(); void test_quickfix_MoveFuncDefOutside_MemberFuncToCpp(); void test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS(); diff --git a/src/plugins/cppeditor/cppincludehierarchymodel.cpp b/src/plugins/cppeditor/cppincludehierarchymodel.cpp index 3a9b6f7f728..8481c8cb0b2 100644 --- a/src/plugins/cppeditor/cppincludehierarchymodel.cpp +++ b/src/plugins/cppeditor/cppincludehierarchymodel.cpp @@ -33,13 +33,14 @@ #include "cppincludehierarchyitem.h" #include -#include +#include #include #include #include #include #include +#include #include @@ -183,8 +184,9 @@ void CppIncludeHierarchyModel::fetchMore(const QModelIndex &parent) } if (item == m_includesItem) { - const Snapshot editorDocumentSnapshot - = BuiltinEditorDocumentParser::get(editorFilePath)->snapshot(); + auto *processor = BaseEditorDocumentProcessor::get(editorFilePath); + QTC_ASSERT(processor, return); + const Snapshot editorDocumentSnapshot = processor->snapshot(); buildHierarchyIncludes_helper(parentItem->filePath(), parentItem, editorDocumentSnapshot, &cyclic); } else { @@ -284,9 +286,11 @@ void CppIncludeHierarchyModel::buildHierarchyIncludes(const QString ¤tFile return; const QString editorFilePath = m_editor->document()->filePath(); - const Snapshot snapshot = BuiltinEditorDocumentParser::get(editorFilePath)->snapshot(); + auto *documentProcessor = BaseEditorDocumentProcessor::get(editorFilePath); + QTC_ASSERT(documentProcessor, return); + const Snapshot editorDocumentSnapshot = documentProcessor->snapshot(); QSet cyclic; - buildHierarchyIncludes_helper(currentFilePath, m_includesItem, snapshot, &cyclic); + buildHierarchyIncludes_helper(currentFilePath, m_includesItem, editorDocumentSnapshot, &cyclic); } void CppIncludeHierarchyModel::buildHierarchyIncludes_helper(const QString &filePath, diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 60d6d517b81..fff21d928de 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -1637,7 +1637,7 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods() InsertVirtualMethods factory( new Tests::InsertVirtualMethodsDialogTest(implementationMode, insertVirtualKeyword)); - Tests::QuickFixTestCase(Tests::singleDocument(original, expected), &factory); + Tests::QuickFixOperationTest(Tests::singleDocument(original, expected), &factory); } /// Check: Insert in implementation file @@ -1683,7 +1683,7 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_implementationFile() InsertVirtualMethods factory(new Tests::InsertVirtualMethodsDialogTest( InsertVirtualMethodsDialog::ModeImplementationFile, true)); - Tests::QuickFixTestCase(testFiles, &factory); + Tests::QuickFixOperationTest(testFiles, &factory); } /// Check: Qualified names. @@ -1735,7 +1735,7 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_BaseClassInNamespace() InsertVirtualMethods factory(new Tests::InsertVirtualMethodsDialogTest( InsertVirtualMethodsDialog::ModeImplementationFile, true)); - Tests::QuickFixTestCase(testFiles, &factory); + Tests::QuickFixOperationTest(testFiles, &factory); } #endif // WITH_TESTS diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 70d2e1c267a..c32e96bf586 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -89,6 +89,89 @@ QList singleDocument(const QByteArray &original, << QuickFixTestDocument::create("file.cpp", original, expected); } +BaseQuickFixTestCase::BaseQuickFixTestCase(const QList &testDocuments, + const ProjectPart::HeaderPaths &headerPaths) + : m_testDocuments(testDocuments) + , m_cppCodeStylePreferences(0) + , m_restoreHeaderPaths(false) +{ + QVERIFY(succeededSoFar()); + m_succeededSoFar = false; + + // Check if there is exactly one cursor marker + unsigned cursorMarkersCount = 0; + foreach (const QuickFixTestDocument::Ptr document, m_testDocuments) { + if (document->hasCursorMarker()) + ++cursorMarkersCount; + } + QVERIFY2(cursorMarkersCount == 1, "Exactly one cursor marker is allowed."); + + // Write documents to disk + foreach (QuickFixTestDocument::Ptr document, m_testDocuments) + document->writeToDisk(); + + // Set appropriate include paths + if (!headerPaths.isEmpty()) { + m_restoreHeaderPaths = true; + m_headerPathsToRestore = m_modelManager->headerPaths(); + m_modelManager->setHeaderPaths(headerPaths); + } + + // Update Code Model + QSet filePaths; + foreach (const QuickFixTestDocument::Ptr &document, m_testDocuments) + filePaths << document->filePath(); + QVERIFY(parseFiles(filePaths)); + + // Open Files + foreach (QuickFixTestDocument::Ptr document, m_testDocuments) { + QVERIFY(openCppEditor(document->filePath(), &document->m_editor, + &document->m_editorWidget)); + closeEditorAtEndOfTestCase(document->m_editor); + + // Set cursor position + const int cursorPosition = document->hasCursorMarker() + ? document->m_cursorPosition : 0; + document->m_editor->setCursorPosition(cursorPosition); + + // Rehighlight + waitForRehighlightedSemanticDocument(document->m_editorWidget); + } + + // Enforce the default cpp code style, so we are independent of config file settings. + // This is needed by e.g. the GenerateGetterSetter quick fix. + m_cppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle(); + QVERIFY(m_cppCodeStylePreferences); + m_cppCodeStylePreferencesOriginalDelegateId = m_cppCodeStylePreferences->currentDelegateId(); + m_cppCodeStylePreferences->setCurrentDelegate("qt"); + + // Find the document having the cursor marker + foreach (const QuickFixTestDocument::Ptr document, m_testDocuments) { + if (document->hasCursorMarker()){ + m_documentWithMarker = document; + break; + } + } + + QVERIFY(m_documentWithMarker); + m_succeededSoFar = true; +} + +BaseQuickFixTestCase::~BaseQuickFixTestCase() +{ + // Restore default cpp code style + if (m_cppCodeStylePreferences) + m_cppCodeStylePreferences->setCurrentDelegate(m_cppCodeStylePreferencesOriginalDelegateId); + + // Restore include paths + if (m_restoreHeaderPaths) + m_modelManager->setHeaderPaths(m_headerPathsToRestore); + + // Remove created files from file system + foreach (const QuickFixTestDocument::Ptr &testDocument, m_testDocuments) + QVERIFY(QFile::remove(testDocument->filePath())); +} + /// Leading whitespace is not removed, so we can check if the indetation ranges /// have been set correctly by the quick-fix. static QString &removeTrailingWhitespace(QString &input) @@ -113,81 +196,30 @@ static QString &removeTrailingWhitespace(QString &input) return input; } -/// The '@' in the originalSource is the position from where the quick-fix discovery is triggered. -/// Exactly one TestFile must contain the cursor position marker '@' in the originalSource. -QuickFixTestCase::QuickFixTestCase(const QList &theTestFiles, - CppQuickFixFactory *factory, - const ProjectPart::HeaderPaths &headerPaths, - int resultIndex, - const QByteArray &expectedFailMessage) - : m_testFiles(theTestFiles) - , m_cppCodeStylePreferences(0) - , m_restoreHeaderPaths(false) +QuickFixOperationTest::QuickFixOperationTest(const QList &testDocuments, + CppQuickFixFactory *factory, + const ProjectPart::HeaderPaths &headerPaths, + int operationIndex, + const QByteArray &expectedFailMessage) + : BaseQuickFixTestCase(testDocuments, headerPaths) { QVERIFY(succeededSoFar()); - // Check if there is exactly one cursor marker - unsigned cursorMarkersCount = 0; - foreach (const QuickFixTestDocument::Ptr testFile, m_testFiles) { - if (testFile->hasCursorMarker()) - ++cursorMarkersCount; - } - QVERIFY2(cursorMarkersCount == 1, "Exactly one cursor marker is allowed."); - - // Write files to disk - foreach (QuickFixTestDocument::Ptr testFile, m_testFiles) - testFile->writeToDisk(); - - // Set appropriate include paths - if (!headerPaths.isEmpty()) { - m_restoreHeaderPaths = true; - m_headerPathsToRestore = m_modelManager->headerPaths(); - m_modelManager->setHeaderPaths(headerPaths); - } - - // Update Code Model - QSet filePaths; - foreach (const QuickFixTestDocument::Ptr &testFile, m_testFiles) - filePaths << testFile->filePath(); - QVERIFY(parseFiles(filePaths)); - - // Open Files - foreach (QuickFixTestDocument::Ptr testFile, m_testFiles) { - QVERIFY(openCppEditor(testFile->filePath(), &testFile->m_editor, - &testFile->m_editorWidget)); - closeEditorAtEndOfTestCase(testFile->m_editor); - - // Set cursor position - const int cursorPosition = testFile->hasCursorMarker() - ? testFile->m_cursorPosition : 0; - testFile->m_editor->setCursorPosition(cursorPosition); - - // Rehighlight - waitForRehighlightedSemanticDocument(testFile->m_editorWidget); - } - - // Enforce the default cpp code style, so we are independent of config file settings. - // This is needed by e.g. the GenerateGetterSetter quick fix. - m_cppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle(); - QVERIFY(m_cppCodeStylePreferences); - m_cppCodeStylePreferencesOriginalDelegateId = m_cppCodeStylePreferences->currentDelegateId(); - m_cppCodeStylePreferences->setCurrentDelegate("qt"); - - // Run the fix in the file having the cursor marker - QuickFixTestDocument::Ptr testFile; - foreach (const QuickFixTestDocument::Ptr file, m_testFiles) { - if (file->hasCursorMarker()) - testFile = file; - } - QVERIFY2(testFile, "No test file with cursor marker found"); - - if (QuickFixOperation::Ptr fix = getFix(factory, testFile->m_editorWidget, resultIndex)) - fix->perform(); - else + // Perform operation if there is one + CppQuickFixInterface quickFixInterface(m_documentWithMarker->m_editorWidget, ExplicitlyInvoked); + TextEditor::QuickFixOperations operations; + factory->match(quickFixInterface, operations); + if (operations.isEmpty()) { qDebug() << "Quickfix was not triggered"; + return; + } + + QVERIFY(operationIndex < operations.size()); + const QuickFixOperation::Ptr operation = operations.at(operationIndex); + operation->perform(); // Compare all files - foreach (const QuickFixTestDocument::Ptr testFile, m_testFiles) { + foreach (const QuickFixTestDocument::Ptr testFile, m_testDocuments) { // Check QString result = testFile->m_editorWidget->document()->toPlainText(); removeTrailingWhitespace(result); @@ -203,27 +235,34 @@ QuickFixTestCase::QuickFixTestCase(const QList &theTe } } -QuickFixTestCase::~QuickFixTestCase() +void QuickFixOperationTest::run(const QList &testDocuments, + CppQuickFixFactory *factory, + const QString &headerPath, + int operationIndex) { - // Restore default cpp code style - if (m_cppCodeStylePreferences) - m_cppCodeStylePreferences->setCurrentDelegate(m_cppCodeStylePreferencesOriginalDelegateId); - - // Restore include paths - if (m_restoreHeaderPaths) - m_modelManager->setHeaderPaths(m_headerPathsToRestore); - - // Remove created files from file system - foreach (const QuickFixTestDocument::Ptr &testDocument, m_testFiles) - QVERIFY(QFile::remove(testDocument->filePath())); + ProjectPart::HeaderPaths headerPaths; + headerPaths += ProjectPart::HeaderPath(headerPath, ProjectPart::HeaderPath::IncludePath); + QuickFixOperationTest(testDocuments, factory, headerPaths, operationIndex); } -void QuickFixTestCase::run(const QList &theTestFiles, - CppQuickFixFactory *factory, const QString &incPath, int resultIndex) +QuickFixOfferedOperationsTest::QuickFixOfferedOperationsTest( + const QList &testDocuments, + CppQuickFixFactory *factory, + const ProjectPart::HeaderPaths &headerPaths, + const QStringList &expectedOperations) + : BaseQuickFixTestCase(testDocuments, headerPaths) { - ProjectPart::HeaderPaths hps; - hps += ProjectPart::HeaderPath(incPath, ProjectPart::HeaderPath::IncludePath); - QuickFixTestCase(theTestFiles, factory, hps, resultIndex); + // Get operations + CppQuickFixInterface quickFixInterface(m_documentWithMarker->m_editorWidget, ExplicitlyInvoked); + TextEditor::QuickFixOperations actualOperations; + factory->match(quickFixInterface, actualOperations); + + // Convert to QStringList + QStringList actualOperationsAsStringList; + foreach (const QuickFixOperation::Ptr &operation, actualOperations) + actualOperationsAsStringList << operation->description(); + + QCOMPARE(actualOperationsAsStringList, expectedOperations); } /// Delegates directly to AddIncludeForUndefinedIdentifierOp for easier testing. @@ -242,16 +281,6 @@ private: const QString m_include; }; -/// Apply the factory on the source and get back the resultIndex'th result or a null pointer. -QSharedPointer QuickFixTestCase::getFix( - CppQuickFixFactory *factory, CppEditorWidget *editorWidget, int resultIndex) -{ - CppQuickFixInterface qfi(editorWidget, ExplicitlyInvoked); - TextEditor::QuickFixOperations results; - factory->match(qfi, results); - return results.isEmpty() ? QuickFixOperation::Ptr() : results.at(resultIndex); -} - } // namespace Tests } // namespace Internal @@ -1467,6 +1496,11 @@ void CppEditorPlugin::test_quickfix_data() " }\n" " f1(*str);\n" "}\n"); + + QTest::newRow("InsertQtPropertyMembers_noTriggerInvalidCode") + << CppQuickFixFactoryPtr(new InsertQtPropertyMembers) + << _("class C { @Q_PROPERTY(typeid foo READ foo) };\n") + << _(); } void CppEditorPlugin::test_quickfix() @@ -1477,7 +1511,7 @@ void CppEditorPlugin::test_quickfix() if (expected.isEmpty()) expected = original; - QuickFixTestCase(singleDocument(original, expected), factory.data()); + QuickFixOperationTest(singleDocument(original, expected), factory.data()); } /// Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix @@ -1530,7 +1564,7 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAn testFiles << QuickFixTestDocument::create("file.cpp", original, expected); GenerateGetterSetter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if definition is inserted right after class for insert definition outside @@ -1573,7 +1607,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_afterClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check from header file: If there is a source file, insert the definition in the source file. @@ -1605,7 +1639,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from header file: If there is a source file, insert the definition in the source file. @@ -1642,7 +1676,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from source file: Insert in source file, not header file. @@ -1672,7 +1706,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic3() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from header file: If the class is in a namespace, the added function definition @@ -1706,7 +1740,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from header file: If the class is in namespace N and the source file has a @@ -1744,7 +1778,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check definition insert inside class @@ -1762,7 +1796,8 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_insideClass() "};"; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), + 1); } /// Check not triggering when definition exists @@ -1776,7 +1811,8 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_notTriggeringWhenDefinitio const QByteArray expected = original; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), + 1); } /// Find right implementation file. @@ -1825,7 +1861,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFil testFiles << QuickFixTestDocument::create("file2.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Ignore generated functions declarations when looking at the surrounding @@ -1880,7 +1916,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_ignoreSurroundingGenerated testFiles << QuickFixTestDocument::create("file2.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if whitespace is respected for operator functions @@ -1904,7 +1940,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_respectWsInOperatorNames1( "}\n"; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check if whitespace is respected for operator functions @@ -1928,7 +1964,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2( "}\n"; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check if a function like macro use is not separated by the function to insert @@ -1970,7 +2006,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if a function like macro use is not separated by the function to insert @@ -2010,7 +2046,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if insertion happens before syntactically erroneous statements at end of file. @@ -2047,7 +2083,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfF testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Respect rvalue references @@ -2075,7 +2111,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_rvalueReference() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Find right implementation file. (QTCREATORBUG-10728) @@ -2114,7 +2150,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findImplementationFile() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_InsertDefFromDecl_unicodeIdentifier() @@ -2158,7 +2194,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_unicodeIdentifier() #undef TEST_UNICODE_IDENTIFIER InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } // Function for one of InsertDeclDef section cases @@ -2194,7 +2230,7 @@ void insertToSectionDeclFromDef(const QByteArray §ion, int sectionIndex) testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDeclFromDef factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), sectionIndex); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), sectionIndex); } /// Check from source file: Insert in header file. @@ -2244,7 +2280,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onSimpleNam + "/afile.cpp", original, expected); AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Cursor is on a qualified name (1) @@ -2284,7 +2320,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onNameOfQua // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQualifiedName() @@ -2323,7 +2359,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQua // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateName() @@ -2362,7 +2398,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateN // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateNameInsideArguments() @@ -2401,7 +2437,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateN // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForwardDeclaration() @@ -2444,7 +2480,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForward // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForwardDeclaration2() @@ -2487,7 +2523,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForward // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForwardHeader() @@ -2532,7 +2568,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForward // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath(), 1); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath(), 1); } /// Check: Ignore *.moc includes @@ -2557,7 +2593,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_i + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include at top for a sorted group @@ -2583,7 +2619,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_s + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include in the middle for a sorted group @@ -2609,7 +2645,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_s + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include at bottom for a sorted group @@ -2635,7 +2671,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_s + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: For an unsorted group the new include is appended @@ -2661,7 +2697,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_a + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert a local include at front if there are only global includes @@ -2688,7 +2724,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_f + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert a global include at back if there are only local includes @@ -2717,7 +2753,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_f + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Prefer group with longest matching prefix @@ -2747,7 +2783,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_p + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"prefixc.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Create a new include group if there are only include groups with a different include dir @@ -2774,7 +2810,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_n + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include dirs, sorted --> insert properly @@ -2802,7 +2838,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include dirs, unsorted --> append @@ -2830,7 +2866,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2856,7 +2892,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"z.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2882,7 +2918,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"a.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2908,7 +2944,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"lib/file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2934,7 +2970,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include @@ -2957,7 +2993,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_n + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include after include guard @@ -2987,7 +3023,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_o + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include if there is a c++ style comment on top @@ -3016,7 +3052,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_v + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include if there is a c style comment on top @@ -3049,7 +3085,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_v + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: If a "Qt Class" was not found by the locator, check the header files in the Qt @@ -3073,8 +3109,33 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_c + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalQtCoreIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalQtCoreIncludePath()); +} +void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noDoubleQtHeaderInclude() +{ + QList testFiles; + + QByteArray original; + QByteArray expected; + + const QByteArray base = TestIncludePaths::directoryOfTestFile().toUtf8(); + + // This file makes the QDir definition available so that locator finds it. + original = expected = "#include \n" + "void avoidBeingRecognizedAsForwardingHeader();"; + testFiles << QuickFixTestDocument::create(base + "/fileUsingQDir.cpp", original, expected); + + original = expected = "@QDir dir;\n"; + testFiles << QuickFixTestDocument::create(base + "/fileWantsToUseQDir.cpp", original, expected); + + ProjectPart::HeaderPaths headerPaths; + headerPaths += ProjectPart::HeaderPath(TestIncludePaths::globalQtCoreIncludePath(), + ProjectPart::HeaderPath::IncludePath); + + AddIncludeForUndefinedIdentifier factory; + const QStringList expectedOperations = QStringList() << QLatin1String("Add #include "); + QuickFixOfferedOperationsTest(testFiles, &factory, headerPaths, expectedOperations); } /// Check: Move definition from header to cpp. @@ -3117,7 +3178,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCpp() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS() @@ -3163,7 +3224,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move definition outside class @@ -3197,7 +3258,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside1() "void Foo::f4() {}\n"; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: Move definition outside class @@ -3239,7 +3300,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check: Move definition from header to cpp (with namespace). @@ -3281,7 +3342,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move definition from header to cpp (with namespace + using). @@ -3325,7 +3386,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move definition outside class with Namespace @@ -3352,7 +3413,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutsideWithNs() "\n}\n"; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: Move free function from header to cpp. @@ -3387,7 +3448,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCpp() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move free function from header to cpp (with namespace). @@ -3425,7 +3486,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move Ctor with member initialization list (QTCREATORBUG-9157). @@ -3465,7 +3526,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move Ctor with member initialization list (QTCREATORBUG-9462). @@ -3510,7 +3571,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if definition is inserted right after class for move definition outside @@ -3552,7 +3613,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_afterClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check if whitespace is respected for operator functions @@ -3574,7 +3635,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames1 ; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check if whitespace is respected for operator functions @@ -3596,7 +3657,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames2 ; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_macroUses() @@ -3628,7 +3689,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_macroUses() ; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory, + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 0, "QTCREATORBUG-12314"); } @@ -3661,7 +3722,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFunc() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncOutside() @@ -3686,7 +3747,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncOutside() "};\n\n\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS() @@ -3726,7 +3787,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing() @@ -3770,7 +3831,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNSUsing() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncOutsideWithNs() @@ -3797,7 +3858,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncOutsideWithNs() "};\n\n\n}\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCpp() @@ -3829,7 +3890,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCpp() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS() @@ -3867,7 +3928,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_CtorWithInitialization() @@ -3906,7 +3967,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_CtorWithInitialization() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Definition should not be placed behind the variable. QTCREATORBUG-10303 @@ -3932,7 +3993,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_structWithAssignedVariable "} bar;\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_macroUses() @@ -3962,7 +4023,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_macroUses() "};\n\n\n\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory, + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 0, "QTCREATORBUG-12314"); } @@ -4000,7 +4061,7 @@ void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); AssignToLocalVariable factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_typeDeduction_data() @@ -4064,7 +4125,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_typeDeduction() } ExtractLiteralAsParameter factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separateFiles() @@ -4090,7 +4151,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separ testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ExtractLiteralAsParameter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_separateFiles() @@ -4124,7 +4185,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_sep testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ExtractLiteralAsParameter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_notTriggeringForInvalidCode() @@ -4142,7 +4203,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_notTriggeringForIn testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ExtractLiteralAsParameter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectOutOfClass() @@ -4175,7 +4236,7 @@ void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectOutOfClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ConvertQt4Connect factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectWithinClass_data() @@ -4222,7 +4283,7 @@ void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectWithinClass() prefix + expected + suffix); ConvertQt4Connect factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } } // namespace Internal diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 72be61be4d1..2a7ea4c3b5b 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -44,13 +44,14 @@ namespace CppEditor { namespace Internal { namespace Tests { -/** - * Represents a test document before and after applying the quick fix. - * - * A TestDocument's source may contain an '@' character to denote - * the cursor position. This marker is removed before the Editor reads - * the document. - */ +/// +/// Represents a test document before and after applying the quick fix. +/// +/// A TestDocument's source may contain an '@' character to denote +/// the cursor position. This marker is removed before the Editor reads +/// the document. +/// + class QuickFixTestDocument : public TestDocument { public: @@ -60,37 +61,27 @@ public: const QByteArray &expectedSource); static Ptr create(const QByteArray &fileName, const QByteArray &source, - const QByteArray &expectedSource); + const QByteArray &expectedSource); public: QString m_expectedSource; }; -/** - * Encapsulates the whole process of setting up an editor, getting the - * quick-fix, applying it, and checking the result. - */ -class QuickFixTestCase : public TestCase +class BaseQuickFixTestCase : public TestCase { public: - QuickFixTestCase(const QList &theTestFiles, - CppQuickFixFactory *factory, - const CppTools::ProjectPart::HeaderPaths &includePaths = - CppTools::ProjectPart::HeaderPaths(), - int resultIndex = 0, - const QByteArray &expectedFailMessage = QByteArray()); - ~QuickFixTestCase(); + /// Exactly one QuickFixTestDocument must contain the cursor position marker '@'. + BaseQuickFixTestCase(const QList &testDocuments, + const CppTools::ProjectPart::HeaderPaths &headerPaths + = CppTools::ProjectPart::HeaderPaths()); - static void run(const QList &theTestFiles, - CppQuickFixFactory *factory, const QString &incPath, int resultIndex = 0); -private: - QSharedPointer getFix(CppQuickFixFactory *factory, - CppEditorWidget *editorWidget, - int resultIndex = 0); + ~BaseQuickFixTestCase(); + +protected: + QuickFixTestDocument::Ptr m_documentWithMarker; + QList m_testDocuments; private: - QList m_testFiles; - CppTools::CppCodeStylePreferences *m_cppCodeStylePreferences; QByteArray m_cppCodeStylePreferencesOriginalDelegateId; @@ -98,6 +89,34 @@ private: bool m_restoreHeaderPaths; }; +/// Tests a concrete QuickFixOperation of a given CppQuickFixFactory +class QuickFixOperationTest : public BaseQuickFixTestCase +{ +public: + QuickFixOperationTest(const QList &testDocuments, + CppQuickFixFactory *factory, + const CppTools::ProjectPart::HeaderPaths &headerPaths + = CppTools::ProjectPart::HeaderPaths(), + int operationIndex = 0, + const QByteArray &expectedFailMessage = QByteArray()); + + static void run(const QList &testDocuments, + CppQuickFixFactory *factory, + const QString &headerPath, + int operationIndex = 0); +}; + +/// Tests the offered operations provided by a given CppQuickFixFactory +class QuickFixOfferedOperationsTest : public BaseQuickFixTestCase +{ +public: + QuickFixOfferedOperationsTest(const QList &testDocuments, + CppQuickFixFactory *factory, + const CppTools::ProjectPart::HeaderPaths &headerPaths + = CppTools::ProjectPart::HeaderPaths(), + const QStringList &expectedOperations = QStringList()); +}; + QList singleDocument(const QByteArray &original, const QByteArray &expected); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 44e8e882780..691d7687dec 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -1866,6 +1866,13 @@ Snapshot forwardingHeaders(const CppQuickFixInterface &interface) return result; } +bool looksLikeAQtClass(const QString &identifier) +{ + return identifier.size() > 2 + && identifier.at(0) == QLatin1Char('Q') + && identifier.at(1).isUpper(); +} + } // anonymous namespace void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interface, @@ -1884,6 +1891,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa const QString currentDocumentFilePath = interface.semanticInfo().doc->fileName(); const ProjectPart::HeaderPaths headerPaths = relevantHeaderPaths(currentDocumentFilePath); + bool qtHeaderFileIncludeOffered = false; // Find an include file through the locator if (CppClassesFilter *classesFilter @@ -1906,7 +1914,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa foreach (const QString &header, headerAndItsForwardingHeaders) { const QString include = findShortestInclude(currentDocumentFilePath, header, headerPaths); - if (!include.isEmpty()) { + if (include.size() > 2) { const QString headerFileName = QFileInfo(info->fileName()).fileName(); QTC_ASSERT(!headerFileName.isEmpty(), break); @@ -1916,6 +1924,9 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa else if (headerFileName.at(1).isUpper()) priority = 1; + if (looksLikeAQtClass(include.mid(1, include.size() - 2))) + qtHeaderFileIncludeOffered = true; + result.append(new AddIncludeForUndefinedIdentifierOp(interface, priority, include)); } @@ -1926,7 +1937,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa // The header file we are looking for might not be (yet) included in any file we have parsed. // As such, it will not be findable via locator. At least for Qt classes, check also for // headers with the same name. - if (className.size() > 2 && className.at(0) == QLatin1Char('Q') && className.at(1).isUpper()) { + if (!qtHeaderFileIncludeOffered && looksLikeAQtClass(className)) { const QString include = findQtIncludeWithSameName(className, headerPaths); if (!include.isEmpty()) result.append(new AddIncludeForUndefinedIdentifierOp(interface, 1, include)); @@ -4254,7 +4265,7 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface, AST * const ast = path.last(); QtPropertyDeclarationAST *qtPropertyDeclaration = ast->asQtPropertyDeclaration(); - if (!qtPropertyDeclaration) + if (!qtPropertyDeclaration || !qtPropertyDeclaration->type_id) return; ClassSpecifierAST *klass = 0; diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index f507176cb74..866508eaab8 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -59,6 +59,7 @@ public: virtual void run() = 0; virtual void semanticRehighlight(bool force) = 0; virtual CppTools::SemanticInfo recalculateSemanticInfo() = 0; + virtual CPlusPlus::Snapshot snapshot() = 0; virtual BaseEditorDocumentParser *parser() = 0; virtual bool isParserRunning() const = 0; diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp index 3a3ee3eebb6..758c7083dbd 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp +++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp @@ -174,6 +174,11 @@ BaseEditorDocumentParser *BuiltinEditorDocumentProcessor::parser() return &m_parser; } +CPlusPlus::Snapshot BuiltinEditorDocumentProcessor::snapshot() +{ + return m_parser.snapshot(); +} + void BuiltinEditorDocumentProcessor::semanticRehighlight(bool force) { const auto source = createSemanticInfoSource(force); diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.h b/src/plugins/cpptools/builtineditordocumentprocessor.h index a0901181200..69f6148322b 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.h +++ b/src/plugins/cpptools/builtineditordocumentprocessor.h @@ -37,7 +37,6 @@ #include "cpptools_global.h" #include "semantichighlighter.h" - namespace CppTools { class CPPTOOLS_EXPORT BuiltinEditorDocumentProcessor : public BaseEditorDocumentProcessor @@ -55,6 +54,7 @@ public: void semanticRehighlight(bool force) Q_DECL_OVERRIDE; CppTools::SemanticInfo recalculateSemanticInfo() Q_DECL_OVERRIDE; BaseEditorDocumentParser *parser() Q_DECL_OVERRIDE; + CPlusPlus::Snapshot snapshot() Q_DECL_OVERRIDE; bool isParserRunning() const Q_DECL_OVERRIDE; private: diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index dfc1ed0d0d7..b4065f13289 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -946,7 +946,8 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers() QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1); QVERIFY(mm->isCppEditor(editor)); - BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName); + auto *parser = BuiltinEditorDocumentParser::get(fileName); + QVERIFY(parser); parser->setUsePrecompiledHeaders(true); parser->update(mm->workingCopy()); diff --git a/src/plugins/cpptools/cppsourceprocessor_test.cpp b/src/plugins/cpptools/cppsourceprocessor_test.cpp index f4a03a2501c..70a98bed2c2 100644 --- a/src/plugins/cpptools/cppsourceprocessor_test.cpp +++ b/src/plugins/cpptools/cppsourceprocessor_test.cpp @@ -30,7 +30,7 @@ #include "cpptoolsplugin.h" -#include "builtineditordocumentparser.h" +#include "baseeditordocumentprocessor.h" #include "cppmodelmanager.h" #include "cppsourceprocessertesthelper.h" #include "cppsourceprocessor.h" @@ -143,9 +143,9 @@ void CppToolsPlugin::test_cppsourceprocessor_includes_cyclic() // Check editor snapshot const QString filePath = editor->document()->filePath(); - BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(filePath); - QVERIFY(parser); - Snapshot snapshot = parser->snapshot(); + auto *processor = BaseEditorDocumentProcessor::get(filePath); + QVERIFY(processor); + Snapshot snapshot = processor->snapshot(); QCOMPARE(snapshot.size(), 3); // Configuration file included // Check includes diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index fc3c40f2310..103ee14a2a4 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -783,7 +783,9 @@ static QByteArray msvcRunTime(const Abi::OSFlavor flavour) case Abi::WindowsMsvc2010Flavor: return "MSVCR100"; case Abi::WindowsMsvc2012Flavor: - return "MSVCR110"; // #FIXME: VS2012 beta, will probably be 12 in final? + return "MSVCR110"; + case Abi::WindowsMsvc2013Flavor: + return "MSVCR120"; default: break; } diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 9c767602c22..ad1a86ea107 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -878,6 +878,7 @@ void DebuggerEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &re } } else { + d->setRemoteSetupState(RemoteSetupFailed); showMessage(_("NOTE: REMOTE SETUP FAILED: ") + result.reason); } } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 54a429933df..fcba0c320cd 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1292,6 +1292,14 @@ void GdbEngine::handleExecuteJumpToLine(const GdbResponse &response) // All is fine. Waiting for a *running // and the temporary breakpoint to be hit. notifyInferiorRunOk(); // Only needed for gdb < 7.0. + } else if (response.resultClass == GdbResultError) { + // Could be "Unreasonable jump request" or similar. + QString out = tr("Cannot jump. Stopped"); + QByteArray msg = response.data["msg"].data(); + if (!msg.isEmpty()) + out += QString::fromLatin1(". " + msg); + showStatusMessage(out); + notifyInferiorRunFailed(); } else if (response.resultClass == GdbResultDone) { // This happens on old gdb. Trigger the effect of a '*stopped'. showStatusMessage(tr("Jumped. Stopped")); @@ -2374,6 +2382,8 @@ void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt) response.condition = child.data(); } else if (child.hasName("enabled")) { response.enabled = (child.data() == "y"); + } else if (child.hasName("disp")) { + response.oneShot = child.data() == "del"; } else if (child.hasName("pending")) { // Any content here would be interesting only if we did accept // spontaneously appearing breakpoints (user using gdb commands). diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index bbadd161a94..7efd0ace733 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -1176,6 +1176,8 @@ void QmlEngine::updateCurrentContext() context = grandParentData->name; } + synchronizeWatchers(); + QmlJS::ConsoleManagerInterface *consoleManager = qmlConsoleManager(); if (consoleManager) consoleManager->setContext(tr("Context:") + QLatin1Char(' ') + context); diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index 8b0c93cb8ef..1de81dbdbf6 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -135,7 +135,6 @@ public: QList debuggerCommands; //Cache - QStringList watchedExpressions; QList currentFrameScopes; QHash stackIndexLookup; @@ -722,9 +721,7 @@ QmlV8ObjectData extractData(const QVariant &data, const QVariant &refsVal) void QmlV8DebuggerClientPrivate::clearCache() { - watchedExpressions.clear(); currentFrameScopes.clear(); - evaluatingExpression.clear(); updateLocalsAndWatchers.clear(); } @@ -958,15 +955,12 @@ void QmlV8DebuggerClient::synchronizeWatchers(const QStringList &watchers) { SDEBUG(watchers); foreach (const QString &exp, watchers) { - if (!d->watchedExpressions.contains(exp)) { - StackHandler *stackHandler = d->engine->stackHandler(); - if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { - d->evaluate(exp, false, false, stackHandler->currentIndex()); - d->evaluatingExpression.insert(d->sequence, exp); - } + StackHandler *stackHandler = d->engine->stackHandler(); + if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { + d->evaluate(exp, false, false, stackHandler->currentIndex()); + d->evaluatingExpression.insert(d->sequence, exp); } } - d->watchedExpressions = watchers; } void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId) diff --git a/src/plugins/designer/gotoslot_test.cpp b/src/plugins/designer/gotoslot_test.cpp index fde64684332..54950c6907d 100644 --- a/src/plugins/designer/gotoslot_test.cpp +++ b/src/plugins/designer/gotoslot_test.cpp @@ -196,9 +196,14 @@ public: } // Compare - const Document::Ptr cppDocument = BuiltinEditorDocumentParser::get(cppFile)->document(); + BuiltinEditorDocumentParser *cppDocumentParser = BuiltinEditorDocumentParser::get(cppFile); + QVERIFY(cppDocumentParser); + const Document::Ptr cppDocument = cppDocumentParser->document(); QVERIFY(checkDiagsnosticMessages(cppDocument)); - const Document::Ptr hDocument = BuiltinEditorDocumentParser::get(hFile)->document(); + + BuiltinEditorDocumentParser *hDocumentParser = BuiltinEditorDocumentParser::get(hFile); + QVERIFY(hDocumentParser); + const Document::Ptr hDocument = hDocumentParser->document(); QVERIFY(checkDiagsnosticMessages(hDocument)); QVERIFY(documentContainsFunctionDefinition(cppDocument, diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index 8530a41832b..a55a1af0c44 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -369,8 +369,6 @@ void IosConfigurations::initialize() { QTC_CHECK(m_instance == 0); m_instance = new IosConfigurations(0); - m_instance->updateSimulators(); - QTimer::singleShot(10000, IosDeviceManager::instance(), SLOT(monitorAvailableDevices())); } bool IosConfigurations::ignoreAllDevices() @@ -429,10 +427,15 @@ void IosConfigurations::updateSimulators() void IosConfigurations::setDeveloperPath(const FileName &devPath) { + static bool hasDevPath = false; if (devPath != m_instance->m_developerPath) { m_instance->m_developerPath = devPath; m_instance->save(); - updateAutomaticKitList(); + if (!hasDevPath && !devPath.isEmpty()) { + hasDevPath = true; + QTimer::singleShot(1000, IosDeviceManager::instance(), SLOT(monitorAvailableDevices())); + m_instance->updateSimulators(); + } emit m_instance->updated(); } } diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 64305e9d2e7..db9675030db 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -1206,11 +1206,10 @@ IEditor *PerforcePlugin::showOutputInEditor(const QString &title, << "Size= " << output.size() << " Type=" << editorType << debugCodec(codec); QString s = title; QString content = output; - const int maxSize = EditorManager::maxTextFileSize() - 1000; + const int maxSize = EditorManager::maxTextFileSize() / 2 - 1000; // ~25 MB, 600000 lines if (content.size() >= maxSize) { - content = tr("[Only %1 MB of output shown]").arg(maxSize / 1024 / 1024) + QLatin1Char('\n') - + content.right(maxSize); - + content = content.left(maxSize); + content += QLatin1Char('\n') + tr("[Only %1 MB of output shown]").arg(maxSize / 1024 / 1024); } IEditor *editor = EditorManager::openEditorWithContents(id, &s, content.toUtf8()); QTC_ASSERT(editor, return 0); diff --git a/src/plugins/projectexplorer/environmentwidget.cpp b/src/plugins/projectexplorer/environmentwidget.cpp index 10074936e92..094f9ecb749 100644 --- a/src/plugins/projectexplorer/environmentwidget.cpp +++ b/src/plugins/projectexplorer/environmentwidget.cpp @@ -128,13 +128,12 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, QWidget *additionalDetails d->m_unsetButton->setText(tr("&Unset")); buttonLayout->addWidget(d->m_unsetButton); - QSpacerItem *verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); - buttonLayout->addItem(verticalSpacer); - d->m_batchEditButton = new QPushButton(this); d->m_batchEditButton->setText(tr("&Batch Edit...")); buttonLayout->addWidget(d->m_batchEditButton); + buttonLayout->addStretch(); + horizontalLayout->addLayout(buttonLayout); vbox2->addLayout(horizontalLayout); diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index 4f93eb55fc9..ab986509b4a 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -141,7 +141,9 @@ KitManagerConfigWidget::~KitManagerConfigWidget() QString KitManagerConfigWidget::displayName() const { - return m_displayName; + if (m_cachedDisplayName.isEmpty()) + m_cachedDisplayName = m_modifiedKit->displayName(); + return m_cachedDisplayName; } void KitManagerConfigWidget::apply() @@ -175,7 +177,7 @@ void KitManagerConfigWidget::discard() } m_iconButton->setIcon(m_modifiedKit->icon()); m_nameEdit->setText(m_modifiedKit->unexpandedDisplayName()); - m_displayName = m_modifiedKit->displayName(); + m_cachedDisplayName.clear(); m_fileSystemFriendlyNameLineEdit->setText(m_modifiedKit->customFileSystemFriendlyName()); emit dirty(); } @@ -315,9 +317,9 @@ void KitManagerConfigWidget::setIcon() void KitManagerConfigWidget::setDisplayName() { int pos = m_nameEdit->cursorPosition(); + m_cachedDisplayName.clear(); m_modifiedKit->setUnexpandedDisplayName(m_nameEdit->text()); m_nameEdit->setCursorPosition(pos); - m_displayName = m_modifiedKit->displayName(); } void KitManagerConfigWidget::setFileSystemFriendlyName() @@ -339,11 +341,11 @@ void KitManagerConfigWidget::workingCopyWasUpdated(Kit *k) foreach (KitConfigWidget *w, m_widgets) w->refresh(); + m_cachedDisplayName.clear(); + if (k->unexpandedDisplayName() != m_nameEdit->text()) m_nameEdit->setText(k->unexpandedDisplayName()); - m_displayName = k->displayName(); - m_fileSystemFriendlyNameLineEdit->setText(k->customFileSystemFriendlyName()); m_iconButton->setIcon(k->icon()); updateVisibility(); diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.h b/src/plugins/projectexplorer/kitmanagerconfigwidget.h index 51651c75c36..e7b5dddc3ab 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.h +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.h @@ -109,7 +109,7 @@ private: bool m_hasUniqueName; QPixmap m_background; QList m_actions; - QString m_displayName; + mutable QString m_cachedDisplayName; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/targetsettingswidget.cpp b/src/plugins/projectexplorer/targetsettingswidget.cpp index 6ea3ceaeac5..5afbcd2eb89 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.cpp +++ b/src/plugins/projectexplorer/targetsettingswidget.cpp @@ -31,6 +31,8 @@ #include "targetsettingswidget.h" #include "ui_targetsettingswidget.h" +#include + #include using namespace ProjectExplorer::Internal; @@ -41,9 +43,15 @@ TargetSettingsWidget::TargetSettingsWidget(QWidget *parent) : m_targetSelector(new TargetSelector(this)) { ui->setupUi(this); - ui->header->setStyleSheet(QLatin1String("QWidget#header {" - "border-image: url(:/projectexplorer/images/targetseparatorbackground.png) 43 0 0 0 repeat;" - "}")); + + if (Utils::creatorTheme()->widgetStyle() == Utils::Theme::StyleFlat) { + ui->separator->setVisible(false); + ui->shadow->setVisible(false); + } else { + ui->header->setStyleSheet(QLatin1String("QWidget#header {" + "border-image: url(:/projectexplorer/images/targetseparatorbackground.png) 43 0 0 0 repeat;" + "}")); + } QHBoxLayout *headerLayout = new QHBoxLayout; headerLayout->setContentsMargins(5, 3, 0, 0); diff --git a/src/plugins/projectexplorer/targetsetupwidget.cpp b/src/plugins/projectexplorer/targetsetupwidget.cpp index 8d1ef537fee..95c06fdb2dc 100644 --- a/src/plugins/projectexplorer/targetsetupwidget.cpp +++ b/src/plugins/projectexplorer/targetsetupwidget.cpp @@ -232,7 +232,7 @@ void TargetSetupWidget::manageKit() page->showKit(m_kit); Core::ICore::showOptionsDialog(Constants::PROJECTEXPLORER_SETTINGS_CATEGORY, Constants::KITS_SETTINGS_PAGE_ID, - this); + this->parentWidget()); } void TargetSetupWidget::setProjectPath(const QString &projectPath) diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 0d2f3836f1b..bc43f4bf8a6 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -66,7 +66,7 @@ const char QMAKE_BS_ID[] = "QtProjectManager.QMakeBuildStep"; const char QMAKE_ARGUMENTS_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeArguments"; const char QMAKE_FORCED_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeForced"; -const char QMAKE_USE_qtQuickCompiler[] = "QtProjectManager.QMakeBuildStep.UseqtQuickCompiler"; +const char QMAKE_USE_QTQUICKCOMPILER[] = "QtProjectManager.QMakeBuildStep.UseQtQuickCompiler"; const char QMAKE_QMLDEBUGLIBAUTO_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto"; const char QMAKE_QMLDEBUGLIB_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary"; } @@ -178,7 +178,7 @@ QStringList QMakeStep::deducedArguments() QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); arguments << QmakeBuildConfiguration::deduceArgumnetsForTargetAbi(targetAbi, version); - if (linkQmlDebuggingLibrary() && version) { + if (linkQmlDebuggingLibrary() && version && !useQtQuickCompiler()) { arguments << QLatin1String(Constants::QMAKEVAR_QUICK1_DEBUG); if (version->qtVersion().majorVersion >= 5) arguments << QLatin1String(Constants::QMAKEVAR_QUICK2_DEBUG); @@ -377,9 +377,6 @@ void QMakeStep::setLinkQmlDebuggingLibrary(bool enable) bool QMakeStep::useQtQuickCompiler() const { - const Core::Context languages = project()->projectLanguages(); - if (!languages.contains(ProjectExplorer::Constants::LANG_QMLJS)) - return false; return m_useQtQuickCompiler; } @@ -430,7 +427,7 @@ QVariantMap QMakeStep::toMap() const map.insert(QLatin1String(QMAKE_QMLDEBUGLIBAUTO_KEY), m_linkQmlDebuggingLibrary == DebugLink); map.insert(QLatin1String(QMAKE_QMLDEBUGLIB_KEY), m_linkQmlDebuggingLibrary == DoLink); map.insert(QLatin1String(QMAKE_FORCED_KEY), m_forced); - map.insert(QLatin1String(QMAKE_USE_qtQuickCompiler), m_useQtQuickCompiler); + map.insert(QLatin1String(QMAKE_USE_QTQUICKCOMPILER), m_useQtQuickCompiler); return map; } @@ -438,7 +435,7 @@ bool QMakeStep::fromMap(const QVariantMap &map) { m_userArgs = map.value(QLatin1String(QMAKE_ARGUMENTS_KEY)).toString(); m_forced = map.value(QLatin1String(QMAKE_FORCED_KEY), false).toBool(); - m_useQtQuickCompiler = map.value(QLatin1String(QMAKE_USE_qtQuickCompiler), false).toBool(); + m_useQtQuickCompiler = map.value(QLatin1String(QMAKE_USE_QTQUICKCOMPILER), false).toBool(); if (map.value(QLatin1String(QMAKE_QMLDEBUGLIBAUTO_KEY), false).toBool()) { m_linkQmlDebuggingLibrary = DebugLink; } else { @@ -524,6 +521,7 @@ void QMakeStepConfigWidget::qtVersionChanged() updateSummaryLabel(); updateEffectiveQMakeCall(); updateQmlDebuggingOption(); + updateQtQuickCompilerOption(); } void QMakeStepConfigWidget::qmakeBuildConfigChanged() @@ -561,11 +559,11 @@ void QMakeStepConfigWidget::useQtQuickCompilerChanged() { if (m_ignoreChange) return; -// m_ui->qtQuickCompilerCheckBox->setChecked(m_step->useQtQuickCompiler()); updateSummaryLabel(); updateEffectiveQMakeCall(); updateQtQuickCompilerOption(); + updateQmlDebuggingOption(); } void QMakeStepConfigWidget::qmakeArgumentsLineEdited() @@ -633,6 +631,7 @@ void QMakeStepConfigWidget::useQtQuickCompilerChecked(bool checked) updateSummaryLabel(); updateEffectiveQMakeCall(); + updateQmlDebuggingOption(); updateQtQuickCompilerOption(); } @@ -654,7 +653,9 @@ void QMakeStepConfigWidget::updateQmlDebuggingOption() { QString warningText; bool supported = QtSupport::BaseQtVersion::isQmlDebuggingSupported(m_step->target()->kit(), - &warningText); + &warningText) + && !m_step->useQtQuickCompiler(); + m_ui->qmlDebuggingLibraryCheckBox->setEnabled(supported); m_ui->debuggingLibraryLabel->setText(tr("Enable QML debugging:")); diff --git a/src/plugins/qmlprofiler/qml/CategoryLabel.qml b/src/plugins/qmlprofiler/qml/CategoryLabel.qml index 75e3d2b02d9..de5f6f7d2c1 100644 --- a/src/plugins/qmlprofiler/qml/CategoryLabel.qml +++ b/src/plugins/qmlprofiler/qml/CategoryLabel.qml @@ -98,7 +98,7 @@ Item { id: dragArea anchors.fill: txt drag.target: dragger - cursorShape: dragging ? Qt.DragMoveCursor : Qt.OpenHandCursor + cursorShape: dragging ? Qt.ClosedHandCursor : Qt.OpenHandCursor } DropArea { diff --git a/src/plugins/qmlprofiler/timelinerenderer.cpp b/src/plugins/qmlprofiler/timelinerenderer.cpp index 5be5eab7559..f71a62bc804 100644 --- a/src/plugins/qmlprofiler/timelinerenderer.cpp +++ b/src/plugins/qmlprofiler/timelinerenderer.cpp @@ -371,6 +371,8 @@ void TimelineRenderer::drawNotes(QPainter *p) if (managerIndex == -1) continue; int modelIndex = m_profilerModelProxy->modelIndexFromManagerIndex(managerIndex); + if (m_profilerModelProxy->hidden(modelIndex)) + continue; int eventIndex = notes->timelineIndex(i); int row = m_profilerModelProxy->row(modelIndex, eventIndex); int rowHeight = m_profilerModelProxy->rowHeight(modelIndex, row); diff --git a/src/plugins/qnx/qnxdeviceconfiguration.cpp b/src/plugins/qnx/qnxdeviceconfiguration.cpp index 3305959bcd5..2224a44e752 100644 --- a/src/plugins/qnx/qnxdeviceconfiguration.cpp +++ b/src/plugins/qnx/qnxdeviceconfiguration.cpp @@ -39,20 +39,62 @@ #include #include #include +#include #include #include #include #include -using namespace Qnx; -using namespace Qnx::Internal; +using namespace ProjectExplorer; +using namespace Utils; + +namespace Qnx { +namespace Internal { -namespace { const char QnxVersionKey[] = "QnxVersion"; const char DeployQtLibrariesActionId [] = "Qnx.Qnx.DeployQtLibrariesAction"; + +static int pidFileCounter = 0; + +QnxDeviceProcess::QnxDeviceProcess(const QSharedPointer &device, QObject *parent) + : SshDeviceProcess(device, parent) +{ + setEnvironment(Environment(OsTypeLinux)); + m_pidFile = QString::fromLatin1("/var/run/qtc.%1.pid").arg(++pidFileCounter); } +QString QnxDeviceProcess::fullCommandLine() const +{ + QStringList args = arguments(); + args.prepend(executable()); + QString cmd = QtcProcess::Arguments::createUnixArgs(args).toString(); + + QString fullCommandLine = QLatin1String( + "test -f /etc/profile && . /etc/profile ; " + "test -f $HOME/profile && . $HOME/profile ; " + ); + + if (!m_workingDir.isEmpty()) + fullCommandLine += QString::fromLatin1("cd %1 ; ").arg(QtcProcess::quoteArg(m_workingDir)); + + for (auto it = environment().constBegin(); it != environment().constEnd(); ++it) + fullCommandLine += QString::fromLatin1("%1='%2' ").arg(it.key()).arg(it.value()); + + fullCommandLine += QString::fromLatin1("%1 & echo $! > %2").arg(cmd).arg(m_pidFile); + + return fullCommandLine; +} + +void QnxDeviceProcess::doSignal(int sig) +{ + auto signaler = new SshDeviceProcess(device(), this); + QString cmd = QString::fromLatin1("kill -%2 `cat %1`").arg(m_pidFile).arg(sig); + connect(signaler, &SshDeviceProcess::finished, signaler, &QObject::deleteLater); + signaler->start(cmd, QStringList()); +} + + class QnxPortsGatheringMethod : public ProjectExplorer::PortsGatheringMethod { // TODO: The command is probably needlessly complicated because the parsing method @@ -196,6 +238,11 @@ ProjectExplorer::DeviceTester *QnxDeviceConfiguration::createDeviceTester() cons return new QnxDeviceTester; } +ProjectExplorer::DeviceProcess *QnxDeviceConfiguration::createProcess(QObject *parent) const +{ + return new QnxDeviceProcess(sharedFromThis(), parent); +} + QList QnxDeviceConfiguration::actionIds() const { QList actions = RemoteLinux::LinuxDevice::actionIds(); @@ -228,3 +275,6 @@ ProjectExplorer::DeviceProcessSignalOperation::Ptr QnxDeviceConfiguration::signa return ProjectExplorer::DeviceProcessSignalOperation::Ptr( new QnxDeviceProcessSignalOperation(sshParameters())); } + +} // namespace Internal +} // namespace Qnx diff --git a/src/plugins/qnx/qnxdeviceconfiguration.h b/src/plugins/qnx/qnxdeviceconfiguration.h index 9f95be2d84d..1fe3aedb53a 100644 --- a/src/plugins/qnx/qnxdeviceconfiguration.h +++ b/src/plugins/qnx/qnxdeviceconfiguration.h @@ -34,10 +34,29 @@ #define QNX_INTERNAL_QNXDEVICECONFIGURATION_H #include +#include namespace Qnx { namespace Internal { +class QnxDeviceProcess : public ProjectExplorer::SshDeviceProcess +{ +public: + QnxDeviceProcess(const QSharedPointer &device, QObject *parent); + + void setWorkingDirectory(const QString &directory) { m_workingDir = directory; } + + void interrupt() { doSignal(2); } + void terminate() { doSignal(15); } + void kill() { doSignal(9); } + QString fullCommandLine() const; + +private: + void doSignal(int sig); + QString m_pidFile; + QString m_workingDir; +}; + class QnxDeviceConfiguration : public RemoteLinux::LinuxDevice { Q_DECLARE_TR_FUNCTIONS(Qnx::Internal::QnxDeviceConfiguration) @@ -56,6 +75,7 @@ public: ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const; ProjectExplorer::DeviceTester *createDeviceTester() const; + ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const; QList actionIds() const; QString displayNameForActionId(Core::Id actionId) const; diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index 5a33a467754..e24a5ee66a1 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -32,7 +32,8 @@ #include "slog2inforunner.h" -#include +#include "qnxdeviceconfiguration.h" + #include using namespace Qnx; @@ -48,13 +49,13 @@ Slog2InfoRunner::Slog2InfoRunner(const QString &applicationId, const RemoteLinux // We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info. m_applicationId.truncate(63); - m_testProcess = new ProjectExplorer::SshDeviceProcess(device, this); + m_testProcess = new QnxDeviceProcess(device, this); connect(m_testProcess, SIGNAL(finished()), this, SLOT(handleTestProcessCompleted())); m_launchDateTimeProcess = new ProjectExplorer::SshDeviceProcess(device, this); connect(m_launchDateTimeProcess, SIGNAL(finished()), this, SLOT(launchSlog2Info())); - m_logProcess = new ProjectExplorer::SshDeviceProcess(device, this); + m_logProcess = new QnxDeviceProcess(device, this); connect(m_logProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readLogStandardOutput())); connect(m_logProcess, SIGNAL(readyReadStandardError()), this, SLOT(readLogStandardError())); connect(m_logProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleLogError())); diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index bf89085e572..0038fa3eab6 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1556,6 +1556,13 @@ bool BaseQtVersion::isQtQuickCompilerSupported(QString *reason) const return false; } + const QString qtQuickCompilerExecutable = + HostOsInfo::withExecutableSuffix(binPath().toString() + QLatin1String("/qtquickcompiler")); + if (!QFileInfo::exists(qtQuickCompilerExecutable)) { + // TODO: Add reason string in master + return false; + } + return true; } diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 4062b9d366e..69e357a1f76 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -7077,6 +7077,12 @@ void TextEditorWidget::inSnippetMode(bool *active) void TextEditorWidget::invokeAssist(AssistKind kind, IAssistProvider *provider) { + if (kind == QuickFix && d->m_snippetOverlay->isVisible()) { + d->m_snippetOverlay->setVisible(false); + d->m_snippetOverlay->mangle(); + d->m_snippetOverlay->clear(); + } + bool previousMode = overwriteMode(); setOverwriteMode(false); ensureCursorVisible(); diff --git a/src/plugins/valgrind/memcheckerrorview.cpp b/src/plugins/valgrind/memcheckerrorview.cpp index c3365105d47..7a4ebf57e98 100644 --- a/src/plugins/valgrind/memcheckerrorview.cpp +++ b/src/plugins/valgrind/memcheckerrorview.cpp @@ -137,7 +137,8 @@ static QString relativeToPath() } static QString errorLocation(const QModelIndex &index, const Error &error, - bool link = false, const QString &linkAttr = QString()) + bool link = false, bool absolutePath = false, + const QString &linkAttr = QString()) { if (!index.isValid()) return QString(); @@ -149,8 +150,9 @@ static QString errorLocation(const QModelIndex &index, const Error &error, } QTC_ASSERT(model, return QString()); + const QString relativePath = absolutePath ? QString() : relativeToPath(); return QCoreApplication::translate("Valgrind::Internal", "in %1"). - arg(makeFrameName(model->findRelevantFrame(error), relativeToPath(), + arg(makeFrameName(model->findRelevantFrame(error), relativePath, link, linkAttr)); } @@ -181,7 +183,9 @@ QWidget *MemcheckErrorDelegate::createDetailsWidget(const QFont & font, p.setBrush(QPalette::Text, p.highlightedText()); errorLabel->setPalette(p); errorLabel->setText(QString::fromLatin1("%1  %2") - .arg(error.what(), errorLocation(errorIndex, error, true, linkStyle), + .arg(error.what(), + errorLocation(errorIndex, error, /*link=*/ true, + /*absolutePath=*/ false, linkStyle), linkStyle)); connect(errorLabel, &QLabel::linkActivated, this, &MemcheckErrorDelegate::openLinkInEditor); @@ -265,17 +269,16 @@ void MemcheckErrorDelegate::copy() const Error error = m_detailsIndex.data(ErrorListModel::ErrorRole).value(); stream << error.what() << "\n"; - stream << " " << errorLocation(m_detailsIndex, error) << "\n"; - - const QString relativeTo = relativeToPath(); + stream << " " + << errorLocation(m_detailsIndex, error, /*link=*/ false, /*absolutePath=*/ true) + << "\n"; foreach (const Stack &stack, error.stacks()) { if (!stack.auxWhat().isEmpty()) stream << stack.auxWhat(); int i = 1; - foreach (const Frame &frame, stack.frames()) { - stream << " " << i++ << ": " << makeFrameName(frame, relativeTo) << "\n"; - } + foreach (const Frame &frame, stack.frames()) + stream << " " << i++ << ": " << makeFrameName(frame, QString(), false) << "\n"; } stream.flush(); diff --git a/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir b/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir index fef83a9cfe6..8710edd2d37 100644 --- a/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir +++ b/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir @@ -1 +1,4 @@ // comment + +class QDir {}; + diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index c7b2ca77731..f055f9a3afc 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -935,6 +935,7 @@ void tst_Dumpers::initTestCase() } else if (m_debuggerEngine == CdbEngine) { setupCdb(&m_makeBinary, &m_env); } else if (m_debuggerEngine == LldbEngine) { + qDebug() << "Dumper dir : " << DUMPERDIR; QProcess debugger; QString cmd = QString::fromUtf8(m_debuggerBinary + " -v"); debugger.start(cmd); @@ -1440,7 +1441,10 @@ void tst_Dumpers::dumper_data() "public:\n" " Foo(int i = 0)\n" " : a(i), b(2)\n" - " {}\n" + " {\n" + " for (int j = 0; j < 6; ++j)\n" + " x[j] = 'a' + j;\n" + " }\n" " virtual ~Foo()\n" " {\n" " a = 5;\n" @@ -3307,7 +3311,7 @@ void tst_Dumpers::dumper_data() //+ Check("var72", "", "@QVariant (QRegion)") FIXME + Check("var73", "", "@QVariant (QBitmap)") + Check("var74", "", "@QVariant (QCursor)") - + Check("var75", "", "@QVariant (QKeySequence)") + + Check("var75", "", "@QVariant (QKeySequence)") % NoLldbEngine // FIXME + Check("var76", "", "@QVariant (QPen)") + Check("var77", "", "@QVariant (QTextLength)") //+ Check("var78", Value5(""), "@QVariant (QTextFormat)") @@ -4848,7 +4852,8 @@ void tst_Dumpers::dumper_data() "#include \n" "using namespace std;\n" - "string fooxx() { return \"bababa\"; }\n", + "string fooxx() { return \"bababa\"; }\n" + + fooData, "int a1 = 43;\n" "const int &b1 = a1;\n" @@ -4868,7 +4873,13 @@ void tst_Dumpers::dumper_data() "const QString &b3 = a3;\n" "typedef QString &Ref3;\n" "const Ref3 d3 = const_cast(a3);\n" - "unused(&a3, &b3, &d3);\n") + "unused(&a3, &b3, &d3);\n\n" + + "Foo a4(12);\n" + "const Foo &b4 = a4;\n" + "typedef Foo &Ref4;\n" + "const Ref4 d4 = const_cast(a4);\n" + "unused(&a4, &b4, &d4);\n") + CoreProfile() @@ -4880,12 +4891,18 @@ void tst_Dumpers::dumper_data() + Check("a2", "\"hello\"", "std::string") + Check("b2", "\"bababa\"", Pattern("(std::)?string &")) // Clang... + Check("c2", "\"world\"", "std::string") - + Check("d2", "\"hello\"", "Ref2") + + Check("d2", "\"hello\"", "Ref2") % NoLldbEngine + Check("a3", "\"hello\"", "@QString") + Check("b3", "\"hello\"", "@QString &") - + Check("d3", "\"hello\"", "Ref3"); + + Check("d3", "\"hello\"", "Ref3") + + Check("a4", "", "Foo") + + Check("a4.a", "12", "int") + + Check("b4", "", "Foo &") + + Check("b4.a", "12", "int") + //+ Check("d4", "\"hello\"", "Ref4"); FIXME: We get "Foo &" instead + + Check("d4.a", "12", "int"); QTest::newRow("DynamicReference") << Data("struct BaseClass { virtual ~BaseClass() {} };\n" @@ -4966,6 +4983,8 @@ void tst_Dumpers::dumper_data() << Data(fooData + "void testPassByReference(Foo &f) {\n" " BREAK;\n" + " int dummy = 2;\n" + " unused(&f, &dummy);\n" "}\n", "Foo f(12);\n" "testPassByReference(f);\n")