163 lines
2.7 KiB
Go
163 lines
2.7 KiB
Go
package sourcemap
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/go-sourcemap/sourcemap/internal/base64vlq"
|
|
)
|
|
|
|
type fn func(m *mappings) (fn, error)
|
|
|
|
type mapping struct {
|
|
genLine int32
|
|
genColumn int32
|
|
sourcesInd int32
|
|
sourceLine int32
|
|
sourceColumn int32
|
|
namesInd int32
|
|
}
|
|
|
|
type mappings struct {
|
|
rd *strings.Reader
|
|
dec base64vlq.Decoder
|
|
|
|
hasName bool
|
|
value mapping
|
|
|
|
values []mapping
|
|
}
|
|
|
|
func parseMappings(s string) ([]mapping, error) {
|
|
if s == "" {
|
|
return nil, errors.New("sourcemap: mappings are empty")
|
|
}
|
|
|
|
rd := strings.NewReader(s)
|
|
m := &mappings{
|
|
rd: rd,
|
|
dec: base64vlq.NewDecoder(rd),
|
|
|
|
values: make([]mapping, 0, mappingsNumber(s)),
|
|
}
|
|
m.value.genLine = 1
|
|
m.value.sourceLine = 1
|
|
|
|
err := m.parse()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
values := m.values
|
|
m.values = nil
|
|
return values, nil
|
|
}
|
|
|
|
func mappingsNumber(s string) int {
|
|
return strings.Count(s, ",") + strings.Count(s, ";")
|
|
}
|
|
|
|
func (m *mappings) parse() error {
|
|
next := parseGenCol
|
|
for {
|
|
c, err := m.rd.ReadByte()
|
|
if err == io.EOF {
|
|
m.pushValue()
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
switch c {
|
|
case ',':
|
|
m.pushValue()
|
|
next = parseGenCol
|
|
case ';':
|
|
m.pushValue()
|
|
|
|
m.value.genLine++
|
|
m.value.genColumn = 0
|
|
|
|
next = parseGenCol
|
|
default:
|
|
err := m.rd.UnreadByte()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
next, err = next(m)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func parseGenCol(m *mappings) (fn, error) {
|
|
n, err := m.dec.Decode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m.value.genColumn += n
|
|
return parseSourcesInd, nil
|
|
}
|
|
|
|
func parseSourcesInd(m *mappings) (fn, error) {
|
|
n, err := m.dec.Decode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m.value.sourcesInd += n
|
|
return parseSourceLine, nil
|
|
}
|
|
|
|
func parseSourceLine(m *mappings) (fn, error) {
|
|
n, err := m.dec.Decode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m.value.sourceLine += n
|
|
return parseSourceCol, nil
|
|
}
|
|
|
|
func parseSourceCol(m *mappings) (fn, error) {
|
|
n, err := m.dec.Decode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m.value.sourceColumn += n
|
|
return parseNamesInd, nil
|
|
}
|
|
|
|
func parseNamesInd(m *mappings) (fn, error) {
|
|
n, err := m.dec.Decode()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m.hasName = true
|
|
m.value.namesInd += n
|
|
return parseGenCol, nil
|
|
}
|
|
|
|
func (m *mappings) pushValue() {
|
|
if m.value.sourceLine == 1 && m.value.sourceColumn == 0 {
|
|
return
|
|
}
|
|
|
|
if m.hasName {
|
|
m.values = append(m.values, m.value)
|
|
m.hasName = false
|
|
} else {
|
|
m.values = append(m.values, mapping{
|
|
genLine: m.value.genLine,
|
|
genColumn: m.value.genColumn,
|
|
sourcesInd: m.value.sourcesInd,
|
|
sourceLine: m.value.sourceLine,
|
|
sourceColumn: m.value.sourceColumn,
|
|
namesInd: -1,
|
|
})
|
|
}
|
|
}
|