v2 / vlib / v / gen / js / sourcemap / mappings.v
171 lines · 150 sloc · 4.51 KB · acf6b344f733169ec6ecc9881f8a8c2c795b9883
Raw
1module sourcemap
2
3import v.gen.js.sourcemap.vlq
4import io
5
6struct Empty {}
7
8pub struct SourcePosition {
9 source_line u32
10 source_column u32
11}
12
13type IndexNumber = u32
14type SourcePositionType = Empty | SourcePosition
15type NameIndexType = Empty | IndexNumber
16
17struct GenPosition {
18 gen_line u32
19 gen_column u32
20}
21
22struct MappingInput {
23 GenPosition
24 name string
25 source_position SourcePositionType
26}
27
28struct Mapping {
29 GenPosition
30 sources_ind u32
31 names_ind NameIndexType
32 source_position SourcePositionType
33}
34
35struct Mappings {
36mut:
37 is_sorted bool
38 last Mapping
39 values []Mapping
40}
41
42fn new_mappings() Mappings {
43 return Mappings{
44 last: Mapping{
45 GenPosition: GenPosition{
46 gen_column: 0
47 gen_line: 0
48 }
49 }
50 is_sorted: true
51 }
52}
53
54// Add the given source mapping
55fn (mut m Mappings) add_mapping(gen_line u32, gen_column u32, sources_ind u32, source_position SourcePositionType,
56 names_ind NameIndexType) {
57 if !(gen_line > m.last.gen_line
58 || (gen_line == m.last.gen_line && gen_column >= m.last.gen_column)) {
59 m.is_sorted = false
60 }
61 m.values << Mapping{
62 GenPosition: GenPosition{
63 gen_line: gen_line
64 gen_column: gen_column
65 }
66 sources_ind: sources_ind
67 names_ind: names_ind
68 source_position: source_position
69 }
70}
71
72// Returns the flat, sorted array of mappings. The mappings are sorted by generated position.
73
74fn (mut m Mappings) get_sorted_array() []Mapping {
75 if !m.is_sorted {
76 panic('not implemented')
77 }
78 return m.values
79}
80
81fn (mut m Mappings) export_mappings(mut output io.Writer) ! {
82 mut previous_generated_line := u32(1)
83 mut previous_generated_column := u32(0)
84 mut previous_source_index := i64(0)
85 mut previous_source_line := i64(0)
86 mut previous_source_column := i64(0)
87 mut previous_name_index := i64(0)
88
89 line_mappings := m.get_sorted_array()
90 len := line_mappings.len
91 for i := 0; i < len; i++ {
92 mapping := line_mappings[i]
93
94 cloned_generated_line := mapping.gen_line
95 if cloned_generated_line > 0 {
96 // Write a ';' for each line between this and last line, way more efficient than storing empty lines or looping...
97 output.write(';'.repeat(int(cloned_generated_line - previous_generated_line)).bytes()) or {
98 panic('Writing vql failed!')
99 }
100 }
101 if cloned_generated_line != previous_generated_line {
102 previous_generated_column = 0
103 previous_generated_line = cloned_generated_line
104 } else {
105 if i > 0 {
106 if !compare_by_generated_positions_inflated(mapping, line_mappings[i - 1]) {
107 continue
108 }
109 output.write(','.bytes()) or { panic('Writing vql failed!') }
110 }
111 }
112
113 vlq.encode(i64(mapping.gen_column - previous_generated_column), mut &output)!
114 previous_generated_column = mapping.gen_column
115 match mapping.source_position {
116 Empty {}
117 SourcePosition {
118 vlq.encode(i64(mapping.sources_ind - previous_source_index), mut &output)!
119 previous_source_index = mapping.sources_ind
120 // lines are stored 0-based in SourceMap spec version 3
121 vlq.encode(i64(mapping.source_position.source_line - 1 - previous_source_line), mut
122 output)!
123 previous_source_line = mapping.source_position.source_line - 1
124 vlq.encode(i64(mapping.source_position.source_column - previous_source_column), mut
125 output)!
126 previous_source_column = mapping.source_position.source_column
127
128 match mapping.names_ind {
129 Empty {}
130 IndexNumber {
131 vlq.encode(i64(mapping.names_ind - previous_name_index), mut &output)!
132 previous_name_index = mapping.names_ind
133 }
134 }
135 }
136 }
137 }
138}
139
140fn compare_by_generated_positions_inflated(mapping_a Mapping, mapping_b Mapping) bool {
141 if mapping_a.gen_line != mapping_b.gen_line {
142 return true
143 }
144 if mapping_a.gen_column != mapping_b.gen_column {
145 return true
146 }
147
148 if mapping_a.sources_ind != mapping_b.sources_ind {
149 return true
150 }
151
152 if mapping_a.source_position.type_name() == mapping_b.source_position.type_name()
153 && mapping_a.source_position is SourcePosition
154 && mapping_b.source_position is SourcePosition {
155 if mapping_a.source_position.source_line != mapping_b.source_position.source_line
156 || mapping_a.source_position.source_column != mapping_b.source_position.source_column {
157 return true
158 }
159 } else {
160 if mapping_a.source_position.type_name() != mapping_b.source_position.type_name() {
161 return true
162 }
163 }
164
165 if mapping_a.names_ind.type_name() == mapping_b.names_ind.type_name()
166 && mapping_a.names_ind is IndexNumber && mapping_b.names_ind is IndexNumber {
167 return mapping_a.names_ind != mapping_b.names_ind
168 } else {
169 return mapping_a.names_ind.type_name() != mapping_b.names_ind.type_name()
170 }
171}
172