}
} else if (
node.type === 'ObjectProperty' &&
- parent!.type === 'ObjectPattern'
+ parent?.type === 'ObjectPattern'
) {
// mark property in destructure pattern
;(node as any).inPattern = true
</script>`).content,
)
})
+
+ test('defineModel() referencing local var', () => {
+ expect(() =>
+ compile(`<script setup>
+ let bar = 1
+ defineModel({
+ default: () => bar
+ })
+ </script>`),
+ ).toThrow(`cannot reference locally declared variables`)
+
+ // allow const
+ expect(() =>
+ compile(`<script setup>
+ const bar = 1
+ defineModel({
+ default: () => bar
+ })
+ </script>`),
+ ).not.toThrow(`cannot reference locally declared variables`)
+
+ // allow in get/set
+ expect(() =>
+ compile(`<script setup>
+ let bar = 1
+ defineModel({
+ get: () => bar,
+ set: () => bar
+ })
+ </script>`),
+ ).not.toThrow(`cannot reference locally declared variables`)
+ })
})
})
checkInvalidScopeReference(ctx.propsDestructureDecl, DEFINE_PROPS)
checkInvalidScopeReference(ctx.emitsRuntimeDecl, DEFINE_EMITS)
checkInvalidScopeReference(ctx.optionsRuntimeDecl, DEFINE_OPTIONS)
+ for (const { runtimeOptionNodes } of Object.values(ctx.modelDecls)) {
+ for (const node of runtimeOptionNodes) {
+ checkInvalidScopeReference(node, DEFINE_MODEL)
+ }
+ }
// 5. remove non-script content
if (script) {
type: TSType | undefined
options: string | undefined
identifier: string | undefined
+ runtimeOptionNodes: Node[]
}
export function processDefineModel(
let optionsString = options && ctx.getString(options)
let optionsRemoved = !options
+ const runtimeOptionNodes: Node[] = []
if (
options &&
// remove prop options from runtime options
removed++
ctx.s.remove(ctx.startOffset! + start, ctx.startOffset! + end)
+ // record prop options for invalid scope var reference check
+ runtimeOptionNodes.push(p)
}
}
if (removed === options.properties.length) {
ctx.modelDecls[modelName] = {
type,
options: optionsString,
+ runtimeOptionNodes,
identifier:
declId && declId.type === 'Identifier' ? declId.name : undefined,
}