UNPKG

@specs-feup/clava

Version:

A C/C++ source-to-source compiler written in Typescript

183 lines (150 loc) 4.61 kB
import Io from "@specs-feup/lara/api/lara/Io.js"; import { debug } from "@specs-feup/lara/api/lara/core/LaraCore.js"; import { JavaClasses } from "@specs-feup/lara/api/lara/util/JavaTypes.js"; import Clava from "../Clava.js"; import CMakerUtils from "./CMakerUtils.js"; /** * Contains CMaker sources */ export default class CMakerSources { untaggedSources = []; taggedSources: Record<string, string[]> = {}; tags: Set<string> = new Set(); disableWeaving: boolean; constructor(disableWeaving: boolean = false) { this.disableWeaving = disableWeaving; } private static VARIABLE_UNTAGGED_SOURCES = "CMAKER_SOURCES"; private static VARIABLE_EXTERNAL_SOURCES = "EXTERNAL_SOURCES"; /** * */ copy() { const newCMakerSources = new CMakerSources(); newCMakerSources.untaggedSources = this.untaggedSources.slice(); newCMakerSources.taggedSources = structuredClone(this.taggedSources); newCMakerSources.tags = structuredClone(this.tags); newCMakerSources.disableWeaving = this.disableWeaving; return newCMakerSources; } /** * Adds the given sources. * * @param paths - Array with paths to sources */ addSources(paths: string[]) { for (const path of paths) { this.addSourcePrivate(this.untaggedSources, path); } } /** * Add the given sources. */ addSource(path: string) { this.addSourcePrivate(this.untaggedSources, path); } /** * Adds the given sources associated to a tag. */ addTaggedSources(tag: string, paths: string[]) { // Get current tagged sources let sources = this.taggedSources[tag]; // If not defined, initialize it if (sources === undefined) { sources = []; this.taggedSources[tag] = sources; this.tags.add(tag); } for (const path of paths) { this.addSourcePrivate(sources, path); } } private addSourcePrivate(sources: string[], path: string | JavaClasses.File) { const parsedPath = CMakerUtils.parsePath(path); sources.push(`"${parsedPath}"`); } /** * @returns An array with the CMake variables that have source files */ getSourceVariables() { const sources = []; if (this.untaggedSources.length > 0) { sources.push(CMakerSources.VARIABLE_UNTAGGED_SOURCES); } if (!this.disableWeaving) { if (Clava.getProgram().extraSources.length > 0) { sources.push(CMakerSources.VARIABLE_EXTERNAL_SOURCES); } } for (const tag of this.tags.values()) { sources.push(tag); } return sources; } private parseSourcePath(path: string | JavaClasses.File) { return `"${CMakerUtils.parsePath(path)}"`; } /** * @returns String with the CMake code that declares the current sources */ getCode() { let code = ""; // Add untagged sources if (this.untaggedSources.length > 0) { code += this.getCodeSource( CMakerSources.VARIABLE_UNTAGGED_SOURCES, this.untaggedSources ); } // Add external sources if weaving is not disabled if (!this.disableWeaving) { code = this.addExternalSources(code); } for (const tag of this.tags.values()) { const tagCode = this.getCodeSource(tag, this.taggedSources[tag]); if (code.length !== 0) { code += "\n"; } code += tagCode; } return code; } private addExternalSources(code: string) { const extraSources = Clava.getProgram().extraSources; const extraSourcesArray = []; for (const extraSource of extraSources) { debug(`Adding external source '${extraSource}'`); if (Io.isFile(extraSource)) { extraSourcesArray.push(this.parseSourcePath(extraSource)); } else if (Io.isFolder(extraSource)) { for (const sourcePath of Io.getPaths(extraSource)) { extraSourcesArray.push(this.parseSourcePath(sourcePath)); } } else { console.log(`[CMAKER] Extra source ' ${extraSource} ' does not exist`); } } if (extraSourcesArray.length > 0) { if (code.length !== 0) { code += "\n"; } code += this.getCodeSource( CMakerSources.VARIABLE_EXTERNAL_SOURCES, extraSourcesArray ); } return code; } /** * @returns String with the CMake code for a given source name and values */ private getCodeSource(sourceName: string, values: string[]) { const prefix = `set (${sourceName} `; // Build space let space = ""; for (let i = 0; i < prefix.length; i++) { space += " "; } return prefix + values.join("\n" + space) + "\n)"; } }