hermes-transform 0.8.0 → 0.10.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 (65) hide show
  1. package/ESLINT_LICENCE +19 -0
  2. package/PRETTIER_LICENCE +7 -0
  3. package/dist/detachedNode.js +100 -42
  4. package/dist/detachedNode.js.flow +116 -41
  5. package/dist/generated/TransformCloneSignatures.js.flow +18 -0
  6. package/dist/generated/TransformModifySignatures.js.flow +1127 -0
  7. package/dist/generated/TransformReplaceSignatures.js.flow +15 -1
  8. package/dist/generated/node-types.js +852 -883
  9. package/dist/generated/node-types.js.flow +1187 -1217
  10. package/dist/generated/special-case-node-types/Comment.js +36 -0
  11. package/dist/generated/special-case-node-types/Comment.js.flow +36 -0
  12. package/dist/generated/special-case-node-types/DeclareExportDeclaration.js +55 -0
  13. package/dist/generated/special-case-node-types/DeclareExportDeclaration.js.flow +97 -0
  14. package/dist/generated/special-case-node-types/ExportNamedDeclaration.js +42 -0
  15. package/dist/generated/special-case-node-types/ExportNamedDeclaration.js.flow +75 -0
  16. package/dist/generated/special-case-node-types/Literal.js +97 -0
  17. package/dist/generated/special-case-node-types/Literal.js.flow +139 -0
  18. package/dist/generated/special-case-node-types/ObjectTypeProperty.js +73 -0
  19. package/dist/generated/special-case-node-types/ObjectTypeProperty.js.flow +107 -0
  20. package/dist/generated/special-case-node-types/Property.js +136 -0
  21. package/dist/generated/special-case-node-types/Property.js.flow +237 -0
  22. package/dist/generated/special-case-node-types/misc.js +119 -0
  23. package/dist/generated/special-case-node-types/misc.js.flow +205 -0
  24. package/dist/generated/special-case-node-types.js +42 -180
  25. package/dist/generated/special-case-node-types.js.flow +7 -258
  26. package/dist/index.js +19 -3
  27. package/dist/index.js.flow +6 -2
  28. package/dist/transform/TransformContext.js +34 -11
  29. package/dist/transform/TransformContext.js.flow +90 -33
  30. package/dist/transform/comments/comments.js +34 -5
  31. package/dist/transform/comments/comments.js.flow +39 -4
  32. package/dist/transform/comments/prettier/main/comments.js +1 -1
  33. package/dist/transform/comments/prettier/main/comments.js.flow +2 -1
  34. package/dist/transform/mutations/InsertStatement.js +4 -3
  35. package/dist/transform/mutations/InsertStatement.js.flow +4 -3
  36. package/dist/transform/mutations/RemoveComment.js +3 -3
  37. package/dist/transform/mutations/RemoveComment.js.flow +3 -5
  38. package/dist/transform/mutations/RemoveNode.js +2 -2
  39. package/dist/transform/mutations/RemoveNode.js.flow +2 -2
  40. package/dist/transform/mutations/RemoveStatement.js +2 -2
  41. package/dist/transform/mutations/RemoveStatement.js.flow +2 -2
  42. package/dist/transform/mutations/ReplaceNode.js +10 -7
  43. package/dist/transform/mutations/ReplaceNode.js.flow +7 -5
  44. package/dist/transform/mutations/ReplaceStatementWithMany.js +2 -2
  45. package/dist/transform/mutations/ReplaceStatementWithMany.js.flow +7 -4
  46. package/dist/transform/mutations/utils/getStatementParent.js +3 -2
  47. package/dist/transform/mutations/utils/getStatementParent.js.flow +5 -2
  48. package/dist/transform/parse.js +55 -0
  49. package/dist/transform/parse.js.flow +55 -0
  50. package/dist/transform/print.js +160 -0
  51. package/dist/transform/print.js.flow +176 -0
  52. package/dist/transform/transform.js +6 -67
  53. package/dist/transform/transform.js.flow +6 -69
  54. package/dist/transform/{getTransformedAST.js → transformAST.js} +7 -16
  55. package/dist/transform/{getTransformedAST.js.flow → transformAST.js.flow} +7 -14
  56. package/dist/traverse/NodeEventGenerator.js.flow +1 -1
  57. package/dist/traverse/traverse.js +36 -35
  58. package/dist/traverse/traverse.js.flow +46 -27
  59. package/package.json +10 -5
  60. package/dist/getVisitorKeys.js +0 -33
  61. package/dist/getVisitorKeys.js.flow +0 -31
  62. package/dist/transform/mutations/utils/arrayUtils.js +0 -43
  63. package/dist/transform/mutations/utils/arrayUtils.js.flow +0 -50
  64. package/dist/traverse/SimpleTraverser.js +0 -118
  65. package/dist/traverse/SimpleTraverser.js.flow +0 -112
@@ -14,84 +14,23 @@ Object.defineProperty(exports, "__esModule", {
14
14
  });
15
15
  exports.transform = transform;
16
16
 
17
- var prettier = _interopRequireWildcard(require("prettier"));
17
+ var _transformAST = require("./transformAST");
18
18
 
19
- var _getTransformedAST = require("./getTransformedAST");
19
+ var _parse = require("./parse");
20
20
 
21
- var _SimpleTraverser = require("../traverse/SimpleTraverser");
22
-
23
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
24
-
25
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
+ var _print = require("./print");
26
22
 
27
23
  function transform(originalCode, visitors, prettierOptions = {}) {
24
+ const parseResult = (0, _parse.parse)(originalCode);
28
25
  const {
29
26
  ast,
30
27
  astWasMutated,
31
28
  mutatedCode
32
- } = (0, _getTransformedAST.getTransformedAST)(originalCode, visitors);
29
+ } = (0, _transformAST.transformAST)(parseResult, visitors);
33
30
 
34
31
  if (!astWasMutated) {
35
32
  return originalCode;
36
33
  }
37
34
 
38
- _SimpleTraverser.SimpleTraverser.traverse(ast, {
39
- enter(node) {
40
- // prettier fully expects the parent pointers are NOT set and
41
- // certain cases can crash due to prettier infinite-looping
42
- // whilst naively traversing the parent property
43
- // https://github.com/prettier/prettier/issues/11793
44
- // $FlowExpectedError[cannot-write]
45
- delete node.parent; // prettier currently relies on the AST being in the old-school, deprecated AST format for optional chaining
46
- // so we have to apply their transform to our AST so it can actually format it.
47
-
48
- if (node.type === 'ChainExpression') {
49
- const newNode = transformChainExpression(node.expression); // $FlowExpectedError[cannot-write]
50
-
51
- delete node.expression; // $FlowExpectedError[prop-missing]
52
- // $FlowExpectedError[cannot-write]
53
-
54
- Object.assign(node, newNode);
55
- }
56
- },
57
-
58
- leave() {}
59
-
60
- }); // we need to delete the comments prop or else prettier will do
61
- // its own attachment pass after the mutation and duplicate the
62
- // comments on each node, borking the output
63
- // $FlowExpectedError[cannot-write]
64
-
65
-
66
- delete ast.comments;
67
- return prettier.format(mutatedCode, // $FlowExpectedError[incompatible-exact] - we don't want to create a dependency on the prettier types
68
- { ...prettierOptions,
69
-
70
- parser() {
71
- return ast;
72
- }
73
-
74
- });
75
- } // https://github.com/prettier/prettier/blob/d962466a828f8ef51435e3e8840178d90b7ec6cd/src/language-js/parse/postprocess/index.js#L161-L182
76
-
77
-
78
- function transformChainExpression(node) {
79
- switch (node.type) {
80
- case 'CallExpression':
81
- // $FlowExpectedError[cannot-write]
82
- node.type = 'OptionalCallExpression'; // $FlowExpectedError[cannot-write]
83
-
84
- node.callee = transformChainExpression(node.callee);
85
- break;
86
-
87
- case 'MemberExpression':
88
- // $FlowExpectedError[cannot-write]
89
- node.type = 'OptionalMemberExpression'; // $FlowExpectedError[cannot-write]
90
-
91
- node.object = transformChainExpression(node.object);
92
- break;
93
- // No default
94
- }
95
-
96
- return node;
35
+ return (0, _print.print)(ast, mutatedCode, prettierOptions);
97
36
  }
@@ -10,13 +10,12 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- import type {ESNode} from 'hermes-estree';
14
13
  import type {Visitor} from '../traverse/traverse';
15
14
  import type {TransformContextAdditions} from './TransformContext';
16
15
 
17
- import * as prettier from 'prettier';
18
- import {getTransformedAST} from './getTransformedAST';
19
- import {SimpleTraverser} from '../traverse/SimpleTraverser';
16
+ import {transformAST} from './transformAST';
17
+ import {parse} from './parse';
18
+ import {print} from './print';
20
19
 
21
20
  export type TransformVisitor = Visitor<TransformContextAdditions>;
22
21
 
@@ -25,74 +24,12 @@ export function transform(
25
24
  visitors: TransformVisitor,
26
25
  prettierOptions: {...} = {},
27
26
  ): string {
28
- const {ast, astWasMutated, mutatedCode} = getTransformedAST(
29
- originalCode,
30
- visitors,
31
- );
27
+ const parseResult = parse(originalCode);
32
28
 
29
+ const {ast, astWasMutated, mutatedCode} = transformAST(parseResult, visitors);
33
30
  if (!astWasMutated) {
34
31
  return originalCode;
35
32
  }
36
33
 
37
- SimpleTraverser.traverse(ast, {
38
- enter(node) {
39
- // prettier fully expects the parent pointers are NOT set and
40
- // certain cases can crash due to prettier infinite-looping
41
- // whilst naively traversing the parent property
42
- // https://github.com/prettier/prettier/issues/11793
43
- // $FlowExpectedError[cannot-write]
44
- delete node.parent;
45
-
46
- // prettier currently relies on the AST being in the old-school, deprecated AST format for optional chaining
47
- // so we have to apply their transform to our AST so it can actually format it.
48
- if (node.type === 'ChainExpression') {
49
- const newNode = transformChainExpression(node.expression);
50
- // $FlowExpectedError[cannot-write]
51
- delete node.expression;
52
- // $FlowExpectedError[prop-missing]
53
- // $FlowExpectedError[cannot-write]
54
- Object.assign(node, newNode);
55
- }
56
- },
57
- leave() {},
58
- });
59
-
60
- // we need to delete the comments prop or else prettier will do
61
- // its own attachment pass after the mutation and duplicate the
62
- // comments on each node, borking the output
63
- // $FlowExpectedError[cannot-write]
64
- delete ast.comments;
65
-
66
- return prettier.format(
67
- mutatedCode,
68
- // $FlowExpectedError[incompatible-exact] - we don't want to create a dependency on the prettier types
69
- {
70
- ...prettierOptions,
71
- parser() {
72
- return ast;
73
- },
74
- },
75
- );
76
- }
77
-
78
- // https://github.com/prettier/prettier/blob/d962466a828f8ef51435e3e8840178d90b7ec6cd/src/language-js/parse/postprocess/index.js#L161-L182
79
- function transformChainExpression(node: ESNode) {
80
- switch (node.type) {
81
- case 'CallExpression':
82
- // $FlowExpectedError[cannot-write]
83
- node.type = 'OptionalCallExpression';
84
- // $FlowExpectedError[cannot-write]
85
- node.callee = transformChainExpression(node.callee);
86
- break;
87
-
88
- case 'MemberExpression':
89
- // $FlowExpectedError[cannot-write]
90
- node.type = 'OptionalMemberExpression';
91
- // $FlowExpectedError[cannot-write]
92
- node.object = transformChainExpression(node.object);
93
- break;
94
- // No default
95
- }
96
-
97
- return node;
34
+ return print(ast, mutatedCode, prettierOptions);
98
35
  }
@@ -12,9 +12,7 @@
12
12
  Object.defineProperty(exports, "__esModule", {
13
13
  value: true
14
14
  });
15
- exports.getTransformedAST = getTransformedAST;
16
-
17
- var _hermesEslint = require("hermes-eslint");
15
+ exports.transformAST = transformAST;
18
16
 
19
17
  var _detachedNode = require("../detachedNode");
20
18
 
@@ -24,8 +22,6 @@ var _MutationContext = require("./MutationContext");
24
22
 
25
23
  var _TransformContext = require("./TransformContext");
26
24
 
27
- var _comments = require("./comments/comments");
28
-
29
25
  var _AddComments = require("./mutations/AddComments");
30
26
 
31
27
  var _CloneCommentsTo = require("./mutations/CloneCommentsTo");
@@ -42,17 +38,12 @@ var _ReplaceNode = require("./mutations/ReplaceNode");
42
38
 
43
39
  var _ReplaceStatementWithMany = require("./mutations/ReplaceStatementWithMany");
44
40
 
45
- function getTransformedAST(code, visitors) {
46
- const {
47
- ast,
48
- scopeManager
49
- } = (0, _hermesEslint.parseForESLint)(code, {
50
- sourceType: 'module'
51
- }); // attach comments before mutation. this will ensure that as nodes are
52
- // cloned / moved around - comments remain in the correct place with respect to the node
53
-
54
- (0, _comments.attachComments)(ast.comments, ast, code); // traverse the AST and colllect the mutations
55
-
41
+ function transformAST({
42
+ ast,
43
+ scopeManager,
44
+ code
45
+ }, visitors) {
46
+ // traverse the AST and colllect the mutations
56
47
  const transformContext = (0, _TransformContext.getTransformContext)();
57
48
  (0, _traverse.traverseWithContext)(code, ast, scopeManager, () => transformContext, visitors); // apply the mutations to the AST
58
49
 
@@ -13,13 +13,12 @@
13
13
  import type {ESNode, Program} from 'hermes-estree';
14
14
  import type {TransformVisitor} from './transform';
15
15
  import type {RemoveCommentMutation} from './mutations/RemoveComment';
16
+ import type {ParseResult} from './parse';
16
17
 
17
- import {parseForESLint} from 'hermes-eslint';
18
18
  import {updateAllParentPointers} from '../detachedNode';
19
19
  import {traverseWithContext} from '../traverse/traverse';
20
20
  import {MutationContext} from './MutationContext';
21
21
  import {getTransformContext} from './TransformContext';
22
- import {attachComments} from './comments/comments';
23
22
  import {performAddCommentsMutation} from './mutations/AddComments';
24
23
  import {performCloneCommentsToMutation} from './mutations/CloneCommentsTo';
25
24
  import {performInsertStatementMutation} from './mutations/InsertStatement';
@@ -29,22 +28,16 @@ import {performRemoveStatementMutation} from './mutations/RemoveStatement';
29
28
  import {performReplaceNodeMutation} from './mutations/ReplaceNode';
30
29
  import {performReplaceStatementWithManyMutation} from './mutations/ReplaceStatementWithMany';
31
30
 
32
- export function getTransformedAST(
33
- code: string,
34
- visitors: TransformVisitor,
35
- ): {
31
+ export type TransformASTResult = {
36
32
  ast: Program,
37
33
  astWasMutated: boolean,
38
34
  mutatedCode: string,
39
- } {
40
- const {ast, scopeManager} = parseForESLint(code, {
41
- sourceType: 'module',
42
- });
43
-
44
- // attach comments before mutation. this will ensure that as nodes are
45
- // cloned / moved around - comments remain in the correct place with respect to the node
46
- attachComments(ast.comments, ast, code);
35
+ };
47
36
 
37
+ export function transformAST(
38
+ {ast, scopeManager, code}: ParseResult,
39
+ visitors: TransformVisitor,
40
+ ): TransformASTResult {
48
41
  // traverse the AST and colllect the mutations
49
42
  const transformContext = getTransformContext();
50
43
  traverseWithContext(
@@ -34,7 +34,7 @@ type ParsedSelector = $ReadOnly<{
34
34
 
35
35
  const ESQUERY_OPTIONS: ESQueryOptions = Object.freeze({
36
36
  visitorKeys: VisitorKeys,
37
- fallback: node => {
37
+ fallback: (node: ESNode) => {
38
38
  throw new Error(`No visitor keys found for node type "${node.type}".`);
39
39
  },
40
40
  });
@@ -12,7 +12,7 @@ var _NodeEventGenerator = require("./NodeEventGenerator");
12
12
 
13
13
  var _SafeEmitter = require("./SafeEmitter");
14
14
 
15
- var _SimpleTraverser = require("./SimpleTraverser");
15
+ var _hermesParser = require("hermes-parser");
16
16
 
17
17
  /**
18
18
  * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -32,27 +32,9 @@ var _SimpleTraverser = require("./SimpleTraverser");
32
32
  */
33
33
  function traverseWithContext(code, ast, scopeManager, additionalContext, visitor) {
34
34
  const emitter = new _SafeEmitter.SafeEmitter();
35
- const nodeQueue = [];
36
- let currentNode = ast; // set parent pointers and build up the traversal queue
37
-
38
- _SimpleTraverser.SimpleTraverser.traverse(ast, {
39
- enter(node, parent) {
40
- // $FlowExpectedError[cannot-write] - hermes doesn't set this
41
- node.parent = parent;
42
- nodeQueue.push({
43
- isEntering: true,
44
- node
45
- });
46
- },
47
-
48
- leave(node) {
49
- nodeQueue.push({
50
- isEntering: false,
51
- node
52
- });
53
- }
54
-
55
- });
35
+ let currentNode = ast;
36
+ let shouldSkipTraversal = false;
37
+ let shouldStopTraversal = false;
56
38
 
57
39
  const getScope = (givenNode = currentNode) => {
58
40
  // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope.
@@ -112,7 +94,13 @@ function traverseWithContext(code, ast, scopeManager, additionalContext, visitor
112
94
 
113
95
  return null;
114
96
  },
115
- getScope
97
+ getScope,
98
+ stopTraversal: () => {
99
+ shouldStopTraversal = true;
100
+ },
101
+ skipTraversal: () => {
102
+ shouldSkipTraversal = true;
103
+ }
116
104
  });
117
105
  const traversalContext = Object.freeze({ ...traversalContextBase,
118
106
  ...additionalContext(traversalContextBase)
@@ -130,19 +118,32 @@ function traverseWithContext(code, ast, scopeManager, additionalContext, visitor
130
118
  }
131
119
  });
132
120
  const eventGenerator = new _NodeEventGenerator.NodeEventGenerator(emitter);
133
- nodeQueue.forEach(traversalInfo => {
134
- currentNode = traversalInfo.node;
135
-
136
- try {
137
- if (traversalInfo.isEntering) {
138
- eventGenerator.enterNode(currentNode);
139
- } else {
140
- eventGenerator.leaveNode(currentNode);
141
- }
142
- } catch (err) {
143
- err.currentNode = currentNode;
144
- throw err;
121
+
122
+ function checkTraversalFlags() {
123
+ if (shouldStopTraversal) {
124
+ // No need to reset the flag since we won't enter any more nodes.
125
+ throw _hermesParser.SimpleTraverser.Break;
126
+ }
127
+
128
+ if (shouldSkipTraversal) {
129
+ shouldSkipTraversal = false;
130
+ throw _hermesParser.SimpleTraverser.Skip;
131
+ }
132
+ }
133
+
134
+ _hermesParser.SimpleTraverser.traverse(ast, {
135
+ enter(node) {
136
+ currentNode = node;
137
+ eventGenerator.enterNode(node);
138
+ checkTraversalFlags();
139
+ },
140
+
141
+ leave(node) {
142
+ currentNode = node;
143
+ eventGenerator.leaveNode(node);
144
+ checkTraversalFlags();
145
145
  }
146
+
146
147
  });
147
148
  }
148
149
 
@@ -15,7 +15,7 @@ import type {EmitterListener} from './SafeEmitter';
15
15
  import {codeFrameColumns} from '@babel/code-frame';
16
16
  import {NodeEventGenerator} from './NodeEventGenerator';
17
17
  import {SafeEmitter} from './SafeEmitter';
18
- import {SimpleTraverser} from './SimpleTraverser';
18
+ import {SimpleTraverser} from 'hermes-parser';
19
19
 
20
20
  export type TraversalContextBase = $ReadOnly<{
21
21
  /**
@@ -55,6 +55,17 @@ export type TraversalContextBase = $ReadOnly<{
55
55
  * (where 56:44 represents L56, Col44)
56
56
  */
57
57
  buildSimpleCodeFrame: (node: ESNode, message: string) => string,
58
+ /**
59
+ * Can be called at any point during the traversal to immediately stop traversal
60
+ * entirely.
61
+ */
62
+ stopTraversal: () => void,
63
+ /**
64
+ * Can be called within the traversal "enter" function to prevent the traverser
65
+ * from traversing the node any further, essentially culling the remainder of the
66
+ * AST branch from traversal.
67
+ */
68
+ skipTraversal: () => void,
58
69
  }>;
59
70
  export type TraversalContext<T> = $ReadOnly<{
60
71
  ...TraversalContextBase,
@@ -77,21 +88,10 @@ export function traverseWithContext<T = TraversalContextBase>(
77
88
  visitor: Visitor<T>,
78
89
  ): void {
79
90
  const emitter = new SafeEmitter();
80
- const nodeQueue: Array<{isEntering: boolean, node: ESNode}> = [];
81
91
 
82
92
  let currentNode: ESNode = ast;
83
-
84
- // set parent pointers and build up the traversal queue
85
- SimpleTraverser.traverse(ast, {
86
- enter(node, parent) {
87
- // $FlowExpectedError[cannot-write] - hermes doesn't set this
88
- node.parent = parent;
89
- nodeQueue.push({isEntering: true, node});
90
- },
91
- leave(node) {
92
- nodeQueue.push({isEntering: false, node});
93
- },
94
- });
93
+ let shouldSkipTraversal = false;
94
+ let shouldStopTraversal = false;
95
95
 
96
96
  const getScope = (givenNode: ESNode = currentNode) => {
97
97
  // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope.
@@ -140,7 +140,7 @@ export function traverseWithContext<T = TraversalContextBase>(
140
140
  scopeManager.getDeclaredVariables(node),
141
141
 
142
142
  getBinding: (name: string) => {
143
- let currentScope = getScope();
143
+ let currentScope: null | Scope = getScope();
144
144
 
145
145
  while (currentScope != null) {
146
146
  for (const variable of currentScope.variables) {
@@ -155,6 +155,14 @@ export function traverseWithContext<T = TraversalContextBase>(
155
155
  },
156
156
 
157
157
  getScope,
158
+
159
+ stopTraversal: () => {
160
+ shouldStopTraversal = true;
161
+ },
162
+
163
+ skipTraversal: () => {
164
+ shouldSkipTraversal = true;
165
+ },
158
166
  });
159
167
 
160
168
  const traversalContext: TraversalContext<T> = Object.freeze({
@@ -176,19 +184,30 @@ export function traverseWithContext<T = TraversalContextBase>(
176
184
  });
177
185
 
178
186
  const eventGenerator = new NodeEventGenerator(emitter);
179
- nodeQueue.forEach(traversalInfo => {
180
- currentNode = traversalInfo.node;
181
-
182
- try {
183
- if (traversalInfo.isEntering) {
184
- eventGenerator.enterNode(currentNode);
185
- } else {
186
- eventGenerator.leaveNode(currentNode);
187
- }
188
- } catch (err) {
189
- err.currentNode = currentNode;
190
- throw err;
187
+
188
+ function checkTraversalFlags(): void {
189
+ if (shouldStopTraversal) {
190
+ // No need to reset the flag since we won't enter any more nodes.
191
+ throw SimpleTraverser.Break;
192
+ }
193
+
194
+ if (shouldSkipTraversal) {
195
+ shouldSkipTraversal = false;
196
+ throw SimpleTraverser.Skip;
191
197
  }
198
+ }
199
+
200
+ SimpleTraverser.traverse(ast, {
201
+ enter(node) {
202
+ currentNode = node;
203
+ eventGenerator.enterNode(node);
204
+ checkTraversalFlags();
205
+ },
206
+ leave(node) {
207
+ currentNode = node;
208
+ eventGenerator.leaveNode(node);
209
+ checkTraversalFlags();
210
+ },
192
211
  });
193
212
  }
194
213
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hermes-transform",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Tools built on top of Hermes-ESTree to enable codebase transformation",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -12,13 +12,18 @@
12
12
  "@babel/code-frame": "^7.16.0",
13
13
  "esquery": "^1.4.0",
14
14
  "flow-enums-runtime": "^0.0.6",
15
- "hermes-eslint": "0.8.0",
16
- "hermes-estree": "0.8.0"
15
+ "hermes-eslint": "0.10.0",
16
+ "hermes-estree": "0.10.0",
17
+ "hermes-parser": "0.10.0"
17
18
  },
18
19
  "peerDependencies": {
19
- "prettier": "^2.4.1"
20
+ "prettier": "^2.7.1"
20
21
  },
21
22
  "files": [
22
- "dist"
23
+ "dist",
24
+ "LICENCE",
25
+ "ESLINT_LICENCE",
26
+ "PRETTIER_LICENCE",
27
+ "README.md"
23
28
  ]
24
29
  }
@@ -1,33 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- */
10
- 'use strict';
11
-
12
- Object.defineProperty(exports, "__esModule", {
13
- value: true
14
- });
15
- exports.getVisitorKeys = getVisitorKeys;
16
- exports.isNode = isNode;
17
-
18
- var _hermesEslint = require("hermes-eslint");
19
-
20
- function isNode(thing) {
21
- return typeof thing === 'object' && thing != null && typeof thing.type === 'string';
22
- }
23
-
24
- function getVisitorKeys(node) {
25
- const keys = _hermesEslint.VisitorKeys[node.type];
26
-
27
- if (keys == null) {
28
- throw new Error(`No visitor keys found for node type "${node.type}".`);
29
- } // $FlowExpectedError[prop-missing]
30
-
31
-
32
- return keys;
33
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict-local
8
- * @format
9
- */
10
-
11
- 'use strict';
12
-
13
- import type {ESNode} from 'hermes-estree';
14
-
15
- import {VisitorKeys} from 'hermes-eslint';
16
-
17
- export function isNode(thing: mixed): boolean %checks {
18
- return (
19
- typeof thing === 'object' && thing != null && typeof thing.type === 'string'
20
- );
21
- }
22
-
23
- export function getVisitorKeys<T: ESNode>(node: T): $ReadOnlyArray<$Keys<T>> {
24
- const keys = VisitorKeys[node.type];
25
- if (keys == null) {
26
- throw new Error(`No visitor keys found for node type "${node.type}".`);
27
- }
28
-
29
- // $FlowExpectedError[prop-missing]
30
- return keys;
31
- }
@@ -1,43 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.insertInArray = insertInArray;
7
- exports.removeFromArray = removeFromArray;
8
- exports.replaceInArray = replaceInArray;
9
-
10
- /**
11
- * Copyright (c) Meta Platforms, Inc. and affiliates.
12
- *
13
- * This source code is licensed under the MIT license found in the
14
- * LICENSE file in the root directory of this source tree.
15
- *
16
- *
17
- * @format
18
- */
19
- function assertArrayBounds(array, index) {
20
- if (index < 0 || index >= array.length) {
21
- throw new Error(`Invalid Mutation: Tried to mutate an elements array with an out of bounds index. Index: ${index}, Array Size: ${array.length}`);
22
- }
23
- }
24
-
25
- function insertInArray(array, index, elements) {
26
- if (index === array.length) {
27
- // Support the insert at end of array case.
28
- return array.concat(elements);
29
- }
30
-
31
- assertArrayBounds(array, index);
32
- return array.slice(0, index).concat(elements).concat(array.slice(index));
33
- }
34
-
35
- function removeFromArray(array, index) {
36
- assertArrayBounds(array, index);
37
- return [...array.slice(0, index), ...array.slice(index + 1)];
38
- }
39
-
40
- function replaceInArray(array, index, elements) {
41
- assertArrayBounds(array, index);
42
- return array.slice(0, index).concat(elements).concat(array.slice(index + 1));
43
- }