static void RotateOpeator(BinaryExpression node, AstNodeList rightSide) { if (rightSide.Count == 0) { // the list is empty -- remove the node altogether node.Parent.ReplaceChild(node, null); } else if (rightSide.Count == 1) { // the list has only one item -- replace the node with the one item node.Parent.ReplaceChild(node, rightSide[0]); } else if (rightSide.Count == 2) { // there are only two items -- rotate the first to the left-hand side // and replace the right-hand side with the second item node.Operand1 = rightSide[0]; node.Operand2 = rightSide[1]; } else { // there will still be more than one left in the list after we peel off the // first one. rotate the first item to the left-hand side var temp = rightSide[0]; rightSide.RemoveAt(0); node.Operand1 = temp; } }
void PossiblyBreakExpressionList(BinaryExpression node, BlockStatement parentBlock, AstNodeList nodeList) { // if the first item can be broken, then we an break it and be done. // otherwise we're going to have to walk until we find a breaking place if (CanBeBroken(nodeList[0])) { // break the first item. insert the left-hand side at our position and // recurse it. Then rotate the node. var index = parentBlock.IndexOf(node); var temp = node.Operand1; RotateOpeator(node, nodeList); parentBlock.Insert(index, temp); // assumes nothing will cause the node to be deleted, because then it // would cause us to miss the following item temp.Accept(this); } else { // the first one can't be broken, so find the first one that can (if any) for (var ndx = 1; ndx < nodeList.Count; ++ndx) { if (CanBeBroken(nodeList[ndx])) { if (ndx == 1) { // the second item is where we are breaking it, so we're going to pull // the first item, replace the list with that first item, then insert // a new comma operator after the current node var temp = nodeList[0]; nodeList.RemoveAt(0); node.Operand2 = temp; // if there's nothing left, then let it die. Otherwise split off // the remainder and insert after the current item. if (nodeList.Count > 0) { parentBlock.InsertAfter(node, CreateSplitNodeFromEnd(nodeList, 0)); } } else { // split off items from the index where we want to split, and insert // it after the current node and leave the node list where it is. parentBlock.InsertAfter(node, CreateSplitNodeFromEnd(nodeList, ndx)); } // and now that we've broken it, bail. break; } } // regardless if anything changed, recurse this node now base.Visit(node); } }
static AstNode CreateSplitNodeFromEnd(AstNodeList nodeList, int ndx) { AstNode newNode; if (ndx == nodeList.Count - 1) { // the LAST one can be broken. Pull it off the list and we will just // insert it after the current node. newNode = nodeList[ndx]; nodeList.RemoveAt(ndx); } else if (ndx == nodeList.Count - 2) { // the PENULTIMATE item can be broken. So create a new comma operator // with the just the last two item and we'll insert it after the current node var left = nodeList[ndx]; nodeList.RemoveAt(ndx); var right = nodeList[ndx]; nodeList.RemoveAt(ndx); newNode = new CommaExpression(left.Context.FlattenToStart()) { Operand1 = left, Operand2 = right }; } else { // at least three items will be pulled off, which means there will // be at least two items on the right, so we'll create a new astlist to // insert those items into a new comma operator var left = nodeList[ndx]; nodeList.RemoveAt(ndx); // if we were passed zero, then just reuse the node list. // otherwise we need to create a new one and move the items // from the index position over. AstNodeList right; if (ndx == 0) { right = nodeList; } else { right = new AstNodeList(nodeList[ndx].Context.FlattenToStart()); while (ndx < nodeList.Count) { var temp = nodeList[ndx]; nodeList.RemoveAt(ndx); right.Append(temp); } } newNode = new CommaExpression(left.Context.FlattenToStart()) { Operand1 = left, Operand2 = right }; } return(newNode); }