21
21
import com .google .common .collect .ImmutableSet ;
22
22
import com .google .javascript .jscomp .parsing .parser .FeatureSet ;
23
23
import com .google .javascript .jscomp .parsing .parser .FeatureSet .Feature ;
24
+ import com .google .javascript .rhino .IR ;
24
25
import com .google .javascript .rhino .Node ;
25
26
import java .util .ArrayDeque ;
26
27
import java .util .Deque ;
@@ -253,11 +254,10 @@ private void moveComputedFieldsWithSideEffectsInsideComputedFunction(
253
254
* becomes
254
255
*
255
256
* <pre>
256
- * var $jscomp$computedfield$0;
257
+ * var $jscomp$computedfield$0 = bar('str') ;
257
258
* class Foo {
258
259
* [$jscomp$computedfield$0] = 4;
259
260
* }
260
- * $jscomp$computedfield$0 = bar('str');
261
261
* </pre>
262
262
*/
263
263
private void extractExpressionFromCompField (
@@ -271,16 +271,12 @@ private void extractExpressionFromCompField(
271
271
272
272
Node compExpression = memberField .getFirstChild ().detach ();
273
273
Node compFieldVar =
274
- astFactory .createSingleVarNameDeclaration (generateUniqueCompFieldVarName (t ));
274
+ astFactory .createSingleVarNameDeclaration (
275
+ generateUniqueCompFieldVarName (t ), compExpression );
275
276
Node compFieldName = compFieldVar .getFirstChild ();
276
277
memberField .addChildToFront (compFieldName .cloneNode ());
277
278
compFieldVar .insertBefore (record .insertionPointBeforeClass );
278
279
compFieldVar .srcrefTreeIfMissing (record .classNode );
279
- Node exprResult =
280
- astFactory .exprResult (astFactory .createAssign (compFieldName .cloneNode (), compExpression ));
281
- exprResult .insertAfter (record .insertionPointAfterClass );
282
- record .insertionPointAfterClass = exprResult ;
283
- exprResult .srcrefTreeIfMissing (record .classNode );
284
280
}
285
281
286
282
/** Returns $jscomp$compfield$[FILE_ID]$[number] */
@@ -298,7 +294,7 @@ private void rewriteInstanceMembers(NodeTraversal t, ClassRecord record) {
298
294
ctorCreator .synthesizeClassConstructorIfMissing (t , record .classNode );
299
295
Node ctor = NodeUtil .getEs6ClassConstructorMemberFunctionDef (record .classNode );
300
296
Node ctorBlock = ctor .getFirstChild ().getLastChild ();
301
- Node insertionPoint = findInitialInstanceInsertionPoint (ctorBlock );
297
+ Node insertionPoint = addTemporaryInsertionPoint (ctorBlock );
302
298
303
299
while (!instanceMembers .isEmpty ()) {
304
300
Node instanceMember = instanceMembers .pop ();
@@ -314,14 +310,14 @@ private void rewriteInstanceMembers(NodeTraversal t, ClassRecord record) {
314
310
instanceMember .isMemberFieldDef ()
315
311
? convNonCompFieldToGetProp (thisNode , instanceMember .detach ())
316
312
: convCompFieldToGetElem (thisNode , instanceMember .detach ());
317
- if (insertionPoint == ctorBlock ) { // insert the field at the beginning of the block, no super
318
- ctorBlock .addChildToFront (transpiledNode );
319
- } else {
320
- transpiledNode .insertAfter (insertionPoint );
321
- }
322
- t .reportCodeChange (); // we moved the field from the class body
323
- t .reportCodeChange (ctorBlock ); // to the constructor, so we need both
313
+
314
+ transpiledNode .insertBefore (insertionPoint );
324
315
}
316
+
317
+ insertionPoint .detach ();
318
+
319
+ t .reportCodeChange (); // we moved the field from the class body
320
+ t .reportCodeChange (ctorBlock ); // to the constructor, so we need both
325
321
}
326
322
327
323
/** Rewrites and moves all static blocks and fields */
@@ -399,25 +395,22 @@ private Node convCompFieldToGetElem(Node receiver, Node computedField) {
399
395
}
400
396
401
397
/**
402
- * Finds the location in the constructor to put the transpiled instance fields
403
- *
404
- * <p>Returns the constructor body if there is no super() call so the field can be put at the
405
- * beginning of the class
398
+ * Finds the location of super() call in the constructor and add a temporary empty node after the
399
+ * super() call. If there is no super() call, add a temporary empty node at the beginning of the
400
+ * constructor body.
406
401
*
407
- * <p>Returns the super() call otherwise so the field can be put after the super() call
402
+ * <p>Returns the added temporary empty node
408
403
*/
409
- private Node findInitialInstanceInsertionPoint (Node ctorBlock ) {
410
- if (NodeUtil .referencesSuper (ctorBlock )) {
411
- // will use the fact that if there is super in the constructor, the first appearance of
412
- // super
413
- // must be the super call
404
+ private Node addTemporaryInsertionPoint (Node ctorBlock ) {
405
+ Node tempNode = IR .empty ();
414
406
for (Node stmt = ctorBlock .getFirstChild (); stmt != null ; stmt = stmt .getNext ()) {
415
407
if (NodeUtil .isExprCall (stmt ) && stmt .getFirstFirstChild ().isSuper ()) {
416
- return stmt ;
408
+ tempNode .insertAfter (stmt );
409
+ return tempNode ;
417
410
}
418
411
}
419
- }
420
- return ctorBlock ; // in case the super loop doesn't work, insert at beginning of block
412
+ ctorBlock . addChildToFront ( tempNode );
413
+ return tempNode ;
421
414
}
422
415
423
416
/**
@@ -489,7 +482,7 @@ void enterField(Node field) {
489
482
if (field .isStaticMember ()) {
490
483
staticMembers .push (field );
491
484
} else {
492
- instanceMembers .push (field );
485
+ instanceMembers .offer (field );
493
486
}
494
487
}
495
488
0 commit comments