@embroider/macros
Version:
Standardized build-time macros for ember apps.
240 lines • 11.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildPlugin = buildPlugin;
exports.makeFirstTransform = makeFirstTransform;
exports.makeSecondTransform = makeSecondTransform;
const literal_1 = __importDefault(require("./literal"));
const get_config_1 = __importDefault(require("./get-config"));
const app_ember_satisfies_1 = __importDefault(require("./app-ember-satisfies"));
const dependency_satisfies_1 = __importDefault(require("./dependency-satisfies"));
const macro_maybe_attrs_1 = require("./macro-maybe-attrs");
const macro_condition_1 = require("./macro-condition");
const fail_build_1 = require("./fail-build");
const shared_internals_1 = require("@embroider/shared-internals");
function buildPlugin(params) {
return {
name: params.name,
plugin: params.methodName === 'makeFirstTransform'
? makeFirstTransform(params.firstTransformParams)
: makeSecondTransform(),
baseDir: () => params.baseDir,
};
}
function makeFirstTransform(opts) {
function embroiderFirstMacrosTransform(env) {
if (!opts.packageRoot && !env.filename) {
throw new Error(`bug in @embroider/macros. Running without packageRoot but don't have filename.`);
}
let packageCache = shared_internals_1.RewrittenPackageCache.shared('embroider', opts.appRoot);
let scopeStack = [];
// packageRoot is set when we run inside classic ember-cli. Otherwise we're in
// Embroider, where we can use absolute filenames.
const moduleName = opts.packageRoot ? env.meta.moduleName : env.filename;
return {
name: '@embroider/macros/first',
visitor: {
...scopeVisitors(env, scopeStack),
SubExpression(node, walker) {
if (node.path.type !== 'PathExpression') {
return;
}
if (inScope(scopeStack, headOf(node.path))) {
return;
}
if (node.path.original === 'macroGetOwnConfig') {
return (0, literal_1.default)((0, get_config_1.default)(node, opts.configs, opts.packageRoot, moduleName, true, packageCache), env.syntax.builders);
}
if (node.path.original === 'macroGetConfig') {
return (0, literal_1.default)((0, get_config_1.default)(node, opts.configs, opts.packageRoot, moduleName, false, packageCache), env.syntax.builders);
}
if (node.path.original === 'macroDependencySatisfies') {
const staticValue = (0, literal_1.default)((0, dependency_satisfies_1.default)(node, opts.packageRoot, moduleName, packageCache), env.syntax.builders);
// If this is a macro expression by itself, then turn it into a macroCondition for the second pass to prune.
// Otherwise assume it's being composed with another macro and evaluate it as a literal
if (walker.parent.node.path.original === 'if') {
return env.syntax.builders.sexpr('macroCondition', [staticValue]);
}
return staticValue;
}
if (node.path.original === 'macroAppEmberSatisfies') {
const staticValue = (0, literal_1.default)((0, app_ember_satisfies_1.default)(node, packageCache), env.syntax.builders);
// If this is a macro expression by itself, then turn it into a macroCondition for the second pass to prune.
// Otherwise assume it's being composed with another macro and evaluate it as a literal
if (walker.parent.node.path.original === 'if') {
return env.syntax.builders.sexpr('macroCondition', [staticValue]);
}
return staticValue;
}
},
MustacheStatement(node) {
if (node.path.type !== 'PathExpression') {
return;
}
if (inScope(scopeStack, headOf(node.path))) {
return;
}
if (node.path.original === 'macroGetOwnConfig') {
return env.syntax.builders.mustache((0, literal_1.default)((0, get_config_1.default)(node, opts.configs, opts.packageRoot, moduleName, true, packageCache), env.syntax.builders));
}
if (node.path.original === 'macroGetConfig') {
return env.syntax.builders.mustache((0, literal_1.default)((0, get_config_1.default)(node, opts.configs, opts.packageRoot, moduleName, false, packageCache), env.syntax.builders));
}
if (node.path.original === 'macroDependencySatisfies') {
return env.syntax.builders.mustache((0, literal_1.default)((0, dependency_satisfies_1.default)(node, opts.packageRoot, moduleName, packageCache), env.syntax.builders));
}
if (node.path.original === 'macroAppEmberSatisfies') {
return env.syntax.builders.mustache((0, literal_1.default)((0, app_ember_satisfies_1.default)(node, packageCache), env.syntax.builders));
}
},
},
};
}
embroiderFirstMacrosTransform.embroiderMacrosASTMarker = true;
embroiderFirstMacrosTransform.parallelBabel = {
requireFile: __filename,
buildUsing: 'makeFirstTransform',
get params() {
return opts;
},
};
return embroiderFirstMacrosTransform;
}
function makeSecondTransform() {
function embroiderSecondMacrosTransform(env) {
let scopeStack = [];
return {
name: '@embroider/macros/second',
visitor: {
...scopeVisitors(env, scopeStack),
BlockStatement(node) {
if (node.path.type !== 'PathExpression') {
return;
}
if (inScope(scopeStack, headOf(node.path))) {
return;
}
if (node.path.original === 'if') {
return (0, macro_condition_1.macroIfBlock)(node);
}
if (node.path.original === 'unless') {
return (0, macro_condition_1.macroUnlessBlock)(node);
}
},
SubExpression(node) {
if (node.path.type !== 'PathExpression') {
return;
}
if (inScope(scopeStack, headOf(node.path))) {
return;
}
if (node.path.original === 'if') {
return (0, macro_condition_1.macroIfExpression)(node, env.syntax.builders);
}
if (node.path.original === 'unless') {
return (0, macro_condition_1.macroUnlessExpression)(node, env.syntax.builders);
}
if (node.path.original === 'macroFailBuild') {
(0, fail_build_1.failBuild)(node);
}
},
ElementNode(node) {
node.modifiers = node.modifiers.filter((modifier) => {
if (modifier.path.type === 'SubExpression' &&
modifier.path.path.type === 'PathExpression' &&
modifier.path.path.original === 'if') {
modifier.path = (0, macro_condition_1.macroIfExpression)(modifier.path, env.syntax.builders);
if (modifier.path.type === 'UndefinedLiteral') {
return false;
}
}
if (modifier.path.type === 'SubExpression' &&
modifier.path.path.type === 'PathExpression' &&
modifier.path.path.original === 'unless') {
modifier.path = (0, macro_condition_1.macroUnlessExpression)(modifier.path, env.syntax.builders);
if (modifier.path.type === 'UndefinedLiteral') {
return false;
}
}
if (modifier.path.type !== 'PathExpression') {
return true;
}
if (inScope(scopeStack, headOf(node.path))) {
return true;
}
if (modifier.path.original === 'macroMaybeAttrs') {
(0, macro_maybe_attrs_1.maybeAttrs)(node, modifier, env.syntax.builders);
}
else {
return true;
}
});
},
MustacheStatement(node) {
if (node.path.type !== 'PathExpression') {
return;
}
if (inScope(scopeStack, headOf(node.path))) {
return;
}
if (node.path.original === 'if') {
return (0, macro_condition_1.macroIfMustache)(node, env.syntax.builders);
}
if (node.path.original === 'unless') {
return (0, macro_condition_1.macroUnlessMustache)(node, env.syntax.builders);
}
if (node.path.original === 'macroFailBuild') {
(0, fail_build_1.failBuild)(node);
}
},
},
};
}
embroiderSecondMacrosTransform.embroiderMacrosASTMarker = true;
embroiderSecondMacrosTransform.parallelBabel = {
requireFile: __filename,
buildUsing: 'makeSecondTransform',
params: undefined,
};
return embroiderSecondMacrosTransform;
}
function inScope(scopeStack, name) {
for (let scope of scopeStack) {
if (scope.includes(name)) {
return true;
}
}
return false;
}
function headOf(path) {
if (!path)
return;
return 'head' in path ? path.head.name : path.parts[0];
}
function scopeVisitors(env, scopeStack) {
function enter(node) {
if (node.blockParams.length > 0) {
scopeStack.push(node.blockParams);
}
}
function exit(node) {
if (node.blockParams.length > 0) {
scopeStack.pop();
}
}
let hasTemplate = 'template' in env.syntax.builders;
if (hasTemplate) {
return {
Template: { enter, exit },
Block: { enter, exit },
};
}
else {
return {
Program: { enter, exit },
};
}
}
//# sourceMappingURL=ast-transform.js.map