UNPKG

antlr-ng

Version:

Next generation ANTLR Tool

158 lines (157 loc) 5.99 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); import { fileURLToPath } from "node:url"; import { STGroupFile } from "stringtemplate4ts"; import { Constants } from "../Constants.js"; import { CodeGenerator } from "../codegen/CodeGenerator.js"; import { GrammarType } from "../support/GrammarType.js"; import { Grammar } from "./Grammar.js"; class BuildDependencyGenerator { constructor(tool, g, libDirectory, generateListeners, generateVisitors) { this.libDirectory = libDirectory; this.generateListeners = generateListeners; this.generateVisitors = generateVisitors; this.tool = tool; this.g = g; this.generator = new CodeGenerator(g); } static { __name(this, "BuildDependencyGenerator"); } tool; g; generator; templates; /** * @returns a list of URL objects that name files ANTLR will emit from T.g. */ getGeneratedFileList() { const files = new Array(); if (this.generator.target.needsHeader()) { files.push(this.getOutputFile(this.generator.getRecognizerFileName(true))); } files.push(this.getOutputFile(this.generator.getRecognizerFileName(false))); files.push(this.getOutputFile(this.generator.getVocabFileName())); let headerExtST = null; const extST = this.generator.templates.getInstanceOf("codeFileExtension"); if (this.generator.templates.isDefined("headerFile")) { headerExtST = this.generator.templates.getInstanceOf("headerFileExtension"); const suffix = Grammar.getGrammarTypeToFileNameSuffix(this.g.type); const fileName = `${this.g.name}${suffix}${headerExtST?.render()}`; files.push(this.getOutputFile(fileName)); } if (this.g.isCombined()) { const suffix = Grammar.getGrammarTypeToFileNameSuffix(GrammarType.Lexer); const lexer = `${this.g.name}${suffix}${extST?.render()}`; files.push(this.getOutputFile(lexer)); const lexerTokens = this.g.name + suffix + Constants.VocabFileExtension; files.push(this.getOutputFile(lexerTokens)); if (headerExtST !== null) { const header = this.g.name + suffix + headerExtST.render(); files.push(this.getOutputFile(header)); } } if (this.generateListeners ?? true) { if (this.generator.target.needsHeader()) { files.push(this.getOutputFile(this.generator.getListenerFileName(true))); } files.push(this.getOutputFile(this.generator.getListenerFileName(false))); if (this.generator.target.needsHeader()) { files.push(this.getOutputFile(this.generator.getBaseListenerFileName(true))); } files.push(this.getOutputFile(this.generator.getBaseListenerFileName(false))); } if (this.generateVisitors) { if (this.generator.target.needsHeader()) { files.push(this.getOutputFile(this.generator.getVisitorFileName(true))); } files.push(this.getOutputFile(this.generator.getVisitorFileName(false))); if (this.generator.target.needsHeader()) { files.push(this.getOutputFile(this.generator.getBaseVisitorFileName(true))); } files.push(this.getOutputFile(this.generator.getBaseVisitorFileName(false))); } const imports = this.g.getAllImportedGrammars(); for (const g of imports) { files.push(this.getOutputFile(g.fileName)); } return files; } getOutputFile(fileName) { let outputDir = this.tool.getOutputDirectory(this.g.fileName); if (outputDir === ".") { outputDir = this.tool.getOutputDirectory(fileName); } if (outputDir === ".") { return new URL(fileName); } return new URL(fileName, outputDir); } /** * @returns a list of urls that name files ANTLR will read to process T.g. This can be .tokens files if the * grammar uses the tokenVocab option as well as any imported grammar files. */ getDependenciesFileList() { const files = this.getNonImportDependenciesFileList(); const imports = this.g.getAllImportedGrammars(); const libDirectory = this.libDirectory ?? "."; for (const g of imports) { const fileName = this.groomQualifiedFileName(libDirectory, g.fileName); files.push(new URL(fileName)); } return files; } /** * Return a list of File objects that name files ANTLR will read to process T.g; This can only be .tokens files * and only if they use the tokenVocab option. * * @returns List of dependencies other than imported grammars */ getNonImportDependenciesFileList() { const files = new Array(); const tokenVocab = this.g.getOptionString("tokenVocab"); if (tokenVocab !== void 0) { const fileName = tokenVocab + Constants.VocabFileExtension; let vocabFile; const libDirectory = this.libDirectory ?? "."; if (libDirectory === ".") { vocabFile = new URL(fileName); } else { vocabFile = new URL(fileName, libDirectory); } files.push(vocabFile); } return files; } getDependencies() { this.loadDependencyTemplates(); const dependenciesST = this.templates.getInstanceOf("dependencies"); dependenciesST.add("in", this.getDependenciesFileList()); dependenciesST.add("out", this.getGeneratedFileList()); dependenciesST.add("grammarFileName", this.g.fileName); return dependenciesST; } loadDependencyTemplates() { if (this.templates) { return; } const templatePath = fileURLToPath(new URL("../../templates/depend.stg", import.meta.url)); this.templates = new STGroupFile(templatePath, "utf-8"); } getGenerator() { return this.generator; } groomQualifiedFileName(outputDir, fileName) { if (outputDir === ".") { return fileName; } else if (outputDir.includes(" ")) { const escSpaces = outputDir.replaceAll(" ", "\\ "); return escSpaces + "/" + fileName; } else { return outputDir + "/" + fileName; } } } export { BuildDependencyGenerator };