diff options
Diffstat (limited to 'src/plugins/nim/project')
20 files changed, 351 insertions, 412 deletions
diff --git a/src/plugins/nim/project/nimbuildconfiguration.cpp b/src/plugins/nim/project/nimbuildconfiguration.cpp index 0827a29327..c6c745f9e6 100644 --- a/src/plugins/nim/project/nimbuildconfiguration.cpp +++ b/src/plugins/nim/project/nimbuildconfiguration.cpp @@ -24,12 +24,9 @@ ****************************************************************************/ #include "nimbuildconfiguration.h" +#include "nimbuildsystem.h" #include "nimcompilerbuildstep.h" #include "nimproject.h" -#include "nimbuildconfiguration.h" -#include "nimcompilerbuildstep.h" -#include "nimcompilercleanstep.h" -#include "nimproject.h" #include "../nimconstants.h" @@ -52,13 +49,14 @@ using namespace Utils; namespace Nim { static FilePath defaultBuildDirectory(const Kit *k, - const QString &projectFilePath, + const FilePath &projectFilePath, const QString &bc, BuildConfiguration::BuildType buildType) { - QFileInfo projectFileInfo(projectFilePath); + QFileInfo projectFileInfo = projectFilePath.toFileInfo(); - ProjectMacroExpander expander(projectFilePath, projectFileInfo.baseName(), k, bc, buildType); + ProjectMacroExpander expander(projectFilePath, + projectFileInfo.baseName(), k, bc, buildType); QString buildDirectory = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate()); if (FileUtils::isAbsolutePath(buildDirectory)) @@ -76,25 +74,25 @@ NimBuildConfiguration::NimBuildConfiguration(Target *target, Core::Id id) setBuildDirectorySettingsKey("Nim.NimBuildConfiguration.BuildDirectory"); } -void NimBuildConfiguration::initialize(const BuildInfo &info) +void NimBuildConfiguration::initialize() { - BuildConfiguration::initialize(info); + BuildConfiguration::initialize(); - auto project = qobject_cast<NimProject *>(target()->project()); - QTC_ASSERT(project, return); + auto bs = qobject_cast<NimBuildSystem *>(project()->buildSystem()); + QTC_ASSERT(bs, return ); // Create the build configuration and initialize it from build info setBuildDirectory(defaultBuildDirectory(target()->kit(), - project->projectFilePath().toString(), - info.displayName, - info.buildType)); + project()->projectFilePath(), + displayName(), + buildType())); // Add nim compiler build step { BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); auto nimCompilerBuildStep = new NimCompilerBuildStep(buildSteps); NimCompilerBuildStep::DefaultBuildOptions defaultOption; - switch (info.buildType) { + switch (initialBuildType()) { case BuildConfiguration::Release: defaultOption = NimCompilerBuildStep::DefaultBuildOptions::Release; break; @@ -106,7 +104,7 @@ void NimBuildConfiguration::initialize(const BuildInfo &info) break; } nimCompilerBuildStep->setDefaultCompilerOptions(defaultOption); - Utils::FilePathList nimFiles = project->nimFiles(); + Utils::FilePathList nimFiles = bs->nimFiles(); if (!nimFiles.isEmpty()) nimCompilerBuildStep->setTargetNimFile(nimFiles.first()); buildSteps->appendStep(nimCompilerBuildStep); @@ -115,15 +113,10 @@ void NimBuildConfiguration::initialize(const BuildInfo &info) // Add clean step { BuildStepList *cleanSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN); - cleanSteps->appendStep(new NimCompilerCleanStep(cleanSteps)); + cleanSteps->appendStep(Constants::C_NIMCOMPILERCLEANSTEP_ID); } } -BuildConfiguration::BuildType NimBuildConfiguration::buildType() const -{ - return BuildConfiguration::Unknown; -} - FilePath NimBuildConfiguration::cacheDirectory() const { return buildDirectory().pathAppended("nimcache"); @@ -154,48 +147,30 @@ NimBuildConfigurationFactory::NimBuildConfigurationFactory() setSupportedProjectMimeTypeName(Constants::C_NIM_PROJECT_MIMETYPE); } -QList<BuildInfo> NimBuildConfigurationFactory::availableBuilds(const Target *parent) const -{ - QList<BuildInfo> result; - for (auto buildType : {BuildConfiguration::Debug, BuildConfiguration::Release}) - result.push_back(createBuildInfo(parent->kit(), buildType)); - return result; -} - -QList<BuildInfo> NimBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const +QList<BuildInfo> NimBuildConfigurationFactory::availableBuilds + (const Kit *k, const FilePath &projectPath, bool forSetup) const { QList<BuildInfo> result; for (auto buildType : {BuildConfiguration::Debug, BuildConfiguration::Release}) { - BuildInfo info = createBuildInfo(k, buildType); - info.displayName = info.typeName; - info.buildDirectory = defaultBuildDirectory(k, projectPath, info.typeName, buildType); + BuildInfo info(this); + info.buildType = buildType; + info.kitId = k->id(); + + if (buildType == BuildConfiguration::Debug) + info.typeName = tr("Debug"); + else if (buildType == BuildConfiguration::Profile) + info.typeName = tr("Profile"); + else if (buildType == BuildConfiguration::Release) + info.typeName = tr("Release"); + + if (forSetup) { + info.displayName = info.typeName; + info.buildDirectory = defaultBuildDirectory(k, projectPath, info.typeName, buildType); + } result.push_back(info); } return result; } -BuildInfo NimBuildConfigurationFactory::createBuildInfo(const Kit *k, BuildConfiguration::BuildType buildType) const -{ - BuildInfo info(this); - info.buildType = buildType; - info.kitId = k->id(); - info.typeName = displayName(buildType); - return info; -} - -QString NimBuildConfigurationFactory::displayName(BuildConfiguration::BuildType buildType) const -{ - switch (buildType) { - case ProjectExplorer::BuildConfiguration::Debug: - return tr("Debug"); - case ProjectExplorer::BuildConfiguration::Profile: - return tr("Profile"); - case ProjectExplorer::BuildConfiguration::Release: - return tr("Release"); - default: - return QString(); - } -} - } // namespace Nim diff --git a/src/plugins/nim/project/nimbuildconfiguration.h b/src/plugins/nim/project/nimbuildconfiguration.h index 3c1819e01d..d5c4a293e4 100644 --- a/src/plugins/nim/project/nimbuildconfiguration.h +++ b/src/plugins/nim/project/nimbuildconfiguration.h @@ -39,8 +39,7 @@ class NimBuildConfiguration : public ProjectExplorer::BuildConfiguration friend class ProjectExplorer::BuildConfigurationFactory; NimBuildConfiguration(ProjectExplorer::Target *target, Core::Id id); - void initialize(const ProjectExplorer::BuildInfo &info) override; - ProjectExplorer::BuildConfiguration::BuildType buildType() const override; + void initialize() override; public: Utils::FilePath cacheDirectory() const; @@ -63,15 +62,9 @@ public: NimBuildConfigurationFactory(); private: - QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override; - - QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k, - const QString &projectPath) const override; - - ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k, - ProjectExplorer::BuildConfiguration::BuildType buildType) const; - - QString displayName(ProjectExplorer::BuildConfiguration::BuildType buildType) const; + QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *k, + const Utils::FilePath &projectPath, + bool forSetup) const override; }; } diff --git a/src/plugins/nim/project/nimbuildsystem.cpp b/src/plugins/nim/project/nimbuildsystem.cpp new file mode 100644 index 0000000000..d5d34452d4 --- /dev/null +++ b/src/plugins/nim/project/nimbuildsystem.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) Filippo Cucchetto <filippocucchetto@gmail.com> +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "nimbuildsystem.h" + +#include "nimproject.h" +#include "nimprojectnode.h" + +#include <utils/algorithm.h> +#include <utils/fileutils.h> +#include <utils/qtcassert.h> + +#include <QVariantMap> + +#if 0 +#include "nimbuildconfiguration.h" +#include "nimtoolchain.h" + +#include "../nimconstants.h" + +#include <coreplugin/icontext.h> +#include <coreplugin/progressmanager/progressmanager.h> +#include <coreplugin/iversioncontrol.h> +#include <coreplugin/vcsmanager.h> +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/kit.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/projectnodes.h> +#include <projectexplorer/target.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/kitinformation.h> +#include <texteditor/textdocument.h> + +#include <utils/runextensions.h> + +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/editormanager/ieditor.h> + +#include <QFileInfo> +#include <QQueue> +#endif + +using namespace ProjectExplorer; +using namespace Utils; + +namespace Nim { + +const char SETTINGS_KEY[] = "Nim.BuildSystem"; +const char EXCLUDED_FILES_KEY[] = "ExcludedFiles"; + +NimBuildSystem::NimBuildSystem(Project *project) + : BuildSystem(project) +{ + connect(project, &Project::settingsLoaded, this, &NimBuildSystem::loadSettings); + connect(project, &Project::aboutToSaveSettings, this, &NimBuildSystem::saveSettings); + + connect(&m_scanner, &TreeScanner::finished, this, &NimBuildSystem::updateProject); + m_scanner.setFilter([this](const Utils::MimeType &, const Utils::FilePath &fp) { + const QString path = fp.toString(); + return excludedFiles().contains(path) || path.endsWith(".nimproject") + || path.contains(".nimproject.user"); + }); + + connect(&m_directoryWatcher, &FileSystemWatcher::directoryChanged, this, [this]() { + requestParse(); + }); +} + +bool NimBuildSystem::addFiles(const QStringList &filePaths) +{ + m_excludedFiles = Utils::filtered(m_excludedFiles, [&](const QString & f) { + return !filePaths.contains(f); + }); + requestParse(); + return true; +} + +bool NimBuildSystem::removeFiles(const QStringList &filePaths) +{ + m_excludedFiles.append(filePaths); + m_excludedFiles = Utils::filteredUnique(m_excludedFiles); + requestParse(); + return true; +} + +bool NimBuildSystem::renameFile(const QString &filePath, const QString &newFilePath) +{ + Q_UNUSED(filePath) + m_excludedFiles.removeOne(newFilePath); + requestParse(); + return true; +} + +void NimBuildSystem::setExcludedFiles(const QStringList &list) +{ + m_excludedFiles = list; +} + +QStringList NimBuildSystem::excludedFiles() +{ + return m_excludedFiles; +} + +void NimBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx) +{ + QTC_ASSERT(!m_currentContext.project, return ); + m_currentContext = std::move(ctx); + QTC_CHECK(m_currentContext.project); + + m_scanner.asyncScanForFiles(m_currentContext.project->projectDirectory()); +} + +const FilePathList NimBuildSystem::nimFiles() const +{ + return project()->files( + [](const Node *n) { return Project::AllFiles(n) && n->path().endsWith(".nim"); }); +} + +void NimBuildSystem::loadSettings() +{ + QVariantMap settings = project()->namedSettings(SETTINGS_KEY).toMap(); + if (settings.contains(EXCLUDED_FILES_KEY)) + m_excludedFiles = settings.value(EXCLUDED_FILES_KEY, m_excludedFiles).toStringList(); + + requestParse(); +} + +void NimBuildSystem::saveSettings() +{ + QVariantMap settings; + settings.insert(EXCLUDED_FILES_KEY, m_excludedFiles); + project()->setNamedSettings(SETTINGS_KEY, settings); +} + +void NimBuildSystem::updateProject() +{ + auto newRoot = std::make_unique<NimProjectNode>(project()->projectDirectory()); + + QSet<QString> directories; + for (FileNode *node : m_scanner.release()) { + if (!node->path().endsWith(".nim")) + node->setEnabled(false); // Disable files that do not end in .nim + directories.insert(node->directory()); + newRoot->addNestedNode(std::unique_ptr<FileNode>(node)); + } + + newRoot->setDisplayName(project()->displayName()); + project()->setRootProjectNode(std::move(newRoot)); + + m_directoryWatcher.addDirectories(Utils::toList(directories), FileSystemWatcher::WatchAllChanges); + + m_currentContext.guard.markAsSuccess(); + + m_currentContext = {}; +} + +} // namespace Nim diff --git a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.h b/src/plugins/nim/project/nimbuildsystem.h index 3de9964856..dde498f452 100644 --- a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.h +++ b/src/plugins/nim/project/nimbuildsystem.h @@ -25,27 +25,45 @@ #pragma once -#include <projectexplorer/buildstep.h> +#include <projectexplorer/buildsystem.h> +#include <projectexplorer/treescanner.h> -namespace Nim { - -class NimCompilerCleanStep; +#include <utils/filesystemwatcher.h> -namespace Ui { class NimCompilerCleanStepConfigWidget; } +namespace Nim { -class NimCompilerCleanStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget +class NimBuildSystem : public ProjectExplorer::BuildSystem { Q_OBJECT public: - NimCompilerCleanStepConfigWidget(NimCompilerCleanStep *cleanStep); + explicit NimBuildSystem(ProjectExplorer::Project *project); + + bool addFiles(const QStringList &filePaths); + bool removeFiles(const QStringList &filePaths); + bool renameFile(const QString &filePath, const QString &newFilePath); + + void setExcludedFiles(const QStringList &list); // Keep for compatibility with Qt Creator 4.10 + QStringList excludedFiles(); // Make private when no longer supporting Qt Creator 4.10 - ~NimCompilerCleanStepConfigWidget(); + void parseProject(ParsingContext &&ctx) final; + + const Utils::FilePathList nimFiles() const; private: - void updateUi(); + void loadSettings(); + void saveSettings(); + + void collectProjectFiles(); + void updateProject(); + + QStringList m_excludedFiles; + + ProjectExplorer::TreeScanner m_scanner; + + ParsingContext m_currentContext; - QScopedPointer<Ui::NimCompilerCleanStepConfigWidget> m_ui; + Utils::FileSystemWatcher m_directoryWatcher; }; -} +} // namespace Nim diff --git a/src/plugins/nim/project/nimcompilerbuildstep.cpp b/src/plugins/nim/project/nimcompilerbuildstep.cpp index 1ecc7e8c63..d9cd7599b2 100644 --- a/src/plugins/nim/project/nimcompilerbuildstep.cpp +++ b/src/plugins/nim/project/nimcompilerbuildstep.cpp @@ -25,9 +25,9 @@ #include "nimcompilerbuildstep.h" #include "nimbuildconfiguration.h" -#include "nimconstants.h" +#include "nimbuildsystem.h" #include "nimcompilerbuildstepconfigwidget.h" -#include "nimproject.h" +#include "nimconstants.h" #include "nimtoolchain.h" #include <projectexplorer/buildconfiguration.h> @@ -206,7 +206,6 @@ void NimCompilerBuildStep::updateProcessParameters() { updateOutFilePath(); updateCommand(); - updateArguments(); updateWorkingDirectory(); updateEnvironment(); emit processParametersChanged(); @@ -220,16 +219,6 @@ void NimCompilerBuildStep::updateOutFilePath() setOutFilePath(bc->buildDirectory().pathAppended(targetName)); } -void NimCompilerBuildStep::updateCommand() -{ - QTC_ASSERT(target(), return); - QTC_ASSERT(target()->kit(), return); - Kit *kit = target()->kit(); - auto tc = dynamic_cast<NimToolChain*>(ToolChainKitAspect::toolChain(kit, Constants::C_NIMLANGUAGE_ID)); - QTC_ASSERT(tc, return); - processParameters()->setCommand(tc->compilerCommand()); -} - void NimCompilerBuildStep::updateWorkingDirectory() { auto bc = qobject_cast<NimBuildConfiguration *>(buildConfiguration()); @@ -237,38 +226,38 @@ void NimCompilerBuildStep::updateWorkingDirectory() processParameters()->setWorkingDirectory(bc->buildDirectory()); } -void NimCompilerBuildStep::updateArguments() +void NimCompilerBuildStep::updateCommand() { auto bc = qobject_cast<NimBuildConfiguration *>(buildConfiguration()); QTC_ASSERT(bc, return); - QStringList arguments; - arguments << QStringLiteral("c"); - - switch (m_defaultOptions) { - case Release: - arguments << QStringLiteral("-d:release"); - break; - case Debug: - arguments << QStringLiteral("--debugInfo") - << QStringLiteral("--lineDir:on"); - break; - default: - break; - } + QTC_ASSERT(target(), return); + QTC_ASSERT(target()->kit(), return); + Kit *kit = target()->kit(); + auto tc = dynamic_cast<NimToolChain*>(ToolChainKitAspect::toolChain(kit, Constants::C_NIMLANGUAGE_ID)); + QTC_ASSERT(tc, return); - arguments << QStringLiteral("--out:%1").arg(m_outFilePath.toString()); - arguments << QStringLiteral("--nimCache:%1").arg(bc->cacheDirectory().toString()); + CommandLine cmd{tc->compilerCommand()}; - arguments << m_userCompilerOptions; - arguments << m_targetNimFile.toString(); + cmd.addArg("c"); - // Remove empty args - auto predicate = [](const QString &str) { return str.isEmpty(); }; - auto it = std::remove_if(arguments.begin(), arguments.end(), predicate); - arguments.erase(it, arguments.end()); + if (m_defaultOptions == Release) + cmd.addArg("-d:release"); + else if (m_defaultOptions == Debug) + cmd.addArgs({"--debugInfo", "--lineDir:on"}); + + cmd.addArg("--out:" + m_outFilePath.toString()); + cmd.addArg("--nimCache:" + bc->cacheDirectory().toString()); + + for (const QString &arg : m_userCompilerOptions) { + if (!arg.isEmpty()) + cmd.addArg(arg); + } + + if (!m_targetNimFile.isEmpty()) + cmd.addArg(m_targetNimFile.toString()); - processParameters()->setArguments(arguments.join(QChar::Space)); + processParameters()->setCommandLine(cmd); } void NimCompilerBuildStep::updateEnvironment() @@ -282,7 +271,8 @@ void NimCompilerBuildStep::updateTargetNimFile() { if (!m_targetNimFile.isEmpty()) return; - const Utils::FilePathList nimFiles = static_cast<NimProject *>(project())->nimFiles(); + const Utils::FilePathList nimFiles = static_cast<NimBuildSystem *>(project()->buildSystem()) + ->nimFiles(); if (!nimFiles.isEmpty()) setTargetNimFile(nimFiles.at(0)); } diff --git a/src/plugins/nim/project/nimcompilerbuildstep.h b/src/plugins/nim/project/nimcompilerbuildstep.h index a866694c9a..b9ea46316f 100644 --- a/src/plugins/nim/project/nimcompilerbuildstep.h +++ b/src/plugins/nim/project/nimcompilerbuildstep.h @@ -72,7 +72,6 @@ private: void updateProcessParameters(); void updateCommand(); void updateWorkingDirectory(); - void updateArguments(); void updateEnvironment(); void updateTargetNimFile(); diff --git a/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp b/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp index 27acf21726..01e9e23ca6 100644 --- a/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp +++ b/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp @@ -24,16 +24,18 @@ ****************************************************************************/ #include "nimcompilerbuildstepconfigwidget.h" -#include "ui_nimcompilerbuildstepconfigwidget.h" #include "nimbuildconfiguration.h" +#include "nimbuildsystem.h" #include "nimcompilerbuildstep.h" -#include "nimproject.h" + +#include "ui_nimcompilerbuildstepconfigwidget.h" #include "../nimconstants.h" #include <projectexplorer/processparameters.h> #include <utils/qtcassert.h> +#include <utils/qtcprocess.h> using namespace ProjectExplorer; using namespace Utils; @@ -51,9 +53,10 @@ NimCompilerBuildStepConfigWidget::NimCompilerBuildStepConfigWidget(NimCompilerBu setSummaryText(tr(Constants::C_NIMCOMPILERBUILDSTEPWIDGET_SUMMARY)); // Connect the project signals - auto project = static_cast<NimProject *>(m_buildStep->project()); - connect(project, &NimProject::fileListChanged, - this, &NimCompilerBuildStepConfigWidget::updateUi); + connect(m_buildStep->project(), + &Project::fileListChanged, + this, + &NimCompilerBuildStepConfigWidget::updateUi); // Connect build step signals connect(m_buildStep, &NimCompilerBuildStep::processParametersChanged, @@ -74,7 +77,7 @@ NimCompilerBuildStepConfigWidget::~NimCompilerBuildStepConfigWidget() = default; void NimCompilerBuildStepConfigWidget::onTargetChanged(int index) { - Q_UNUSED(index); + Q_UNUSED(index) auto data = m_ui->targetComboBox->currentData(); FilePath path = FilePath::fromString(data.toString()); m_buildStep->setTargetNimFile(path); @@ -103,28 +106,22 @@ void NimCompilerBuildStepConfigWidget::updateCommandLineText() { ProcessParameters *parameters = m_buildStep->processParameters(); - QStringList command; - command << parameters->command().toString(); - command << parameters->arguments(); - - // Remove empty args - auto predicate = [](const QString & str) { return str.isEmpty(); }; - auto it = std::remove_if(command.begin(), command.end(), predicate); - command.erase(it, command.end()); + const CommandLine cmd = parameters->command(); + const QStringList parts = QtcProcess::splitArgs(cmd.toUserOutput()); - m_ui->commandTextEdit->setText(command.join(QChar::LineFeed)); + m_ui->commandTextEdit->setText(parts.join(QChar::LineFeed)); } void NimCompilerBuildStepConfigWidget::updateTargetComboBox() { - QTC_ASSERT(m_buildStep, return); + QTC_ASSERT(m_buildStep, return ); - auto project = qobject_cast<NimProject *>(m_buildStep->project()); - QTC_ASSERT(project, return); + const auto bs = qobject_cast<NimBuildSystem *>(m_buildStep->project()->buildSystem()); + QTC_ASSERT(bs, return ); // Re enter the files m_ui->targetComboBox->clear(); - foreach (const FilePath &file, project->nimFiles()) + for (const FilePath &file : bs->nimFiles()) m_ui->targetComboBox->addItem(file.fileName(), file.toString()); const int index = m_ui->targetComboBox->findData(m_buildStep->targetNimFile().toString()); diff --git a/src/plugins/nim/project/nimcompilercleanstep.cpp b/src/plugins/nim/project/nimcompilercleanstep.cpp index b802582108..03fa8fd67b 100644 --- a/src/plugins/nim/project/nimcompilercleanstep.cpp +++ b/src/plugins/nim/project/nimcompilercleanstep.cpp @@ -25,10 +25,10 @@ #include "nimcompilercleanstep.h" #include "nimbuildconfiguration.h" -#include "nimcompilercleanstepconfigwidget.h" #include "../nimconstants.h" +#include <projectexplorer/projectconfigurationaspects.h> #include <projectexplorer/projectexplorerconstants.h> #include <utils/qtcassert.h> @@ -45,11 +45,15 @@ NimCompilerCleanStep::NimCompilerCleanStep(BuildStepList *parentList) { setDefaultDisplayName(tr("Nim Clean Step")); setDisplayName(tr("Nim Clean Step")); -} -BuildStepConfigWidget *NimCompilerCleanStep::createConfigWidget() -{ - return new NimCompilerCleanStepConfigWidget(this); + auto workingDirectory = addAspect<BaseStringAspect>(); + workingDirectory->setLabelText(tr("Working directory:")); + workingDirectory->setDisplayStyle(BaseStringAspect::LineEditDisplay); + + setSummaryUpdater([this, workingDirectory] { + workingDirectory->setFilePath(buildConfiguration()->buildDirectory()); + return displayName(); + }); } bool NimCompilerCleanStep::init() @@ -122,7 +126,7 @@ NimCompilerCleanStepFactory::NimCompilerCleanStepFactory() setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN); setSupportedConfiguration(Constants::C_NIMBUILDCONFIGURATION_ID); setRepeatable(false); - setDisplayName(NimCompilerCleanStep::tr(Nim::Constants::C_NIMCOMPILERCLEANSTEP_DISPLAY)); + setDisplayName(NimCompilerCleanStep::tr("Nim Compiler Clean Step")); } } // Nim diff --git a/src/plugins/nim/project/nimcompilercleanstep.h b/src/plugins/nim/project/nimcompilercleanstep.h index 2cbde61beb..8acf4e0ae5 100644 --- a/src/plugins/nim/project/nimcompilercleanstep.h +++ b/src/plugins/nim/project/nimcompilercleanstep.h @@ -38,8 +38,6 @@ class NimCompilerCleanStep : public ProjectExplorer::BuildStep public: NimCompilerCleanStep(ProjectExplorer::BuildStepList *parentList); - ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override; - private: bool init() override; void doRun() override; diff --git a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.cpp b/src/plugins/nim/project/nimcompilercleanstepconfigwidget.cpp deleted file mode 100644 index 0b82052202..0000000000 --- a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) Filippo Cucchetto <filippocucchetto@gmail.com> -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "nimcompilercleanstepconfigwidget.h" -#include "ui_nimcompilercleanstepconfigwidget.h" -#include "nimcompilercleanstep.h" - -#include "../nimconstants.h" - -#include "projectexplorer/buildconfiguration.h" - -using namespace ProjectExplorer; - -namespace Nim { - -NimCompilerCleanStepConfigWidget::NimCompilerCleanStepConfigWidget(NimCompilerCleanStep *cleanStep) - : BuildStepConfigWidget(cleanStep) - , m_ui(new Ui::NimCompilerCleanStepConfigWidget()) -{ - m_ui->setupUi(this); - setDisplayName(tr(Constants::C_NIMCOMPILERCLEANSTEPWIDGET_DISPLAY)); - setSummaryText(tr(Constants::C_NIMCOMPILERCLEANSTEPWIDGET_SUMMARY)); - connect(cleanStep->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged, - this, &NimCompilerCleanStepConfigWidget::updateUi); - updateUi(); -} - -NimCompilerCleanStepConfigWidget::~NimCompilerCleanStepConfigWidget() = default; - -void NimCompilerCleanStepConfigWidget::updateUi() -{ - auto buildDiretory = step()->buildConfiguration()->buildDirectory(); - m_ui->workingDirectoryLineEdit->setText(buildDiretory.toString()); -} - -} - diff --git a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.ui b/src/plugins/nim/project/nimcompilercleanstepconfigwidget.ui deleted file mode 100644 index 20dd2e05d0..0000000000 --- a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.ui +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Nim::NimCompilerCleanStepConfigWidget</class> - <widget class="QWidget" name="Nim::NimCompilerCleanStepConfigWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <property name="windowTitle"> - <string/> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QFormLayout" name="formLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="workingDirectoryLabel"> - <property name="text"> - <string>Working directory:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="workingDirectoryLineEdit"> - <property name="readOnly"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp index a6cad1657f..08f1019c8a 100644 --- a/src/plugins/nim/project/nimproject.cpp +++ b/src/plugins/nim/project/nimproject.cpp @@ -24,42 +24,20 @@ ****************************************************************************/ #include "nimproject.h" -#include "nimbuildconfiguration.h" -#include "nimprojectnode.h" -#include "nimtoolchain.h" #include "../nimconstants.h" +#include "nimbuildsystem.h" +#include "nimtoolchain.h" #include <coreplugin/icontext.h> -#include <coreplugin/progressmanager/progressmanager.h> -#include <coreplugin/iversioncontrol.h> -#include <coreplugin/vcsmanager.h> -#include <projectexplorer/buildconfiguration.h> -#include <projectexplorer/kit.h> -#include <projectexplorer/projectexplorerconstants.h> -#include <projectexplorer/projectnodes.h> -#include <projectexplorer/target.h> -#include <projectexplorer/toolchain.h> #include <projectexplorer/kitinformation.h> -#include <texteditor/textdocument.h> - -#include <utils/algorithm.h> -#include <utils/qtcassert.h> -#include <utils/runextensions.h> - -#include <coreplugin/editormanager/editormanager.h> -#include <coreplugin/editormanager/ieditor.h> - -#include <QFileInfo> -#include <QQueue> +#include <projectexplorer/projectexplorerconstants.h> using namespace ProjectExplorer; using namespace Utils; namespace Nim { -const int MIN_TIME_BETWEEN_PROJECT_SCANS = 4500; - NimProject::NimProject(const FilePath &fileName) : Project(Constants::C_NIM_MIMETYPE, fileName) { setId(Constants::C_NIMPROJECT_ID); @@ -67,87 +45,7 @@ NimProject::NimProject(const FilePath &fileName) : Project(Constants::C_NIM_MIME // ensure debugging is enabled (Nim plugin translates nim code to C code) setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); - m_projectScanTimer.setSingleShot(true); - connect(&m_projectScanTimer, &QTimer::timeout, this, &NimProject::collectProjectFiles); - connect(this, &Project::settingsLoaded, this, &NimProject::collectProjectFiles); - - connect(&m_futureWatcher, &QFutureWatcher<QList<FileNode *>>::finished, this, - &NimProject::updateProject); -} - -void NimProject::scheduleProjectScan() -{ - auto elapsedTime = m_lastProjectScan.elapsed(); - if (elapsedTime < MIN_TIME_BETWEEN_PROJECT_SCANS) { - if (!m_projectScanTimer.isActive()) { - m_projectScanTimer.setInterval(MIN_TIME_BETWEEN_PROJECT_SCANS - elapsedTime); - m_projectScanTimer.start(); - } - } else { - collectProjectFiles(); - } -} - -bool NimProject::addFiles(const QStringList &filePaths) -{ - m_excludedFiles = Utils::filtered(m_excludedFiles, [&](const QString & f) { - return !filePaths.contains(f); - }); - scheduleProjectScan(); - return true; -} - -bool NimProject::removeFiles(const QStringList &filePaths) -{ - m_excludedFiles.append(filePaths); - m_excludedFiles = Utils::filteredUnique(m_excludedFiles); - scheduleProjectScan(); - return true; -} - -bool NimProject::renameFile(const QString &filePath, const QString &newFilePath) -{ - Q_UNUSED(filePath) - m_excludedFiles.removeOne(newFilePath); - scheduleProjectScan(); - return true; -} - -void NimProject::collectProjectFiles() -{ - m_lastProjectScan.start(); - QTC_ASSERT(!m_futureWatcher.future().isRunning(), return); - FilePath prjDir = projectDirectory(); - QFuture<QList<ProjectExplorer::FileNode *>> future = Utils::runAsync([prjDir, - excluded = m_excludedFiles] { - return FileNode::scanForFiles(prjDir, [excluded](const FilePath & fn) -> FileNode * { - const QString fileName = fn.fileName(); - if (excluded.contains(fn.toString()) - || fileName.endsWith(".nimproject", HostOsInfo::fileNameCaseSensitivity()) - || fileName.contains(".nimproject.user", HostOsInfo::fileNameCaseSensitivity())) - return nullptr; - return new FileNode(fn, FileType::Source); - }); - }); - m_futureWatcher.setFuture(future); - Core::ProgressManager::addTask(future, tr("Scanning for Nim files"), "Nim.Project.Scan"); -} - -void NimProject::updateProject() -{ - emitParsingStarted(); - - auto newRoot = std::make_unique<NimProjectNode>(*this, projectDirectory()); - - QList<FileNode *> files = m_futureWatcher.future().result(); - - for (FileNode *node : files) - newRoot->addNestedNode(std::unique_ptr<FileNode>(node)); - - newRoot->setDisplayName(displayName()); - setRootProjectNode(std::move(newRoot)); - - emitParsingFinished(true); + setBuildSystem(std::make_unique<NimBuildSystem>(this)); } Tasks NimProject::projectIssues(const Kit *k) const @@ -164,24 +62,20 @@ Tasks NimProject::projectIssues(const Kit *k) const return result; } -FilePathList NimProject::nimFiles() const -{ - return files([](const ProjectExplorer::Node *n) { - return AllFiles(n) && n->filePath().endsWith(".nim"); - }); -} - QVariantMap NimProject::toMap() const { QVariantMap result = Project::toMap(); - result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = m_excludedFiles; + result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = static_cast<NimBuildSystem *>(buildSystem()) + ->excludedFiles(); return result; } Project::RestoreResult NimProject::fromMap(const QVariantMap &map, QString *errorMessage) { - m_excludedFiles = map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList(); - return Project::fromMap(map, errorMessage); + auto result = Project::fromMap(map, errorMessage); + static_cast<NimBuildSystem *>(buildSystem()) + ->setExcludedFiles(map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList()); + return result; } } // namespace Nim diff --git a/src/plugins/nim/project/nimproject.h b/src/plugins/nim/project/nimproject.h index d0143de2fd..afe33cf940 100644 --- a/src/plugins/nim/project/nimproject.h +++ b/src/plugins/nim/project/nimproject.h @@ -34,6 +34,8 @@ namespace Nim { +class NimBuildSystem; + class NimProject : public ProjectExplorer::Project { Q_OBJECT @@ -42,25 +44,13 @@ public: explicit NimProject(const Utils::FilePath &fileName); ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final; - Utils::FilePathList nimFiles() const; - QVariantMap toMap() const final; - bool addFiles(const QStringList &filePaths); - bool removeFiles(const QStringList &filePaths); - bool renameFile(const QString &filePath, const QString &newFilePath); + // Keep for compatibility with Qt Creator 4.10 + QVariantMap toMap() const final; protected: + // Keep for compatibility with Qt Creator 4.10 RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final; - -private: - void scheduleProjectScan(); - void collectProjectFiles(); - void updateProject(); - - QStringList m_excludedFiles; - QFutureWatcher<QList<ProjectExplorer::FileNode *>> m_futureWatcher; - QElapsedTimer m_lastProjectScan; - QTimer m_projectScanTimer; }; -} +} // namespace Nim diff --git a/src/plugins/nim/project/nimprojectnode.cpp b/src/plugins/nim/project/nimprojectnode.cpp index 6a6385b67e..5232ea500c 100644 --- a/src/plugins/nim/project/nimprojectnode.cpp +++ b/src/plugins/nim/project/nimprojectnode.cpp @@ -24,17 +24,18 @@ ****************************************************************************/ #include "nimprojectnode.h" -#include "nimproject.h" + +#include "nimbuildsystem.h" + +#include <projectexplorer/projecttree.h> using namespace ProjectExplorer; using namespace Utils; namespace Nim { -NimProjectNode::NimProjectNode(NimProject &project, - const FilePath &projectFilePath) +NimProjectNode::NimProjectNode(const FilePath &projectFilePath) : ProjectNode(projectFilePath) - , m_project(project) {} bool NimProjectNode::supportsAction(ProjectAction action, const Node *node) const @@ -53,12 +54,14 @@ bool NimProjectNode::supportsAction(ProjectAction action, const Node *node) cons bool NimProjectNode::addFiles(const QStringList &filePaths, QStringList *) { - return m_project.addFiles(filePaths); + return buildSystem()->addFiles(filePaths); } -bool NimProjectNode::removeFiles(const QStringList &filePaths, QStringList *) +RemovedFilesFromProject NimProjectNode::removeFiles(const QStringList &filePaths, + QStringList *) { - return m_project.removeFiles(filePaths); + return buildSystem()->removeFiles(filePaths) ? RemovedFilesFromProject::Ok + : RemovedFilesFromProject::Error; } bool NimProjectNode::deleteFiles(const QStringList &) @@ -68,7 +71,13 @@ bool NimProjectNode::deleteFiles(const QStringList &) bool NimProjectNode::renameFile(const QString &filePath, const QString &newFilePath) { - return m_project.renameFile(filePath, newFilePath); + return buildSystem()->renameFile(filePath, newFilePath); } +NimBuildSystem *NimProjectNode::buildSystem() const +{ + return qobject_cast<NimBuildSystem *>( + ProjectTree::instance()->projectForNode(this)->buildSystem()); } + +} // namespace Nim diff --git a/src/plugins/nim/project/nimprojectnode.h b/src/plugins/nim/project/nimprojectnode.h index 6a950bdf4f..98ea5aeff1 100644 --- a/src/plugins/nim/project/nimprojectnode.h +++ b/src/plugins/nim/project/nimprojectnode.h @@ -31,21 +31,22 @@ namespace Utils { class FilePath; } namespace Nim { -class NimProject; +class NimBuildSystem; class NimProjectNode : public ProjectExplorer::ProjectNode { public: - NimProjectNode(NimProject &project, const Utils::FilePath &projectFilePath); + NimProjectNode(const Utils::FilePath &projectFilePath); bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override; bool addFiles(const QStringList &filePaths, QStringList *) override; - bool removeFiles(const QStringList &filePaths, QStringList *) override; + ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths, + QStringList *) override; bool deleteFiles(const QStringList &) override; bool renameFile(const QString &filePath, const QString &newFilePath) override; private: - NimProject &m_project; + NimBuildSystem *buildSystem() const; }; } diff --git a/src/plugins/nim/project/nimrunconfiguration.cpp b/src/plugins/nim/project/nimrunconfiguration.cpp index 7849f4dc19..9bfcc275bb 100644 --- a/src/plugins/nim/project/nimrunconfiguration.cpp +++ b/src/plugins/nim/project/nimrunconfiguration.cpp @@ -63,7 +63,8 @@ NimRunConfiguration::NimRunConfiguration(Target *target, Core::Id id) void NimRunConfiguration::updateConfiguration() { auto buildConfiguration = qobject_cast<NimBuildConfiguration *>(activeBuildConfiguration()); - QTC_ASSERT(buildConfiguration, return); + if (!buildConfiguration) + return; setActiveBuildConfiguration(buildConfiguration); const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo(); aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(outFileInfo.absoluteFilePath())); diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index 3e7fcbef72..6a922f9553 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -49,19 +49,7 @@ NimToolChain::NimToolChain(Core::Id typeId) , m_version(std::make_tuple(-1,-1,-1)) { setLanguage(Constants::C_NIMLANGUAGE_ID); -} - -NimToolChain::NimToolChain(const NimToolChain &other) - : ToolChain(other.typeId()) - , m_compilerCommand(other.m_compilerCommand) - , m_version(other.m_version) -{ - setLanguage(Constants::C_NIMLANGUAGE_ID); -} - -QString NimToolChain::typeDisplayName() const -{ - return NimToolChainFactory::tr("Nim"); + setTypeDisplayName(NimToolChainFactory::tr("Nim")); } Abi NimToolChain::targetAbi() const @@ -97,12 +85,14 @@ WarningFlags NimToolChain::warningFlags(const QStringList &) const return WarningFlags::NoWarnings; } -ToolChain::BuiltInHeaderPathsRunner NimToolChain::createBuiltInHeaderPathsRunner() const +ToolChain::BuiltInHeaderPathsRunner NimToolChain::createBuiltInHeaderPathsRunner( + const Environment &) const { return ToolChain::BuiltInHeaderPathsRunner(); } -HeaderPaths NimToolChain::builtInHeaderPaths(const QStringList &, const FilePath &) const +HeaderPaths NimToolChain::builtInHeaderPaths(const QStringList &, const FilePath &, + const Environment &) const { return {}; } diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h index b35e073ccd..4b9f6c9cd7 100644 --- a/src/plugins/nim/project/nimtoolchain.h +++ b/src/plugins/nim/project/nimtoolchain.h @@ -36,7 +36,6 @@ public: NimToolChain(); explicit NimToolChain(Core::Id typeId); - QString typeDisplayName() const override; ProjectExplorer::Abi targetAbi() const override; bool isValid() const override; @@ -45,9 +44,11 @@ public: Utils::LanguageExtensions languageExtensions(const QStringList &flags) const final; ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final; - BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override; + BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner( + const Utils::Environment &) const override; ProjectExplorer::HeaderPaths builtInHeaderPaths(const QStringList &flags, - const Utils::FilePath &sysRoot) const final; + const Utils::FilePath &sysRoot, + const Utils::Environment &) const final; void addToEnvironment(Utils::Environment &env) const final; Utils::FilePath makeCommand(const Utils::Environment &env) const final; Utils::FilePath compilerCommand() const final; @@ -62,8 +63,6 @@ public: static bool parseVersion(const Utils::FilePath &path, std::tuple<int, int, int> &version); private: - NimToolChain(const NimToolChain &other); - Utils::FilePath m_compilerCommand; std::tuple<int, int, int> m_version; }; diff --git a/src/plugins/nim/project/nimtoolchainfactory.cpp b/src/plugins/nim/project/nimtoolchainfactory.cpp index 5fc94c4926..7467ab7789 100644 --- a/src/plugins/nim/project/nimtoolchainfactory.cpp +++ b/src/plugins/nim/project/nimtoolchainfactory.cpp @@ -73,13 +73,13 @@ QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alr return result; } -QList<ToolChain *> NimToolChainFactory::autoDetect(const FilePath &compilerPath, const Core::Id &language) +QList<ToolChain *> NimToolChainFactory::detectForImport(const ToolChainDescription &tcd) { QList<ToolChain *> result; - if (language == Constants::C_NIMLANGUAGE_ID) { + if (tcd.language == Constants::C_NIMLANGUAGE_ID) { auto tc = new NimToolChain; tc->setDetection(ToolChain::ManualDetection); // FIXME: sure? - tc->setCompilerCommand(compilerPath); + tc->setCompilerCommand(tcd.compilerPath); result.append(tc); } return result; diff --git a/src/plugins/nim/project/nimtoolchainfactory.h b/src/plugins/nim/project/nimtoolchainfactory.h index 70a49cbb37..0b79653400 100644 --- a/src/plugins/nim/project/nimtoolchainfactory.h +++ b/src/plugins/nim/project/nimtoolchainfactory.h @@ -42,7 +42,7 @@ public: NimToolChainFactory(); QList<ProjectExplorer::ToolChain *> autoDetect(const QList<ProjectExplorer::ToolChain *> &alreadyKnown) final; - QList<ProjectExplorer::ToolChain *> autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language) final; + QList<ProjectExplorer::ToolChain *> detectForImport(const ProjectExplorer::ToolChainDescription &tcd) final; }; class NimToolChainConfigWidget : public ProjectExplorer::ToolChainConfigWidget |