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