-
-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathoperation.ts
95 lines (87 loc) · 2.99 KB
/
operation.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
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
import { type IREffect, IRNodeTypes, type OperationNode } from '../ir'
import type { CodegenContext } from '../generate'
import { genInsertNode, genPrependNode } from './dom'
import { genSetDynamicEvents, genSetEvent } from './event'
import { genFor } from './for'
import { genSetHtml } from './html'
import { genIf } from './if'
import { genSetModelValue } from './modelValue'
import { genDynamicProps, genSetProp } from './prop'
import { genDeclareOldRef, genSetTemplateRef } from './templateRef'
import { genCreateTextNode, genSetText } from './text'
import {
type CodeFragment,
INDENT_END,
INDENT_START,
NEWLINE,
buildCodeFragment,
} from './utils'
import { genCreateComponent } from './component'
export function genOperations(opers: OperationNode[], context: CodegenContext) {
const [frag, push] = buildCodeFragment()
for (const operation of opers) {
push(...genOperation(operation, context))
}
return frag
}
export function genOperation(
oper: OperationNode,
context: CodegenContext,
): CodeFragment[] {
switch (oper.type) {
case IRNodeTypes.SET_PROP:
return genSetProp(oper, context)
case IRNodeTypes.SET_DYNAMIC_PROPS:
return genDynamicProps(oper, context)
case IRNodeTypes.SET_TEXT:
return genSetText(oper, context)
case IRNodeTypes.SET_EVENT:
return genSetEvent(oper, context)
case IRNodeTypes.SET_DYNAMIC_EVENTS:
return genSetDynamicEvents(oper, context)
case IRNodeTypes.SET_HTML:
return genSetHtml(oper, context)
case IRNodeTypes.SET_TEMPLATE_REF:
return genSetTemplateRef(oper, context)
case IRNodeTypes.SET_MODEL_VALUE:
return genSetModelValue(oper, context)
case IRNodeTypes.CREATE_TEXT_NODE:
return genCreateTextNode(oper, context)
case IRNodeTypes.INSERT_NODE:
return genInsertNode(oper, context)
case IRNodeTypes.PREPEND_NODE:
return genPrependNode(oper, context)
case IRNodeTypes.IF:
return genIf(oper, context)
case IRNodeTypes.FOR:
return genFor(oper, context)
case IRNodeTypes.CREATE_COMPONENT_NODE:
return genCreateComponent(oper, context)
case IRNodeTypes.DECLARE_OLD_REF:
return genDeclareOldRef(oper)
}
return []
}
export function genEffects(effects: IREffect[], context: CodegenContext) {
const [frag, push] = buildCodeFragment()
for (const effect of effects) {
push(...genEffect(effect, context))
}
return frag
}
export function genEffect({ operations }: IREffect, context: CodegenContext) {
const { vaporHelper } = context
const [frag, push] = buildCodeFragment(
NEWLINE,
`${vaporHelper('renderEffect')}(() => `,
)
const [operationsExps, pushOps] = buildCodeFragment()
operations.forEach(op => pushOps(...genOperation(op, context)))
const newlineCount = operationsExps.filter(frag => frag === NEWLINE).length
if (newlineCount > 1) {
push('{', INDENT_START, ...operationsExps, INDENT_END, NEWLINE, '})')
} else {
push(...operationsExps.filter(frag => frag !== NEWLINE), ')')
}
return frag
}