use :node;
var Node = module.require('./Node').Node;
fn Parameter(id, defaultValue, splat)
extends Node { this.type = 'Parameter'; this.splat = splat; this.id = id; this.id.parent = this; this.defaultValue = defaultValue; if this.defaultValue? { this.defaultValue.parent = this; }
}
Parameter.prototype.codegen = () -> {
if !super.codegen() { return; } this.id = this.id.codegen(false); if this.defaultValue? { this.defaultValue = this.defaultValue.codegen(); } return this;
};
Parameter.prototype.hasCallExpression = () -> {
return false;
};
Parameter.generateFunctionBody = (func, params, body, defaults) -> {
var splatPosition = -1; for param, i in params { if param.splat { if splatPosition != -1 { Node.getErrorManager().error({ type: "MultipleSplatsDisallowed", message: "multiple splats are disallowed in a function declaration", loc: param.loc }); } splatPosition = i; } param = param.codegen(); defaults.push(param.defaultValue); params[i] = param.id; func.defineIdentifier(param.id); } if splatPosition != -1 { var declarations = [{ "type": "VariableDeclarator", "id": { "type": "Identifier", "name": "__splat" }, "init": null }]; for param, i in params { var init; if i < splatPosition { init = { "type": "MemberExpression", "computed": true, "object": { "type": "Identifier", "name": "arguments" }, "property": { "type": "Literal", "value": i } }; } else if i == splatPosition { init = { "type": "ConditionalExpression", "test": { "type": "BinaryExpression", "operator": "<=", "left": { "type": "Literal", "value": params.length }, "right": { "type": "MemberExpression", "computed": false, "object": { "type": "Identifier", "name": "arguments" }, "property": { "type": "Identifier", "name": "length" } } }, "consequent": { "type": "CallExpression", "callee": { "type": "MemberExpression", "computed": false, "object": { "type": "MemberExpression", "computed": false, "object": { "type": "ArrayExpression", "elements": [] }, "property": { "type": "Identifier", "name": "slice" } }, "property": { "type": "Identifier", "name": "call" } }, "arguments": [{ "type": "Identifier", "name": "arguments" }, { "type": "Literal", "value": splatPosition }] }, "alternate": { "type": "ArrayExpression", "elements": [] } }; if splatPosition < params.length - 1 { init.consequent.arguments.push({ "type": "AssignmentExpression", "operator": "=", "left": { "type": "Identifier", "name": "__splat" }, "right": { "type": "BinaryExpression", "operator": "-", "left": { "type": "MemberExpression", "computed": false, "object": { "type": "Identifier", "name": "arguments" }, "property": { "type": "Identifier", "name": "length" } }, "right": { "type": "Literal", "value": params.length - splatPosition - 1 } } }); init.alternate = { "type": "SequenceExpression", "expressions": [{ "type": "AssignmentExpression", "operator": "=", "left": { "type": "Identifier", "name": "__splat" }, "right": { "type": "Literal", "value": splatPosition } }, { "type": "ArrayExpression", "elements": [] }] }; } } else { init = { "type": "MemberExpression", "computed": true, "object": { "type": "Identifier", "name": "arguments" }, "property": { "type": "UpdateExpression", "operator": "++", "argument": { "type": "Identifier", "name": "__splat" }, "prefix": false } }; } declarations.push({ "type": "VariableDeclarator", "id": param, "init": init }); } body.body = [{ "type": "VariableDeclaration", "codeGenerated": true, "declarations": declarations, "kind": "let" }].concat(body.body); params.length = 0; }
};
exports.Parameter = Parameter;