Skip to content

replaceRevive: Use switch/case for what's interesting in replacer.#4362

Merged
gnprice merged 8 commits into
zulip:masterfrom
chrisbobbe:pr-replacer-switch-case
Dec 29, 2020
Merged

replaceRevive: Use switch/case for what's interesting in replacer.#4362
gnprice merged 8 commits into
zulip:masterfrom
chrisbobbe:pr-replacer-switch-case

Conversation

@chrisbobbe
Copy link
Copy Markdown
Collaborator

As Greg suggests, at
#4348 (comment).

Also add some comments / jsdoc.

Copy link
Copy Markdown
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

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

Thanks @chrisbobbe ! All LGTM and ready to merge, modulo a small comment below.

Comment thread src/boot/replaceRevive.js
data: FallbackAvatarURL.serialize(value),
[SERIALIZED_TYPE_FIELD_NAME]: 'FallbackAvatarURL',
};
case (Immutable.Map.prototype: $FlowFixMe):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This bit isn't NFC because instanceof Immutable.Map would accept an Immutable.OrderedMap (the one subclass Immutable has for that class), and this won't.

... Which is a fix to a latent bug! We don't currently use OrderedMap, but if we did, the old code would cheerfully serialize it, and then deserialize it as a plain Immutable.Map.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ah, right, good catch—I'll make a note in the commit message and remove the [nfc] mark.

chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this pull request Dec 29, 2020
As Greg suggests [1].

It isn't quite NFC, as Greg points out [2]. It fixes a latent bug:
before this, if we had used an `Immutable.OrderedMap` anywhere, the
replacer would have cheerfully serialized it with the `ImmutableMap`
identifier, and it would get deserialized as a plain `Immutable.Map`
instead of an `Immutable.OrderedMap`.

[1] zulip#4348 (comment)
[2] zulip#4362 (comment)
@chrisbobbe chrisbobbe force-pushed the pr-replacer-switch-case branch from 7be177a to dbc002d Compare December 29, 2020 20:04
@chrisbobbe
Copy link
Copy Markdown
Collaborator Author

Thanks for the review! I just pushed a new revision with that commit-message change.

@chrisbobbe chrisbobbe changed the title replaceRevive [nfc]: Use switch/case for what's interesting in replacer. replaceRevive: Use switch/case for what's interesting in replacer. Dec 29, 2020
Greg reports that this is equivalent [1], and it seems to work just
fine.

[1] zulip#4348 (comment)
…aces.

We know that these classes don't have `.toJSON` methods -- after
all, we wrote them -- but this brings us closer to refactoring this
logic into a simpler switch/case, which we'll do soon.
One of the `invariant`s just above this code ensures that `value`
and `origValue` will be identical (===). (The only reason they would
ever differ is that `value` is the result of calling `origValue`'s
`toJSON` method, if present. That invariant would throw if `toJSON`
were present.)

So, we can choose between them. Might as well use `origValue`. That
way, most of the code in this function uses `origValue`, which
clears the way for a nice upcoming refactor where we use a
switch/case instead of lots of `if` / `else if`s. It also helps
isolate `value` as something that's useful mainly for saving
computation in a particular way, as we do in the `Immutable.Map`
case (see bf8837c for more on that).
This won't stay here; soon, we'll make it an even earlier return.
But we'll do so in separate commits, so we have room to explain
more.
This is NFC because there's no loss to the set of possible errors
the `invariant`s were catching. In particular, the check we're
bringing upwards neatly replaces the check that establishes whether
the `invariant`s ran (or indeed were possible to express).
Not totally NFC because of the potential for a notable performance
gain (we now avoid doing some unnecessary checks).

This will allow us to refactor our many `if` / `else if` cases into
a simpler switch/case on `Object.getPrototypeOf(origValue)`, by
letting us call `Object.getPrototypeOf(origValue)` in the first
place. (It fails on `null` and `undefined`.)

This is NFC because `origValue` being non-`null` and having `typeof`
'object' is a necessary condition for any of the `if` / `else if`
conditions to be true.
As Greg suggests [1].

It isn't quite NFC, as Greg points out [2]. It fixes a latent bug:
before this, if we had used an `Immutable.OrderedMap` anywhere, the
replacer would have cheerfully serialized it with the `ImmutableMap`
identifier, and it would get deserialized as a plain `Immutable.Map`
instead of an `Immutable.OrderedMap`.

[1] zulip#4348 (comment)
[2] zulip#4362 (comment)
@gnprice gnprice force-pushed the pr-replacer-switch-case branch from dbc002d to 05048c7 Compare December 29, 2020 21:58
@gnprice
Copy link
Copy Markdown
Member

gnprice commented Dec 29, 2020

Thanks -- merged!

@gnprice gnprice merged commit 05048c7 into zulip:master Dec 29, 2020
@chrisbobbe chrisbobbe deleted the pr-replacer-switch-case branch November 4, 2021 23:59
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.

2 participants