-
-
Notifications
You must be signed in to change notification settings - Fork 209
/
Copy pathoptimize.js
98 lines (89 loc) · 3.04 KB
/
optimize.js
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
90
91
92
93
94
95
96
97
98
'use strict'
const returnFnRE = /^\s+return ([.a-zA-Z0-9]+)\(\w+\)$/
const fnRE = /^\s*function\s+/
const fnNameRE = /^\s+function ([a-zA-Z0-9_]+) \(input\) {$/
const jsonConcatRE = /^\s*json\s*\+=/
const letJsonRE = /^\s*let json =/
const returnJsonRE = /^\s*return json\s*$/
const returnEmptyStringRE = /^\s*return '' \+/
const closingCurlyBracketRE = /^\s*}\s*$/
/**
* @param {Array<string>} code
* @returns {Array<string>}
*/
function optimize (raw) {
let code = raw.split('\n')
code = optimizeJsonConcat(code)
code = optimizeLetJson(code)
code = optimizeDirectReturn(code)
code = optimizeReturnEmptyString(code)
code = optimizeDirectAssignWrappedFns(code)
return code.join('\n')
}
function optimizeJsonConcat (code) {
const optimizedJsonConcat = []
for (let i = 0; i < code.length; i++) {
if (i > 0 && jsonConcatRE.test(code[i]) && jsonConcatRE.test(code[i - 1])) {
const lastEntry = optimizedJsonConcat.pop()
const mergedEntry = lastEntry + ' +' + code[i].substring(code[i].indexOf('json +=') + 7)
optimizedJsonConcat.push(mergedEntry)
} else {
optimizedJsonConcat.push(code[i])
}
}
return optimizedJsonConcat
}
function optimizeLetJson (code) {
const optimizedLetJsonCode = []
for (let i = 0; i < code.length; i++) {
if (i > 0 && jsonConcatRE.test(code[i]) && letJsonRE.test(code[i - 1])) {
const mergedEntry = code[i - 1] + ' +' + code[i].substring(code[i].indexOf('json +=') + 7)
optimizedLetJsonCode.pop() // Remove the previous entry
optimizedLetJsonCode.push(mergedEntry)
} else {
optimizedLetJsonCode.push(code[i])
}
}
return optimizedLetJsonCode
}
function optimizeDirectReturn (code) {
const optimizedDirectReturnCode = []
for (let i = 0; i < code.length; i++) {
if (i > 0 && returnJsonRE.test(code[i]) && letJsonRE.test(code[i - 1])) {
const mergedEntry = code[i].slice(0, code[i].indexOf('return') + 6) + code[i - 1].substring(code[i - 1].indexOf('let json =') + 10)
optimizedDirectReturnCode.pop() // Remove the previous entry
optimizedDirectReturnCode.push(mergedEntry)
} else {
optimizedDirectReturnCode.push(code[i])
}
}
return optimizedDirectReturnCode
}
function optimizeReturnEmptyString (code) {
for (let i = 0; i < code.length; i++) {
if (returnEmptyStringRE.test(code[i])) {
code[i] = code[i].replace('return \'\' +', 'return')
}
}
return code
}
function optimizeDirectAssignWrappedFns (code) {
const optimizedDirectAssignFns = []
for (let i = 0; i < code.length; i++) {
if (
fnRE.test(code[i]) &&
returnFnRE.test(code[i + 1]) &&
closingCurlyBracketRE.test(code[i + 2])
) {
const serializerFnName = code[i + 1].match(returnFnRE)[1]
const fnName = code[i].match(fnNameRE)[1]
const whitespace = code[i].slice(0, code[i].indexOf('f'))
optimizedDirectAssignFns[i] = `${whitespace}const ${fnName} = ${serializerFnName}`
i += 2
} else {
optimizedDirectAssignFns.push(code[i])
}
}
return optimizedDirectAssignFns
}
module.exports = optimize