]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
Merge branch 'main' into feat/reactiveity-transform-shorthands
authorAnthony Fu <anthonyfu117@hotmail.com>
Fri, 13 May 2022 08:19:09 +0000 (16:19 +0800)
committerAnthony Fu <anthonyfu117@hotmail.com>
Fri, 13 May 2022 08:19:09 +0000 (16:19 +0800)
1  2 
packages/compiler-sfc/src/compileScript.ts
packages/compiler-sfc/src/index.ts
packages/reactivity-transform/__tests__/reactivityTransform.spec.ts
packages/reactivity-transform/src/reactivityTransform.ts

index 62540dfe339921a8d1693d56d2e423db43ed7d18,0e1431c69452c51e5155d6b9e4927675185f6a98..22e1bb7018f859dcf0d306f5b39ff3a7239ecfe2
@@@ -11,15 -11,14 +11,14 @@@ import 
    isFunctionType,
    walkIdentifiers
  } from '@vue/compiler-dom'
- import { SFCDescriptor, SFCScriptBlock } from './parse'
- import { parse as _parse, ParserOptions, ParserPlugin } from '@babel/parser'
+ import { DEFAULT_FILENAME, SFCDescriptor, SFCScriptBlock } from './parse'
  import {
-   camelize,
-   capitalize,
-   generateCodeFrame,
-   isObject,
-   makeMap
- } from '@vue/shared'
+   parse as _parse,
+   parseExpression,
+   ParserOptions,
+   ParserPlugin
+ } from '@babel/parser'
 -import { camelize, capitalize, generateCodeFrame, makeMap } from '@vue/shared'
++import { camelize, capitalize, generateCodeFrame, isObject,makeMap } from '@vue/shared'
  import {
    Node,
    Declaration,
Simple merge
index 6f97367eb092237dd4b86a686b8affdc05845ebf,34d537d221becd5f8d24e16f8595c256a7f67a24..dccab00b88d9645072449587415aba7a2e40b097
@@@ -294,264 -273,233 +294,265 @@@ export function createReactivityTransfo
          }
        }
      }
 -  }
  
 -  function processRefDeclaration(
 -    method: string,
 -    id: VariableDeclarator['id'],
 -    call: CallExpression
 -  ) {
 -    excludedIds.add(call.callee as Identifier)
 -    if (method === convertSymbol) {
 -      // $
 -      // remove macro
 -      s.remove(call.callee.start! + offset, call.callee.end! + offset)
 -      if (id.type === 'Identifier') {
 -        // single variable
 -        registerRefBinding(id)
 -      } else if (id.type === 'ObjectPattern') {
 -        processRefObjectPattern(id, call)
 -      } else if (id.type === 'ArrayPattern') {
 -        processRefArrayPattern(id, call)
 -      }
 -    } else {
 -      // shorthands
 -      if (id.type === 'Identifier') {
 -        registerRefBinding(id)
 -        // replace call
 -        s.overwrite(
 -          call.start! + offset,
 -          call.start! + method.length + offset,
 -          helper(method.slice(1))
 -        )
 +    function processRefDeclaration(
 +      method: string,
 +      id: VariableDeclarator['id'],
 +      call: CallExpression
 +    ) {
 +      excludedIds.add(call.callee as Identifier)
 +      if (method === convertSymbol) {
 +        // $
 +        // remove macro
 +        s.remove(call.callee.start! + offset, call.callee.end! + offset)
 +        if (id.type === 'Identifier') {
 +          // single variable
 +          registerRefBinding(id)
 +        } else if (id.type === 'ObjectPattern') {
 +          processRefObjectPattern(id, call)
 +        } else if (id.type === 'ArrayPattern') {
 +          processRefArrayPattern(id, call)
 +        }
        } else {
 -        error(`${method}() cannot be used with destructure patterns.`, call)
 +        // shorthands
 +        const name = method.slice(1)
 +        const isBuiltIn = builtInShorthands.includes(name)
 +        if (id.type !== 'Identifier' && isBuiltIn) {
 +          error(`${method}() cannot be used with destructure patterns.`, call)
 +        } else {
 +          // replace call
 +          s.overwrite(
 +            call.start! + offset,
 +            call.start! + method.length + offset,
 +            isBuiltIn ? helper(name) : name
 +          )
 +          if (id.type === 'Identifier') {
 +            // single variable
 +            registerRefBinding(id)
 +          } else if (id.type === 'ObjectPattern') {
 +            processRefObjectPattern(id, call)
 +          } else if (id.type === 'ArrayPattern') {
 +            processRefArrayPattern(id, call)
 +          }
 +        }
        }
      }
 -  }
  
 -  function processRefObjectPattern(
 -    pattern: ObjectPattern,
 -    call: CallExpression,
 -    tempVar?: string,
 -    path: PathSegment[] = []
 -  ) {
 -    if (!tempVar) {
 -      tempVar = genTempVar()
 -      // const { x } = $(useFoo()) --> const __$temp_1 = useFoo()
 -      s.overwrite(pattern.start! + offset, pattern.end! + offset, tempVar)
 -    }
 +    function processRefObjectPattern(
 +      pattern: ObjectPattern,
 +      call: CallExpression,
 +      tempVar?: string,
 +      path: PathSegment[] = []
 +    ) {
 +      if (!tempVar) {
 +        tempVar = genTempVar()
 +        // const { x } = $(useFoo()) --> const __$temp_1 = useFoo()
 +        s.overwrite(pattern.start! + offset, pattern.end! + offset, tempVar)
 +      }
  
 -    for (const p of pattern.properties) {
 -      let nameId: Identifier | undefined
 -      let key: Expression | string | undefined
 -      let defaultValue: Expression | undefined
 -      if (p.type === 'ObjectProperty') {
 -        if (p.key.start! === p.value.start!) {
 -          // shorthand { foo }
 -          nameId = p.key as Identifier
 -          if (p.value.type === 'Identifier') {
 -            // avoid shorthand value identifier from being processed
 -            excludedIds.add(p.value)
 -          } else if (
 -            p.value.type === 'AssignmentPattern' &&
 -            p.value.left.type === 'Identifier'
 -          ) {
 -            // { foo = 1 }
 -            excludedIds.add(p.value.left)
 -            defaultValue = p.value.right
 -          }
 -        } else {
 -          key = p.computed ? p.key : (p.key as Identifier).name
 -          if (p.value.type === 'Identifier') {
 -            // { foo: bar }
 -            nameId = p.value
 -          } else if (p.value.type === 'ObjectPattern') {
 -            processRefObjectPattern(p.value, call, tempVar, [...path, key])
 -          } else if (p.value.type === 'ArrayPattern') {
 -            processRefArrayPattern(p.value, call, tempVar, [...path, key])
 -          } else if (p.value.type === 'AssignmentPattern') {
 -            if (p.value.left.type === 'Identifier') {
 -              // { foo: bar = 1 }
 -              nameId = p.value.left
 +      for (const p of pattern.properties) {
 +        let nameId: Identifier | undefined
 +        let key: Expression | string | undefined
 +        let defaultValue: Expression | undefined
 +        if (p.type === 'ObjectProperty') {
 +          if (p.key.start! === p.value.start!) {
 +            // shorthand { foo }
 +            nameId = p.key as Identifier
 +            if (p.value.type === 'Identifier') {
 +              // avoid shorthand value identifier from being processed
 +              excludedIds.add(p.value)
 +            } else if (
 +              p.value.type === 'AssignmentPattern' &&
 +              p.value.left.type === 'Identifier'
 +            ) {
 +              // { foo = 1 }
 +              excludedIds.add(p.value.left)
                defaultValue = p.value.right
 -            } else if (p.value.left.type === 'ObjectPattern') {
 -              processRefObjectPattern(p.value.left, call, tempVar, [
 -                ...path,
 -                [key, p.value.right]
 -              ])
 -            } else if (p.value.left.type === 'ArrayPattern') {
 -              processRefArrayPattern(p.value.left, call, tempVar, [
 -                ...path,
 -                [key, p.value.right]
 -              ])
 -            } else {
 -              // MemberExpression case is not possible here, ignore
 +            }
 +          } else {
 +            key = p.computed ? p.key : (p.key as Identifier).name
 +            if (p.value.type === 'Identifier') {
 +              // { foo: bar }
 +              nameId = p.value
 +            } else if (p.value.type === 'ObjectPattern') {
 +              processRefObjectPattern(p.value, call, tempVar, [...path, key])
 +            } else if (p.value.type === 'ArrayPattern') {
 +              processRefArrayPattern(p.value, call, tempVar, [...path, key])
 +            } else if (p.value.type === 'AssignmentPattern') {
 +              if (p.value.left.type === 'Identifier') {
 +                // { foo: bar = 1 }
 +                nameId = p.value.left
 +                defaultValue = p.value.right
 +              } else if (p.value.left.type === 'ObjectPattern') {
 +                processRefObjectPattern(p.value.left, call, tempVar, [
 +                  ...path,
 +                  [key, p.value.right]
 +                ])
 +              } else if (p.value.left.type === 'ArrayPattern') {
 +                processRefArrayPattern(p.value.left, call, tempVar, [
 +                  ...path,
 +                  [key, p.value.right]
 +                ])
 +              } else {
 +                // MemberExpression case is not possible here, ignore
 +              }
              }
            }
 +        } else {
 +          // rest element { ...foo }
 +          error(`reactivity destructure does not support rest elements.`, p)
 +        }
 +        if (nameId) {
 +          registerRefBinding(nameId)
 +          // inject toRef() after original replaced pattern
 +          const source = pathToString(tempVar, path)
 +          const keyStr = isString(key)
 +            ? `'${key}'`
 +            : key
 +            ? snip(key)
 +            : `'${nameId.name}'`
 +          const defaultStr = defaultValue ? `, ${snip(defaultValue)}` : ``
 +          s.appendLeft(
 +            call.end! + offset,
 +            `,\n  ${nameId.name} = ${helper(
 +              'toRef'
 +            )}(${source}, ${keyStr}${defaultStr})`
 +          )
          }
 -      } else {
 -        // rest element { ...foo }
 -        error(`reactivity destructure does not support rest elements.`, p)
 -      }
 -      if (nameId) {
 -        registerRefBinding(nameId)
 -        // inject toRef() after original replaced pattern
 -        const source = pathToString(tempVar, path)
 -        const keyStr = isString(key)
 -          ? `'${key}'`
 -          : key
 -          ? snip(key)
 -          : `'${nameId.name}'`
 -        const defaultStr = defaultValue ? `, ${snip(defaultValue)}` : ``
 -        s.appendLeft(
 -          call.end! + offset,
 -          `,\n  ${nameId.name} = ${helper(
 -            'toRef'
 -          )}(${source}, ${keyStr}${defaultStr})`
 -        )
        }
      }
 -  }
 -
 -  function processRefArrayPattern(
 -    pattern: ArrayPattern,
 -    call: CallExpression,
 -    tempVar?: string,
 -    path: PathSegment[] = []
 -  ) {
 -    if (!tempVar) {
 -      // const [x] = $(useFoo()) --> const __$temp_1 = useFoo()
 -      tempVar = genTempVar()
 -      s.overwrite(pattern.start! + offset, pattern.end! + offset, tempVar)
 -    }
  
 -    for (let i = 0; i < pattern.elements.length; i++) {
 -      const e = pattern.elements[i]
 -      if (!e) continue
 -      let nameId: Identifier | undefined
 -      let defaultValue: Expression | undefined
 -      if (e.type === 'Identifier') {
 -        // [a] --> [__a]
 -        nameId = e
 -      } else if (e.type === 'AssignmentPattern') {
 -        // [a = 1]
 -        nameId = e.left as Identifier
 -        defaultValue = e.right
 -      } else if (e.type === 'RestElement') {
 -        // [...a]
 -        error(`reactivity destructure does not support rest elements.`, e)
 -      } else if (e.type === 'ObjectPattern') {
 -        processRefObjectPattern(e, call, tempVar, [...path, i])
 -      } else if (e.type === 'ArrayPattern') {
 -        processRefArrayPattern(e, call, tempVar, [...path, i])
 +    function processRefArrayPattern(
 +      pattern: ArrayPattern,
 +      call: CallExpression,
 +      tempVar?: string,
 +      path: PathSegment[] = []
 +    ) {
 +      if (!tempVar) {
 +        // const [x] = $(useFoo()) --> const __$temp_1 = useFoo()
 +        tempVar = genTempVar()
 +        s.overwrite(pattern.start! + offset, pattern.end! + offset, tempVar)
        }
 -      if (nameId) {
 -        registerRefBinding(nameId)
 -        // inject toRef() after original replaced pattern
 -        const source = pathToString(tempVar, path)
 -        const defaultStr = defaultValue ? `, ${snip(defaultValue)}` : ``
 -        s.appendLeft(
 -          call.end! + offset,
 -          `,\n  ${nameId.name} = ${helper(
 -            'toRef'
 -          )}(${source}, ${i}${defaultStr})`
 -        )
 +
 +      for (let i = 0; i < pattern.elements.length; i++) {
 +        const e = pattern.elements[i]
 +        if (!e) continue
 +        let nameId: Identifier | undefined
 +        let defaultValue: Expression | undefined
 +        if (e.type === 'Identifier') {
 +          // [a] --> [__a]
 +          nameId = e
 +        } else if (e.type === 'AssignmentPattern') {
 +          // [a = 1]
 +          nameId = e.left as Identifier
 +          defaultValue = e.right
 +        } else if (e.type === 'RestElement') {
 +          // [...a]
 +          error(`reactivity destructure does not support rest elements.`, e)
 +        } else if (e.type === 'ObjectPattern') {
 +          processRefObjectPattern(e, call, tempVar, [...path, i])
 +        } else if (e.type === 'ArrayPattern') {
 +          processRefArrayPattern(e, call, tempVar, [...path, i])
 +        }
 +        if (nameId) {
 +          registerRefBinding(nameId)
 +          // inject toRef() after original replaced pattern
 +          const source = pathToString(tempVar, path)
 +          const defaultStr = defaultValue ? `, ${snip(defaultValue)}` : ``
 +          s.appendLeft(
 +            call.end! + offset,
 +            `,\n  ${nameId.name} = ${helper(
 +              'toRef'
 +            )}(${source}, ${i}${defaultStr})`
 +          )
 +        }
        }
      }
 -  }
  
 -  type PathSegmentAtom = Expression | string | number
 +    type PathSegmentAtom = Expression | string | number
  
 -  type PathSegment =
 -    | PathSegmentAtom
 -    | [PathSegmentAtom, Expression /* default value */]
 +    type PathSegment =
 +      | PathSegmentAtom
 +      | [PathSegmentAtom, Expression /* default value */]
  
 -  function pathToString(source: string, path: PathSegment[]): string {
 -    if (path.length) {
 -      for (const seg of path) {
 -        if (isArray(seg)) {
 -          source = `(${source}${segToString(seg[0])} || ${snip(seg[1])})`
 -        } else {
 -          source += segToString(seg)
 +    function pathToString(source: string, path: PathSegment[]): string {
 +      if (path.length) {
 +        for (const seg of path) {
 +          if (isArray(seg)) {
 +            source = `(${source}${segToString(seg[0])} || ${snip(seg[1])})`
 +          } else {
 +            source += segToString(seg)
 +          }
          }
        }
 +      return source
      }
 -    return source
 -  }
  
 -  function segToString(seg: PathSegmentAtom): string {
 -    if (typeof seg === 'number') {
 -      return `[${seg}]`
 -    } else if (typeof seg === 'string') {
 -      return `.${seg}`
 -    } else {
 -      return snip(seg)
 +    function segToString(seg: PathSegmentAtom): string {
 +      if (typeof seg === 'number') {
 +        return `[${seg}]`
 +      } else if (typeof seg === 'string') {
 +        return `.${seg}`
 +      } else {
 +        return snip(seg)
 +      }
      }
 -  }
  
 -  function rewriteId(
 -    scope: Scope,
 -    id: Identifier,
 -    parent: Node,
 -    parentStack: Node[]
 -  ): boolean {
 -    if (hasOwn(scope, id.name)) {
 -      const bindingType = scope[id.name]
 -      if (bindingType) {
 -        const isProp = bindingType === 'prop'
 -        if (isStaticProperty(parent) && parent.shorthand) {
 -          // let binding used in a property shorthand
 -          // skip for destructure patterns
 -          if (
 -            !(parent as any).inPattern ||
 -            isInDestructureAssignment(parent, parentStack)
 -          ) {
 +    function rewriteId(
 +      scope: Scope,
 +      id: Identifier,
 +      parent: Node,
 +      parentStack: Node[]
 +    ): boolean {
 +      if (hasOwn(scope, id.name)) {
 +        const bindingType = scope[id.name]
 +        if (bindingType) {
 +          const isProp = bindingType === 'prop'
 +          if (isStaticProperty(parent) && parent.shorthand) {
 +            // let binding used in a property shorthand
 +            // skip for destructure patterns
 +            if (
 +              !(parent as any).inPattern ||
 +              isInDestructureAssignment(parent, parentStack)
 +            ) {
 +              if (isProp) {
 +                if (escapeScope) {
 +                  // prop binding in $$()
 +                  // { prop } -> { prop: __prop_prop }
 +                  registerEscapedPropBinding(id)
 +                  s.appendLeft(
 +                    id.end! + offset,
 +                    `: __props_${propsLocalToPublicMap[id.name]}`
 +                  )
 +                } else {
-                   // { prop } -> { prop: __prop.prop }
++                  // { prop } -> { prop: __props.prop }
 +                  s.appendLeft(
 +                    id.end! + offset,
-                     `: __props.${propsLocalToPublicMap[id.name]}`
++                    `: ${genPropsAccessExp(propsLocalToPublicMap[id.name])}`
 +                  )
 +                }
 +              } else {
 +                // { foo } -> { foo: foo.value }
 +                s.appendLeft(id.end! + offset, `: ${id.name}.value`)
 +              }
 +            }
 +          } else {
              if (isProp) {
                if (escapeScope) {
-                 // x --> __props_x
+                 // prop binding in $$()
+                 // { prop } -> { prop: __props_prop }
                  registerEscapedPropBinding(id)
 -                s.appendLeft(
 +                s.overwrite(
 +                  id.start! + offset,
                    id.end! + offset,
 -                  `__props_${propsLocalToPublicMap[id.name]}`
 +                  `__props_${propsLocalToPublicMap[id.name]}`
                  )
                } else {
 -                // { prop } -> { prop: __props.prop }
 -                s.appendLeft(
 +                // x --> __props.x
 +                s.overwrite(
 +                  id.start! + offset,
                    id.end! + offset,
-                   `__props.${propsLocalToPublicMap[id.name]}`
 -                  `: ${genPropsAccessExp(propsLocalToPublicMap[id.name])}`
++                  genPropsAccessExp(propsLocalToPublicMap[id.name])
                  )
                }
              } else {