hermes-transform 0.28.0 → 0.29.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.
- package/dist/detachedNode.js +1 -0
- package/dist/detachedNode.js.flow +1 -0
- package/dist/generated/node-types.js +1 -12
- package/dist/generated/node-types.js.flow +2 -19
- package/dist/generated/special-case-node-types/misc.js +11 -0
- package/dist/generated/special-case-node-types/misc.js.flow +18 -0
- package/dist/src/detachedNode.js +178 -0
- package/dist/src/generated/node-types.js +2212 -0
- package/dist/src/generated/special-case-node-types/Comment.js +36 -0
- package/dist/src/generated/special-case-node-types/DeclareExportDeclaration.js +58 -0
- package/dist/src/generated/special-case-node-types/DeclareHook.js +33 -0
- package/dist/src/generated/special-case-node-types/ExportNamedDeclaration.js +44 -0
- package/dist/src/generated/special-case-node-types/Literal.js +97 -0
- package/dist/src/generated/special-case-node-types/ObjectTypeProperty.js +74 -0
- package/dist/src/generated/special-case-node-types/Property.js +136 -0
- package/dist/src/generated/special-case-node-types/misc.js +158 -0
- package/dist/src/generated/special-case-node-types.js +69 -0
- package/dist/src/index.js +53 -0
- package/dist/src/transform/Errors.js +43 -0
- package/dist/src/transform/MutationContext.js +81 -0
- package/dist/src/transform/TransformContext.js +213 -0
- package/dist/src/transform/comments/comments.js +308 -0
- package/dist/src/transform/comments/prettier/common/util.js +364 -0
- package/dist/src/transform/comments/prettier/language-js/comments.js +788 -0
- package/dist/src/transform/comments/prettier/language-js/loc.js +42 -0
- package/dist/src/transform/comments/prettier/language-js/printer-estree.js +32 -0
- package/dist/src/transform/comments/prettier/language-js/utils.js +119 -0
- package/dist/src/transform/comments/prettier/main/comments.js +440 -0
- package/dist/src/transform/comments/prettier/utils/get-last.js +13 -0
- package/dist/src/transform/mutations/AddComments.js +43 -0
- package/dist/src/transform/mutations/CloneCommentsTo.js +31 -0
- package/dist/src/transform/mutations/InsertStatement.js +91 -0
- package/dist/src/transform/mutations/ModifyNodeInPlace.js +59 -0
- package/dist/src/transform/mutations/RemoveComment.js +78 -0
- package/dist/src/transform/mutations/RemoveNode.js +205 -0
- package/dist/src/transform/mutations/RemoveStatement.js +59 -0
- package/dist/src/transform/mutations/ReplaceNode.js +92 -0
- package/dist/src/transform/mutations/ReplaceStatementWithMany.js +79 -0
- package/dist/src/transform/mutations/utils/getStatementParent.js +143 -0
- package/dist/src/transform/mutations/utils/isValidModuleDeclarationParent.js +43 -0
- package/dist/src/transform/parse.js +56 -0
- package/dist/src/transform/print.js +134 -0
- package/dist/src/transform/transform.js +36 -0
- package/dist/src/transform/transformAST.js +134 -0
- package/dist/src/traverse/NodeEventGenerator.js +353 -0
- package/dist/src/traverse/SafeEmitter.js +52 -0
- package/dist/src/traverse/esquery.js +37 -0
- package/dist/src/traverse/traverse.js +150 -0
- package/dist/transform/comments/prettier/language-js/comments.js +29 -1
- package/dist/transform/mutations/utils/getStatementParent.js.flow +7 -5
- package/package.json +5 -5
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createReplaceStatementWithManyMutation = createReplaceStatementWithManyMutation;
|
|
7
|
+
exports.performReplaceStatementWithManyMutation = performReplaceStatementWithManyMutation;
|
|
8
|
+
|
|
9
|
+
var _hermesParser = require("hermes-parser");
|
|
10
|
+
|
|
11
|
+
var _getStatementParent = require("./utils/getStatementParent");
|
|
12
|
+
|
|
13
|
+
var _isValidModuleDeclarationParent = require("./utils/isValidModuleDeclarationParent");
|
|
14
|
+
|
|
15
|
+
var _comments = require("../comments/comments");
|
|
16
|
+
|
|
17
|
+
var _Errors = require("../Errors");
|
|
18
|
+
|
|
19
|
+
var t = _interopRequireWildcard(require("../../generated/node-types"));
|
|
20
|
+
|
|
21
|
+
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); }
|
|
22
|
+
|
|
23
|
+
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; }
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
27
|
+
*
|
|
28
|
+
* This source code is licensed under the MIT license found in the
|
|
29
|
+
* LICENSE file in the root directory of this source tree.
|
|
30
|
+
*
|
|
31
|
+
*
|
|
32
|
+
* @format
|
|
33
|
+
*/
|
|
34
|
+
function createReplaceStatementWithManyMutation(target, nodesToReplaceWith, options) {
|
|
35
|
+
var _options$keepComments;
|
|
36
|
+
|
|
37
|
+
if (nodesToReplaceWith.length === 0) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
type: 'replaceStatementWithMany',
|
|
43
|
+
target,
|
|
44
|
+
nodesToReplaceWith,
|
|
45
|
+
keepComments: (_options$keepComments = options == null ? void 0 : options.keepComments) != null ? _options$keepComments : false
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function performReplaceStatementWithManyMutation(mutationContext, mutation) {
|
|
50
|
+
const replacementParent = (0, _getStatementParent.getStatementParent)(mutation.target); // enforce that if we are replacing with module declarations - they are being inserted in a valid location
|
|
51
|
+
|
|
52
|
+
if (!(0, _isValidModuleDeclarationParent.isValidModuleDeclarationParent)(replacementParent.parent, mutation.nodesToReplaceWith)) {
|
|
53
|
+
throw new _Errors.InvalidReplacementError(`import/export cannot be replaced into a ${replacementParent.parent.type}.`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
mutationContext.markDeletion(mutation.target);
|
|
57
|
+
mutationContext.markMutation(replacementParent.parent, replacementParent.key);
|
|
58
|
+
|
|
59
|
+
if (mutation.keepComments) {
|
|
60
|
+
// attach comments to the very first replacement node
|
|
61
|
+
(0, _comments.moveCommentsToNewNode)(mutation.target, mutation.nodesToReplaceWith[0]);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (replacementParent.type === 'array') {
|
|
65
|
+
const parent = replacementParent.parent;
|
|
66
|
+
parent[replacementParent.key] = _hermesParser.astArrayMutationHelpers.replaceInArray(parent[replacementParent.key], replacementParent.targetIndex, mutation.nodesToReplaceWith);
|
|
67
|
+
return replacementParent.parent;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const statementsToReplaceWith = // $FlowExpectedError[incompatible-cast] -- this is enforced by isValidModuleDeclarationParent above
|
|
71
|
+
mutation.nodesToReplaceWith; // we need to wrap the nodes in a BlockStatement as before there was only 1 node
|
|
72
|
+
|
|
73
|
+
const blockStatement = t.BlockStatement({
|
|
74
|
+
body: statementsToReplaceWith,
|
|
75
|
+
parent: replacementParent.parent
|
|
76
|
+
});
|
|
77
|
+
replacementParent.parent[replacementParent.key] = blockStatement;
|
|
78
|
+
return replacementParent.parent;
|
|
79
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getStatementParent = getStatementParent;
|
|
7
|
+
|
|
8
|
+
var _Errors = require("../../Errors");
|
|
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 getStatementParent(target) {
|
|
20
|
+
function assertValidStatementLocation(parentWithType, ...invalidKeys) {
|
|
21
|
+
for (const key of invalidKeys) {
|
|
22
|
+
// $FlowExpectedError[prop-missing]
|
|
23
|
+
const value = parentWithType[key];
|
|
24
|
+
|
|
25
|
+
if (value === target || Array.isArray(value) && value.includes(target)) {
|
|
26
|
+
throw new _Errors.InvalidStatementError(`Attempted to insert a statement into \`${parentWithType.type}.${key}\`.`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getAssertedIndex(key, arr) {
|
|
32
|
+
const idx = arr.indexOf(target);
|
|
33
|
+
|
|
34
|
+
if (idx === -1) {
|
|
35
|
+
throw new _Errors.InvalidStatementError(`Could not find target in array of \`${parent.type}.${key}\`.`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return idx;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const parent = target.parent;
|
|
42
|
+
|
|
43
|
+
const result = (() => {
|
|
44
|
+
switch (parent.type) {
|
|
45
|
+
case 'IfStatement':
|
|
46
|
+
{
|
|
47
|
+
assertValidStatementLocation(parent, 'test');
|
|
48
|
+
const key = parent.consequent === target ? 'consequent' : 'alternate';
|
|
49
|
+
return {
|
|
50
|
+
type: 'single',
|
|
51
|
+
parent,
|
|
52
|
+
key
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
case 'LabeledStatement':
|
|
57
|
+
{
|
|
58
|
+
assertValidStatementLocation(parent, 'label');
|
|
59
|
+
return {
|
|
60
|
+
type: 'single',
|
|
61
|
+
parent,
|
|
62
|
+
key: 'body'
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
case 'WithStatement':
|
|
67
|
+
{
|
|
68
|
+
assertValidStatementLocation(parent, 'object');
|
|
69
|
+
return {
|
|
70
|
+
type: 'single',
|
|
71
|
+
parent,
|
|
72
|
+
key: 'body'
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
case 'DoWhileStatement':
|
|
77
|
+
case 'WhileStatement':
|
|
78
|
+
{
|
|
79
|
+
assertValidStatementLocation(parent, 'test');
|
|
80
|
+
return {
|
|
81
|
+
type: 'single',
|
|
82
|
+
parent,
|
|
83
|
+
key: 'body'
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case 'ForStatement':
|
|
88
|
+
{
|
|
89
|
+
assertValidStatementLocation(parent, 'init', 'test', 'update');
|
|
90
|
+
return {
|
|
91
|
+
type: 'single',
|
|
92
|
+
parent,
|
|
93
|
+
key: 'body'
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
case 'ForInStatement':
|
|
98
|
+
case 'ForOfStatement':
|
|
99
|
+
{
|
|
100
|
+
assertValidStatementLocation(parent, // $FlowExpectedError[prop-missing] - flow does not track properties from parent interface
|
|
101
|
+
'left', // $FlowExpectedError[prop-missing] - flow does not track properties from parent interface
|
|
102
|
+
'right');
|
|
103
|
+
return {
|
|
104
|
+
type: 'single',
|
|
105
|
+
parent,
|
|
106
|
+
key: 'body'
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
case 'SwitchCase':
|
|
111
|
+
{
|
|
112
|
+
assertValidStatementLocation(parent, 'test');
|
|
113
|
+
return {
|
|
114
|
+
type: 'array',
|
|
115
|
+
parent,
|
|
116
|
+
key: 'consequent',
|
|
117
|
+
targetIndex: getAssertedIndex('consequent', parent.consequent)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
case 'BlockStatement':
|
|
122
|
+
case 'Program':
|
|
123
|
+
{
|
|
124
|
+
return {
|
|
125
|
+
type: 'array',
|
|
126
|
+
parent,
|
|
127
|
+
key: 'body',
|
|
128
|
+
targetIndex: getAssertedIndex('body', parent.body)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
throw new _Errors.InvalidStatementError(`Expected to find a valid statement parent, but found a parent of type "${parent.type}".`);
|
|
134
|
+
})();
|
|
135
|
+
|
|
136
|
+
if ( // array insertions are already validated by the getAssertedIndex function
|
|
137
|
+
result.targetIndex == null && // $FlowExpectedError[prop-missing]
|
|
138
|
+
result.parent[result.key] !== target) {
|
|
139
|
+
throw new _Errors.InvalidStatementError(`Expected to find the target "${target.type}" on the "${result.parent.type}.${result.key}", but found a different node. ` + 'This likely means that you attempted to mutate around the target after it was deleted/replaced.');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isValidModuleDeclarationParent = isValidModuleDeclarationParent;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
10
|
+
*
|
|
11
|
+
* This source code is licensed under the MIT license found in the
|
|
12
|
+
* LICENSE file in the root directory of this source tree.
|
|
13
|
+
*
|
|
14
|
+
*
|
|
15
|
+
* @noformat
|
|
16
|
+
*/
|
|
17
|
+
function isModuleDeclaration(node)
|
|
18
|
+
/*: node is (
|
|
19
|
+
| ImportDeclaration
|
|
20
|
+
| ExportNamedDeclaration
|
|
21
|
+
| ExportDefaultDeclaration
|
|
22
|
+
| ExportAllDeclaration
|
|
23
|
+
) */
|
|
24
|
+
{
|
|
25
|
+
return node.type === 'ImportDeclaration' || node.type === 'ExportNamedDeclaration' || node.type === 'ExportDefaultDeclaration' || node.type === 'ExportAllDeclaration';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isValidModuleDeclarationParent(target, nodesToInsertOrReplace) {
|
|
29
|
+
if (target.type === 'Program' || target.type === 'BlockStatement' && target.parent.type === 'DeclareModule') {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const node of nodesToInsertOrReplace) {
|
|
34
|
+
if (!isModuleDeclaration( // $FlowExpectedError[incompatible-cast]
|
|
35
|
+
node)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
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.parse = parse;
|
|
16
|
+
|
|
17
|
+
var _comments = require("./comments/comments");
|
|
18
|
+
|
|
19
|
+
var _hermesEslint = require("hermes-eslint");
|
|
20
|
+
|
|
21
|
+
async function parse(code) {
|
|
22
|
+
const {
|
|
23
|
+
ast,
|
|
24
|
+
scopeManager
|
|
25
|
+
} = (0, _hermesEslint.parseForESLint)(code, {
|
|
26
|
+
sourceType: 'module',
|
|
27
|
+
enableExperimentalComponentSyntax: true
|
|
28
|
+
}); // Don't include the docblock comment in the comment list as we don't want to attach it
|
|
29
|
+
// as it should be maintained at the top of the file as nodes are moved around.
|
|
30
|
+
|
|
31
|
+
let comments = ast.comments;
|
|
32
|
+
|
|
33
|
+
if (ast.docblock != null && ast.docblock.comment === comments[0]) {
|
|
34
|
+
const [first, ...nonDocblockComments] = comments; // Since we will not be attaching this comment automatically we need to add the
|
|
35
|
+
// properties prettier expects for printing.
|
|
36
|
+
// $FlowExpectedError[prop-missing]
|
|
37
|
+
|
|
38
|
+
first.placement = 'endOfLine'; // $FlowExpectedError[prop-missing]
|
|
39
|
+
|
|
40
|
+
first.leading = true; // $FlowExpectedError[prop-missing]
|
|
41
|
+
|
|
42
|
+
first.trailing = false; // $FlowExpectedError[prop-missing]
|
|
43
|
+
|
|
44
|
+
first.printed = false;
|
|
45
|
+
comments = nonDocblockComments;
|
|
46
|
+
} // attach comments before mutation. this will ensure that as nodes are
|
|
47
|
+
// cloned / moved around - comments remain in the correct place with respect to the node
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
(0, _comments.attachComments)(comments, ast, code);
|
|
51
|
+
return {
|
|
52
|
+
ast,
|
|
53
|
+
scopeManager,
|
|
54
|
+
code
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
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.print = print;
|
|
16
|
+
|
|
17
|
+
var _hermesParser = require("hermes-parser");
|
|
18
|
+
|
|
19
|
+
var prettier = _interopRequireWildcard(require("prettier"));
|
|
20
|
+
|
|
21
|
+
var _comments = require("./comments/comments");
|
|
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; }
|
|
26
|
+
|
|
27
|
+
let cache = 1;
|
|
28
|
+
const cacheBase = Math.random();
|
|
29
|
+
|
|
30
|
+
async function print(ast, originalCode, prettierOptions = {}, visitorKeys) {
|
|
31
|
+
// $FlowExpectedError[incompatible-type] This is now safe to access.
|
|
32
|
+
const program = ast; // If the AST body is empty, we can skip the cost of prettier by returning a static string of the contents.
|
|
33
|
+
|
|
34
|
+
if (program.body.length === 0) {
|
|
35
|
+
var _program$docblock;
|
|
36
|
+
|
|
37
|
+
// If the program had a docblock comment, we need to create the string manually.
|
|
38
|
+
const docblockComment = (_program$docblock = program.docblock) == null ? void 0 : _program$docblock.comment;
|
|
39
|
+
|
|
40
|
+
if (docblockComment != null) {
|
|
41
|
+
return '/*' + docblockComment.value + '*/\n';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return '';
|
|
45
|
+
} // Cleanup the comments from the AST and generate the "orginal" code needed for prettier.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
const codeForPrinting = (0, _comments.mutateESTreeASTCommentsForPrettier)(program, originalCode); // Fix up the AST to match what prettier expects.
|
|
49
|
+
|
|
50
|
+
(0, _hermesParser.mutateESTreeASTForPrettier)(program, visitorKeys);
|
|
51
|
+
|
|
52
|
+
switch (getPrettierMajorVersion()) {
|
|
53
|
+
case '3':
|
|
54
|
+
{
|
|
55
|
+
// Lazy require this module as it only exists in prettier v3.
|
|
56
|
+
const prettierFlowPlugin = require('prettier/plugins/flow');
|
|
57
|
+
|
|
58
|
+
return prettier.format(codeForPrinting, // $FlowExpectedError[incompatible-exact] - we don't want to create a dependency on the prettier types
|
|
59
|
+
{ ...prettierOptions,
|
|
60
|
+
parser: 'flow',
|
|
61
|
+
requirePragma: false,
|
|
62
|
+
plugins: [{
|
|
63
|
+
parsers: {
|
|
64
|
+
flow: { ...prettierFlowPlugin.parsers.flow,
|
|
65
|
+
|
|
66
|
+
parse() {
|
|
67
|
+
return program;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
case '2':
|
|
77
|
+
{
|
|
78
|
+
var _hermesPlugin$parsers;
|
|
79
|
+
|
|
80
|
+
const hermesPlugin = require('prettier-plugin-hermes-parser');
|
|
81
|
+
|
|
82
|
+
const hermesParser = (_hermesPlugin$parsers = hermesPlugin.parsers) == null ? void 0 : _hermesPlugin$parsers.hermes;
|
|
83
|
+
|
|
84
|
+
if (hermesParser == null) {
|
|
85
|
+
throw new Error('Hermes parser plugin not found');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return prettier.format(codeForPrinting, // $FlowExpectedError[incompatible-exact] - we don't want to create a dependency on the prettier types
|
|
89
|
+
{ ...prettierOptions,
|
|
90
|
+
parser: 'hermes',
|
|
91
|
+
requirePragma: false,
|
|
92
|
+
plugins: [// $FlowExpectedError[incompatible-call] Cache value is not expected but needed in this case.
|
|
93
|
+
{
|
|
94
|
+
parsers: {
|
|
95
|
+
hermes: { ...hermesParser,
|
|
96
|
+
// Prettier caches the plugin, by making this key always unique we ensure the new `parse`
|
|
97
|
+
// function with the correct AST is always called.
|
|
98
|
+
cache: `${cacheBase}-${cache++}`,
|
|
99
|
+
|
|
100
|
+
// Provide the passed AST to prettier
|
|
101
|
+
parse() {
|
|
102
|
+
return program;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
printers: hermesPlugin.printers
|
|
108
|
+
}]
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
case 'UNSUPPORTED':
|
|
113
|
+
default:
|
|
114
|
+
{
|
|
115
|
+
throw new Error(`Unknown or unsupported prettier version of "${prettier.version}". Only major versions 3 or 2 of prettier are supported.`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function getPrettierMajorVersion() {
|
|
121
|
+
const {
|
|
122
|
+
version
|
|
123
|
+
} = prettier;
|
|
124
|
+
|
|
125
|
+
if (version.startsWith('3.')) {
|
|
126
|
+
return '3';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (version.startsWith('2.')) {
|
|
130
|
+
return '2';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return 'UNSUPPORTED';
|
|
134
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
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.transform = transform;
|
|
16
|
+
|
|
17
|
+
var _transformAST = require("./transformAST");
|
|
18
|
+
|
|
19
|
+
var _parse = require("./parse");
|
|
20
|
+
|
|
21
|
+
var _print = require("./print");
|
|
22
|
+
|
|
23
|
+
async function transform(originalCode, visitors, prettierOptions = {}) {
|
|
24
|
+
const parseResult = await (0, _parse.parse)(originalCode);
|
|
25
|
+
const {
|
|
26
|
+
ast,
|
|
27
|
+
astWasMutated,
|
|
28
|
+
mutatedCode
|
|
29
|
+
} = (0, _transformAST.transformAST)(parseResult, visitors);
|
|
30
|
+
|
|
31
|
+
if (!astWasMutated) {
|
|
32
|
+
return originalCode;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (0, _print.print)(ast, mutatedCode, prettierOptions);
|
|
36
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
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.transformAST = transformAST;
|
|
16
|
+
|
|
17
|
+
var _detachedNode = require("../detachedNode");
|
|
18
|
+
|
|
19
|
+
var _traverse = require("../traverse/traverse");
|
|
20
|
+
|
|
21
|
+
var _MutationContext = require("./MutationContext");
|
|
22
|
+
|
|
23
|
+
var _TransformContext = require("./TransformContext");
|
|
24
|
+
|
|
25
|
+
var _AddComments = require("./mutations/AddComments");
|
|
26
|
+
|
|
27
|
+
var _CloneCommentsTo = require("./mutations/CloneCommentsTo");
|
|
28
|
+
|
|
29
|
+
var _InsertStatement = require("./mutations/InsertStatement");
|
|
30
|
+
|
|
31
|
+
var _RemoveComment = require("./mutations/RemoveComment");
|
|
32
|
+
|
|
33
|
+
var _RemoveNode = require("./mutations/RemoveNode");
|
|
34
|
+
|
|
35
|
+
var _RemoveStatement = require("./mutations/RemoveStatement");
|
|
36
|
+
|
|
37
|
+
var _ReplaceNode = require("./mutations/ReplaceNode");
|
|
38
|
+
|
|
39
|
+
var _ReplaceStatementWithMany = require("./mutations/ReplaceStatementWithMany");
|
|
40
|
+
|
|
41
|
+
var _ModifyNodeInPlace = require("./mutations/ModifyNodeInPlace");
|
|
42
|
+
|
|
43
|
+
function transformAST({
|
|
44
|
+
ast,
|
|
45
|
+
scopeManager,
|
|
46
|
+
code
|
|
47
|
+
}, visitors) {
|
|
48
|
+
// traverse the AST and collect the mutations
|
|
49
|
+
const transformContext = (0, _TransformContext.getTransformContext)();
|
|
50
|
+
(0, _traverse.traverseWithContext)(code, ast, scopeManager, () => transformContext, visitors); // apply the mutations to the AST
|
|
51
|
+
|
|
52
|
+
const mutationContext = new _MutationContext.MutationContext(code);
|
|
53
|
+
const removeCommentMutations = [];
|
|
54
|
+
|
|
55
|
+
for (const mutation of transformContext.mutations) {
|
|
56
|
+
const mutationRoot = (() => {
|
|
57
|
+
switch (mutation.type) {
|
|
58
|
+
case 'modifyNodeInPlace':
|
|
59
|
+
{
|
|
60
|
+
return (0, _ModifyNodeInPlace.performModifyNodeInPlaceMutation)(mutationContext, mutation);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
case 'insertStatement':
|
|
64
|
+
{
|
|
65
|
+
return (0, _InsertStatement.performInsertStatementMutation)(mutationContext, mutation);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
case 'replaceNode':
|
|
69
|
+
{
|
|
70
|
+
return (0, _ReplaceNode.performReplaceNodeMutation)(mutationContext, mutation);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
case 'replaceStatementWithMany':
|
|
74
|
+
{
|
|
75
|
+
return (0, _ReplaceStatementWithMany.performReplaceStatementWithManyMutation)(mutationContext, mutation);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
case 'removeNode':
|
|
79
|
+
{
|
|
80
|
+
return (0, _RemoveNode.performRemoveNodeMutation)(mutationContext, mutation);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
case 'removeStatement':
|
|
84
|
+
{
|
|
85
|
+
return (0, _RemoveStatement.performRemoveStatementMutation)(mutationContext, mutation);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
case 'removeComment':
|
|
89
|
+
{
|
|
90
|
+
// these are handled later
|
|
91
|
+
removeCommentMutations.push(mutation);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
case 'addComments':
|
|
96
|
+
{
|
|
97
|
+
return (0, _AddComments.performAddCommentsMutation)(mutationContext, mutation);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
case 'cloneCommentsTo':
|
|
101
|
+
{
|
|
102
|
+
return (0, _CloneCommentsTo.performCloneCommentsToMutation)(mutationContext, mutation);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
})(); // ensure the subtree's parent pointers are correct
|
|
106
|
+
// this is required for two reasons:
|
|
107
|
+
// 1) The userland transform is just JS - so there's nothing stopping them
|
|
108
|
+
// from doing anything dodgy. The flow types have some enforcement, but
|
|
109
|
+
// ofc that can just be ignored with a suppression.
|
|
110
|
+
// 2) Shallow clones are a necessary evil in the transform because they
|
|
111
|
+
// allow codemods to do simple changes to just one node without the
|
|
112
|
+
// weight that comes with deeply cloning the entire AST.
|
|
113
|
+
// However we can't update the parent pointers of the cloned node's
|
|
114
|
+
// children until the mutation step or else we would be mutating
|
|
115
|
+
// real AST nodes and potentially break the traverse step.
|
|
116
|
+
//
|
|
117
|
+
// Being strict here just helps us ensure we keep everything in sync
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if (mutationRoot) {
|
|
121
|
+
(0, _detachedNode.updateAllParentPointers)(mutationRoot);
|
|
122
|
+
}
|
|
123
|
+
} // remove the comments
|
|
124
|
+
// this is done at the end because it requires a complete traversal of the AST
|
|
125
|
+
// so that we can find relevant node's attachment array
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
(0, _RemoveComment.performRemoveCommentMutations)(ast, removeCommentMutations);
|
|
129
|
+
return {
|
|
130
|
+
ast,
|
|
131
|
+
astWasMutated: transformContext.astWasMutated,
|
|
132
|
+
mutatedCode: mutationContext.code
|
|
133
|
+
};
|
|
134
|
+
}
|