Skip to content

Function expression containing any semicolon in event handler causes parsing errorΒ #14287

@auvred

Description

@auvred

Vue version

3.5.26

Link to minimal reproduction

https://play.vuejs.org/#eNp9kE9LAzEQxb9KmEsVSgpWPdRV/EMPelBRjwFZ0umamk1CMlkXlv3uJimtPUhPCe/95vFmBrhzjncRYQEVYet0TXgjDGOVMi4Suy3PtYB1NJKUNezklA1scjVhowA2S2w1OxiEKVCQ1qxVwzfBmpQ75DgB0rZOafQvLscEAQtWnOzVWtufp6KRjzjd6fIL5fc/+ib0WRPw6jGg71DA3qPaN0hbe/n+jH36783WrqJO9BHzDYPVMXfcYvfRrFLtA660fWyd9aRM8xGWPaEJu6Vy0UyOhReQjvtwZPW/unN+XuaEGdMVPzv0OTMdcM4v+NkljL9dnInL

Steps to reproduce

Any function expression with semicolon inside it:

<template>
  <input @input="function () { ';' }" />
</template>

What is expected?

No parsing errors.

What is actually happening?

(2:18) Error parsing JavaScript expression: Unexpected token (1:10)

When an event handler's source code string contains at least one semicolon (;), the handler is parsed as a statement. However, in JS, function declarations must have a name function DECL() {}. When the handler doesn't contain a semicolon, it's parsed as an expression; in that case a function expression may not have a name function () {}, so no parsing error is raised.

const hasMultipleStatements = exp.content.includes(`;`)

Workarounds:

  • Use an arrow functions @input="() => { ';' }"
  • Wrap the function in parens (enforcing it to be parsed as a function expression rather than a function declaration) @input="(function () { ';' })"

What if, instead of using a heuristic (exp.content.includes(';')), the Vue parser tried to parse the event handler as an expression first (by wrapping the handler code in parens), and then, if a parser error occurred, fell back to parsing it as statements?

System Info

Any additional comments?

Doing so will also probably fix #8854

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions