flow-api-translator 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.
- package/LICENSE +21 -0
- package/README.md +44 -0
- package/dist/flowDefToTSDef.js +2325 -0
- package/dist/flowDefToTSDef.js.flow +2507 -0
- package/dist/flowImportTo.js +73 -0
- package/dist/flowImportTo.js.flow +73 -0
- package/dist/flowToFlowDef.js +932 -0
- package/dist/flowToFlowDef.js.flow +1303 -0
- package/dist/flowToJS.js +188 -0
- package/dist/flowToJS.js.flow +166 -0
- package/dist/index.js +78 -0
- package/dist/index.js.flow +84 -0
- package/dist/utils/DocblockUtils.js +33 -0
- package/dist/utils/DocblockUtils.js.flow +36 -0
- package/dist/utils/ErrorUtils.js +102 -0
- package/dist/utils/ErrorUtils.js.flow +100 -0
- package/dist/utils/FlowAnalyze.js +55 -0
- package/dist/utils/FlowAnalyze.js.flow +47 -0
- package/dist/utils/TranslationUtils.js +42 -0
- package/dist/utils/TranslationUtils.js.flow +44 -0
- package/dist/utils/ts-estree-ast-types.js +30 -0
- package/dist/utils/ts-estree-ast-types.js.flow +2052 -0
- package/package.json +27 -0
package/dist/flowToJS.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
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.flowToJS = flowToJS;
|
|
16
|
+
|
|
17
|
+
var _DocblockUtils = require("./utils/DocblockUtils");
|
|
18
|
+
|
|
19
|
+
var _hermesParser = require("hermes-parser");
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
nodeWith
|
|
23
|
+
} = _hermesParser.astNodeMutationHelpers;
|
|
24
|
+
|
|
25
|
+
function transform(node) {
|
|
26
|
+
switch (node.type) {
|
|
27
|
+
case 'Program':
|
|
28
|
+
{
|
|
29
|
+
const docblock = node.docblock;
|
|
30
|
+
|
|
31
|
+
if (docblock == null) {
|
|
32
|
+
return node;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return nodeWith(node, {
|
|
36
|
+
docblock: (0, _DocblockUtils.removeAtFlowFromDocblock)(docblock)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
case 'TypeCastExpression':
|
|
41
|
+
{
|
|
42
|
+
return node.expression;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
case 'CallExpression':
|
|
46
|
+
case 'NewExpression':
|
|
47
|
+
{
|
|
48
|
+
if (node.typeArguments != null) {
|
|
49
|
+
return nodeWith(node, {
|
|
50
|
+
typeArguments: null
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return node;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
case 'ObjectPattern':
|
|
58
|
+
case 'ArrayPattern':
|
|
59
|
+
case 'Identifier':
|
|
60
|
+
{
|
|
61
|
+
if (node.typeAnnotation != null) {
|
|
62
|
+
return nodeWith(node, {
|
|
63
|
+
typeAnnotation: null
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return node;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
case 'DeclareClass':
|
|
71
|
+
case 'DeclareFunction':
|
|
72
|
+
case 'DeclareInterface':
|
|
73
|
+
case 'DeclareModule':
|
|
74
|
+
case 'DeclareModuleExports':
|
|
75
|
+
case 'DeclareOpaqueType':
|
|
76
|
+
case 'DeclareTypeAlias':
|
|
77
|
+
case 'DeclareVariable':
|
|
78
|
+
case 'InterfaceDeclaration':
|
|
79
|
+
case 'OpaqueType':
|
|
80
|
+
case 'TypeAlias':
|
|
81
|
+
{
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
case 'FunctionDeclaration':
|
|
86
|
+
case 'ArrowFunctionExpression':
|
|
87
|
+
case 'FunctionExpression':
|
|
88
|
+
{
|
|
89
|
+
const newParams = [];
|
|
90
|
+
|
|
91
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
92
|
+
if (i === 0 && node.params[0].type === 'Identifier' && node.params[0].name === 'this') {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let param = node.params[i];
|
|
97
|
+
|
|
98
|
+
if (param.type === 'AssignmentPattern') {
|
|
99
|
+
param = param.left;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (param.optional === true) {
|
|
103
|
+
param = nodeWith(param, {
|
|
104
|
+
optional: false
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
newParams.push(param);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return nodeWith(node, {
|
|
112
|
+
params: newParams,
|
|
113
|
+
returnType: null,
|
|
114
|
+
typeParameters: null,
|
|
115
|
+
predicate: null
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
case 'ClassDeclaration':
|
|
120
|
+
case 'ClassExpression':
|
|
121
|
+
{
|
|
122
|
+
return nodeWith(node, {
|
|
123
|
+
typeParameters: null,
|
|
124
|
+
superTypeParameters: null,
|
|
125
|
+
implements: [],
|
|
126
|
+
decorators: []
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
case 'PropertyDefinition':
|
|
131
|
+
{
|
|
132
|
+
return nodeWith(node, {
|
|
133
|
+
typeAnnotation: null,
|
|
134
|
+
variance: null,
|
|
135
|
+
declare: false,
|
|
136
|
+
optional: false
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
case 'ImportDeclaration':
|
|
141
|
+
{
|
|
142
|
+
if (node.importKind === 'type' || node.importKind === 'typeof') {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const nonTypeSpecifiers = node.specifiers.filter(s => s.type !== 'ImportSpecifier' || s.importKind !== 'type' && s.importKind !== 'typeof');
|
|
147
|
+
|
|
148
|
+
if (nonTypeSpecifiers.length === 0) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (nonTypeSpecifiers.length === node.specifiers.length) {
|
|
153
|
+
return node;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return nodeWith(node, {
|
|
157
|
+
specifiers: nonTypeSpecifiers
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
case 'ExportAllDeclaration':
|
|
162
|
+
case 'ExportNamedDeclaration':
|
|
163
|
+
{
|
|
164
|
+
if (node.exportKind === 'type') {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return node;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
default:
|
|
172
|
+
{
|
|
173
|
+
return node;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function flowToJS(sourceAST, _code, _scopeManager) {
|
|
179
|
+
const result = _hermesParser.SimpleTransform.transform(sourceAST, {
|
|
180
|
+
transform
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (result == null || result.type !== 'Program') {
|
|
184
|
+
throw new Error('flowToJS: Unexpected transform result.');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
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 {ScopeManager} from 'hermes-eslint';
|
|
14
|
+
import type {ESNode, Program} from 'hermes-estree';
|
|
15
|
+
|
|
16
|
+
import {removeAtFlowFromDocblock} from './utils/DocblockUtils';
|
|
17
|
+
|
|
18
|
+
import {SimpleTransform, astNodeMutationHelpers} from 'hermes-parser';
|
|
19
|
+
const {nodeWith} = astNodeMutationHelpers;
|
|
20
|
+
|
|
21
|
+
function transform(node: ESNode): ESNode | null {
|
|
22
|
+
switch (node.type) {
|
|
23
|
+
case 'Program': {
|
|
24
|
+
const docblock = node.docblock;
|
|
25
|
+
if (docblock == null) {
|
|
26
|
+
return node;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return nodeWith(node, {
|
|
30
|
+
docblock: removeAtFlowFromDocblock(docblock),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
case 'TypeCastExpression': {
|
|
35
|
+
return node.expression;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
case 'CallExpression':
|
|
39
|
+
case 'NewExpression': {
|
|
40
|
+
if (node.typeArguments != null) {
|
|
41
|
+
return nodeWith(node, {typeArguments: null});
|
|
42
|
+
}
|
|
43
|
+
return node;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
case 'ObjectPattern':
|
|
47
|
+
case 'ArrayPattern':
|
|
48
|
+
case 'Identifier': {
|
|
49
|
+
if (node.typeAnnotation != null) {
|
|
50
|
+
return nodeWith(node, {typeAnnotation: null});
|
|
51
|
+
}
|
|
52
|
+
return node;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
case 'DeclareClass':
|
|
56
|
+
case 'DeclareFunction':
|
|
57
|
+
case 'DeclareInterface':
|
|
58
|
+
case 'DeclareModule':
|
|
59
|
+
case 'DeclareModuleExports':
|
|
60
|
+
case 'DeclareOpaqueType':
|
|
61
|
+
case 'DeclareTypeAlias':
|
|
62
|
+
case 'DeclareVariable':
|
|
63
|
+
case 'InterfaceDeclaration':
|
|
64
|
+
case 'OpaqueType':
|
|
65
|
+
case 'TypeAlias': {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
case 'FunctionDeclaration':
|
|
70
|
+
case 'ArrowFunctionExpression':
|
|
71
|
+
case 'FunctionExpression': {
|
|
72
|
+
const newParams = [];
|
|
73
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
74
|
+
if (
|
|
75
|
+
i === 0 &&
|
|
76
|
+
node.params[0].type === 'Identifier' &&
|
|
77
|
+
node.params[0].name === 'this'
|
|
78
|
+
) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let param = node.params[i];
|
|
83
|
+
if (param.type === 'AssignmentPattern') {
|
|
84
|
+
param = param.left;
|
|
85
|
+
}
|
|
86
|
+
if (param.optional === true) {
|
|
87
|
+
param = nodeWith(param, {optional: false});
|
|
88
|
+
}
|
|
89
|
+
newParams.push(param);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return nodeWith(node, {
|
|
93
|
+
params: newParams,
|
|
94
|
+
returnType: null,
|
|
95
|
+
typeParameters: null,
|
|
96
|
+
predicate: null,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
case 'ClassDeclaration':
|
|
101
|
+
case 'ClassExpression': {
|
|
102
|
+
return nodeWith(node, {
|
|
103
|
+
typeParameters: null,
|
|
104
|
+
superTypeParameters: null,
|
|
105
|
+
implements: [],
|
|
106
|
+
decorators: [],
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
case 'PropertyDefinition': {
|
|
111
|
+
return nodeWith(node, {
|
|
112
|
+
typeAnnotation: null,
|
|
113
|
+
variance: null,
|
|
114
|
+
declare: false,
|
|
115
|
+
optional: false,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
case 'ImportDeclaration': {
|
|
120
|
+
if (node.importKind === 'type' || node.importKind === 'typeof') {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const nonTypeSpecifiers = node.specifiers.filter(
|
|
124
|
+
s =>
|
|
125
|
+
s.type !== 'ImportSpecifier' ||
|
|
126
|
+
(s.importKind !== 'type' && s.importKind !== 'typeof'),
|
|
127
|
+
);
|
|
128
|
+
if (nonTypeSpecifiers.length === 0) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
if (nonTypeSpecifiers.length === node.specifiers.length) {
|
|
132
|
+
return node;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return nodeWith(node, {
|
|
136
|
+
specifiers: nonTypeSpecifiers,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
case 'ExportAllDeclaration':
|
|
141
|
+
case 'ExportNamedDeclaration': {
|
|
142
|
+
if (node.exportKind === 'type') {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
return node;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
default: {
|
|
149
|
+
return node;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function flowToJS(
|
|
155
|
+
sourceAST: Program,
|
|
156
|
+
_code: string,
|
|
157
|
+
_scopeManager: ScopeManager,
|
|
158
|
+
): Program {
|
|
159
|
+
const result = SimpleTransform.transform(sourceAST, {
|
|
160
|
+
transform,
|
|
161
|
+
});
|
|
162
|
+
if (result == null || result.type !== 'Program') {
|
|
163
|
+
throw new Error('flowToJS: Unexpected transform result.');
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
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.translateFlowDefToTSDef = translateFlowDefToTSDef;
|
|
16
|
+
exports.translateFlowImportsTo = translateFlowImportsTo;
|
|
17
|
+
exports.translateFlowToFlowDef = translateFlowToFlowDef;
|
|
18
|
+
exports.translateFlowToJS = translateFlowToJS;
|
|
19
|
+
exports.translateFlowToTSDef = translateFlowToTSDef;
|
|
20
|
+
|
|
21
|
+
var _hermesTransform = require("hermes-transform");
|
|
22
|
+
|
|
23
|
+
var _visitorKeys = require("@typescript-eslint/visitor-keys");
|
|
24
|
+
|
|
25
|
+
var _flowToFlowDef = _interopRequireDefault(require("./flowToFlowDef"));
|
|
26
|
+
|
|
27
|
+
var _flowDefToTSDef = require("./flowDefToTSDef");
|
|
28
|
+
|
|
29
|
+
var _flowToJS = require("./flowToJS");
|
|
30
|
+
|
|
31
|
+
var _flowImportTo = require("./flowImportTo");
|
|
32
|
+
|
|
33
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
34
|
+
|
|
35
|
+
function translateFlowToFlowDef(code, prettierOptions = {}) {
|
|
36
|
+
const {
|
|
37
|
+
ast,
|
|
38
|
+
scopeManager
|
|
39
|
+
} = (0, _hermesTransform.parse)(code);
|
|
40
|
+
const [flowDefAst, mutatedCode] = (0, _flowToFlowDef.default)(ast, code, scopeManager, {
|
|
41
|
+
recoverFromErrors: true
|
|
42
|
+
});
|
|
43
|
+
return (0, _hermesTransform.print)(flowDefAst, mutatedCode, prettierOptions);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function translateFlowToTSDef(code, prettierOptions = {}) {
|
|
47
|
+
const flowDefCode = translateFlowToFlowDef(code, prettierOptions);
|
|
48
|
+
return translateFlowDefToTSDef(flowDefCode, prettierOptions);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function translateFlowDefToTSDef(code, prettierOptions = {}) {
|
|
52
|
+
const {
|
|
53
|
+
ast,
|
|
54
|
+
scopeManager
|
|
55
|
+
} = (0, _hermesTransform.parse)(code);
|
|
56
|
+
const tsAST = (0, _flowDefToTSDef.flowDefToTSDef)(code, ast, scopeManager);
|
|
57
|
+
return (0, _hermesTransform.print)( // $FlowExpectedError[incompatible-call] - this is fine as we're providing the visitor keys
|
|
58
|
+
tsAST, code, { ...prettierOptions
|
|
59
|
+
}, _visitorKeys.visitorKeys);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function translateFlowToJS(code, prettierOptions = {}) {
|
|
63
|
+
const {
|
|
64
|
+
ast,
|
|
65
|
+
scopeManager
|
|
66
|
+
} = (0, _hermesTransform.parse)(code);
|
|
67
|
+
const jsAST = (0, _flowToJS.flowToJS)(ast, code, scopeManager);
|
|
68
|
+
return (0, _hermesTransform.print)(jsAST, code, prettierOptions);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function translateFlowImportsTo(code, prettierOptions = {}, opts) {
|
|
72
|
+
const {
|
|
73
|
+
ast,
|
|
74
|
+
scopeManager
|
|
75
|
+
} = (0, _hermesTransform.parse)(code);
|
|
76
|
+
const jsAST = (0, _flowImportTo.flowImportTo)(ast, code, scopeManager, opts);
|
|
77
|
+
return (0, _hermesTransform.print)(jsAST, code, prettierOptions);
|
|
78
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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 {MapperOptions} from './flowImportTo';
|
|
14
|
+
|
|
15
|
+
import {parse, print} from 'hermes-transform';
|
|
16
|
+
import {visitorKeys as tsVisitorKeys} from '@typescript-eslint/visitor-keys';
|
|
17
|
+
import flowToFlowDef from './flowToFlowDef';
|
|
18
|
+
import {flowDefToTSDef} from './flowDefToTSDef';
|
|
19
|
+
import {flowToJS} from './flowToJS';
|
|
20
|
+
import {flowImportTo} from './flowImportTo';
|
|
21
|
+
|
|
22
|
+
export function translateFlowToFlowDef(
|
|
23
|
+
code: string,
|
|
24
|
+
prettierOptions: {...} = {},
|
|
25
|
+
): string {
|
|
26
|
+
const {ast, scopeManager} = parse(code);
|
|
27
|
+
|
|
28
|
+
const [flowDefAst, mutatedCode] = flowToFlowDef(ast, code, scopeManager, {
|
|
29
|
+
recoverFromErrors: true,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return print(flowDefAst, mutatedCode, prettierOptions);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function translateFlowToTSDef(
|
|
36
|
+
code: string,
|
|
37
|
+
prettierOptions: {...} = {},
|
|
38
|
+
): string {
|
|
39
|
+
const flowDefCode = translateFlowToFlowDef(code, prettierOptions);
|
|
40
|
+
|
|
41
|
+
return translateFlowDefToTSDef(flowDefCode, prettierOptions);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function translateFlowDefToTSDef(
|
|
45
|
+
code: string,
|
|
46
|
+
prettierOptions: {...} = {},
|
|
47
|
+
): string {
|
|
48
|
+
const {ast, scopeManager} = parse(code);
|
|
49
|
+
const tsAST = flowDefToTSDef(code, ast, scopeManager);
|
|
50
|
+
|
|
51
|
+
return print(
|
|
52
|
+
// $FlowExpectedError[incompatible-call] - this is fine as we're providing the visitor keys
|
|
53
|
+
tsAST,
|
|
54
|
+
code,
|
|
55
|
+
{
|
|
56
|
+
...prettierOptions,
|
|
57
|
+
},
|
|
58
|
+
tsVisitorKeys,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function translateFlowToJS(
|
|
63
|
+
code: string,
|
|
64
|
+
prettierOptions: {...} = {},
|
|
65
|
+
): string {
|
|
66
|
+
const {ast, scopeManager} = parse(code);
|
|
67
|
+
|
|
68
|
+
const jsAST = flowToJS(ast, code, scopeManager);
|
|
69
|
+
|
|
70
|
+
return print(jsAST, code, prettierOptions);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type {MapperOptions as FlowImportsMapperOptions};
|
|
74
|
+
export function translateFlowImportsTo(
|
|
75
|
+
code: string,
|
|
76
|
+
prettierOptions: {...} = {},
|
|
77
|
+
opts: MapperOptions,
|
|
78
|
+
): string {
|
|
79
|
+
const {ast, scopeManager} = parse(code);
|
|
80
|
+
|
|
81
|
+
const jsAST = flowImportTo(ast, code, scopeManager, opts);
|
|
82
|
+
|
|
83
|
+
return print(jsAST, code, prettierOptions);
|
|
84
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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.removeAtFlowFromDocblock = removeAtFlowFromDocblock;
|
|
16
|
+
const FLOW_DIRECTIVE = /(@flow(\s+(strict(-local)?|weak))?|@noflow)/;
|
|
17
|
+
|
|
18
|
+
function removeAtFlowFromDocblock(docblock) {
|
|
19
|
+
if (!FLOW_DIRECTIVE.test(docblock.comment.value)) {
|
|
20
|
+
return docblock;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
// $FlowExpectedError[cannot-spread-interface]
|
|
25
|
+
comment: { ...docblock.comment,
|
|
26
|
+
value: docblock.comment.value.replace(FLOW_DIRECTIVE, '')
|
|
27
|
+
},
|
|
28
|
+
directives: { ...docblock.directives,
|
|
29
|
+
flow: undefined,
|
|
30
|
+
noflow: undefined
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
import type {DocblockMetadata} from 'hermes-estree';
|
|
14
|
+
|
|
15
|
+
const FLOW_DIRECTIVE = /(@flow(\s+(strict(-local)?|weak))?|@noflow)/;
|
|
16
|
+
|
|
17
|
+
export function removeAtFlowFromDocblock(
|
|
18
|
+
docblock: DocblockMetadata,
|
|
19
|
+
): DocblockMetadata {
|
|
20
|
+
if (!FLOW_DIRECTIVE.test(docblock.comment.value)) {
|
|
21
|
+
return docblock;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
// $FlowExpectedError[cannot-spread-interface]
|
|
26
|
+
comment: {
|
|
27
|
+
...docblock.comment,
|
|
28
|
+
value: docblock.comment.value.replace(FLOW_DIRECTIVE, ''),
|
|
29
|
+
},
|
|
30
|
+
directives: {
|
|
31
|
+
...docblock.directives,
|
|
32
|
+
flow: undefined,
|
|
33
|
+
noflow: undefined,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
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.UnexpectedTranslationError = exports.ExpectedTranslationError = void 0;
|
|
16
|
+
exports.flowFixMeOrError = flowFixMeOrError;
|
|
17
|
+
exports.translationError = translationError;
|
|
18
|
+
exports.unexpectedTranslationError = unexpectedTranslationError;
|
|
19
|
+
|
|
20
|
+
var _hermesTransform = require("hermes-transform");
|
|
21
|
+
|
|
22
|
+
var _codeFrame = require("@babel/code-frame");
|
|
23
|
+
|
|
24
|
+
function flowFixMeOrError(container, message, context) {
|
|
25
|
+
if (context.recoverFromErrors) {
|
|
26
|
+
return _hermesTransform.t.GenericTypeAnnotation({
|
|
27
|
+
id: _hermesTransform.t.Identifier({
|
|
28
|
+
name: '$FlowFixMe'
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
throw translationError(container, message, context);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class TranslationErrorBase extends Error {
|
|
37
|
+
constructor(node, message, context) {
|
|
38
|
+
const framedMessage = buildCodeFrame(node, message, context.code);
|
|
39
|
+
super( // jest error snapshots will use a hard-coded string representation if
|
|
40
|
+
// `instanceof Error` which makes the code frame look awful and hard to verify:
|
|
41
|
+
//
|
|
42
|
+
// [TranslationError: > 12 | code
|
|
43
|
+
// | ^^^^ error]
|
|
44
|
+
//
|
|
45
|
+
// this just adds a newline in jest tests so that it all lines up nicely
|
|
46
|
+
//
|
|
47
|
+
// [TranslationError:
|
|
48
|
+
// > 12 | code
|
|
49
|
+
// | ^^^^ error]
|
|
50
|
+
process.env.JEST_WORKER_ID == null ? framedMessage : `\n${framedMessage}`);
|
|
51
|
+
this.name = 'TranslationError';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class ExpectedTranslationError extends TranslationErrorBase {
|
|
57
|
+
constructor(...args) {
|
|
58
|
+
super(...args);
|
|
59
|
+
this.name = 'ExpectedTranslationError';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
exports.ExpectedTranslationError = ExpectedTranslationError;
|
|
65
|
+
|
|
66
|
+
function translationError(node, message, context) {
|
|
67
|
+
return new ExpectedTranslationError(node, message, context);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class UnexpectedTranslationError extends TranslationErrorBase {
|
|
71
|
+
constructor(...args) {
|
|
72
|
+
super(...args);
|
|
73
|
+
this.name = 'UnexpectedTranslationError';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
exports.UnexpectedTranslationError = UnexpectedTranslationError;
|
|
79
|
+
|
|
80
|
+
function unexpectedTranslationError(node, message, context) {
|
|
81
|
+
return new UnexpectedTranslationError(node, message, context);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function buildCodeFrame(node, message, code) {
|
|
85
|
+
// babel uses 1-indexed columns
|
|
86
|
+
const locForBabel = {
|
|
87
|
+
start: {
|
|
88
|
+
line: node.loc.start.line,
|
|
89
|
+
column: node.loc.start.column + 1
|
|
90
|
+
},
|
|
91
|
+
end: {
|
|
92
|
+
line: node.loc.end.line,
|
|
93
|
+
column: node.loc.end.column + 1
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
return (0, _codeFrame.codeFrameColumns)(code, locForBabel, {
|
|
97
|
+
linesAbove: 0,
|
|
98
|
+
linesBelow: 0,
|
|
99
|
+
highlightCode: process.env.NODE_ENV !== 'test',
|
|
100
|
+
message: message
|
|
101
|
+
});
|
|
102
|
+
}
|