Skip to content

Commit

Permalink
dx(defineModel): warn against reference of setup scope variables in d…
Browse files Browse the repository at this point in the history
…efineModel options

close #10093
  • Loading branch information
yyx990803 committed Jan 12, 2024
1 parent d35b877 commit c604791
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/compiler-core/src/babelUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function walkIdentifiers(
}
} else if (
node.type === 'ObjectProperty' &&
parent!.type === 'ObjectPattern'
parent?.type === 'ObjectPattern'
) {
// mark property in destructure pattern
;(node as any).inPattern = true
Expand Down
32 changes: 32 additions & 0 deletions packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,38 @@ describe('SFC compile <script setup>', () => {
</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`)
})
})
})

Expand Down
5 changes: 5 additions & 0 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,11 @@ export function compileScript(
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) {
Expand Down
5 changes: 5 additions & 0 deletions packages/compiler-sfc/src/script/defineModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface ModelDecl {
type: TSType | undefined
options: string | undefined
identifier: string | undefined
runtimeOptionNodes: Node[]
}

export function processDefineModel(
Expand Down Expand Up @@ -48,6 +49,7 @@ export function processDefineModel(

let optionsString = options && ctx.getString(options)
let optionsRemoved = !options
const runtimeOptionNodes: Node[] = []

if (
options &&
Expand Down Expand Up @@ -75,6 +77,8 @@ export function processDefineModel(
// 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) {
Expand All @@ -89,6 +93,7 @@ export function processDefineModel(
ctx.modelDecls[modelName] = {
type,
options: optionsString,
runtimeOptionNodes,
identifier:
declId && declId.type === 'Identifier' ? declId.name : undefined,
}
Expand Down

0 comments on commit c604791

Please sign in to comment.