forked from qt-creator/qt-creator
Nim: Adapt to recent buildconfiguration changes
Change-Id: Ib1d893f9e6d7c6c78bd4dded7a7d6434e6727a0c Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -71,12 +71,16 @@ void NimbleBuildConfiguration::initialize()
|
||||
|
||||
setBuildDirectory(project()->projectDirectory());
|
||||
|
||||
// Don't add a nimble build step when the package has no binaries (i.e a library package)
|
||||
if (!m_nimbleBuildSystem->metadata().bin.empty())
|
||||
{
|
||||
// FIXME: This is the wrong place for this decision, as it depends on
|
||||
// information that's typically only available after parsing which takes
|
||||
// the build configuration that is initialized here into account.
|
||||
|
||||
// // Don't add a nimble build step when the package has no binaries (i.e a library package)
|
||||
// if (!m_nimbleBuildSystem->metadata().bin.empty())
|
||||
// {
|
||||
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
|
||||
buildSteps->appendStep(new NimbleBuildStep(buildSteps));
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
bool NimbleBuildConfiguration::fromMap(const QVariantMap &map)
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "nimblebuildsystem.h"
|
||||
#include "nimbleproject.h"
|
||||
#include "nimproject.h"
|
||||
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
@@ -34,16 +35,15 @@
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
|
||||
using namespace Nim;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace {
|
||||
namespace Nim {
|
||||
|
||||
const char C_NIMBLEPROJECT_TASKS[] = "Nim.NimbleProject.Tasks";
|
||||
const char C_NIMBLEPROJECT_METADATA[] = "Nim.NimbleProject.Metadata";
|
||||
|
||||
std::vector<NimbleTask> parseTasks(const QString &nimblePath, const QString &workingDirectory)
|
||||
static std::vector<NimbleTask> parseTasks(const QString &nimblePath, const QString &workingDirectory)
|
||||
{
|
||||
QProcess process;
|
||||
process.setWorkingDirectory(workingDirectory);
|
||||
@@ -67,7 +67,8 @@ std::vector<NimbleTask> parseTasks(const QString &nimblePath, const QString &wor
|
||||
return result;
|
||||
}
|
||||
|
||||
NimbleMetadata parseMetadata(const QString &nimblePath, const QString &workingDirectory) {
|
||||
static NimbleMetadata parseMetadata(const QString &nimblePath, const QString &workingDirectory)
|
||||
{
|
||||
QProcess process;
|
||||
process.setWorkingDirectory(workingDirectory);
|
||||
process.start(QStandardPaths::findExecutable(nimblePath), {"dump"});
|
||||
@@ -105,52 +106,49 @@ NimbleMetadata parseMetadata(const QString &nimblePath, const QString &workingDi
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NimbleBuildSystem::NimbleBuildSystem(Target *target)
|
||||
: NimBuildSystem(target)
|
||||
: BuildSystem(target), m_projectScanner(target->project())
|
||||
{
|
||||
// Not called in parseProject due to nimble behavior to create temporary
|
||||
// files in project directory. This creation in turn stimulate the fs watcher
|
||||
// that in turn causes project parsing (thus a loop if invoke in parseProject).
|
||||
// For this reason we call this function manually during project creation
|
||||
// See https://github.com/nim-lang/nimble/issues/720
|
||||
m_directoryWatcher.addFile(projectFilePath().toString(), FileSystemWatcher::WatchModifiedDate);
|
||||
m_projectScanner.watchProjectFilePath();
|
||||
|
||||
connect(&m_directoryWatcher, &FileSystemWatcher::fileChanged, this, [this](const QString &path) {
|
||||
if (path == projectFilePath().toString()) {
|
||||
updateProject();
|
||||
}
|
||||
connect(&m_projectScanner, &NimProjectScanner::fileChanged, this, [this](const QString &path) {
|
||||
if (path == projectFilePath().toString())
|
||||
requestDelayedParse();
|
||||
});
|
||||
|
||||
updateProject();
|
||||
connect(&m_projectScanner, &NimProjectScanner::requestReparse,
|
||||
this, &NimbleBuildSystem::requestDelayedParse);
|
||||
|
||||
connect(&m_projectScanner, &NimProjectScanner::finished, this, &NimbleBuildSystem::updateProject);
|
||||
|
||||
connect(&m_projectScanner, &NimProjectScanner::directoryChanged, this, [this] {
|
||||
if (!isWaitingForParse())
|
||||
requestDelayedParse();
|
||||
});
|
||||
|
||||
requestDelayedParse();
|
||||
}
|
||||
|
||||
void NimbleBuildSystem::triggerParsing()
|
||||
{
|
||||
m_guard = guardParsingRun();
|
||||
m_projectScanner.startScan();
|
||||
}
|
||||
|
||||
void NimbleBuildSystem::updateProject()
|
||||
{
|
||||
updateProjectMetaData();
|
||||
updateProjectTasks();
|
||||
}
|
||||
const FilePath projectDir = projectDirectory();
|
||||
|
||||
void NimbleBuildSystem::updateProjectTasks()
|
||||
{
|
||||
setTasks(parseTasks(QStandardPaths::findExecutable("nimble"), projectDirectory().toString()));
|
||||
}
|
||||
|
||||
void NimbleBuildSystem::updateProjectMetaData()
|
||||
{
|
||||
setMetadata(parseMetadata(QStandardPaths::findExecutable("nimble"), projectDirectory().toString()));
|
||||
}
|
||||
|
||||
void NimbleBuildSystem::updateApplicationTargets()
|
||||
{
|
||||
const NimbleMetadata &metaData = metadata();
|
||||
const FilePath &projectDir = project()->projectDirectory();
|
||||
const FilePath binDir = projectDir.pathAppended(metaData.binDir);
|
||||
m_metadata = parseMetadata(QStandardPaths::findExecutable("nimble"), projectDir.toString());
|
||||
const FilePath binDir = projectDir.pathAppended(m_metadata.binDir);
|
||||
const FilePath srcDir = projectDir.pathAppended("src");
|
||||
|
||||
QList<BuildTargetInfo> targets = Utils::transform(metaData.bin, [&](const QString &bin){
|
||||
QList<BuildTargetInfo> targets = Utils::transform(m_metadata.bin, [&](const QString &bin){
|
||||
BuildTargetInfo info = {};
|
||||
info.displayName = bin;
|
||||
info.targetFilePath = binDir.pathAppended(HostOsInfo::withExecutableSuffix(bin));
|
||||
@@ -161,6 +159,18 @@ void NimbleBuildSystem::updateApplicationTargets()
|
||||
});
|
||||
|
||||
setApplicationTargets(std::move(targets));
|
||||
|
||||
std::vector<NimbleTask> tasks = parseTasks(QStandardPaths::findExecutable("nimble"), projectDir.toString());
|
||||
if (tasks != m_tasks) {
|
||||
m_tasks = std::move(tasks);
|
||||
emit tasksChanged();
|
||||
}
|
||||
|
||||
// Complete scan
|
||||
m_guard.markAsSuccess();
|
||||
m_guard = {};
|
||||
|
||||
emitBuildSystemUpdated();
|
||||
}
|
||||
|
||||
std::vector<NimbleTask> NimbleBuildSystem::tasks() const
|
||||
@@ -173,25 +183,6 @@ NimbleMetadata NimbleBuildSystem::metadata() const
|
||||
return m_metadata;
|
||||
}
|
||||
|
||||
void NimbleBuildSystem::setTasks(std::vector<NimbleTask> tasks)
|
||||
{
|
||||
if (tasks == m_tasks)
|
||||
return;
|
||||
m_tasks = std::move(tasks);
|
||||
emit tasksChanged();
|
||||
|
||||
emitBuildSystemUpdated();
|
||||
}
|
||||
|
||||
void NimbleBuildSystem::setMetadata(NimbleMetadata metadata)
|
||||
{
|
||||
if (m_metadata == metadata)
|
||||
return;
|
||||
m_metadata = std::move(metadata);
|
||||
|
||||
updateApplicationTargets();
|
||||
}
|
||||
|
||||
void NimbleBuildSystem::saveSettings()
|
||||
{
|
||||
QStringList result;
|
||||
@@ -214,4 +205,44 @@ void NimbleBuildSystem::loadSettings()
|
||||
std::vector<NimbleTask> result;
|
||||
for (int i = 0; i < list.size(); i += 2)
|
||||
result.push_back({list[i], list[i + 1]});
|
||||
|
||||
requestParse();
|
||||
}
|
||||
|
||||
bool NimbleBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
||||
{
|
||||
if (node->asFileNode()) {
|
||||
return action == ProjectAction::Rename
|
||||
|| action == ProjectAction::RemoveFile;
|
||||
}
|
||||
if (node->isFolderNodeType() || node->isProjectNodeType()) {
|
||||
return action == ProjectAction::AddNewFile
|
||||
|| action == ProjectAction::RemoveFile
|
||||
|| action == ProjectAction::AddExistingFile;
|
||||
}
|
||||
return BuildSystem::supportsAction(context, action, node);
|
||||
}
|
||||
|
||||
bool NimbleBuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *)
|
||||
{
|
||||
return m_projectScanner.addFiles(filePaths);
|
||||
}
|
||||
|
||||
RemovedFilesFromProject NimbleBuildSystem::removeFiles(Node *,
|
||||
const QStringList &filePaths,
|
||||
QStringList *)
|
||||
{
|
||||
return m_projectScanner.removeFiles(filePaths);
|
||||
}
|
||||
|
||||
bool NimbleBuildSystem::deleteFiles(Node *, const QStringList &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NimbleBuildSystem::renameFile(Node *, const QString &filePath, const QString &newFilePath)
|
||||
{
|
||||
return m_projectScanner.renameFile(filePath, newFilePath);
|
||||
}
|
||||
|
||||
} // Nim
|
||||
|
@@ -48,9 +48,12 @@ struct NimbleMetadata
|
||||
bool operator==(const NimbleMetadata &o) const {
|
||||
return bin == o.bin && binDir == o.binDir && srcDir == o.srcDir;
|
||||
}
|
||||
bool operator!=(const NimbleMetadata &o) const {
|
||||
return !operator==(o);
|
||||
}
|
||||
};
|
||||
|
||||
class NimbleBuildSystem : public NimBuildSystem
|
||||
class NimbleBuildSystem : public ProjectExplorer::BuildSystem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -58,26 +61,36 @@ public:
|
||||
NimbleBuildSystem(ProjectExplorer::Target *target);
|
||||
|
||||
std::vector<NimbleTask> tasks() const;
|
||||
|
||||
NimbleMetadata metadata() const;
|
||||
|
||||
void setTasks(std::vector<NimbleTask> tasks);
|
||||
void setMetadata(NimbleMetadata metadata);
|
||||
|
||||
signals:
|
||||
void tasksChanged();
|
||||
|
||||
private:
|
||||
void loadSettings() override;
|
||||
void saveSettings() override;
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
void updateProject();
|
||||
void updateProjectTasks();
|
||||
void updateProjectMetaData();
|
||||
void updateApplicationTargets();
|
||||
|
||||
bool supportsAction(ProjectExplorer::Node *,
|
||||
ProjectExplorer::ProjectAction action,
|
||||
const ProjectExplorer::Node *node) const override;
|
||||
bool addFiles(ProjectExplorer::Node *node,
|
||||
const QStringList &filePaths, QStringList *) override;
|
||||
ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *node,
|
||||
const QStringList &filePaths,
|
||||
QStringList *) override;
|
||||
bool deleteFiles(ProjectExplorer::Node *, const QStringList &) override;
|
||||
bool renameFile(ProjectExplorer::Node *,
|
||||
const QString &filePath, const QString &newFilePath) override;
|
||||
|
||||
void triggerParsing() final;
|
||||
|
||||
NimbleMetadata m_metadata;
|
||||
std::vector<NimbleTask> m_tasks;
|
||||
|
||||
NimProjectScanner m_projectScanner;
|
||||
ParseGuard m_guard;
|
||||
};
|
||||
|
||||
}
|
||||
} // Nim
|
||||
|
@@ -44,4 +44,28 @@ NimbleProject::NimbleProject(const Utils::FilePath &fileName)
|
||||
setBuildSystemCreator([] (Target *t) { return new NimbleBuildSystem(t); });
|
||||
}
|
||||
|
||||
QVariantMap NimbleProject::toMap() const
|
||||
{
|
||||
QVariantMap result = Project::toMap();
|
||||
result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = m_excludedFiles;
|
||||
return result;
|
||||
}
|
||||
|
||||
Project::RestoreResult NimbleProject::fromMap(const QVariantMap &map, QString *errorMessage)
|
||||
{
|
||||
auto result = Project::fromMap(map, errorMessage);
|
||||
m_excludedFiles = map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList();
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList NimbleProject::excludedFiles() const
|
||||
{
|
||||
return m_excludedFiles;
|
||||
}
|
||||
|
||||
void NimbleProject::setExcludedFiles(const QStringList &excludedFiles)
|
||||
{
|
||||
m_excludedFiles = excludedFiles;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -36,6 +36,18 @@ class NimbleProject : public ProjectExplorer::Project
|
||||
|
||||
public:
|
||||
NimbleProject(const Utils::FilePath &filename);
|
||||
|
||||
// Keep for compatibility with Qt Creator 4.10
|
||||
QVariantMap toMap() const final;
|
||||
|
||||
QStringList excludedFiles() const;
|
||||
void setExcludedFiles(const QStringList &excludedFiles);
|
||||
|
||||
protected:
|
||||
// Keep for compatibility with Qt Creator 4.10
|
||||
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
|
||||
|
||||
QStringList m_excludedFiles;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -24,7 +24,6 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "nimbuildconfiguration.h"
|
||||
#include "nimbuildsystem.h"
|
||||
#include "nimcompilerbuildstep.h"
|
||||
#include "nimproject.h"
|
||||
|
||||
@@ -78,9 +77,6 @@ void NimBuildConfiguration::initialize()
|
||||
{
|
||||
BuildConfiguration::initialize();
|
||||
|
||||
auto bs = qobject_cast<NimBuildSystem *>(buildSystem());
|
||||
QTC_ASSERT(bs, return );
|
||||
|
||||
// Create the build configuration and initialize it from build info
|
||||
setBuildDirectory(defaultBuildDirectory(target()->kit(),
|
||||
project()->projectFilePath(),
|
||||
@@ -104,7 +100,11 @@ void NimBuildConfiguration::initialize()
|
||||
break;
|
||||
}
|
||||
nimCompilerBuildStep->setDefaultCompilerOptions(defaultOption);
|
||||
Utils::FilePathList nimFiles = bs->nimFiles();
|
||||
|
||||
const Utils::FilePathList nimFiles = project()->files([](const Node *n) {
|
||||
return Project::AllFiles(n) && n->path().endsWith(".nim");
|
||||
});
|
||||
|
||||
if (!nimFiles.isEmpty())
|
||||
nimCompilerBuildStep->setTargetNimFile(nimFiles.first());
|
||||
buildSteps->appendStep(nimCompilerBuildStep);
|
||||
|
@@ -35,8 +35,6 @@
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QVariantMap>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
@@ -45,80 +43,159 @@ namespace Nim {
|
||||
const char SETTINGS_KEY[] = "Nim.BuildSystem";
|
||||
const char EXCLUDED_FILES_KEY[] = "ExcludedFiles";
|
||||
|
||||
NimBuildSystem::NimBuildSystem(Target *target)
|
||||
: BuildSystem(target)
|
||||
NimProjectScanner::NimProjectScanner(Project *project)
|
||||
: m_project(project)
|
||||
{
|
||||
connect(target->project(), &Project::settingsLoaded, this, &NimBuildSystem::loadSettings);
|
||||
connect(target->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) {
|
||||
setFilter([this](const Utils::MimeType &, const FilePath &fp) {
|
||||
const QString path = fp.toString();
|
||||
return excludedFiles().contains(path)
|
||||
|| path.endsWith(".nimproject")
|
||||
|| path.contains(".nimproject.user");
|
||||
|| path.contains(".nimproject.user")
|
||||
|| path.contains(".nimble.user");
|
||||
});
|
||||
|
||||
connect(&m_directoryWatcher, &FileSystemWatcher::directoryChanged, this, [this] {
|
||||
if (!isWaitingForParse())
|
||||
requestDelayedParse();
|
||||
connect(&m_directoryWatcher, &FileSystemWatcher::directoryChanged,
|
||||
this, &NimProjectScanner::directoryChanged);
|
||||
connect(&m_directoryWatcher, &FileSystemWatcher::fileChanged,
|
||||
this, &NimProjectScanner::fileChanged);
|
||||
|
||||
connect(m_project, &Project::settingsLoaded, this, &NimProjectScanner::loadSettings);
|
||||
connect(m_project, &Project::aboutToSaveSettings, this, &NimProjectScanner::saveSettings);
|
||||
|
||||
connect(&m_scanner, &TreeScanner::finished, this, [this] {
|
||||
// Collect scanned nodes
|
||||
std::vector<std::unique_ptr<FileNode>> nodes;
|
||||
for (FileNode *node : m_scanner.release()) {
|
||||
if (!node->path().endsWith(".nim") && !node->path().endsWith(".nimble"))
|
||||
node->setEnabled(false); // Disable files that do not end in .nim
|
||||
nodes.emplace_back(node);
|
||||
}
|
||||
|
||||
// Sync watched dirs
|
||||
const QSet<QString> fsDirs = Utils::transform<QSet>(nodes, &FileNode::directory);
|
||||
const QSet<QString> projectDirs = Utils::toSet(m_directoryWatcher.directories());
|
||||
m_directoryWatcher.addDirectories(Utils::toList(fsDirs - projectDirs), FileSystemWatcher::WatchAllChanges);
|
||||
m_directoryWatcher.removeDirectories(Utils::toList(projectDirs - fsDirs));
|
||||
|
||||
// Sync project files
|
||||
const QSet<FilePath> fsFiles = Utils::transform<QSet>(nodes, &FileNode::filePath);
|
||||
const QSet<FilePath> projectFiles = Utils::toSet(m_project->files([](const Node *n) { return Project::AllFiles(n); }));
|
||||
|
||||
if (fsFiles != projectFiles) {
|
||||
auto projectNode = std::make_unique<ProjectNode>(m_project->projectDirectory());
|
||||
projectNode->setDisplayName(m_project->displayName());
|
||||
projectNode->addNestedNodes(std::move(nodes));
|
||||
m_project->setRootProjectNode(std::move(projectNode));
|
||||
}
|
||||
|
||||
emit finished();
|
||||
});
|
||||
}
|
||||
|
||||
bool NimBuildSystem::addFiles(const QStringList &filePaths)
|
||||
void NimProjectScanner::loadSettings()
|
||||
{
|
||||
QVariantMap settings = m_project->namedSettings(SETTINGS_KEY).toMap();
|
||||
if (settings.contains(EXCLUDED_FILES_KEY))
|
||||
setExcludedFiles(settings.value(EXCLUDED_FILES_KEY, excludedFiles()).toStringList());
|
||||
|
||||
emit requestReparse();
|
||||
}
|
||||
|
||||
void NimProjectScanner::saveSettings()
|
||||
{
|
||||
QVariantMap settings;
|
||||
settings.insert(EXCLUDED_FILES_KEY, excludedFiles());
|
||||
m_project->setNamedSettings(SETTINGS_KEY, settings);
|
||||
}
|
||||
|
||||
void NimProjectScanner::setFilter(const TreeScanner::FileFilter &filter)
|
||||
{
|
||||
m_scanner.setFilter(filter);
|
||||
}
|
||||
|
||||
void NimProjectScanner::startScan()
|
||||
{
|
||||
m_scanner.asyncScanForFiles(m_project->projectDirectory());
|
||||
}
|
||||
|
||||
void NimProjectScanner::watchProjectFilePath()
|
||||
{
|
||||
m_directoryWatcher.addFile(m_project->projectFilePath().toString(), FileSystemWatcher::WatchModifiedDate);
|
||||
}
|
||||
|
||||
void NimProjectScanner::setExcludedFiles(const QStringList &list)
|
||||
{
|
||||
static_cast<NimbleProject *>(m_project)->setExcludedFiles(list);
|
||||
}
|
||||
|
||||
QStringList NimProjectScanner::excludedFiles() const
|
||||
{
|
||||
return static_cast<NimbleProject *>(m_project)->excludedFiles();
|
||||
}
|
||||
|
||||
bool NimProjectScanner::addFiles(const QStringList &filePaths)
|
||||
{
|
||||
setExcludedFiles(Utils::filtered(excludedFiles(), [&](const QString & f) {
|
||||
return !filePaths.contains(f);
|
||||
}));
|
||||
requestParse();
|
||||
|
||||
requestReparse();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NimBuildSystem::removeFiles(const QStringList &filePaths)
|
||||
RemovedFilesFromProject NimProjectScanner::removeFiles(const QStringList &filePaths)
|
||||
{
|
||||
setExcludedFiles(Utils::filteredUnique(excludedFiles() + filePaths));
|
||||
requestParse();
|
||||
return true;
|
||||
|
||||
requestReparse();
|
||||
|
||||
return RemovedFilesFromProject::Ok;
|
||||
}
|
||||
|
||||
bool NimBuildSystem::renameFile(const QString &filePath, const QString &newFilePath)
|
||||
bool NimProjectScanner::renameFile(const QString &, const QString &to)
|
||||
{
|
||||
Q_UNUSED(filePath)
|
||||
QStringList files = excludedFiles();
|
||||
files.removeOne(newFilePath);
|
||||
files.removeOne(to);
|
||||
setExcludedFiles(files);
|
||||
requestParse();
|
||||
|
||||
requestReparse();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NimBuildSystem::setExcludedFiles(const QStringList &list)
|
||||
NimBuildSystem::NimBuildSystem(Target *target)
|
||||
: BuildSystem(target), m_projectScanner(target->project())
|
||||
{
|
||||
static_cast<NimProject *>(project())->setExcludedFiles(list);
|
||||
}
|
||||
connect(&m_projectScanner, &NimProjectScanner::finished, this, [this] {
|
||||
m_guard.markAsSuccess();
|
||||
m_guard = {}; // Trigger destructor of previous object, emitting parsingFinished()
|
||||
|
||||
QStringList NimBuildSystem::excludedFiles()
|
||||
{
|
||||
return static_cast<NimProject *>(project())->excludedFiles();
|
||||
emitBuildSystemUpdated();
|
||||
});
|
||||
|
||||
connect(&m_projectScanner, &NimProjectScanner::requestReparse,
|
||||
this, &NimBuildSystem::requestDelayedParse);
|
||||
|
||||
connect(&m_projectScanner, &NimProjectScanner::directoryChanged, this, [this] {
|
||||
if (!isWaitingForParse())
|
||||
requestDelayedParse();
|
||||
});
|
||||
|
||||
requestDelayedParse();
|
||||
}
|
||||
|
||||
void NimBuildSystem::triggerParsing()
|
||||
{
|
||||
m_guard = guardParsingRun();
|
||||
m_scanner.asyncScanForFiles(projectDirectory());
|
||||
}
|
||||
|
||||
const FilePathList NimBuildSystem::nimFiles() const
|
||||
{
|
||||
return project()->files([](const Node *n) {
|
||||
return Project::AllFiles(n) && n->path().endsWith(".nim");
|
||||
});
|
||||
m_projectScanner.startScan();
|
||||
}
|
||||
|
||||
void NimBuildSystem::loadSettings()
|
||||
{
|
||||
QVariantMap settings = project()->namedSettings(SETTINGS_KEY).toMap();
|
||||
if (settings.contains(EXCLUDED_FILES_KEY))
|
||||
setExcludedFiles(settings.value(EXCLUDED_FILES_KEY, excludedFiles()).toStringList());
|
||||
m_projectScanner.setExcludedFiles(settings.value(EXCLUDED_FILES_KEY, m_projectScanner.excludedFiles()).toStringList());
|
||||
|
||||
requestParse();
|
||||
}
|
||||
@@ -126,44 +203,10 @@ void NimBuildSystem::loadSettings()
|
||||
void NimBuildSystem::saveSettings()
|
||||
{
|
||||
QVariantMap settings;
|
||||
settings.insert(EXCLUDED_FILES_KEY, excludedFiles());
|
||||
settings.insert(EXCLUDED_FILES_KEY, m_projectScanner.excludedFiles());
|
||||
project()->setNamedSettings(SETTINGS_KEY, settings);
|
||||
}
|
||||
|
||||
void NimBuildSystem::updateProject()
|
||||
{
|
||||
// Collect scanned nodes
|
||||
std::vector<std::unique_ptr<FileNode>> nodes;
|
||||
for (FileNode *node : m_scanner.release()) {
|
||||
if (!node->path().endsWith(".nim") && !node->path().endsWith(".nimble"))
|
||||
node->setEnabled(false); // Disable files that do not end in .nim
|
||||
nodes.emplace_back(node);
|
||||
}
|
||||
|
||||
// Sync watched dirs
|
||||
const QSet<QString> fsDirs = Utils::transform<QSet>(nodes, &FileNode::directory);
|
||||
const QSet<QString> projectDirs = Utils::toSet(m_directoryWatcher.directories());
|
||||
m_directoryWatcher.addDirectories(Utils::toList(fsDirs - projectDirs), FileSystemWatcher::WatchAllChanges);
|
||||
m_directoryWatcher.removeDirectories(Utils::toList(projectDirs - fsDirs));
|
||||
|
||||
// Sync project files
|
||||
const QSet<FilePath> fsFiles = Utils::transform<QSet>(nodes, &FileNode::filePath);
|
||||
const QSet<FilePath> projectFiles = Utils::toSet(project()->files([](const Node *n) { return Project::AllFiles(n); }));
|
||||
|
||||
if (fsFiles != projectFiles) {
|
||||
auto projectNode = std::make_unique<ProjectNode>(project()->projectDirectory());
|
||||
projectNode->setDisplayName(project()->displayName());
|
||||
projectNode->addNestedNodes(std::move(nodes));
|
||||
setRootProjectNode(std::move(projectNode));
|
||||
}
|
||||
|
||||
// Complete scan
|
||||
m_guard.markAsSuccess();
|
||||
m_guard = {}; // Trigger destructor of previous object, emitting parsingFinished()
|
||||
|
||||
emitBuildSystemUpdated();
|
||||
}
|
||||
|
||||
bool NimBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
||||
{
|
||||
if (node->asFileNode()) {
|
||||
@@ -180,15 +223,14 @@ bool NimBuildSystem::supportsAction(Node *context, ProjectAction action, const N
|
||||
|
||||
bool NimBuildSystem::addFiles(Node *, const QStringList &filePaths, QStringList *)
|
||||
{
|
||||
return addFiles(filePaths);
|
||||
return m_projectScanner.addFiles(filePaths);
|
||||
}
|
||||
|
||||
RemovedFilesFromProject NimBuildSystem::removeFiles(Node *,
|
||||
const QStringList &filePaths,
|
||||
QStringList *)
|
||||
{
|
||||
return removeFiles(filePaths) ? RemovedFilesFromProject::Ok
|
||||
: RemovedFilesFromProject::Error;
|
||||
return m_projectScanner.removeFiles(filePaths);
|
||||
}
|
||||
|
||||
bool NimBuildSystem::deleteFiles(Node *, const QStringList &)
|
||||
@@ -198,6 +240,7 @@ bool NimBuildSystem::deleteFiles(Node *, const QStringList &)
|
||||
|
||||
bool NimBuildSystem::renameFile(Node *, const QString &filePath, const QString &newFilePath)
|
||||
{
|
||||
return renameFile(filePath, newFilePath);
|
||||
return m_projectScanner.renameFile(filePath, newFilePath);
|
||||
}
|
||||
|
||||
} // namespace Nim
|
||||
|
@@ -32,6 +32,39 @@
|
||||
|
||||
namespace Nim {
|
||||
|
||||
class NimProjectScanner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NimProjectScanner(ProjectExplorer::Project *project);
|
||||
|
||||
void setFilter(const ProjectExplorer::TreeScanner::FileFilter &filter);
|
||||
void startScan();
|
||||
void watchProjectFilePath();
|
||||
|
||||
void setExcludedFiles(const QStringList &list);
|
||||
QStringList excludedFiles() const;
|
||||
|
||||
bool addFiles(const QStringList &filePaths);
|
||||
ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths);
|
||||
bool renameFile(const QString &from, const QString &to);
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
void requestReparse();
|
||||
void directoryChanged();
|
||||
void fileChanged(const QString &path);
|
||||
|
||||
private:
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
ProjectExplorer::Project *m_project = nullptr;
|
||||
ProjectExplorer::TreeScanner m_scanner;
|
||||
Utils::FileSystemWatcher m_directoryWatcher;
|
||||
};
|
||||
|
||||
class NimBuildSystem : public ProjectExplorer::BuildSystem
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -39,41 +72,28 @@ class NimBuildSystem : public ProjectExplorer::BuildSystem
|
||||
public:
|
||||
explicit NimBuildSystem(ProjectExplorer::Target *target);
|
||||
|
||||
bool addFiles(const QStringList &filePaths);
|
||||
bool removeFiles(const QStringList &filePaths);
|
||||
bool renameFile(const QString &filePath, const QString &newFilePath);
|
||||
|
||||
bool supportsAction(ProjectExplorer::Node *,
|
||||
ProjectExplorer::ProjectAction action,
|
||||
const ProjectExplorer::Node *node) const override;
|
||||
const ProjectExplorer::Node *node) const final;
|
||||
bool addFiles(ProjectExplorer::Node *node,
|
||||
const QStringList &filePaths, QStringList *) override;
|
||||
const QStringList &filePaths, QStringList *) final;
|
||||
ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *node,
|
||||
const QStringList &filePaths,
|
||||
QStringList *) override;
|
||||
bool deleteFiles(ProjectExplorer::Node *, const QStringList &) override;
|
||||
bool deleteFiles(ProjectExplorer::Node *, const QStringList &) final;
|
||||
bool renameFile(ProjectExplorer::Node *,
|
||||
const QString &filePath, const QString &newFilePath) override;
|
||||
|
||||
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
|
||||
const QString &filePath, const QString &newFilePath) final;
|
||||
|
||||
void triggerParsing() override;
|
||||
|
||||
const Utils::FilePathList nimFiles() const;
|
||||
|
||||
protected:
|
||||
virtual void loadSettings();
|
||||
virtual void saveSettings();
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
void collectProjectFiles();
|
||||
void updateProject();
|
||||
|
||||
ProjectExplorer::TreeScanner m_scanner;
|
||||
|
||||
ParseGuard m_guard;
|
||||
|
||||
Utils::FileSystemWatcher m_directoryWatcher;
|
||||
NimProjectScanner m_projectScanner;
|
||||
};
|
||||
|
||||
} // namespace Nim
|
||||
|
@@ -271,8 +271,9 @@ void NimCompilerBuildStep::updateTargetNimFile()
|
||||
{
|
||||
if (!m_targetNimFile.isEmpty())
|
||||
return;
|
||||
const Utils::FilePathList nimFiles =
|
||||
static_cast<NimBuildSystem *>(buildConfiguration()->buildSystem())->nimFiles();
|
||||
const Utils::FilePathList nimFiles = project()->files([](const Node *n) {
|
||||
return Project::AllFiles(n) && n->path().endsWith(".nim");
|
||||
});
|
||||
if (!nimFiles.isEmpty())
|
||||
setTargetNimFile(nimFiles.at(0));
|
||||
}
|
||||
|
@@ -116,12 +116,14 @@ void NimCompilerBuildStepConfigWidget::updateTargetComboBox()
|
||||
{
|
||||
QTC_ASSERT(m_buildStep, return );
|
||||
|
||||
const auto bs = qobject_cast<NimBuildSystem *>(m_buildStep->buildConfiguration()->buildSystem());
|
||||
QTC_ASSERT(bs, return );
|
||||
|
||||
// Re enter the files
|
||||
m_ui->targetComboBox->clear();
|
||||
for (const FilePath &file : bs->nimFiles())
|
||||
|
||||
const FilePathList nimFiles = m_buildStep->project()->files([](const Node *n) {
|
||||
return Project::AllFiles(n) && n->path().endsWith(".nim");
|
||||
});
|
||||
|
||||
for (const FilePath &file : nimFiles)
|
||||
m_ui->targetComboBox->addItem(file.fileName(), file.toString());
|
||||
|
||||
const int index = m_ui->targetComboBox->findData(m_buildStep->targetNimFile().toString());
|
||||
|
@@ -28,12 +28,11 @@
|
||||
|
||||
#include "../nimconstants.h"
|
||||
|
||||
#include <projectexplorer/buildsystem.h>
|
||||
#include <projectexplorer/localenvironmentaspect.h>
|
||||
#include <projectexplorer/runconfigurationaspects.h>
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
@@ -55,8 +54,7 @@ NimRunConfiguration::NimRunConfiguration(Target *target, Core::Id id)
|
||||
setDefaultDisplayName(tr("Current Build Target"));
|
||||
|
||||
// Connect target signals
|
||||
connect(target, &Target::activeBuildConfigurationChanged,
|
||||
this, &NimRunConfiguration::updateConfiguration);
|
||||
connect(target, &Target::buildSystemUpdated, this, &NimRunConfiguration::updateConfiguration);
|
||||
updateConfiguration();
|
||||
}
|
||||
|
||||
@@ -65,35 +63,12 @@ void NimRunConfiguration::updateConfiguration()
|
||||
auto buildConfiguration = qobject_cast<NimBuildConfiguration *>(activeBuildConfiguration());
|
||||
if (!buildConfiguration)
|
||||
return;
|
||||
setActiveBuildConfiguration(buildConfiguration);
|
||||
const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo();
|
||||
aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(outFileInfo.absoluteFilePath()));
|
||||
const QString workingDirectory = outFileInfo.absoluteDir().absolutePath();
|
||||
aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(FilePath::fromString(workingDirectory));
|
||||
}
|
||||
|
||||
void NimRunConfiguration::setActiveBuildConfiguration(NimBuildConfiguration *activeBuildConfiguration)
|
||||
{
|
||||
if (m_buildConfiguration == activeBuildConfiguration)
|
||||
return;
|
||||
|
||||
if (m_buildConfiguration) {
|
||||
disconnect(m_buildConfiguration, &NimBuildConfiguration::buildDirectoryChanged,
|
||||
this, &NimRunConfiguration::updateConfiguration);
|
||||
disconnect(m_buildConfiguration, &NimBuildConfiguration::outFilePathChanged,
|
||||
this, &NimRunConfiguration::updateConfiguration);
|
||||
}
|
||||
|
||||
m_buildConfiguration = activeBuildConfiguration;
|
||||
|
||||
if (m_buildConfiguration) {
|
||||
connect(m_buildConfiguration, &NimBuildConfiguration::buildDirectoryChanged,
|
||||
this, &NimRunConfiguration::updateConfiguration);
|
||||
connect(m_buildConfiguration, &NimBuildConfiguration::outFilePathChanged,
|
||||
this, &NimRunConfiguration::updateConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
// NimRunConfigurationFactory
|
||||
|
||||
NimRunConfigurationFactory::NimRunConfigurationFactory() : FixedRunConfigurationFactory(QString())
|
||||
|
@@ -29,8 +29,6 @@
|
||||
|
||||
namespace Nim {
|
||||
|
||||
class NimBuildConfiguration;
|
||||
|
||||
class NimRunConfiguration : public ProjectExplorer::RunConfiguration
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -40,9 +38,6 @@ public:
|
||||
|
||||
private:
|
||||
void updateConfiguration();
|
||||
void setActiveBuildConfiguration(NimBuildConfiguration *activeBuildConfiguration);
|
||||
|
||||
NimBuildConfiguration *m_buildConfiguration = nullptr;
|
||||
};
|
||||
|
||||
class NimRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory
|
||||
|
Reference in New Issue
Block a user