aboutsummaryrefslogtreecommitdiff
path: root/node_modules/call-signature/index.js
blob: 327cb56edc9894ad5beed7a3da9b44e0226dcd49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
'use strict';
module.exports.parse = parse;
module.exports.generate = generate;

// TODO(jamestalmage): Allow full range of identifier characters instead of just ASCII
//
// This will likely require a build step
//
// SPEC: http://www.ecma-international.org/ecma-262/5.1/#sec-7.6
//
// TOOLING:
//    https://github.com/mathiasbynens/regenerate
//    https://www.npmjs.com/package/regjsgen

var regex = /^\s*(?:([A-Za-z$_][A-Za-z0-9$_]*)\s*\.)?\s*([A-Za-z$_][A-Za-z0-9$_]*)\s*\(\s*((?:[A-Za-z$_][A-Za-z0-9$_]*)|(?:\[\s*[A-Za-z$_][A-Za-z0-9$_]*\s*]))?((?:\s*,\s*(?:(?:[A-Za-z$_][A-Za-z0-9$_]*)|(?:\[\s*[A-Za-z$_][A-Za-z0-9$_]*\s*])))+)?\s*\)\s*$/;

function parse(str) {
	var match = regex.exec(str);
	if (!match) {
		return null;
	}

	var callee;
	if (match[1]) {
		callee = {
			type: 'MemberExpression',
			object: match[1],
			member: match[2]
		};
	} else {
		callee = {
			type: 'Identifier',
			name: match[2]
		};
	}

	var args = match[4] || '';
	args = args.split(',');
	if (match[3]) {
		args[0] = match[3];
	}
	var trimmed = [];
	args.forEach(function (str) {
		var optional = false;
		str = str.replace(/\s+/g, '');
		if (!str.length) {
			return;
		}
		if (str.charAt(0) === '[' && str.charAt(str.length - 1) === ']') {
			optional = true;
			str = str.substring(1, str.length - 1);
		}
		trimmed.push({
			name: str,
			optional: optional
		});
	});

	return {
		callee: callee,
		args: trimmed
	};
}

function generate(parsed) {
	var callee;
	if (parsed.callee.type === 'MemberExpression') {
		callee = [
			parsed.callee.object,
			'.',
			parsed.callee.member
		];
	} else {
		callee = [parsed.callee.name];
	}
	return callee.concat([
		'(',
		parsed.args.map(function (arg) {
			return arg.optional ? '[' + arg.name + ']' : arg.name;
		}).join(', '),
		')'
	]).join('');
}