go-sourcemap / sourcemap

Source maps consumer for Golang
http://godoc.org/github.com/go-sourcemap/sourcemap
BSD 2-Clause "Simplified" License
71 stars 20 forks source link

Parsing bug with typescript generated source map #18

Open tigerwill90 opened 2 years ago

tigerwill90 commented 2 years ago

Hi there,

First of all, thanks for this nice package :)

I found a strange behavior using source map generated by typescript. It's look like a parsing bug but maybe I missed something.

Here are two compiled js outputs using tsc. The only diff is the line where the error is thrown.

/*
test.ts
1 | throw Error("foo")
2 |
3 |
*/
var js1 = `"use strict";
throw Error("foo");
//# sourceMappingURL=test.js.map`

var map1 = `{"version":3,"file":"test.js","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":";AAAA,MAAM,KAAK,CAAC,KAAK,CAAC,CAAA"}`

/*
test.ts
1 |
2 | throw Error("foo")
3 |
*/
var js2 = `"use strict";
throw Error("foo");
//# sourceMappingURL=test.js.map`

var map2 = `{"version":3,"file":"test.js","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":";AACA,MAAM,KAAK,CAAC,KAAK,CAAC,CAAA"}`

Here is the mapping dump from https://pastcompute.github.io/ScriptMapper/ for map1

../test.ts,2,0,1,0,null
../test.ts,2,6,1,6,null
../test.ts,2,11,1,11,null
../test.ts,2,12,1,12,null
../test.ts,2,17,1,17,null
../test.ts,2,18,1,18,null
../test.ts,2,19,1,18,null

And it look like the first decoded mapping segment is missing, note that the mapping slice is allocated with the correct capacity.

// len(6), cap(7)
0 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 6
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 6
 namesInd = {int32} -1
1 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 11
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 11
 namesInd = {int32} -1
2 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 12
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 12
 namesInd = {int32} -1
3 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 17
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 17
 namesInd = {int32} -1
4 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 18
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 18
 namesInd = {int32} -1
5 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 19
 sourcesInd = {int32} 0
 sourceLine = {int32} 1
 sourceColumn = {int32} 18
 namesInd = {int32} -1

Here is the mapping dump for map2

../test.ts,2,0,2,0,null
../test.ts,2,6,2,6,null
../test.ts,2,11,2,11,null
../test.ts,2,12,2,12,null
../test.ts,2,17,2,17,null
../test.ts,2,18,2,18,null
../test.ts,2,19,2,18,null

And this produce the expected result

// len(7), cap(7)
0 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 0
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 0
 namesInd = {int32} -1
1 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 6
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 6
 namesInd = {int32} -1
2 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 11
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 11
 namesInd = {int32} -1
3 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 12
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 12
 namesInd = {int32} -1
4 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 17
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 17
 namesInd = {int32} -1
5 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 18
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 18
 namesInd = {int32} -1
6 = {sourcemap.mapping} 
 genLine = {int32} 2
 genColumn = {int32} 19
 sourcesInd = {int32} 0
 sourceLine = {int32} 2
 sourceColumn = {int32} 18
 namesInd = {int32} -1

So if I haven't missed anything along the way, smp.Source(2, 1) should produce 1, 0, true

SourceMap(map1)
func SourceMap(m string) {
    smp, err := sourcemap.Parse("test.js.map", []byte(m))
    if err != nil {
        panic(err)
    }
    fmt.Println(smp.Source(2, 1)) // 0 0 false
}

Let me know if I can help you reproduce this strange behavior somehow :)