@@ -23,7 +23,7 @@ import { parse, ParserPlugin } from '@babel/parser'
2323import { hasOwn , isArray , isString } from '@vue/shared'
2424
2525const TO_VAR_SYMBOL = '$'
26- const TO_REF_SYMBOL = '$$'
26+ const ESCAPE_SYMBOL = '$$'
2727const shorthands = [ 'ref' , 'computed' , 'shallowRef' , 'toRef' , 'customRef' ]
2828const transformCheckRE = / [ ^ \w ] \$ (?: \$ | r e f | c o m p u t e d | s h a l l o w R e f ) ? \s * ( \( | \< ) /
2929
@@ -420,30 +420,52 @@ export function transformAST(
420420 const isProp = bindingType === 'prop'
421421 if ( isStaticProperty ( parent ) && parent . shorthand ) {
422422 // let binding used in a property shorthand
423- // { foo } -> { foo: foo.value }
424- // { prop } -> { prop: __prop.prop }
425423 // skip for destructure patterns
426424 if (
427425 ! ( parent as any ) . inPattern ||
428426 isInDestructureAssignment ( parent , parentStack )
429427 ) {
430428 if ( isProp ) {
431- s . appendLeft (
432- id . end ! + offset ,
433- `: __props.${ propsLocalToPublicMap [ id . name ] } `
434- )
429+ if ( escapeScope ) {
430+ // prop binding in $$()
431+ // { prop } -> { prop: __prop_prop }
432+ registerEscapedPropBinding ( id )
433+ s . appendLeft (
434+ id . end ! + offset ,
435+ `: __props_${ propsLocalToPublicMap [ id . name ] } `
436+ )
437+ } else {
438+ // { prop } -> { prop: __prop.prop }
439+ s . appendLeft (
440+ id . end ! + offset ,
441+ `: __props.${ propsLocalToPublicMap [ id . name ] } `
442+ )
443+ }
435444 } else {
445+ // { foo } -> { foo: foo.value }
436446 s . appendLeft ( id . end ! + offset , `: ${ id . name } .value` )
437447 }
438448 }
439449 } else {
440450 if ( isProp ) {
441- s . overwrite (
442- id . start ! + offset ,
443- id . end ! + offset ,
444- `__props.${ propsLocalToPublicMap [ id . name ] } `
445- )
451+ if ( escapeScope ) {
452+ // x --> __props_x
453+ registerEscapedPropBinding ( id )
454+ s . overwrite (
455+ id . start ! + offset ,
456+ id . end ! + offset ,
457+ `__props_${ propsLocalToPublicMap [ id . name ] } `
458+ )
459+ } else {
460+ // x --> __props.x
461+ s . overwrite (
462+ id . start ! + offset ,
463+ id . end ! + offset ,
464+ `__props.${ propsLocalToPublicMap [ id . name ] } `
465+ )
466+ }
446467 } else {
468+ // x --> x.value
447469 s . appendLeft ( id . end ! + offset , '.value' )
448470 }
449471 }
@@ -453,8 +475,25 @@ export function transformAST(
453475 return false
454476 }
455477
478+ const propBindingRefs : Record < string , true > = { }
479+ function registerEscapedPropBinding ( id : Identifier ) {
480+ if ( ! propBindingRefs . hasOwnProperty ( id . name ) ) {
481+ propBindingRefs [ id . name ] = true
482+ const publicKey = propsLocalToPublicMap [ id . name ]
483+ s . prependRight (
484+ offset ,
485+ `const __props_${ publicKey } = ${ helper (
486+ `toRef`
487+ ) } (__props, '${ publicKey } ')\n`
488+ )
489+ }
490+ }
491+
456492 // check root scope first
457493 walkScope ( ast , true )
494+
495+ // inside $$()
496+ let escapeScope : CallExpression | undefined
458497 ; ( walk as any ) ( ast , {
459498 enter ( node : Node , parent ?: Node ) {
460499 parent && parentStack . push ( parent )
@@ -488,6 +527,8 @@ export function transformAST(
488527
489528 if (
490529 node . type === 'Identifier' &&
530+ // if inside $$(), skip unless this is a destructured prop binding
531+ ! ( escapeScope && rootScope [ node . name ] !== 'prop' ) &&
491532 isReferencedIdentifier ( node , parent ! , parentStack ) &&
492533 ! excludedIds . has ( node )
493534 ) {
@@ -512,9 +553,9 @@ export function transformAST(
512553 )
513554 }
514555
515- if ( callee === TO_REF_SYMBOL ) {
556+ if ( callee === ESCAPE_SYMBOL ) {
516557 s . remove ( node . callee . start ! + offset , node . callee . end ! + offset )
517- return this . skip ( )
558+ escapeScope = node
518559 }
519560
520561 // TODO remove when out of experimental
@@ -543,6 +584,9 @@ export function transformAST(
543584 scopeStack . pop ( )
544585 currentScope = scopeStack [ scopeStack . length - 1 ] || null
545586 }
587+ if ( node === escapeScope ) {
588+ escapeScope = undefined
589+ }
546590 }
547591 } )
548592
0 commit comments