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

feat: Add support for range mappings proposal #77

Merged
merged 64 commits into from
Mar 20, 2024

Conversation

kdy1
Copy link
Contributor

@kdy1 kdy1 commented Jan 25, 2024

src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
@loewenheim
Copy link
Contributor

loewenheim commented Jan 25, 2024

Hi, thank you for the contribution!

I think there is a fundamental misunderstanding here: it seems to me that the both decode_rmi function and the loop in decode_regular in which it is used assume that there is at most one range mapping per line. This is the only way I can see

            if rmi != 0 && (line_index as u32) == rmi - 1 {
                range_tokens.push(tokens.len() as u32)
            }

making sense—if the current index within the line is the number of the range token, we push the current token index to the list of range tokens.

But I think the proposal is meant to work differently: there can be many range mappings per line, and the ith bit in the rangeMappings for that line (modulo bit/byte endianness, I actually find this slightly confusing) tells you whether the ith mapping is one of them.

Consider this example: currently, decode_rmi("AAB") == 13. This is correct insofar as "AAB" makes the 13th mapping a range mapping, but the function shouldn't return 13, it should return the number with only the 13th bit set ¹. The current implementation clearly doesn't generalize to more than one range mapping per line.

Correctness aside, I'm really excited about this. These range mappings would've saved me a lot of pain in the past.

¹ Or better yet, as @Swatinem says, a bit vector.

src/types.rs Outdated Show resolved Hide resolved
@kdy1 kdy1 marked this pull request as ready for review January 29, 2024 09:13
src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/types.rs Outdated Show resolved Hide resolved
src/types.rs Outdated Show resolved Hide resolved
@kdy1 kdy1 marked this pull request as draft January 30, 2024 04:22
@kdy1 kdy1 marked this pull request as ready for review January 30, 2024 04:31
src/decoder.rs Outdated Show resolved Hide resolved
src/encoder.rs Outdated Show resolved Hide resolved
src/encoder.rs Outdated Show resolved Hide resolved
src/encoder.rs Show resolved Hide resolved
@loewenheim
Copy link
Contributor

I believe converting between 0- and 1-based indices causes some unnecessary confusion here.

  1. In decoder.rs line 219, you push a 0-based index to range_tokens.
  2. In SourceMap::get_token you binary search range_tokens for the token's index, which is 0-based.
  3. In test_decode_rmi, you convert to 1-based indices, I assume for purposes of clarity?
  4. In encoder.rs line 81, you add 1 to the index to make it 1-based.
  5. In encoder.rs lines 43-45, you assert that the indices are all greater than 0 (i.e. 1-based), but then subtract 1 to make them 0-based.

I would say remove the 1-based indexing in (4) and (5) (and arguably (3) as well) and just assume 0-based indices everywhere.

@kdy1 kdy1 requested review from loewenheim, sokra and Swatinem February 1, 2024 02:10
@loewenheim
Copy link
Contributor

Just a heads-up—I haven't forgotten about this, I just haven't had the time to look at it.

src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/decoder.rs Outdated Show resolved Hide resolved
src/encoder.rs Outdated Show resolved Hide resolved
Comment on lines +48 to +49
/// Range mapping index is invalid
InvalidRangeMappingIndex(data_encoding::DecodeError),
Copy link
Member

Choose a reason for hiding this comment

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

Just a NOTE: this is a breaking change as Error is not (yet) marked as #[non_exhaustive]

Copy link
Contributor

Choose a reason for hiding this comment

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

I would say if we're ok with making a breaking change here, then we should also put the information whether a token is a range token directly on RawToken.

@kdy1 kdy1 requested a review from Swatinem February 28, 2024 06:24
Copy link
Member

@Swatinem Swatinem left a comment

Choose a reason for hiding this comment

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

lgtm.

We have a very limited number of unit tests that just test the en/decoding of the range mappings.
Can we construct a more e2e test that shows how these are actually used?

src/encoder.rs Outdated Show resolved Hide resolved
src/encoder.rs Outdated Show resolved Hide resolved
src/types.rs Outdated Show resolved Hide resolved
@kdy1 kdy1 requested a review from sokra March 4, 2024 07:42
@kdy1 kdy1 changed the title feat: Add support for range mappings propsal feat: Add support for range mappings proposal Mar 13, 2024
@kdy1 kdy1 requested a review from Swatinem March 13, 2024 02:53
@kdy1
Copy link
Contributor Author

kdy1 commented Mar 13, 2024

@Swatinem I added some tests for lookup_token

@Swatinem
Copy link
Member

The test now makes it a bit clearer what this proposal is trying to achieve.

So if I understand it correctly, new bitvec mapping adds this is_range flag.
And the is_range flag determines if the mapping is using the "offset" from the initial binary search lookup to then adjust the output line/column numbers.

With a more visual example:

   /* foo */ if (some_other_code) { return; }
//           ^ - original token
// v - output token
   if (some_other_code) { return; }
//     ^ - lookup position

So the offset between lookup position and output token is added to original token, so that you end up exactly at the same position in relative code if it is merely shifted a bit by the sourcemap?

Copy link
Member

@Swatinem Swatinem left a comment

Choose a reason for hiding this comment

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

code lgtm!

thanks for working on this and implementing all the feedback ❤️

};
self.tokens.push(raw);
raw
}

/// Adds a new mapping to the builder.
#[allow(clippy::too_many_arguments)]
Copy link
Member

Choose a reason for hiding this comment

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

TBH, clippy is absolutely right to complain here. Trying to review the tests for this on github, I completely lose track of what all these parameters mean (without inlay hints).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, but I'm not sure how should I fix it.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, me neither :-( I think this is fine this way, just wanted to call it out as a future improvement opportunity.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah this is definitely on the list for an eventual rework. These signatures can't stay like this.

@kdy1
Copy link
Contributor Author

kdy1 commented Mar 14, 2024

Yeap, exactly. This will be useful for the minifier, which does not have full input source locations.

This is the case because no tools emit a perfect source map while transpiling, and the mappings in inputSourceMap is not enough. With this RFC, it will have much more information about the input.

Copy link
Contributor

@loewenheim loewenheim left a comment

Choose a reason for hiding this comment

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

Looks good to me. Thank you for working on this!

};
self.tokens.push(raw);
raw
}

/// Adds a new mapping to the builder.
#[allow(clippy::too_many_arguments)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah this is definitely on the list for an eventual rework. These signatures can't stay like this.

@Swatinem Swatinem merged commit c95386a into getsentry:master Mar 20, 2024
4 checks passed
@kdy1 kdy1 deleted the range-mapping branch March 25, 2024 03:03
kdy1 added a commit to swc-project/swc that referenced this pull request Mar 25, 2024
kdy1 added a commit to vercel/turborepo that referenced this pull request Apr 10, 2024
### Description

Update SWC crates.


1. To keep in sync
2. Prepare usage of source map range mappings.
getsentry/rust-sourcemap#77


### Testing Instructions

See next.js counterpart.

vercel/next.js#63790

Closes PACK-2861
kdy1 added a commit to vercel/next.js that referenced this pull request Apr 11, 2024
# Turbopack


* vercel/turborepo#7409 <!-- hrmny - chore: add
parallel rust frontend and remove unused rust dependencies -->
* vercel/turborepo#7920 <!-- Tobias Koppers - remove
warning when there is no PostCSS config -->
* vercel/turborepo#7929 <!-- Tim Neutkens - Remove
environment variables page from Turbopack docs -->
* vercel/turborepo#7926 <!-- Tim Neutkens - Remove
outdated section -->
* vercel/turborepo#7925 <!-- Tim Neutkens - Update
Turbopack CSS docs -->
* vercel/turborepo#7928 <!-- Tim Neutkens - Update
Next.js mention in Turbopack docs -->
* vercel/turborepo#7856 <!-- Donny/강동윤 - build:
Update `swc_core` to `v0.90.29` -->



### What?

Update SWC crates.

### Why?

1. To keep in sync
2. Prepare usage of source map range mappings.
getsentry/rust-sourcemap#77

### How?



Closes PACK-2860
ForsakenHarmony pushed a commit to vercel/next.js that referenced this pull request Jul 25, 2024
### Description

Update SWC crates.


1. To keep in sync
2. Prepare usage of source map range mappings.
getsentry/rust-sourcemap#77


### Testing Instructions

See next.js counterpart.

#63790

Closes PACK-2861
ForsakenHarmony pushed a commit to vercel/next.js that referenced this pull request Jul 29, 2024
### Description

Update SWC crates.


1. To keep in sync
2. Prepare usage of source map range mappings.
getsentry/rust-sourcemap#77


### Testing Instructions

See next.js counterpart.

#63790

Closes PACK-2861
ForsakenHarmony pushed a commit to vercel/next.js that referenced this pull request Jul 29, 2024
### Description

Update SWC crates.


1. To keep in sync
2. Prepare usage of source map range mappings.
getsentry/rust-sourcemap#77


### Testing Instructions

See next.js counterpart.

#63790

Closes PACK-2861
ForsakenHarmony pushed a commit to vercel/next.js that referenced this pull request Aug 1, 2024
### Description

Update SWC crates.


1. To keep in sync
2. Prepare usage of source map range mappings.
getsentry/rust-sourcemap#77


### Testing Instructions

See next.js counterpart.

#63790

Closes PACK-2861
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.

4 participants