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

refactor(parser): make Source::set_position safe #2341

Merged
merged 1 commit into from
Feb 8, 2024

Conversation

overlookmotel
Copy link
Collaborator

@overlookmotel overlookmotel commented Feb 7, 2024

Make Source::set_position a safe function.

This addresses a shortcoming of #2288.

Instead of requiring caller of Source::set_position to guarantee that the SourcePosition is created from this Source, the preceding PRs enforce this guarantee at the type level.

Source::set_position is going to be a central API for transitioning the lexer to processing the source as bytes, rather than chars (and the anticipated speed-ups that will produce). So making this method safe will remove the need for a lot of unsafe code blocks, and boilerplate comments promising "SAFETY: There's only one Source", when to the developer, this is blindingly obvious anyway.

So, while splitting the parser into Parser and ParserImpl (#2339) is an annoying change to have to make, I believe the benefit of this PR justifies it.

@overlookmotel
Copy link
Collaborator Author

overlookmotel commented Feb 7, 2024

@github-actions github-actions bot added the A-parser Area - Parser label Feb 7, 2024
Copy link

codspeed-hq bot commented Feb 7, 2024

CodSpeed Performance Report

Merging #2341 will not alter performance

Comparing 02-07-refactor_parser_make_Source_set_position_safe (66c6e8e) with main (aef593f)

Summary

✅ 27 untouched benchmarks

@overlookmotel
Copy link
Collaborator Author

My first foray into Graphite. Is this roughly how you like it to be used? Did I split the change into too many PRs? Or too few?

Boshen pushed a commit that referenced this pull request Feb 7, 2024
Split parser into public interface `Parser` and internal implementation `ParserImpl`.

This involves no changes to public API.

This change is a bit annoying, but justification is that it's required for #2341, which I believe to be very worthwhile.

The `ParserOptions` type also makes it a bit clearer what the defaults for `allow_return_outside_function` and `preserve_parens` are. It came as a surprise to me that `preserve_parens` defaults to `true`, and this refactor makes that a bit more obvious when reading the code.

All the real changes are in [oxc_parser/src/lib.rs](https://github.com/oxc-project/oxc/pull/2339/files#diff-8e59dfd35fc50b6ac9a9ccd991e25c8b5d30826e006d565a2e01f3d15dc5f7cb). The rest of the diff is basically replacing `Parser` with `ParserImpl` everywhere else.
@overlookmotel overlookmotel force-pushed the 02-07-parser_refactor_promise_only_one_on_a_thread_at_a_time branch from 0769a03 to 5dcc001 Compare February 7, 2024 15:35
@overlookmotel overlookmotel force-pushed the 02-07-refactor_parser_make_Source_set_position_safe branch from fee4da9 to 9789eac Compare February 7, 2024 17:44
@overlookmotel
Copy link
Collaborator Author

Now updated to reflect new approach on #2340, and rebased on top of it (not sure why Graphite didn't do the latter automatically).

So ready to merge if you're happy with #2340.

Copy link
Member

Boshen commented Feb 8, 2024

Merge activity

  • Feb 8, 1:51 AM EST: @Boshen started a stack merge that includes this pull request via Graphite.
  • Feb 8, 1:52 AM EST: Graphite rebased this pull request as part of a merge.
  • Feb 8, 1:56 AM EST: @Boshen merged this pull request with Graphite.

Base automatically changed from 02-07-parser_refactor_promise_only_one_on_a_thread_at_a_time to main February 8, 2024 06:51
Boshen pushed a commit that referenced this pull request Feb 8, 2024
)

Introduce invariant that only a single `lexer::Source` can exist on a thread at one time.

This is a preparatory step for #2341.

2 notes:

Restriction is only 1 x `ParserImpl` / `Lexer` / `Source` on 1 *thread* at a time, not globally. So this does not prevent parsing multiple files simultaneously on different threads.

Restriction does not apply to public type `Parser`, only `ParserImpl`. `ParserImpl`s are not created in created in `Parser::new`, but instead in `Parser::parse`, where they're created and then immediately consumed. So the end user is also free to create multiple `Parser` instances (if they want to for some reason) on the same thread.
@Boshen Boshen force-pushed the 02-07-refactor_parser_make_Source_set_position_safe branch from 9789eac to 66c6e8e Compare February 8, 2024 06:51
@Boshen Boshen merged commit f347016 into main Feb 8, 2024
21 checks passed
@Boshen Boshen deleted the 02-07-refactor_parser_make_Source_set_position_safe branch February 8, 2024 06:56
@overlookmotel
Copy link
Collaborator Author

Thanks Boshen!

IWANABETHATGUY pushed a commit to IWANABETHATGUY/oxc that referenced this pull request May 29, 2024
Split parser into public interface `Parser` and internal implementation `ParserImpl`.

This involves no changes to public API.

This change is a bit annoying, but justification is that it's required for oxc-project#2341, which I believe to be very worthwhile.

The `ParserOptions` type also makes it a bit clearer what the defaults for `allow_return_outside_function` and `preserve_parens` are. It came as a surprise to me that `preserve_parens` defaults to `true`, and this refactor makes that a bit more obvious when reading the code.

All the real changes are in [oxc_parser/src/lib.rs](https://github.com/oxc-project/oxc/pull/2339/files#diff-8e59dfd35fc50b6ac9a9ccd991e25c8b5d30826e006d565a2e01f3d15dc5f7cb). The rest of the diff is basically replacing `Parser` with `ParserImpl` everywhere else.
IWANABETHATGUY pushed a commit to IWANABETHATGUY/oxc that referenced this pull request May 29, 2024
…c-project#2340)

Introduce invariant that only a single `lexer::Source` can exist on a thread at one time.

This is a preparatory step for oxc-project#2341.

2 notes:

Restriction is only 1 x `ParserImpl` / `Lexer` / `Source` on 1 *thread* at a time, not globally. So this does not prevent parsing multiple files simultaneously on different threads.

Restriction does not apply to public type `Parser`, only `ParserImpl`. `ParserImpl`s are not created in created in `Parser::new`, but instead in `Parser::parse`, where they're created and then immediately consumed. So the end user is also free to create multiple `Parser` instances (if they want to for some reason) on the same thread.
IWANABETHATGUY pushed a commit to IWANABETHATGUY/oxc that referenced this pull request May 29, 2024
Make `Source::set_position` a safe function.

This addresses a shortcoming of oxc-project#2288.

Instead of requiring caller of `Source::set_position` to guarantee that the `SourcePosition` is created from this `Source`, the preceding PRs enforce this guarantee at the type level.

`Source::set_position` is going to be a central API for transitioning the lexer to processing the source as bytes, rather than `char`s (and the anticipated speed-ups that will produce). So making this method safe will remove the need for a *lot* of unsafe code blocks, and boilerplate comments promising "SAFETY: There's only one `Source`", when to the developer, this is blindingly obvious anyway.

So, while splitting the parser into `Parser` and `ParserImpl` (oxc-project#2339) is an annoying change to have to make, I believe the benefit of this PR justifies it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parser Area - Parser
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants