1
1
import { isString } from '@vue/shared'
2
2
import { ForParseResult } from './transforms/vFor'
3
3
import {
4
- CREATE_VNODE ,
5
- WITH_DIRECTIVES ,
6
4
RENDER_SLOT ,
7
5
CREATE_SLOTS ,
8
6
RENDER_LIST ,
9
7
OPEN_BLOCK ,
10
8
CREATE_BLOCK ,
11
- FRAGMENT
9
+ FRAGMENT ,
10
+ CREATE_VNODE ,
11
+ WITH_DIRECTIVES
12
12
} from './runtimeHelpers'
13
13
import { PropsExpression } from './transforms/transformElement'
14
- import { ImportItem } from './transform'
14
+ import { ImportItem , TransformContext } from './transform'
15
15
16
16
// Vue template is a platform-agnostic superset of HTML (syntax only).
17
17
// More namespaces like SVG and MathML are declared by platform specific
@@ -38,12 +38,12 @@ export const enum NodeTypes {
38
38
FOR ,
39
39
TEXT_CALL ,
40
40
// codegen
41
+ VNODE_CALL ,
41
42
JS_CALL_EXPRESSION ,
42
43
JS_OBJECT_EXPRESSION ,
43
44
JS_PROPERTY ,
44
45
JS_ARRAY_EXPRESSION ,
45
46
JS_FUNCTION_EXPRESSION ,
46
- JS_SEQUENCE_EXPRESSION ,
47
47
JS_CONDITIONAL_EXPRESSION ,
48
48
JS_CACHE_EXPRESSION ,
49
49
@@ -123,43 +123,40 @@ export interface BaseElementNode extends Node {
123
123
isSelfClosing : boolean
124
124
props : Array < AttributeNode | DirectiveNode >
125
125
children : TemplateChildNode [ ]
126
- codegenNode :
127
- | CallExpression
128
- | SimpleExpressionNode
129
- | CacheExpression
130
- | SequenceExpression
131
- | undefined
132
126
}
133
127
134
128
export interface PlainElementNode extends BaseElementNode {
135
129
tagType : ElementTypes . ELEMENT
136
130
codegenNode :
137
- | ElementCodegenNode
131
+ | VNodeCall
138
132
| SimpleExpressionNode // when hoisted
139
133
| CacheExpression // when cached by v-once
140
- | SequenceExpression // when turned into a block
141
134
| undefined
142
135
ssrCodegenNode ?: TemplateLiteral
143
136
}
144
137
145
138
export interface ComponentNode extends BaseElementNode {
146
139
tagType : ElementTypes . COMPONENT
147
140
codegenNode :
148
- | ComponentCodegenNode
141
+ | VNodeCall
149
142
| CacheExpression // when cached by v-once
150
143
| undefined
151
144
ssrCodegenNode ?: CallExpression
152
145
}
153
146
154
147
export interface SlotOutletNode extends BaseElementNode {
155
148
tagType : ElementTypes . SLOT
156
- codegenNode : SlotOutletCodegenNode | undefined | CacheExpression // when cached by v-once
149
+ codegenNode :
150
+ | RenderSlotCall
151
+ | CacheExpression // when cached by v-once
152
+ | undefined
157
153
ssrCodegenNode ?: CallExpression
158
154
}
159
155
160
156
export interface TemplateNode extends BaseElementNode {
161
157
tagType : ElementTypes . TEMPLATE
162
158
// TemplateNode is a container type that always gets compiled away
159
+ codegenNode : undefined
163
160
}
164
161
165
162
export interface TextNode extends Node {
@@ -220,7 +217,7 @@ export interface CompoundExpressionNode extends Node {
220
217
export interface IfNode extends Node {
221
218
type : NodeTypes . IF
222
219
branches : IfBranchNode [ ]
223
- codegenNode ?: IfCodegenNode
220
+ codegenNode ?: IfConditionalExpression
224
221
}
225
222
226
223
export interface IfBranchNode extends Node {
@@ -246,20 +243,42 @@ export interface TextCallNode extends Node {
246
243
codegenNode : CallExpression | SimpleExpressionNode // when hoisted
247
244
}
248
245
246
+ export type TemplateTextChildNode =
247
+ | TextNode
248
+ | InterpolationNode
249
+ | CompoundExpressionNode
250
+
251
+ export interface VNodeCall extends Node {
252
+ type : NodeTypes . VNODE_CALL
253
+ tag : string | symbol | CallExpression
254
+ props : PropsExpression | undefined
255
+ children :
256
+ | TemplateChildNode [ ] // multiple children
257
+ | TemplateTextChildNode // single text child
258
+ | SlotsExpression // component slots
259
+ | ForRenderListExpression // v-for fragment call
260
+ | undefined
261
+ patchFlag : string | undefined
262
+ dynamicProps : string | undefined
263
+ directives : DirectiveArguments | undefined
264
+ isBlock : boolean
265
+ isForBlock : boolean
266
+ }
267
+
249
268
// JS Node Types ---------------------------------------------------------------
250
269
251
270
// We also include a number of JavaScript AST nodes for code generation.
252
271
// The AST is an intentionally minimal subset just to meet the exact needs of
253
272
// Vue render function generation.
254
273
255
274
export type JSChildNode =
275
+ | VNodeCall
256
276
| CallExpression
257
277
| ObjectExpression
258
278
| ArrayExpression
259
279
| ExpressionNode
260
280
| FunctionExpression
261
281
| ConditionalExpression
262
- | SequenceExpression
263
282
| CacheExpression
264
283
| AssignmentExpression
265
284
@@ -301,11 +320,6 @@ export interface FunctionExpression extends Node {
301
320
isSlot : boolean
302
321
}
303
322
304
- export interface SequenceExpression extends Node {
305
- type : NodeTypes . JS_SEQUENCE_EXPRESSION
306
- expressions : JSChildNode [ ]
307
- }
308
-
309
323
export interface ConditionalExpression extends Node {
310
324
type : NodeTypes . JS_CONDITIONAL_EXPRESSION
311
325
test : JSChildNode
@@ -360,58 +374,32 @@ export interface ReturnStatement extends Node {
360
374
361
375
// Codegen Node Types ----------------------------------------------------------
362
376
363
- // createVNode(...)
364
- export interface PlainElementCodegenNode extends CallExpression {
365
- callee : typeof CREATE_VNODE | typeof CREATE_BLOCK
366
- arguments : // tag, props, children, patchFlag, dynamicProps
367
- | [ string | symbol ]
368
- | [ string | symbol , PropsExpression ]
369
- | [ string | symbol , 'null' | PropsExpression , TemplateChildNode [ ] ]
370
- | [
371
- string | symbol ,
372
- 'null' | PropsExpression ,
373
- 'null' | TemplateChildNode [ ] ,
374
- string
375
- ]
376
- | [
377
- string | symbol ,
378
- 'null' | PropsExpression ,
379
- 'null' | TemplateChildNode [ ] ,
380
- string ,
381
- string
382
- ]
377
+ export interface DirectiveArguments extends ArrayExpression {
378
+ elements : DirectiveArgumentNode [ ]
383
379
}
384
380
385
- export type ElementCodegenNode =
386
- | PlainElementCodegenNode
387
- | CodegenNodeWithDirective < PlainElementCodegenNode >
381
+ export interface DirectiveArgumentNode extends ArrayExpression {
382
+ elements : // dir, exp, arg, modifiers
383
+ | [ string ]
384
+ | [ string , ExpressionNode ]
385
+ | [ string , ExpressionNode , ExpressionNode ]
386
+ | [ string , ExpressionNode , ExpressionNode , ObjectExpression ]
387
+ }
388
388
389
- // createVNode(...)
390
- export interface PlainComponentCodegenNode extends CallExpression {
391
- callee : typeof CREATE_VNODE | typeof CREATE_BLOCK
392
- arguments : // Comp, props, slots, patchFlag, dynamicProps
393
- | [ string | symbol ]
394
- | [ string | symbol , PropsExpression ]
395
- | [ string | symbol , 'null' | PropsExpression , SlotsExpression ]
396
- | [
397
- string | symbol ,
398
- 'null' | PropsExpression ,
399
- 'null' | SlotsExpression ,
400
- string
401
- ]
389
+ // renderSlot(...)
390
+ export interface RenderSlotCall extends CallExpression {
391
+ callee : typeof RENDER_SLOT
392
+ arguments : // $slots, name, props, fallback
393
+ | [ string , string | ExpressionNode ]
394
+ | [ string , string | ExpressionNode , PropsExpression ]
402
395
| [
403
- string | symbol ,
404
- 'null' | PropsExpression ,
405
- 'null' | SlotsExpression ,
406
396
string ,
407
- string
397
+ string | ExpressionNode ,
398
+ PropsExpression | '{}' ,
399
+ TemplateChildNode [ ]
408
400
]
409
401
}
410
402
411
- export type ComponentCodegenNode =
412
- | PlainComponentCodegenNode
413
- | CodegenNodeWithDirective < PlainComponentCodegenNode >
414
-
415
403
export type SlotsExpression = SlotsObjectExpression | DynamicSlotsExpression
416
404
417
405
// { foo: () => [...] }
@@ -462,63 +450,20 @@ export interface DynamicSlotFnProperty extends Property {
462
450
value : SlotFunctionExpression
463
451
}
464
452
465
- // withDirectives(createVNode(...), [
466
- // [_directive_foo, someValue],
467
- // [_directive_bar, someValue, "arg", { mod: true }]
468
- // ])
469
- export interface CodegenNodeWithDirective < T extends CallExpression >
470
- extends CallExpression {
471
- callee : typeof WITH_DIRECTIVES
472
- arguments : [ T , DirectiveArguments ]
473
- }
474
-
475
- export interface DirectiveArguments extends ArrayExpression {
476
- elements : DirectiveArgumentNode [ ]
477
- }
478
-
479
- export interface DirectiveArgumentNode extends ArrayExpression {
480
- elements : // dir, exp, arg, modifiers
481
- | [ string ]
482
- | [ string , ExpressionNode ]
483
- | [ string , ExpressionNode , ExpressionNode ]
484
- | [ string , ExpressionNode , ExpressionNode , ObjectExpression ]
485
- }
486
-
487
- // renderSlot(...)
488
- export interface SlotOutletCodegenNode extends CallExpression {
489
- callee : typeof RENDER_SLOT
490
- arguments : // $slots, name, props, fallback
491
- | [ string , string | ExpressionNode ]
492
- | [ string , string | ExpressionNode , PropsExpression ]
493
- | [
494
- string ,
495
- string | ExpressionNode ,
496
- PropsExpression | '{}' ,
497
- TemplateChildNode [ ]
498
- ]
499
- }
500
-
501
- export type BlockCodegenNode =
502
- | ElementCodegenNode
503
- | ComponentCodegenNode
504
- | SlotOutletCodegenNode
505
-
506
- export interface IfCodegenNode extends SequenceExpression {
507
- expressions : [ OpenBlockExpression , IfConditionalExpression ]
508
- }
453
+ export type BlockCodegenNode = VNodeCall | RenderSlotCall
509
454
510
455
export interface IfConditionalExpression extends ConditionalExpression {
511
456
consequent : BlockCodegenNode
512
457
alternate : BlockCodegenNode | IfConditionalExpression
513
458
}
514
459
515
- export interface ForCodegenNode extends SequenceExpression {
516
- expressions : [ OpenBlockExpression , ForBlockCodegenNode ]
517
- }
518
-
519
- export interface ForBlockCodegenNode extends CallExpression {
520
- callee : typeof CREATE_BLOCK
521
- arguments : [ typeof FRAGMENT , 'null' , ForRenderListExpression , string ]
460
+ export interface ForCodegenNode extends VNodeCall {
461
+ isBlock : true
462
+ tag : typeof FRAGMENT
463
+ props : undefined
464
+ children : ForRenderListExpression
465
+ patchFlag : string
466
+ isForBlock : true
522
467
}
523
468
524
469
export interface ForRenderListExpression extends CallExpression {
@@ -530,11 +475,6 @@ export interface ForIteratorExpression extends FunctionExpression {
530
475
returns : BlockCodegenNode
531
476
}
532
477
533
- export interface OpenBlockExpression extends CallExpression {
534
- callee : typeof OPEN_BLOCK
535
- arguments : [ ]
536
- }
537
-
538
478
// AST Utilities ---------------------------------------------------------------
539
479
540
480
// Some expressions, e.g. sequence and conditional expressions, are never
@@ -565,6 +505,42 @@ export function createRoot(
565
505
}
566
506
}
567
507
508
+ export function createVNodeCall (
509
+ context : TransformContext ,
510
+ tag : VNodeCall [ 'tag' ] ,
511
+ props ?: VNodeCall [ 'props' ] ,
512
+ children ?: VNodeCall [ 'children' ] ,
513
+ patchFlag ?: VNodeCall [ 'patchFlag' ] ,
514
+ dynamicProps ?: VNodeCall [ 'dynamicProps' ] ,
515
+ directives ?: VNodeCall [ 'directives' ] ,
516
+ isBlock : VNodeCall [ 'isBlock' ] = false ,
517
+ isForBlock : VNodeCall [ 'isForBlock' ] = false ,
518
+ loc = locStub
519
+ ) : VNodeCall {
520
+ if ( isBlock ) {
521
+ context . helper ( OPEN_BLOCK )
522
+ context . helper ( CREATE_BLOCK )
523
+ } else {
524
+ context . helper ( CREATE_VNODE )
525
+ }
526
+ if ( directives ) {
527
+ context . helper ( WITH_DIRECTIVES )
528
+ }
529
+
530
+ return {
531
+ type : NodeTypes . VNODE_CALL ,
532
+ tag,
533
+ props,
534
+ children,
535
+ patchFlag,
536
+ dynamicProps,
537
+ directives,
538
+ isBlock,
539
+ isForBlock,
540
+ loc
541
+ }
542
+ }
543
+
568
544
export function createArrayExpression (
569
545
elements : ArrayExpression [ 'elements' ] ,
570
546
loc : SourceLocation = locStub
@@ -638,15 +614,9 @@ export function createCompoundExpression(
638
614
}
639
615
}
640
616
641
- type InferCodegenNodeType < T > = T extends
642
- | typeof CREATE_VNODE
643
- | typeof CREATE_BLOCK
644
- ? PlainElementCodegenNode | PlainComponentCodegenNode
645
- : T extends typeof WITH_DIRECTIVES
646
- ?
647
- | CodegenNodeWithDirective < PlainElementCodegenNode >
648
- | CodegenNodeWithDirective < PlainComponentCodegenNode >
649
- : T extends typeof RENDER_SLOT ? SlotOutletCodegenNode : CallExpression
617
+ type InferCodegenNodeType < T > = T extends typeof RENDER_SLOT
618
+ ? RenderSlotCall
619
+ : CallExpression
650
620
651
621
export function createCallExpression < T extends CallExpression [ 'callee' ] > (
652
622
callee : T ,
@@ -678,16 +648,6 @@ export function createFunctionExpression(
678
648
}
679
649
}
680
650
681
- export function createSequenceExpression (
682
- expressions : SequenceExpression [ 'expressions' ]
683
- ) : SequenceExpression {
684
- return {
685
- type : NodeTypes . JS_SEQUENCE_EXPRESSION ,
686
- expressions,
687
- loc : locStub
688
- }
689
- }
690
-
691
651
export function createConditionalExpression (
692
652
test : ConditionalExpression [ 'test' ] ,
693
653
consequent : ConditionalExpression [ 'consequent' ] ,
0 commit comments