'use strict'; var Node = require('./Node'); var ok = require('assert').ok; function removeTrailingUndefineds(args) { var i; var last = args.length-1; for (i=last; i>=0; i--) { if (args[i].type !== 'Literal' || args[i].value !== undefined) { break; } } if (i !== last) { args = args.slice(0, i+1); } return args; } class InvokeMacro extends Node { constructor(def) { super('InvokeMacro'); this.el = def.el; this.name = def.name; this.args = def.args; this.body = this.makeContainer(def.body); if (this.name != null) { ok(typeof this.name === 'string', 'Invalid macro name: ' + this.name); } } generateCode(codegen) { var el = this.el; var name = this.name; var args = this.args; var body = this.body; var builder = codegen.builder; var macroDef; if (el) { name = el.tagName; body = el.body; if (typeof name !== 'string') { codegen.context.addError(el, 'Element node with a dynamic tag name cannot be used to invoke a macro', 'ERR_INVOKE_MACRO'); return; } macroDef = codegen.context.getRegisteredMacro(name); if (!macroDef) { codegen.context.addError(el, 'Element node does not correspond to a macro', 'ERR_INVOKE_MACRO'); return; } if (el.argument) { args = builder.parseJavaScriptArgs(el.argument); } else { args = new Array(macroDef.params.length); for (let i=0; i { var paramName = attr.name; var paramIndex = macroDef.getParamIndex(paramName); if (paramIndex == null) { codegen.context.addError(el, 'The "' + name + '" macro does not have a parameter named "' + paramName + '"', 'ERR_INVOKE_MACRO'); return; } var value = attr.value; if (value == null) { value = builder.literal(true); } args[paramIndex] = value; }); } } else { macroDef = codegen.context.getRegisteredMacro(name); if (!macroDef) { codegen.addError('Macro not found with name "' + name + '"', 'ERR_INVOKE_MACRO'); return; } } if (!args) { args = []; } while (args.length < macroDef.params.length) { args.push(builder.literal(undefined)); } if (body && body.length) { args[macroDef.getParamIndex('renderBody')] = builder.renderBodyFunction(body); } args[macroDef.getParamIndex('out')] = builder.identifier('out'); args = removeTrailingUndefineds(args); return builder.functionCall(builder.identifier(macroDef.functionName), args); } walk(walker) { this.el = walker.walk(this.el); this.name = walker.walk(this.name); this.args = walker.walk(this.args); this.body = walker.walk(this.body); } } module.exports = InvokeMacro;