Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80620 views
1
/* -*- Mode: js; js-indent-level: 2; -*- */
2
/*
3
* Copyright 2011 Mozilla Foundation and contributors
4
* Licensed under the New BSD license. See LICENSE or:
5
* http://opensource.org/licenses/BSD-3-Clause
6
*/
7
if (typeof define !== 'function') {
8
var define = require('amdefine')(module, require);
9
}
10
define(function (require, exports, module) {
11
12
var util = require('./util');
13
14
function SourceMapConsumer(aSourceMap) {
15
var sourceMap = aSourceMap;
16
if (typeof aSourceMap === 'string') {
17
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
18
}
19
20
// We do late requires because the subclasses require() this file.
21
if (sourceMap.sections != null) {
22
var indexedSourceMapConsumer = require('./indexed-source-map-consumer');
23
return new indexedSourceMapConsumer.IndexedSourceMapConsumer(sourceMap);
24
} else {
25
var basicSourceMapConsumer = require('./basic-source-map-consumer');
26
return new basicSourceMapConsumer.BasicSourceMapConsumer(sourceMap);
27
}
28
}
29
30
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
31
var basicSourceMapConsumer = require('./basic-source-map-consumer');
32
return basicSourceMapConsumer.BasicSourceMapConsumer
33
.fromSourceMap(aSourceMap);
34
}
35
36
/**
37
* The version of the source mapping spec that we are consuming.
38
*/
39
SourceMapConsumer.prototype._version = 3;
40
41
42
// `__generatedMappings` and `__originalMappings` are arrays that hold the
43
// parsed mapping coordinates from the source map's "mappings" attribute. They
44
// are lazily instantiated, accessed via the `_generatedMappings` and
45
// `_originalMappings` getters respectively, and we only parse the mappings
46
// and create these arrays once queried for a source location. We jump through
47
// these hoops because there can be many thousands of mappings, and parsing
48
// them is expensive, so we only want to do it if we must.
49
//
50
// Each object in the arrays is of the form:
51
//
52
// {
53
// generatedLine: The line number in the generated code,
54
// generatedColumn: The column number in the generated code,
55
// source: The path to the original source file that generated this
56
// chunk of code,
57
// originalLine: The line number in the original source that
58
// corresponds to this chunk of generated code,
59
// originalColumn: The column number in the original source that
60
// corresponds to this chunk of generated code,
61
// name: The name of the original symbol which generated this chunk of
62
// code.
63
// }
64
//
65
// All properties except for `generatedLine` and `generatedColumn` can be
66
// `null`.
67
//
68
// `_generatedMappings` is ordered by the generated positions.
69
//
70
// `_originalMappings` is ordered by the original positions.
71
72
SourceMapConsumer.prototype.__generatedMappings = null;
73
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
74
get: function () {
75
if (!this.__generatedMappings) {
76
this.__generatedMappings = [];
77
this.__originalMappings = [];
78
this._parseMappings(this._mappings, this.sourceRoot);
79
}
80
81
return this.__generatedMappings;
82
}
83
});
84
85
SourceMapConsumer.prototype.__originalMappings = null;
86
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
87
get: function () {
88
if (!this.__originalMappings) {
89
this.__generatedMappings = [];
90
this.__originalMappings = [];
91
this._parseMappings(this._mappings, this.sourceRoot);
92
}
93
94
return this.__originalMappings;
95
}
96
});
97
98
SourceMapConsumer.prototype._nextCharIsMappingSeparator =
99
function SourceMapConsumer_nextCharIsMappingSeparator(aStr) {
100
var c = aStr.charAt(0);
101
return c === ";" || c === ",";
102
};
103
104
/**
105
* Parse the mappings in a string in to a data structure which we can easily
106
* query (the ordered arrays in the `this.__generatedMappings` and
107
* `this.__originalMappings` properties).
108
*/
109
SourceMapConsumer.prototype._parseMappings =
110
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
111
throw new Error("Subclasses must implement _parseMappings");
112
};
113
114
SourceMapConsumer.GENERATED_ORDER = 1;
115
SourceMapConsumer.ORIGINAL_ORDER = 2;
116
117
SourceMapConsumer.LEAST_UPPER_BOUND = 1;
118
SourceMapConsumer.GREATEST_LOWER_BOUND = 2;
119
120
/**
121
* Iterate over each mapping between an original source/line/column and a
122
* generated line/column in this source map.
123
*
124
* @param Function aCallback
125
* The function that is called with each mapping.
126
* @param Object aContext
127
* Optional. If specified, this object will be the value of `this` every
128
* time that `aCallback` is called.
129
* @param aOrder
130
* Either `SourceMapConsumer.GENERATED_ORDER` or
131
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
132
* iterate over the mappings sorted by the generated file's line/column
133
* order or the original's source/line/column order, respectively. Defaults to
134
* `SourceMapConsumer.GENERATED_ORDER`.
135
*/
136
SourceMapConsumer.prototype.eachMapping =
137
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
138
var context = aContext || null;
139
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
140
141
var mappings;
142
switch (order) {
143
case SourceMapConsumer.GENERATED_ORDER:
144
mappings = this._generatedMappings;
145
break;
146
case SourceMapConsumer.ORIGINAL_ORDER:
147
mappings = this._originalMappings;
148
break;
149
default:
150
throw new Error("Unknown order of iteration.");
151
}
152
153
var sourceRoot = this.sourceRoot;
154
mappings.map(function (mapping) {
155
var source = mapping.source;
156
if (source != null && sourceRoot != null) {
157
source = util.join(sourceRoot, source);
158
}
159
return {
160
source: source,
161
generatedLine: mapping.generatedLine,
162
generatedColumn: mapping.generatedColumn,
163
originalLine: mapping.originalLine,
164
originalColumn: mapping.originalColumn,
165
name: mapping.name
166
};
167
}).forEach(aCallback, context);
168
};
169
170
/**
171
* Returns all generated line and column information for the original source
172
* and line provided. The only argument is an object with the following
173
* properties:
174
*
175
* - source: The filename of the original source.
176
* - line: The line number in the original source.
177
*
178
* and an array of objects is returned, each with the following properties:
179
*
180
* - line: The line number in the generated source, or null.
181
* - column: The column number in the generated source, or null.
182
*/
183
SourceMapConsumer.prototype.allGeneratedPositionsFor =
184
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
185
var needle = {
186
source: util.getArg(aArgs, 'source'),
187
originalLine: util.getArg(aArgs, 'line'),
188
originalColumn: 0
189
};
190
191
if (this.sourceRoot != null) {
192
needle.source = util.relative(this.sourceRoot, needle.source);
193
}
194
195
var mappings = [];
196
197
var index = this._findMapping(needle,
198
this._originalMappings,
199
"originalLine",
200
"originalColumn",
201
util.compareByOriginalPositions);
202
if (index >= 0) {
203
var mapping = this._originalMappings[index];
204
205
// Iterate until either we run out of mappings, or we run into
206
// a mapping for a different line. Since mappings are sorted, this is
207
// guaranteed to find all mappings for the line we are interested in.
208
while (mapping && mapping.originalLine === needle.originalLine) {
209
mappings.push({
210
line: util.getArg(mapping, 'generatedLine', null),
211
column: util.getArg(mapping, 'generatedColumn', null),
212
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
213
});
214
215
mapping = this._originalMappings[++index];
216
}
217
}
218
219
return mappings;
220
};
221
222
exports.SourceMapConsumer = SourceMapConsumer;
223
224
});
225
226