flow-remove-types 2.174.1 → 2.176.0

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.
Files changed (2) hide show
  1. package/index.js +61 -42
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -148,6 +148,8 @@ function resultPrinter(options, source, removedNodes) {
148
148
 
149
149
  var LINE_RX = /(\r\n?|\n|\u2028|\u2029)/;
150
150
 
151
+ var THIS_PARAM_MARKER = '__THIS_PARAM_MARKER__';
152
+
151
153
  // A collection of methods for each AST type names which contain Flow types to
152
154
  // be removed.
153
155
  var removeFlowVisitor = {
@@ -171,9 +173,14 @@ var removeFlowVisitor = {
171
173
  ClassExpression: removeImplementedInterfaces,
172
174
 
173
175
  Identifier: function (context, node, ast) {
176
+ if (node[THIS_PARAM_MARKER] === true) {
177
+ removeNode(context, node);
178
+ removeTrailingCommaNode(context, node);
179
+ return false;
180
+ }
174
181
  if (node.optional) {
175
182
  // Find the optional token.
176
- var idx = findTokenIndex(ast.tokens, startOf(node));
183
+ var idx = findTokenIndexAtStartOfNode(ast.tokens, node);
177
184
  do {
178
185
  idx++;
179
186
  } while (getLabel(ast.tokens[idx]) !== '?');
@@ -183,16 +190,22 @@ var removeFlowVisitor = {
183
190
 
184
191
  FunctionDeclaration: function (context, node) {
185
192
  if (node.params && node.params.length) {
186
- if (node.params[0].name === 'this') {
187
- return removeNode(context, node.params[0], undefined, node.params[1]);
193
+ if (
194
+ node.params[0].type === 'Identifier' &&
195
+ node.params[0].name === 'this'
196
+ ) {
197
+ node.params[0][THIS_PARAM_MARKER] = true;
188
198
  }
189
199
  }
190
200
  },
191
201
 
192
202
  FunctionExpression: function (context, node) {
193
203
  if (node.params && node.params.length) {
194
- if (node.params[0].name === 'this') {
195
- return removeNode(context, node.params[0], undefined, node.params[1]);
204
+ if (
205
+ node.params[0].type === 'Identifier' &&
206
+ node.params[0].name === 'this'
207
+ ) {
208
+ node.params[0][THIS_PARAM_MARKER] = true;
196
209
  }
197
210
  }
198
211
  },
@@ -223,7 +236,7 @@ var removeFlowVisitor = {
223
236
  var ast = context.ast;
224
237
 
225
238
  // Flow quirk: Remove importKind which is outside the node
226
- var idxStart = findTokenIndex(ast.tokens, startOf(node));
239
+ var idxStart = findTokenIndexAtStartOfNode(ast.tokens, node);
227
240
  var maybeImportKind = ast.tokens[idxStart - 1];
228
241
  var maybeImportKindLabel = getLabel(maybeImportKind);
229
242
  if (
@@ -233,19 +246,8 @@ var removeFlowVisitor = {
233
246
  removeNode(context, maybeImportKind);
234
247
  }
235
248
 
236
- // Remove the node itself
237
249
  removeNode(context, node);
238
-
239
- // Remove trailing comma
240
- var idx = findTokenIndex(ast.tokens, endOf(node));
241
-
242
- while (isComment(ast.tokens[idx])) {
243
- // NOTE: ast.tokens has no comments in Flow
244
- idx++;
245
- }
246
- if (getLabel(ast.tokens[idx]) === ',') {
247
- removeNode(context, ast.tokens[idx]);
248
- }
250
+ removeTrailingCommaNode(context, node);
249
251
  return false;
250
252
  }
251
253
  },
@@ -264,12 +266,12 @@ var removeFlowVisitor = {
264
266
  var returnType = node.returnType;
265
267
  if (returnType) {
266
268
  var ast = context.ast;
267
- var paramEndIdx = findTokenIndex(ast.tokens, startOf(returnType));
269
+ var paramEndIdx = findTokenIndexAtStartOfNode(ast.tokens, returnType);
268
270
  do {
269
271
  paramEndIdx--;
270
272
  } while (isComment(ast.tokens[paramEndIdx]));
271
273
 
272
- var arrowIdx = findTokenIndex(ast.tokens, endOf(returnType));
274
+ var arrowIdx = findTokenIndexAtEndOfNode(ast.tokens, returnType);
273
275
  while (getLabel(ast.tokens[arrowIdx]) !== '=>') {
274
276
  arrowIdx++;
275
277
  }
@@ -302,12 +304,12 @@ function removeImplementedInterfaces(context, node, ast) {
302
304
  if (node.implements && node.implements.length > 0) {
303
305
  var first = node.implements[0];
304
306
  var last = node.implements[node.implements.length - 1];
305
- var idx = findTokenIndex(ast.tokens, startOf(first));
307
+ var idx = findTokenIndexAtStartOfNode(ast.tokens, first);
306
308
  do {
307
309
  idx--;
308
310
  } while (ast.tokens[idx].value !== 'implements');
309
311
 
310
- var lastIdx = findTokenIndex(ast.tokens, startOf(last));
312
+ var lastIdx = findTokenIndexAtStartOfNode(ast.tokens, last);
311
313
  do {
312
314
  if (!isComment(ast.tokens[idx])) {
313
315
  // NOTE: ast.tokens has no comments in Flow
@@ -319,7 +321,7 @@ function removeImplementedInterfaces(context, node, ast) {
319
321
 
320
322
  // Append node to the list of removed nodes, ensuring the order of the nodes
321
323
  // in the list.
322
- function removeNode(context, node, _ast, nextInList) {
324
+ function removeNode(context, node) {
323
325
  var removedNodes = context.removedNodes;
324
326
  var length = removedNodes.length;
325
327
  var index = length;
@@ -327,16 +329,6 @@ function removeNode(context, node, _ast, nextInList) {
327
329
  // Check for line's leading and trailing space to be removed.
328
330
  var spaceNode = context.pretty ? getLeadingSpaceNode(context, node) : null;
329
331
  var lineNode = context.pretty ? getTrailingLineNode(context, node) : null;
330
- var commaNode = nextInList
331
- ? createNode({
332
- start: endOf(node),
333
- end: startOf(nextInList),
334
- loc: {
335
- start: endOf(node),
336
- end: startOf(nextInList),
337
- },
338
- })
339
- : null;
340
332
 
341
333
  while (index > 0 && endOf(removedNodes[index - 1]) > startOf(node)) {
342
334
  index--;
@@ -350,9 +342,6 @@ function removeNode(context, node, _ast, nextInList) {
350
342
  if (lineNode) {
351
343
  removedNodes.push(lineNode);
352
344
  }
353
- if (commaNode) {
354
- removedNodes.push(commaNode);
355
- }
356
345
  } else {
357
346
  if (lineNode) {
358
347
  if (spaceNode) {
@@ -379,6 +368,22 @@ function removeNodeIfNotCommentType(context, node) {
379
368
  return removeNode(context, node);
380
369
  }
381
370
 
371
+ function removeTrailingCommaNode(context, node) {
372
+ var ast = context.ast;
373
+
374
+ // Remove trailing comma (potentially the next node)
375
+ var idx = findTokenIndexAtEndOfNode(ast.tokens, node) + 1;
376
+
377
+ while (isComment(ast.tokens[idx])) {
378
+ // NOTE: ast.tokens has no comments in Flow
379
+ idx++;
380
+ }
381
+ if (getLabel(ast.tokens[idx]) === ',') {
382
+ removeNode(context, ast.tokens[idx]);
383
+ }
384
+ return false;
385
+ }
386
+
382
387
  function getPragmaNode(context, start, size) {
383
388
  var source = context.source;
384
389
  var line = 1;
@@ -463,7 +468,7 @@ function getSpliceNodeAtPos(context, pos, loc, value) {
463
468
  // Returns true if node is the last to be removed from a line.
464
469
  function isLastNodeRemovedFromLine(context, node) {
465
470
  var tokens = context.ast.tokens;
466
- var priorTokenIdx = findTokenIndex(tokens, startOf(node)) - 1;
471
+ var priorTokenIdx = findTokenIndexAtStartOfNode(tokens, node) - 1;
467
472
  var token = tokens[priorTokenIdx];
468
473
  var line = node.loc.end.line;
469
474
 
@@ -500,7 +505,7 @@ function isRemovedToken(context, token) {
500
505
 
501
506
  // Iterate through the tokens contained by the removed node to find a match.
502
507
  var tokens = context.ast.tokens;
503
- var tokenIdx = findTokenIndex(tokens, startOf(node));
508
+ var tokenIdx = findTokenIndexAtStartOfNode(tokens, node);
504
509
  while (endOf(tokens[tokenIdx]) <= endOf(node)) {
505
510
  if (token === tokens[tokenIdx]) {
506
511
  return true;
@@ -546,16 +551,23 @@ function visit(ast, context, visitor) {
546
551
 
547
552
  // Given an array of sorted tokens, find the index of the token which contains
548
553
  // the given offset. Uses binary search for O(log N) performance.
549
- function findTokenIndex(tokens, offset) {
554
+ function findTokenIndex(tokens, offset, matchBiasParam) {
555
+ // Token ranges often overlap at the edges e.g {start: 0, end: 100}, {start: 100, end: 300}. The
556
+ // `matchBiasParam` param allows a user to specify what to do in this case, defaulting to matching
557
+ // against the start of a token range.
558
+ var matchBias = matchBiasParam === 'end' ? 'end' : 'start';
550
559
  var min = 0;
551
560
  var max = tokens.length - 1;
561
+ var ptr;
552
562
 
553
563
  while (min <= max) {
554
- var ptr = ((min + max) / 2) | 0;
564
+ ptr = ((min + max) / 2) | 0;
555
565
  var token = tokens[ptr];
556
- if (endOf(token) <= offset) {
566
+ var end = endOf(token);
567
+ var start = startOf(token);
568
+ if (end < offset || (matchBias === 'start' && end === offset)) {
557
569
  min = ptr + 1;
558
- } else if (startOf(token) > offset) {
570
+ } else if (start > offset || (matchBias === 'end' && start === offset)) {
559
571
  max = ptr - 1;
560
572
  } else {
561
573
  return ptr;
@@ -565,6 +577,13 @@ function findTokenIndex(tokens, offset) {
565
577
  return ptr;
566
578
  }
567
579
 
580
+ function findTokenIndexAtStartOfNode(tokens, node) {
581
+ return findTokenIndex(tokens, startOf(node), 'start');
582
+ }
583
+ function findTokenIndexAtEndOfNode(tokens, node) {
584
+ return findTokenIndex(tokens, endOf(node), 'end');
585
+ }
586
+
568
587
  // True if the provided token is a comment.
569
588
  function isComment(token) {
570
589
  return token.type === 'Block' || token.type === 'Line';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flow-remove-types",
3
- "version": "2.174.1",
3
+ "version": "2.176.0",
4
4
  "description": "Removes Flow type annotations from JavaScript files with speed and simplicity.",
5
5
  "author": {
6
6
  "name": "Flow Team",
@@ -44,7 +44,7 @@
44
44
  "es6"
45
45
  ],
46
46
  "dependencies": {
47
- "flow-parser": "^0.174.1",
47
+ "flow-parser": "^0.176.0",
48
48
  "pirates": "^3.0.2",
49
49
  "vlq": "^0.2.1"
50
50
  },