-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathengine_source_map.go
More file actions
121 lines (112 loc) · 2.41 KB
/
Copy pathengine_source_map.go
File metadata and controls
121 lines (112 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package engine
import (
"bytes"
"encoding/json"
"fmt"
"github.com/ZenLiuCN/fn"
"github.com/dop251/goja"
"github.com/dop251/goja/parser"
"math/rand"
"strings"
)
var (
ColumnMarker = "♦"
)
func (s *Engine) useMapping(b []byte) string {
rnd := fmt.Sprintf("%d.map", rand.Int())
s.Runtime.SetParserOptions(parser.WithSourceMapLoader(func(path string) ([]byte, error) {
if path == rnd {
return b, nil
}
return nil, nil
}))
return "\n//# sourceMappingURL=" + rnd
}
func (s *Engine) freeMapping() {
s.SourceMap = nil
s.Runtime.SetParserOptions([]parser.Option{}...)
}
type SourceMapping map[string]*SourceMap
func (s SourceMapping) register(src *SourceMap) {
for _, source := range src.Sources {
s[source] = src
}
}
func (s SourceMapping) dump(b *bytes.Buffer, stacks []goja.StackFrame) {
for _, stack := range stacks {
loc := stack.Position()
f := stack.SrcName()
if f != "<native>" {
if o, ok := s[f]; ok {
if src := o.Code(f, loc.Line-1, loc.Column); src != "" {
b.WriteString("\n")
b.WriteString(f)
b.WriteString(fmt.Sprintf("[%d:%d]", loc.Line, loc.Column))
b.WriteString("\t")
b.WriteString(src)
continue
}
}
}
b.WriteByte('\n')
stack.Write(b)
}
}
func (s SourceMapping) one() *SourceMap {
for _, sourceMap := range s {
return sourceMap
}
return nil
}
type SourceMap struct {
File string `json:"file"`
SourceRoot string `json:"sourceRoot"`
Sources []string `json:"sources"`
SourcesContent []string `json:"sourcesContent"`
buf [][][]rune
}
func (s *SourceMap) Code(src string, line, col int) string {
n := -1
for i, source := range s.Sources {
if source == src {
n = i
break
}
}
if n < 0 {
return ""
}
if s.buf == nil {
s.buf = make([][][]rune, len(s.Sources))
}
if s.buf[n] == nil {
for _, s2 := range strings.Split(s.SourcesContent[n], "\n") {
s.buf[n] = append(s.buf[n], []rune(s2))
}
}
b := s.buf[n]
if len(b) < line {
return ""
}
l := b[line]
if len(l) < col {
return string(l) + ColumnMarker
}
return string(l[:col]) + ColumnMarker + string(l[col:])
}
func NewSourceMap(bin []byte) (v SourceMapping) {
defer func() {
if r := recover(); r != nil {
fmt.Printf("error on generate source mapping :%#+v", r)
v = nil
}
}()
if len(bin) == 0 {
return
}
var src = new(SourceMap)
fn.Panic(json.Unmarshal(bin, src))
v = make(SourceMapping)
v.register(src)
return
}