bifocal/node_modules/gscan/lib/ast-linter/helpers/index.js

119 lines
3.5 KiB
JavaScript

const {AST} = require('handlebars');
function getPartialName(node) {
return node.name.original;
}
function getNodeName(node) {
switch (node.type) {
case 'SubExpression':
case 'MustacheStatement':
case 'BlockStatement':
return `${node.path.data ? '@' : ''}${node.path.parts.join('.')}`;
case 'Program':
return;
case 'PathExpression':
default:
if (node.data){
return `@${node.parts.join('.')}`;
}
if (node.parts) {
return node.parts[0];
}
if (node.name.parts) {
return node.name.parts[0];
}
if (node.name.original) {
return node.name.original;
}
}
}
function _blockPrefixChar(node) {
return node.inverse && !node.program ? '^' : '#';
}
function logNode(node) {
const prefix = (node.inverse || node.program) ? _blockPrefixChar(node) : '';
return `{{${prefix}${getNodeName(node)}}}`;
}
// Extracted from https://github.com/handlebars-lang/handlebars.js/blob/6790c080c641ef2b44e663800e1794fae180977a/lib/handlebars/compiler/compiler.js#L429
function blockParamIndex(name, options) {
for (
let depth = 0, len = options.blockParams.length;
depth < len;
depth++
) {
let blockParams = options.blockParams[depth],
param = blockParams && blockParams.indexOf(name);
if (blockParams && param >= 0) {
return [depth, param];
}
}
}
// Extracted from https://github.com/handlebars-lang/handlebars.js/blob/6790c080c641ef2b44e663800e1794fae180977a/lib/handlebars/compiler/compiler.js#L368
function classifyNode(sexpr, options = {knownHelpers: [], knownHelpersOnly: false, blockParams: []}) {
let isSimple = AST.helpers.simpleId(sexpr.path);
let isBlockParam = isSimple && !!blockParamIndex(sexpr.path.parts[0], options);
// a mustache is an eligible helper if:
// * its id is simple (a single part, not `this` or `..`)
let isHelper = !isBlockParam && AST.helpers.helperExpression(sexpr);
// if a mustache is an eligible helper but not a definite
// helper, it is ambiguous, and will be resolved in a later
// pass or at runtime.
let isEligible = !isBlockParam && (isHelper || isSimple);
// if ambiguous, we can possibly resolve the ambiguity now
// An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
if (isEligible && !isHelper) {
let name = sexpr.path.parts[0];
if (options.knownHelpers.includes(name)) {
isHelper = true;
} else if (options.knownHelpersOnly) {
isEligible = false;
}
}
if (isHelper) {
return 'helper';
} else if (isEligible) {
return 'ambiguous';
} else {
return 'simple';
}
}
// Extracted from https://github.com/handlebars-lang/handlebars.js/blob/6790c080c641ef2b44e663800e1794fae180977a/lib/handlebars/compiler/compiler.js#L522
function transformLiteralToPath(sexpr) {
if (!sexpr.path.parts) {
let literal = sexpr.path;
// Casting to string here to make false and 0 literal values play nicely with the rest
// of the system.
sexpr.path = {
type: 'PathExpression',
data: false,
depth: 0,
parts: [literal.original + ''],
original: literal.original + '',
loc: literal.loc
};
}
}
module.exports = {
getNodeName,
getPartialName,
logNode,
classifyNode,
transformLiteralToPath
};