1 | /*
|
---|
2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
---|
3 | Author Tobias Koppers @sokra
|
---|
4 | */
|
---|
5 |
|
---|
6 | "use strict";
|
---|
7 |
|
---|
8 | const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(
|
---|
9 | ""
|
---|
10 | );
|
---|
11 |
|
---|
12 | const CONTINUATION_BIT = 0x20;
|
---|
13 |
|
---|
14 | const createMappingsSerializer = options => {
|
---|
15 | const linesOnly = options && options.columns === false;
|
---|
16 | return linesOnly
|
---|
17 | ? createLinesOnlyMappingsSerializer()
|
---|
18 | : createFullMappingsSerializer();
|
---|
19 | };
|
---|
20 |
|
---|
21 | const createFullMappingsSerializer = () => {
|
---|
22 | let currentLine = 1;
|
---|
23 | let currentColumn = 0;
|
---|
24 | let currentSourceIndex = 0;
|
---|
25 | let currentOriginalLine = 1;
|
---|
26 | let currentOriginalColumn = 0;
|
---|
27 | let currentNameIndex = 0;
|
---|
28 | let activeMapping = false;
|
---|
29 | let activeName = false;
|
---|
30 | let initial = true;
|
---|
31 | return (
|
---|
32 | generatedLine,
|
---|
33 | generatedColumn,
|
---|
34 | sourceIndex,
|
---|
35 | originalLine,
|
---|
36 | originalColumn,
|
---|
37 | nameIndex
|
---|
38 | ) => {
|
---|
39 | if (activeMapping && currentLine === generatedLine) {
|
---|
40 | // A mapping is still active
|
---|
41 | if (
|
---|
42 | sourceIndex === currentSourceIndex &&
|
---|
43 | originalLine === currentOriginalLine &&
|
---|
44 | originalColumn === currentOriginalColumn &&
|
---|
45 | !activeName &&
|
---|
46 | nameIndex < 0
|
---|
47 | ) {
|
---|
48 | // avoid repeating the same original mapping
|
---|
49 | return "";
|
---|
50 | }
|
---|
51 | } else {
|
---|
52 | // No mapping is active
|
---|
53 | if (sourceIndex < 0) {
|
---|
54 | // avoid writing unneccessary generated mappings
|
---|
55 | return "";
|
---|
56 | }
|
---|
57 | }
|
---|
58 |
|
---|
59 | let str;
|
---|
60 | if (currentLine < generatedLine) {
|
---|
61 | str = ";".repeat(generatedLine - currentLine);
|
---|
62 | currentLine = generatedLine;
|
---|
63 | currentColumn = 0;
|
---|
64 | initial = false;
|
---|
65 | } else if (initial) {
|
---|
66 | str = "";
|
---|
67 | initial = false;
|
---|
68 | } else {
|
---|
69 | str = ",";
|
---|
70 | }
|
---|
71 |
|
---|
72 | const writeValue = value => {
|
---|
73 | const sign = (value >>> 31) & 1;
|
---|
74 | const mask = value >> 31;
|
---|
75 | const absValue = (value + mask) ^ mask;
|
---|
76 | let data = (absValue << 1) | sign;
|
---|
77 | for (;;) {
|
---|
78 | const sextet = data & 0x1f;
|
---|
79 | data >>= 5;
|
---|
80 | if (data === 0) {
|
---|
81 | str += ALPHABET[sextet];
|
---|
82 | break;
|
---|
83 | } else {
|
---|
84 | str += ALPHABET[sextet | CONTINUATION_BIT];
|
---|
85 | }
|
---|
86 | }
|
---|
87 | };
|
---|
88 | writeValue(generatedColumn - currentColumn);
|
---|
89 | currentColumn = generatedColumn;
|
---|
90 | if (sourceIndex >= 0) {
|
---|
91 | activeMapping = true;
|
---|
92 | if (sourceIndex === currentSourceIndex) {
|
---|
93 | str += "A";
|
---|
94 | } else {
|
---|
95 | writeValue(sourceIndex - currentSourceIndex);
|
---|
96 | currentSourceIndex = sourceIndex;
|
---|
97 | }
|
---|
98 | writeValue(originalLine - currentOriginalLine);
|
---|
99 | currentOriginalLine = originalLine;
|
---|
100 | if (originalColumn === currentOriginalColumn) {
|
---|
101 | str += "A";
|
---|
102 | } else {
|
---|
103 | writeValue(originalColumn - currentOriginalColumn);
|
---|
104 | currentOriginalColumn = originalColumn;
|
---|
105 | }
|
---|
106 | if (nameIndex >= 0) {
|
---|
107 | writeValue(nameIndex - currentNameIndex);
|
---|
108 | currentNameIndex = nameIndex;
|
---|
109 | activeName = true;
|
---|
110 | } else {
|
---|
111 | activeName = false;
|
---|
112 | }
|
---|
113 | } else {
|
---|
114 | activeMapping = false;
|
---|
115 | }
|
---|
116 | return str;
|
---|
117 | };
|
---|
118 | };
|
---|
119 |
|
---|
120 | const createLinesOnlyMappingsSerializer = () => {
|
---|
121 | let lastWrittenLine = 0;
|
---|
122 | let currentLine = 1;
|
---|
123 | let currentSourceIndex = 0;
|
---|
124 | let currentOriginalLine = 1;
|
---|
125 | return (
|
---|
126 | generatedLine,
|
---|
127 | _generatedColumn,
|
---|
128 | sourceIndex,
|
---|
129 | originalLine,
|
---|
130 | _originalColumn,
|
---|
131 | _nameIndex
|
---|
132 | ) => {
|
---|
133 | if (sourceIndex < 0) {
|
---|
134 | // avoid writing generated mappings at all
|
---|
135 | return "";
|
---|
136 | }
|
---|
137 | if (lastWrittenLine === generatedLine) {
|
---|
138 | // avoid writing multiple original mappings per line
|
---|
139 | return "";
|
---|
140 | }
|
---|
141 | let str;
|
---|
142 | const writeValue = value => {
|
---|
143 | const sign = (value >>> 31) & 1;
|
---|
144 | const mask = value >> 31;
|
---|
145 | const absValue = (value + mask) ^ mask;
|
---|
146 | let data = (absValue << 1) | sign;
|
---|
147 | for (;;) {
|
---|
148 | const sextet = data & 0x1f;
|
---|
149 | data >>= 5;
|
---|
150 | if (data === 0) {
|
---|
151 | str += ALPHABET[sextet];
|
---|
152 | break;
|
---|
153 | } else {
|
---|
154 | str += ALPHABET[sextet | CONTINUATION_BIT];
|
---|
155 | }
|
---|
156 | }
|
---|
157 | };
|
---|
158 | lastWrittenLine = generatedLine;
|
---|
159 | if (generatedLine === currentLine + 1) {
|
---|
160 | currentLine = generatedLine;
|
---|
161 | if (sourceIndex === currentSourceIndex) {
|
---|
162 | currentSourceIndex = sourceIndex;
|
---|
163 | if (originalLine === currentOriginalLine + 1) {
|
---|
164 | currentOriginalLine = originalLine;
|
---|
165 | return ";AACA";
|
---|
166 | } else {
|
---|
167 | str = ";AA";
|
---|
168 | writeValue(originalLine - currentOriginalLine);
|
---|
169 | currentOriginalLine = originalLine;
|
---|
170 | return str + "A";
|
---|
171 | }
|
---|
172 | } else {
|
---|
173 | str = ";A";
|
---|
174 | writeValue(sourceIndex - currentSourceIndex);
|
---|
175 | currentSourceIndex = sourceIndex;
|
---|
176 | writeValue(originalLine - currentOriginalLine);
|
---|
177 | currentOriginalLine = originalLine;
|
---|
178 | return str + "A";
|
---|
179 | }
|
---|
180 | } else {
|
---|
181 | str = ";".repeat(generatedLine - currentLine);
|
---|
182 | currentLine = generatedLine;
|
---|
183 | if (sourceIndex === currentSourceIndex) {
|
---|
184 | currentSourceIndex = sourceIndex;
|
---|
185 | if (originalLine === currentOriginalLine + 1) {
|
---|
186 | currentOriginalLine = originalLine;
|
---|
187 | return str + "AACA";
|
---|
188 | } else {
|
---|
189 | str += "AA";
|
---|
190 | writeValue(originalLine - currentOriginalLine);
|
---|
191 | currentOriginalLine = originalLine;
|
---|
192 | return str + "A";
|
---|
193 | }
|
---|
194 | } else {
|
---|
195 | str += "A";
|
---|
196 | writeValue(sourceIndex - currentSourceIndex);
|
---|
197 | currentSourceIndex = sourceIndex;
|
---|
198 | writeValue(originalLine - currentOriginalLine);
|
---|
199 | currentOriginalLine = originalLine;
|
---|
200 | return str + "A";
|
---|
201 | }
|
---|
202 | }
|
---|
203 | };
|
---|
204 | };
|
---|
205 |
|
---|
206 | module.exports = createMappingsSerializer;
|
---|