Initial commit
[yaffs-website] / node_modules / js-yaml / lib / js-yaml / type / js / function.js
1 'use strict';
2
3 var esprima;
4
5 // Browserified version does not have esprima
6 //
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.
11 //
12 try {
13   // workaround to exclude package from browserify list.
14   var _require = require;
15   esprima = _require('esprima');
16 } catch (_) {
17   /*global window */
18   if (typeof window !== 'undefined') esprima = window.esprima;
19 }
20
21 var Type = require('../../type');
22
23 function resolveJavascriptFunction(data) {
24   if (data === null) return false;
25
26   try {
27     var source = '(' + data + ')',
28         ast    = esprima.parse(source, { range: true });
29
30     if (ast.type                    !== 'Program'             ||
31         ast.body.length             !== 1                     ||
32         ast.body[0].type            !== 'ExpressionStatement' ||
33         ast.body[0].expression.type !== 'FunctionExpression') {
34       return false;
35     }
36
37     return true;
38   } catch (err) {
39     return false;
40   }
41 }
42
43 function constructJavascriptFunction(data) {
44   /*jslint evil:true*/
45
46   var source = '(' + data + ')',
47       ast    = esprima.parse(source, { range: true }),
48       params = [],
49       body;
50
51   if (ast.type                    !== 'Program'             ||
52       ast.body.length             !== 1                     ||
53       ast.body[0].type            !== 'ExpressionStatement' ||
54       ast.body[0].expression.type !== 'FunctionExpression') {
55     throw new Error('Failed to resolve function');
56   }
57
58   ast.body[0].expression.params.forEach(function (param) {
59     params.push(param.name);
60   });
61
62   body = ast.body[0].expression.body.range;
63
64   // Esprima's ranges include the first '{' and the last '}' characters on
65   // function expressions. So cut them out.
66   /*eslint-disable no-new-func*/
67   return new Function(params, source.slice(body[0] + 1, body[1] - 1));
68 }
69
70 function representJavascriptFunction(object /*, style*/) {
71   return object.toString();
72 }
73
74 function isFunction(object) {
75   return Object.prototype.toString.call(object) === '[object Function]';
76 }
77
78 module.exports = new Type('tag:yaml.org,2002:js/function', {
79   kind: 'scalar',
80   resolve: resolveJavascriptFunction,
81   construct: constructJavascriptFunction,
82   predicate: isFunction,
83   represent: representJavascriptFunction
84 });