11import { parseExpression } from '@babel/parser'
2- import {
3- isNodesEquivalent ,
4- type Expression ,
5- type Identifier ,
6- type Node ,
7- } from '@babel/types'
82import { extend , isGloballyAllowed } from '@vue/shared'
93import { walkAST , walkIdentifiers } from 'ast-kit'
104import {
@@ -23,6 +17,7 @@ import type { BlockIRNode, ForIRNode, IREffect } from '../ir'
2317import { genBlockContent } from './block'
2418import { genExpression } from './expression'
2519import { genOperation } from './operation'
20+ import type { Expression , Identifier , Node } from '@babel/types'
2621
2722/**
2823 * Flags to optimize vapor `createFor` runtime behavior, shared between the
@@ -114,6 +109,7 @@ export function genFor(
114109 render ,
115110 keyProp ,
116111 idMap ,
112+ context . ir . source ,
117113 )
118114 const selectorDeclarations : CodeFragment [ ] = [ ]
119115 const selectorSetup : CodeFragment [ ] = [ ]
@@ -331,6 +327,7 @@ function matchPatterns(
331327 render : BlockIRNode ,
332328 keyProp : SimpleExpressionNode | undefined ,
333329 idMap : Record < string , string | SimpleExpressionNode | null > ,
330+ source : string ,
334331) {
335332 const selectorPatterns : NonNullable <
336333 ReturnType < typeof matchSelectorPattern >
@@ -341,12 +338,21 @@ function matchPatterns(
341338
342339 render . effect = render . effect . filter ( ( effect ) => {
343340 if ( keyProp !== undefined ) {
344- const selector = matchSelectorPattern ( effect , keyProp . ast , idMap )
341+ const selector = matchSelectorPattern (
342+ effect ,
343+ keyProp . content ,
344+ idMap ,
345+ source ,
346+ )
345347 if ( selector ) {
346348 selectorPatterns . push ( selector )
347349 return false
348350 }
349- const keyOnly = matchKeyOnlyBindingPattern ( effect , keyProp . ast )
351+ const keyOnly = matchKeyOnlyBindingPattern (
352+ effect ,
353+ keyProp . content ,
354+ source ,
355+ )
350356 if ( keyOnly ) {
351357 keyOnlyBindingPatterns . push ( keyOnly )
352358 return false
@@ -364,7 +370,8 @@ function matchPatterns(
364370
365371function matchKeyOnlyBindingPattern (
366372 effect : IREffect ,
367- keyAst : any ,
373+ key : string ,
374+ source : string ,
368375) :
369376 | {
370377 effect : IREffect
@@ -376,7 +383,7 @@ function matchKeyOnlyBindingPattern(
376383 if (
377384 typeof ast === 'object' &&
378385 ast !== null &&
379- isKeyOnlyBinding ( ast , keyAst )
386+ isKeyOnlyBinding ( ast , key , source )
380387 ) {
381388 return { effect }
382389 }
@@ -385,8 +392,9 @@ function matchKeyOnlyBindingPattern(
385392
386393function matchSelectorPattern (
387394 effect : IREffect ,
388- keyAst : any ,
395+ key : string ,
389396 idMap : Record < string , string | SimpleExpressionNode | null > ,
397+ source : string ,
390398) :
391399 | {
392400 effect : IREffect
@@ -414,8 +422,8 @@ function matchSelectorPattern(
414422 [ left , right ] ,
415423 [ right , left ] ,
416424 ] ) {
417- const aIsKey = isKeyOnlyBinding ( a , keyAst )
418- const bIsKey = isKeyOnlyBinding ( b , keyAst )
425+ const aIsKey = isKeyOnlyBinding ( a , key , source )
426+ const bIsKey = isKeyOnlyBinding ( b , key , source )
419427 const bVars = analyzeVariableScopes ( b , idMap )
420428 if ( aIsKey && ! bIsKey && ! bVars . locals . length ) {
421429 matcheds . push ( [ a , b ] )
@@ -482,8 +490,8 @@ function matchSelectorPattern(
482490 [ left , right ] ,
483491 [ right , left ] ,
484492 ] ) {
485- const aIsKey = isKeyOnlyBinding ( a , keyAst )
486- const bIsKey = isKeyOnlyBinding ( b , keyAst )
493+ const aIsKey = isKeyOnlyBinding ( a , key , source )
494+ const bIsKey = isKeyOnlyBinding ( b , key , source )
487495 const bVars = analyzeVariableScopes ( b , idMap )
488496 if ( aIsKey && ! bIsKey && ! bVars . locals . length ) {
489497 return {
@@ -535,11 +543,11 @@ function analyzeVariableScopes(
535543 return { globals, locals }
536544}
537545
538- function isKeyOnlyBinding ( expr : Node , keyAst : any ) {
546+ function isKeyOnlyBinding ( expr : Node , key : string , source : string ) {
539547 let only = true
540548 walkAST ( expr , {
541549 enter ( node ) {
542- if ( isNodesEquivalent ( node , keyAst ) ) {
550+ if ( source . slice ( node . start ! , node . end ! ) === key ) {
543551 this . skip ( )
544552 return
545553 }
0 commit comments