}
}
}
- }
- 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 {