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

applySourceMap produces incorrect mappings if input maps have different granularities #351

Closed
TimHambourger opened this issue Aug 5, 2018 · 2 comments

Comments

@TimHambourger
Copy link

Description

SourceMapGenerator.prototype.applySourceMap can produce incorrect mappings if the two input maps use different line segmenting strategies.

Steps to reproduce

Follow the steps at this associated repro.

The two input maps are input/map_intermediate_to_final.json and input/map_original_to_intermediate.json, which correspond to source files reference/src_original.tsx, reference/src_intermediate.jsx, and reference/src_final.js. You can inspect the input maps in parsed format in output/parsed_intermediate_to_final.json and output/parsed_original_to_intermediate.json.

Both input maps look valid. And yet the merged map represented by output/map_merged.json and output/parsed_merged.json is incorrect. You can see the issue in generated lines 9, 10, 11, and 13. E.g. for generated line 10, output/parsed_merged.json gives

    {
        "generatedLine": 10,
        "generatedColumn": 0,
        "originalLine": 5,
        "originalColumn": 0
    }

Which corresponds to

from reference/src_final.js:

    console.log('indented');

from reference/src_original.tsx:

function someFunction() {

These lines do not correspond to each other.

Analysis

I see a narrow issue and a general issue.

The narrow issue is that applySourceMap leaves the downstream mapping unchanged if it can't find an upstream mapping for the same line with the same or lower column number. That's b/c in that case the original_location_for call in SourceMapConsumer.prototype.originalPositionFor ends up finding a mapping from the previous line. Due to #261, this causes originalPositionFor to return a nulled out mapping. This in turn causes applySourceMap to skip this mapping and leave the downstream mapping unchanged.

This matters for these input maps because map_original_to_intermediate.json follows a convention of starting its first mapping for each line AFTER any initial indentation, while map_intermediate_to_final.json has many lines w/ just a single mapping at column 0.

E.g., for the line console.log('several');, output/parsed_original_to_intermediate.json gives

    {
        "generatedLine": 4,
        "generatedColumn": 4,
        "originalLine": 6,
        "originalColumn": 4
    },
    // several more mappings for this line

whereas output/parsed_intermediate_to_final.json just has

    {
        "generatedLine": 9,
        "generatedColumn": 0,
        "originalLine": 4,
        "originalColumn": 0
    }

Both mappings give correct line numbers, they just start from different columns. That difference turns out to be crucial.

The general issue is that applySourceMap currently always produces a merged map that has the same number of mappings per line as the downstream map. For my inputs, the downstream map is much less granular than the upstream map. So this essentially means throwing away detail from the upstream map.

So a good first step might be fixing #261. Or, as I suggested on that thread, at least giving applySourceMap a way to specify fuzzy matching when it calls originalPositionFor. A further step would be modifying applySourceMap's algorithm to take something like the union of all mappings from both maps.

@robpalme
Copy link

robpalme commented Dec 7, 2018

This sounds like a duplicate of #216

I agree that this ought to be fixed somehow.

@jkrems
Copy link
Collaborator

jkrems commented Apr 18, 2021

Duplicate of #216

@jkrems jkrems closed this as completed Apr 18, 2021
@jkrems jkrems marked this as a duplicate of #216 Apr 18, 2021
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

No branches or pull requests

3 participants