hermes-transform 0.11.1 → 0.12.1

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.
@@ -55,6 +55,7 @@ export const asDetachedNode: {
55
55
  node: ?MaybeDetachedNode<T>,
56
56
  config?: {useDeepClone: boolean},
57
57
  ): ?DetachedNode<T>,
58
+ // $FlowFixMe[incompatible-exact]
58
59
  } = <T: ESNode>(
59
60
  node: ?MaybeDetachedNode<T>,
60
61
  {useDeepClone}: {useDeepClone: boolean} = {useDeepClone: false},
@@ -549,7 +549,7 @@ function ComponentDeclaration(props) {
549
549
  params: props.params.map(n => (0, _detachedNode.asDetachedNodeForCodeGen)(n)),
550
550
  body: (0, _detachedNode.asDetachedNodeForCodeGen)(props.body),
551
551
  typeParameters: (0, _detachedNode.asDetachedNodeForCodeGen)(props.typeParameters),
552
- returnType: (0, _detachedNode.asDetachedNodeForCodeGen)(props.returnType)
552
+ rendersType: (0, _detachedNode.asDetachedNodeForCodeGen)(props.rendersType)
553
553
  });
554
554
  (0, _detachedNode.setParentPointersInDirectChildren)(node);
555
555
  return node;
@@ -572,7 +572,7 @@ function ComponentTypeAnnotation(props) {
572
572
  params: props.params.map(n => (0, _detachedNode.asDetachedNodeForCodeGen)(n)),
573
573
  rest: (0, _detachedNode.asDetachedNodeForCodeGen)(props.rest),
574
574
  typeParameters: (0, _detachedNode.asDetachedNodeForCodeGen)(props.typeParameters),
575
- returnType: (0, _detachedNode.asDetachedNodeForCodeGen)(props.returnType)
575
+ rendersType: (0, _detachedNode.asDetachedNodeForCodeGen)(props.rendersType)
576
576
  });
577
577
  (0, _detachedNode.setParentPointersInDirectChildren)(node);
578
578
  return node;
@@ -649,7 +649,7 @@ function DeclareComponent(props) {
649
649
  params: props.params.map(n => (0, _detachedNode.asDetachedNodeForCodeGen)(n)),
650
650
  rest: (0, _detachedNode.asDetachedNodeForCodeGen)(props.rest),
651
651
  typeParameters: (0, _detachedNode.asDetachedNodeForCodeGen)(props.typeParameters),
652
- returnType: (0, _detachedNode.asDetachedNodeForCodeGen)(props.returnType)
652
+ rendersType: (0, _detachedNode.asDetachedNodeForCodeGen)(props.rendersType)
653
653
  });
654
654
  (0, _detachedNode.setParentPointersInDirectChildren)(node);
655
655
  return node;
@@ -1788,7 +1788,8 @@ function TypeParameter(props) {
1788
1788
  name: props.name,
1789
1789
  bound: (0, _detachedNode.asDetachedNodeForCodeGen)(props.bound),
1790
1790
  variance: (0, _detachedNode.asDetachedNodeForCodeGen)(props.variance),
1791
- default: (0, _detachedNode.asDetachedNodeForCodeGen)(props.default)
1791
+ default: (0, _detachedNode.asDetachedNodeForCodeGen)(props.default),
1792
+ usesExtendsBound: props.usesExtendsBound
1792
1793
  });
1793
1794
  (0, _detachedNode.setParentPointersInDirectChildren)(node);
1794
1795
  return node;
@@ -301,7 +301,7 @@ export type ComponentDeclarationProps = {
301
301
  +typeParameters?: ?MaybeDetachedNode<
302
302
  ComponentDeclarationType['typeParameters'],
303
303
  >,
304
- +returnType?: ?MaybeDetachedNode<ComponentDeclarationType['returnType']>,
304
+ +rendersType?: ?MaybeDetachedNode<ComponentDeclarationType['rendersType']>,
305
305
  };
306
306
 
307
307
  export type ComponentParameterProps = {
@@ -318,12 +318,12 @@ export type ComponentTypeAnnotationProps = {
318
318
  +typeParameters?: ?MaybeDetachedNode<
319
319
  ComponentTypeAnnotationType['typeParameters'],
320
320
  >,
321
- +returnType?: ?MaybeDetachedNode<ComponentTypeAnnotationType['returnType']>,
321
+ +rendersType?: ?MaybeDetachedNode<ComponentTypeAnnotationType['rendersType']>,
322
322
  };
323
323
 
324
324
  export type ComponentTypeParameterProps = {
325
325
  +name?: ?MaybeDetachedNode<ComponentTypeParameterType['name']>,
326
- +typeAnnotation?: ?MaybeDetachedNode<
326
+ +typeAnnotation: MaybeDetachedNode<
327
327
  ComponentTypeParameterType['typeAnnotation'],
328
328
  >,
329
329
  +optional: ComponentTypeParameterType['optional'],
@@ -370,7 +370,7 @@ export type DeclareComponentProps = {
370
370
  >,
371
371
  +rest?: ?MaybeDetachedNode<DeclareComponentType['rest']>,
372
372
  +typeParameters?: ?MaybeDetachedNode<DeclareComponentType['typeParameters']>,
373
- +returnType?: ?MaybeDetachedNode<DeclareComponentType['returnType']>,
373
+ +rendersType?: ?MaybeDetachedNode<DeclareComponentType['rendersType']>,
374
374
  };
375
375
 
376
376
  export type DeclaredPredicateProps = {
@@ -1025,6 +1025,7 @@ export type TypeParameterProps = {
1025
1025
  +bound?: ?MaybeDetachedNode<TypeParameterType['bound']>,
1026
1026
  +variance?: ?MaybeDetachedNode<TypeParameterType['variance']>,
1027
1027
  +default?: ?MaybeDetachedNode<TypeParameterType['default']>,
1028
+ +usesExtendsBound: TypeParameterType['usesExtendsBound'],
1028
1029
  };
1029
1030
 
1030
1031
  export type TypeParameterDeclarationProps = {
@@ -1358,7 +1359,7 @@ export function ComponentDeclaration(props: {
1358
1359
  params: props.params.map(n => asDetachedNodeForCodeGen(n)),
1359
1360
  body: asDetachedNodeForCodeGen(props.body),
1360
1361
  typeParameters: asDetachedNodeForCodeGen(props.typeParameters),
1361
- returnType: asDetachedNodeForCodeGen(props.returnType),
1362
+ rendersType: asDetachedNodeForCodeGen(props.rendersType),
1362
1363
  });
1363
1364
  setParentPointersInDirectChildren(node);
1364
1365
  return node;
@@ -1387,7 +1388,7 @@ export function ComponentTypeAnnotation(props: {
1387
1388
  params: props.params.map(n => asDetachedNodeForCodeGen(n)),
1388
1389
  rest: asDetachedNodeForCodeGen(props.rest),
1389
1390
  typeParameters: asDetachedNodeForCodeGen(props.typeParameters),
1390
- returnType: asDetachedNodeForCodeGen(props.returnType),
1391
+ rendersType: asDetachedNodeForCodeGen(props.rendersType),
1391
1392
  });
1392
1393
  setParentPointersInDirectChildren(node);
1393
1394
  return node;
@@ -1485,7 +1486,7 @@ export function DeclareComponent(props: {
1485
1486
  params: props.params.map(n => asDetachedNodeForCodeGen(n)),
1486
1487
  rest: asDetachedNodeForCodeGen(props.rest),
1487
1488
  typeParameters: asDetachedNodeForCodeGen(props.typeParameters),
1488
- returnType: asDetachedNodeForCodeGen(props.returnType),
1489
+ rendersType: asDetachedNodeForCodeGen(props.rendersType),
1489
1490
  });
1490
1491
  setParentPointersInDirectChildren(node);
1491
1492
  return node;
@@ -2962,6 +2963,7 @@ export function TypeParameter(props: {
2962
2963
  bound: asDetachedNodeForCodeGen(props.bound),
2963
2964
  variance: asDetachedNodeForCodeGen(props.variance),
2964
2965
  default: asDetachedNodeForCodeGen(props.default),
2966
+ usesExtendsBound: props.usesExtendsBound,
2965
2967
  });
2966
2968
  setParentPointersInDirectChildren(node);
2967
2969
  return node;
@@ -47,6 +47,7 @@ function getTransformContext() {
47
47
  }
48
48
 
49
49
  const cloneAPIs = {
50
+ // $FlowFixMe[incompatible-exact]
50
51
  shallowCloneNode: node => {
51
52
  if (node == null) {
52
53
  return null;
@@ -61,6 +62,7 @@ function getTransformContext() {
61
62
 
62
63
  return (0, _detachedNode.shallowCloneNode)(node, newProps);
63
64
  },
65
+ // $FlowFixMe[incompatible-exact]
64
66
  shallowCloneArray: nodes => {
65
67
  if (nodes == null) {
66
68
  return null;
@@ -75,6 +77,7 @@ function getTransformContext() {
75
77
  return (0, _detachedNode.shallowCloneNode)(node, {});
76
78
  });
77
79
  },
80
+ // $FlowFixMe[incompatible-exact]
78
81
  deepCloneNode: node => {
79
82
  if (node == null) {
80
83
  return null;
@@ -154,6 +157,7 @@ function getTransformContext() {
154
157
  }
155
158
  };
156
159
  const replaceAPIs = {
160
+ // $FlowFixMe[incompatible-exact]
157
161
  replaceNode: (target, nodeToReplaceWith, options) => {
158
162
  pushMutation((0, _ReplaceNode.createReplaceNodeMutation)(target, (0, _detachedNode.asDetachedNode)(nodeToReplaceWith), options));
159
163
  },
@@ -330,6 +330,7 @@ export function getTransformContext(): TransformContextAdditions {
330
330
  }
331
331
 
332
332
  const cloneAPIs: TransformCloneAPIs = {
333
+ // $FlowFixMe[incompatible-exact]
333
334
  shallowCloneNode: ((
334
335
  node: ?ESNode,
335
336
  ): // $FlowExpectedError[incompatible-cast]
@@ -354,6 +355,7 @@ export function getTransformContext(): TransformContextAdditions {
354
355
  return shallowCloneNode(node, newProps);
355
356
  }: TransformCloneAPIs['shallowCloneNodeWithOverrides']),
356
357
 
358
+ // $FlowFixMe[incompatible-exact]
357
359
  shallowCloneArray: (<T: ESNode>(
358
360
  nodes: ?$ReadOnlyArray<?T>,
359
361
  ): // $FlowExpectedError[incompatible-cast]
@@ -371,6 +373,7 @@ export function getTransformContext(): TransformContextAdditions {
371
373
  });
372
374
  }: TransformCloneAPIs['shallowCloneArray']),
373
375
 
376
+ // $FlowFixMe[incompatible-exact]
374
377
  deepCloneNode: ((
375
378
  node: ?ESNode,
376
379
  ): // $FlowExpectedError[incompatible-cast]
@@ -501,6 +504,7 @@ export function getTransformContext(): TransformContextAdditions {
501
504
  }: TransformRemoveAPIs['removeStatement']),
502
505
  };
503
506
  const replaceAPIs: TransformReplaceAPIs = {
507
+ // $FlowFixMe[incompatible-exact]
504
508
  replaceNode: ((
505
509
  target: ESNode,
506
510
  nodeToReplaceWith: MaybeDetachedNode<ESNode>,
@@ -29,6 +29,7 @@ function createRemoveNodeMutation(node) {
29
29
  const VALID_ENUM_MEMBER_PARENTS = ['EnumBooleanBody', 'EnumNumberBody', 'EnumStringBody', 'EnumSymbolBody'];
30
30
  const VALID_FUNCTION_PARAMETER_PARENTS = ['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'];
31
31
  const VALID_PROPERTY_PARENTS = ['ObjectExpression', 'ObjectPattern'];
32
+ const VALID_COMPONENT_TYPE_PARAMETER_PARENTS = ['DeclareComponent', 'ComponentTypeAnnotation'];
32
33
 
33
34
  function getRemovalParent(node) {
34
35
  const key = (() => {
@@ -57,6 +58,15 @@ function getRemovalParent(node) {
57
58
  case 'EnumStringMember':
58
59
  assertParent(VALID_ENUM_MEMBER_PARENTS);
59
60
  return 'members';
61
+ // Components
62
+
63
+ case 'ComponentParameter':
64
+ assertParent('ComponentDeclaration');
65
+ return 'params';
66
+
67
+ case 'ComponentTypeParameter':
68
+ assertParent(VALID_COMPONENT_TYPE_PARAMETER_PARENTS);
69
+ return 'params';
60
70
  // FunctionParameter
61
71
 
62
72
  case 'AssignmentPattern':
@@ -121,6 +131,7 @@ function getRemovalParent(node) {
121
131
  case 'ArrowFunctionExpression':
122
132
  case 'FunctionDeclaration':
123
133
  case 'FunctionExpression':
134
+ case 'ComponentDeclaration':
124
135
  return 'params';
125
136
 
126
137
  case 'ArrayPattern':
@@ -135,7 +146,7 @@ function getRemovalParent(node) {
135
146
  return 'arguments';
136
147
 
137
148
  default:
138
- throw new _Errors.InvalidRemovalError(getErrorMessage(['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression', 'ArrayPattern', 'ObjectPattern', 'CallExpression', 'OptionalCallExpression', 'NewExpression']));
149
+ throw new _Errors.InvalidRemovalError(getErrorMessage(['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression', 'ComponentDeclaration', 'ArrayPattern', 'ObjectPattern', 'CallExpression', 'OptionalCallExpression', 'NewExpression']));
139
150
  }
140
151
 
141
152
  // SpreadElement can be the child of a number of usecases
@@ -10,6 +10,8 @@
10
10
 
11
11
  import type {
12
12
  ESNode,
13
+ ComponentParameter,
14
+ ComponentTypeParameter,
13
15
  ClassMember,
14
16
  EnumBooleanMember,
15
17
  EnumDefaultedMember,
@@ -37,6 +39,8 @@ export type RemoveNodeMutation = $ReadOnly<{
37
39
  type: 'removeNode',
38
40
  node:
39
41
  | ClassMember
42
+ | ComponentParameter
43
+ | ComponentTypeParameter
40
44
  | EnumBooleanMember
41
45
  | EnumDefaultedMember
42
46
  | EnumNumberMember
@@ -78,6 +82,10 @@ const VALID_PROPERTY_PARENTS: $ReadOnlyArray<string> = [
78
82
  'ObjectExpression',
79
83
  'ObjectPattern',
80
84
  ];
85
+ const VALID_COMPONENT_TYPE_PARAMETER_PARENTS: $ReadOnlyArray<string> = [
86
+ 'DeclareComponent',
87
+ 'ComponentTypeAnnotation',
88
+ ];
81
89
  function getRemovalParent(node: RemoveNodeMutation['node']): $ReadOnly<{
82
90
  type: 'array',
83
91
  parent: ESNode,
@@ -118,6 +126,15 @@ function getRemovalParent(node: RemoveNodeMutation['node']): $ReadOnly<{
118
126
  assertParent(VALID_ENUM_MEMBER_PARENTS);
119
127
  return 'members';
120
128
 
129
+ // Components
130
+ case 'ComponentParameter':
131
+ assertParent('ComponentDeclaration');
132
+ return 'params';
133
+
134
+ case 'ComponentTypeParameter':
135
+ assertParent(VALID_COMPONENT_TYPE_PARAMETER_PARENTS);
136
+ return 'params';
137
+
121
138
  // FunctionParameter
122
139
  case 'AssignmentPattern':
123
140
  case 'ArrayPattern':
@@ -188,6 +205,7 @@ function getRemovalParent(node: RemoveNodeMutation['node']): $ReadOnly<{
188
205
  case 'ArrowFunctionExpression':
189
206
  case 'FunctionDeclaration':
190
207
  case 'FunctionExpression':
208
+ case 'ComponentDeclaration':
191
209
  return 'params';
192
210
 
193
211
  case 'ArrayPattern':
@@ -207,6 +225,7 @@ function getRemovalParent(node: RemoveNodeMutation['node']): $ReadOnly<{
207
225
  'ArrowFunctionExpression',
208
226
  'FunctionDeclaration',
209
227
  'FunctionExpression',
228
+ 'ComponentDeclaration',
210
229
  'ArrayPattern',
211
230
  'ObjectPattern',
212
231
  'CallExpression',
@@ -18,12 +18,13 @@ var _comments = require("./comments/comments");
18
18
 
19
19
  var _hermesEslint = require("hermes-eslint");
20
20
 
21
- function parse(code) {
21
+ async function parse(code) {
22
22
  const {
23
23
  ast,
24
24
  scopeManager
25
25
  } = (0, _hermesEslint.parseForESLint)(code, {
26
- sourceType: 'module'
26
+ sourceType: 'module',
27
+ enableExperimentalComponentSyntax: true
27
28
  }); // Don't include the docblock comment in the comment list as we don't want to attach it
28
29
  // as it should be maintained at the top of the file as nodes are moved around.
29
30
 
@@ -22,9 +22,10 @@ export type ParseResult = {
22
22
  code: string,
23
23
  };
24
24
 
25
- export function parse(code: string): ParseResult {
25
+ export async function parse(code: string): Promise<ParseResult> {
26
26
  const {ast, scopeManager} = parseForESLint(code, {
27
27
  sourceType: 'module',
28
+ enableExperimentalComponentSyntax: true,
28
29
  });
29
30
 
30
31
  // Don't include the docblock comment in the comment list as we don't want to attach it
@@ -24,7 +24,7 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
24
24
 
25
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
26
 
27
- function print(ast, originalCode, prettierOptions = {}, visitorKeys) {
27
+ async function print(ast, originalCode, prettierOptions = {}, visitorKeys) {
28
28
  // $FlowExpectedError[incompatible-type] This is now safe to access.
29
29
  const program = ast; // The docblock comment is never attached to any AST nodes, since its technically
30
30
  // attached to the program. However this is specific to our AST and in order for
@@ -42,119 +42,69 @@ function print(ast, originalCode, prettierOptions = {}, visitorKeys) {
42
42
  } // Fix up the AST to match what prettier expects.
43
43
 
44
44
 
45
- mutateASTForPrettier(program, visitorKeys); // we need to delete the comments prop or else prettier will do
45
+ (0, _hermesParser.mutateESTreeASTForPrettier)(program, visitorKeys); // we need to delete the comments prop or else prettier will do
46
46
  // its own attachment pass after the mutation and duplicate the
47
47
  // comments on each node, borking the output
48
48
  // $FlowExpectedError[cannot-write]
49
49
 
50
50
  delete program.comments;
51
- return prettier.format(originalCode, // $FlowExpectedError[incompatible-exact] - we don't want to create a dependency on the prettier types
52
- { ...prettierOptions,
53
51
 
54
- parser() {
55
- return program;
56
- }
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(originalCode, // $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
+ }
57
75
 
58
- });
59
- }
76
+ case '2':
77
+ {
78
+ return prettier.format(originalCode, // $FlowExpectedError[incompatible-exact] - we don't want to create a dependency on the prettier types
79
+ { ...prettierOptions,
80
+
81
+ parser() {
82
+ return program;
83
+ }
84
+
85
+ });
86
+ }
60
87
 
61
- function mutateASTForPrettier(rootNode, visitorKeys) {
62
- _hermesParser.SimpleTraverser.traverse(rootNode, {
63
- enter(node) {
64
- // prettier fully expects the parent pointers are NOT set and
65
- // certain cases can crash due to prettier infinite-looping
66
- // whilst naively traversing the parent property
67
- // https://github.com/prettier/prettier/issues/11793
68
- // $FlowExpectedError[cannot-write]
69
- delete node.parent; // prettier currently relies on the AST being in the old-school, deprecated AST format for optional chaining
70
- // so we have to apply their transform to our AST so it can actually format it.
71
-
72
- if (node.type === 'ChainExpression') {
73
- const newNode = transformChainExpression(node.expression); // Clear out existing properties
74
-
75
- for (const k of Object.keys(node)) {
76
- // $FlowExpectedError[prop-missing]
77
- delete node[k];
78
- } // Traverse `newNode` and its children.
79
-
80
-
81
- mutateASTForPrettier(newNode, visitorKeys); // Overwrite `node` to match `newNode` while retaining the reference.
82
- // $FlowExpectedError[prop-missing]
83
- // $FlowExpectedError[cannot-write]
84
-
85
- Object.assign(node, newNode); // Skip traversing the existing nodes since we are replacing them.
86
-
87
- throw _hermesParser.SimpleTraverser.Skip;
88
- } // Prettier currently relies on comparing the `node` vs `node.value` start positions to know if an
89
- // `ObjectTypeProperty` is a method or not (instead of using the `node.method` boolean). To correctly print
90
- // the node when its not a method we need the start position to be different from the `node.value`s start
91
- // position.
92
-
93
-
94
- if (node.type === 'ObjectTypeProperty') {
95
- if (node.method === false && node.kind === 'init' && node.range[0] === 1 && node.value.range[0] === 1) {
96
- // $FlowExpectedError[cannot-write]
97
- // $FlowExpectedError[cannot-spread-interface]
98
- node.value = { ...node.value,
99
- range: [2, node.value.range[1]]
100
- };
101
- }
102
- } // Prettier currently relies on comparing the the start positions to know if the import/export specifier should have a
103
- // rename (eg `Name` vs `Name as Name`) when the name is exactly the same
104
- // So we need to ensure that the range is always the same to avoid the useless code printing
105
-
106
-
107
- if (node.type === 'ImportSpecifier') {
108
- if (node.local.name === node.imported.name) {
109
- if (node.local.range == null) {
110
- // for our TS-ast printing which has no locs
111
- // $FlowExpectedError[cannot-write]
112
- node.local.range = [0, 0];
113
- } // $FlowExpectedError[cannot-write]
114
-
115
-
116
- node.imported.range = [...node.local.range];
117
- }
88
+ case 'UNSUPPORTED':
89
+ default:
90
+ {
91
+ throw new Error(`Unknown or unsupported prettier version of "${prettier.version}". Only major versions 3 or 2 of prettier are supported.`);
118
92
  }
93
+ }
94
+ }
119
95
 
120
- if (node.type === 'ExportSpecifier') {
121
- if (node.local.name === node.exported.name) {
122
- if (node.local.range == null) {
123
- // for our TS-ast printing which has no locs
124
- // $FlowExpectedError[cannot-write]
125
- node.local.range = [0, 0];
126
- } // $FlowExpectedError[cannot-write]
96
+ function getPrettierMajorVersion() {
97
+ const {
98
+ version
99
+ } = prettier;
127
100
 
101
+ if (version.startsWith('3.')) {
102
+ return '3';
103
+ }
128
104
 
129
- node.exported.range = [...node.local.range];
130
- }
131
- }
132
- },
133
-
134
- leave() {},
135
-
136
- visitorKeys
137
- });
138
- } // https://github.com/prettier/prettier/blob/d962466a828f8ef51435e3e8840178d90b7ec6cd/src/language-js/parse/postprocess/index.js#L161-L182
139
-
140
-
141
- function transformChainExpression(node) {
142
- switch (node.type) {
143
- case 'CallExpression':
144
- // $FlowExpectedError[cannot-spread-interface]
145
- return { ...node,
146
- type: 'OptionalCallExpression',
147
- callee: transformChainExpression(node.callee)
148
- };
149
-
150
- case 'MemberExpression':
151
- // $FlowExpectedError[cannot-spread-interface]
152
- return { ...node,
153
- type: 'OptionalMemberExpression',
154
- object: transformChainExpression(node.object)
155
- };
156
- // No default
105
+ if (version.startsWith('2.')) {
106
+ return '2';
157
107
  }
158
108
 
159
- return node;
109
+ return 'UNSUPPORTED';
160
110
  }