JJJ SSSSS 333333 GGGG EEEEEEE NN NN
JJJ SS 3333 GG GG EE NNN NN
JJJ SSSSS 3333 GG EEEEE NN N NN
JJ JJJ SS 333 GG GG EE NN NNN
JJJJJ SSSSS 333333 GGGGGG EEEEEEE NN NN
Author: mee Contact: meeteshmehta@cse.iitb.ac.in
This project generates boilerplate code to restrict types of values that can be contained in the AST
This project was developed to generate boilerplate code for Iridium's Three Address Code pass. It was originally intended to be name 3JS, but as class names cant start with 3 we named it JS3.
This project requires nodeJS and npm.
npm iLets say we want to restrict the language such that the Program body can only contain ImportDeclaration statements.
- Nodes that we want to restrict types are described in
languageRestriction.json.
{
"@babelImports": [ "ImportDeclaration" ],
"Program": {
"body": "Array< ImportDeclaration >"
}
}
-
Get the babel AST Type information file and name it
orig.ts(Usually it exists innode_modules/@babel/types/lib/index.d.ts). The one we are using is from version@babel/core -> ^7.25.2. -
Run this command to generate the outputs.
node --import=tsx main.ts- This will generate three files as output,
JS3Constructors.ts,JS3Handlers.ts,JS3Types.ts.
The file JS3Types.ts contains interfaces and types aliases on the restricted nodes.
export type JS3Program_body = Array< ImportDeclaration >;
export interface JS3Program extends Program {
body: JS3Program_body;
}The file JS3Handlers.ts contains visitor functions for the modified nodes with boilerplate code.
type OtherProps = any;
function handleProgram(node: Program, ...otherProps: OtherProps) {
// 4 fallthrough props, 1 restricted props
let orig_body = node.body; // Handling prop body
let fin_body : JS3Program_body; // Handling prop body
if (Array.isArray ( orig_body )) {
for (const _arrProp of orig_body) {
if(isBlockStatement (_arrProp)) {
console.error("TODO // unhandled Program->[body]->BlockStatement");
} else if(isBreakStatement (_arrProp)) {
console.error("TODO // unhandled Program->[body]->BreakStatement");
} // ... All the constructors
}
}
// let result: JS3Program = generateJS3Program(fin_body, node);
} The file JS3Constructors.ts contains constructors to generate the new nodes.
export function generateBaseNodeFrom(from: Node): Node {
const { start, end, loc, range, extra } = from;
const result = { start, end, loc, range, extra } as Node
return result
}
export function generateJS3Program(_body : JS3Program_body, from: Program) : JS3Program {
let to: JS3Program = generateBaseNodeFrom(from) as JS3Program;
to.type = from.type;
to.directives = from.directives;
to.sourceType = from.sourceType;
to.interpreter = from.interpreter;
to.body = _body;
return to;
}