Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compiler-sfc: invalid declaration while using multiple variables with defineEmits and defineProps #7422

Closed
mnixry opened this issue Dec 28, 2022 · 1 comment · Fixed by #7423
Labels
has PR A pull request has already been submitted to solve the issue 🔩 p2-edge-case scope: compiler

Comments

@mnixry
Copy link

mnixry commented Dec 28, 2022

Vue version

3.2.45

Link to minimal reproduction

https://sfc.vuejs.org/#eNqlkMFuwjAQRH/F8gWQcFykigMEpB567wf4EpINuIrt1doJQlH+vesArdQe69u8WXvGO8o3xGLoQe5kGWuymESE1OPReOswUBKjIGjFJFoKTix4dGF8HXxMwsWzOGR3udo/GVLAyLSB1nr4yGq5Whsv5gPOph/3PSt2hdan50TF7ksm9ZOcMtkzaYwv9b0jt2ORwGFXJWAlRHnZHMdx7jRNpWY1U+uxT2JQLjTQHYxk30i2Sv19W67l/avKVVh8xuB5GWO+bR5GNHInZpIZryBrIy8pYdxxMcAu3BQSDBauavu63SjFUyq2teKM25lC75vCQ+pseysqRM12Qb1P1kEB0akThWsE4ngjH+uakzTDAUgR+AYI6P/Jvx78k57DJ+MnOX0Byzq2CA==

Steps to reproduce

Define a set of variable with multiple declarations in SFC with <script setup>:

const props = defineProps(),
      emits = defineEmits(), //b
      a = 0, //c
      b = 0; //d

It will lead to wrong transpile result:

const , //b
      a = 0, //c
      b = 0; //d

What is expected?

It should be compiled into:

const a = 0, //c
    b = 0; //d

Without any syntax error.

What is actually happening?

This bug is introduced in #6778, compiler-sfc fixed a bug #6757, which is also related to multiple variable declaration.
Can reproduce in #6778's sfc-playgroound preview, but works perfectly in #6777 and older version.

Briefly, it occurs while we're processing a macro token with define*, with the following steps:

if (i === 0) {
// first one, locate the start of the next
end = node.declarations[i + 1].start! + startOffset
} else {
// not first one, locate the end of the prev
start = node.declarations[i - 1].end! + startOffset
}

  • Get the actual position of the declaration of macros
  • Remove the variable declaration of macros, based on the position, it has different behavior in multiple declarations:
    • If the variable declaration is the first one, remove all the characters between the begin of current declaration and begin of next declaration
    • If the variable declaration is not the first one, remove all the characters between the end of previous declaration and end of current declaration

We can notice that, if the declaration is the last macro but not the last variable declaration, it will keep the redundant part of the declaration, which leads to the final syntax error.

To fix this issue, we can make the characters between the beginning of current and begin of next (if have) are unconditionally removed:

if (i < total - 1) {
    // not the last one, locate the start of the next
    end = node.declarations[i + 1].start + startOffset
}
if (i != 0) {
	// not first one, locate the end of the prev
	start = node.declarations[i - 1].end + startOffset
}

I will submit a PR trying to fix that if you like this solution.

System Info

No response

Any additional comments?

No response

@edison1105
Copy link
Member

@mnixry PR welcome.

mnixry added a commit to mnixry/nonebot-plugin-gocqhttp that referenced this issue Dec 30, 2022
sxzz added a commit that referenced this issue Jan 26, 2023
sxzz added a commit that referenced this issue Feb 4, 2023
@haoqunjiang haoqunjiang added has PR A pull request has already been submitted to solve the issue scope: compiler labels Mar 20, 2023
sxzz added a commit that referenced this issue Mar 27, 2023
sxzz added a commit that referenced this issue Mar 28, 2023
yyx990803 pushed a commit that referenced this issue Mar 28, 2023
IAmSSH pushed a commit to IAmSSH/core that referenced this issue May 14, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Sep 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
has PR A pull request has already been submitted to solve the issue 🔩 p2-edge-case scope: compiler
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants