11import {
22 type SimpleExpressionNode ,
33 createSimpleExpression ,
4- isStaticNode ,
54 walkIdentifiers ,
65} from '@vue/compiler-dom'
76import { genBlockContent } from './block'
@@ -16,12 +15,7 @@ import {
1615 genCall ,
1716 genMulti ,
1817} from './utils'
19- import {
20- type Expression ,
21- type Identifier ,
22- type Node ,
23- isNodesEquivalent ,
24- } from '@babel/types'
18+ import type { Expression , Identifier , Node } from '@babel/types'
2519import { parseExpression } from '@babel/parser'
2620import { VaporVForFlags } from '../../../shared/src/vaporFlags'
2721import { walk } from 'estree-walker'
@@ -330,12 +324,12 @@ function matchPatterns(
330324
331325 render . effect = render . effect . filter ( effect => {
332326 if ( keyProp !== undefined ) {
333- const selector = matchSelectorPattern ( effect , keyProp . ast , idMap )
327+ const selector = matchSelectorPattern ( effect , keyProp . content , idMap )
334328 if ( selector ) {
335329 selectorPatterns . push ( selector )
336330 return false
337331 }
338- const keyOnly = matchKeyOnlyBindingPattern ( effect , keyProp . ast )
332+ const keyOnly = matchKeyOnlyBindingPattern ( effect , keyProp . content )
339333 if ( keyOnly ) {
340334 keyOnlyBindingPatterns . push ( keyOnly )
341335 return false
@@ -353,17 +347,17 @@ function matchPatterns(
353347
354348function matchKeyOnlyBindingPattern (
355349 effect : IREffect ,
356- keyAst : any ,
350+ key : string ,
357351) :
358352 | {
359353 effect : IREffect
360354 }
361355 | undefined {
362356 // TODO: expressions can be multiple?
363357 if ( effect . expressions . length === 1 ) {
364- const ast = effect . expressions [ 0 ] . ast
358+ const { ast, content } = effect . expressions [ 0 ]
365359 if ( typeof ast === 'object' && ast !== null ) {
366- if ( isKeyOnlyBinding ( ast , keyAst ) ) {
360+ if ( isKeyOnlyBinding ( ast , key , content ) ) {
367361 return { effect }
368362 }
369363 }
@@ -372,7 +366,7 @@ function matchKeyOnlyBindingPattern(
372366
373367function matchSelectorPattern (
374368 effect : IREffect ,
375- keyAst : any ,
369+ key : string ,
376370 idMap : Record < string , string | SimpleExpressionNode | null > ,
377371) :
378372 | {
@@ -382,7 +376,7 @@ function matchSelectorPattern(
382376 | undefined {
383377 // TODO: expressions can be multiple?
384378 if ( effect . expressions . length === 1 ) {
385- const ast = effect . expressions [ 0 ] . ast
379+ const { ast, content } = effect . expressions [ 0 ]
386380 if ( typeof ast === 'object' && ast ) {
387381 const matcheds : [ key : Expression , selector : Expression ] [ ] = [ ]
388382
@@ -400,10 +394,10 @@ function matchSelectorPattern(
400394 [ left , right ] ,
401395 [ right , left ] ,
402396 ] ) {
403- const aIsKey = isKeyOnlyBinding ( a , keyAst )
404- const bIsKey = isKeyOnlyBinding ( b , keyAst )
397+ const aIsKey = isKeyOnlyBinding ( a , key , content )
398+ const bIsKey = isKeyOnlyBinding ( b , key , content )
405399 const bVars = analyzeVariableScopes ( b , idMap )
406- if ( aIsKey && ! bIsKey && ! bVars . locals . length ) {
400+ if ( aIsKey && ! bIsKey && ! bVars . length ) {
407401 matcheds . push ( [ a , b ] )
408402 }
409403 }
@@ -416,18 +410,14 @@ function matchSelectorPattern(
416410 const content = effect . expressions [ 0 ] . content
417411
418412 let hasExtraId = false
419- const parentStackMap = new Map < Identifier , Node [ ] > ( )
420- const parentStack : Node [ ] = [ ]
421413 walkIdentifiers (
422414 ast ,
423415 id => {
424416 if ( id . start !== key . start && id . start !== selector . start ) {
425417 hasExtraId = true
426418 }
427- parentStackMap . set ( id , parentStack . slice ( ) )
428419 } ,
429420 false ,
430- parentStack ,
431421 )
432422
433423 if ( ! hasExtraId ) {
@@ -448,62 +438,22 @@ function matchSelectorPattern(
448438 }
449439 }
450440 }
451-
452- const content = effect . expressions [ 0 ] . content
453- if (
454- typeof ast === 'object' &&
455- ast &&
456- ast . type === 'ConditionalExpression' &&
457- ast . test . type === 'BinaryExpression' &&
458- ast . test . operator === '===' &&
459- ast . test . left . type !== 'PrivateName' &&
460- isStaticNode ( ast . consequent ) &&
461- isStaticNode ( ast . alternate )
462- ) {
463- const left = ast . test . left
464- const right = ast . test . right
465- for ( const [ a , b ] of [
466- [ left , right ] ,
467- [ right , left ] ,
468- ] ) {
469- const aIsKey = isKeyOnlyBinding ( a , keyAst )
470- const bIsKey = isKeyOnlyBinding ( b , keyAst )
471- const bVars = analyzeVariableScopes ( b , idMap )
472- if ( aIsKey && ! bIsKey && ! bVars . locals . length ) {
473- return {
474- effect,
475- // @ts -expect-error
476- selector : {
477- content : content . slice ( b . start ! - 1 , b . end ! - 1 ) ,
478- ast : b ,
479- loc : b . loc as any ,
480- isStatic : false ,
481- } ,
482- }
483- }
484- }
485- }
486441 }
487442}
488443
489444function analyzeVariableScopes (
490445 ast : Node ,
491446 idMap : Record < string , string | SimpleExpressionNode | null > ,
492447) {
493- let globals : string [ ] = [ ]
494448 let locals : string [ ] = [ ]
495449
496450 const ids : Identifier [ ] = [ ]
497- const parentStackMap = new Map < Identifier , Node [ ] > ( )
498- const parentStack : Node [ ] = [ ]
499451 walkIdentifiers (
500452 ast ,
501453 id => {
502454 ids . push ( id )
503- parentStackMap . set ( id , parentStack . slice ( ) )
504455 } ,
505456 false ,
506- parentStack ,
507457 )
508458
509459 for ( const id of ids ) {
@@ -512,19 +462,17 @@ function analyzeVariableScopes(
512462 }
513463 if ( idMap [ id . name ] ) {
514464 locals . push ( id . name )
515- } else {
516- globals . push ( id . name )
517465 }
518466 }
519467
520- return { globals , locals }
468+ return locals
521469}
522470
523- function isKeyOnlyBinding ( expr : Node , keyAst : any ) {
471+ function isKeyOnlyBinding ( expr : Node , key : string , source : string ) {
524472 let only = true
525473 walk ( expr , {
526474 enter ( node ) {
527- if ( isNodesEquivalent ( node , keyAst ) ) {
475+ if ( source . slice ( node . start ! - 1 , node . end ! - 1 ) === key ) {
528476 this . skip ( )
529477 return
530478 }
0 commit comments