UNPKG

@embroider/macros

Version:

Standardized build-time macros for ember apps.

240 lines • 11.4 kB
"use strict"; 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