hermes-transform 0.8.0 → 0.9.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.
@@ -7,6 +7,7 @@ exports.ArrowFunctionExpression = ArrowFunctionExpression;
7
7
  exports.BigIntLiteral = BigIntLiteral;
8
8
  exports.BlockComment = BlockComment;
9
9
  exports.BooleanLiteral = BooleanLiteral;
10
+ exports.ClassDeclaration = ClassDeclaration;
10
11
  exports.Identifier = Identifier;
11
12
  exports.LineComment = LineComment;
12
13
  exports.NullLiteral = NullLiteral;
@@ -32,16 +33,35 @@ These are a number of special-case node creation functions that we can't auto-ge
32
33
  The list of exported functions here must be kept in sync with the `NODES_WITH_SPECIAL_HANDLING`
33
34
  list in `scripts/genTransformNodeTypes` to ensure there's no duplicates
34
35
  */
35
- function ArrowFunctionExpression({
36
- parent,
37
- ...props
38
- }) {
39
- const node = (0, _detachedNode.detachedProps)(parent, {
36
+ function ArrowFunctionExpression(props) {
37
+ const node = (0, _detachedNode.detachedProps)(props.parent, {
40
38
  type: 'ArrowFunctionExpression',
41
39
  id: null,
42
40
  // $FlowExpectedError[incompatible-use]
43
41
  expression: props.body.type !== 'BlockStatement',
44
- ...props
42
+ params: props.params.map(n => (0, _detachedNode.asDetachedNode)(n)),
43
+ body: (0, _detachedNode.asDetachedNode)(props.body),
44
+ typeParameters: (0, _detachedNode.asDetachedNode)(props.typeParameters),
45
+ returnType: (0, _detachedNode.asDetachedNode)(props.returnType),
46
+ predicate: (0, _detachedNode.asDetachedNode)(props.predicate),
47
+ async: props.async
48
+ });
49
+ (0, _detachedNode.setParentPointersInDirectChildren)(node);
50
+ return node;
51
+ }
52
+
53
+ function ClassDeclaration(props) {
54
+ var _props$decorators, _props$implements;
55
+
56
+ const node = (0, _detachedNode.detachedProps)(props.parent, {
57
+ type: 'ClassDeclaration',
58
+ id: (0, _detachedNode.asDetachedNode)(props.id),
59
+ typeParameters: (0, _detachedNode.asDetachedNode)(props.typeParameters),
60
+ superClass: (0, _detachedNode.asDetachedNode)(props.superClass),
61
+ superTypeParameters: (0, _detachedNode.asDetachedNode)(props.superTypeParameters),
62
+ decorators: ((_props$decorators = props.decorators) != null ? _props$decorators : []).map(n => (0, _detachedNode.asDetachedNode)(n)),
63
+ implements: ((_props$implements = props.implements) != null ? _props$implements : []).map(n => (0, _detachedNode.asDetachedNode)(n)),
64
+ body: (0, _detachedNode.asDetachedNode)(props.body)
45
65
  });
46
66
  (0, _detachedNode.setParentPointersInDirectChildren)(node);
47
67
  return node;
@@ -49,49 +69,41 @@ function ArrowFunctionExpression({
49
69
  // also the value is supposed to be a RegExp instance
50
70
 
51
71
 
52
- function RegExpLiteral({
53
- pattern,
54
- flags,
55
- parent
56
- }) {
57
- const value = new RegExp(pattern, flags);
58
- return (0, _detachedNode.detachedProps)(parent, {
72
+ function RegExpLiteral(props) {
73
+ const value = new RegExp(props.pattern, props.flags);
74
+ return (0, _detachedNode.detachedProps)(props.parent, {
59
75
  type: 'Literal',
60
76
  value,
61
77
  raw: value.toString(),
62
78
  regex: {
63
- pattern,
64
- flags
79
+ pattern: props.pattern,
80
+ flags: props.flags
65
81
  }
66
82
  });
67
83
  } // raw/cooked are on a subobject in the estree spec, but are flat on the hermes types
68
84
 
69
85
 
70
- function TemplateElement({
71
- tail,
72
- parent,
73
- ...value
74
- }) {
75
- return (0, _detachedNode.detachedProps)(parent, {
86
+ function TemplateElement(props) {
87
+ return (0, _detachedNode.detachedProps)(props.parent, {
76
88
  type: 'TemplateElement',
77
- tail,
78
- value
89
+ tail: props.tail,
90
+ value: {
91
+ cooked: props.cooked,
92
+ raw: props.raw
93
+ }
79
94
  });
80
95
  } // Identifier has a bunch of stuff that usually you don't want to provide - so we have
81
96
  // this manual def to allow us to default some values
82
97
 
83
98
 
84
- function Identifier({
85
- parent,
86
- optional = false,
87
- typeAnnotation = null,
88
- ...props
89
- }) {
90
- const node = (0, _detachedNode.detachedProps)(parent, {
99
+ function Identifier(props) {
100
+ var _props$optional;
101
+
102
+ const node = (0, _detachedNode.detachedProps)(props.parent, {
91
103
  type: 'Identifier',
92
- optional,
93
- typeAnnotation,
94
- ...props
104
+ name: props.name,
105
+ optional: (_props$optional = props.optional) != null ? _props$optional : false,
106
+ typeAnnotation: (0, _detachedNode.asDetachedNode)(props.typeAnnotation)
95
107
  });
96
108
  (0, _detachedNode.setParentPointersInDirectChildren)(node);
97
109
  return node;
@@ -100,15 +112,12 @@ function Identifier({
100
112
  //
101
113
 
102
114
 
103
- function BigIntLiteral({
104
- parent,
105
- ...props
106
- }) {
115
+ function BigIntLiteral(props) {
107
116
  var _props$raw;
108
117
 
109
- const node = (0, _detachedNode.detachedProps)(parent, {
118
+ const node = (0, _detachedNode.detachedProps)(props.parent, {
110
119
  type: 'Literal',
111
- ...props,
120
+ value: props.value,
112
121
  raw: (_props$raw = props.raw) != null ? _props$raw : `${props.value}n`,
113
122
  bigint: `${props.value}`
114
123
  });
@@ -116,84 +125,69 @@ function BigIntLiteral({
116
125
  return node;
117
126
  }
118
127
 
119
- function BooleanLiteral({
120
- parent,
121
- value
122
- }) {
123
- return (0, _detachedNode.detachedProps)(parent, {
128
+ function BooleanLiteral(props) {
129
+ return (0, _detachedNode.detachedProps)(props.parent, {
124
130
  type: 'Literal',
125
- raw: value ? 'true' : 'false',
126
- value
131
+ raw: props.value ? 'true' : 'false',
132
+ value: props.value
127
133
  });
128
134
  }
129
135
 
130
- function NumericLiteral({
131
- parent,
132
- ...props
133
- }) {
136
+ function NumericLiteral(props) {
134
137
  var _props$raw2;
135
138
 
136
- return (0, _detachedNode.detachedProps)(parent, {
139
+ return (0, _detachedNode.detachedProps)(props.parent, {
137
140
  type: 'Literal',
138
- ...props,
141
+ value: props.value,
139
142
  raw: (_props$raw2 = props.raw) != null ? _props$raw2 : `${props.value}`
140
143
  });
141
144
  }
142
145
 
143
- function NullLiteral({
144
- parent
145
- } = {}) {
146
- return (0, _detachedNode.detachedProps)(parent, {
146
+ function NullLiteral(props = { ...null
147
+ }) {
148
+ return (0, _detachedNode.detachedProps)(props.parent, {
147
149
  type: 'Literal',
148
150
  value: null,
149
151
  raw: 'null'
150
152
  });
151
153
  }
152
154
 
153
- function StringLiteral({
154
- parent,
155
- raw: rawIn,
156
- value
157
- }) {
158
- const hasSingleQuote = value.includes('"');
159
- const hasDoubleQuote = value.includes("'");
160
- let raw = rawIn;
155
+ function StringLiteral(props) {
156
+ const hasSingleQuote = props.value.includes('"');
157
+ const hasDoubleQuote = props.value.includes("'");
158
+ let raw = props.raw;
161
159
 
162
160
  if (raw == null) {
163
161
  if (hasSingleQuote && hasDoubleQuote) {
164
- raw = `'${value.replace(/'/g, "\\'")}'`;
162
+ raw = `'${props.value.replace(/'/g, "\\'")}'`;
165
163
  } else if (hasSingleQuote) {
166
- raw = `"${value}"`;
164
+ raw = `"${props.value}"`;
167
165
  } else {
168
- raw = `'${value}'`;
166
+ raw = `'${props.value}'`;
169
167
  }
170
168
  }
171
169
 
172
- return (0, _detachedNode.detachedProps)(parent, {
170
+ return (0, _detachedNode.detachedProps)(props.parent, {
173
171
  type: 'Literal',
174
172
  raw,
175
- value
173
+ value: props.value
176
174
  });
177
175
  }
178
176
 
179
- function LineComment({
180
- value
181
- }) {
177
+ function LineComment(props) {
182
178
  // $FlowExpectedError[prop-missing]
183
179
  // $FlowExpectedError[incompatible-return]
184
180
  return (0, _detachedNode.detachedProps)(undefined, {
185
181
  type: 'Line',
186
- value
182
+ value: props.value
187
183
  });
188
184
  }
189
185
 
190
- function BlockComment({
191
- value
192
- }) {
186
+ function BlockComment(props) {
193
187
  // $FlowExpectedError[prop-missing]
194
188
  // $FlowExpectedError[incompatible-return]
195
189
  return (0, _detachedNode.detachedProps)(undefined, {
196
190
  type: 'Block',
197
- value
191
+ value: props.value
198
192
  });
199
193
  }
@@ -17,20 +17,22 @@ list in `scripts/genTransformNodeTypes` to ensure there's no duplicates
17
17
  import type {
18
18
  ESNode,
19
19
  ArrowFunctionExpression as ArrowFunctionExpressionType,
20
- RegExpLiteral as RegExpLiteralType,
21
- TemplateElement as TemplateElementType,
22
- Identifier as IdentifierType,
23
20
  BigIntLiteral as BigIntLiteralType,
21
+ BlockComment as BlockCommentType,
24
22
  BooleanLiteral as BooleanLiteralType,
25
- NumericLiteral as NumericLiteralType,
23
+ ClassDeclaration as ClassDeclarationType,
24
+ Identifier as IdentifierType,
25
+ LineComment as LineCommentType,
26
26
  NullLiteral as NullLiteralType,
27
+ NumericLiteral as NumericLiteralType,
28
+ RegExpLiteral as RegExpLiteralType,
27
29
  StringLiteral as StringLiteralType,
28
- LineComment as LineCommentType,
29
- BlockComment as BlockCommentType,
30
+ TemplateElement as TemplateElementType,
30
31
  } from 'hermes-estree';
31
- import type {DetachedNode} from '../detachedNode';
32
+ import type {DetachedNode, MaybeDetachedNode} from '../detachedNode';
32
33
 
33
34
  import {
35
+ asDetachedNode,
34
36
  detachedProps,
35
37
  setParentPointersInDirectChildren,
36
38
  } from '../detachedNode';
@@ -40,29 +42,66 @@ import {
40
42
  // No need to make consumers set these
41
43
  export type ArrowFunctionExpressionProps = {
42
44
  +params: $ReadOnlyArray<
43
- DetachedNode<ArrowFunctionExpressionType['params'][number]>,
45
+ MaybeDetachedNode<ArrowFunctionExpressionType['params'][number]>,
44
46
  >,
45
- +body: DetachedNode<ArrowFunctionExpressionType['body']>,
46
- +typeParameters?: ?DetachedNode<
47
+ +body: MaybeDetachedNode<ArrowFunctionExpressionType['body']>,
48
+ +typeParameters?: ?MaybeDetachedNode<
47
49
  ArrowFunctionExpressionType['typeParameters'],
48
50
  >,
49
- +returnType?: ?DetachedNode<ArrowFunctionExpressionType['returnType']>,
50
- +predicate?: ?DetachedNode<ArrowFunctionExpressionType['predicate']>,
51
+ +returnType?: ?MaybeDetachedNode<ArrowFunctionExpressionType['returnType']>,
52
+ +predicate?: ?MaybeDetachedNode<ArrowFunctionExpressionType['predicate']>,
51
53
  +async: ArrowFunctionExpressionType['async'],
52
54
  };
53
- export function ArrowFunctionExpression({
54
- parent,
55
- ...props
56
- }: {
55
+ export function ArrowFunctionExpression(props: {
57
56
  ...$ReadOnly<ArrowFunctionExpressionProps>,
58
57
  +parent?: ESNode,
59
58
  }): DetachedNode<ArrowFunctionExpressionType> {
60
- const node = detachedProps<ArrowFunctionExpressionType>(parent, {
59
+ const node = detachedProps<ArrowFunctionExpressionType>(props.parent, {
61
60
  type: 'ArrowFunctionExpression',
62
61
  id: null,
63
62
  // $FlowExpectedError[incompatible-use]
64
63
  expression: props.body.type !== 'BlockStatement',
65
- ...props,
64
+ params: props.params.map(n => asDetachedNode(n)),
65
+ body: asDetachedNode(props.body),
66
+ typeParameters: asDetachedNode(props.typeParameters),
67
+ returnType: asDetachedNode(props.returnType),
68
+ predicate: asDetachedNode(props.predicate),
69
+ async: props.async,
70
+ });
71
+ setParentPointersInDirectChildren(node);
72
+ return node;
73
+ }
74
+
75
+ export type ClassDeclarationProps = {
76
+ +id?: ?MaybeDetachedNode<ClassDeclarationType['id']>,
77
+ +typeParameters?: ?MaybeDetachedNode<ClassDeclarationType['typeParameters']>,
78
+ +superClass?: ?MaybeDetachedNode<ClassDeclarationType['superClass']>,
79
+ +superTypeParameters?: ?MaybeDetachedNode<
80
+ ClassDeclarationType['superTypeParameters'],
81
+ >,
82
+ // make this optional as it's rarer that people would want to include them
83
+ +implements?: $ReadOnlyArray<
84
+ MaybeDetachedNode<ClassDeclarationType['implements'][number]>,
85
+ >,
86
+ // make this optional as it's rarer that people would want to include them
87
+ +decorators?: $ReadOnlyArray<
88
+ MaybeDetachedNode<ClassDeclarationType['decorators'][number]>,
89
+ >,
90
+ +body: MaybeDetachedNode<ClassDeclarationType['body']>,
91
+ };
92
+ export function ClassDeclaration(props: {
93
+ ...$ReadOnly<ClassDeclarationProps>,
94
+ +parent?: ESNode,
95
+ }): DetachedNode<ClassDeclarationType> {
96
+ const node = detachedProps<ClassDeclarationType>(props.parent, {
97
+ type: 'ClassDeclaration',
98
+ id: asDetachedNode(props.id),
99
+ typeParameters: asDetachedNode(props.typeParameters),
100
+ superClass: asDetachedNode(props.superClass),
101
+ superTypeParameters: asDetachedNode(props.superTypeParameters),
102
+ decorators: (props.decorators ?? []).map(n => asDetachedNode(n)),
103
+ implements: (props.implements ?? []).map(n => asDetachedNode(n)),
104
+ body: asDetachedNode(props.body),
66
105
  });
67
106
  setParentPointersInDirectChildren(node);
68
107
  return node;
@@ -74,22 +113,18 @@ export type RegExpLiteralProps = {
74
113
  +pattern: RegExpLiteralType['regex']['pattern'],
75
114
  +flags: RegExpLiteralType['regex']['flags'],
76
115
  };
77
- export function RegExpLiteral({
78
- pattern,
79
- flags,
80
- parent,
81
- }: {
116
+ export function RegExpLiteral(props: {
82
117
  ...$ReadOnly<RegExpLiteralProps>,
83
118
  +parent?: ESNode,
84
119
  }): DetachedNode<RegExpLiteralType> {
85
- const value = new RegExp(pattern, flags);
86
- return detachedProps<RegExpLiteralType>(parent, {
120
+ const value = new RegExp(props.pattern, props.flags);
121
+ return detachedProps<RegExpLiteralType>(props.parent, {
87
122
  type: 'Literal',
88
123
  value,
89
124
  raw: value.toString(),
90
125
  regex: {
91
- pattern,
92
- flags,
126
+ pattern: props.pattern,
127
+ flags: props.flags,
93
128
  },
94
129
  });
95
130
  }
@@ -100,18 +135,17 @@ export type TemplateElementProps = {
100
135
  +cooked: TemplateElementType['value']['cooked'],
101
136
  +raw: TemplateElementType['value']['raw'],
102
137
  };
103
- export function TemplateElement({
104
- tail,
105
- parent,
106
- ...value
107
- }: {
138
+ export function TemplateElement(props: {
108
139
  ...$ReadOnly<TemplateElementProps>,
109
140
  +parent?: ESNode,
110
141
  }): DetachedNode<TemplateElementType> {
111
- return detachedProps<TemplateElementType>(parent, {
142
+ return detachedProps<TemplateElementType>(props.parent, {
112
143
  type: 'TemplateElement',
113
- tail,
114
- value,
144
+ tail: props.tail,
145
+ value: {
146
+ cooked: props.cooked,
147
+ raw: props.raw,
148
+ },
115
149
  });
116
150
  }
117
151
 
@@ -119,23 +153,18 @@ export function TemplateElement({
119
153
  // this manual def to allow us to default some values
120
154
  export type IdentifierProps = {
121
155
  +name: IdentifierType['name'],
122
- +typeAnnotation?: ?DetachedNode<IdentifierType['typeAnnotation']>,
156
+ +typeAnnotation?: ?MaybeDetachedNode<IdentifierType['typeAnnotation']>,
123
157
  +optional?: IdentifierType['optional'],
124
158
  };
125
- export function Identifier({
126
- parent,
127
- optional = false,
128
- typeAnnotation = null,
129
- ...props
130
- }: {
159
+ export function Identifier(props: {
131
160
  ...$ReadOnly<IdentifierProps>,
132
161
  +parent?: ESNode,
133
162
  }): DetachedNode<IdentifierType> {
134
- const node = detachedProps<IdentifierType>(parent, {
163
+ const node = detachedProps<IdentifierType>(props.parent, {
135
164
  type: 'Identifier',
136
- optional,
137
- typeAnnotation,
138
- ...props,
165
+ name: props.name,
166
+ optional: props.optional ?? false,
167
+ typeAnnotation: asDetachedNode(props.typeAnnotation),
139
168
  });
140
169
  setParentPointersInDirectChildren(node);
141
170
  return node;
@@ -153,16 +182,13 @@ export type BigIntLiteralProps = {
153
182
  */
154
183
  +raw?: NumericLiteralType['raw'],
155
184
  };
156
- export function BigIntLiteral({
157
- parent,
158
- ...props
159
- }: {
185
+ export function BigIntLiteral(props: {
160
186
  ...$ReadOnly<BigIntLiteralProps>,
161
187
  +parent?: ESNode,
162
188
  }): DetachedNode<BigIntLiteralType> {
163
- const node = detachedProps<BigIntLiteralType>(parent, {
189
+ const node = detachedProps<BigIntLiteralType>(props.parent, {
164
190
  type: 'Literal',
165
- ...props,
191
+ value: props.value,
166
192
  raw: props.raw ?? `${props.value}n`,
167
193
  bigint: `${props.value}`,
168
194
  });
@@ -173,17 +199,14 @@ export function BigIntLiteral({
173
199
  export type BooleanLiteralProps = {
174
200
  +value: BooleanLiteralType['value'],
175
201
  };
176
- export function BooleanLiteral({
177
- parent,
178
- value,
179
- }: {
202
+ export function BooleanLiteral(props: {
180
203
  ...$ReadOnly<BooleanLiteralProps>,
181
204
  +parent?: ESNode,
182
205
  }): DetachedNode<BooleanLiteralType> {
183
- return detachedProps<BooleanLiteralType>(parent, {
206
+ return detachedProps<BooleanLiteralType>(props.parent, {
184
207
  type: 'Literal',
185
- raw: value ? 'true' : 'false',
186
- value,
208
+ raw: props.value ? 'true' : 'false',
209
+ value: props.value,
187
210
  });
188
211
  }
189
212
 
@@ -195,27 +218,24 @@ export type NumericLiteralProps = {
195
218
  */
196
219
  +raw?: NumericLiteralType['raw'],
197
220
  };
198
- export function NumericLiteral({
199
- parent,
200
- ...props
201
- }: {
221
+ export function NumericLiteral(props: {
202
222
  ...$ReadOnly<NumericLiteralProps>,
203
223
  +parent?: ESNode,
204
224
  }): DetachedNode<NumericLiteralType> {
205
- return detachedProps<NumericLiteralType>(parent, {
225
+ return detachedProps<NumericLiteralType>(props.parent, {
206
226
  type: 'Literal',
207
- ...props,
227
+ value: props.value,
208
228
  raw: props.raw ?? `${props.value}`,
209
229
  });
210
230
  }
211
231
 
212
232
  export type NullLiteralProps = {};
213
- export function NullLiteral({
214
- parent,
215
- }: {
216
- +parent?: ESNode,
217
- } = {}): DetachedNode<NullLiteralType> {
218
- return detachedProps<NullLiteralType>(parent, {
233
+ export function NullLiteral(
234
+ props: {
235
+ +parent?: ESNode,
236
+ } = {...null},
237
+ ): DetachedNode<NullLiteralType> {
238
+ return detachedProps<NullLiteralType>(props.parent, {
219
239
  type: 'Literal',
220
240
  value: null,
221
241
  raw: 'null',
@@ -226,49 +246,45 @@ export type StringLiteralProps = {
226
246
  +value: StringLiteralType['value'],
227
247
  +raw?: StringLiteralType['raw'],
228
248
  };
229
- export function StringLiteral({
230
- parent,
231
- raw: rawIn,
232
- value,
233
- }: {
249
+ export function StringLiteral(props: {
234
250
  ...$ReadOnly<StringLiteralProps>,
235
251
  +parent?: ESNode,
236
252
  }): DetachedNode<StringLiteralType> {
237
- const hasSingleQuote = value.includes('"');
238
- const hasDoubleQuote = value.includes("'");
239
- let raw = rawIn;
253
+ const hasSingleQuote = props.value.includes('"');
254
+ const hasDoubleQuote = props.value.includes("'");
255
+ let raw = props.raw;
240
256
  if (raw == null) {
241
257
  if (hasSingleQuote && hasDoubleQuote) {
242
- raw = `'${value.replace(/'/g, "\\'")}'`;
258
+ raw = `'${props.value.replace(/'/g, "\\'")}'`;
243
259
  } else if (hasSingleQuote) {
244
- raw = `"${value}"`;
260
+ raw = `"${props.value}"`;
245
261
  } else {
246
- raw = `'${value}'`;
262
+ raw = `'${props.value}'`;
247
263
  }
248
264
  }
249
- return detachedProps<StringLiteralType>(parent, {
265
+ return detachedProps<StringLiteralType>(props.parent, {
250
266
  type: 'Literal',
251
267
  raw,
252
- value,
268
+ value: props.value,
253
269
  });
254
270
  }
255
271
 
256
272
  export type LineCommentProps = {+value: string};
257
- export function LineComment({value}: LineCommentProps): LineCommentType {
273
+ export function LineComment(props: LineCommentProps): LineCommentType {
258
274
  // $FlowExpectedError[prop-missing]
259
275
  // $FlowExpectedError[incompatible-return]
260
276
  return detachedProps<LineCommentType>(undefined, {
261
277
  type: 'Line',
262
- value,
278
+ value: props.value,
263
279
  });
264
280
  }
265
281
 
266
282
  export type BlockCommentProps = {+value: string};
267
- export function BlockComment({value}: BlockCommentProps): BlockCommentType {
283
+ export function BlockComment(props: BlockCommentProps): BlockCommentType {
268
284
  // $FlowExpectedError[prop-missing]
269
285
  // $FlowExpectedError[incompatible-return]
270
286
  return detachedProps<BlockCommentType>(undefined, {
271
287
  type: 'Block',
272
- value,
288
+ value: props.value,
273
289
  });
274
290
  }
@@ -52,10 +52,9 @@ function getTransformContext() {
52
52
  return null;
53
53
  }
54
54
 
55
- return (0, _detachedNode.shallowCloneNode)(node);
55
+ return (0, _detachedNode.shallowCloneNode)(node, {});
56
56
  },
57
- // $FlowExpectedError[incompatible-exact]
58
- shallowCloneNodeWithOverrides: (node, newProps) => {
57
+ shallowCloneNodeWithOverrides: (node, newProps = {}) => {
59
58
  if (node == null) {
60
59
  return null;
61
60
  }
@@ -67,17 +66,23 @@ function getTransformContext() {
67
66
  return null;
68
67
  }
69
68
 
70
- return nodes.map(node => (0, _detachedNode.shallowCloneNode)(node));
69
+ return nodes.map(node => {
70
+ if (node == null) {
71
+ // $FlowExpectedError[incompatible-call]
72
+ return node;
73
+ }
74
+
75
+ return (0, _detachedNode.shallowCloneNode)(node, {});
76
+ });
71
77
  },
72
78
  deepCloneNode: node => {
73
79
  if (node == null) {
74
80
  return null;
75
81
  }
76
82
 
77
- return (0, _detachedNode.deepCloneNode)(node);
83
+ return (0, _detachedNode.deepCloneNode)(node, {});
78
84
  },
79
- // $FlowExpectedError[incompatible-exact]
80
- deepCloneNodeWithOverrides: (node, newProps) => {
85
+ deepCloneNodeWithOverrides: (node, newProps = {}) => {
81
86
  if (node == null) {
82
87
  return null;
83
88
  }
@@ -130,10 +135,14 @@ function getTransformContext() {
130
135
  };
131
136
  const insertAPIs = {
132
137
  insertAfterStatement: (target, nodesToInsert) => {
133
- pushMutation((0, _InsertStatement.createInsertStatementMutation)('after', target, toArray(nodesToInsert)));
138
+ pushMutation((0, _InsertStatement.createInsertStatementMutation)('after', target, toArray(nodesToInsert).map(n => (0, _detachedNode.asDetachedNode)(n, {
139
+ useDeepClone: true
140
+ }))));
134
141
  },
135
142
  insertBeforeStatement: (target, nodesToInsert) => {
136
- pushMutation((0, _InsertStatement.createInsertStatementMutation)('before', target, toArray(nodesToInsert)));
143
+ pushMutation((0, _InsertStatement.createInsertStatementMutation)('before', target, toArray(nodesToInsert).map(n => (0, _detachedNode.asDetachedNode)(n, {
144
+ useDeepClone: true
145
+ }))));
137
146
  }
138
147
  };
139
148
  const removeAPIs = {
@@ -146,10 +155,23 @@ function getTransformContext() {
146
155
  };
147
156
  const replaceAPIs = {
148
157
  replaceNode: (target, nodeToReplaceWith, options) => {
149
- pushMutation((0, _ReplaceNode.createReplaceNodeMutation)(target, nodeToReplaceWith, options));
158
+ pushMutation((0, _ReplaceNode.createReplaceNodeMutation)(target, (0, _detachedNode.asDetachedNode)(nodeToReplaceWith), options));
150
159
  },
151
160
  replaceStatementWithMany: (target, nodesToReplaceWith, options) => {
152
- pushMutation((0, _ReplaceStatementWithMany.createReplaceStatementWithManyMutation)(target, nodesToReplaceWith, options));
161
+ pushMutation((0, _ReplaceStatementWithMany.createReplaceStatementWithManyMutation)(target, nodesToReplaceWith.map(n => (0, _detachedNode.asDetachedNode)(n)), options));
162
+ }
163
+ };
164
+ const modifyAPIs = {
165
+ modifyNodeInPlace: (node, newProps = {}, options) => {
166
+ if (node == null) {
167
+ return;
168
+ }
169
+
170
+ const cloned = (0, _detachedNode.shallowCloneNode)(node, newProps, {
171
+ preserveLocation: true
172
+ }); // $FlowExpectedError[incompatible-call]
173
+
174
+ replaceAPIs.replaceNode(node, cloned, options);
153
175
  }
154
176
  };
155
177
  return {
@@ -163,6 +185,7 @@ function getTransformContext() {
163
185
  ...cloneAPIs,
164
186
  ...commentAPIs,
165
187
  ...insertAPIs,
188
+ ...modifyAPIs,
166
189
  ...removeAPIs,
167
190
  ...replaceAPIs
168
191
  };