-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathfunction-parser.js
More file actions
89 lines (74 loc) · 2.12 KB
/
function-parser.js
File metadata and controls
89 lines (74 loc) · 2.12 KB
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
84
85
86
87
88
89
const parseTraditionalFunction = fnString => {
fnString = fnString.slice('function'.length).trim()
isGenerator = fnString[0] === '*'
if (isGenerator) {
fnString = fnString.slice(1).trim()
}
const parameterStartIdx = fnString.indexOf('(')
let parameterEndIdx
let counter = 0
for (var i = parameterStartIdx+1; i < fnString.length; i++) {
const token = fnString[i]
if (token == ')' && counter == 0) {
parameterEndIdx = i
break
}
if (token == '(') {
counter += 1
} else if (token == ')') {
counter -= 1
}
}
const isAnonymous = parameterStartIdx == 0
const _rawParameter = fnString.slice(parameterStartIdx + 1, parameterEndIdx)
const bodyStartIndex = fnString.indexOf('{', parameterEndIdx)
const body = fnString.slice(bodyStartIndex + 1, fnString.length - 1).trim()
fnString = fnString.slice(0, bodyStartIndex).trim()
const name = isAnonymous ? null : fnString.slice(0, parameterStartIdx)
return {
type: isGenerator ? 'GENERATOR' : 'TRADITIONAL',
name,
_rawParameter,
body,
}
}
const parseArrowFunction = fnString => {
const arrowIndex = fnString.indexOf('=>')
let body = fnString.slice(arrowIndex+2).trim()
const hasCurlyBrace = body[0] == '{'
if (hasCurlyBrace) {
body = body.slice(1,-1).trim()
} else {
body = 'return ' + body
}
const parameterWithParentheses = fnString.slice(0, arrowIndex).trim()
const hasParentheses = fnString[0] == '('
let _rawParameter
if (hasParentheses) {
_rawParameter = parameterWithParentheses.slice(1,-1)
} else {
_rawParameter = parameterWithParentheses
}
return {
type: 'ARROW',
name: null,
_rawParameter,
body,
}
}
const parseFunction = fnString => {
const isAsync = fnString.startsWith('async')
if (isAsync) {
fnString = fnString.slice('async'.length).trim()
}
const isTraditionalFunction = fnString.startsWith('function')
let parsed
if (isTraditionalFunction) {
parsed = parseTraditionalFunction(fnString)
} else {
parsed = parseArrowFunction(fnString)
}
parsed['async'] = isAsync
return parsed
}
module.exports = parseFunction