@@ -14,12 +14,12 @@ import {
14
14
import { TransformContext } from '../transform'
15
15
import { PatchFlags , isString , isSymbol } from '@vue/shared'
16
16
import { isSlotOutlet } from '../utils'
17
+ import { CREATE_VNODE } from '../runtimeHelpers'
17
18
18
19
export function hoistStatic ( root : RootNode , context : TransformContext ) {
19
20
walk (
20
21
root ,
21
22
context ,
22
- new Map ( ) ,
23
23
// Root node is unfortunately non-hoistable due to potential parent
24
24
// fallthrough attributes.
25
25
isSingleElementRoot ( root , root . children [ 0 ] )
@@ -41,7 +41,6 @@ export function isSingleElementRoot(
41
41
function walk (
42
42
node : ParentNode ,
43
43
context : TransformContext ,
44
- resultCache : Map < TemplateChildNode , ConstantTypes > ,
45
44
doNotHoistNode : boolean = false
46
45
) {
47
46
let hasHoistedNode = false
@@ -65,7 +64,7 @@ function walk(
65
64
) {
66
65
const constantType = doNotHoistNode
67
66
? ConstantTypes . NOT_CONSTANT
68
- : getConstantType ( child , resultCache )
67
+ : getConstantType ( child , context )
69
68
if ( constantType > ConstantTypes . NOT_CONSTANT ) {
70
69
if ( constantType < ConstantTypes . CAN_STRINGIFY ) {
71
70
canStringify = false
@@ -87,7 +86,7 @@ function walk(
87
86
( ! flag ||
88
87
flag === PatchFlags . NEED_PATCH ||
89
88
flag === PatchFlags . TEXT ) &&
90
- getGeneratedPropsConstantType ( child , resultCache ) >=
89
+ getGeneratedPropsConstantType ( child , context ) >=
91
90
ConstantTypes . CAN_HOIST
92
91
) {
93
92
const props = getNodeProps ( child )
@@ -98,7 +97,7 @@ function walk(
98
97
}
99
98
}
100
99
} else if ( child . type === NodeTypes . TEXT_CALL ) {
101
- const contentType = getConstantType ( child . content , resultCache )
100
+ const contentType = getConstantType ( child . content , context )
102
101
if ( contentType > 0 ) {
103
102
if ( contentType < ConstantTypes . CAN_STRINGIFY ) {
104
103
canStringify = false
@@ -112,17 +111,16 @@ function walk(
112
111
113
112
// walk further
114
113
if ( child . type === NodeTypes . ELEMENT ) {
115
- walk ( child , context , resultCache )
114
+ walk ( child , context )
116
115
} else if ( child . type === NodeTypes . FOR ) {
117
116
// Do not hoist v-for single child because it has to be a block
118
- walk ( child , context , resultCache , child . children . length === 1 )
117
+ walk ( child , context , child . children . length === 1 )
119
118
} else if ( child . type === NodeTypes . IF ) {
120
119
for ( let i = 0 ; i < child . branches . length ; i ++ ) {
121
120
// Do not hoist v-if single child because it has to be a block
122
121
walk (
123
122
child . branches [ i ] ,
124
123
context ,
125
- resultCache ,
126
124
child . branches [ i ] . children . length === 1
127
125
)
128
126
}
@@ -136,14 +134,15 @@ function walk(
136
134
137
135
export function getConstantType (
138
136
node : TemplateChildNode | SimpleExpressionNode ,
139
- resultCache : Map < TemplateChildNode , ConstantTypes > = new Map ( )
137
+ context : TransformContext
140
138
) : ConstantTypes {
139
+ const { constantCache } = context
141
140
switch ( node . type ) {
142
141
case NodeTypes . ELEMENT :
143
142
if ( node . tagType !== ElementTypes . ELEMENT ) {
144
143
return ConstantTypes . NOT_CONSTANT
145
144
}
146
- const cached = resultCache . get ( node )
145
+ const cached = constantCache . get ( node )
147
146
if ( cached !== undefined ) {
148
147
return cached
149
148
}
@@ -161,12 +160,9 @@ export function getConstantType(
161
160
// non-hoistable expressions that refers to scope variables, e.g. compiler
162
161
// injected keys or cached event handlers. Therefore we need to always
163
162
// check the codegenNode's props to be sure.
164
- const generatedPropsType = getGeneratedPropsConstantType (
165
- node ,
166
- resultCache
167
- )
163
+ const generatedPropsType = getGeneratedPropsConstantType ( node , context )
168
164
if ( generatedPropsType === ConstantTypes . NOT_CONSTANT ) {
169
- resultCache . set ( node , ConstantTypes . NOT_CONSTANT )
165
+ constantCache . set ( node , ConstantTypes . NOT_CONSTANT )
170
166
return ConstantTypes . NOT_CONSTANT
171
167
}
172
168
if ( generatedPropsType < returnType ) {
@@ -175,9 +171,9 @@ export function getConstantType(
175
171
176
172
// 2. its children.
177
173
for ( let i = 0 ; i < node . children . length ; i ++ ) {
178
- const childType = getConstantType ( node . children [ i ] , resultCache )
174
+ const childType = getConstantType ( node . children [ i ] , context )
179
175
if ( childType === ConstantTypes . NOT_CONSTANT ) {
180
- resultCache . set ( node , ConstantTypes . NOT_CONSTANT )
176
+ constantCache . set ( node , ConstantTypes . NOT_CONSTANT )
181
177
return ConstantTypes . NOT_CONSTANT
182
178
}
183
179
if ( childType < returnType ) {
@@ -193,9 +189,9 @@ export function getConstantType(
193
189
for ( let i = 0 ; i < node . props . length ; i ++ ) {
194
190
const p = node . props [ i ]
195
191
if ( p . type === NodeTypes . DIRECTIVE && p . name === 'bind' && p . exp ) {
196
- const expType = getConstantType ( p . exp , resultCache )
192
+ const expType = getConstantType ( p . exp , context )
197
193
if ( expType === ConstantTypes . NOT_CONSTANT ) {
198
- resultCache . set ( node , ConstantTypes . NOT_CONSTANT )
194
+ constantCache . set ( node , ConstantTypes . NOT_CONSTANT )
199
195
return ConstantTypes . NOT_CONSTANT
200
196
}
201
197
if ( expType < returnType ) {
@@ -210,12 +206,13 @@ export function getConstantType(
210
206
// nested updates.
211
207
if ( codegenNode . isBlock ) {
212
208
codegenNode . isBlock = false
209
+ context . helper ( CREATE_VNODE )
213
210
}
214
211
215
- resultCache . set ( node , returnType )
212
+ constantCache . set ( node , returnType )
216
213
return returnType
217
214
} else {
218
- resultCache . set ( node , ConstantTypes . NOT_CONSTANT )
215
+ constantCache . set ( node , ConstantTypes . NOT_CONSTANT )
219
216
return ConstantTypes . NOT_CONSTANT
220
217
}
221
218
case NodeTypes . TEXT :
@@ -227,7 +224,7 @@ export function getConstantType(
227
224
return ConstantTypes . NOT_CONSTANT
228
225
case NodeTypes . INTERPOLATION :
229
226
case NodeTypes . TEXT_CALL :
230
- return getConstantType ( node . content , resultCache )
227
+ return getConstantType ( node . content , context )
231
228
case NodeTypes . SIMPLE_EXPRESSION :
232
229
return node . constType
233
230
case NodeTypes . COMPOUND_EXPRESSION :
@@ -237,7 +234,7 @@ export function getConstantType(
237
234
if ( isString ( child ) || isSymbol ( child ) ) {
238
235
continue
239
236
}
240
- const childType = getConstantType ( child , resultCache )
237
+ const childType = getConstantType ( child , context )
241
238
if ( childType === ConstantTypes . NOT_CONSTANT ) {
242
239
return ConstantTypes . NOT_CONSTANT
243
240
} else if ( childType < returnType ) {
@@ -256,15 +253,15 @@ export function getConstantType(
256
253
257
254
function getGeneratedPropsConstantType (
258
255
node : PlainElementNode ,
259
- resultCache : Map < TemplateChildNode , ConstantTypes >
256
+ context : TransformContext
260
257
) : ConstantTypes {
261
258
let returnType = ConstantTypes . CAN_STRINGIFY
262
259
const props = getNodeProps ( node )
263
260
if ( props && props . type === NodeTypes . JS_OBJECT_EXPRESSION ) {
264
261
const { properties } = props
265
262
for ( let i = 0 ; i < properties . length ; i ++ ) {
266
263
const { key, value } = properties [ i ]
267
- const keyType = getConstantType ( key , resultCache )
264
+ const keyType = getConstantType ( key , context )
268
265
if ( keyType === ConstantTypes . NOT_CONSTANT ) {
269
266
return keyType
270
267
}
@@ -274,7 +271,7 @@ function getGeneratedPropsConstantType(
274
271
if ( value . type !== NodeTypes . SIMPLE_EXPRESSION ) {
275
272
return ConstantTypes . NOT_CONSTANT
276
273
}
277
- const valueType = getConstantType ( value , resultCache )
274
+ const valueType = getConstantType ( value , context )
278
275
if ( valueType === ConstantTypes . NOT_CONSTANT ) {
279
276
return valueType
280
277
}
0 commit comments