CustomToolChain: Allow MSVC output parser on non-Windows systems

To do that, move the existing enumeration-based system to a
string base. MSVC/Windows and Custom/Unix shared the same
enumeration value (3), so we must provide an operating system
aware upgrade path.

Task-number: QTCREATORBUG-16247
Change-Id: I8beeeabc09119fc501933a7287f2f982195363a2
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Andre Hartmann
2017-04-14 21:45:41 +02:00
committed by André Hartmann
parent e19620ddd5
commit 2ff642d8e4
12 changed files with 118 additions and 54 deletions

View File

@@ -122,6 +122,11 @@ void ClangParser::stdError(const QString &line)
IOutputParser::stdError(line); IOutputParser::stdError(line);
} }
Core::Id ClangParser::id()
{
return Core::Id("ProjectExplorer.OutputParser.Clang");
}
// Unit tests: // Unit tests:
#ifdef WITH_TESTS #ifdef WITH_TESTS

View File

@@ -40,6 +40,8 @@ public:
ClangParser(); ClangParser();
void stdError(const QString &line); void stdError(const QString &line);
static Core::Id id();
private: private:
QRegularExpression m_commandRegExp; QRegularExpression m_commandRegExp;
QRegularExpression m_inLineRegExp; QRegularExpression m_inLineRegExp;

View File

@@ -140,6 +140,11 @@ void CustomParser::setSettings(const CustomParserSettings &settings)
m_warning = settings.warning; m_warning = settings.warning;
} }
Core::Id CustomParser::id()
{
return Core::Id("ProjectExplorer.OutputParser.Custom");
}
bool CustomParser::hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel, bool CustomParser::hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel,
const CustomParserExpression &expression, Task::TaskType taskType) const CustomParserExpression &expression, Task::TaskType taskType)
{ {

View File

@@ -91,6 +91,8 @@ public:
void setSettings(const CustomParserSettings &settings); void setSettings(const CustomParserSettings &settings);
static Core::Id id();
private: private:
bool hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel, bool hasMatch(const QString &line, CustomParserExpression::CustomParserChannel channel,
const CustomParserExpression &expression, Task::TaskType taskType); const CustomParserExpression &expression, Task::TaskType taskType);

View File

@@ -83,7 +83,7 @@ static const char warningExampleKeyC[] = "ProjectExplorer.CustomToolChain.Warnin
CustomToolChain::CustomToolChain(Detection d) : CustomToolChain::CustomToolChain(Detection d) :
ToolChain(Constants::CUSTOM_TOOLCHAIN_TYPEID, d), ToolChain(Constants::CUSTOM_TOOLCHAIN_TYPEID, d),
m_outputParser(Gcc) m_outputParserId(GccParser::id())
{ } { }
CustomToolChain::CustomToolChain(Core::Id language, Detection d) : CustomToolChain(d) CustomToolChain::CustomToolChain(Core::Id language, Detection d) : CustomToolChain(d)
@@ -222,16 +222,17 @@ FileNameList CustomToolChain::suggestedMkspecList() const
IOutputParser *CustomToolChain::outputParser() const IOutputParser *CustomToolChain::outputParser() const
{ {
switch (m_outputParser) { if (m_outputParserId == GccParser::id())
case Gcc: return new GccParser; return new GccParser;
case Clang: return new ClangParser; if (m_outputParserId == ClangParser::id())
case LinuxIcc: return new LinuxIccParser; return new ClangParser;
#if defined(Q_OS_WIN) if (m_outputParserId == LinuxIccParser::id())
case Msvc: return new MsvcParser; return new LinuxIccParser;
#endif if (m_outputParserId == MsvcParser::id())
case Custom: return new CustomParser(m_customParserSettings); return new MsvcParser;
default: return nullptr; if (m_outputParserId == CustomParser::id())
} return new CustomParser(m_customParserSettings);
return nullptr;
} }
QStringList CustomToolChain::headerPathsList() const QStringList CustomToolChain::headerPathsList() const
@@ -326,7 +327,7 @@ QVariantMap CustomToolChain::toMap() const
data.insert(QLatin1String(headerPathsKeyC), headerPathsList()); data.insert(QLatin1String(headerPathsKeyC), headerPathsList());
data.insert(QLatin1String(cxx11FlagsKeyC), m_cxx11Flags); data.insert(QLatin1String(cxx11FlagsKeyC), m_cxx11Flags);
data.insert(QLatin1String(mkspecsKeyC), mkspecs()); data.insert(QLatin1String(mkspecsKeyC), mkspecs());
data.insert(QLatin1String(outputParserKeyC), m_outputParser); data.insert(QLatin1String(outputParserKeyC), m_outputParserId.toSetting());
data.insert(QLatin1String(errorPatternKeyC), m_customParserSettings.error.pattern()); data.insert(QLatin1String(errorPatternKeyC), m_customParserSettings.error.pattern());
data.insert(QLatin1String(errorFileNameCapKeyC), m_customParserSettings.error.fileNameCap()); data.insert(QLatin1String(errorFileNameCapKeyC), m_customParserSettings.error.fileNameCap());
data.insert(QLatin1String(errorLineNumberCapKeyC), m_customParserSettings.error.lineNumberCap()); data.insert(QLatin1String(errorLineNumberCapKeyC), m_customParserSettings.error.lineNumberCap());
@@ -355,7 +356,7 @@ bool CustomToolChain::fromMap(const QVariantMap &data)
setHeaderPaths(data.value(QLatin1String(headerPathsKeyC)).toStringList()); setHeaderPaths(data.value(QLatin1String(headerPathsKeyC)).toStringList());
m_cxx11Flags = data.value(QLatin1String(cxx11FlagsKeyC)).toStringList(); m_cxx11Flags = data.value(QLatin1String(cxx11FlagsKeyC)).toStringList();
setMkspecs(data.value(QLatin1String(mkspecsKeyC)).toString()); setMkspecs(data.value(QLatin1String(mkspecsKeyC)).toString());
m_outputParser = (OutputParser)data.value(QLatin1String(outputParserKeyC)).toInt(); setOutputParserId(Core::Id::fromSetting(data.value(QLatin1String(outputParserKeyC))));
m_customParserSettings.error.setPattern(data.value(QLatin1String(errorPatternKeyC)).toString()); m_customParserSettings.error.setPattern(data.value(QLatin1String(errorPatternKeyC)).toString());
m_customParserSettings.error.setFileNameCap(data.value(QLatin1String(errorFileNameCapKeyC)).toInt()); m_customParserSettings.error.setFileNameCap(data.value(QLatin1String(errorFileNameCapKeyC)).toInt());
m_customParserSettings.error.setLineNumberCap(data.value(QLatin1String(errorLineNumberCapKeyC)).toInt()); m_customParserSettings.error.setLineNumberCap(data.value(QLatin1String(errorLineNumberCapKeyC)).toInt());
@@ -371,8 +372,6 @@ bool CustomToolChain::fromMap(const QVariantMap &data)
static_cast<CustomParserExpression::CustomParserChannel>(data.value(QLatin1String(warningChannelKeyC)).toInt())); static_cast<CustomParserExpression::CustomParserChannel>(data.value(QLatin1String(warningChannelKeyC)).toInt()));
m_customParserSettings.warning.setExample(data.value(QLatin1String(warningExampleKeyC)).toString()); m_customParserSettings.warning.setExample(data.value(QLatin1String(warningExampleKeyC)).toString());
QTC_ASSERT(m_outputParser >= Gcc && m_outputParser < OutputParserCount, return false);
return true; return true;
} }
@@ -389,16 +388,51 @@ bool CustomToolChain::operator ==(const ToolChain &other) const
&& m_systemHeaderPaths == customTc->m_systemHeaderPaths; && m_systemHeaderPaths == customTc->m_systemHeaderPaths;
} }
CustomToolChain::OutputParser CustomToolChain::outputParserType() const Core::Id CustomToolChain::outputParserId() const
{ {
return m_outputParser; return m_outputParserId;
} }
void CustomToolChain::setOutputParserType(CustomToolChain::OutputParser parser) static Core::Id convertLegacySettings(Core::Id parserId)
{ {
if (m_outputParser == parser) enum OutputParser
{
Gcc = 0,
Clang = 1,
LinuxIcc = 2,
Msvc = 3,
Custom = 4,
OutputParserCount
};
bool ok;
const OutputParser index = static_cast<OutputParser>(parserId.toString().toInt(&ok));
if (!ok)
return parserId;
switch (index) {
case Gcc:
return GccParser::id();
case Clang:
return ClangParser::id();
case LinuxIcc:
return LinuxIccParser::id();
case Msvc:
return HostOsInfo::isWindowsHost() ? MsvcParser::id() : CustomParser::id();
case Custom:
return CustomParser::id();
default:
return parserId;
}
}
void CustomToolChain::setOutputParserId(Core::Id parserId)
{
parserId = convertLegacySettings(parserId);
if (m_outputParserId == parserId)
return; return;
m_outputParser = parser; m_outputParserId = parserId;
toolChainUpdated(); toolChainUpdated();
} }
@@ -415,18 +449,16 @@ void CustomToolChain::setCustomParserSettings(const CustomParserSettings &settin
toolChainUpdated(); toolChainUpdated();
} }
QString CustomToolChain::parserName(CustomToolChain::OutputParser parser) QList<CustomToolChain::Parser> CustomToolChain::parsers()
{ {
switch (parser) { QList<CustomToolChain::Parser> result;
case Gcc: return tr("GCC"); result.append({GccParser::id(), tr("GCC")});
case Clang: return tr("Clang"); result.append({ClangParser::id(), tr("Clang")});
case LinuxIcc: return tr("ICC"); result.append({LinuxIccParser::id(), tr("ICC")});
#if defined(Q_OS_WIN) result.append({MsvcParser::id(), tr("MSVC")});
case Msvc: return tr("MSVC"); result.append({CustomParser::id(), tr("Custom")});
#endif
case Custom: return tr("Custom"); return result;
default: return QString();
}
} }
ToolChainConfigWidget *CustomToolChain::configurationWidget() ToolChainConfigWidget *CustomToolChain::configurationWidget()
@@ -536,8 +568,9 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
{ {
Q_ASSERT(tc); Q_ASSERT(tc);
for (int i = 0; i < CustomToolChain::OutputParserCount; ++i) const QList<CustomToolChain::Parser> parsers = CustomToolChain::parsers();
m_errorParserComboBox->addItem(CustomToolChain::parserName((CustomToolChain::OutputParser)i)); for (auto parser : parsers)
m_errorParserComboBox->addItem(parser.displayName, parser.parserId.toString());
auto parserLayoutWidget = new QWidget; auto parserLayoutWidget = new QWidget;
auto parserLayout = new QHBoxLayout(parserLayoutWidget); auto parserLayout = new QHBoxLayout(parserLayoutWidget);
@@ -581,7 +614,7 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) :
this, &CustomToolChainConfigWidget::errorParserChanged); this, &CustomToolChainConfigWidget::errorParserChanged);
connect(m_customParserSettingsButton, &QAbstractButton::clicked, connect(m_customParserSettingsButton, &QAbstractButton::clicked,
this, &CustomToolChainConfigWidget::openCustomParserSettingsDialog); this, &CustomToolChainConfigWidget::openCustomParserSettingsDialog);
errorParserChanged(m_errorParserComboBox->currentIndex()); errorParserChanged();
} }
void CustomToolChainConfigWidget::updateSummaries() void CustomToolChainConfigWidget::updateSummaries()
@@ -593,9 +626,10 @@ void CustomToolChainConfigWidget::updateSummaries()
emit dirty(); emit dirty();
} }
void CustomToolChainConfigWidget::errorParserChanged(int index) void CustomToolChainConfigWidget::errorParserChanged(int )
{ {
m_customParserSettingsButton->setEnabled(index == m_errorParserComboBox->count() - 1); const auto currentId = Core::Id::fromSetting(m_errorParserComboBox->currentData());
m_customParserSettingsButton->setEnabled(currentId == CustomParser::id());
emit dirty(); emit dirty();
} }
@@ -627,7 +661,7 @@ void CustomToolChainConfigWidget::applyImpl()
tc->setCxx11Flags(m_cxx11Flags->text().split(QLatin1Char(','))); tc->setCxx11Flags(m_cxx11Flags->text().split(QLatin1Char(',')));
tc->setMkspecs(m_mkspecs->text()); tc->setMkspecs(m_mkspecs->text());
tc->setDisplayName(displayName); // reset display name tc->setDisplayName(displayName); // reset display name
tc->setOutputParserType((CustomToolChain::OutputParser)m_errorParserComboBox->currentIndex()); tc->setOutputParserId(Core::Id::fromSetting(m_errorParserComboBox->currentData()));
tc->setCustomParserSettings(m_customParserSettings); tc->setCustomParserSettings(m_customParserSettings);
} }
@@ -643,7 +677,8 @@ void CustomToolChainConfigWidget::setFromToolchain()
m_headerPaths->setPlainText(tc->headerPathsList().join(QLatin1Char('\n'))); m_headerPaths->setPlainText(tc->headerPathsList().join(QLatin1Char('\n')));
m_cxx11Flags->setText(tc->cxx11Flags().join(QLatin1Char(','))); m_cxx11Flags->setText(tc->cxx11Flags().join(QLatin1Char(',')));
m_mkspecs->setText(tc->mkspecs()); m_mkspecs->setText(tc->mkspecs());
m_errorParserComboBox->setCurrentIndex(tc->outputParserType()); int index = m_errorParserComboBox->findData(tc->outputParserId().toSetting());
m_errorParserComboBox->setCurrentIndex(index);
m_customParserSettings = tc->customParserSettings(); m_customParserSettings = tc->customParserSettings();
blockSignals(blocked); blockSignals(blocked);
} }
@@ -659,7 +694,7 @@ bool CustomToolChainConfigWidget::isDirtyImpl() const
|| m_headerDetails->entries() != tc->headerPathsList() || m_headerDetails->entries() != tc->headerPathsList()
|| m_cxx11Flags->text().split(QLatin1Char(',')) != tc->cxx11Flags() || m_cxx11Flags->text().split(QLatin1Char(',')) != tc->cxx11Flags()
|| m_mkspecs->text() != tc->mkspecs() || m_mkspecs->text() != tc->mkspecs()
|| m_errorParserComboBox->currentIndex() == tc->outputParserType() || Core::Id::fromSetting(m_errorParserComboBox->currentData()) == tc->outputParserId()
|| m_customParserSettings != tc->customParserSettings(); || m_customParserSettings != tc->customParserSettings();
} }

View File

@@ -59,16 +59,10 @@ class PROJECTEXPLORER_EXPORT CustomToolChain : public ToolChain
Q_DECLARE_TR_FUNCTIONS(CustomToolChain) Q_DECLARE_TR_FUNCTIONS(CustomToolChain)
public: public:
enum OutputParser class Parser {
{ public:
Gcc = 0, Core::Id parserId; ///< A unique id identifying a parser
Clang = 1, QString displayName; ///< A translateable name to show in the user interface
LinuxIcc = 2,
#if defined(Q_OS_WIN)
Msvc = 3,
#endif
Custom,
OutputParserCount
}; };
QString typeDisplayName() const override; QString typeDisplayName() const override;
@@ -113,11 +107,11 @@ public:
ToolChain *clone() const override; ToolChain *clone() const override;
OutputParser outputParserType() const; Core::Id outputParserId() const;
void setOutputParserType(OutputParser parser); void setOutputParserId(Core::Id parserId);
CustomParserSettings customParserSettings() const; CustomParserSettings customParserSettings() const;
void setCustomParserSettings(const CustomParserSettings &settings); void setCustomParserSettings(const CustomParserSettings &settings);
static QString parserName(OutputParser parser); static QList<CustomToolChain::Parser> parsers();
protected: protected:
CustomToolChain(const CustomToolChain &) = default; CustomToolChain(const CustomToolChain &) = default;
@@ -135,7 +129,7 @@ private:
QStringList m_cxx11Flags; QStringList m_cxx11Flags;
Utils::FileNameList m_mkspecs; Utils::FileNameList m_mkspecs;
OutputParser m_outputParser; Core::Id m_outputParserId;
CustomParserSettings m_customParserSettings; CustomParserSettings m_customParserSettings;
friend class Internal::CustomToolChainFactory; friend class Internal::CustomToolChainFactory;
@@ -175,7 +169,7 @@ public:
private: private:
void updateSummaries(); void updateSummaries();
void errorParserChanged(int index); void errorParserChanged(int index = -1);
void openCustomParserSettingsDialog(); void openCustomParserSettingsDialog();
protected: protected:

View File

@@ -144,6 +144,11 @@ void GccParser::stdOutput(const QString &line)
IOutputParser::stdOutput(line); IOutputParser::stdOutput(line);
} }
Core::Id GccParser::id()
{
return Core::Id("ProjectExplorer.OutputParser.Gcc");
}
void GccParser::newTask(const Task &task) void GccParser::newTask(const Task &task)
{ {
doFlush(); doFlush();

View File

@@ -43,6 +43,8 @@ public:
void stdError(const QString &line) override; void stdError(const QString &line) override;
void stdOutput(const QString &line) override; void stdOutput(const QString &line) override;
static Core::Id id();
protected: protected:
void newTask(const Task &task); void newTask(const Task &task);
void doFlush() override; void doFlush() override;

View File

@@ -116,6 +116,11 @@ void LinuxIccParser::stdError(const QString &line)
} }
} }
Core::Id LinuxIccParser::id()
{
return Core::Id("ProjectExplorer.OutputParser.Icc");
}
void LinuxIccParser::doFlush() void LinuxIccParser::doFlush()
{ {
if (m_temporary.isNull()) if (m_temporary.isNull())

View File

@@ -41,6 +41,8 @@ public:
void stdError(const QString &line) override; void stdError(const QString &line) override;
static Core::Id id();
private: private:
void doFlush() override; void doFlush() override;

View File

@@ -168,6 +168,11 @@ void MsvcParser::stdError(const QString &line)
IOutputParser::stdError(line); IOutputParser::stdError(line);
} }
Core::Id MsvcParser::id()
{
return Core::Id("ProjectExplorer.OutputParser.Msvc");
}
bool MsvcParser::processCompileLine(const QString &line) bool MsvcParser::processCompileLine(const QString &line)
{ {
doFlush(); doFlush();

View File

@@ -43,6 +43,8 @@ public:
void stdOutput(const QString &line) override; void stdOutput(const QString &line) override;
void stdError(const QString &line) override; void stdError(const QString &line) override;
static Core::Id id();
private: private:
void doFlush() override; void doFlush() override;
bool processCompileLine(const QString &line); bool processCompileLine(const QString &line);