private static void RotateOpeator(JsBinaryOperator node, JsAstNodeList 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; } }
public override bool ReplaceChild(JsAstNode oldNode, JsAstNode newNode) { // if the old node isn't our element list, ignore the cal if (oldNode == Elements) { if (newNode == null) { // we want to remove the list altogether Elements = null; return(true); } else { // if the new node isn't an AstNodeList, then ignore the call JsAstNodeList newList = newNode as JsAstNodeList; if (newList != null) { // replace it Elements = newList; return(true); } } } return(false); }
public override void Visit(JsAstNodeList node) { if (node != null && node.Count > 0) { // this is really only ever not-ed when it's the right-hand operand // of a comma operator, which we flattened to decrease stack recursion. // so to logical-not this element, we only need to not the last item // in the list (because all the others are comma-separated) node[node.Count - 1].Accept(this); } }
public void Visit(JsAstNodeList node) { if (node != null) { // don't bother setting the order of the list itself, just the items for (var ndx = 0; ndx < node.Count; ++ndx) { var item = node[ndx]; if (item != null) { item.Accept(this); } } } }
public void Visit(JsAstNodeList node) { if (node != null) { for (var ndx = 0; ndx < node.Count; ++ndx) { if (ndx > 0) { m_writer.Write(','); } if (node[ndx] != null) { node[ndx].Accept(this); } } } }
public override bool ReplaceChild(JsAstNode oldNode, JsAstNode newNode) { if (Expression == oldNode) { Expression = newNode; return(true); } if (Cases == oldNode) { JsAstNodeList newList = newNode as JsAstNodeList; if (newNode == null || newList != null) { // remove it Cases = newList; return(true); } } return(false); }
/// <summary> /// an astlist is equivalent to another astlist if they both have the same number of /// items, and each item is equivalent to the corresponding item in the other /// </summary> /// <param name="otherNode"></param> /// <returns></returns> public override bool IsEquivalentTo(JsAstNode otherNode) { bool isEquivalent = false; JsAstNodeList otherList = otherNode as JsAstNodeList; if (otherList != null && m_list.Count == otherList.Count) { // now assume it's true unless we come across an item that ISN'T // equivalent, at which case we'll bail the test. isEquivalent = true; for (var ndx = 0; ndx < m_list.Count; ++ndx) { if (!m_list[ndx].IsEquivalentTo(otherList[ndx])) { isEquivalent = false; break; } } } return(isEquivalent); }
public void Visit(JsAstNodeList node) { // shoudn't get here Debug.Fail("shouldn't get here"); }
public void Visit(JsAstNodeList node) { // not applicable; terminate }
public static JsAstNode CombineWithComma(JsContext context, JsParser parser, JsAstNode operand1, JsAstNode operand2) { var comma = new JsCommaOperator(context, parser); // if the left is a comma-operator already.... var leftBinary = operand1 as JsBinaryOperator; var rightBinary = operand2 as JsBinaryOperator; if (leftBinary != null && leftBinary.OperatorToken == JsToken.Comma) { // the left-hand side is already a comma operator. Instead of nesting these, we're // going to combine them // move the old list's left-hand side to our left-hand side comma.Operand1 = leftBinary.Operand1; JsAstNodeList list; if (rightBinary != null && rightBinary.OperatorToken == JsToken.Comma) { // the right is ALSO a comma operator. Create a new list, append all the rest of the operands // and set our right-hand side to be the list list = new JsAstNodeList(null, parser); list.Append(leftBinary.Operand2).Append(rightBinary.Operand1).Append(rightBinary.Operand2); } else { // the right is not a comma operator. // see if the left-hand side already has a list we can use list = leftBinary.Operand2 as JsAstNodeList; if (list == null) { // it's not a list already // create a new list with the left's right and our right and set it to our right list = new JsAstNodeList(null, parser); list.Append(leftBinary.Operand2); } // and add our right-hand operand to the end of the list list.Append(operand2); } // set the list on the right comma.Operand2 = list; } else if (rightBinary != null && rightBinary.OperatorToken == JsToken.Comma) { // the left hand side is NOT a comma operator. comma.Operand1 = operand1; // the right-hand side is already a comma-operator, but the left is not. // see if it already has a list we can reuse var rightList = rightBinary.Operand2 as JsAstNodeList; if (rightList != null) { // it does. Prepend its right-hand operand and use the list rightList.Insert(0, rightBinary.Operand1); } else { // it's not -- create a new list containing the operands rightList = new JsAstNodeList(rightBinary.Context, parser); rightList.Append(rightBinary.Operand1); rightList.Append(rightBinary.Operand2); } comma.Operand2 = rightList; } else { comma.Operand1 = operand1; comma.Operand2 = operand2; } return(comma); }
private void PossiblyBreakExpressionList(JsBinaryOperator node, JsBlock parentBlock, JsAstNodeList 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); } }
private static JsAstNode CreateSplitNodeFromEnd(JsAstNodeList nodeList, int ndx) { JsAstNode 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 JsCommaOperator(null, nodeList.Parser) { 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. JsAstNodeList right; if (ndx == 0) { right = nodeList; } else { right = new JsAstNodeList(null, nodeList.Parser); while (ndx < nodeList.Count) { var temp = nodeList[ndx]; nodeList.RemoveAt(ndx); right.Append(temp); } } newNode = new JsCommaOperator(null, nodeList.Parser) { Operand1 = left, Operand2 = right }; } return(newNode); }