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
|
@@ -0,0 +1,100 @@
|
|
|
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 {ObjectWithLoc, TypeAnnotationType} from 'hermes-estree';
|
|
14
|
+
import type {TranslationContext} from './TranslationUtils';
|
|
15
|
+
import type {DetachedNode} from 'hermes-transform';
|
|
16
|
+
|
|
17
|
+
import {t} from 'hermes-transform';
|
|
18
|
+
import {codeFrameColumns} from '@babel/code-frame';
|
|
19
|
+
|
|
20
|
+
export function flowFixMeOrError(
|
|
21
|
+
container: ObjectWithLoc,
|
|
22
|
+
message: string,
|
|
23
|
+
context: TranslationContext,
|
|
24
|
+
): DetachedNode<TypeAnnotationType> {
|
|
25
|
+
if (context.recoverFromErrors) {
|
|
26
|
+
return t.GenericTypeAnnotation({id: t.Identifier({name: '$FlowFixMe'})});
|
|
27
|
+
}
|
|
28
|
+
throw translationError(container, message, context);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class TranslationErrorBase extends Error {
|
|
32
|
+
name: string = 'TranslationError';
|
|
33
|
+
constructor(
|
|
34
|
+
node: ObjectWithLoc,
|
|
35
|
+
message: string,
|
|
36
|
+
context: $ReadOnly<{code: string, ...}>,
|
|
37
|
+
) {
|
|
38
|
+
const framedMessage = buildCodeFrame(node, message, context.code);
|
|
39
|
+
super(
|
|
40
|
+
// jest error snapshots will use a hard-coded string representation if
|
|
41
|
+
// `instanceof Error` which makes the code frame look awful and hard to verify:
|
|
42
|
+
//
|
|
43
|
+
// [TranslationError: > 12 | code
|
|
44
|
+
// | ^^^^ error]
|
|
45
|
+
//
|
|
46
|
+
// this just adds a newline in jest tests so that it all lines up nicely
|
|
47
|
+
//
|
|
48
|
+
// [TranslationError:
|
|
49
|
+
// > 12 | code
|
|
50
|
+
// | ^^^^ error]
|
|
51
|
+
process.env.JEST_WORKER_ID == null ? framedMessage : `\n${framedMessage}`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class ExpectedTranslationError extends TranslationErrorBase {
|
|
57
|
+
name: string = 'ExpectedTranslationError';
|
|
58
|
+
}
|
|
59
|
+
export function translationError(
|
|
60
|
+
node: ObjectWithLoc,
|
|
61
|
+
message: string,
|
|
62
|
+
context: $ReadOnly<{code: string, ...}>,
|
|
63
|
+
): Error {
|
|
64
|
+
return new ExpectedTranslationError(node, message, context);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export class UnexpectedTranslationError extends TranslationErrorBase {
|
|
68
|
+
name: string = 'UnexpectedTranslationError';
|
|
69
|
+
}
|
|
70
|
+
export function unexpectedTranslationError(
|
|
71
|
+
node: ObjectWithLoc,
|
|
72
|
+
message: string,
|
|
73
|
+
context: $ReadOnly<{code: string, ...}>,
|
|
74
|
+
): Error {
|
|
75
|
+
return new UnexpectedTranslationError(node, message, context);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function buildCodeFrame(
|
|
79
|
+
node: ObjectWithLoc,
|
|
80
|
+
message: string,
|
|
81
|
+
code: string,
|
|
82
|
+
): string {
|
|
83
|
+
// babel uses 1-indexed columns
|
|
84
|
+
const locForBabel = {
|
|
85
|
+
start: {
|
|
86
|
+
line: node.loc.start.line,
|
|
87
|
+
column: node.loc.start.column + 1,
|
|
88
|
+
},
|
|
89
|
+
end: {
|
|
90
|
+
line: node.loc.end.line,
|
|
91
|
+
column: node.loc.end.column + 1,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
return codeFrameColumns(code, locForBabel, {
|
|
95
|
+
linesAbove: 0,
|
|
96
|
+
linesBelow: 0,
|
|
97
|
+
highlightCode: process.env.NODE_ENV !== 'test',
|
|
98
|
+
message: message,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
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.analyzeFunctionReturn = analyzeFunctionReturn;
|
|
16
|
+
exports.analyzeTypeDependencies = analyzeTypeDependencies;
|
|
17
|
+
|
|
18
|
+
var _hermesTransform = require("hermes-transform");
|
|
19
|
+
|
|
20
|
+
var _hermesParser = require("hermes-parser");
|
|
21
|
+
|
|
22
|
+
function analyzeFunctionReturn(func) {
|
|
23
|
+
const returnType = func.returnType;
|
|
24
|
+
|
|
25
|
+
if (returnType != null) {
|
|
26
|
+
return returnType;
|
|
27
|
+
} // We trust Flow has validated this function to only return void
|
|
28
|
+
// $FlowFixMe[incompatible-return]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
return _hermesTransform.t.TypeAnnotation({
|
|
32
|
+
typeAnnotation: _hermesTransform.t.VoidTypeAnnotation()
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function analyzeTypeDependencies(rootNode, context) {
|
|
37
|
+
const deps = [];
|
|
38
|
+
|
|
39
|
+
_hermesParser.SimpleTraverser.traverse(rootNode, {
|
|
40
|
+
enter(node) {
|
|
41
|
+
if (node.type === 'Identifier' || node.type === 'JSXIdentifier') {
|
|
42
|
+
const variable = context.referenceMap.get(node);
|
|
43
|
+
|
|
44
|
+
if (variable != null) {
|
|
45
|
+
deps.push(variable.name);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
leave() {}
|
|
51
|
+
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return deps;
|
|
55
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
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 {AFunction, TypeAnnotation, ESNode} from 'hermes-estree';
|
|
14
|
+
import type {TranslationContext, Dep} from './TranslationUtils';
|
|
15
|
+
|
|
16
|
+
import {t} from 'hermes-transform';
|
|
17
|
+
import {SimpleTraverser} from 'hermes-parser';
|
|
18
|
+
|
|
19
|
+
export function analyzeFunctionReturn(func: AFunction): TypeAnnotation {
|
|
20
|
+
const returnType = func.returnType;
|
|
21
|
+
if (returnType != null) {
|
|
22
|
+
return returnType;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// We trust Flow has validated this function to only return void
|
|
26
|
+
// $FlowFixMe[incompatible-return]
|
|
27
|
+
return t.TypeAnnotation({typeAnnotation: t.VoidTypeAnnotation()});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function analyzeTypeDependencies(
|
|
31
|
+
rootNode: ESNode,
|
|
32
|
+
context: TranslationContext,
|
|
33
|
+
): $ReadOnlyArray<Dep> {
|
|
34
|
+
const deps = [];
|
|
35
|
+
SimpleTraverser.traverse(rootNode, {
|
|
36
|
+
enter(node: ESNode) {
|
|
37
|
+
if (node.type === 'Identifier' || node.type === 'JSXIdentifier') {
|
|
38
|
+
const variable = context.referenceMap.get(node);
|
|
39
|
+
if (variable != null) {
|
|
40
|
+
deps.push(variable.name);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
leave() {},
|
|
45
|
+
});
|
|
46
|
+
return deps;
|
|
47
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
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.createTranslationContext = createTranslationContext;
|
|
16
|
+
|
|
17
|
+
function createTranslationContext(code, scopeManager, {
|
|
18
|
+
recoverFromErrors
|
|
19
|
+
}) {
|
|
20
|
+
const referenceMap = new Map();
|
|
21
|
+
const variableMap = new Map();
|
|
22
|
+
const moduleScope = scopeManager.globalScope.childScopes[0];
|
|
23
|
+
|
|
24
|
+
if (moduleScope == null || moduleScope.type !== 'module') {
|
|
25
|
+
throw new Error('createTranslationContext: Module scope not found');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (const variable of moduleScope.variables) {
|
|
29
|
+
for (const reference of variable.references) {
|
|
30
|
+
referenceMap.set(reference.identifier, variable);
|
|
31
|
+
variableMap.set(variable.name, variable);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
scopeManager,
|
|
37
|
+
referenceMap,
|
|
38
|
+
variableMap,
|
|
39
|
+
recoverFromErrors,
|
|
40
|
+
code
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
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 {Identifier, JSXIdentifier} from 'hermes-estree';
|
|
14
|
+
import type {ScopeManager, Variable} from 'hermes-eslint';
|
|
15
|
+
|
|
16
|
+
export type Dep = string;
|
|
17
|
+
export type TranslationOptions = {recoverFromErrors: boolean};
|
|
18
|
+
export type TranslationContext = {
|
|
19
|
+
scopeManager: ScopeManager,
|
|
20
|
+
referenceMap: Map<Identifier | JSXIdentifier, Variable>,
|
|
21
|
+
variableMap: Map<Dep, Variable>,
|
|
22
|
+
recoverFromErrors: boolean,
|
|
23
|
+
code: string,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function createTranslationContext(
|
|
27
|
+
code: string,
|
|
28
|
+
scopeManager: ScopeManager,
|
|
29
|
+
{recoverFromErrors}: TranslationOptions,
|
|
30
|
+
): TranslationContext {
|
|
31
|
+
const referenceMap = new Map<Identifier | JSXIdentifier, Variable>();
|
|
32
|
+
const variableMap = new Map<Dep, Variable>();
|
|
33
|
+
const moduleScope = scopeManager.globalScope.childScopes[0];
|
|
34
|
+
if (moduleScope == null || moduleScope.type !== 'module') {
|
|
35
|
+
throw new Error('createTranslationContext: Module scope not found');
|
|
36
|
+
}
|
|
37
|
+
for (const variable of moduleScope.variables) {
|
|
38
|
+
for (const reference of variable.references) {
|
|
39
|
+
referenceMap.set(reference.identifier, variable);
|
|
40
|
+
variableMap.set(variable.name, variable);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {scopeManager, referenceMap, variableMap, recoverFromErrors, code};
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The following types have been adapted by hand from
|
|
13
|
+
* https://unpkg.com/browse/@typescript-eslint/types@5.41.0/dist/generated/ast-spec.d.ts
|
|
14
|
+
*
|
|
15
|
+
* Changes:
|
|
16
|
+
* - remove and inline `ValueOf` type
|
|
17
|
+
* - `undefined` -> `void`
|
|
18
|
+
* - remove all `declare` keywords
|
|
19
|
+
* - comment out `bigint` type
|
|
20
|
+
* -> flow doesn't support it yet
|
|
21
|
+
* - remove `range` and `loc` from `NodeOrTokenData`
|
|
22
|
+
* -> during conversion our locations will be all off, so we'll rely on prettier to print later
|
|
23
|
+
* - make all properties readonly and all arrays $ReadOnlyArray
|
|
24
|
+
* -> unlike TS - flow enforces subtype constraints strictly!
|
|
25
|
+
* - add `type` to interfaces that previously relied upon inheriting the `type`
|
|
26
|
+
* -> this is because flow sentinel refinement does not check inherited members
|
|
27
|
+
* - create "Ambiguous" versions for some nodes that have unions (like PropertyDefinition, MemberDefinition)
|
|
28
|
+
* -> makes it easier to construct them from other nodes that have unions
|
|
29
|
+
*/
|
|
30
|
+
'use strict';
|