.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / 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   /* eslint-disable no-redeclare */
18   /* global window */
19   if (typeof window !== 'undefined') esprima = window.esprima;
20 }
21
22 var Type = require('../../type');
23
24 function resolveJavascriptFunction(data) {
25   if (data === null) return false;
26
27   try {
28     var source = '(' + data + ')',
29         ast    = esprima.parse(source, { range: true });
30
31     if (ast.type                    !== 'Program'             ||
32         ast.body.length             !== 1                     ||
33         ast.body[0].type            !== 'ExpressionStatement' ||
34         (ast.body[0].expression.type !== 'ArrowFunctionExpression' &&
35           ast.body[0].expression.type !== 'FunctionExpression')) {
36       return false;
37     }
38
39     return true;
40   } catch (err) {
41     return false;
42   }
43 }
44
45 function constructJavascriptFunction(data) {
46   /*jslint evil:true*/
47
48   var source = '(' + data + ')',
49       ast    = esprima.parse(source, { range: true }),
50       params = [],
51       body;
52
53   if (ast.type                    !== 'Program'             ||
54       ast.body.length             !== 1                     ||
55       ast.body[0].type            !== 'ExpressionStatement' ||
56       (ast.body[0].expression.type !== 'ArrowFunctionExpression' &&
57         ast.body[0].expression.type !== 'FunctionExpression')) {
58     throw new Error('Failed to resolve function');
59   }
60
61   ast.body[0].expression.params.forEach(function (param) {
62     params.push(param.name);
63   });
64
65   body = ast.body[0].expression.body.range;
66
67   // Esprima's ranges include the first '{' and the last '}' characters on
68   // function expressions. So cut them out.
69   if (ast.body[0].expression.body.type === 'BlockStatement') {
70     /*eslint-disable no-new-func*/
71     return new Function(params, source.slice(body[0] + 1, body[1] - 1));
72   }
73   // ES6 arrow functions can omit the BlockStatement. In that case, just return
74   // the body.
75   /*eslint-disable no-new-func*/
76   return new Function(params, 'return ' + source.slice(body[0], body[1]));
77 }
78
79 function representJavascriptFunction(object /*, style*/) {
80   return object.toString();
81 }
82
83 function isFunction(object) {
84   return Object.prototype.toString.call(object) === '[object Function]';
85 }
86
87 module.exports = new Type('tag:yaml.org,2002:js/function', {
88   kind: 'scalar',
89   resolve: resolveJavascriptFunction,
90   construct: constructJavascriptFunction,
91   predicate: isFunction,
92   represent: representJavascriptFunction
93 });