Skip to content

chore: remove binding.expression #12530

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

Merged
merged 25 commits into from
Jul 24, 2024
Merged

chore: remove binding.expression #12530

merged 25 commits into from
Jul 24, 2024

Conversation

Rich-Harris
Copy link
Member

@Rich-Harris Rich-Harris commented Jul 22, 2024

hal-fixing-lightbulb.gif

This started out with #12511. As mentioned in that PR, I'd like to move more of the each block optimisation to compile time, if possible. My first step was to get rid of $.unwrap(i) in cases like this...

{#each things as thing, i}
  <p>{i}: {thing.name}</p>
{/each}
$.each(node, 1, () => things, $.index, ($$anchor, thing, i) => {
  var p = root_1();
  var text = $.child(p);

  $.reset(p);
-  $.template_effect(() => $.set_text(text, `${$.unwrap(i) ?? ""}: ${$.unwrap(thing).name ?? ""}`));
+  $.template_effect(() => $.set_text(text, `${i}: ${$.unwrap(thing).name ?? ""}`));
  $.append($$anchor, p);
});

...because it's a bit daft to call $.unwrap when we know perfectly well that i is a) not a signal, and b) defined, making the ?? "" pointless. (Also, unwrap relies on brittle duck typing and should be removed.)

But it wasn't that simple, because in some contexts the index might be wrapped in a source, and in others (i.e. the key function) not. Which made me happy because there's a part of our codebase that I've wanted to get rid of for a long time, and I finally have a good reason: binding.expression.

Essentially, we assign an expression to certain bindings when we have specific transformation requirements. But it's not really in keeping with how the rest of the compiler works — ideally, transformation would be pure, and all the mutatey stuff would happen during the analysis phase. (Imagine a world in which it's possible to generate server and client output from a single compiler run, rather than the current — wasteful — process of parsing and analysing from scratch before handing the result off to the transformation phase. While that's not a near term goal, reducing the number of places where mutation can happen in order to make code more understandable and robust is always a goal.)

And we have a perfectly good mechanism already — context.state. This PR adds a getters record to TransformState that allows nodes to create those ad hoc overrides without mutating the bindings themselves. This should make it much easier to fix the i thing above, and no doubt other things too.

Right now it only uses getters in one place, hence draft status.

  • needs to have an equivalent setters record to replace binding.mutation will do this in a follow-up

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

Copy link

changeset-bot bot commented Jul 22, 2024

🦋 Changeset detected

Latest commit: b445acd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

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

@Rich-Harris Rich-Harris changed the title chore: remove binding.expression chore: remove binding.expression and binding.mutation Jul 22, 2024
@Rich-Harris Rich-Harris marked this pull request as ready for review July 23, 2024 18:54
@Rich-Harris
Copy link
Member Author

Marked this ready for review. Right now it probably looks like a step backwards from a certain angle, but this is a first step towards making all this stuff a lot more flexible and robust — I anticipate that the state.getters[name] approach can replace serialize_get_binding in its entirety. More excitingly, I think we can do the same thing for binding.mutation and get rid of serialize_set_binding, which is a horrifically complicated function that has proven somewhat resistant to refactoring.

@Rich-Harris Rich-Harris changed the title chore: remove binding.expression and binding.mutation chore: remove binding.expression Jul 24, 2024
Copy link
Contributor

@trueadm trueadm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Rich-Harris Rich-Harris merged commit cf8df0b into main Jul 24, 2024
9 checks passed
@Rich-Harris Rich-Harris deleted the remove-binding-expression branch July 24, 2024 14:19
@Rich-Harris Rich-Harris mentioned this pull request Aug 2, 2024
5 tasks
@Rich-Harris Rich-Harris mentioned this pull request Aug 10, 2024
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants