-
Notifications
You must be signed in to change notification settings - Fork 20
/
merge-literal-add.ts
42 lines (37 loc) · 1.42 KB
/
merge-literal-add.ts
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
import { Expression, Literal, Statement, Identifier, Block, SyntaxNode } from '../ast/renderer-ast-dfn'
import { L, isLiteral, isIdentifier, isBlock, isBinaryExpression, isExpressionStatement } from '../ast/renderer-ast-util'
import { walk } from '../ast/renderer-ast-walker'
type HTMLAddEqualLiteral = Statement & { value: { lhs: Identifier, op: '+=', rhs: Literal } }
export function mergeLiteralAdd (node: Expression | Statement): void {
for (const descendant of walk(node)) {
if (isBlock(descendant)) doMergeLiteralAdd(descendant)
}
}
/**
* 合并连续的 html += 字面量字符串
*/
function doMergeLiteralAdd (node: Block) {
let prev: HTMLAddEqualLiteral | null = null
const filteredBody = []
for (const child of node.body) {
if (isHTMLAddEqualLiteral(child)) {
if (prev !== null) {
prev.value.rhs = L(prev.value.rhs.value + child.value.rhs.value)
continue
}
prev = child
} else {
prev = null
}
filteredBody.push(child)
}
node.body = filteredBody
}
function isHTMLAddEqualLiteral (statement: SyntaxNode): statement is HTMLAddEqualLiteral {
if (!isExpressionStatement(statement)) return false
const expr = statement.value
return isBinaryExpression(expr) &&
isIdentifier(expr.lhs) && expr.lhs.name === 'html' &&
expr.op === '+=' &&
isLiteral(expr.rhs)
}