Merge remote-tracking branch 'origin/3.6'

Change-Id: Ibee24c1c80984cdc45e7bcf3e4fbb5f1e6b81454
This commit is contained in:
Eike Ziller
2015-11-17 09:37:57 +01:00
51 changed files with 622 additions and 361 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@@ -114,6 +114,30 @@
data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to
other developers for examination or load data saved by them. other developers for examination or load data saved by them.
\section1 Specifying Flushing Settings
You can specify flushing settings for the QML Profiler either globally for
all projects or separately for each project. To specify global settings,
select \uicontrol Tools > \uicontrol Options > \uicontrol Analyzer.
To specify custom QML Profiler settings for a particular project, select
\uicontrol Projects and then select \uicontrol Custom in \uicontrol
{QML Profiler Settings}. To restore the global settings for the project,
select \uicontrol {Restore Global}.
\image qml-profiler-settings.png "QML Profiler Settings"
Select the \uicontrol {Flush data while profiling} check box to flush the
data periodically instead of flushing all data when profiling stops. This
saves memory on the target device and shortens the wait between the
profiling being stopped and the data being displayed.
In the \uicontrol {Flush interval} field, set the flush interval in
milliseconds. The shorter the interval, the more often the data is flushed.
The longer the interval, the more data has to be buffered in the target
application, potentially wasting memory. However, the flushing itself takes
time, which can distort the profiling results.
\section1 Attaching to Running Qt Quick Applications \section1 Attaching to Running Qt Quick Applications
To profile Qt Quick applications that are not launched by \QC, select To profile Qt Quick applications that are not launched by \QC, select
@@ -509,11 +533,6 @@
Click on an event to move to it in the source code Click on an event to move to it in the source code
in the code editor. in the code editor.
JavaScript events often duplicate bindings or signals, so you can show and
hide them by selecting \uicontrol {Show JavaScript Events} in the context
menu. To show and hide QML events (\uicontrol Create, \uicontrol Compile,
and \uicontrol Signal), select \uicontrol {Show QML Events}.
\image qtcreator-analyzer-bindings.png "Events view" \image qtcreator-analyzer-bindings.png "Events view"
The \uicontrol Callers and \uicontrol Callees panes show dependencies between events. The \uicontrol Callers and \uicontrol Callees panes show dependencies between events.

View File

@@ -2346,7 +2346,7 @@
\li Activation \li Activation
\row \row
\li Move Component into \c filename.qml \li Move Component into Separate File
\li Moves a QML type into a separate file \li Moves a QML type into a separate file
\li QML type name \li QML type name
\row \row
@@ -2370,7 +2370,7 @@
\li QML type property \li QML type property
\row \row
\li Wrap in Loader \li Wrap Component in Loader
\li Wraps the type in a Component type and loads it dynamically in a \li Wraps the type in a Component type and loads it dynamically in a
Loader type. This is usually done to improve startup time. Loader type. This is usually done to improve startup time.
\li QML type name \li QML type name

View File

@@ -39,7 +39,7 @@
\table \table
\header \header
\li {1,3} Target Platform \li {1,2} Target Platform
\li {3,1} Development Platform \li {3,1} Development Platform
\header \header
\li Linux \li Linux

View File

@@ -99,8 +99,8 @@
\list 1 \list 1
\li Choose \uicontrol {File > New File or Project > Libraries > \li Choose \uicontrol File > \uicontrol {New File or Project} >
C++ Library} to create the library. \uicontrol Library > \uicontrol {C++ Library} to create the library.
The \uicontrol {Introduction and Product Location} dialog opens. The \uicontrol {Introduction and Product Location} dialog opens.

View File

@@ -47,6 +47,7 @@
\li \inlineimage creator_gettingstarted.png \li \inlineimage creator_gettingstarted.png
\li \inlineimage creator_managingprojects.png \li \inlineimage creator_managingprojects.png
\li \inlineimage creator_designinguserinterface.png \li \inlineimage creator_designinguserinterface.png
\li \inlineimage creator_coding.png
\row \row
\li \b {\l{Getting Started}} \li \b {\l{Getting Started}}
\list \list
@@ -69,11 +70,6 @@
\li \l{Developing Widget Based Applications} \li \l{Developing Widget Based Applications}
\li \l{Optimizing Applications for Mobile Devices} \li \l{Optimizing Applications for Mobile Devices}
\endlist \endlist
\row
\li \inlineimage creator_coding.png
\li \inlineimage creator_buildingrunning.png
\li \inlineimage creator_testing.png
\row
\li \b {\l{Coding}} \li \b {\l{Coding}}
\list \list
\li \l{Modeling} \li \l{Modeling}
@@ -82,6 +78,12 @@
\li \l{Refactoring} \li \l{Refactoring}
\li \l{Configuring the Editor} \li \l{Configuring the Editor}
\endlist \endlist
\row
\li \inlineimage creator_buildingrunning.png
\li \inlineimage creator_testing.png
\li \inlineimage creator_advanceduse.png
\li \inlineimage creator_gettinghelp.png
\row
\li \b {\l{Building and Running}} \li \b {\l{Building and Running}}
\list \list
\li \l{Building for Multiple Platforms} \li \l{Building for Multiple Platforms}
@@ -95,11 +97,6 @@
\li \l{Analyzing Code} \li \l{Analyzing Code}
\li \l{Running Autotests} \li \l{Running Autotests}
\endlist \endlist
\row
\li \inlineimage creator_advanceduse.png
\li \inlineimage creator_gettinghelp.png
\li
\row
\li \b {\l{Advanced Use}} \li \b {\l{Advanced Use}}
\list \list
\li \l{Supported Platforms} \li \l{Supported Platforms}
@@ -118,7 +115,7 @@
\endlist \endlist
\li \li
\row \row
\li {3,1} \note To report bugs and suggestions to the Qt Bug \li {4,1} \note To report bugs and suggestions to the Qt Bug
Tracker, select \uicontrol {Help > Report Bug}. Tracker, select \uicontrol {Help > Report Bug}.
You can also join the \QC mailing list at: You can also join the \QC mailing list at:

View File

@@ -59,7 +59,7 @@
\li \uicontrol {Qt Quick Controls UI} is like \uicontrol {Qt Quick UI}, \li \uicontrol {Qt Quick Controls UI} is like \uicontrol {Qt Quick UI},
but using Qt Quick Controls. but using Qt Quick Controls.
\li \uicontrol {Qt Quick Extension Plugins} (in the \uicontrol Libraries category) \li \uicontrol {Qt Quick Extension Plugins} (in the \uicontrol Library category)
create C++ plugins that make it possible to offer extensions that create C++ plugins that make it possible to offer extensions that
can be loaded dynamically into Qt Quick applications. Select can be loaded dynamically into Qt Quick applications. Select
\uicontrol {Qt Quick 1 Extension Plugin} to create extensions for \uicontrol {Qt Quick 1 Extension Plugin} to create extensions for

View File

@@ -82,7 +82,13 @@ QDataStream &operator>>(QDataStream &in, SourceLocationContainer &container)
bool operator==(const SourceLocationContainer &first, const SourceLocationContainer &second) bool operator==(const SourceLocationContainer &first, const SourceLocationContainer &second)
{ {
return first.offset_ == second.offset_ && first.filePath_ == second.filePath_; return !(first != second);
}
bool operator!=(const SourceLocationContainer &first, const SourceLocationContainer &second)
{
return first.offset_ != second.offset_
|| first.filePath_ != second.filePath_;
} }
bool operator<(const SourceLocationContainer &first, const SourceLocationContainer &second) bool operator<(const SourceLocationContainer &first, const SourceLocationContainer &second)

View File

@@ -44,6 +44,7 @@ class CMBIPC_EXPORT SourceLocationContainer
friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const SourceLocationContainer &container); friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const SourceLocationContainer &container);
friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, SourceLocationContainer &container); friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, SourceLocationContainer &container);
friend CMBIPC_EXPORT bool operator==(const SourceLocationContainer &first, const SourceLocationContainer &second); friend CMBIPC_EXPORT bool operator==(const SourceLocationContainer &first, const SourceLocationContainer &second);
friend CMBIPC_EXPORT bool operator!=(const SourceLocationContainer &first, const SourceLocationContainer &second);
friend CMBIPC_EXPORT bool operator<(const SourceLocationContainer &first, const SourceLocationContainer &second); friend CMBIPC_EXPORT bool operator<(const SourceLocationContainer &first, const SourceLocationContainer &second);
public: public:
@@ -65,6 +66,7 @@ private:
CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const SourceLocationContainer &container); CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const SourceLocationContainer &container);
CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, SourceLocationContainer &container); CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, SourceLocationContainer &container);
CMBIPC_EXPORT bool operator==(const SourceLocationContainer &first, const SourceLocationContainer &second); CMBIPC_EXPORT bool operator==(const SourceLocationContainer &first, const SourceLocationContainer &second);
CMBIPC_EXPORT bool operator!=(const SourceLocationContainer &first, const SourceLocationContainer &second);
CMBIPC_EXPORT bool operator<(const SourceLocationContainer &first, const SourceLocationContainer &second); CMBIPC_EXPORT bool operator<(const SourceLocationContainer &first, const SourceLocationContainer &second);
CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceLocationContainer &container); CMBIPC_EXPORT QDebug operator<<(QDebug debug, const SourceLocationContainer &container);

View File

@@ -94,7 +94,7 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err
pchManager, &PchManager::onProjectPartsUpdated); pchManager, &PchManager::onProjectPartsUpdated);
// Register ModelManagerSupportProvider // Register ModelManagerSupportProvider
cppModelManager->addModelManagerSupportProvider(&m_modelManagerSupportProvider); cppModelManager->setClangModelManagerSupportProvider(&m_modelManagerSupportProvider);
initializeTextMarks(); initializeTextMarks();

View File

@@ -174,13 +174,8 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor)
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(document); TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(document);
if (textDocument && cppModelManager()->isCppEditor(editor)) { if (textDocument && cppModelManager()->isCppEditor(editor)) {
const QString clangSupportId = QLatin1String(Constants::CLANG_MODELMANAGERSUPPORT_ID);
if (cppModelManager()->isManagedByModelManagerSupport(textDocument, clangSupportId)) {
connectTextDocumentToTranslationUnit(textDocument); connectTextDocumentToTranslationUnit(textDocument);
connectToWidgetsMarkContextMenuRequested(editor->widget()); connectToWidgetsMarkContextMenuRequested(editor->widget());
} else {
connectTextDocumentToUnsavedFiles(textDocument);
}
// TODO: Ensure that not fully loaded documents are updated? // TODO: Ensure that not fully loaded documents are updated?
} }

View File

@@ -55,7 +55,7 @@ static const QLatin1Char kDoubleQuote('"');
static const QLatin1Char kNewLine('\n'); static const QLatin1Char kNewLine('\n');
static const QLatin1Char kHorizontalTab('\t'); static const QLatin1Char kHorizontalTab('\t');
const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeMode.ClangCodeMode"; const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeModel.ClangCodeModel";
const char CLANG_ERROR[] = "Clang.Error"; const char CLANG_ERROR[] = "Clang.Error";
const char CLANG_WARNING[] = "Clang.Warning"; const char CLANG_WARNING[] = "Clang.Warning";

View File

@@ -35,13 +35,11 @@
#include "../clangmodelmanagersupport.h" #include "../clangmodelmanagersupport.h"
#include <clangcodemodel/clangeditordocumentprocessor.h> #include <clangcodemodel/clangeditordocumentprocessor.h>
#include <clangcodemodel/constants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cpptools/cppcodemodelsettings.h> #include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cpptoolsconstants.h>
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
#include <cpptools/cpptoolstestcase.h> #include <cpptools/cpptoolstestcase.h>
#include <cpptools/modelmanagertesthelper.h> #include <cpptools/modelmanagertesthelper.h>
@@ -857,7 +855,7 @@ private:
ActivateClangModelManagerSupport(); ActivateClangModelManagerSupport();
CppCodeModelSettingsPtr m_codeModelSettings; CppCodeModelSettingsPtr m_codeModelSettings;
QHash<QString, QString> m_previousValues; bool m_clangCodeModelWasUsedPreviously;
}; };
ActivateClangModelManagerSupport::ActivateClangModelManagerSupport( ActivateClangModelManagerSupport::ActivateClangModelManagerSupport(
@@ -865,22 +863,16 @@ ActivateClangModelManagerSupport::ActivateClangModelManagerSupport(
: m_codeModelSettings(codeModelSettings) : m_codeModelSettings(codeModelSettings)
{ {
QTC_CHECK(m_codeModelSettings); QTC_CHECK(m_codeModelSettings);
const QString clangModelManagerSupportId
= QLatin1String(Constants::CLANG_MODELMANAGERSUPPORT_ID); m_clangCodeModelWasUsedPreviously = m_codeModelSettings->useClangCodeModel();
foreach (const QString &mimeType, CppTools::CppCodeModelSettings::supportedMimeTypes()) {
m_previousValues.insert(mimeType, m_codeModelSettings->setUseClangCodeModel(true);
m_codeModelSettings->modelManagerSupportIdForMimeType(mimeType));
m_codeModelSettings->setModelManagerSupportIdForMimeType(mimeType,
clangModelManagerSupportId);
}
m_codeModelSettings->emitChanged(); m_codeModelSettings->emitChanged();
} }
ActivateClangModelManagerSupport::~ActivateClangModelManagerSupport() ActivateClangModelManagerSupport::~ActivateClangModelManagerSupport()
{ {
QHash<QString, QString>::const_iterator i = m_previousValues.constBegin(); m_codeModelSettings->setUseClangCodeModel(m_clangCodeModelWasUsedPreviously);
for (; i != m_previousValues.end(); ++i)
m_codeModelSettings->setModelManagerSupportIdForMimeType(i.key(), i.value());
m_codeModelSettings->emitChanged(); m_codeModelSettings->emitChanged();
} }

View File

@@ -51,6 +51,8 @@ Q_DECLARE_METATYPE(Core::IWizardFactory*)
namespace { namespace {
const int ICON_SIZE = 22; const int ICON_SIZE = 22;
const char LAST_CATEGORY_KEY[] = "Core/NewDialog/LastCategory";
const char LAST_PLATFORM_KEY[] = "Core/NewDialog/LastPlatform";
class WizardFactoryContainer class WizardFactoryContainer
{ {
@@ -188,8 +190,6 @@ using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
bool NewDialog::m_isRunning = false; bool NewDialog::m_isRunning = false;
QString NewDialog::m_lastCategory = QString();
QString NewDialog::m_lastPlatform = QString();
NewDialog::NewDialog(QWidget *parent) : NewDialog::NewDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
@@ -302,12 +302,18 @@ void NewDialog::showDialog()
{ {
QModelIndex idx; QModelIndex idx;
if (!m_lastPlatform.isEmpty()) QString lastPlatform = ICore::settings()->value(QLatin1String(LAST_PLATFORM_KEY)).toString();
m_ui->comboBox->setCurrentIndex(m_ui->comboBox->findData(m_lastPlatform)); QString lastCategory = ICore::settings()->value(QLatin1String(LAST_CATEGORY_KEY)).toString();
if (!m_lastCategory.isEmpty()) if (!lastPlatform.isEmpty()) {
int index = m_ui->comboBox->findData(lastPlatform);
if (index != -1)
m_ui->comboBox->setCurrentIndex(index);
}
if (!lastCategory.isEmpty())
foreach (QStandardItem* item, m_categoryItems) { foreach (QStandardItem* item, m_categoryItems) {
if (item->data(Qt::UserRole) == m_lastCategory) if (item->data(Qt::UserRole) == lastCategory)
idx = m_twoLevelProxyModel->mapToSource(m_model->indexFromItem(item)); idx = m_twoLevelProxyModel->mapToSource(m_model->indexFromItem(item));
} }
if (!idx.isValid()) if (!idx.isValid())
@@ -449,8 +455,9 @@ void NewDialog::saveState()
QModelIndex idx = m_ui->templateCategoryView->currentIndex(); QModelIndex idx = m_ui->templateCategoryView->currentIndex();
QStandardItem *currentItem = m_model->itemFromIndex(m_twoLevelProxyModel->mapToSource(idx)); QStandardItem *currentItem = m_model->itemFromIndex(m_twoLevelProxyModel->mapToSource(idx));
if (currentItem) if (currentItem)
m_lastCategory = currentItem->data(Qt::UserRole).toString(); ICore::settings()->setValue(QLatin1String(LAST_CATEGORY_KEY),
m_lastPlatform = m_ui->comboBox->currentData().toString(); currentItem->data(Qt::UserRole));
ICore::settings()->setValue(QLatin1String(LAST_PLATFORM_KEY), m_ui->comboBox->currentData());
} }
void NewDialog::accept() void NewDialog::accept()

View File

@@ -85,8 +85,6 @@ private:
void addItem(QStandardItem *topLevelCategoryItem, IWizardFactory *factory); void addItem(QStandardItem *topLevelCategoryItem, IWizardFactory *factory);
void saveState(); void saveState();
static QString m_lastCategory;
static QString m_lastPlatform;
static bool m_isRunning; static bool m_isRunning;
Ui::NewDialog *m_ui; Ui::NewDialog *m_ui;

View File

@@ -2517,8 +2517,6 @@ static void mimeTypeFactoryLookup(const Utils::MimeType &mimeType,
seen.insert(parent.name()); seen.insert(parent.name());
if (seen.size() != seenSize) // not seen before, so add if (seen.size() != seenSize) // not seen before, so add
queue.append(parent); queue.append(parent);
else
qWarning("MimeTypes: Parent hierarchy loop detected for '%s'!", qPrintable(parent.name()));
} }
} }
} }

View File

@@ -61,8 +61,6 @@ const char CPP_SNIPPETS_GROUP_ID[] = "C++";
const char CPP_PREPROCESSOR_PROJECT_PREFIX[] = "CppPreprocessorProject-"; const char CPP_PREPROCESSOR_PROJECT_PREFIX[] = "CppPreprocessorProject-";
const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeMode.ClangCodeMode";
} // namespace Constants } // namespace Constants
} // namespace CppEditor } // namespace CppEditor

View File

@@ -181,7 +181,7 @@ void CppEditorDocument::onMimeTypeChanged()
const QString &mt = mimeType(); const QString &mt = mimeType();
m_isObjCEnabled = (mt == QLatin1String(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE) m_isObjCEnabled = (mt == QLatin1String(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE)
|| mt == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); || mt == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE));
m_completionAssistProvider = mm()->completionAssistProvider(mt); m_completionAssistProvider = mm()->completionAssistProvider();
initializeTimer(); initializeTimer();
} }
@@ -292,7 +292,7 @@ void CppEditorDocument::releaseResources()
void CppEditorDocument::initializeTimer() void CppEditorDocument::initializeTimer()
{ {
m_processorTimer.setSingleShot(true); m_processorTimer.setSingleShot(true);
if (mm()->isManagedByModelManagerSupport(this, QLatin1String(Constants::CLANG_MODELMANAGERSUPPORT_ID))) if (mm()->isClangCodeModelActive())
m_processorTimer.setInterval(clangProcessDocumentIntervalInMs); m_processorTimer.setInterval(clangProcessDocumentIntervalInMs);
else else
m_processorTimer.setInterval(processDocumentIntervalInMs); m_processorTimer.setInterval(processDocumentIntervalInMs);

View File

@@ -1298,7 +1298,7 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST
Function *funTy = c->type()->asFunctionType(); Function *funTy = c->type()->asFunctionType();
if (!funTy) // Template function has an overridden type if (!funTy) // Template function has an overridden type
funTy = r.type()->asFunctionType(); funTy = r.type()->asFunctionType();
if (!funTy) if (!funTy || funTy->isAmbiguous())
continue; // TODO: add diagnostic messages and color call-operators calls too? continue; // TODO: add diagnostic messages and color call-operators calls too?
if (argumentCount < funTy->minimumArgumentCount()) { if (argumentCount < funTy->minimumArgumentCount()) {

View File

@@ -29,23 +29,22 @@
****************************************************************************/ ****************************************************************************/
#include "cppcodemodelsettings.h" #include "cppcodemodelsettings.h"
#include "cppmodelmanagersupport.h"
#include "cpptoolsconstants.h" #include "cpptoolsconstants.h"
#include <QSettings>
using namespace CppTools; using namespace CppTools;
static QLatin1String cppHeaderMimeType(Constants::CPP_HEADER_MIMETYPE); static QLatin1String cppHeaderMimeType(Constants::CPP_HEADER_MIMETYPE);
static QLatin1String cHeaderMimeType(Constants::C_HEADER_MIMETYPE); static QLatin1String cHeaderMimeType(Constants::C_HEADER_MIMETYPE);
static QLatin1String clangExtraOptionsKey(Constants::CPPTOOLS_EXTRA_CLANG_OPTIONS); static QLatin1String clangExtraOptionsKey(Constants::CPPTOOLS_EXTRA_CLANG_OPTIONS);
static QLatin1String useClangCodeModelKey(Constants::CPPTOOLS_USE_CLANG_CODE_MODEL);
void CppCodeModelSettings::fromSettings(QSettings *s) void CppCodeModelSettings::fromSettings(QSettings *s)
{ {
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP)); s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
QVariant supporters = s->value(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY));
foreach (const QString &mimeType, supportedMimeTypes())
setIdForMimeType(supporters, mimeType);
setUseClangCodeModel(s->value(useClangCodeModelKey, false).toBool());
setExtraClangOptions(s->value(clangExtraOptionsKey, defaultExtraClangOptions()).toStringList()); setExtraClangOptions(s->value(clangExtraOptionsKey, defaultExtraClangOptions()).toStringList());
QVariant v = s->value(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), PchUse_None); QVariant v = s->value(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), PchUse_None);
@@ -58,66 +57,24 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
void CppCodeModelSettings::toSettings(QSettings *s) void CppCodeModelSettings::toSettings(QSettings *s)
{ {
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP)); s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
QHash<QString, QVariant> var;
foreach (const QString &mimeType, m_modelManagerSupportByMimeType.keys()) s->setValue(useClangCodeModelKey, useClangCodeModel());
var[mimeType] = m_modelManagerSupportByMimeType[mimeType];
s->setValue(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY), QVariant(var));
s->setValue(clangExtraOptionsKey, extraClangOptions()); s->setValue(clangExtraOptionsKey, extraClangOptions());
s->setValue(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), pchUsage()); s->setValue(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), pchUsage());
s->endGroup(); s->endGroup();
emit changed(); emit changed();
} }
QStringList CppCodeModelSettings::supportedMimeTypes() bool CppCodeModelSettings::useClangCodeModel() const
{ {
return QStringList({ return m_useClangCodeModel;
QLatin1String(Constants::C_SOURCE_MIMETYPE),
QLatin1String(Constants::CPP_SOURCE_MIMETYPE),
QLatin1String(Constants::OBJECTIVE_C_SOURCE_MIMETYPE),
QLatin1String(Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE),
QLatin1String(Constants::CPP_HEADER_MIMETYPE)
});
} }
void CppCodeModelSettings::emitChanged() void CppCodeModelSettings::setUseClangCodeModel(bool useClangCodeModel)
{ {
emit changed(); m_useClangCodeModel = useClangCodeModel;
}
void CppCodeModelSettings::setModelManagerSupportProviders(
const QList<ModelManagerSupportProvider *> &providers)
{
m_modelManagerSupportsByName.clear();
foreach (ModelManagerSupportProvider *provider, providers)
m_modelManagerSupportsByName[provider->displayName()] = provider->id();
}
QString CppCodeModelSettings::modelManagerSupportIdForMimeType(const QString &mimeType) const
{
if (mimeType == cHeaderMimeType)
return m_modelManagerSupportByMimeType.value(cppHeaderMimeType);
else
return m_modelManagerSupportByMimeType.value(mimeType);
}
void CppCodeModelSettings::setModelManagerSupportIdForMimeType(const QString &mimeType,
const QString &id)
{
QString theMimeType = mimeType;
if (theMimeType == cHeaderMimeType)
theMimeType = cppHeaderMimeType;
m_modelManagerSupportByMimeType.insert(theMimeType, id);
}
bool CppCodeModelSettings::hasModelManagerSupportIdForMimeType(const QString &mimeType,
const QString &id) const
{
if (mimeType == cHeaderMimeType)
return m_modelManagerSupportByMimeType.value(cppHeaderMimeType) == id;
else
return m_modelManagerSupportByMimeType.value(mimeType) == id;
} }
QStringList CppCodeModelSettings::defaultExtraClangOptions() QStringList CppCodeModelSettings::defaultExtraClangOptions()
@@ -147,8 +104,17 @@ void CppCodeModelSettings::setExtraClangOptions(const QStringList &extraClangOpt
m_extraClangOptions = extraClangOptions; m_extraClangOptions = extraClangOptions;
} }
void CppCodeModelSettings::setIdForMimeType(const QVariant &var, const QString &mimeType) CppCodeModelSettings::PCHUsage CppCodeModelSettings::pchUsage() const
{ {
QHash<QString, QVariant> mimeToId = var.toHash(); return m_pchUsage;
m_modelManagerSupportByMimeType[mimeType] = mimeToId.value(mimeType, defaultId()).toString(); }
void CppCodeModelSettings::setPCHUsage(CppCodeModelSettings::PCHUsage pchUsage)
{
m_pchUsage = pchUsage;
}
void CppCodeModelSettings::emitChanged()
{
emit changed();
} }

View File

@@ -33,15 +33,15 @@
#include "cpptools_global.h" #include "cpptools_global.h"
#include <QHash> #include <QObject>
#include <QList> #include <QStringList>
#include <QSettings>
#include <QString> QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace CppTools { namespace CppTools {
class ModelManagerSupportProvider;
class CPPTOOLS_EXPORT CppCodeModelSettings : public QObject class CPPTOOLS_EXPORT CppCodeModelSettings : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -53,34 +53,19 @@ public:
}; };
public: public:
CppCodeModelSettings(): m_pchUsage(PchUse_None) {}
void fromSettings(QSettings *s); void fromSettings(QSettings *s);
void toSettings(QSettings *s); void toSettings(QSettings *s);
void setModelManagerSupportProviders(const QList<ModelManagerSupportProvider *> &supporters); public:
bool useClangCodeModel() const;
QString modelManagerSupportIdForMimeType(const QString &mimeType) const; void setUseClangCodeModel(bool useClangCodeModel);
void setModelManagerSupportIdForMimeType(const QString &mimeType, const QString &id);
bool hasModelManagerSupportIdForMimeType(const QString &mimeType, const QString &id) const;
const QHash<QString, QString> &availableModelManagerSupportProvidersByName() const
{ return m_modelManagerSupportsByName; }
QString defaultId() const
{ return m_defaultId; }
void setDefaultId(const QString &defaultId)
{ m_defaultId = defaultId; }
static QStringList defaultExtraClangOptions(); static QStringList defaultExtraClangOptions();
QStringList extraClangOptions() const; QStringList extraClangOptions() const;
void setExtraClangOptions(const QStringList &extraClangOptions); void setExtraClangOptions(const QStringList &extraClangOptions);
PCHUsage pchUsage() const { return m_pchUsage; } PCHUsage pchUsage() const;
void setPCHUsage(PCHUsage pchUsage) { m_pchUsage = pchUsage; } void setPCHUsage(PCHUsage pchUsage);
static QStringList supportedMimeTypes();
public: // for tests public: // for tests
void emitChanged(); void emitChanged();
@@ -89,14 +74,10 @@ signals:
void changed(); void changed();
private: private:
void setIdForMimeType(const QVariant &var, const QString &mimeType); bool m_isClangCodeModelAvailable = false;
bool m_useClangCodeModel = false;
private:
QHash<QString, QString> m_modelManagerSupportByMimeType;
QHash<QString, QString> m_modelManagerSupportsByName;
QStringList m_extraClangOptions; QStringList m_extraClangOptions;
QString m_defaultId; PCHUsage m_pchUsage = PchUse_None;
PCHUsage m_pchUsage;
}; };
} // namespace CppTools } // namespace CppTools

View File

@@ -29,6 +29,7 @@
****************************************************************************/ ****************************************************************************/
#include "cppcodemodelsettingspage.h" #include "cppcodemodelsettingspage.h"
#include "cppmodelmanager.h"
#include "cpptoolsconstants.h" #include "cpptoolsconstants.h"
#include "ui_cppcodemodelsettingspage.h" #include "ui_cppcodemodelsettingspage.h"
@@ -63,41 +64,26 @@ void CppCodeModelSettingsWidget::setSettings(const QSharedPointer<CppCodeModelSe
m_settings = s; m_settings = s;
setupClangCodeModelWidgets(); setupClangCodeModelWidgets();
m_ui->ignorePCHCheckBox->setChecked(s->pchUsage() == CppCodeModelSettings::PchUse_None); setupPchCheckBox();
} }
void CppCodeModelSettingsWidget::applyToSettings() const void CppCodeModelSettingsWidget::applyToSettings() const
{ {
bool changed = false; bool changed = false;
if (applyClangCodeModelWidgetsToSettings()) changed |= applyClangCodeModelWidgetsToSettings();
changed = true; changed |= applyPchCheckBoxToSettings();
if (m_ui->ignorePCHCheckBox->isChecked() !=
(m_settings->pchUsage() == CppCodeModelSettings::PchUse_None)) {
m_settings->setPCHUsage(
m_ui->ignorePCHCheckBox->isChecked() ? CppCodeModelSettings::PchUse_None
: CppCodeModelSettings::PchUse_BuildSystem);
changed = true;
}
if (changed) if (changed)
m_settings->toSettings(Core::ICore::settings()); m_settings->toSettings(Core::ICore::settings());
} }
static bool isClangCodeModelActive(const CppCodeModelSettings &settings)
{
const QString currentCodeModelId
= settings.modelManagerSupportIdForMimeType(QLatin1String(Constants::CPP_SOURCE_MIMETYPE));
return currentCodeModelId != settings.defaultId();
}
void CppCodeModelSettingsWidget::setupClangCodeModelWidgets() const void CppCodeModelSettingsWidget::setupClangCodeModelWidgets() const
{ {
bool isClangActive = false; bool isClangActive = false;
const bool isClangAvailable = m_settings->availableModelManagerSupportProvidersByName().size() > 1; const bool isClangAvailable = CppModelManager::instance()->isClangCodeModelAvailable();
if (isClangAvailable) if (isClangAvailable)
isClangActive = isClangCodeModelActive(*m_settings.data()); isClangActive = m_settings->useClangCodeModel();
m_ui->activateClangCodeModelPluginHint->setVisible(!isClangAvailable); m_ui->activateClangCodeModelPluginHint->setVisible(!isClangAvailable);
m_ui->clangSettingsGroupBox->setEnabled(isClangAvailable); m_ui->clangSettingsGroupBox->setEnabled(isClangAvailable);
@@ -107,25 +93,50 @@ void CppCodeModelSettingsWidget::setupClangCodeModelWidgets() const
m_ui->clangOptionsToAppendTextEdit->document()->setPlainText(extraClangOptions); m_ui->clangOptionsToAppendTextEdit->document()->setPlainText(extraClangOptions);
} }
void CppCodeModelSettingsWidget::setupPchCheckBox() const
{
const bool ignorePch = m_settings->pchUsage() == CppCodeModelSettings::PchUse_None;
m_ui->ignorePCHCheckBox->setChecked(ignorePch);
}
bool CppCodeModelSettingsWidget::applyClangCodeModelWidgetsToSettings() const bool CppCodeModelSettingsWidget::applyClangCodeModelWidgetsToSettings() const
{ {
// Once the underlying settings are not mime type based anymore, simplify here. bool settingsChanged = false;
// Until then, ensure that the settings are set uniformly for all the mime types
// to avoid surprises.
const QString activeCodeModelId = m_ui->clangSettingsGroupBox->isChecked() const bool previouslyClangWasActive = m_settings->useClangCodeModel();
? QLatin1String("ClangCodeMode.ClangCodeMode") const bool nowClangIsActive = m_ui->clangSettingsGroupBox->isChecked();
: QLatin1String("CppTools.BuiltinCodeModel"); if (nowClangIsActive != previouslyClangWasActive) {
m_settings->setUseClangCodeModel(nowClangIsActive);
settingsChanged = true;
}
foreach (const QString &mimeType, m_settings->supportedMimeTypes()) const QStringList previousOptions = m_settings->extraClangOptions();
m_settings->setModelManagerSupportIdForMimeType(mimeType, activeCodeModelId); const QString newOptionsAsString = m_ui->clangOptionsToAppendTextEdit->document()->toPlainText();
const QStringList newOptions = newOptionsAsString.split(QLatin1Char('\n'),
const QString clangOptionsText = m_ui->clangOptionsToAppendTextEdit->document()->toPlainText();
const QStringList extraClangOptions = clangOptionsText.split(QLatin1Char('\n'),
QString::SkipEmptyParts); QString::SkipEmptyParts);
m_settings->setExtraClangOptions(extraClangOptions); if (newOptions != previousOptions) {
m_settings->setExtraClangOptions(newOptions);
settingsChanged = true;
}
return settingsChanged;
}
bool CppCodeModelSettingsWidget::applyPchCheckBoxToSettings() const
{
const bool newIgnorePch = m_ui->ignorePCHCheckBox->isChecked();
const bool previousIgnorePch = m_settings->pchUsage() == CppCodeModelSettings::PchUse_None;
if (newIgnorePch != previousIgnorePch) {
const CppCodeModelSettings::PCHUsage pchUsage = m_ui->ignorePCHCheckBox->isChecked()
? CppCodeModelSettings::PchUse_None
: CppCodeModelSettings::PchUse_BuildSystem;
m_settings->setPCHUsage(pchUsage);
return true; return true;
}
return false;
} }
CppCodeModelSettingsPage::CppCodeModelSettingsPage(QSharedPointer<CppCodeModelSettings> &settings, CppCodeModelSettingsPage::CppCodeModelSettingsPage(QSharedPointer<CppCodeModelSettings> &settings,

View File

@@ -59,7 +59,10 @@ public:
private: private:
void setupClangCodeModelWidgets() const; void setupClangCodeModelWidgets() const;
void setupPchCheckBox() const;
bool applyClangCodeModelWidgetsToSettings() const; bool applyClangCodeModelWidgetsToSettings() const;
bool applyPchCheckBoxToSettings() const;
private: private:
Ui::CppCodeModelSettingsPage *m_ui; Ui::CppCodeModelSettingsPage *m_ui;

View File

@@ -151,11 +151,10 @@ public:
QMap<QString, CppEditorDocumentHandle *> m_cppEditorDocuments; QMap<QString, CppEditorDocumentHandle *> m_cppEditorDocuments;
QSet<AbstractEditorSupport *> m_extraEditorSupports; QSet<AbstractEditorSupport *> m_extraEditorSupports;
// Completion & highlighting // Model Manager Supports for e.g. completion and highlighting
ModelManagerSupportProviderInternal m_modelManagerSupportInternalProvider; ModelManagerSupportProvider *m_clangModelManagerSupportProvider;
ModelManagerSupport::Ptr m_modelManagerSupportInternal; ModelManagerSupport::Ptr m_builtinModelManagerSupport;
QHash<QString, ModelManagerSupportProvider *> m_availableModelManagerSupports; ModelManagerSupport::Ptr m_activeModelManagerSupport;
QHash<QString, ModelManagerSupport::Ptr> m_activeModelManagerSupports;
// Indexing // Indexing
CppIndexingSupport *m_indexingSupporter; CppIndexingSupport *m_indexingSupporter;
@@ -293,6 +292,14 @@ CppModelManager *CppModelManager::instance()
return m_instance; return m_instance;
} }
void CppModelManager::initializeModelManagerSupports()
{
d->m_clangModelManagerSupportProvider = nullptr;
d->m_builtinModelManagerSupport
= ModelManagerSupportProviderInternal().createModelManagerSupport();
d->m_activeModelManagerSupport = d->m_builtinModelManagerSupport;
}
CppModelManager::CppModelManager(QObject *parent) CppModelManager::CppModelManager(QObject *parent)
: CppModelManagerBase(parent), d(new CppModelManagerPrivate) : CppModelManagerBase(parent), d(new CppModelManagerPrivate)
{ {
@@ -337,15 +344,10 @@ CppModelManager::CppModelManager(QObject *parent)
QSharedPointer<CppCodeModelSettings> codeModelSettings QSharedPointer<CppCodeModelSettings> codeModelSettings
= CppToolsPlugin::instance()->codeModelSettings(); = CppToolsPlugin::instance()->codeModelSettings();
codeModelSettings->setDefaultId(d->m_modelManagerSupportInternalProvider.id());
connect(codeModelSettings.data(), &CppCodeModelSettings::changed, connect(codeModelSettings.data(), &CppCodeModelSettings::changed,
this, &CppModelManager::onCodeModelSettingsChanged); this, &CppModelManager::onCodeModelSettingsChanged);
d->m_modelManagerSupportInternal initializeModelManagerSupports();
= d->m_modelManagerSupportInternalProvider.createModelManagerSupport();
d->m_activeModelManagerSupports.insert(d->m_modelManagerSupportInternalProvider.id(),
d->m_modelManagerSupportInternal);
addModelManagerSupportProvider(&d->m_modelManagerSupportInternalProvider);
d->m_internalIndexingSupport = new BuiltinIndexingSupport; d->m_internalIndexingSupport = new BuiltinIndexingSupport;
} }
@@ -665,31 +667,6 @@ void CppModelManager::removeProjectInfoFilesAndIncludesFromSnapshot(const Projec
} }
} }
void CppModelManager::handleAddedModelManagerSupports(const QSet<QString> &supportIds)
{
foreach (const QString &id, supportIds) {
ModelManagerSupportProvider * const provider = d->m_availableModelManagerSupports.value(id);
if (provider) {
QTC_CHECK(!d->m_activeModelManagerSupports.contains(id));
d->m_activeModelManagerSupports.insert(id, provider->createModelManagerSupport());
}
}
}
QList<ModelManagerSupport::Ptr> CppModelManager::handleRemovedModelManagerSupports(
const QSet<QString> &supportIds)
{
QList<ModelManagerSupport::Ptr> removed;
foreach (const QString &id, supportIds) {
const ModelManagerSupport::Ptr support = d->m_activeModelManagerSupports.value(id);
d->m_activeModelManagerSupports.remove(id);
removed << support;
}
return removed;
}
void CppModelManager::closeCppEditorDocuments() void CppModelManager::closeCppEditorDocuments()
{ {
QList<Core::IDocument *> cppDocumentsToClose; QList<Core::IDocument *> cppDocumentsToClose;
@@ -964,12 +941,15 @@ bool CppModelManager::isCppEditor(Core::IEditor *editor) const
return editor->context().contains(ProjectExplorer::Constants::LANG_CXX); return editor->context().contains(ProjectExplorer::Constants::LANG_CXX);
} }
bool CppModelManager::isManagedByModelManagerSupport(Core::IDocument *document, const QString &id) const bool CppModelManager::isClangCodeModelAvailable() const
{ {
auto documentMimeTupe = document->mimeType(); return d->m_clangModelManagerSupportProvider != nullptr;
auto codeModelSettings = CppToolsPlugin::instance()->codeModelSettings(); }
return codeModelSettings->hasModelManagerSupportIdForMimeType(documentMimeTupe, id); bool CppModelManager::isClangCodeModelActive() const
{
return isClangCodeModelAvailable()
&& d->m_activeModelManagerSupport != d->m_builtinModelManagerSupport;
} }
void CppModelManager::emitDocumentUpdated(Document::Ptr doc) void CppModelManager::emitDocumentUpdated(Document::Ptr doc)
@@ -1053,43 +1033,25 @@ void CppModelManager::onCurrentEditorChanged(Core::IEditor *editor)
} }
} }
static const QSet<QString> activeModelManagerSupportsFromSettings()
{
QSet<QString> result;
QSharedPointer<CppCodeModelSettings> codeModelSettings
= CppToolsPlugin::instance()->codeModelSettings();
const QStringList mimeTypes = codeModelSettings->supportedMimeTypes();
foreach (const QString &mimeType, mimeTypes) {
const QString id = codeModelSettings->modelManagerSupportIdForMimeType(mimeType);
if (!id.isEmpty())
result << id;
}
return result;
}
void CppModelManager::onCodeModelSettingsChanged() void CppModelManager::onCodeModelSettingsChanged()
{ {
const QSet<QString> currentCodeModelSupporters = d->m_activeModelManagerSupports.keys().toSet(); const bool isClangActive = isClangCodeModelActive();
const QSet<QString> newCodeModelSupporters = activeModelManagerSupportsFromSettings(); const QSharedPointer<CppCodeModelSettings> settings
= CppToolsPlugin::instance()->codeModelSettings();
QSet<QString> added = newCodeModelSupporters; ModelManagerSupport::Ptr newCodeModelSupport;
added.subtract(currentCodeModelSupporters);
added.remove(d->m_modelManagerSupportInternalProvider.id());
handleAddedModelManagerSupports(added);
QSet<QString> removed = currentCodeModelSupporters; if (isClangCodeModelAvailable()) {
removed.subtract(newCodeModelSupporters); if (!isClangActive && settings->useClangCodeModel())
removed.remove(d->m_modelManagerSupportInternalProvider.id()); newCodeModelSupport = d->m_clangModelManagerSupportProvider->createModelManagerSupport();
const QList<ModelManagerSupport::Ptr> supportsToDelete else if (isClangActive && !settings->useClangCodeModel())
= handleRemovedModelManagerSupports(removed); newCodeModelSupport = d->m_builtinModelManagerSupport;
QTC_CHECK(removed.size() == supportsToDelete.size()); }
if (!added.isEmpty() || !removed.isEmpty()) if (newCodeModelSupport) {
closeCppEditorDocuments(); closeCppEditorDocuments();
d->m_activeModelManagerSupport = newCodeModelSupport;
// supportsToDelete goes out of scope and deletes the supports }
} }
void CppModelManager::onAboutToLoadSession() void CppModelManager::onAboutToLoadSession()
@@ -1201,44 +1163,26 @@ void CppModelManager::finishedRefreshingSourceFiles(const QSet<QString> &files)
emit sourceFilesRefreshed(files); emit sourceFilesRefreshed(files);
} }
void CppModelManager::addModelManagerSupportProvider( void CppModelManager::setClangModelManagerSupportProvider(
ModelManagerSupportProvider *modelManagerSupportProvider) ModelManagerSupportProvider *modelManagerSupportProvider)
{ {
QTC_ASSERT(modelManagerSupportProvider, return); QTC_ASSERT(modelManagerSupportProvider, return);
d->m_availableModelManagerSupports[modelManagerSupportProvider->id()] QTC_CHECK(d->m_clangModelManagerSupportProvider == nullptr);
= modelManagerSupportProvider;
QSharedPointer<CppCodeModelSettings> cms = CppToolsPlugin::instance()->codeModelSettings(); d->m_clangModelManagerSupportProvider = modelManagerSupportProvider;
cms->setModelManagerSupportProviders(d->m_availableModelManagerSupports.values());
onCodeModelSettingsChanged(); onCodeModelSettingsChanged();
} }
ModelManagerSupport::Ptr CppModelManager::modelManagerSupportForMimeType( CppCompletionAssistProvider *CppModelManager::completionAssistProvider() const
const QString &mimeType) const
{ {
QSharedPointer<CppCodeModelSettings> cms = CppToolsPlugin::instance()->codeModelSettings(); return d->m_activeModelManagerSupport->completionAssistProvider();
const QString &id = cms->modelManagerSupportIdForMimeType(mimeType);
return d->m_activeModelManagerSupports.value(id, d->m_modelManagerSupportInternal);
}
CppCompletionAssistProvider *CppModelManager::completionAssistProvider(
const QString &mimeType) const
{
if (mimeType.isEmpty())
return 0;
ModelManagerSupport::Ptr cms = modelManagerSupportForMimeType(mimeType);
QTC_ASSERT(cms, return 0);
return cms->completionAssistProvider();
} }
BaseEditorDocumentProcessor *CppModelManager::editorDocumentProcessor( BaseEditorDocumentProcessor *CppModelManager::editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) const TextEditor::TextDocument *baseTextDocument) const
{ {
QTC_ASSERT(baseTextDocument, return 0); return d->m_activeModelManagerSupport->editorDocumentProcessor(baseTextDocument);
ModelManagerSupport::Ptr cms = modelManagerSupportForMimeType(baseTextDocument->mimeType());
QTC_ASSERT(cms, return 0);
return cms->editorDocumentProcessor(baseTextDocument);
} }
void CppModelManager::setIndexingSupport(CppIndexingSupport *indexingSupport) void CppModelManager::setIndexingSupport(CppIndexingSupport *indexingSupport)

View File

@@ -121,7 +121,8 @@ public:
void emitAbstractEditorSupportRemoved(const QString &filePath); void emitAbstractEditorSupportRemoved(const QString &filePath);
bool isCppEditor(Core::IEditor *editor) const; bool isCppEditor(Core::IEditor *editor) const;
bool isManagedByModelManagerSupport(Core::IDocument *document, const QString &id) const; bool isClangCodeModelAvailable() const;
bool isClangCodeModelActive() const;
QSet<AbstractEditorSupport*> abstractEditorSupports() const; QSet<AbstractEditorSupport*> abstractEditorSupports() const;
void addExtraEditorSupport(AbstractEditorSupport *editorSupport); void addExtraEditorSupport(AbstractEditorSupport *editorSupport);
@@ -143,8 +144,8 @@ public:
void finishedRefreshingSourceFiles(const QSet<QString> &files); void finishedRefreshingSourceFiles(const QSet<QString> &files);
void addModelManagerSupportProvider(ModelManagerSupportProvider *modelManagerSupportProvider); void setClangModelManagerSupportProvider(ModelManagerSupportProvider *modelManagerSupportProvider);
CppCompletionAssistProvider *completionAssistProvider(const QString &mimeType) const; CppCompletionAssistProvider *completionAssistProvider() const;
BaseEditorDocumentProcessor *editorDocumentProcessor( BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) const; TextEditor::TextDocument *baseTextDocument) const;
@@ -205,6 +206,7 @@ private slots:
void onCoreAboutToClose(); void onCoreAboutToClose();
private: private:
void initializeModelManagerSupports();
void delayedGC(); void delayedGC();
void recalculateProjectPartMappings(); void recalculateProjectPartMappings();
void updateCppEditorDocuments() const; void updateCppEditorDocuments() const;
@@ -213,13 +215,8 @@ private:
void removeFilesFromSnapshot(const QSet<QString> &removedFiles); void removeFilesFromSnapshot(const QSet<QString> &removedFiles);
void removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo); void removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo);
void handleAddedModelManagerSupports(const QSet<QString> &supportIds);
QList<ModelManagerSupport::Ptr> handleRemovedModelManagerSupports(
const QSet<QString> &supportIds);
void closeCppEditorDocuments(); void closeCppEditorDocuments();
ModelManagerSupport::Ptr modelManagerSupportForMimeType(const QString &mimeType) const;
WorkingCopy buildWorkingCopyList(); WorkingCopy buildWorkingCopyList();
void ensureUpdated(); void ensureUpdated();

View File

@@ -53,9 +53,9 @@ const char CPPTOOLS_SETTINGSGROUP[] = "CppTools";
const char LOWERCASE_CPPFILES_KEY[] = "LowerCaseFiles"; const char LOWERCASE_CPPFILES_KEY[] = "LowerCaseFiles";
enum { lowerCaseFilesDefault = 1 }; enum { lowerCaseFilesDefault = 1 };
const char CPPTOOLS_SORT_EDITOR_DOCUMENT_OUTLINE[] = "SortedMethodOverview"; const char CPPTOOLS_SORT_EDITOR_DOCUMENT_OUTLINE[] = "SortedMethodOverview";
const char CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY[] = "ModelManagerSupporters";
const char CPPTOOLS_MODEL_MANAGER_PCH_USAGE[] = "PCHUsage"; const char CPPTOOLS_MODEL_MANAGER_PCH_USAGE[] = "PCHUsage";
const char CPPTOOLS_EXTRA_CLANG_OPTIONS[] = "ExtraClangOptions"; const char CPPTOOLS_EXTRA_CLANG_OPTIONS[] = "ExtraClangOptions";
const char CPPTOOLS_USE_CLANG_CODE_MODEL[] = "UseClangCodeModel";
const char CPP_CODE_STYLE_SETTINGS_ID[] = "A.Cpp.Code Style"; const char CPP_CODE_STYLE_SETTINGS_ID[] = "A.Cpp.Code Style";
const char CPP_CODE_STYLE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "Code Style"); const char CPP_CODE_STYLE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "Code Style");

View File

@@ -519,19 +519,20 @@ void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const
const bool wantQmlDebugger = m_debuggerAspect->useQmlDebugger() && (m_rp.languages & QmlLanguage); const bool wantQmlDebugger = m_debuggerAspect->useQmlDebugger() && (m_rp.languages & QmlLanguage);
if (wantQmlDebugger) { if (wantQmlDebugger) {
QString qmlArgs; QmlDebug::QmlDebugServicesPreset service;
if (wantCppDebugger) { if (wantCppDebugger) {
if (m_rp.nativeMixedEnabled) { if (m_rp.nativeMixedEnabled) {
qmlArgs = QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlNativeDebuggerServices); service = QmlDebug::QmlNativeDebuggerServices;
} else { } else {
m_rp.masterEngineType = QmlCppEngineType; m_rp.masterEngineType = QmlCppEngineType;
qmlArgs = QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlDebuggerServices, m_rp.qmlServerPort); service = QmlDebug::QmlDebuggerServices;
} }
} else { } else {
m_rp.masterEngineType = QmlEngineType; m_rp.masterEngineType = QmlEngineType;
qmlArgs = QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlDebuggerServices, m_rp.qmlServerPort); service = QmlDebug::QmlDebuggerServices;
} }
QtcProcess::addArg(&m_rp.processArgs, qmlArgs); if (m_rp.startMode != AttachExternal)
QtcProcess::addArg(&m_rp.processArgs, QmlDebug::qmlDebugCommandLineArguments(service, m_rp.qmlServerPort));
} }
} }

View File

@@ -71,16 +71,14 @@ public:
class GerritChange class GerritChange
{ {
public: public:
GerritChange() : number(0), depth(-1) {}
bool isValid() const { return number && !url.isEmpty() && !project.isEmpty(); } bool isValid() const { return number && !url.isEmpty() && !project.isEmpty(); }
QString filterString() const; QString filterString() const;
QStringList gitFetchArguments(const QSharedPointer<GerritParameters> &p) const; QStringList gitFetchArguments(const QSharedPointer<GerritParameters> &p) const;
QString url; QString url;
int number; int number = 0;
int dependsOnNumber; int dependsOnNumber = 0;
int neededByNumber; int neededByNumber = 0;
QString title; QString title;
QString owner; QString owner;
QString email; QString email;
@@ -89,7 +87,7 @@ public:
QString status; QString status;
QDateTime lastUpdated; QDateTime lastUpdated;
GerritPatchSet currentPatchSet; GerritPatchSet currentPatchSet;
int depth; int depth = -1;
}; };
typedef QSharedPointer<GerritChange> GerritChangePtr; typedef QSharedPointer<GerritChange> GerritChangePtr;

View File

@@ -1062,6 +1062,8 @@ bool SessionManager::loadSession(const QString &session)
// retrieve all values before the following code could change them again // retrieve all values before the following code could change them again
Id modeId = Id::fromSetting(value(QLatin1String("ActiveMode"))); Id modeId = Id::fromSetting(value(QLatin1String("ActiveMode")));
if (!modeId.isValid())
modeId = Id(Core::Constants::MODE_EDIT);
QColor c = QColor(reader.restoreValue(QLatin1String("Color")).toString()); QColor c = QColor(reader.restoreValue(QLatin1String("Color")).toString());
if (c.isValid()) if (c.isValid())
@@ -1083,9 +1085,10 @@ bool SessionManager::loadSession(const QString &session)
d->m_future.reportFinished(); d->m_future.reportFinished();
d->m_future = QFutureInterface<void>(); d->m_future = QFutureInterface<void>();
// restore the active mode // Fall back to Project mode if the startup project is unconfigured and
if (!modeId.isValid()) // use the mode saved in the session otherwise
modeId = Id(Core::Constants::MODE_EDIT); if (d->m_startupProject && d->m_startupProject->needsConfiguration())
modeId = Id(Constants::MODE_SESSION);
ModeManager::activateMode(modeId); ModeManager::activateMode(modeId);
ModeManager::setFocusToCurrentMode(); ModeManager::setFocusToCurrentMode();

View File

@@ -115,6 +115,7 @@ FunctionHintProposalWidget::FunctionHintProposalWidget()
connect(upArrow, SIGNAL(clicked()), SLOT(previousPage())); connect(upArrow, SIGNAL(clicked()), SLOT(previousPage()));
connect(downArrow, SIGNAL(clicked()), SLOT(nextPage())); connect(downArrow, SIGNAL(clicked()), SLOT(nextPage()));
connect(d->m_popupFrame.data(), &QObject::destroyed, this, &FunctionHintProposalWidget::abort);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
} }

View File

@@ -33,14 +33,18 @@
#include "winrtrunnerhelper.h" #include "winrtrunnerhelper.h"
#include <debugger/debuggerkitinformation.h> #include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerrunconfigurationaspect.h>
#include <debugger/debuggerruncontrol.h> #include <debugger/debuggerruncontrol.h>
#include <debugger/debuggerstartparameters.h> #include <debugger/debuggerstartparameters.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
#include <QFileInfo> #include <QFileInfo>
#include <QLocalServer> #include <QLocalServer>
#include <QLocalSocket> #include <QLocalSocket>
#include <QTcpServer>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
@@ -57,6 +61,24 @@ WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl, WinRtRunnerHelper *
connect(m_debugRunControl, SIGNAL(finished()), this, SLOT(finish())); connect(m_debugRunControl, SIGNAL(finished()), this, SLOT(finish()));
} }
bool WinRtDebugSupport::useQmlDebugging(WinRtRunConfiguration *runConfig)
{
Debugger::DebuggerRunConfigurationAspect *extraAspect =
runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>();
return extraAspect && extraAspect->useQmlDebugger();
}
bool WinRtDebugSupport::getFreePort(quint16 &qmlDebuggerPort, QString *errorMessage)
{
QTcpServer server;
if (!server.listen(QHostAddress::LocalHost, qmlDebuggerPort)) {
*errorMessage = tr("Not enough free ports for QML debugging.");
return false;
}
qmlDebuggerPort = server.serverPort();
return true;
}
WinRtDebugSupport::~WinRtDebugSupport() WinRtDebugSupport::~WinRtDebugSupport()
{ {
delete m_runner; delete m_runner;
@@ -87,6 +109,16 @@ RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runC
return 0; return 0;
} }
if (useQmlDebugging(runConfig)) {
quint16 qmlDebugPort = 0;
if (!getFreePort(qmlDebugPort, errorMessage))
return 0;
runConfig->setArguments(runConfig->arguments() + QLatin1Char(' ')
+ QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlDebuggerServices, qmlDebugPort));
params.qmlServerAddress = QHostAddress::LocalHost;
params.qmlServerPort = qmlDebugPort;
}
WinRtRunnerHelper *runner = new WinRtRunnerHelper(runConfig, errorMessage); WinRtRunnerHelper *runner = new WinRtRunnerHelper(runConfig, errorMessage);
if (!errorMessage->isEmpty()) if (!errorMessage->isEmpty())
return 0; return 0;
@@ -121,7 +153,7 @@ RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runC
server.close(); server.close();
Debugger::DebuggerRunControl *debugRunControl Debugger::DebuggerRunControl *debugRunControl
= createDebuggerRunControl(params, runConfig, errorMessage, mode); = createDebuggerRunControl(params, runConfig, errorMessage, mode);
runner->setRunControl(debugRunControl); runner->setDebugRunControl(debugRunControl);
new WinRtDebugSupport(debugRunControl, runner); new WinRtDebugSupport(debugRunControl, runner);
return debugRunControl; return debugRunControl;
} }

View File

@@ -54,6 +54,9 @@ public:
private: private:
WinRtDebugSupport(ProjectExplorer::RunControl *runControl, WinRtRunnerHelper *runner); WinRtDebugSupport(ProjectExplorer::RunControl *runControl, WinRtRunnerHelper *runner);
static bool useQmlDebugging(WinRtRunConfiguration *runConfig);
static bool getFreePort(quint16 &qmlDebuggerPort, QString *errorMessage);
ProjectExplorer::RunControl *m_debugRunControl; ProjectExplorer::RunControl *m_debugRunControl;
WinRtRunnerHelper *m_runner; WinRtRunnerHelper *m_runner;

View File

@@ -45,6 +45,7 @@
#include <qtsupport/baseqtversion.h> #include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <debugger/debuggerruncontrol.h>
#include <QDir> #include <QDir>
@@ -54,6 +55,7 @@ using namespace WinRt::Internal;
WinRtRunnerHelper::WinRtRunnerHelper(WinRtRunConfiguration *runConfiguration, QString *errormessage) WinRtRunnerHelper::WinRtRunnerHelper(WinRtRunConfiguration *runConfiguration, QString *errormessage)
: QObject() : QObject()
, m_messenger(0) , m_messenger(0)
, m_debugMessenger(0)
, m_runConfiguration(runConfiguration) , m_runConfiguration(runConfiguration)
, m_process(0) , m_process(0)
{ {
@@ -63,6 +65,7 @@ WinRtRunnerHelper::WinRtRunnerHelper(WinRtRunConfiguration *runConfiguration, QS
WinRtRunnerHelper::WinRtRunnerHelper(ProjectExplorer::RunControl *runControl) WinRtRunnerHelper::WinRtRunnerHelper(ProjectExplorer::RunControl *runControl)
: QObject(runControl) : QObject(runControl)
, m_messenger(runControl) , m_messenger(runControl)
, m_debugMessenger(0)
, m_runConfiguration(0) , m_runConfiguration(0)
, m_process(0) , m_process(0)
{ {
@@ -112,6 +115,17 @@ bool WinRtRunnerHelper::init(WinRtRunConfiguration *runConfiguration, QString *e
return true; return true;
} }
void WinRtRunnerHelper::appendMessage(const QString &message, Utils::OutputFormat format)
{
if (m_debugMessenger && (format == Utils::StdOutFormat || format == Utils::StdErrFormat)){
// We wan to filter out the waiting for connection message from the QML debug server
m_debugMessenger->showMessage(message, format == Utils::StdOutFormat ? Debugger::AppOutput
: Debugger::AppError);
} else if (m_messenger) {
m_messenger->appendMessage(message, format);
}
}
void WinRtRunnerHelper::debug(const QString &debuggerExecutable, const QString &debuggerArguments) void WinRtRunnerHelper::debug(const QString &debuggerExecutable, const QString &debuggerArguments)
{ {
m_debuggerExecutable = debuggerExecutable; m_debuggerExecutable = debuggerExecutable;
@@ -138,27 +152,22 @@ bool WinRtRunnerHelper::waitForStarted(int msecs)
return m_process->waitForStarted(msecs); return m_process->waitForStarted(msecs);
} }
void WinRtRunnerHelper::setRunControl(ProjectExplorer::RunControl *runControl) void WinRtRunnerHelper::setDebugRunControl(Debugger::DebuggerRunControl *runControl)
{ {
m_debugMessenger = runControl;
m_messenger = runControl; m_messenger = runControl;
} }
void WinRtRunnerHelper::onProcessReadyReadStdOut() void WinRtRunnerHelper::onProcessReadyReadStdOut()
{ {
QTC_ASSERT(m_process, return); QTC_ASSERT(m_process, return);
if (m_messenger) { appendMessage(QString::fromLocal8Bit(m_process->readAllStandardOutput()), Utils::StdOutFormat);
m_messenger->appendMessage(QString::fromLocal8Bit(
m_process->readAllStandardOutput()), Utils::StdOutFormat);
}
} }
void WinRtRunnerHelper::onProcessReadyReadStdErr() void WinRtRunnerHelper::onProcessReadyReadStdErr()
{ {
QTC_ASSERT(m_process, return); QTC_ASSERT(m_process, return);
if (m_messenger) { appendMessage(QString::fromLocal8Bit(m_process->readAllStandardError()), Utils::StdErrFormat);
m_messenger->appendMessage(QString::fromLocal8Bit(
m_process->readAllStandardError()), Utils::StdErrFormat);
}
} }
void WinRtRunnerHelper::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) void WinRtRunnerHelper::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
@@ -173,11 +182,8 @@ void WinRtRunnerHelper::onProcessFinished(int exitCode, QProcess::ExitStatus exi
void WinRtRunnerHelper::onProcessError(QProcess::ProcessError processError) void WinRtRunnerHelper::onProcessError(QProcess::ProcessError processError)
{ {
QTC_ASSERT(m_process, return); QTC_ASSERT(m_process, return);
if (m_messenger) { appendMessage(tr("Error while executing the WinRT Runner Tool: %1\n").arg(
m_messenger->appendMessage(tr("Error while executing the WinRT Runner Tool: %1\n").arg( m_process->errorString()), Utils::ErrorMessageFormat);
m_process->errorString()),
Utils::ErrorMessageFormat);
}
m_process->disconnect(); m_process->disconnect();
m_process->deleteLater(); m_process->deleteLater();
m_process = 0; m_process = 0;
@@ -193,16 +199,16 @@ void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf)
QtcProcess::addArg(&runnerArgs, QString::number(m_device->deviceId())); QtcProcess::addArg(&runnerArgs, QString::number(m_device->deviceId()));
} }
Utils::QtcProcess *process = 0; QtcProcess *process = 0;
bool connectProcess = false; bool connectProcess = false;
switch (conf) { switch (conf) {
case Debug: case Debug:
Utils::QtcProcess::addArg(&runnerArgs, QStringLiteral("--debug")); QtcProcess::addArg(&runnerArgs, QStringLiteral("--debug"));
Utils::QtcProcess::addArg(&runnerArgs, m_debuggerExecutable); QtcProcess::addArg(&runnerArgs, m_debuggerExecutable);
if (!m_debuggerArguments.isEmpty()) { if (!m_debuggerArguments.isEmpty()) {
Utils::QtcProcess::addArg(&runnerArgs, QStringLiteral("--debugger-arguments")); QtcProcess::addArg(&runnerArgs, QStringLiteral("--debugger-arguments"));
Utils::QtcProcess::addArg(&runnerArgs, m_debuggerArguments); QtcProcess::addArg(&runnerArgs, m_debuggerArguments);
} }
// fall through // fall through
case Start: case Start:
@@ -213,7 +219,7 @@ void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf)
process = m_process; process = m_process;
break; break;
case Stop: case Stop:
Utils::QtcProcess::addArgs(&runnerArgs, QStringLiteral("--stop")); QtcProcess::addArgs(&runnerArgs, QStringLiteral("--stop"));
process = new QtcProcess(this); process = new QtcProcess(this);
break; break;
} }
@@ -225,10 +231,7 @@ void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf)
if (!m_arguments.isEmpty()) if (!m_arguments.isEmpty())
QtcProcess::addArgs(&runnerArgs, m_arguments); QtcProcess::addArgs(&runnerArgs, m_arguments);
if (m_messenger) { appendMessage(QStringLiteral("winrtrunner ") + runnerArgs + QLatin1Char('\n'), NormalMessageFormat);
m_messenger->appendMessage(QStringLiteral("winrtrunner ") + runnerArgs + QLatin1Char('\n'),
Utils::NormalMessageFormat);
}
if (connectProcess) { if (connectProcess) {
connect(process, SIGNAL(started()), SIGNAL(started())); connect(process, SIGNAL(started()), SIGNAL(started()));

View File

@@ -43,6 +43,7 @@
namespace Utils { class QtcProcess; } namespace Utils { class QtcProcess; }
namespace ProjectExplorer { class RunControl; } namespace ProjectExplorer { class RunControl; }
namespace Debugger { class DebuggerRunControl; }
namespace WinRt { namespace WinRt {
namespace Internal { namespace Internal {
@@ -62,7 +63,7 @@ public:
void stop(); void stop();
bool waitForStarted(int msecs = 10000); bool waitForStarted(int msecs = 10000);
void setRunControl(ProjectExplorer::RunControl *runControl); void setDebugRunControl(Debugger::DebuggerRunControl *runControl);
signals: signals:
void started(); void started();
@@ -79,8 +80,10 @@ private:
enum RunConf { Start, Stop, Debug }; enum RunConf { Start, Stop, Debug };
void startWinRtRunner(const RunConf &conf); void startWinRtRunner(const RunConf &conf);
bool init(WinRtRunConfiguration *runConfiguration, QString *errorMessage); bool init(WinRtRunConfiguration *runConfiguration, QString *errorMessage);
void appendMessage(const QString &message, Utils::OutputFormat format);
ProjectExplorer::RunControl *m_messenger; ProjectExplorer::RunControl *m_messenger;
Debugger::DebuggerRunControl *m_debugMessenger;
WinRtRunConfiguration *m_runConfiguration; WinRtRunConfiguration *m_runConfiguration;
WinRtDevice::ConstPtr m_device; WinRtDevice::ConstPtr m_device;
Utils::Environment m_environment; Utils::Environment m_environment;

View File

@@ -233,7 +233,7 @@ void ClangIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message
message.file().projectPartId()); message.file().projectPartId());
client()->diagnosticsChanged(DiagnosticsChangedMessage(translationUnit.fileContainer(), client()->diagnosticsChanged(DiagnosticsChangedMessage(translationUnit.fileContainer(),
translationUnit.diagnostics().toDiagnosticContainers())); translationUnit.mainFileDiagnostics()));
} catch (const TranslationUnitDoesNotExistException &exception) { } catch (const TranslationUnitDoesNotExistException &exception) {
client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistMessage(exception.fileContainer())); client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistMessage(exception.fileContainer()));
} catch (const ProjectPartDoNotExistException &exception) { } catch (const ProjectPartDoNotExistException &exception) {

View File

@@ -138,7 +138,7 @@ DiagnosticSet Diagnostic::childDiagnostics() const
return DiagnosticSet(clang_getChildDiagnostics(cxDiagnostic)); return DiagnosticSet(clang_getChildDiagnostics(cxDiagnostic));
} }
DiagnosticContainer Diagnostic::toDiagnosticContainer() const DiagnosticContainer Diagnostic::toDiagnosticContainer(const IsAcceptedDiagnostic &isAcceptedChildDiagnostic) const
{ {
return DiagnosticContainer(text(), return DiagnosticContainer(text(),
category(), category(),
@@ -147,7 +147,14 @@ DiagnosticContainer Diagnostic::toDiagnosticContainer() const
location().toSourceLocationContainer(), location().toSourceLocationContainer(),
getSourceRangeContainers(), getSourceRangeContainers(),
getFixItContainers(), getFixItContainers(),
childDiagnostics().toDiagnosticContainers()); childDiagnostics().toDiagnosticContainers(isAcceptedChildDiagnostic));
}
DiagnosticContainer Diagnostic::toDiagnosticContainer() const
{
const auto acceptAllDiagnostics = [](const Diagnostic &) { return true; };
return toDiagnosticContainer(acceptAllDiagnostics);
} }
QVector<SourceRangeContainer> Diagnostic::getSourceRangeContainers() const QVector<SourceRangeContainer> Diagnostic::getSourceRangeContainers() const

View File

@@ -35,6 +35,7 @@
#include <clang-c/Index.h> #include <clang-c/Index.h>
#include <functional>
#include <vector> #include <vector>
class Utf8String; class Utf8String;
@@ -75,6 +76,9 @@ public:
std::vector<FixIt> fixIts() const; std::vector<FixIt> fixIts() const;
DiagnosticSet childDiagnostics() const; DiagnosticSet childDiagnostics() const;
using IsAcceptedDiagnostic = std::function<bool (const Diagnostic &)>;
DiagnosticContainer toDiagnosticContainer(
const IsAcceptedDiagnostic &isAcceptedChildDiagnostic) const;
DiagnosticContainer toDiagnosticContainer() const; DiagnosticContainer toDiagnosticContainer() const;
private: private:

View File

@@ -86,12 +86,22 @@ DiagnosticSet::ConstIterator DiagnosticSet::end() const
} }
QVector<DiagnosticContainer> DiagnosticSet::toDiagnosticContainers() const QVector<DiagnosticContainer> DiagnosticSet::toDiagnosticContainers() const
{
const auto isAcceptedDiagnostic = [](const Diagnostic &) { return true; };
return toDiagnosticContainers(isAcceptedDiagnostic);
}
QVector<DiagnosticContainer> DiagnosticSet::toDiagnosticContainers(
const Diagnostic::IsAcceptedDiagnostic &isAcceptedDiagnostic) const
{ {
QVector<DiagnosticContainer> diagnosticContainers; QVector<DiagnosticContainer> diagnosticContainers;
diagnosticContainers.reserve(size()); diagnosticContainers.reserve(size());
for (const Diagnostic &diagnostic : *this) for (const Diagnostic &diagnostic : *this) {
diagnosticContainers.push_back(diagnostic.toDiagnosticContainer()); if (isAcceptedDiagnostic(diagnostic))
diagnosticContainers.push_back(diagnostic.toDiagnosticContainer(isAcceptedDiagnostic));
}
return diagnosticContainers; return diagnosticContainers;
} }

View File

@@ -38,6 +38,8 @@
#include <QVector> #include <QVector>
#include <functional>
namespace ClangBackEnd { namespace ClangBackEnd {
class DiagnosticSetIterator; class DiagnosticSetIterator;
@@ -71,6 +73,8 @@ public:
ConstIterator end() const; ConstIterator end() const;
QVector<DiagnosticContainer> toDiagnosticContainers() const; QVector<DiagnosticContainer> toDiagnosticContainers() const;
QVector<DiagnosticContainer> toDiagnosticContainers(
const Diagnostic::IsAcceptedDiagnostic &isAcceptedDiagnostic) const;
private: private:
DiagnosticSet(CXDiagnosticSet cxDiagnosticSet); DiagnosticSet(CXDiagnosticSet cxDiagnosticSet);

View File

@@ -33,8 +33,10 @@
#include "clangstring.h" #include "clangstring.h"
#include "codecompleter.h" #include "codecompleter.h"
#include "commandlinearguments.h" #include "commandlinearguments.h"
#include "diagnosticcontainer.h"
#include "diagnosticset.h" #include "diagnosticset.h"
#include "projectpart.h" #include "projectpart.h"
#include "sourcelocation.h"
#include "translationunitfilenotexitexception.h" #include "translationunitfilenotexitexception.h"
#include "translationunitisnullexception.h" #include "translationunitisnullexception.h"
#include "translationunitparseerrorexception.h" #include "translationunitparseerrorexception.h"
@@ -218,6 +220,16 @@ DiagnosticSet TranslationUnit::diagnostics() const
return DiagnosticSet(clang_getDiagnosticSetFromTU(cxTranslationUnit())); return DiagnosticSet(clang_getDiagnosticSetFromTU(cxTranslationUnit()));
} }
QVector<ClangBackEnd::DiagnosticContainer> TranslationUnit::mainFileDiagnostics() const
{
const auto mainFilePath = filePath();
const auto isMainFileDiagnostic = [mainFilePath](const Diagnostic &diagnostic) {
return diagnostic.location().filePath() == mainFilePath;
};
return diagnostics().toDiagnosticContainers(isMainFileDiagnostic);
}
const QSet<Utf8String> &TranslationUnit::dependedFilePaths() const const QSet<Utf8String> &TranslationUnit::dependedFilePaths() const
{ {
createTranslationUnitIfNeeded(); createTranslationUnitIfNeeded();

View File

@@ -49,6 +49,7 @@ class TranslationUnitData;
class CodeCompleter; class CodeCompleter;
class UnsavedFiles; class UnsavedFiles;
class ProjectPart; class ProjectPart;
class DiagnosticContainer;
class DiagnosticSet; class DiagnosticSet;
class FileContainer; class FileContainer;
class TranslationUnits; class TranslationUnits;
@@ -102,6 +103,7 @@ public:
bool hasNewDiagnostics() const; bool hasNewDiagnostics() const;
DiagnosticSet diagnostics() const; DiagnosticSet diagnostics() const;
QVector<DiagnosticContainer> mainFileDiagnostics() const;
const QSet<Utf8String> &dependedFilePaths() const; const QSet<Utf8String> &dependedFilePaths() const;

View File

@@ -291,7 +291,7 @@ void TranslationUnits::sendDiagnosticChangedMessage(const TranslationUnit &trans
{ {
if (sendDiagnosticsChangedCallback) { if (sendDiagnosticsChangedCallback) {
DiagnosticsChangedMessage message(translationUnit.fileContainer(), DiagnosticsChangedMessage message(translationUnit.fileContainer(),
translationUnit.diagnostics().toDiagnosticContainers()); translationUnit.mainFileDiagnostics());
sendDiagnosticsChangedCallback(std::move(message)); sendDiagnosticsChangedCallback(std::move(message));
} }

View File

@@ -1022,6 +1022,55 @@ void tst_CheckSymbols::test_checksymbols_data()
<< Use(3, 3, 7, Highlighting::LocalUse) << Use(3, 3, 7, Highlighting::LocalUse)
<< Use(3, 11, 10, Highlighting::FieldUse)); << Use(3, 11, 10, Highlighting::FieldUse));
QTest::newRow("instantation_as_function_call_QTCREATORBUG15212")
<< _("struct Foo {};\n"
"template <typename Type> struct test {\n"
" test() {}\n"
" test(int, int) {}\n"
"};\n"
"void test(int int_argument) {\n"
" const int very_long_constant_of_type_int = 11111111111111111;\n"
" test<Foo> foo1;\n"
" test<Foo> foo2(int_argument, int_argument);\n"
" test<Foo> foo3(very_long_constant_of_type_int,\n"
" very_long_constant_of_type_int);\n"
" test<int> size1(int_argument, int_argument);\n"
" (void)foo1, foo2, foo3, size1;\n"
" test(int_argument);\n"
"}\n")
<< (UseList()
<< Use(1, 8, 3, Highlighting::TypeUse)
<< Use(2, 20, 4, Highlighting::TypeUse)
<< Use(2, 33, 4, Highlighting::TypeUse)
<< Use(3, 3, 4, Highlighting::TypeUse)
<< Use(4, 3, 4, Highlighting::TypeUse)
<< Use(6, 6, 4, Highlighting::FunctionUse)
<< Use(6, 15, 12, Highlighting::LocalUse)
<< Use(7, 13, 30, Highlighting::LocalUse)
<< Use(8, 3, 4, Highlighting::TypeUse)
<< Use(8, 8, 3, Highlighting::TypeUse)
<< Use(8, 13, 4, Highlighting::LocalUse)
<< Use(9, 3, 4, Highlighting::TypeUse)
<< Use(9, 8, 3, Highlighting::TypeUse)
<< Use(9, 13, 4, Highlighting::LocalUse)
<< Use(9, 18, 12, Highlighting::LocalUse)
<< Use(9, 32, 12, Highlighting::LocalUse)
<< Use(10, 3, 4, Highlighting::TypeUse)
<< Use(10, 8, 3, Highlighting::TypeUse)
<< Use(10, 13, 4, Highlighting::LocalUse)
<< Use(10, 18, 30, Highlighting::LocalUse)
<< Use(11, 18, 30, Highlighting::LocalUse)
<< Use(12, 3, 4, Highlighting::TypeUse)
<< Use(12, 13, 5, Highlighting::LocalUse)
<< Use(12, 19, 12, Highlighting::LocalUse)
<< Use(12, 33, 12, Highlighting::LocalUse)
<< Use(13, 9, 4, Highlighting::LocalUse)
<< Use(13, 15, 4, Highlighting::LocalUse)
<< Use(13, 21, 4, Highlighting::LocalUse)
<< Use(13, 27, 5, Highlighting::LocalUse)
<< Use(14, 3, 4, Highlighting::FunctionUse)
<< Use(14, 8, 12, Highlighting::LocalUse));
QTest::newRow("unicodeIdentifier1") QTest::newRow("unicodeIdentifier1")
<< _("class My" TEST_UNICODE_IDENTIFIER "Type { int " TEST_UNICODE_IDENTIFIER "Member; };\n" << _("class My" TEST_UNICODE_IDENTIFIER "Type { int " TEST_UNICODE_IDENTIFIER "Member; };\n"
"void f(My" TEST_UNICODE_IDENTIFIER "Type var" TEST_UNICODE_IDENTIFIER ")\n" "void f(My" TEST_UNICODE_IDENTIFIER "Type var" TEST_UNICODE_IDENTIFIER ")\n"

View File

@@ -0,0 +1,2 @@
void f() {}

View File

@@ -0,0 +1,4 @@
#include "diagnostic_diagnosticset_header.cpp"
void f() {}

View File

@@ -28,9 +28,15 @@
** **
****************************************************************************/ ****************************************************************************/
#include <clangbackendipc_global.h>
#include <diagnosticcontainer.h>
#include <diagnosticset.h> #include <diagnosticset.h>
#include <fixitcontainer.h>
#include <projectpart.h> #include <projectpart.h>
#include <projects.h> #include <projects.h>
#include <sourcelocation.h>
#include <sourcelocationcontainer.h>
#include <sourcerangecontainer.h>
#include <translationunit.h> #include <translationunit.h>
#include <translationunits.h> #include <translationunits.h>
#include <unsavedfiles.h> #include <unsavedfiles.h>
@@ -40,15 +46,27 @@
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gmock/gmock-matchers.h> #include <gmock/gmock-matchers.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "matcher-diagnosticcontainer.h"
#include "gtest-qt-printing.h" #include "gtest-qt-printing.h"
using ::testing::Contains;
using ::testing::Not;
using ::testing::PrintToString;
using ::ClangBackEnd::Diagnostic;
using ::ClangBackEnd::DiagnosticSet; using ::ClangBackEnd::DiagnosticSet;
using ::ClangBackEnd::TranslationUnit; using ::ClangBackEnd::DiagnosticContainer;
using ::ClangBackEnd::FixItContainer;
using ::ClangBackEnd::ProjectPart; using ::ClangBackEnd::ProjectPart;
using ::ClangBackEnd::SourceLocation;
using ::ClangBackEnd::SourceLocationContainer;
using ::ClangBackEnd::TranslationUnit;
using ::ClangBackEnd::UnsavedFiles; using ::ClangBackEnd::UnsavedFiles;
namespace { namespace {
const Utf8String headerFilePath = Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnosticset_header.cpp");
class DiagnosticSet : public ::testing::Test class DiagnosticSet : public ::testing::Test
{ {
protected: protected:
@@ -60,6 +78,15 @@ protected:
projectPart, projectPart,
Utf8StringVector(), Utf8StringVector(),
translationUnits}; translationUnits};
TranslationUnit translationUnitMainFile{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnosticset_mainfile.cpp"),
projectPart,
Utf8StringVector(),
translationUnits};
::DiagnosticSet diagnosticSetWithChildren{translationUnitMainFile.diagnostics()};
protected:
enum ChildMode { WithChild, WithoutChild };
DiagnosticContainer expectedDiagnostic(ChildMode childMode) const;
}; };
TEST_F(DiagnosticSet, SetHasContent) TEST_F(DiagnosticSet, SetHasContent)
@@ -120,4 +147,63 @@ TEST_F(DiagnosticSet, BeginPlusOneIsEqualEnd)
ASSERT_TRUE(++set.begin() == set.end()); ASSERT_TRUE(++set.begin() == set.end());
} }
TEST_F(DiagnosticSet, ToDiagnosticContainersLetThroughByDefault)
{
const auto diagnosticContainerWithoutChild = expectedDiagnostic(WithChild);
const auto diagnostics = translationUnitMainFile.diagnostics().toDiagnosticContainers();
ASSERT_THAT(diagnostics, Contains(IsDiagnosticContainer(diagnosticContainerWithoutChild)));
}
TEST_F(DiagnosticSet, ToDiagnosticContainersFiltersOutTopLevelItem)
{
const auto acceptNoDiagnostics = [](const Diagnostic &) { return false; };
const auto diagnostics = diagnosticSetWithChildren.toDiagnosticContainers(acceptNoDiagnostics);
ASSERT_TRUE(diagnostics.isEmpty());
}
TEST_F(DiagnosticSet, ToDiagnosticContainersFiltersOutChildren)
{
const auto diagnosticContainerWithoutChild = expectedDiagnostic(WithoutChild);
const auto acceptMainFileDiagnostics = [this](const Diagnostic &diagnostic) {
return diagnostic.location().filePath() == translationUnitMainFile.filePath();
};
const auto diagnostics = diagnosticSetWithChildren.toDiagnosticContainers(acceptMainFileDiagnostics);
ASSERT_THAT(diagnostics, Contains(IsDiagnosticContainer(diagnosticContainerWithoutChild)));
}
DiagnosticContainer DiagnosticSet::expectedDiagnostic(DiagnosticSet::ChildMode childMode) const
{
QVector<DiagnosticContainer> children;
if (childMode == WithChild) {
const auto child = DiagnosticContainer(
Utf8StringLiteral("note: previous definition is here"),
Utf8StringLiteral("Semantic Issue"),
{Utf8String(), Utf8String()},
ClangBackEnd::DiagnosticSeverity::Note,
SourceLocationContainer(headerFilePath, 1, 5),
{},
{},
{}
);
children.append(child);
}
return DiagnosticContainer(
Utf8StringLiteral("error: redefinition of 'f'"),
Utf8StringLiteral("Semantic Issue"),
{Utf8String(), Utf8String()},
ClangBackEnd::DiagnosticSeverity::Error,
SourceLocationContainer(translationUnitMainFile.filePath(), 3, 53),
{},
{},
children
);
}
} }

View File

@@ -29,7 +29,9 @@
****************************************************************************/ ****************************************************************************/
#include <diagnostic.h> #include <diagnostic.h>
#include <diagnosticcontainer.h>
#include <diagnosticset.h> #include <diagnosticset.h>
#include <fixitcontainer.h>
#include <projectpart.h> #include <projectpart.h>
#include <translationunit.h> #include <translationunit.h>
#include <translationunits.h> #include <translationunits.h>
@@ -43,9 +45,16 @@
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gmock/gmock-matchers.h> #include <gmock/gmock-matchers.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "gtest-qt-printing.h" #include "gtest-qt-printing.h"
#include "matcher-diagnosticcontainer.h"
using ::testing::Contains;
using ::testing::Not;
using ::testing::PrintToString;
using ClangBackEnd::DiagnosticSet; using ClangBackEnd::DiagnosticSet;
using ClangBackEnd::DiagnosticContainer;
using ClangBackEnd::TranslationUnit; using ClangBackEnd::TranslationUnit;
using ClangBackEnd::ProjectPart; using ClangBackEnd::ProjectPart;
using ClangBackEnd::UnsavedFiles; using ClangBackEnd::UnsavedFiles;
@@ -53,7 +62,8 @@ using ClangBackEnd::Diagnostic;
using ClangBackEnd::SourceLocation; using ClangBackEnd::SourceLocation;
using ClangBackEnd::DiagnosticSeverity; using ClangBackEnd::DiagnosticSeverity;
using ClangBackEnd::TranslationUnits; using ClangBackEnd::TranslationUnits;
using testing::PrintToString; using ClangBackEnd::FixItContainer;
using ClangBackEnd::SourceLocationContainer;
namespace { namespace {
@@ -87,6 +97,10 @@ protected:
translationUnits}; translationUnits};
DiagnosticSet diagnosticSet{translationUnit.diagnostics()}; DiagnosticSet diagnosticSet{translationUnit.diagnostics()};
::Diagnostic diagnostic{diagnosticSet.back()}; ::Diagnostic diagnostic{diagnosticSet.back()};
protected:
enum ChildMode { WithChild, WithoutChild };
DiagnosticContainer expectedDiagnostic(ChildMode childMode) const;
}; };
TEST_F(Diagnostic, MoveContructor) TEST_F(Diagnostic, MoveContructor)
@@ -152,4 +166,55 @@ TEST_F(Diagnostic, ChildDiagnosticsText)
ASSERT_THAT(childDiagnostic.text(), Utf8StringLiteral("note: previous declaration is here")); ASSERT_THAT(childDiagnostic.text(), Utf8StringLiteral("note: previous declaration is here"));
} }
TEST_F(Diagnostic, toDiagnosticContainerLetChildrenThroughByDefault)
{
const auto diagnosticWithChild = expectedDiagnostic(WithChild);
const auto diagnostic = diagnosticSet.front().toDiagnosticContainer();
ASSERT_THAT(diagnostic, IsDiagnosticContainer(diagnosticWithChild));
}
TEST_F(Diagnostic, toDiagnosticContainerFiltersOutChildren)
{
const auto diagnosticWithoutChild = expectedDiagnostic(WithoutChild);
const auto acceptDiagnosticWithSpecificText = [](const ::Diagnostic &diagnostic) {
return diagnostic.text() != Utf8StringLiteral("note: previous declaration is here");
};
const auto diagnostic = diagnosticSet.front().toDiagnosticContainer(acceptDiagnosticWithSpecificText);
ASSERT_THAT(diagnostic, IsDiagnosticContainer(diagnosticWithoutChild));
}
DiagnosticContainer Diagnostic::expectedDiagnostic(Diagnostic::ChildMode childMode) const
{
QVector<DiagnosticContainer> children;
if (childMode == WithChild) {
const auto child = DiagnosticContainer(
Utf8StringLiteral("note: previous declaration is here"),
Utf8StringLiteral("Semantic Issue"),
{Utf8String(), Utf8String()},
ClangBackEnd::DiagnosticSeverity::Note,
SourceLocationContainer(translationUnit.filePath(), 2, 14),
{},
{},
{}
);
children.append(child);
}
return
DiagnosticContainer(
Utf8StringLiteral("warning: 'X' is missing exception specification 'noexcept'"),
Utf8StringLiteral("Semantic Issue"),
{Utf8String(), Utf8String()},
ClangBackEnd::DiagnosticSeverity::Warning,
SourceLocationContainer(translationUnit.filePath(), 5, 38),
{},
{},
children
);
}
} }

View File

@@ -1,31 +1,25 @@
GMOCK_DIR = $$(GMOCK_DIR) GOOGLETEST_DIR = $$(GOOGLETEST_DIR)
!isEmpty(GMOCK_DIR):GTEST_DIR = $$GMOCK_DIR/gtest
linux-* { isEmpty(GOOGLETEST_DIR):linux-* {
isEmpty(GMOCK_DIR):GMOCK_DIR = /usr/include/gmock GTEST_SRC_DIR = /usr/include/gmock
!exists($$GTEST_DIR):GTEST_DIR = /usr/include/gtest GMOCK_SRC_DIR = /usr/include/gtest
} else {
GTEST_SRC_DIR = $$GOOGLETEST_DIR/googletest
GMOCK_SRC_DIR = $$GOOGLETEST_DIR/googlemock
} }
requires(exists($$GMOCK_DIR)) requires(exists($$GTEST_SRC_DIR):exists($$GMOCK_SRC_DIR))
!exists($$GMOCK_DIR):message("No gmock is found! To enabe unit tests set GMOCK_DIR") !exists($$GOOGLETEST_DIR):message("No gmock is found! To enabe unit tests set GOOGLETEST_DIR")
GTEST_SRC_DIR = $$GTEST_DIR
GMOCK_SRC_DIR = $$GMOCK_DIR
linux-* {
!exists($$GTEST_SRC_DIR/src/gtest-all.cc):GTEST_SRC_DIR = /usr/src/gtest
!exists($$GMOCK_SRC_DIR/src/gmock-all.cc):GMOCK_SRC_DIR = /usr/src/gmock
}
DEFINES += \ DEFINES += \
GTEST_HAS_STD_INITIALIZER_LIST_ \ GTEST_HAS_STD_INITIALIZER_LIST_ \
GTEST_LANG_CXX11 GTEST_LANG_CXX11
INCLUDEPATH *= \ INCLUDEPATH *= \
$$GTEST_DIR \
$$GTEST_DIR/include \
$$GMOCK_DIR \
$$GMOCK_DIR/include \
$$GTEST_SRC_DIR \ $$GTEST_SRC_DIR \
$$GMOCK_SRC_DIR $$GTEST_SRC_DIR/include \
$$GMOCK_SRC_DIR \
$$GMOCK_SRC_DIR/include \
SOURCES += \ SOURCES += \
$$GMOCK_SRC_DIR/src/gmock-all.cc \ $$GMOCK_SRC_DIR/src/gmock-all.cc \

View File

@@ -0,0 +1,63 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include <gmock/gmock.h>
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include "gtest-qt-printing.h"
namespace {
using ::testing::PrintToString;
MATCHER_P(IsDiagnosticContainer, diagnosticContainer, "")
{
if (arg.text() != diagnosticContainer.text()) {
*result_listener << "text is " + PrintToString(arg.text())
+ " and not " + PrintToString(diagnosticContainer.text());
return false;
}
if (arg.location() != diagnosticContainer.location()) {
*result_listener << "location is " + PrintToString(arg.location())
+ " and not " + PrintToString(diagnosticContainer.location());
return false;
}
if (arg.children() != diagnosticContainer.children()) {
*result_listener << "children are " + PrintToString(arg.children())
+ " and not " + PrintToString(diagnosticContainer.children());
return false;
}
return true;
}
} // anonymous

View File

@@ -59,6 +59,7 @@ HEADERS += \
gtest-qt-printing.h \ gtest-qt-printing.h \
mockipclient.h \ mockipclient.h \
mockipcserver.h \ mockipcserver.h \
spydummy.h spydummy.h \
matcher-diagnosticcontainer.h
OTHER_FILES += $$files(data/*) OTHER_FILES += $$files(data/*)