UNPKG

edacation

Version:

Library and CLI for interacting with Yosys and nextpnr.

204 lines 7.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Project = exports.ProjectOutputFile = exports.ProjectInputFile = void 0; const util_js_1 = require("../util.js"); const configuration_js_1 = require("./configuration.js"); class ProjectInputFile { constructor(_path, _type) { this._path = _path; this._type = _type; } get path() { return this._path; } get type() { return this._type; } set type(type) { this._type = type; } static serialize(file) { return { path: file.path, type: file.type }; } static deserialize(data, ..._args) { // Older versions of this module (<= 0.3.9) stored input files as an array of paths instead, // so we need to migrate if data is a string (single output file). if (typeof data === 'string') { data = { path: data, type: 'design' }; } return new ProjectInputFile(data.path, data.type); } } exports.ProjectInputFile = ProjectInputFile; class ProjectOutputFile { constructor(_project, _path, _targetId = null, _stale = false) { this._project = _project; this._path = _path; this._targetId = _targetId; this._stale = _stale; } get path() { return this._path; } get targetId() { return this._targetId; } set targetId(id) { if (id !== null && this._project.getTarget(id) === null) { throw new Error(`Invalid target id: ${id}`); } this._targetId = id; } get target() { if (!this._targetId) return null; return this._project.getTarget(this._targetId); } get stale() { return this._stale; } set stale(isStale) { this._stale = isStale; } static serialize(file) { return { path: file.path, targetId: file.targetId, stale: file.stale }; } static deserialize(project, data, ..._args) { // Older versions of this module (<= 0.3.12) stored output files as an array of paths instead, // so we need to migrate if data is a string (single output file). if (typeof data === 'string') { data = { path: data, targetId: null, stale: false }; } return new ProjectOutputFile(project, data.path, data.targetId, data.stale); } } exports.ProjectOutputFile = ProjectOutputFile; class Project { constructor(name, inputFiles = [], outputFiles = [], configuration = configuration_js_1.DEFAULT_CONFIGURATION) { this.name = name; this.inputFiles = inputFiles.map((file) => ProjectInputFile.deserialize(file)); this.outputFiles = outputFiles.map((file) => ProjectOutputFile.deserialize(this, file)); const config = configuration_js_1.schemaProjectConfiguration.safeParse(configuration); if (config.success) { this.configuration = config.data; } else { throw new Error(`Failed to parse project configuration: ${config.error.toString()}`); } // Trigger a config 'update' to deploy any modifications it might want to make this.updateConfiguration({}); } getName() { return this.name; } getInputFiles() { return this.inputFiles; } hasInputFile(filePath) { return this.getInputFile(filePath) !== null; } getInputFile(filePath) { return this.inputFiles.find((file) => file.path === filePath) ?? null; } addInputFiles(files) { for (const file of files) { if (!this.hasInputFile(file.path)) { const inputFile = new ProjectInputFile(file.path, file.type ?? 'design'); this.inputFiles.push(inputFile); } } this.inputFiles.sort((a, b) => { return a < b ? -1 : 1; }); } removeInputFiles(filePaths) { this.inputFiles = this.inputFiles.filter((file) => !filePaths.includes(file.path)); } getOutputFiles() { return this.outputFiles; } hasOutputFile(filePath) { return this.getOutputFile(filePath) !== null; } getOutputFile(filePath) { return this.outputFiles.find((file) => file.path === filePath) ?? null; } addOutputFiles(files) { for (const file of files) { const existingOutFile = this.getOutputFile(file.path); if (existingOutFile) { // File already exists, so we don't want to add it again. // But, we should make sure the target ID gets updated and set `stale` to false. existingOutFile.targetId = file.targetId; existingOutFile.stale = false; continue; } const outputFile = new ProjectOutputFile(this, file.path, file.targetId); if (outputFile.target === null) throw new Error(`Invalid target ID: ${file.targetId}`); this.outputFiles.push(outputFile); } this.outputFiles.sort((a, b) => { return a < b ? -1 : 1; }); } removeOutputFiles(filePaths) { this.outputFiles = this.outputFiles.filter((file) => !filePaths.includes(file.path)); } expireOutputFiles() { for (const file of this.outputFiles) { file.stale = true; } } getConfiguration() { return this.configuration; } updateConfiguration(configuration) { this.configuration = { ...this.configuration, ...configuration }; // Unset 'lingering' output file target IDs for (const outFile of this.outputFiles) { if (!outFile.target) outFile.targetId = null; } } getTarget(id) { const targets = this.configuration.targets; return targets.find((target) => target.id === id) ?? null; } static serialize(project) { return { name: project.name, inputFiles: project.inputFiles.map((file) => ProjectInputFile.serialize(file)), outputFiles: project.outputFiles.map((file) => ProjectOutputFile.serialize(file)), configuration: project.configuration }; } static deserialize(data, ..._args) { const name = data.name; const inputFiles = data.inputFiles ?? []; const outputFiles = data.outputFiles ?? []; const configuration = data.configuration ?? {}; return new Project(name, inputFiles, outputFiles, configuration); } static loadFromData(rawData) { const data = (0, util_js_1.decodeJSON)(rawData); const project = Project.deserialize(data); return project; } static storeToData(project) { const data = Project.serialize(project); return (0, util_js_1.encodeJSON)(data, true); } } exports.Project = Project; //# sourceMappingURL=project.js.map