The Node.js module exports two functions, selectAst
and makeExpr
, which are used for parsing and manipulating JavaScript code, and require dependencies such as esprima
and escodegen
. The functions work together to convert code to HTML, generate string representations of ASTs, and parse code to extract its structure and content.
npm run import -- "select ast"
var esprima = require('esprima')
var escodegen = require('escodegen')
var importer = require('../Core')
var {
selectDom,
evaluateDom,
treeToHtml,
htmlToTree
} = importer.import("select tree",
"tree to html",
"html to tree")
var FUNCTION_BODY = `//FunctionDeclaration/BlockStatement`
function toString(ctx, subctx) {
var ast = (subctx || ctx)
if(typeof ast.ownerDocument !== 'undefined') {
ast = htmlToTree(ast)
}
//escodegen.attachComments(ast, ast.comments, ast.tokens, ast.whitespace)
return escodegen.generate(ast, {
comment: true,
tokens: true,
whitespace: true,
format: {indent: {style: ' '}, quotes: 'single'}
})
}
function selectAst(descriptor, code) {
if(typeof code === 'function') {
code = code.toString()
}
if(typeof code === 'string') {
try {
if(code.match(/^import\s|\simport\s|^export\s|\sexport\s/gi)) {
code = esprima.parseModule(code, {range: true, tokens: true,
comment: true, whitespace: true, strict: false})
} else {
code = esprima.parse(code, {range: true, tokens: true,
comment: true, whitespace: true, strict: false})
}
} catch(e) {
console.log(e)
throw new Error('Could not parse \n' + code)
}
}
// TODO: move this conversion to selectDom for all objects?
// No more selectTree because jsel and friends are inconsistent.
if(typeof code.evaluate === 'undefined'
&& typeof code.ownerDocument === 'undefined') {
code = selectDom('//Program', treeToHtml(code))
code.ownerDocument.toString = toString.bind(code, code)
}
return selectDom(descriptor, code)
}
function makeExpr(code) {
if(typeof code === 'function') {
return selectAst([FUNCTION_BODY], code.toString())[0]
}
return selectAst([`//ExpressionStatement/*`], `(${code})`)[0]
}
module.exports = {
selectAst,
makeExpr
}
const { parse } = require('esprima');
const { generate } = require('escodegen');
const {
selectDom,
evaluateDom,
treeToHtml,
htmlToTree
} = require('../Core').import(['select tree', 'tree to html', 'html to tree']);
const FUNCTION_BODY = '//FunctionDeclaration/BlockStatement';
const QUOTES ='single';
const INDENT_STYLE =' ';
function toString(ast, subctx) {
if (ast.ownerDocument) {
return generate(ast, {
comment: true,
tokens: true,
whitespace: true,
format: {
indent: { style: INDENT_STYLE },
quotes: QUOTES
}
});
}
return generate(ast, {
comment: true,
tokens: true,
whitespace: true,
format: {
indent: { style: INDENT_STYLE },
quotes: QUOTES
}
});
}
function selectAst(descriptor, code) {
if (typeof code === 'function') {
code = code.toString();
}
try {
if (code.includes('import') || code.includes('export')) {
code = parseModule(code, { range: true, tokens: true, comment: true, whitespace: true, strict: false });
} else {
code = parse(code, { range: true, tokens: true, comment: true, whitespace: true, strict: false });
}
} catch (error) {
console.error(error);
throw new Error(`Could not parse: \n${code}`);
}
if (!code.evaluate &&!code.ownerDocument) {
code = selectDom('//Program', treeToHtml(code));
Object.defineProperty(code, 'toString', {
value: toString.bind(code, code),
enumerable: false,
writable: false
});
}
return selectDom(descriptor, code);
}
function makeExpr(code) {
if (typeof code === 'function') {
return selectAst([FUNCTION_BODY], code.toString())[0];
}
return selectAst([`//ExpressionStatement/*`], `(${code})`)[0];
}
module.exports = {
selectAst,
makeExpr
};
The provided code is a Node.js module that exports two functions: selectAst
and makeExpr
. These functions appear to be used for parsing and manipulating JavaScript code.
The code requires the following dependencies:
esprima
for parsing JavaScript codeescodegen
for generating JavaScript code from Abstract Syntax Trees (ASTs)../Core
(not shown in the code snippet) which exports several functions, including selectDom
, evaluateDom
, treeToHtml
, and htmlToTree
toString(ctx, subctx)
This function takes an AST and its optional subcontext as input. It converts the AST to HTML using htmlToTree
, if necessary, and then generates a string representation of the AST using escodegen.generate
.
selectAst(descriptor, code)
This function takes a descriptor and a code string (or a function that returns a code string) as input. It attempts to parse the code using esprima.parseModule
or esprima.parse
, depending on whether the code contains import/export statements. If parsing fails, it logs an error and throws a new error. If the code is a function, it converts it to a string. It then converts the code to an AST, if necessary, and passes it to selectDom
along with the descriptor.
makeExpr(code)
This function takes a code string (or a function that returns a code string) as input. If the code is a function, it calls selectAst
with the function body descriptor (FUNCTION_BODY
) and the code string. Otherwise, it calls selectAst
with a descriptor that matches an expression statement and wraps the code string in parentheses. The resulting AST is returned.
The module exports the selectAst
and makeExpr
functions.