5 // Browserified version does not have esprima
7 // 1. For node.js just require module as deps
8 // 2. For browser try to require mudule via external AMD system.
9 // If not found - try to fallback to window.esprima. If not
10 // found too - then fail to parse.
13 esprima = require('esprima');
16 if (typeof window !== 'undefined') { esprima = window.esprima; }
19 var Type = require('../../type');
21 function resolveJavascriptFunction(data) {
27 var source = '(' + data + ')',
28 ast = esprima.parse(source, { range: true }),
32 if ('Program' !== ast.type ||
33 1 !== ast.body.length ||
34 'ExpressionStatement' !== ast.body[0].type ||
35 'FunctionExpression' !== ast.body[0].expression.type) {
45 function constructJavascriptFunction(data) {
48 var source = '(' + data + ')',
49 ast = esprima.parse(source, { range: true }),
53 if ('Program' !== ast.type ||
54 1 !== ast.body.length ||
55 'ExpressionStatement' !== ast.body[0].type ||
56 'FunctionExpression' !== ast.body[0].expression.type) {
57 throw new Error('Failed to resolve function');
60 ast.body[0].expression.params.forEach(function (param) {
61 params.push(param.name);
64 body = ast.body[0].expression.body.range;
66 // Esprima's ranges include the first '{' and the last '}' characters on
67 // function expressions. So cut them out.
68 return new Function(params, source.slice(body[0]+1, body[1]-1));
71 function representJavascriptFunction(object /*, style*/) {
72 return object.toString();
75 function isFunction(object) {
76 return '[object Function]' === Object.prototype.toString.call(object);
79 module.exports = new Type('tag:yaml.org,2002:js/function', {
81 resolve: resolveJavascriptFunction,
82 construct: constructJavascriptFunction,
83 predicate: isFunction,
84 represent: representJavascriptFunction