4040import com .google .javascript .jscomp .graph .LinkedDirectedGraph ;
4141import com .google .javascript .rhino .IR ;
4242import com .google .javascript .rhino .Node ;
43+ import com .google .javascript .rhino .Token ;
4344import java .io .File ;
4445import java .io .IOException ;
4546import java .util .ArrayDeque ;
@@ -323,6 +324,7 @@ public void remove() {
323324 checkState (parent .hasOneChild ());
324325 replaceWithRhs (containingNode , parent );
325326 break ;
327+ case CLASS :
326328 case FUNCTION :
327329 replaceWithRhs (containingNode , parent );
328330 break ;
@@ -333,6 +335,19 @@ public void remove() {
333335 replaceWithRhs (containingNode , parent );
334336 }
335337 break ;
338+ case STRING_KEY :
339+ Node grandparent = parent .getParent ();
340+ NodeUtil .removeChild (/* parent= */ containingNode , /* node= */ parent );
341+ compiler .reportChangeToEnclosingScope (grandparent );
342+ if (!containingNode .hasChildren () && containingNode .getParent ().isDestructuringLhs ()) {
343+ Node rhs = containingNode .getNext ().detach ();
344+ Node newExp = new Node (Token .EXPR_RESULT , rhs );
345+ containingNode .getGrandparent ().replaceWith (newExp );
346+ }
347+ break ;
348+ case DEFAULT_VALUE :
349+ case REST :
350+ case ARRAY_PATTERN : // we don't know which child to remove
336351 case OBJECTLIT :
337352 // TODO(nicksantos): Come up with a way to remove this.
338353 // If we remove object lit keys, then we will need to also
@@ -538,6 +553,15 @@ public void visit(NodeTraversal t, Node n, Node parent) {
538553 NameInformation ns = createNameInformation (t , targetObject );
539554 checkNotNull (ns , "createNameInformation returned null for: %s" , targetObject );
540555 recordDepScope (n , ns );
556+ } else if (n .isDestructuringLhs ()) {
557+ for (Node child : NodeUtil .getLhsNodesOfDeclaration (n )) {
558+ if (!child .getParent ().isComputedProp ()) {
559+ checkState (child .isName ());
560+ NameInformation ns = createNameInformation (t , child );
561+ checkNotNull (ns , "createNameInformation returned null for: %s" , n );
562+ recordDepScope (child , ns );
563+ }
564+ }
541565 }
542566 }
543567
@@ -657,7 +681,17 @@ public void visit(NodeTraversal t, Node n, Node parent) {
657681 NameInformation ns = createNameInformation (t , n );
658682 checkNotNull (ns , "createNameInformation returned null for: %s" , n );
659683 recordSet (ns .name , n );
660- } else if (NodeUtil .isFunctionDeclaration (n ) && t .inGlobalScope ()) {
684+ } else if (NodeUtil .isNameDeclaration (parent ) && n .isDestructuringLhs ()){
685+ for (Node child : NodeUtil .getLhsNodesOfDeclaration (n )) {
686+ if (!child .getParent ().isComputedProp ()) {
687+ checkState (child .isName ());
688+ NameInformation ns = createNameInformation (t , child );
689+ checkNotNull (ns , "createNameInformation returned null for: %s" , n );
690+ recordSet (ns .name , child );
691+ }
692+ }
693+ } else if (t .inGlobalScope ()
694+ && (NodeUtil .isFunctionDeclaration (n ) || NodeUtil .isClassDeclaration (n ))) {
661695 Node nameNode = n .getFirstChild ();
662696 NameInformation ns = createNameInformation (t , nameNode );
663697 if (ns != null ) {
@@ -679,6 +713,7 @@ public void visit(NodeTraversal t, Node n, Node parent) {
679713 NameInformation ns = createNameInformation (t , nameNode );
680714 if (ns != null ) {
681715 if (ns .isPrototype ) {
716+
682717 recordPrototypeSet (ns .prototypeClass , ns .prototypeProperty , n );
683718 } else {
684719 recordSet (ns .name , nameNode );
@@ -795,7 +830,7 @@ private void addSimplifiedChildren(Node n) {
795830 }
796831
797832 private void addSimplifiedExpression (Node n , Node parent ) {
798- if (parent . isVar ( )) {
833+ if (NodeUtil . isNameDeclaration ( parent )) {
799834 Node value = n .getFirstChild ();
800835 if (value != null ) {
801836 addSimplifiedChildren (value );
@@ -840,26 +875,30 @@ public boolean shouldTraverse(NodeTraversal t, Node n, Node parent) {
840875 addAllChildren (iter );
841876 }
842877
843- if (parent . isVar () ||
844- parent .isExprResult () ||
845- parent .isReturn () ||
846- parent .isThrow ()) {
878+ if (NodeUtil . isNameDeclaration ( parent )
879+ || parent .isExprResult ()
880+ || parent .isReturn ()
881+ || parent .isThrow ()) {
847882 addSimplifiedExpression (n , parent );
848883 }
849884
850- if ((parent .isIf () ||
851- parent .isWhile () ||
852- parent .isWith () ||
853- parent .isSwitch () ||
854- parent .isCase ()) &&
855- parent .getFirstChild () == n ) {
885+ if ((parent .isIf ()
886+ || parent .isWhile ()
887+ || parent .isWith ()
888+ || parent .isSwitch ()
889+ || parent .isCase ())
890+ && parent .getFirstChild () == n ) {
856891 addAllChildren (n );
857892 }
858893
859894 if (parent .isDo () && parent .getLastChild () == n ) {
860895 addAllChildren (n );
861896 }
862897
898+ if (parent .isDestructuringLhs () && n .isCall ()) {
899+ addAllChildren (n );
900+ }
901+
863902 return true ;
864903 }
865904
@@ -1252,7 +1291,6 @@ private void recordReference(String fromName, String toName,
12521291 // Don't bother recording self-references.
12531292 return ;
12541293 }
1255-
12561294 JsName from = getName (fromName , true );
12571295 JsName to = getName (toName , true );
12581296 referenceGraph .connectIfNotConnectedInDirection (from , depType , to );
@@ -1567,7 +1605,7 @@ private NameInformation createNameInformation(NodeTraversal t, Node n) {
15671605 }
15681606 }
15691607
1570- // Check whether this is a class-defining call. Classes may only be defined
1608+ // Check whether this is a class-defining call. Non Es6+ classes may only be defined
15711609 // in the global scope.
15721610 if (parent .isCall () && t .inGlobalHoistScope ()) {
15731611 CodingConvention convention = compiler .getCodingConvention ();
@@ -1578,7 +1616,6 @@ private NameInformation createNameInformation(NodeTraversal t, Node n) {
15781616 nameInfo .superclass = classes .superclassName ;
15791617 return nameInfo ;
15801618 }
1581-
15821619 String singletonGetterClass =
15831620 convention .getSingletonGetterClassName (parent );
15841621 if (singletonGetterClass != null ) {
@@ -1588,6 +1625,17 @@ private NameInformation createNameInformation(NodeTraversal t, Node n) {
15881625 }
15891626 }
15901627
1628+ // Check whether this is an ES6 class
1629+ if (parent .isClass ()) {
1630+ checkState (n .isName ());
1631+ NameInformation nameInfo = new NameInformation (n .getString ());
1632+ if (n .getNext ().isName ()) { // class it extends from
1633+ nameInfo .superclass = n .getNext ().getString ();
1634+ nameInfo .onlyAffectsClassDef = true ;
1635+ }
1636+ return nameInfo ;
1637+ }
1638+
15911639 switch (rootNameNode .getToken ()) {
15921640 case NAME :
15931641 // Check whether this is an assignment to a prototype property
@@ -1878,6 +1926,7 @@ private void replaceTopLevelExpressionWithRhs(Node parent, Node n) {
18781926
18791927 switch (n .getToken ()) {
18801928 case EXPR_RESULT :
1929+ case CLASS :
18811930 case FUNCTION :
18821931 case VAR :
18831932 case LET :
@@ -1988,6 +2037,7 @@ private static List<Node> getRhsSubexpressions(Node n) {
19882037 case EXPR_RESULT :
19892038 // process body
19902039 return getRhsSubexpressions (n .getFirstChild ());
2040+ case CLASS :
19912041 case FUNCTION :
19922042 // function nodes have no RHS
19932043 return ImmutableList .of ();
@@ -2008,6 +2058,7 @@ private static List<Node> getRhsSubexpressions(Node n) {
20082058 return ImmutableList .of ();
20092059 }
20102060 }
2061+ case DESTRUCTURING_LHS :
20112062 case ASSIGN :
20122063 {
20132064 // add LHS and RHS expressions - LHS may be a complex expression
0 commit comments