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

Draft: Add a decoding algorithm for index maps #132

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

takikawa
Copy link
Collaborator

@takikawa takikawa commented Sep 27, 2024

Rendered draft

This PR adds a decoding algorithm for index maps along the lines of the existing algorithms for normal source maps.

I'll leave a few comments for cases in the spec where it's not clear what we should do:

  • Error cases for offsets
  • The check for index map overlap

1. Let |offsetLine| be |section|[`"offset"`][`"line"`].
1. Let |offsetColumn| be |section|[`"offset"`][`"column"`].
1. If |offsetLine| is not a number, [=optionally report an error=].
1. If |offsetColumn| is not a number, [=optionally report an error=].
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I left these checks a bit vague, but it's not very meaningful for line and column to be non-integral values. Should we coerce these to integers and then add them? Or reject non-integral values? (as in Number.isInteger())

1. If |offsetColumn| is not a number, [=optionally report an error=].
1. If |previousOffset| is not null,
1. If |previousLastMapping| is not null,
1. If |offsetLine| is less than |previousLastMapping|'s [=decoded mapping/generatedLine=], [=optionally report an error=].
Copy link
Collaborator Author

@takikawa takikawa Sep 27, 2024

Choose a reason for hiding this comment

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

Should these range checks be "less than or equal to" to be strict inequality rather than allowing equality?

Note: This part of the decoding algorithm checks that index source map sections do not overlap. While it is
expected that generators should not produce index source maps with overlapping sections, source map
consumers may choose instead to only check the simpler condition that the sections are ordered and therefore
that offsets appear in increasing order.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As the note says, I'm not sure anyone will implement the overlap check here (which ensures that the offset position comes after the last ordered mapping, or the last offset if no mappings exist, of the last section) but it encodes what we expect of generators at least.

Note: none of the browsers implement an overlap check as far as I know. I think only Firefox dev tools even checks order of offsets.

source-map.bs Outdated
1. [=For each=] |mapping| of |decodedSection|'s [=decoded source map/mappings=]:
1. Let |offsetMapping| be a new [=decoded mapping=].
1. Set |offsetMapping|'s [=decoded mapping/generatedLine=] to |mapping|'s [=decoded mapping/generatedLine=] + |offsetLine|.
1. Set |offsetMapping|'s [=decoded mapping/generatedColumn=] to |mapping|'s [=decoded mapping/generatedColumn=] + |offsetColumn|.
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like it also adds the offsetColumn to all subsequent lines? Should this be guarded by "if this is the first generated line of the mapping"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh thanks for catching this, yeah this should only apply to the first line.

(alternatively, this part of the algorithm could be changed to pass the offsets to the "decode a source map" as initial offset arguments which are normally 0)

1. Let |offsetMapping| be a new [=decoded mapping=].
1. Set |offsetMapping|'s [=decoded mapping/generatedLine=] to |mapping|'s [=decoded mapping/generatedLine=] + |offsetLine|.
1. If |firstLine| is null, set |firstLine| to |offsetMapping|'s [=decoded mapping/generatedLine=].
1. If |offsetMapping|'s [=decoded mapping/generatedLine=] is equal to |firstLine|, set |offsetMapping|'s [=decoded mapping/generatedColumn=] to |mapping|'s [=decoded mapping/generatedColumn=] + |offsetColumn|.
Copy link
Member

Choose a reason for hiding this comment

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

This should just check for mapping.generatedLine === 1. If the first mapping is on generated line 3, that doesn't get column added.

1. If |section|[`"map"`] does not [=map/exist=], then report an error.
1. Let |decodedSection| be the result of [=decoding a source map=] given |section|[`"map"`] and |baseURL|.
1. If the previous step reported an error, [=optionally report an error=] and continue with the next iteration.
1. Set |sourceMap|'s [=decoded source map/sources=] to the result of [=list/extending=] |sourceMap|'s [=decoded source map/sources=] with |decodedSection|'s [=decoded source map/sources=].
Copy link
Member

Choose a reason for hiding this comment

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

This is a simple append, but the mapping.originalSources are just strings, so we could treat as a set.

1. [=list/Append=] |offsetMapping| to |offsetMappings|.
1. Set |sourceMap|'s [=decoded source map/mappings=] to the result of [=list/extending=] |sourceMap|'s [=decoded source map/mappings=] with |offsetMappings|.
1. Set |previousOffset| to |section|[`"offset"`].
1. Let |sortedMappings| be the result of [=list/sorting=] |offsetMappings| in ascending order, with an item |a| being less than |b| if |a| is [=generated position less than=] |b|.
Copy link
Member

Choose a reason for hiding this comment

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

Let's do this before the append? They're N distinct regions, no reason to let the sorting algorithm do position guesses in another sections mappings.

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