Skip to content

Source Maps missing 1 group #4786

Description

@schneems

Every coffee script file I compile seems to be missing one "group" from the "mappings" section of the source map. Here's an example:

namespace 'Codetriage', (exports) ->
  class exports.TabNavigation
    constructor: (options = {}) ->
      @tabItem      = $("a[data-toggle]")
      @locationHash = location.hash
      @defaultLocation() unless @locationHash
      @watchHistory()
      @bindDataToggleTabEvent()
      @showTabLocation() if @locationHash

Compile with:

$ coffee -mc --no-header foo.coffee

Generates:

(function() {
  namespace('Codetriage', function(exports) {
    return exports.TabNavigation = class TabNavigation {
      constructor(options = {}) {
        this.tabItem = $("a[data-toggle]");
        this.locationHash = location.hash;
        if (!this.locationHash) {
          this.defaultLocation();
        }
        this.watchHistory();
        this.bindDataToggleTabEvent();
        if (this.locationHash) {
          this.showTabLocation();
        }
      }

    };
  });

}).call(this);

//# sourceMappingURL=foo.js.map

The generated file has 20 lines (ends on }).call(this);). The source map looks like this:

{
  "version": 3,
  "file": "foo.js",
  "sourceRoot": "",
  "sources": [
    "foo.coffee"
  ],
  "names": [],
  "mappings": "AAAA;EAAA,SAAA,CAAU,YAAV,EAAwB,QAAA,CAAC,OAAD,CAAA;WAChB,OAAO,CAAC,gBAAd,MAAA,cAAA;MACE,WAAa,CAAC,UAAU,CAAA,CAAX,CAAA;QACX,IAAC,CAAA,OAAD,GAAgB,CAAA,CAAE,gBAAF;QAChB,IAAC,CAAA,YAAD,GAAgB,QAAQ,CAAC;QACzB,IAAA,CAA0B,IAAC,CAAA,YAA3B;UAAA,IAAC,CAAA,eAAD,CAAA,EAAA;;QACA,IAAC,CAAA,YAAD,CAAA;QACA,IAAC,CAAA,sBAAD,CAAA;QACA,IAAsB,IAAC,CAAA,YAAvB;UAAA,IAAC,CAAA,eAAD,CAAA,EAAA;;MANW;;IADf;EADsB,CAAxB;AAAA",
  "sourcesContent": [
    "namespace 'Codetriage', (exports) ->\n  class exports.TabNavigation\n    constructor: (options = {}) ->\n      @tabItem      = $(\"a[data-toggle]\")\n      @locationHash = location.hash\n      @defaultLocation() unless @locationHash\n      @watchHistory()\n      @bindDataToggleTabEvent()\n      @showTabLocation() if @locationHash\n\n"
  ]
}

It has

"AAAA;EAAA,SAAA,CAAU,YAAV,EAAwB,QAAA,CAAC,OAAD,CAAA;WAChB,OAAO,CAAC,gBAAd,MAAA,cAAA;MACE,WAAa,CAAC,UAAU,CAAA,CAAX,CAAA;QACX,IAAC,CAAA,OAAD,GAAgB,CAAA,CAAE,gBAAF;QAChB,IAAC,CAAA,YAAD,GAAgB,QAAQ,CAAC;QACzB,IAAA,CAA0B,IAAC,CAAA,YAA3B;UAAA,IAAC,CAAA,eAAD,CAAA,EAAA;;QACA,IAAC,CAAA,YAAD,CAAA;QACA,IAAC,CAAA,sBAAD,CAAA;QACA,IAAsB,IAAC,CAAA,YAAvB;UAAA,IAAC,CAAA,eAAD,CAAA,EAAA;;MANW;;IADf;EADsB,CAAxB;AAAA".count(';') + 1
# => 19

The +1 is since the last section does not end with a semicolon

19 mappings groups, which would indicate the source file only has 19 lines, even though ours has 20.

There should be a mapping for each section, but it looks like it's missing one. I'm not totally sure which line is missing though

If you use the source-map node package to parse the source map with this:

var sourceMap = require('source-map');
var fs        = require('fs');

fs.readFile('./foo.js.map', 'utf8', function (err, data) {
  if (err) {
    return console.log(err);
  }
  var smc = new sourceMap.SourceMapConsumer(data);

  smc.eachMapping(function(m) {
    console.log(m);
  });
});

It does not show a mapping for line 9:

{ source: 'foo.coffee',
  generatedLine: 8,
  generatedColumn: 31,
  originalLine: 6,
  originalColumn: 6,
  name: null }
{ source: 'foo.coffee',
  generatedLine: 8,
  generatedColumn: 33,
  originalLine: 6,
  originalColumn: 6,
  name: null }

// generatedLine: 9 should be here

{ source: 'foo.coffee',
  generatedLine: 10,
  generatedColumn: 8,
  originalLine: 7,
  originalColumn: 6,
  name: null }
{ source: 'foo.coffee',
  generatedLine: 10,
  generatedColumn: 12,
  originalLine: 7,
  originalColumn: 7,
  name: null }

Also the last line seems to be 19 instead of 20:

{ source: 'foo.coffee',
  generatedLine: 19,
  generatedColumn: 0,
  originalLine: 1,
  originalColumn: 0,
  name: null }

This doesn't appear to be an issue parsing the source map in the browser, it seems that if you skip a line that chrome will default to whatever the previous line was mapped to. However I'm maintaining a tool that is trying to concatenate source maps. To do this we need to know the size of the generated sizes and we're using the number of "groupings" in a "mappings" field https://github.com/rails/sprockets/blob/341fed4f91e0dfd75f9740ee77885488db58aecd/lib/sprockets/source_map_utils.rb#L80.

Every time I concatenate two files where one of them is a coffeescript generated file the resultant offset of the second source map section is off by one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions