2 Star 0 Fork 0

mirrors_go-sourcemap/sourcemap

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
consumer.go 5.02 KB
一键复制 编辑 原始数据 按行查看 历史
Vladimir Mihailenco 提交于 2024-03-13 15:20 +08:00 . chore: cleanup
package sourcemap
import (
"encoding/json"
"fmt"
"net/url"
"path"
"sort"
)
type sourceMap struct {
Version int `json:"version"`
File string `json:"file"`
SourceRoot string `json:"sourceRoot"`
Sources []string `json:"sources"`
SourcesContent []string `json:"sourcesContent"`
Names []json.RawMessage `json:"names,string"`
Mappings string `json:"mappings"`
mappings []mapping
}
type v3 struct {
sourceMap
Sections []section `json:"sections"`
}
func (m *sourceMap) parse(sourcemapURL string) error {
if err := checkVersion(m.Version); err != nil {
return err
}
var sourceRootURL *url.URL
if m.SourceRoot != "" {
u, err := url.Parse(m.SourceRoot)
if err != nil {
return err
}
if u.IsAbs() {
sourceRootURL = u
}
} else if sourcemapURL != "" {
u, err := url.Parse(sourcemapURL)
if err != nil {
return err
}
if u.IsAbs() {
u.Path = path.Dir(u.Path)
sourceRootURL = u
}
}
for i, src := range m.Sources {
m.Sources[i] = m.absSource(sourceRootURL, src)
}
mappings, err := parseMappings(m.Mappings)
if err != nil {
return err
}
m.mappings = mappings
// Free memory.
m.Mappings = ""
return nil
}
func (m *sourceMap) absSource(root *url.URL, source string) string {
if path.IsAbs(source) {
return source
}
if u, err := url.Parse(source); err == nil && u.IsAbs() {
return source
}
if root != nil {
u := *root
u.Path = path.Join(u.Path, source)
return u.String()
}
if m.SourceRoot != "" {
return path.Join(m.SourceRoot, source)
}
return source
}
func (m *sourceMap) name(idx int) string {
if idx >= len(m.Names) {
return ""
}
raw := m.Names[idx]
if len(raw) == 0 {
return ""
}
if raw[0] == '"' && raw[len(raw)-1] == '"' {
var str string
if err := json.Unmarshal(raw, &str); err == nil {
return str
}
}
return string(raw)
}
type section struct {
Offset struct {
Line int `json:"line"`
Column int `json:"column"`
} `json:"offset"`
Map *sourceMap `json:"map"`
}
type Consumer struct {
sourcemapURL string
file string
sections []section
}
func Parse(sourcemapURL string, b []byte) (*Consumer, error) {
v3 := new(v3)
err := json.Unmarshal(b, v3)
if err != nil {
return nil, err
}
if err := checkVersion(v3.Version); err != nil {
return nil, err
}
if len(v3.Sections) == 0 {
v3.Sections = append(v3.Sections, section{
Map: &v3.sourceMap,
})
}
for _, s := range v3.Sections {
err := s.Map.parse(sourcemapURL)
if err != nil {
return nil, err
}
}
reverse(v3.Sections)
return &Consumer{
sourcemapURL: sourcemapURL,
file: v3.File,
sections: v3.Sections,
}, nil
}
func (c *Consumer) SourcemapURL() string {
return c.sourcemapURL
}
// File returns an optional name of the generated code
// that this source map is associated with.
func (c *Consumer) File() string {
return c.file
}
// Source returns the original source, name, line, and column information
// for the generated source's line and column positions.
func (c *Consumer) Source(
genLine, genColumn int,
) (source, name string, line, column int, ok bool) {
for i := range c.sections {
s := &c.sections[i]
if s.Offset.Line < genLine ||
(s.Offset.Line+1 == genLine && s.Offset.Column <= genColumn) {
genLine -= s.Offset.Line
genColumn -= s.Offset.Column
return c.source(s.Map, genLine, genColumn)
}
}
return
}
func (c *Consumer) source(
m *sourceMap, genLine, genColumn int,
) (source, name string, line, column int, ok bool) {
if len(m.mappings) == 0 {
return
}
i := sort.Search(len(m.mappings), func(i int) bool {
m := &m.mappings[i]
if int(m.genLine) == genLine {
return int(m.genColumn) >= genColumn
}
return int(m.genLine) >= genLine
})
var match *mapping
// Mapping not found
if i == len(m.mappings) {
// lets see if the line is correct but the column is bigger
match = &m.mappings[i-1]
if int(match.genLine) != genLine {
return
}
} else {
match = &m.mappings[i]
// Fuzzy match.
if int(match.genLine) > genLine || int(match.genColumn) > genColumn {
if i == 0 {
return
}
match = &m.mappings[i-1]
}
}
if match.sourcesInd >= 0 {
source = m.Sources[match.sourcesInd]
}
if match.namesInd >= 0 {
name = m.name(int(match.namesInd))
}
line = int(match.sourceLine)
column = int(match.sourceColumn)
ok = true
return
}
// SourceContent returns the original source content for the source.
func (c *Consumer) SourceContent(source string) string {
for i := range c.sections {
s := &c.sections[i]
for i, src := range s.Map.Sources {
if src == source {
if i < len(s.Map.SourcesContent) {
return s.Map.SourcesContent[i]
}
break
}
}
}
return ""
}
func checkVersion(version int) error {
if version == 3 || version == 0 {
return nil
}
return fmt.Errorf(
"sourcemap: got version=%d, but only 3rd version is supported",
version,
)
}
func reverse(ss []section) {
last := len(ss) - 1
for i := 0; i < len(ss)/2; i++ {
ss[i], ss[last-i] = ss[last-i], ss[i]
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mirrors_go-sourcemap/sourcemap.git
git@gitee.com:mirrors_go-sourcemap/sourcemap.git
mirrors_go-sourcemap
sourcemap
sourcemap
v2.1.4

搜索帮助