refactor(compiler-sfc): simplify props destructure arguments

This commit is contained in:
Evan You 2023-04-11 14:37:57 +08:00
parent 5a529bbf23
commit 0232c00e11
2 changed files with 14 additions and 25 deletions

View File

@ -918,14 +918,7 @@ export function compileScript(
// 3 props destructure transform // 3 props destructure transform
if (ctx.propsDestructureDecl) { if (ctx.propsDestructureDecl) {
transformDestructuredProps( transformDestructuredProps(ctx, vueImportAliases)
scriptSetupAst,
ctx.s,
startOffset,
ctx.propsDestructuredBindings,
error,
vueImportAliases
)
} }
// 4. Apply reactivity transform // 4. Apply reactivity transform

View File

@ -5,7 +5,6 @@ import {
Program, Program,
VariableDeclaration VariableDeclaration
} from '@babel/types' } from '@babel/types'
import MagicString from 'magic-string'
import { walk } from 'estree-walker' import { walk } from 'estree-walker'
import { import {
extractIdentifiers, extractIdentifiers,
@ -16,8 +15,8 @@ import {
walkFunctionParams walkFunctionParams
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { genPropsAccessExp } from '@vue/shared' import { genPropsAccessExp } from '@vue/shared'
import { PropsDestructureBindings } from './defineProps'
import { isCallOf, unwrapTSNode } from './utils' import { isCallOf, unwrapTSNode } from './utils'
import { ScriptCompileContext } from './context'
/** /**
* true -> prop binding * true -> prop binding
@ -26,11 +25,7 @@ import { isCallOf, unwrapTSNode } from './utils'
type Scope = Record<string, boolean> type Scope = Record<string, boolean>
export function transformDestructuredProps( export function transformDestructuredProps(
ast: Program, ctx: ScriptCompileContext,
s: MagicString,
offset = 0,
knownProps: PropsDestructureBindings,
error: (msg: string, node: Node, end?: number) => never,
vueImportAliases: Record<string, string> vueImportAliases: Record<string, string>
) { ) {
const rootScope: Scope = {} const rootScope: Scope = {}
@ -40,8 +35,8 @@ export function transformDestructuredProps(
const parentStack: Node[] = [] const parentStack: Node[] = []
const propsLocalToPublicMap: Record<string, string> = Object.create(null) const propsLocalToPublicMap: Record<string, string> = Object.create(null)
for (const key in knownProps) { for (const key in ctx.propsDestructuredBindings) {
const { local } = knownProps[key] const { local } = ctx.propsDestructuredBindings[key]
rootScope[local] = true rootScope[local] = true
propsLocalToPublicMap[local] = key propsLocalToPublicMap[local] = key
} }
@ -60,7 +55,7 @@ export function transformDestructuredProps(
if (currentScope) { if (currentScope) {
currentScope[id.name] = false currentScope[id.name] = false
} else { } else {
error( ctx.error(
'registerBinding called without active scope, something is wrong.', 'registerBinding called without active scope, something is wrong.',
id id
) )
@ -121,7 +116,7 @@ export function transformDestructuredProps(
(parent.type === 'AssignmentExpression' && id === parent.left) || (parent.type === 'AssignmentExpression' && id === parent.left) ||
parent.type === 'UpdateExpression' parent.type === 'UpdateExpression'
) { ) {
error(`Cannot assign to destructured props as they are readonly.`, id) ctx.error(`Cannot assign to destructured props as they are readonly.`, id)
} }
if (isStaticProperty(parent) && parent.shorthand) { if (isStaticProperty(parent) && parent.shorthand) {
@ -132,16 +127,16 @@ export function transformDestructuredProps(
isInDestructureAssignment(parent, parentStack) isInDestructureAssignment(parent, parentStack)
) { ) {
// { prop } -> { prop: __props.prop } // { prop } -> { prop: __props.prop }
s.appendLeft( ctx.s.appendLeft(
id.end! + offset, id.end! + ctx.startOffset!,
`: ${genPropsAccessExp(propsLocalToPublicMap[id.name])}` `: ${genPropsAccessExp(propsLocalToPublicMap[id.name])}`
) )
} }
} else { } else {
// x --> __props.x // x --> __props.x
s.overwrite( ctx.s.overwrite(
id.start! + offset, id.start! + ctx.startOffset!,
id.end! + offset, id.end! + ctx.startOffset!,
genPropsAccessExp(propsLocalToPublicMap[id.name]) genPropsAccessExp(propsLocalToPublicMap[id.name])
) )
} }
@ -151,7 +146,7 @@ export function transformDestructuredProps(
if (isCallOf(node, alias)) { if (isCallOf(node, alias)) {
const arg = unwrapTSNode(node.arguments[0]) const arg = unwrapTSNode(node.arguments[0])
if (arg.type === 'Identifier' && currentScope[arg.name]) { if (arg.type === 'Identifier' && currentScope[arg.name]) {
error( ctx.error(
`"${arg.name}" is a destructured prop and should not be passed directly to ${method}(). ` + `"${arg.name}" is a destructured prop and should not be passed directly to ${method}(). ` +
`Pass a getter () => ${arg.name} instead.`, `Pass a getter () => ${arg.name} instead.`,
arg arg
@ -161,6 +156,7 @@ export function transformDestructuredProps(
} }
// check root scope first // check root scope first
const ast = ctx.scriptSetupAst!
walkScope(ast, true) walkScope(ast, true)
;(walk as any)(ast, { ;(walk as any)(ast, {
enter(node: Node, parent?: Node) { enter(node: Node, parent?: Node) {