private void PossiblyBreakExpressionStatement(JsBinaryOperator node, JsBlock parentBlock) { var nodeList = node.Operand2 as JsAstNodeList; if (nodeList != null) { PossiblyBreakExpressionList(node, parentBlock, nodeList); } else { // not a list if (CanBeBroken(node.Operand2)) { // flatten the operator. We have to explicitly recurse the left-hand side. var temp = node.Operand1; parentBlock.ReplaceChild(node, temp); parentBlock.InsertAfter(temp, node.Operand2); temp.Accept(this); } else { // no change; just recurse normally base.Visit(node); } } }
public override void Visit(JsBinaryOperator node) { if (node != null) { // if this isn't a comma-operator, just recurse normal. // if it is and this is the root block (parent is null) or a function block // or there's already more than one statement in the block, we will want to possibly break // this comma-operator expression statement into separate expression statements. JsBlock parentBlock; if (node.OperatorToken == JsToken.Comma && m_parser.Settings.IsModificationAllowed(JsTreeModifications.UnfoldCommaExpressionStatements) && ((parentBlock = node.Parent as JsBlock) != null) && (parentBlock.Parent == null || parentBlock.Parent is JsFunctionObject || parentBlock.Parent is JsTryNode || parentBlock.Parent is JsSwitchCase || parentBlock.Count > 1)) { // possibly break this one comma statement into multiple statements and recurse PossiblyBreakExpressionStatement(node, parentBlock); } else { // just recurse it normally base.Visit(node); } } }
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 void Visit(JsBinaryOperator node) { // if there's a left-hand operand, recurse into it if (node != null && node.Operand1 != null) { node.Operand1.Accept(this); } }
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); } }
public override void Visit(JsBinaryOperator node) { if (node != null) { if (m_measure) { // measure MeasureBinaryOperator(node); } else { // convert ConvertBinaryOperator(node); } } }
public void Visit(JsBinaryOperator node) { if (node != null) { if (node.Operand1 != null) { node.Operand1.Accept(this); } if (node.Operand2 != null) { node.Operand2.Accept(this); } node.Index = NextOrderIndex; } }
private void ConvertBinaryOperator(JsBinaryOperator node) { // depending on the operator, perform whatever we need to do to apply a logical // not to the operation switch (node.OperatorToken) { case JsToken.Equal: node.OperatorToken = JsToken.NotEqual; break; case JsToken.NotEqual: node.OperatorToken = JsToken.Equal; break; case JsToken.StrictEqual: node.OperatorToken = JsToken.StrictNotEqual; break; case JsToken.StrictNotEqual: node.OperatorToken = JsToken.StrictEqual; break; case JsToken.LessThan: //node.OperatorToken = JSToken.GreaterThanEqual; //break; case JsToken.GreaterThan: //node.OperatorToken = JSToken.LessThanEqual; //break; case JsToken.LessThanEqual: //node.OperatorToken = JSToken.GreaterThan; //break; case JsToken.GreaterThanEqual: //node.OperatorToken = JSToken.LessThan; //break; case JsToken.Assign: case JsToken.PlusAssign: case JsToken.MinusAssign: case JsToken.MultiplyAssign: case JsToken.DivideAssign: case JsToken.ModuloAssign: case JsToken.BitwiseAndAssign: case JsToken.BitwiseOrAssign: case JsToken.BitwiseXorAssign: case JsToken.LeftShiftAssign: case JsToken.RightShiftAssign: case JsToken.UnsignedRightShiftAssign: case JsToken.BitwiseAnd: case JsToken.BitwiseOr: case JsToken.BitwiseXor: case JsToken.Divide: case JsToken.Multiply: case JsToken.Modulo: case JsToken.Minus: case JsToken.Plus: case JsToken.LeftShift: case JsToken.RightShift: case JsToken.UnsignedRightShift: case JsToken.In: case JsToken.InstanceOf: WrapWithLogicalNot(node); break; case JsToken.Comma: // to logical-not a comma-operator, we just need to logical-not the // right-hand side node.Operand2.Accept(this); break; case JsToken.LogicalAnd: case JsToken.LogicalOr: if (node.Parent is JsBlock || (node.Parent is JsCommaOperator && node.Parent.Parent is JsBlock)) { // if the parent is a block, then this is a simple expression statement: // expr1 || expr2; or expr1 && expr2; If so, then the result isn't // used anywhere and we're just using the || or && operator as a // shorter if-statement. So we don't need to negate the right-hand // side, just the left-hand side. if (node.Operand1 != null) { node.Operand1.Accept(this); } } else { // the logical-not of a logical-and or logical-or operation is the // other operation against the not of each operand. Since the opposite // operator is the same length as this operator, then we just need // to recurse both operands and swap the operator token if (node.Operand1 != null) { node.Operand1.Accept(this); } if (node.Operand2 != null) { node.Operand2.Accept(this); } } node.OperatorToken = node.OperatorToken == JsToken.LogicalAnd ? JsToken.LogicalOr : JsToken.LogicalAnd; break; } }
private void MeasureBinaryOperator(JsBinaryOperator node) { // depending on the operator, calculate the potential difference in length switch (node.OperatorToken) { case JsToken.Equal: case JsToken.NotEqual: case JsToken.StrictEqual: case JsToken.StrictNotEqual: // these operators can be turned into a logical not without any // delta in code size. == becomes !=, etc. break; case JsToken.LessThan: case JsToken.GreaterThan: // these operators would add another character when turnbed into a not. // for example, < becomes >=, etc //++m_delta; //break; case JsToken.LessThanEqual: case JsToken.GreaterThanEqual: // these operators would subtract another character when turnbed into a not. // for example, <= becomes >, etc //--m_delta; //break; case JsToken.Assign: case JsToken.PlusAssign: case JsToken.MinusAssign: case JsToken.MultiplyAssign: case JsToken.DivideAssign: case JsToken.ModuloAssign: case JsToken.BitwiseAndAssign: case JsToken.BitwiseOrAssign: case JsToken.BitwiseXorAssign: case JsToken.LeftShiftAssign: case JsToken.RightShiftAssign: case JsToken.UnsignedRightShiftAssign: case JsToken.BitwiseAnd: case JsToken.BitwiseOr: case JsToken.BitwiseXor: case JsToken.Divide: case JsToken.Multiply: case JsToken.Modulo: case JsToken.Minus: case JsToken.Plus: case JsToken.LeftShift: case JsToken.RightShift: case JsToken.UnsignedRightShift: case JsToken.In: case JsToken.InstanceOf: // these operators have no logical not, which means we need to wrap them in // a unary logical-not operator. And since they have a lower precedence than // the unary logical-not, they'll have to be wrapped in parens. So that means // logical-not'ing these guys adds three characters m_delta += 3; break; case JsToken.Comma: // to logical-not a comma-operator, we just need to logical-not the // right-hand side node.Operand2.Accept(this); break; case JsToken.LogicalAnd: case JsToken.LogicalOr: if (node.Parent is JsBlock || (node.Parent is JsCommaOperator && node.Parent.Parent is JsBlock)) { // if the parent is a block, then this is a simple expression statement: // expr1 || expr2; or expr1 && expr2; If so, then the result isn't // used anywhere and we're just using the || or && operator as a // shorter if-statement. So we don't need to negate the right-hand // side, just the left-hand side. if (node.Operand1 != null) { node.Operand1.Accept(this); } } else { // the logical-not of a logical-and or logical-or operation is the // other operation against the not of each operand. Since the opposite // operator is the same length as this operator, then we just need // to recurse both operands to find the true delta. if (node.Operand1 != null) { node.Operand1.Accept(this); } if (node.Operand2 != null) { node.Operand2.Accept(this); } } break; } }
public void Visit(JsBinaryOperator node) { // invalid! ignore IsValid = false; }
public void Visit(JsBinaryOperator node) { // not applicable; terminate }
public void Visit(JsBinaryOperator node) { // lesser precedence than the new operator; use parens m_needsParens = true; }