-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
fix: wrong function hoisting when mixing event-handling syntaxes #11295
fix: wrong function hoisting when mixing event-handling syntaxes #11295
Conversation
🦋 Changeset detectedLatest commit: e372742 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Thank you, but as I said on the issue (and it seems Rich agrees) I personally would prefer this to be a compiler error instead ("cannot mix old and new event handling syntax in the same component. Migrate towards event attributes completely" or sth like that). |
@dummdidumm We can traverse the AST to detect the usage of the old event system. If so, we can flag it within the analysis object. During a second traversal of the tree, if we encounter occurrences of the new event handling, we can raise a compile error. Something like that: walk(/** @type {import('#compiler').SvelteNode} */ (ast), state, {
OnDirective(_, context) {
context.state.analysis.uses_directives = true;
context.next();
}
}); |
I'm pretty sure we can do it in one go using two variables on the analysis object: |
a36f530
to
9352c54
Compare
@dummdidumm, I implemented the error for detecting both occurrences of event-handling syntaxes applying your suggestions. However, I encountered an issue: numerous tests utilize both syntaxes. To prevent potential side effects, given the uncertainty of their usage, I opted for a warning instead. It alerts users about the presence of both syntaxes. Additionally, I kept the previous fix allowing their combined use within the same component. Could you please provide any suggestions or feedback on this approach? |
Which tests are those? I'm ok with adjusting them. A warning doesn't buy us much because we already warn on all event directives as soon as someone is entering runes mode. |
Here are the ones I found: |
dd061f8
to
0d22f48
Compare
@dummdidumm, I fixed the tests as follows: for tests using both old and new event handling syntaxes in regular elements, I replaced these elements with components to account for scenarios where the components may not be under the author's control. Maintaining the original logic of the tests. Additionally, I added more tests to confirm that warnings and the new compiler errors trigger as expected. |
0d22f48
to
5b08b50
Compare
… old and new event-handling syntaxes
5b08b50
to
f9acfe6
Compare
@dummdidumm what if user wants to use |
This case is already handled correctly today and shouldn't be a compiler error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Hello, Not sure if I should post this here or create a new issue, but I think there is a major flaw about this. Imagine the following component using Svelte 4 syntax : // Button.svelte
<button on:click><slot/></button> Currently, the migration tool will generate this code for Svelte 5 : // Button.svelte
<script>
let { children, onclick } = $props();
</script>
<button {onclick}>{@render children()}</button> Fine. This is correct... but it implies that all other components that use it will also need to be updated to the new syntax. // App.svelte
<script>
import Button from './Button.svelte';
</script>
<Button on:click={()=>alert("clicked")} /> Demo here : REPL This is particularly problematic on large projects where components will be migrated gradually... And there's worse: if the migration tool changes => I think that this error should not apply to the forward directive, and that <button {onclick}>click</button> // OK
<button {onclick} on:click={onclick}>click</button> // ERROR
<button {onclick} on:click>click</button> // WARNING |
Fixes #11262
The bug occurs as follows: When only the old event handling system is used (specified by
on:
followed by the event name), the compiler designates the delegated event as non-hoistable. However, when the new event handling system is employed, it is marked as hoistable. The issue arises when these two systems are mixed.Currently, there are a few validations in place, but none address this specific interaction between the old and new systems. Consequently, the compiler defaults to labeling any function or callback as hoistable when the new event-handling system is utilized. This causes a problem with the old system, which fails to handle the arguments correctly, as they are not passed to the function or callback as expected.
Essentially, the PR issues an error to the user about the use of both old and new event-handling syntaxes and advises against using them simultaneously within the same component. This error only triggers when mixed syntaxes are used within the same component and on regular/Svelte elements.
Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.Tests and linting
pnpm test
and lint the project withpnpm lint