-
-
Notifications
You must be signed in to change notification settings - Fork 415
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
Refactor builtin Map
intrinsics to follow more closely the spec
#1572
Conversation
Test262 conformance changes:
Fixed tests (32):
|
ab0f7c7
to
9efae49
Compare
Map
intrínsics to follow more closely the specMap
intrinsics to follow more closely the spec
9efae49
to
52cef22
Compare
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.
Looks really nice.
I've got a few little things.
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.
The conformance numbers look great, and the code seems good, but I'll need some convincing in some design decisions :)
pub value: JsValue, | ||
pub done: bool, |
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.
This I don't like. Is this needed? Using public members makes this structure modifiable almost anywhere and with no control, and makes it much more difficult if we ever want to change the inner structure.
The getter and setter patterns are very well established in Rust for a reason. They are less error prone and easier to maintain external compatibility.
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.
Using getters and setters is justifiable if we had to maintain some state internally. This struct is just a wrapper for a (Value, bool)
to represent an iterator item, I don't see the utility on having only getters if the struct will have just is_done
and get_value
as methods.
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.
While you are right that there is no functionality with this struct, I think the private fields preserve the nature of the struct. It should only be used to access the result of an iterator next call. If the fields are public, the struct is really only a wrapper for (JsValue, bool)
. In that case we could also just work with that tuple directly instead of using a struct.
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.
We could return a tuple, but using an struct makes more explicit what each type represents. That's the same reason why it's more idiomatic to represent a 2d point as a Point {x: f64, y: f64}
instead of a (f64, f64)
.
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.
But, if it's not meant to be modified, we don't even need the setters, and not having them would prevent accidental mutation.
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.
But it is meant to be modified. Or at least is meant to be destructured and used as an owned value, like in:
boa/boa/src/syntax/ast/node/array/mod.rs
Lines 54 to 60 in 2f8c35d
let next = iterator_record.next(context)?; | |
if next.is_done() { | |
break; | |
} | |
let next_value = next.value(); | |
//next_index += 1; | |
elements.push(next_value.clone()); |
or in
boa/boa/src/syntax/ast/node/new/mod.rs
Lines 61 to 66 in 2f8c35d
let next = iterator_record.next(context)?; | |
if next.is_done() { | |
break; | |
} | |
let next_value = next.value(); | |
v_args.push(next_value.clone()); |
And no function takes an IteratorResult
as a parameter, so we don't need to ensure that IteratorResult
is not modified. If we used IteratorResult
as a parameter on any function, I would completely agree with using getters.
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.
Now that I think about this, is there a reason that IteratorResult
is pub
instead of pub(crate)
at all? We neither return nor accept this anywhere in the public api.
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.
Now that I think about this, is there a reason that
IteratorResult
ispub
instead ofpub(crate)
at all? We neither return nor accept this anywhere in the public api.
Yeah, I just copied the current visibility, but maybe we shouldn't expose it to the user.
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.
The API is not very well defined yet, and we will probably need to change many visibilities. I'm OK with these changes.
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.
LGTM, only exception is having the extra methods in Object
like @Razican said. In my opinion it doesn't abstract that much code away and is one more thing people need to know about.
Ah, I forgot to push my last changes 😅 |
Changes:
OrderedMap
to reset itsempty_count
onclear
.Map
object.AddEntriesFromIterable
.IteratorResult
.Context
to the end of all relatedIterator
methods.