antlr-ng
Version:
Next generation ANTLR Tool
158 lines (157 loc) • 5.99 kB
JavaScript
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
};