hermes-parser 0.18.0 → 0.18.2

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.
@@ -78,7 +78,7 @@ function getComponentParameterName(paramName) {
78
78
  }
79
79
  }
80
80
 
81
- function createPropsTypeAnnotation(loc, range) {
81
+ function createPropsTypeAnnotation(propTypes, spread, loc, range) {
82
82
  // Create empty loc for type annotation nodes
83
83
  const createParamsTypeLoc = () => ({
84
84
  loc: {
@@ -87,8 +87,34 @@ function createPropsTypeAnnotation(loc, range) {
87
87
  },
88
88
  range: range != null ? range : [0, 0],
89
89
  parent: EMPTY_PARENT
90
- });
90
+ }); // Optimize `{...Props}` -> `Props`
91
+
92
+
93
+ if (spread != null && propTypes.length === 0) {
94
+ return {
95
+ type: 'TypeAnnotation',
96
+ typeAnnotation: spread.argument,
97
+ ...createParamsTypeLoc()
98
+ };
99
+ }
100
+
101
+ const typeProperties = [...propTypes];
102
+
103
+ if (spread != null) {
104
+ // Spread needs to be the first type, as inline properties take precedence.
105
+ typeProperties.unshift(spread);
106
+ }
91
107
 
108
+ const propTypeObj = {
109
+ type: 'ObjectTypeAnnotation',
110
+ callProperties: [],
111
+ properties: typeProperties,
112
+ indexers: [],
113
+ internalSlots: [],
114
+ exact: false,
115
+ inexact: false,
116
+ ...createParamsTypeLoc()
117
+ };
92
118
  return {
93
119
  type: 'TypeAnnotation',
94
120
  typeAnnotation: {
@@ -102,16 +128,7 @@ function createPropsTypeAnnotation(loc, range) {
102
128
  },
103
129
  typeParameters: {
104
130
  type: 'TypeParameterInstantiation',
105
- params: [{
106
- type: 'ObjectTypeAnnotation',
107
- callProperties: [],
108
- properties: [],
109
- indexers: [],
110
- internalSlots: [],
111
- exact: false,
112
- inexact: true,
113
- ...createParamsTypeLoc()
114
- }],
131
+ params: [propTypeObj],
115
132
  ...createParamsTypeLoc()
116
133
  },
117
134
  ...createParamsTypeLoc()
@@ -130,13 +147,9 @@ function mapComponentParameters(params) {
130
147
 
131
148
 
132
149
  if (params.length === 1 && params[0].type === 'RestElement' && params[0].argument.type === 'Identifier') {
133
- var _restElementArgument$, _restElementArgument$2;
134
-
135
150
  const restElementArgument = params[0].argument;
136
151
  return {
137
- props: nodeWith(restElementArgument, {
138
- typeAnnotation: createPropsTypeAnnotation((_restElementArgument$ = restElementArgument.typeAnnotation) == null ? void 0 : _restElementArgument$.loc, (_restElementArgument$2 = restElementArgument.typeAnnotation) == null ? void 0 : _restElementArgument$2.range)
139
- }),
152
+ props: restElementArgument,
140
153
  ref: null
141
154
  };
142
155
  } // Filter out any ref param and capture it's details.
@@ -151,12 +164,30 @@ function mapComponentParameters(params) {
151
164
 
152
165
  return true;
153
166
  });
167
+ const [propTypes, spread] = paramsWithoutRef.reduce(([propTypes, spread], param) => {
168
+ switch (param.type) {
169
+ case 'RestElement':
170
+ {
171
+ if (spread != null) {
172
+ throw (0, _createSyntaxError.createSyntaxError)(param, `Invalid state, multiple rest elements found as Component Parameters`);
173
+ }
174
+
175
+ return [propTypes, mapComponentParameterRestElementType(param)];
176
+ }
177
+
178
+ case 'ComponentParameter':
179
+ {
180
+ propTypes.push(mapComponentParameterType(param));
181
+ return [propTypes, spread];
182
+ }
183
+ }
184
+ }, [[], null]);
154
185
  const propsProperties = paramsWithoutRef.flatMap(mapComponentParameter);
155
186
  let props = null;
156
187
 
157
188
  if (propsProperties.length === 0) {
158
189
  if (refParam == null) {
159
- throw new Error('TransformReactScriptForBabel: Invalid state, ref should always be set at this point if props are empty');
190
+ throw new Error('StripComponentSyntax: Invalid state, ref should always be set at this point if props are empty');
160
191
  }
161
192
 
162
193
  const emptyParamsLoc = {
@@ -169,7 +200,7 @@ function mapComponentParameters(params) {
169
200
  type: 'Identifier',
170
201
  name: '_$$empty_props_placeholder$$',
171
202
  optional: false,
172
- typeAnnotation: createPropsTypeAnnotation(emptyParamsLoc, emptyParamsRange),
203
+ typeAnnotation: createPropsTypeAnnotation([], null, emptyParamsLoc, emptyParamsRange),
173
204
  loc: emptyParamsLoc,
174
205
  range: emptyParamsRange,
175
206
  parent: EMPTY_PARENT
@@ -179,7 +210,7 @@ function mapComponentParameters(params) {
179
210
  props = {
180
211
  type: 'ObjectPattern',
181
212
  properties: propsProperties,
182
- typeAnnotation: createPropsTypeAnnotation({
213
+ typeAnnotation: createPropsTypeAnnotation(propTypes, spread, {
183
214
  start: lastPropsProperty.loc.end,
184
215
  end: lastPropsProperty.loc.end
185
216
  }, [lastPropsProperty.range[1], lastPropsProperty.range[1]]),
@@ -204,6 +235,53 @@ function mapComponentParameters(params) {
204
235
  };
205
236
  }
206
237
 
238
+ function mapComponentParameterType(param) {
239
+ var _typeAnnotation$typeA;
240
+
241
+ const typeAnnotation = param.local.type === 'AssignmentPattern' ? param.local.left.typeAnnotation : param.local.typeAnnotation;
242
+ const optional = param.local.type === 'AssignmentPattern' ? true : param.local.type === 'Identifier' ? param.local.optional : false;
243
+ return {
244
+ type: 'ObjectTypeProperty',
245
+ key: (0, _astNodeMutationHelpers.shallowCloneNode)(param.name),
246
+ value: (_typeAnnotation$typeA = typeAnnotation == null ? void 0 : typeAnnotation.typeAnnotation) != null ? _typeAnnotation$typeA : {
247
+ type: 'AnyTypeAnnotation',
248
+ loc: param.local.loc,
249
+ range: param.local.range,
250
+ parent: EMPTY_PARENT
251
+ },
252
+ kind: 'init',
253
+ optional,
254
+ method: false,
255
+ static: false,
256
+ proto: false,
257
+ variance: null,
258
+ loc: param.local.loc,
259
+ range: param.local.range,
260
+ parent: EMPTY_PARENT
261
+ };
262
+ }
263
+
264
+ function mapComponentParameterRestElementType(param) {
265
+ var _param$argument$typeA, _param$argument$typeA2;
266
+
267
+ if (param.argument.type !== 'Identifier' && param.argument.type !== 'ObjectPattern') {
268
+ throw (0, _createSyntaxError.createSyntaxError)(param, `Invalid ${param.argument.type} encountered in restParameter`);
269
+ }
270
+
271
+ return {
272
+ type: 'ObjectTypeSpreadProperty',
273
+ argument: (_param$argument$typeA = (_param$argument$typeA2 = param.argument.typeAnnotation) == null ? void 0 : _param$argument$typeA2.typeAnnotation) != null ? _param$argument$typeA : {
274
+ type: 'AnyTypeAnnotation',
275
+ loc: param.loc,
276
+ range: param.range,
277
+ parent: EMPTY_PARENT
278
+ },
279
+ loc: param.loc,
280
+ range: param.range,
281
+ parent: EMPTY_PARENT
282
+ };
283
+ }
284
+
207
285
  function mapComponentParameter(param) {
208
286
  switch (param.type) {
209
287
  case 'RestElement':
@@ -40,6 +40,8 @@ import type {
40
40
  Statement,
41
41
  AssignmentPattern,
42
42
  BindingName,
43
+ ObjectTypePropertySignature,
44
+ ObjectTypeSpreadProperty,
43
45
  } from 'hermes-estree';
44
46
 
45
47
  import {SimpleTransform} from '../transform/SimpleTransform';
@@ -100,6 +102,8 @@ function getComponentParameterName(
100
102
  }
101
103
 
102
104
  function createPropsTypeAnnotation(
105
+ propTypes: Array<ObjectTypePropertySignature>,
106
+ spread: ?ObjectTypeSpreadProperty,
103
107
  loc: ?SourceLocation,
104
108
  range: ?Range,
105
109
  ): TypeAnnotation {
@@ -113,6 +117,35 @@ function createPropsTypeAnnotation(
113
117
  parent: EMPTY_PARENT,
114
118
  });
115
119
 
120
+ // Optimize `{...Props}` -> `Props`
121
+ if (spread != null && propTypes.length === 0) {
122
+ return {
123
+ type: 'TypeAnnotation',
124
+ typeAnnotation: spread.argument,
125
+ ...createParamsTypeLoc(),
126
+ };
127
+ }
128
+
129
+ const typeProperties: Array<
130
+ ObjectTypePropertySignature | ObjectTypeSpreadProperty,
131
+ > = [...propTypes];
132
+
133
+ if (spread != null) {
134
+ // Spread needs to be the first type, as inline properties take precedence.
135
+ typeProperties.unshift(spread);
136
+ }
137
+
138
+ const propTypeObj = {
139
+ type: 'ObjectTypeAnnotation',
140
+ callProperties: [],
141
+ properties: typeProperties,
142
+ indexers: [],
143
+ internalSlots: [],
144
+ exact: false,
145
+ inexact: false,
146
+ ...createParamsTypeLoc(),
147
+ };
148
+
116
149
  return {
117
150
  type: 'TypeAnnotation',
118
151
  typeAnnotation: {
@@ -126,18 +159,7 @@ function createPropsTypeAnnotation(
126
159
  },
127
160
  typeParameters: {
128
161
  type: 'TypeParameterInstantiation',
129
- params: [
130
- {
131
- type: 'ObjectTypeAnnotation',
132
- callProperties: [],
133
- properties: [],
134
- indexers: [],
135
- internalSlots: [],
136
- exact: false,
137
- inexact: true,
138
- ...createParamsTypeLoc(),
139
- },
140
- ],
162
+ params: [propTypeObj],
141
163
  ...createParamsTypeLoc(),
142
164
  },
143
165
  ...createParamsTypeLoc(),
@@ -164,12 +186,7 @@ function mapComponentParameters(
164
186
  ) {
165
187
  const restElementArgument = params[0].argument;
166
188
  return {
167
- props: nodeWith(restElementArgument, {
168
- typeAnnotation: createPropsTypeAnnotation(
169
- restElementArgument.typeAnnotation?.loc,
170
- restElementArgument.typeAnnotation?.range,
171
- ),
172
- }),
189
+ props: restElementArgument,
173
190
  ref: null,
174
191
  };
175
192
  }
@@ -188,13 +205,36 @@ function mapComponentParameters(
188
205
  return true;
189
206
  });
190
207
 
208
+ const [propTypes, spread] = paramsWithoutRef.reduce<
209
+ [Array<ObjectTypePropertySignature>, ?ObjectTypeSpreadProperty],
210
+ >(
211
+ ([propTypes, spread], param) => {
212
+ switch (param.type) {
213
+ case 'RestElement': {
214
+ if (spread != null) {
215
+ throw createSyntaxError(
216
+ param,
217
+ `Invalid state, multiple rest elements found as Component Parameters`,
218
+ );
219
+ }
220
+ return [propTypes, mapComponentParameterRestElementType(param)];
221
+ }
222
+ case 'ComponentParameter': {
223
+ propTypes.push(mapComponentParameterType(param));
224
+ return [propTypes, spread];
225
+ }
226
+ }
227
+ },
228
+ [[], null],
229
+ );
230
+
191
231
  const propsProperties = paramsWithoutRef.flatMap(mapComponentParameter);
192
232
 
193
233
  let props = null;
194
234
  if (propsProperties.length === 0) {
195
235
  if (refParam == null) {
196
236
  throw new Error(
197
- 'TransformReactScriptForBabel: Invalid state, ref should always be set at this point if props are empty',
237
+ 'StripComponentSyntax: Invalid state, ref should always be set at this point if props are empty',
198
238
  );
199
239
  }
200
240
  const emptyParamsLoc = {
@@ -208,6 +248,8 @@ function mapComponentParameters(
208
248
  name: '_$$empty_props_placeholder$$',
209
249
  optional: false,
210
250
  typeAnnotation: createPropsTypeAnnotation(
251
+ [],
252
+ null,
211
253
  emptyParamsLoc,
212
254
  emptyParamsRange,
213
255
  ),
@@ -221,6 +263,8 @@ function mapComponentParameters(
221
263
  type: 'ObjectPattern',
222
264
  properties: propsProperties,
223
265
  typeAnnotation: createPropsTypeAnnotation(
266
+ propTypes,
267
+ spread,
224
268
  {
225
269
  start: lastPropsProperty.loc.end,
226
270
  end: lastPropsProperty.loc.end,
@@ -247,6 +291,67 @@ function mapComponentParameters(
247
291
  };
248
292
  }
249
293
 
294
+ function mapComponentParameterType(
295
+ param: ComponentParameter,
296
+ ): ObjectTypePropertySignature {
297
+ const typeAnnotation =
298
+ param.local.type === 'AssignmentPattern'
299
+ ? param.local.left.typeAnnotation
300
+ : param.local.typeAnnotation;
301
+ const optional =
302
+ param.local.type === 'AssignmentPattern'
303
+ ? true
304
+ : param.local.type === 'Identifier'
305
+ ? param.local.optional
306
+ : false;
307
+
308
+ return {
309
+ type: 'ObjectTypeProperty',
310
+ key: shallowCloneNode(param.name),
311
+ value: typeAnnotation?.typeAnnotation ?? {
312
+ type: 'AnyTypeAnnotation',
313
+ loc: param.local.loc,
314
+ range: param.local.range,
315
+ parent: EMPTY_PARENT,
316
+ },
317
+ kind: 'init',
318
+ optional,
319
+ method: false,
320
+ static: false,
321
+ proto: false,
322
+ variance: null,
323
+ loc: param.local.loc,
324
+ range: param.local.range,
325
+ parent: EMPTY_PARENT,
326
+ };
327
+ }
328
+
329
+ function mapComponentParameterRestElementType(
330
+ param: RestElement,
331
+ ): ObjectTypeSpreadProperty {
332
+ if (
333
+ param.argument.type !== 'Identifier' &&
334
+ param.argument.type !== 'ObjectPattern'
335
+ ) {
336
+ throw createSyntaxError(
337
+ param,
338
+ `Invalid ${param.argument.type} encountered in restParameter`,
339
+ );
340
+ }
341
+ return {
342
+ type: 'ObjectTypeSpreadProperty',
343
+ argument: param.argument.typeAnnotation?.typeAnnotation ?? {
344
+ type: 'AnyTypeAnnotation',
345
+ loc: param.loc,
346
+ range: param.range,
347
+ parent: EMPTY_PARENT,
348
+ },
349
+ loc: param.loc,
350
+ range: param.range,
351
+ parent: EMPTY_PARENT,
352
+ };
353
+ }
354
+
250
355
  function mapComponentParameter(
251
356
  param: ComponentParameter | RestElement,
252
357
  ): Array<DestructuringObjectProperty | RestElement> {
@@ -19,6 +19,7 @@ var _ESTreeVisitorKeys = _interopRequireDefault(require("../generated/ESTreeVisi
19
19
 
20
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
21
 
22
+ // $FlowFixMe[deprecated-type]
22
23
  function isNode(thing) {
23
24
  return typeof thing === 'object' && thing != null && typeof thing.type === 'string';
24
25
  }
@@ -15,6 +15,7 @@ import type {VisitorKeys as VisitorKeysType} from '../generated/ESTreeVisitorKey
15
15
 
16
16
  import FlowVisitorKeys from '../generated/ESTreeVisitorKeys';
17
17
 
18
+ // $FlowFixMe[deprecated-type]
18
19
  export function isNode(thing: mixed): boolean %checks {
19
20
  return (
20
21
  typeof thing === 'object' && thing != null && typeof thing.type === 'string'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hermes-parser",
3
- "version": "0.18.0",
3
+ "version": "0.18.2",
4
4
  "description": "A JavaScript parser built from the Hermes engine",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  "url": "git@github.com:facebook/hermes.git"
10
10
  },
11
11
  "dependencies": {
12
- "hermes-estree": "0.18.0"
12
+ "hermes-estree": "0.18.2"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@babel/parser": "7.7.4",