metro-source-map 0.54.0 → 0.54.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.54.0",
2
+ "version": "0.54.1",
3
3
  "name": "metro-source-map",
4
4
  "description": "🚇 Source map generator for Metro.",
5
5
  "main": "src/source-map.js",
@@ -19,6 +19,6 @@
19
19
  "license": "MIT",
20
20
  "devDependencies": {
21
21
  "@babel/parser": "^7.0.0",
22
- "metro-symbolicate": "0.54.0"
22
+ "metro-symbolicate": "0.54.1"
23
23
  }
24
24
  }
package/src/Generator.js CHANGED
@@ -226,6 +226,9 @@ class IndexedSet {
226
226
  }
227
227
 
228
228
  items() {
229
+ /* $FlowFixMe(>=0.98.0 site=react_native_fb) This comment suppresses an
230
+ * error found when Flow v0.98 was deployed. To see the error delete this
231
+ * comment and run Flow. */
229
232
  return Array.from(this.map.keys());
230
233
  }
231
234
  }
@@ -212,6 +212,9 @@ class IndexedSet {
212
212
  }
213
213
 
214
214
  items() {
215
+ /* $FlowFixMe(>=0.98.0 site=react_native_fb) This comment suppresses an
216
+ * error found when Flow v0.98 was deployed. To see the error delete this
217
+ * comment and run Flow. */
215
218
  return Array.from(this.map.keys());
216
219
  }
217
220
  }
@@ -16,8 +16,77 @@ function _interopRequireDefault(obj) {
16
16
  return obj && obj.__esModule ? obj : { default: obj };
17
17
  }
18
18
 
19
+ function _slicedToArray(arr, i) {
20
+ return (
21
+ _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest()
22
+ );
23
+ }
24
+
25
+ function _nonIterableRest() {
26
+ throw new TypeError("Invalid attempt to destructure non-iterable instance");
27
+ }
28
+
29
+ function _iterableToArrayLimit(arr, i) {
30
+ var _arr = [];
31
+ var _n = true;
32
+ var _d = false;
33
+ var _e = undefined;
34
+ try {
35
+ for (
36
+ var _i = arr[Symbol.iterator](), _s;
37
+ !(_n = (_s = _i.next()).done);
38
+ _n = true
39
+ ) {
40
+ _arr.push(_s.value);
41
+ if (i && _arr.length === i) break;
42
+ }
43
+ } catch (err) {
44
+ _d = true;
45
+ _e = err;
46
+ } finally {
47
+ try {
48
+ if (!_n && _i["return"] != null) _i["return"]();
49
+ } finally {
50
+ if (_d) throw _e;
51
+ }
52
+ }
53
+ return _arr;
54
+ }
55
+
56
+ function _arrayWithHoles(arr) {
57
+ if (Array.isArray(arr)) return arr;
58
+ }
59
+
60
+ function _toConsumableArray(arr) {
61
+ return (
62
+ _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread()
63
+ );
64
+ }
65
+
66
+ function _nonIterableSpread() {
67
+ throw new TypeError("Invalid attempt to spread non-iterable instance");
68
+ }
69
+
70
+ function _iterableToArray(iter) {
71
+ if (
72
+ Symbol.iterator in Object(iter) ||
73
+ Object.prototype.toString.call(iter) === "[object Arguments]"
74
+ )
75
+ return Array.from(iter);
76
+ }
77
+
78
+ function _arrayWithoutHoles(arr) {
79
+ if (Array.isArray(arr)) {
80
+ for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++)
81
+ arr2[i] = arr[i];
82
+ return arr2;
83
+ }
84
+ }
85
+
19
86
  const B64Builder = require("./B64Builder");
20
87
 
88
+ const fsPath = require("path");
89
+
21
90
  const t = require("@babel/types");
22
91
 
23
92
  /**
@@ -28,9 +97,9 @@ const t = require("@babel/types");
28
97
  * The output is encoded for use in a source map. For details about the format,
29
98
  * see MappingEncoder below.
30
99
  */
31
- function generateFunctionMap(ast) {
100
+ function generateFunctionMap(ast, context) {
32
101
  const encoder = new MappingEncoder();
33
- forEachMapping(ast, mapping => encoder.push(mapping));
102
+ forEachMapping(ast, context, mapping => encoder.push(mapping));
34
103
  return encoder.getResult();
35
104
  }
36
105
  /**
@@ -40,9 +109,9 @@ function generateFunctionMap(ast) {
40
109
  * Lines are 1-based and columns are 0-based.
41
110
  */
42
111
 
43
- function generateFunctionMappingsArray(ast) {
112
+ function generateFunctionMappingsArray(ast, context) {
44
113
  const mappings = [];
45
- forEachMapping(ast, mapping => {
114
+ forEachMapping(ast, context, mapping => {
46
115
  mappings.push(mapping);
47
116
  });
48
117
  return mappings;
@@ -52,7 +121,7 @@ function generateFunctionMappingsArray(ast) {
52
121
  * mappings, one at a time.
53
122
  */
54
123
 
55
- function forEachMapping(ast, pushMapping) {
124
+ function forEachMapping(ast, context, pushMapping) {
56
125
  const nameStack = [];
57
126
  let tailPos = {
58
127
  line: 1,
@@ -97,10 +166,23 @@ function forEachMapping(ast, pushMapping) {
97
166
  }
98
167
  }
99
168
 
169
+ if (!context) {
170
+ context = {};
171
+ }
172
+
173
+ const basename = context.filename
174
+ ? fsPath.basename(context.filename).replace(/\..+$/, "")
175
+ : null;
100
176
  (0, _traverse.default)(ast, {
101
177
  "Function|Program": {
102
178
  enter(path) {
103
- pushFrame(getNameForPath(path), path.node.loc);
179
+ let name = getNameForPath(path);
180
+
181
+ if (basename) {
182
+ name = removeNamePrefix(name, basename);
183
+ }
184
+
185
+ pushFrame(name, path.node.loc);
104
186
  },
105
187
 
106
188
  exit(path) {
@@ -111,6 +193,7 @@ function forEachMapping(ast, pushMapping) {
111
193
  }
112
194
 
113
195
  const ANONYMOUS_NAME = "<anonymous>";
196
+ const CALLEES_TO_SKIP = ["Object.freeze"];
114
197
  /**
115
198
  * Derive a contextual name for the given AST node (Function, Program, Class or
116
199
  * ObjectExpression).
@@ -137,7 +220,7 @@ function getNameForPath(path) {
137
220
  if (t.isObjectMethod(node) || t.isClassMethod(node)) {
138
221
  id = node.key;
139
222
 
140
- if (node.kind !== "method") {
223
+ if (node.kind !== "method" && node.kind !== "constructor") {
141
224
  kind = node.kind;
142
225
  }
143
226
 
@@ -174,12 +257,16 @@ function getNameForPath(path) {
174
257
  let name = getNameFromId(id);
175
258
 
176
259
  if (name == null) {
177
- if (t.isCallExpression(parent)) {
260
+ if (t.isCallExpression(parent) || t.isNewExpression(parent)) {
178
261
  // foo(function () {})
179
262
  const argIndex = parent.arguments.indexOf(node);
180
263
 
181
264
  if (argIndex !== -1) {
182
- const calleeName = getNameFromId(parent.callee);
265
+ const calleeName = getNameFromId(parent.callee); // var f = Object.freeze(function () {})
266
+
267
+ if (CALLEES_TO_SKIP.indexOf(calleeName) !== -1) {
268
+ return getNameForPath(parentPath);
269
+ }
183
270
 
184
271
  if (calleeName) {
185
272
  return `${calleeName}$argument_${argIndex}`;
@@ -223,12 +310,38 @@ function isAnyIdentifier(node) {
223
310
  }
224
311
 
225
312
  function getNameFromId(id) {
226
- if (!id) {
313
+ const parts = getNamePartsFromId(id);
314
+
315
+ if (!parts.length) {
227
316
  return null;
228
317
  }
229
318
 
230
- if (t.isCallExpression(id)) {
231
- return getNameFromId(id.callee);
319
+ if (parts.length > 5) {
320
+ return (
321
+ parts[0] +
322
+ "." +
323
+ parts[1] +
324
+ "..." +
325
+ parts[parts.length - 2] +
326
+ "." +
327
+ parts[parts.length - 1]
328
+ );
329
+ }
330
+
331
+ return parts.join(".");
332
+ }
333
+
334
+ function getNamePartsFromId(id) {
335
+ if (!id) {
336
+ return [];
337
+ }
338
+
339
+ if (t.isCallExpression(id) || t.isNewExpression(id)) {
340
+ return getNamePartsFromId(id.callee);
341
+ }
342
+
343
+ if (t.isTypeCastExpression(id)) {
344
+ return getNamePartsFromId(id.expression);
232
345
  }
233
346
 
234
347
  let name;
@@ -246,7 +359,7 @@ function getNameFromId(id) {
246
359
  }
247
360
 
248
361
  if (name != null) {
249
- return t.toBindingIdentifierName(name);
362
+ return [t.toBindingIdentifierName(name)];
250
363
  }
251
364
 
252
365
  if (t.isImport(id)) {
@@ -254,7 +367,7 @@ function getNameFromId(id) {
254
367
  }
255
368
 
256
369
  if (name != null) {
257
- return name;
370
+ return [name];
258
371
  }
259
372
 
260
373
  if (isAnyMemberExpression(id)) {
@@ -269,20 +382,47 @@ function getNameFromId(id) {
269
382
  name = "@@" + propertyName;
270
383
  }
271
384
  } else {
272
- const propertyName = getNameFromId(id.property);
385
+ const propertyName = getNamePartsFromId(id.property);
273
386
 
274
- if (propertyName) {
275
- const objectName = getNameFromId(id.object);
387
+ if (propertyName.length) {
388
+ const objectName = getNamePartsFromId(id.object);
276
389
 
277
- if (objectName) {
278
- name = `${objectName}.${propertyName}`;
390
+ if (objectName.length) {
391
+ return _toConsumableArray(objectName).concat(
392
+ _toConsumableArray(propertyName)
393
+ );
279
394
  } else {
280
- name = propertyName;
395
+ return propertyName;
281
396
  }
282
397
  }
283
398
  }
284
399
  }
285
400
 
401
+ return name ? [name] : [];
402
+ }
403
+
404
+ const DELIMITER_START_RE = /^[^A-Za-z0-9_$@]+/;
405
+ /**
406
+ * Strip the given prefix from `name`, if it occurs there, plus any delimiter
407
+ * characters that follow (of which at least one is required). If an empty
408
+ * string would be returned, return the original name instead.
409
+ */
410
+
411
+ function removeNamePrefix(name, namePrefix) {
412
+ if (!namePrefix.length || !name.startsWith(namePrefix)) {
413
+ return name;
414
+ }
415
+
416
+ const shortenedName = name.substr(namePrefix.length);
417
+
418
+ const _ref = shortenedName.match(DELIMITER_START_RE) || [],
419
+ _ref2 = _slicedToArray(_ref, 1),
420
+ delimiterMatch = _ref2[0];
421
+
422
+ if (delimiterMatch) {
423
+ return shortenedName.substr(delimiterMatch.length) || name;
424
+ }
425
+
286
426
  return name;
287
427
  }
288
428
  /**
@@ -327,9 +467,9 @@ class MappingEncoder {
327
467
  };
328
468
  }
329
469
 
330
- push(_ref) {
331
- let name = _ref.name,
332
- start = _ref.start;
470
+ push(_ref3) {
471
+ let name = _ref3.name,
472
+ start = _ref3.start;
333
473
 
334
474
  let nameIndex = this._namesMap.get(name);
335
475
 
@@ -12,6 +12,7 @@
12
12
 
13
13
  const B64Builder = require('./B64Builder');
14
14
 
15
+ const fsPath = require('path');
15
16
  const t = require('@babel/types');
16
17
 
17
18
  import type {FBSourceFunctionMap} from './source-map';
@@ -20,6 +21,7 @@ import traverse from '@babel/traverse';
20
21
  import type {Path} from '@babel/traverse';
21
22
  type Position = {line: number, column: number};
22
23
  type RangeMapping = {name: string, start: Position};
24
+ type Context = {filename?: string};
23
25
 
24
26
  /**
25
27
  * Generate a map of source positions to function names. The names are meant to
@@ -29,9 +31,9 @@ type RangeMapping = {name: string, start: Position};
29
31
  * The output is encoded for use in a source map. For details about the format,
30
32
  * see MappingEncoder below.
31
33
  */
32
- function generateFunctionMap(ast: Ast): FBSourceFunctionMap {
34
+ function generateFunctionMap(ast: Ast, context?: Context): FBSourceFunctionMap {
33
35
  const encoder = new MappingEncoder();
34
- forEachMapping(ast, mapping => encoder.push(mapping));
36
+ forEachMapping(ast, context, mapping => encoder.push(mapping));
35
37
  return encoder.getResult();
36
38
  }
37
39
 
@@ -41,9 +43,12 @@ function generateFunctionMap(ast: Ast): FBSourceFunctionMap {
41
43
  *
42
44
  * Lines are 1-based and columns are 0-based.
43
45
  */
44
- function generateFunctionMappingsArray(ast: Ast): $ReadOnlyArray<RangeMapping> {
46
+ function generateFunctionMappingsArray(
47
+ ast: Ast,
48
+ context?: Context,
49
+ ): $ReadOnlyArray<RangeMapping> {
45
50
  const mappings = [];
46
- forEachMapping(ast, mapping => {
51
+ forEachMapping(ast, context, mapping => {
47
52
  mappings.push(mapping);
48
53
  });
49
54
  return mappings;
@@ -53,7 +58,11 @@ function generateFunctionMappingsArray(ast: Ast): $ReadOnlyArray<RangeMapping> {
53
58
  * Traverses a Babel AST and calls the supplied callback with function name
54
59
  * mappings, one at a time.
55
60
  */
56
- function forEachMapping(ast: Ast, pushMapping: RangeMapping => void) {
61
+ function forEachMapping(
62
+ ast: Ast,
63
+ context: ?Context,
64
+ pushMapping: RangeMapping => void,
65
+ ) {
57
66
  const nameStack = [];
58
67
  let tailPos = {line: 1, column: 0};
59
68
  let tailName = null;
@@ -86,10 +95,22 @@ function forEachMapping(ast: Ast, pushMapping: RangeMapping => void) {
86
95
  }
87
96
  }
88
97
 
98
+ if (!context) {
99
+ context = {};
100
+ }
101
+
102
+ const basename = context.filename
103
+ ? fsPath.basename(context.filename).replace(/\..+$/, '')
104
+ : null;
105
+
89
106
  traverse(ast, {
90
107
  'Function|Program': {
91
108
  enter(path) {
92
- pushFrame(getNameForPath(path), path.node.loc);
109
+ let name = getNameForPath(path);
110
+ if (basename) {
111
+ name = removeNamePrefix(name, basename);
112
+ }
113
+ pushFrame(name, path.node.loc);
93
114
  },
94
115
  exit(path) {
95
116
  popFrame();
@@ -99,6 +120,7 @@ function forEachMapping(ast: Ast, pushMapping: RangeMapping => void) {
99
120
  }
100
121
 
101
122
  const ANONYMOUS_NAME = '<anonymous>';
123
+ const CALLEES_TO_SKIP = ['Object.freeze'];
102
124
 
103
125
  /**
104
126
  * Derive a contextual name for the given AST node (Function, Program, Class or
@@ -118,7 +140,7 @@ function getNameForPath(path: Path): string {
118
140
  let kind = '';
119
141
  if (t.isObjectMethod(node) || t.isClassMethod(node)) {
120
142
  id = node.key;
121
- if (node.kind !== 'method') {
143
+ if (node.kind !== 'method' && node.kind !== 'constructor') {
122
144
  kind = node.kind;
123
145
  }
124
146
  propertyPath = path;
@@ -154,11 +176,15 @@ function getNameForPath(path: Path): string {
154
176
  let name = getNameFromId(id);
155
177
 
156
178
  if (name == null) {
157
- if (t.isCallExpression(parent)) {
179
+ if (t.isCallExpression(parent) || t.isNewExpression(parent)) {
158
180
  // foo(function () {})
159
181
  const argIndex = parent.arguments.indexOf(node);
160
182
  if (argIndex !== -1) {
161
183
  const calleeName = getNameFromId(parent.callee);
184
+ // var f = Object.freeze(function () {})
185
+ if (CALLEES_TO_SKIP.indexOf(calleeName) !== -1) {
186
+ return getNameForPath(parentPath);
187
+ }
162
188
  if (calleeName) {
163
189
  return `${calleeName}$argument_${argIndex}`;
164
190
  }
@@ -198,12 +224,36 @@ function isAnyIdentifier(node: Ast): boolean {
198
224
  }
199
225
 
200
226
  function getNameFromId(id: Ast): ?string {
201
- if (!id) {
227
+ const parts = getNamePartsFromId(id);
228
+
229
+ if (!parts.length) {
202
230
  return null;
203
231
  }
232
+ if (parts.length > 5) {
233
+ return (
234
+ parts[0] +
235
+ '.' +
236
+ parts[1] +
237
+ '...' +
238
+ parts[parts.length - 2] +
239
+ '.' +
240
+ parts[parts.length - 1]
241
+ );
242
+ }
243
+ return parts.join('.');
244
+ }
245
+
246
+ function getNamePartsFromId(id: Ast): $ReadOnlyArray<string> {
247
+ if (!id) {
248
+ return [];
249
+ }
250
+
251
+ if (t.isCallExpression(id) || t.isNewExpression(id)) {
252
+ return getNamePartsFromId(id.callee);
253
+ }
204
254
 
205
- if (t.isCallExpression(id)) {
206
- return getNameFromId(id.callee);
255
+ if (t.isTypeCastExpression(id)) {
256
+ return getNamePartsFromId(id.expression);
207
257
  }
208
258
 
209
259
  let name;
@@ -221,7 +271,7 @@ function getNameFromId(id: Ast): ?string {
221
271
  }
222
272
 
223
273
  if (name != null) {
224
- return t.toBindingIdentifierName(name);
274
+ return [t.toBindingIdentifierName(name)];
225
275
  }
226
276
 
227
277
  if (t.isImport(id)) {
@@ -229,7 +279,7 @@ function getNameFromId(id: Ast): ?string {
229
279
  }
230
280
 
231
281
  if (name != null) {
232
- return name;
282
+ return [name];
233
283
  }
234
284
 
235
285
  if (isAnyMemberExpression(id)) {
@@ -243,18 +293,39 @@ function getNameFromId(id: Ast): ?string {
243
293
  name = '@@' + propertyName;
244
294
  }
245
295
  } else {
246
- const propertyName = getNameFromId(id.property);
247
- if (propertyName) {
248
- const objectName = getNameFromId(id.object);
249
- if (objectName) {
250
- name = `${objectName}.${propertyName}`;
296
+ const propertyName = getNamePartsFromId(id.property);
297
+ if (propertyName.length) {
298
+ const objectName = getNamePartsFromId(id.object);
299
+ if (objectName.length) {
300
+ return [...objectName, ...propertyName];
251
301
  } else {
252
- name = propertyName;
302
+ return propertyName;
253
303
  }
254
304
  }
255
305
  }
256
306
  }
257
307
 
308
+ return name ? [name] : [];
309
+ }
310
+
311
+ const DELIMITER_START_RE = /^[^A-Za-z0-9_$@]+/;
312
+
313
+ /**
314
+ * Strip the given prefix from `name`, if it occurs there, plus any delimiter
315
+ * characters that follow (of which at least one is required). If an empty
316
+ * string would be returned, return the original name instead.
317
+ */
318
+ function removeNamePrefix(name: string, namePrefix: string): string {
319
+ if (!namePrefix.length || !name.startsWith(namePrefix)) {
320
+ return name;
321
+ }
322
+
323
+ const shortenedName = name.substr(namePrefix.length);
324
+ const [delimiterMatch] = shortenedName.match(DELIMITER_START_RE) || [];
325
+ if (delimiterMatch) {
326
+ return shortenedName.substr(delimiterMatch.length) || name;
327
+ }
328
+
258
329
  return name;
259
330
  }
260
331
 
package/src/source-map.js CHANGED
@@ -17,6 +17,9 @@ const _require = require("./BundleBuilder"),
17
17
  createIndexMap = _require.createIndexMap,
18
18
  BundleBuilder = _require.BundleBuilder;
19
19
 
20
+ const _require2 = require("./generateFunctionMap"),
21
+ generateFunctionMap = _require2.generateFunctionMap;
22
+
20
23
  /**
21
24
  * Creates a source map from modules with "raw mappings", i.e. an array of
22
25
  * tuples with either 2, 4, or 5 elements:
@@ -132,6 +135,7 @@ function countLines(string) {
132
135
  module.exports = {
133
136
  BundleBuilder,
134
137
  createIndexMap,
138
+ generateFunctionMap,
135
139
  fromRawMappings,
136
140
  toBabelSegments,
137
141
  toSegmentTuple
@@ -14,6 +14,7 @@ const Generator = require('./Generator');
14
14
  const SourceMap = require('source-map');
15
15
 
16
16
  const {createIndexMap, BundleBuilder} = require('./BundleBuilder');
17
+ const {generateFunctionMap} = require('./generateFunctionMap');
17
18
 
18
19
  import type {BabelSourceMap} from '@babel/core';
19
20
  import type {BabelSourceMapSegment} from '@babel/generator';
@@ -33,7 +34,7 @@ type FBExtensions = {
33
34
  x_facebook_sources?: FBSourcesArray,
34
35
  };
35
36
 
36
- export type FBSourcesArray = $ReadOnlyArray<FBSourceMetadata>;
37
+ export type FBSourcesArray = $ReadOnlyArray<?FBSourceMetadata>;
37
38
  export type FBSourceMetadata = [?FBSourceFunctionMap];
38
39
  export type FBSourceFunctionMap = {|
39
40
  +names: $ReadOnlyArray<string>,
@@ -181,6 +182,7 @@ function countLines(string) {
181
182
  module.exports = {
182
183
  BundleBuilder,
183
184
  createIndexMap,
185
+ generateFunctionMap,
184
186
  fromRawMappings,
185
187
  toBabelSegments,
186
188
  toSegmentTuple,