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;
     }
 }
예제 #2
0
 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);
 }
예제 #3
0
 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);
             }
         }
     }
 }
예제 #5
0
        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);
                    }
                }
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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");
 }
예제 #9
0
 public void Visit(JsAstNodeList node)
 {
     // not applicable; terminate
 }
예제 #10
0
        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);
        }