public override object VisitAssignmentExpression(AssignmentExpression assignment, object data) { base.VisitAssignmentExpression(assignment, data); // Combine "x = x op y" into "x op= y" BinaryOperatorExpression binary = assignment.Right as BinaryOperatorExpression; if (binary != null && assignment.Operator == AssignmentOperatorType.Assign) { if (CanConvertToCompoundAssignment(assignment.Left) && assignment.Left.IsMatch(binary.Left)) { assignment.Operator = GetAssignmentOperatorForBinaryOperator(binary.Operator); if (assignment.Operator != AssignmentOperatorType.Assign) { // If we found a shorter operator, get rid of the BinaryOperatorExpression: assignment.CopyAnnotationsFrom(binary); assignment.Right = binary.Right.WithAnnotation(assignment.Right.GetAllRecursiveILRanges()); assignment.AddAnnotation(new RestoreOriginalAssignOperatorAnnotation(binary)); } } } if (context.Settings.IntroduceIncrementAndDecrement && (assignment.Operator == AssignmentOperatorType.Add || assignment.Operator == AssignmentOperatorType.Subtract)) { // detect increment/decrement if (assignment.Right.IsMatch(new PrimitiveExpression(1))) { // only if it's not a custom operator if (assignment.Annotation <IMethod>() == null) { UnaryOperatorType type; // When the parent is an expression statement, pre- or post-increment doesn't matter; // so we can pick post-increment which is more commonly used (for (int i = 0; i < x; i++)) if (assignment.Parent is ExpressionStatement) { type = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement; } else { type = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.Increment : UnaryOperatorType.Decrement; } assignment.ReplaceWith(new UnaryOperatorExpression(type, assignment.Left.Detach()).CopyAnnotationsFrom(assignment).WithAnnotation(assignment.GetAllRecursiveILRanges())); } } } return(null); }
public override void VisitAssignmentExpression(AssignmentExpression assignment) { base.VisitAssignmentExpression(assignment); // Combine "x = x op y" into "x op= y" BinaryOperatorExpression binary = assignment.Right as BinaryOperatorExpression; if (binary != null && assignment.Operator == AssignmentOperatorType.Assign) { if (CanConvertToCompoundAssignment(assignment.Left) && assignment.Left.IsMatch(binary.Left)) { assignment.Operator = GetAssignmentOperatorForBinaryOperator(binary.Operator); if (assignment.Operator != AssignmentOperatorType.Assign) { // If we found a shorter operator, get rid of the BinaryOperatorExpression: assignment.CopyAnnotationsFrom(binary); assignment.Right = binary.Right; } } } // TODO: context.Settings.IntroduceIncrementAndDecrement if (assignment.Operator == AssignmentOperatorType.Add || assignment.Operator == AssignmentOperatorType.Subtract) { // detect increment/decrement var rr = assignment.Right.GetResolveResult(); if (rr.IsCompileTimeConstant && rr.Type.IsCSharpPrimitiveIntegerType() && CSharpPrimitiveCast.Cast(rr.Type.GetTypeCode(), 1, false).Equals(rr.ConstantValue)) { // only if it's not a custom operator if (assignment.Annotation <IL.CallInstruction>() == null) { UnaryOperatorType type; // When the parent is an expression statement, pre- or post-increment doesn't matter; // so we can pick post-increment which is more commonly used (for (int i = 0; i < x; i++)) if (assignment.Parent is ExpressionStatement) { type = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement; } else { type = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.Increment : UnaryOperatorType.Decrement; } assignment.ReplaceWith(new UnaryOperatorExpression(type, assignment.Left.Detach()).CopyAnnotationsFrom(assignment)); } } } }
public override object VisitAssignmentExpression(AssignmentExpression assignment, object data) { base.VisitAssignmentExpression(assignment, data); // Combine "x = x op y" into "x op= y" BinaryOperatorExpression binary = assignment.Right as BinaryOperatorExpression; if (binary != null && assignment.Operator == AssignmentOperatorType.Assign) { if (IsWithoutSideEffects(assignment.Left) && assignment.Left.Match(binary.Left) != null) { switch (binary.Operator) { case BinaryOperatorType.Add: assignment.Operator = AssignmentOperatorType.Add; break; case BinaryOperatorType.Subtract: assignment.Operator = AssignmentOperatorType.Subtract; break; case BinaryOperatorType.Multiply: assignment.Operator = AssignmentOperatorType.Multiply; break; case BinaryOperatorType.Divide: assignment.Operator = AssignmentOperatorType.Divide; break; case BinaryOperatorType.Modulus: assignment.Operator = AssignmentOperatorType.Modulus; break; case BinaryOperatorType.ShiftLeft: assignment.Operator = AssignmentOperatorType.ShiftLeft; break; case BinaryOperatorType.ShiftRight: assignment.Operator = AssignmentOperatorType.ShiftRight; break; case BinaryOperatorType.BitwiseAnd: assignment.Operator = AssignmentOperatorType.BitwiseAnd; break; case BinaryOperatorType.BitwiseOr: assignment.Operator = AssignmentOperatorType.BitwiseOr; break; case BinaryOperatorType.ExclusiveOr: assignment.Operator = AssignmentOperatorType.ExclusiveOr; break; } if (assignment.Operator != AssignmentOperatorType.Assign) { // If we found a shorter operator, get rid of the BinaryOperatorExpression: assignment.CopyAnnotationsFrom(binary); assignment.Right = binary.Right; } } } if (assignment.Operator == AssignmentOperatorType.Add || assignment.Operator == AssignmentOperatorType.Subtract) { // detect increment/decrement if (assignment.Right.Match(new PrimitiveExpression(1)) != null) { // only if it's not a custom operator if (assignment.Annotation <MethodReference>() == null) { UnaryOperatorType type; // When the parent is an expression statement, pre- or post-increment doesn't matter; // so we can pick post-increment which is more commonly used (for (int i = 0; i < x; i++)) if (assignment.Parent is ExpressionStatement) { type = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement; } else { type = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.Increment : UnaryOperatorType.Decrement; } assignment.ReplaceWith(new UnaryOperatorExpression(type, assignment.Left.Detach()).CopyAnnotationsFrom(assignment)); } } } return(null); }
public override void ExitAssignmentExpression(AssignmentExpression assignmentExpression) { if (assignmentExpression.Operator.Value != "=") { var rightSide = assignmentExpression.Right; rightSide.Remove(); var leftClone = AstCloner.Clone(assignmentExpression.Left); switch (leftClone) { case SimpleNameExpression simpleNameExpression: if (simpleNameExpression.Declaration is SetterDeclaration) { var classDeclaration = (ClassDeclaration)simpleNameExpression.Declaration.Parent; var getterSetter = classDeclaration.GettersAndSetters.Single(x => x.Setter == simpleNameExpression.Declaration); simpleNameExpression.Declaration = getterSetter.Getter; } break; case MemberExpression memberExpression: if (memberExpression.Declaration is SetterDeclaration) { var classDeclaration = (ClassDeclaration)memberExpression.Declaration.Parent; var getterSetter = classDeclaration.GettersAndSetters.Single(x => x.Setter == memberExpression.Declaration); memberExpression.Declaration = getterSetter.Getter; } break; } assignmentExpression.AddChild( new BinaryExpression(assignmentExpression.Context, new INode[] { leftClone, new Token(assignmentExpression.Context, assignmentExpression.Operator.Value.Substring(0, assignmentExpression.Operator.Value.Length - 1)), rightSide })); assignmentExpression.Operator.Value = "="; } if (!(assignmentExpression.Parent is ExpressionStatement || assignmentExpression.Parent is ForStatement || assignmentExpression.Parent is ForeachStatement)) { var statement = assignmentExpression.NearestAncestorOfType <IStatement>(); var block = (BlockStatement)statement.Parent; var variable = new VariableDeclaration(assignmentExpression.Context, "var" + NumberWheel.Next(), new INode[] { assignmentExpression.Type.Wrap(assignmentExpression.Context), assignmentExpression.Right }) { VariableType = VariableType.Const }; block.VariableDeclarations.Add(variable); block.AddChildBefore(statement, new VariableDeclarationStatement(assignmentExpression.Context, variable)); block.AddChildBefore(statement, new ExpressionStatement(assignmentExpression.Context, new AssignmentExpression( assignmentExpression.Context, new INode[] { assignmentExpression.Left, assignmentExpression.Operator, new SimpleNameExpression(assignmentExpression.Context, variable.Name) { Declaration = variable, Type = variable.Type }, }) { Type = assignmentExpression.Type }) ); assignmentExpression.ReplaceWith( new SimpleNameExpression(assignmentExpression.Context, variable.Name) { Declaration = variable, Type = variable.Type }); } }
public override void VisitAssignmentExpression (AssignmentExpression assignmentExpression) { base.VisitAssignmentExpression (assignmentExpression); if (assignmentExpression.Operator != AssignmentOperatorType.Add && assignmentExpression.Operator != AssignmentOperatorType.Subtract) return; var t = assignmentExpression.Left.Annotation<EventDefinition> (); if (t == null) return; var left = assignmentExpression.Left; var right = assignmentExpression.Right; left.Remove (); right.Remove (); var isAdd = assignmentExpression.Operator == AssignmentOperatorType.Add; var m = new InvocationExpression ( new MemberReferenceExpression (left, isAdd ? "Add" : "Remove"), right); assignmentExpression.ReplaceWith (m); }