diff options
13 files changed, 91 insertions, 133 deletions
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzer.pro b/plugins/clangstaticanalyzer/clangstaticanalyzer.pro index 67eb90ad41..cdffb1f1d1 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzer.pro +++ b/plugins/clangstaticanalyzer/clangstaticanalyzer.pro @@ -10,7 +10,6 @@ SOURCES += \ clangstaticanalyzerdiagnosticmodel.cpp \ clangstaticanalyzerdiagnosticview.cpp \ clangstaticanalyzerlogfilereader.cpp \ - clangstaticanalyzerpathchooser.cpp \ clangstaticanalyzerplugin.cpp \ clangstaticanalyzerprojectsettings.cpp \ clangstaticanalyzerprojectsettingsmanager.cpp \ @@ -30,7 +29,6 @@ HEADERS += \ clangstaticanalyzerdiagnosticview.h \ clangstaticanalyzer_global.h \ clangstaticanalyzerlogfilereader.h \ - clangstaticanalyzerpathchooser.h \ clangstaticanalyzerplugin.h \ clangstaticanalyzerprojectsettings.h \ clangstaticanalyzerprojectsettingsmanager.h \ diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs b/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs index 098c4186c2..2ccc31337c 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs +++ b/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs @@ -33,8 +33,6 @@ QtcPlugin { "clangstaticanalyzerdiagnosticview.h", "clangstaticanalyzerlogfilereader.cpp", "clangstaticanalyzerlogfilereader.h", - "clangstaticanalyzerpathchooser.cpp", - "clangstaticanalyzerpathchooser.h", "clangstaticanalyzerplugin.cpp", "clangstaticanalyzerplugin.h", "clangstaticanalyzerprojectsettings.cpp", diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp index ced034aa6c..d73fd5436a 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp @@ -19,6 +19,8 @@ #include "clangstaticanalyzerconfigwidget.h" #include "ui_clangstaticanalyzerconfigwidget.h" +#include "clangstaticanalyzerutils.h" + #include <QThread> namespace ClangStaticAnalyzer { @@ -33,7 +35,16 @@ ClangStaticAnalyzerConfigWidget::ClangStaticAnalyzerConfigWidget( { m_ui->setupUi(this); - m_ui->clangExecutableChooser->setPath(settings->clangExecutable()); + Utils::PathChooser * const chooser = m_ui->clangExecutableChooser; + chooser->setExpectedKind(Utils::PathChooser::ExistingCommand); + chooser->setHistoryCompleter(QLatin1String("ClangStaticAnalyzer.ClangCommand.History")); + chooser->setPromptDialogTitle(tr("Clang Command")); + chooser->setPath(settings->clangExecutable()); + const auto validator = [chooser](Utils::FancyLineEdit *edit, QString *errorMessage) { + return chooser->defaultValidationFunction()(edit, errorMessage) + && isClangExecutableUsable(chooser->fileName().toString(), errorMessage); + }; + chooser->setValidationFunction(validator); connect(m_ui->clangExecutableChooser, &Utils::PathChooser::changed, [settings](const QString &path) { settings->setClangExecutable(path); }); diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui b/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui index 8997f3a7d1..800733a331 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui @@ -30,7 +30,7 @@ <item row="0" column="1"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="ClangStaticAnalyzer::Internal::PathChooser" name="clangExecutableChooser" native="true"/> + <widget class="Utils::PathChooser" name="clangExecutableChooser" native="true"/> </item> </layout> </item> @@ -88,9 +88,9 @@ </widget> <customwidgets> <customwidget> - <class>ClangStaticAnalyzer::Internal::PathChooser</class> + <class>Utils::PathChooser</class> <extends>QWidget</extends> - <header location="global">clangstaticanalyzer/clangstaticanalyzerpathchooser.h</header> + <header location="global">utils/pathchooser.h</header> <container>1</container> </customwidget> </customwidgets> diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerpathchooser.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerpathchooser.cpp deleted file mode 100644 index b5711bfeab..0000000000 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerpathchooser.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd -** All rights reserved. -** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us -** -** This file is part of the Qt Enterprise LicenseChecker Add-on. -** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. -** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io/contact-us -** -****************************************************************************/ -#include "clangstaticanalyzerpathchooser.h" - -#include "clangstaticanalyzerutils.h" - -namespace ClangStaticAnalyzer { -namespace Internal { - -PathChooser::PathChooser(QWidget *parent) : Utils::PathChooser(parent) -{ - setExpectedKind(Utils::PathChooser::ExistingCommand); - setHistoryCompleter(QLatin1String("ClangStaticAnalyzer.ClangCommand.History")); - setPromptDialogTitle(tr("Clang Command")); -} - -bool PathChooser::validatePath(const QString &path, QString *errorMessage) -{ - if (!Utils::PathChooser::validatePath(path, errorMessage)) - return false; - return isClangExecutableUsable(fileName().toString(), errorMessage); -} - -} // namespace Internal -} // namespace ClangStaticAnalyzer diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerpathchooser.h b/plugins/clangstaticanalyzer/clangstaticanalyzerpathchooser.h deleted file mode 100644 index b4bc3c5947..0000000000 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerpathchooser.h +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd -** All rights reserved. -** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us -** -** This file is part of the Qt Enterprise LicenseChecker Add-on. -** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. -** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io/contact-us -** -****************************************************************************/ -#ifndef QTC_CLANGSTATICANALYZER_PATHCHOOSER_H -#define QTC_CLANGSTATICANALYZER_PATHCHOOSER_H - -#include <utils/pathchooser.h> - -namespace ClangStaticAnalyzer { -namespace Internal { - -class PathChooser : public Utils::PathChooser -{ - Q_OBJECT - -public: - PathChooser(QWidget *parent = 0); - -private: - bool validatePath(const QString &path, QString *errorMessage = 0); -}; - -} // namespace Internal -} // namespace ClangStaticAnalyzer - -#endif // Include guard. diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index 0bdbe1da0c..6bf9582e37 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -146,14 +146,13 @@ static QStringList argumentsFromProjectPart(const CppTools::ProjectPart::Ptr &pr return result; } -static QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyzeFromCompilerCallData( +static AnalyzeUnits unitsToAnalyzeFromCompilerCallData( const ProjectInfo::CompilerCallData &compilerCallData, unsigned char wordWidth) { - typedef ClangStaticAnalyzerRunControl::AnalyzeUnit AnalyzeUnit; qCDebug(LOG) << "Taking arguments for analyzing from CompilerCallData."; - QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyze; + AnalyzeUnits unitsToAnalyze; QHashIterator<QString, QList<QStringList> > it(compilerCallData); while (it.hasNext()) { @@ -169,15 +168,13 @@ static QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyzeFromCompi return unitsToAnalyze; } -static QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyzeFromProjectParts( - const QList<ProjectPart::Ptr> projectParts, - const QString &toolchainType, - unsigned char wordWidth) +static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QList<ProjectPart::Ptr> projectParts, + const QString &toolchainType, + unsigned char wordWidth) { - typedef ClangStaticAnalyzerRunControl::AnalyzeUnit AnalyzeUnit; qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts."; - QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyze; + AnalyzeUnits unitsToAnalyze; foreach (const ProjectPart::Ptr &projectPart, projectParts) { if (!projectPart->selectedForBuilding) @@ -200,16 +197,38 @@ static QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyzeFromProje return unitsToAnalyze; } -QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> ClangStaticAnalyzerRunControl::unitsToAnalyze() +AnalyzeUnits ClangStaticAnalyzerRunControl::sortedUnitsToAnalyze() { - QTC_ASSERT(m_projectInfo.isValid(), return QList<ClangStaticAnalyzerRunControl::AnalyzeUnit>()); + QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits()); + AnalyzeUnits units; const ProjectInfo::CompilerCallData compilerCallData = m_projectInfo.compilerCallData(); - if (!compilerCallData.isEmpty()) - return unitsToAnalyzeFromCompilerCallData(compilerCallData, m_wordWidth); - return unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(), - m_toolchainType, - m_wordWidth); + if (compilerCallData.isEmpty()) { + units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(), + m_toolchainType, + m_wordWidth); + } else { + units = unitsToAnalyzeFromCompilerCallData(compilerCallData, m_wordWidth); + } + + Utils::sort(units, [](const AnalyzeUnit &a1, const AnalyzeUnit &a2) -> bool { + return a1.file < a2.file; + }); + return units; +} + +static QDebug operator<<(QDebug debug, const Utils::Environment &environment) +{ + foreach (const QString &entry, environment.toStringList()) + debug << "\n " << entry; + return debug; +} + +static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits) +{ + foreach (const AnalyzeUnit &unit, analyzeUnits) + debug << "\n " << unit.file; + return debug; } bool ClangStaticAnalyzerRunControl::startEngine() @@ -250,14 +269,8 @@ bool ClangStaticAnalyzerRunControl::startEngine() m_clangLogFileDir = temporaryDir.path(); // Collect files - QList<AnalyzeUnit> unitsToProcess = unitsToAnalyze(); - Utils::sort(unitsToProcess, [](const AnalyzeUnit &a1, const AnalyzeUnit &a2) -> bool { - return a1.file < a2.file; - }); - - qCDebug(LOG) << "Files to process:"; - foreach (const AnalyzeUnit &fileConfig, unitsToProcess) - qCDebug(LOG) << fileConfig.file; + const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(); + qCDebug(LOG) << "Files to process:" << unitsToProcess; m_unitsToProcess = unitsToProcess; m_initialFilesToProcessSize = m_unitsToProcess.count(); m_filesAnalyzed = 0; @@ -275,6 +288,7 @@ bool ClangStaticAnalyzerRunControl::startEngine() m_progress.reportStarted(); // Start process(es) + qCDebug(LOG) << "Environment:" << startParameters().environment; m_runners.clear(); const int parallelRuns = ClangStaticAnalyzerSettings::instance()->simultaneousProcesses(); QTC_ASSERT(parallelRuns >= 1, emit finished(); return false); @@ -340,7 +354,10 @@ ClangStaticAnalyzerRunner *ClangStaticAnalyzerRunControl::createRunner() QTC_ASSERT(!m_clangLogFileDir.isEmpty(), return 0); ClangStaticAnalyzerRunner *runner - = new ClangStaticAnalyzerRunner(m_clangExecutable, m_clangLogFileDir, this); + = new ClangStaticAnalyzerRunner(m_clangExecutable, + m_clangLogFileDir, + startParameters().environment, + this); connect(runner, &ClangStaticAnalyzerRunner::finishedWithSuccess, this, &ClangStaticAnalyzerRunControl::onRunnerFinishedWithSuccess); connect(runner, &ClangStaticAnalyzerRunner::finishedWithFailure, diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h index f5782714f5..7a4729babe 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h @@ -31,20 +31,20 @@ namespace Internal { class ClangStaticAnalyzerRunner; class Diagnostic; +struct AnalyzeUnit { + AnalyzeUnit(const QString &file, const QStringList &options) + : file(file), arguments(options) {} + + QString file; + QStringList arguments; // without file itself and "-o somePath" +}; +typedef QList<AnalyzeUnit> AnalyzeUnits; + class ClangStaticAnalyzerRunControl : public Analyzer::AnalyzerRunControl { Q_OBJECT public: - struct AnalyzeUnit { - AnalyzeUnit(const QString &file, const QStringList &options) - : file(file), arguments(options) {} - - QString file; - QStringList arguments; // without file itself and "-o somePath" - }; - -public: explicit ClangStaticAnalyzerRunControl(const Analyzer::AnalyzerStartParameters &startParams, ProjectExplorer::RunConfiguration *runConfiguration, const CppTools::ProjectInfo &projectInfo); @@ -58,7 +58,7 @@ signals: void newDiagnosticsAvailable(const QList<Diagnostic> &diagnostics); private: - QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyze(); + AnalyzeUnits sortedUnitsToAnalyze(); void analyzeNextFile(); ClangStaticAnalyzerRunner *createRunner(); @@ -77,7 +77,7 @@ private: QString m_clangExecutable; QString m_clangLogFileDir; QFutureInterface<void> m_progress; - QList<AnalyzeUnit> m_unitsToProcess; + AnalyzeUnits m_unitsToProcess; QSet<ClangStaticAnalyzerRunner *> m_runners; int m_initialFilesToProcessSize; int m_filesAnalyzed; diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp index 9e8d69a4df..0b54fa2af3 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp @@ -25,6 +25,7 @@ #include <cpptools/cppmodelmanager.h> #include <cpptools/cppprojects.h> +#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/gcctoolchain.h> #include <projectexplorer/kit.h> #include <projectexplorer/kitinformation.h> @@ -74,8 +75,12 @@ RunControl *ClangStaticAnalyzerRunControlFactory::create(RunConfiguration *runCo const ProjectInfo projectInfoBeforeBuild = m_tool->projectInfoBeforeBuild(); QTC_ASSERT(projectInfoBeforeBuild.isValid(), return 0); - Project *project = SessionManager::startupProject(); + QTC_ASSERT(runConfiguration, return 0); + Target * const target = runConfiguration->target(); + QTC_ASSERT(target, return 0); + Project * const project = target->project(); QTC_ASSERT(project, return 0); + const ProjectInfo projectInfoAfterBuild = CppModelManager::instance()->projectInfo(project); if (projectInfoAfterBuild.configurationOrFilesChanged(projectInfoBeforeBuild)) { @@ -95,6 +100,10 @@ RunControl *ClangStaticAnalyzerRunControlFactory::create(RunConfiguration *runCo AnalyzerStartParameters sp; sp.runMode = runMode; sp.startMode = StartLocal; + BuildConfiguration * const buildConfiguration = target->activeBuildConfiguration(); + QTC_ASSERT(buildConfiguration, return 0); + sp.environment = buildConfiguration->environment(); + return AnalyzerManager::createRunControl(sp, runConfiguration); } diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp index be3cc8607d..be934bbc8c 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp @@ -64,6 +64,7 @@ QString finishedWithBadExitCode(int exitCode) ClangStaticAnalyzerRunner::ClangStaticAnalyzerRunner(const QString &clangExecutable, const QString &clangLogFileDir, + const Utils::Environment &environment, QObject *parent) : QObject(parent) , m_clangExecutable(clangExecutable) @@ -73,6 +74,7 @@ ClangStaticAnalyzerRunner::ClangStaticAnalyzerRunner(const QString &clangExecuta QTC_CHECK(!m_clangLogFileDir.isEmpty()); m_process.setProcessChannelMode(QProcess::MergedChannels); + m_process.setProcessEnvironment(environment.toProcessEnvironment()); m_process.setWorkingDirectory(m_clangLogFileDir); // Current clang-cl puts log file into working dir. connect(&m_process, &QProcess::started, this, &ClangStaticAnalyzerRunner::onProcessStarted); diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h index 6164d6ab80..62f8152771 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h @@ -37,6 +37,7 @@ class ClangStaticAnalyzerRunner : public QObject public: ClangStaticAnalyzerRunner(const QString &clangExecutable, const QString &clangLogFileDir, + const Utils::Environment &environment, QObject *parent = 0); ~ClangStaticAnalyzerRunner(); diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index ce5fc9b3d3..38e715dfc1 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -166,7 +166,7 @@ AnalyzerRunControl *ClangStaticAnalyzerTool::createRunControl( // Some projects provides CompilerCallData once a build is finished, // so pass on the updated Project Info unless no configuration change // (defines/includes/files) happened. - Project *project = SessionManager::startupProject(); + Project *project = runConfiguration->target()->project(); QTC_ASSERT(project, return 0); const CppTools::ProjectInfo projectInfoAfterBuild = CppTools::CppModelManager::instance()->projectInfo(project); @@ -185,9 +185,8 @@ AnalyzerRunControl *ClangStaticAnalyzerTool::createRunControl( return engine; } -static bool dontStartAfterHintForDebugMode() +static bool dontStartAfterHintForDebugMode(Project *project) { - const Project *project = SessionManager::startupProject(); BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown; if (project) { if (const Target *target = project->activeTarget()) { @@ -222,13 +221,14 @@ void ClangStaticAnalyzerTool::startTool() { AnalyzerManager::showMode(); - if (dontStartAfterHintForDebugMode()) + Project *project = SessionManager::startupProject(); + QTC_ASSERT(project, emit finished(false); return); + + if (dontStartAfterHintForDebugMode(project)) return; m_diagnosticModel->clear(); setBusyCursor(true); - Project *project = SessionManager::startupProject(); - QTC_ASSERT(project, emit finished(false); return); m_diagnosticFilterModel->setProject(project); m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(project); QTC_ASSERT(m_projectInfoBeforeBuild.isValid(), emit finished(false); return); diff --git a/plugins/clangstaticanalyzer/tests/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp b/plugins/clangstaticanalyzer/tests/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp index 428213717f..53d31b1d7e 100644 --- a/plugins/clangstaticanalyzer/tests/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp +++ b/plugins/clangstaticanalyzer/tests/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp @@ -141,7 +141,8 @@ void ClangStaticAnalyzerRunnerTest::runWithTestCodeGeneratedOneIssue() QTemporaryDir temporaryDir(QDir::tempPath() + QLatin1String("/qtc-clangstaticanalyzer-XXXXXX")); QVERIFY(temporaryDir.isValid()); - ClangStaticAnalyzerRunner runner(QLatin1String("clang"), temporaryDir.path()); + ClangStaticAnalyzerRunner runner(QLatin1String("clang"), temporaryDir.path(), + Utils::Environment::systemEnvironment()); ClangStaticAnalyzerRunnerSignalTester st(&runner); QVERIFY(runner.run(testFilePath)); @@ -153,7 +154,8 @@ void ClangStaticAnalyzerRunnerTest::runWithNonExistentFileToAnalyze() { QTemporaryDir temporaryDir(QDir::tempPath() + QLatin1String("/qtc-clangstaticanalyzer-XXXXXX")); QVERIFY(temporaryDir.isValid()); - ClangStaticAnalyzerRunner runner(QLatin1String("clang"), temporaryDir.path()); + ClangStaticAnalyzerRunner runner(QLatin1String("clang"), temporaryDir.path(), + Utils::Environment::systemEnvironment()); ClangStaticAnalyzerRunnerSignalTester st(&runner); QVERIFY(runner.run(QLatin1String("not.existing.file.111"))); |