Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81154 views
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
esprima = require('esprima');
14
} catch (_) {
15
/*global window */
16
if (typeof window !== 'undefined') { esprima = window.esprima; }
17
}
18
19
var Type = require('../../type');
20
21
function resolveJavascriptFunction(data) {
22
if (null === data) {
23
return false;
24
}
25
26
try {
27
var source = '(' + data + ')',
28
ast = esprima.parse(source, { range: true }),
29
params = [],
30
body;
31
32
if ('Program' !== ast.type ||
33
1 !== ast.body.length ||
34
'ExpressionStatement' !== ast.body[0].type ||
35
'FunctionExpression' !== ast.body[0].expression.type) {
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 ('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');
58
}
59
60
ast.body[0].expression.params.forEach(function (param) {
61
params.push(param.name);
62
});
63
64
body = ast.body[0].expression.body.range;
65
66
// Esprima's ranges include the first '{' and the last '}' characters on
67
// function expressions. So cut them out.
68
/*eslint-disable no-new-func*/
69
return new Function(params, source.slice(body[0] + 1, body[1] - 1));
70
}
71
72
function representJavascriptFunction(object /*, style*/) {
73
return object.toString();
74
}
75
76
function isFunction(object) {
77
return '[object Function]' === Object.prototype.toString.call(object);
78
}
79
80
module.exports = new Type('tag:yaml.org,2002:js/function', {
81
kind: 'scalar',
82
resolve: resolveJavascriptFunction,
83
construct: constructJavascriptFunction,
84
predicate: isFunction,
85
represent: representJavascriptFunction
86
});
87
88