flow-api-translator 0.15.1 → 0.17.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.
@@ -265,9 +265,15 @@ function stripUnusedDefs(detachedStmt, usedDeps, context) {
265
265
 
266
266
  function convertStatement(stmt, context) {
267
267
  switch (stmt.type) {
268
+ case 'ComponentDeclaration':
269
+ {
270
+ const [result, deps] = convertComponentDeclaration(stmt, context);
271
+ return [result, deps];
272
+ }
273
+
268
274
  case 'FunctionDeclaration':
269
275
  {
270
- const [result, deps] = convertFunctionDeclation(stmt, context);
276
+ const [result, deps] = convertFunctionDeclaration(stmt, context);
271
277
  return [result, deps];
272
278
  }
273
279
 
@@ -491,9 +497,19 @@ function convertLiteral(expr, context) {
491
497
 
492
498
  function convertExportDeclaration(decl, opts, context) {
493
499
  switch (decl.type) {
500
+ case 'ComponentDeclaration':
501
+ {
502
+ const [declDecl, deps] = convertComponentDeclaration(decl, context);
503
+ return [opts.default ? _hermesTransform.t.DeclareExportDefaultDeclaration({
504
+ declaration: declDecl
505
+ }) : _hermesTransform.t.DeclareExportDeclarationNamedWithDeclaration({
506
+ declaration: declDecl
507
+ }), deps];
508
+ }
509
+
494
510
  case 'FunctionDeclaration':
495
511
  {
496
- const [declDecl, deps] = convertFunctionDeclation(decl, context);
512
+ const [declDecl, deps] = convertFunctionDeclaration(decl, context);
497
513
  return [opts.default ? _hermesTransform.t.DeclareExportDefaultDeclaration({
498
514
  declaration: declDecl
499
515
  }) : _hermesTransform.t.DeclareExportDeclarationNamedWithDeclaration({
@@ -588,6 +604,20 @@ function convertExportDeclaration(decl, opts, context) {
588
604
  }
589
605
 
590
606
  function convertExportDefaultDeclaration(stmt, context) {
607
+ const expr = stmt.declaration;
608
+
609
+ if ((0, _hermesEstree.isExpression)(expr) && expr.type === 'Identifier') {
610
+ const name = expr.name;
611
+ const [declDecl, deps] = [_hermesTransform.t.TypeofTypeAnnotation({
612
+ argument: _hermesTransform.t.Identifier({
613
+ name
614
+ })
615
+ }), (0, _FlowAnalyze.analyzeTypeDependencies)(expr, context)];
616
+ return [_hermesTransform.t.DeclareExportDefaultDeclaration({
617
+ declaration: declDecl
618
+ }), deps];
619
+ }
620
+
591
621
  return convertExportDeclaration(stmt.declaration, {
592
622
  default: true
593
623
  }, context);
@@ -637,6 +667,14 @@ function convertVariableDeclaration(stmt, context) {
637
667
  return [(0, _ErrorUtils.flowFixMeOrError)(first, `VariableDeclaration: Type annotation missing`, context), []];
638
668
  }
639
669
 
670
+ if (init.type === 'Identifier') {
671
+ return [_hermesTransform.t.TypeofTypeAnnotation({
672
+ argument: _hermesTransform.t.Identifier({
673
+ name: init.name
674
+ })
675
+ }), (0, _FlowAnalyze.analyzeTypeDependencies)(init, context)];
676
+ }
677
+
640
678
  return convertExpressionToTypeAnnotation(init, context);
641
679
  })();
642
680
 
@@ -783,7 +821,86 @@ function convertClassMember(member, context) {
783
821
  }
784
822
  }
785
823
 
786
- function convertFunctionDeclation(func, context) {
824
+ function convertComponentDeclaration(comp, context) {
825
+ const [resultTypeParams, typeParamsDeps] = convertTypeParameterDeclarationOrNull(comp.typeParameters, context);
826
+ const [resultParams, resultRestParam, paramsAndRestDeps] = convertComponentParameters(comp.params, context);
827
+
828
+ const [resultRendersType, rendersTypeDeps] = (() => {
829
+ const rendersType = comp.rendersType;
830
+
831
+ if (rendersType == null) {
832
+ return EMPTY_TRANSLATION_RESULT;
833
+ }
834
+
835
+ return [(0, _hermesTransform.asDetachedNode)(rendersType), (0, _FlowAnalyze.analyzeTypeDependencies)(rendersType, context)];
836
+ })();
837
+
838
+ return [_hermesTransform.t.DeclareComponent({
839
+ id: comp.id,
840
+ params: resultParams,
841
+ rest: resultRestParam,
842
+ typeParameters: resultTypeParams,
843
+ rendersType: resultRendersType
844
+ }), [...typeParamsDeps, ...paramsAndRestDeps, ...rendersTypeDeps]];
845
+ }
846
+
847
+ function convertComponentParameters(params, context) {
848
+ return params.reduce(([resultParams, restParam, paramsDeps], param) => {
849
+ switch (param.type) {
850
+ case 'ComponentParameter':
851
+ {
852
+ let optional = false;
853
+ let local = param.local;
854
+
855
+ if (local.type === 'AssignmentPattern') {
856
+ local = local.left;
857
+ optional = true;
858
+ }
859
+
860
+ if (!optional && local.type === 'Identifier') {
861
+ optional = local.optional;
862
+ }
863
+
864
+ const [typeAnnotationType, typeDeps] = convertTypeAnnotation(local.typeAnnotation, param, context);
865
+
866
+ const resultParam = _hermesTransform.t.ComponentTypeParameter({
867
+ name: (0, _hermesTransform.asDetachedNode)(param.name),
868
+ typeAnnotation: typeAnnotationType,
869
+ optional
870
+ });
871
+
872
+ return [[...resultParams, resultParam], restParam, [...paramsDeps, ...typeDeps]];
873
+ }
874
+
875
+ case 'RestElement':
876
+ {
877
+ if (restParam != null) {
878
+ throw (0, _ErrorUtils.translationError)(param, `ComponentParameter: Multiple rest elements found`, context);
879
+ }
880
+
881
+ const argument = param.argument;
882
+
883
+ if (argument.type === 'AssignmentPattern' || argument.type === 'ArrayPattern' || argument.type === 'RestElement') {
884
+ throw (0, _ErrorUtils.translationError)(param, `ComponentParameter: Invalid RestElement usage`, context);
885
+ }
886
+
887
+ const [typeAnnotationType, typeDeps] = convertTypeAnnotation(argument.typeAnnotation, argument, context);
888
+
889
+ const resultRestParam = _hermesTransform.t.ComponentTypeParameter({
890
+ name: _hermesTransform.t.Identifier({
891
+ name: argument.type === 'Identifier' ? argument.name : 'rest'
892
+ }),
893
+ typeAnnotation: typeAnnotationType,
894
+ optional: argument.type === 'Identifier' ? argument.optional : false
895
+ });
896
+
897
+ return [resultParams, resultRestParam, [...paramsDeps, ...typeDeps]];
898
+ }
899
+ }
900
+ }, [[], null, []]);
901
+ }
902
+
903
+ function convertFunctionDeclaration(func, context) {
787
904
  const id = func.id;
788
905
 
789
906
  if (id == null) {
@@ -18,7 +18,11 @@ import type {
18
18
  ClassMember,
19
19
  ClassPropertyNameComputed,
20
20
  ClassPropertyNameNonComputed,
21
+ ComponentDeclaration,
22
+ ComponentParameter,
23
+ ComponentTypeParameter,
21
24
  DeclareClass,
25
+ DeclareComponent,
22
26
  DeclareFunction,
23
27
  DeclareOpaqueType,
24
28
  DeclareVariable,
@@ -43,12 +47,14 @@ import type {
43
47
  ObjectTypeProperty,
44
48
  OpaqueType,
45
49
  Program,
50
+ RestElement,
46
51
  Statement,
47
52
  StringLiteral,
48
53
  TypeAlias,
49
54
  TypeAnnotation,
50
55
  TypeAnnotationType,
51
56
  TypeCastExpression,
57
+ TypeOperator,
52
58
  TypeParameterDeclaration,
53
59
  TypeParameterInstantiation,
54
60
  VariableDeclaration,
@@ -356,8 +362,12 @@ function convertStatement(
356
362
  context: TranslationContext,
357
363
  ): TranslatedResult<ProgramStatement> {
358
364
  switch (stmt.type) {
365
+ case 'ComponentDeclaration': {
366
+ const [result, deps] = convertComponentDeclaration(stmt, context);
367
+ return [result, deps];
368
+ }
359
369
  case 'FunctionDeclaration': {
360
- const [result, deps] = convertFunctionDeclation(stmt, context);
370
+ const [result, deps] = convertFunctionDeclaration(stmt, context);
361
371
  return [result, deps];
362
372
  }
363
373
  case 'ClassDeclaration': {
@@ -608,8 +618,21 @@ function convertExportDeclaration(
608
618
  context: TranslationContext,
609
619
  ): TranslatedResult<ProgramStatement> {
610
620
  switch (decl.type) {
621
+ case 'ComponentDeclaration': {
622
+ const [declDecl, deps] = convertComponentDeclaration(decl, context);
623
+ return [
624
+ opts.default
625
+ ? t.DeclareExportDefaultDeclaration({
626
+ declaration: declDecl,
627
+ })
628
+ : t.DeclareExportDeclarationNamedWithDeclaration({
629
+ declaration: declDecl,
630
+ }),
631
+ deps,
632
+ ];
633
+ }
611
634
  case 'FunctionDeclaration': {
612
- const [declDecl, deps] = convertFunctionDeclation(decl, context);
635
+ const [declDecl, deps] = convertFunctionDeclaration(decl, context);
613
636
  return [
614
637
  opts.default
615
638
  ? t.DeclareExportDefaultDeclaration({
@@ -744,6 +767,20 @@ function convertExportDefaultDeclaration(
744
767
  stmt: ExportDefaultDeclaration,
745
768
  context: TranslationContext,
746
769
  ): TranslatedResult<ProgramStatement> {
770
+ const expr = stmt.declaration;
771
+ if (isExpression(expr) && (expr: Expression).type === 'Identifier') {
772
+ const name = ((expr: $FlowFixMe): Identifier).name;
773
+ const [declDecl, deps] = [
774
+ t.TypeofTypeAnnotation({argument: t.Identifier({name})}),
775
+ analyzeTypeDependencies(expr, context),
776
+ ];
777
+ return [
778
+ t.DeclareExportDefaultDeclaration({
779
+ declaration: declDecl,
780
+ }),
781
+ deps,
782
+ ];
783
+ }
747
784
  return convertExportDeclaration(stmt.declaration, {default: true}, context);
748
785
  }
749
786
 
@@ -814,6 +851,13 @@ function convertVariableDeclaration(
814
851
  ];
815
852
  }
816
853
 
854
+ if (init.type === 'Identifier') {
855
+ return [
856
+ t.TypeofTypeAnnotation({argument: t.Identifier({name: init.name})}),
857
+ analyzeTypeDependencies(init, context),
858
+ ];
859
+ }
860
+
817
861
  return convertExpressionToTypeAnnotation(init, context);
818
862
  })();
819
863
 
@@ -1048,8 +1092,126 @@ function convertClassMember(
1048
1092
  }
1049
1093
  }
1050
1094
  }
1095
+ function convertComponentDeclaration(
1096
+ comp: ComponentDeclaration,
1097
+ context: TranslationContext,
1098
+ ): TranslatedResult<DeclareComponent> {
1099
+ const [resultTypeParams, typeParamsDeps] =
1100
+ convertTypeParameterDeclarationOrNull(comp.typeParameters, context);
1101
+
1102
+ const [resultParams, resultRestParam, paramsAndRestDeps] =
1103
+ convertComponentParameters(comp.params, context);
1104
+
1105
+ const [resultRendersType, rendersTypeDeps] = (() => {
1106
+ const rendersType = comp.rendersType;
1107
+ if (rendersType == null) {
1108
+ return EMPTY_TRANSLATION_RESULT;
1109
+ }
1110
+
1111
+ return [
1112
+ asDetachedNode<TypeOperator>(rendersType),
1113
+ analyzeTypeDependencies(rendersType, context),
1114
+ ];
1115
+ })();
1116
+
1117
+ return [
1118
+ t.DeclareComponent({
1119
+ id: comp.id,
1120
+ params: resultParams,
1121
+ rest: resultRestParam,
1122
+ typeParameters: resultTypeParams,
1123
+ rendersType: resultRendersType,
1124
+ }),
1125
+ [...typeParamsDeps, ...paramsAndRestDeps, ...rendersTypeDeps],
1126
+ ];
1127
+ }
1128
+
1129
+ type TranslatedComponentParametersResults = [
1130
+ $ReadOnlyArray<DetachedNode<ComponentTypeParameter>>,
1131
+ ?DetachedNode<ComponentTypeParameter>,
1132
+ TranslatedDeps,
1133
+ ];
1134
+
1135
+ function convertComponentParameters(
1136
+ params: $ReadOnlyArray<ComponentParameter | RestElement>,
1137
+ context: TranslationContext,
1138
+ ): TranslatedComponentParametersResults {
1139
+ return params.reduce<TranslatedComponentParametersResults>(
1140
+ ([resultParams, restParam, paramsDeps], param) => {
1141
+ switch (param.type) {
1142
+ case 'ComponentParameter': {
1143
+ let optional = false;
1144
+ let local = param.local;
1145
+ if (local.type === 'AssignmentPattern') {
1146
+ local = local.left;
1147
+ optional = true;
1148
+ }
1149
+ if (!optional && local.type === 'Identifier') {
1150
+ optional = local.optional;
1151
+ }
1152
+
1153
+ const [typeAnnotationType, typeDeps] = convertTypeAnnotation(
1154
+ local.typeAnnotation,
1155
+ param,
1156
+ context,
1157
+ );
1158
+
1159
+ const resultParam = t.ComponentTypeParameter({
1160
+ name: asDetachedNode(param.name),
1161
+ typeAnnotation: typeAnnotationType,
1162
+ optional,
1163
+ });
1164
+
1165
+ return [
1166
+ [...resultParams, resultParam],
1167
+ restParam,
1168
+ [...paramsDeps, ...typeDeps],
1169
+ ];
1170
+ }
1171
+ case 'RestElement': {
1172
+ if (restParam != null) {
1173
+ throw translationError(
1174
+ param,
1175
+ `ComponentParameter: Multiple rest elements found`,
1176
+ context,
1177
+ );
1178
+ }
1179
+ const argument = param.argument;
1180
+ if (
1181
+ argument.type === 'AssignmentPattern' ||
1182
+ argument.type === 'ArrayPattern' ||
1183
+ argument.type === 'RestElement'
1184
+ ) {
1185
+ throw translationError(
1186
+ param,
1187
+ `ComponentParameter: Invalid RestElement usage`,
1188
+ context,
1189
+ );
1190
+ }
1191
+ const [typeAnnotationType, typeDeps] = convertTypeAnnotation(
1192
+ argument.typeAnnotation,
1193
+ argument,
1194
+ context,
1195
+ );
1196
+
1197
+ const resultRestParam = t.ComponentTypeParameter({
1198
+ name: t.Identifier({
1199
+ name: argument.type === 'Identifier' ? argument.name : 'rest',
1200
+ }),
1201
+ typeAnnotation: typeAnnotationType,
1202
+ optional:
1203
+ argument.type === 'Identifier' ? argument.optional : false,
1204
+ });
1205
+
1206
+ return [resultParams, resultRestParam, [...paramsDeps, ...typeDeps]];
1207
+ }
1208
+ }
1209
+ },
1210
+ [[], null, []],
1211
+ );
1212
+ }
1051
1213
 
1052
- function convertFunctionDeclation(
1214
+ function convertFunctionDeclaration(
1053
1215
  func: FunctionDeclaration,
1054
1216
  context: TranslationContext,
1055
1217
  ): TranslatedResult<DeclareFunction> {
package/dist/flowToJS.js CHANGED
@@ -14,175 +14,26 @@ Object.defineProperty(exports, "__esModule", {
14
14
  });
15
15
  exports.flowToJS = flowToJS;
16
16
 
17
- var _DocblockUtils = require("./utils/DocblockUtils");
18
-
19
17
  var _hermesParser = require("hermes-parser");
20
18
 
19
+ var _DocblockUtils = require("./utils/DocblockUtils");
20
+
21
21
  const {
22
22
  nodeWith
23
23
  } = _hermesParser.astNodeMutationHelpers;
24
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
- }
25
+ function stripAtFlow(ast, _options) {
26
+ const docblock = ast.docblock;
107
27
 
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
- }
28
+ if (docblock == null) {
29
+ return ast;
175
30
  }
176
- }
177
31
 
178
- function flowToJS(sourceAST, _code, _scopeManager) {
179
- const result = _hermesParser.SimpleTransform.transform(sourceAST, {
180
- transform
32
+ return nodeWith(ast, {
33
+ docblock: (0, _DocblockUtils.removeAtFlowFromDocblock)(docblock)
181
34
  });
35
+ }
182
36
 
183
- if (result == null || result.type !== 'Program') {
184
- throw new Error('flowToJS: Unexpected transform result.');
185
- }
186
-
187
- return result;
37
+ function flowToJS(sourceAST, _code, _scopeManager) {
38
+ return [_hermesParser.Transforms.stripComponentSyntax, _hermesParser.Transforms.stripFlowTypes, stripAtFlow].reduce((ast, transform) => transform(ast, {}), sourceAST);
188
39
  }