public void AndIsShortcircuit()
        {
            IExpression falseexpr = new ConstantExpression(false);
            IExpression dividebyzero = new BinaryOperatorExpression(new ConstantExpression(1), new ConstantExpression(0), BinaryOperator.Divide);

            Assert.IsFalse((bool)(new BooleanExpression(falseexpr, dividebyzero, BooleanOperator.And)).Evaluate(null));
        }
		public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
		{
			bool forceSpaces = false;
			switch (binaryOperatorExpression.Operator) {
				case BinaryOperatorType.Equality:
				case BinaryOperatorType.InEquality:
					forceSpaces = policy.SpaceAroundEqualityOperator;
					break;
				case BinaryOperatorType.GreaterThan:
				case BinaryOperatorType.GreaterThanOrEqual:
				case BinaryOperatorType.LessThan:
				case BinaryOperatorType.LessThanOrEqual:
					forceSpaces = policy.SpaceAroundRelationalOperator;
					break;
				case BinaryOperatorType.ConditionalAnd:
				case BinaryOperatorType.ConditionalOr:
					forceSpaces = policy.SpaceAroundLogicalOperator;
					break;
				case BinaryOperatorType.BitwiseAnd:
				case BinaryOperatorType.BitwiseOr:
				case BinaryOperatorType.ExclusiveOr:
					forceSpaces = policy.SpaceAroundBitwiseOperator;
					break;
				case BinaryOperatorType.Add:
				case BinaryOperatorType.Subtract:
					forceSpaces = policy.SpaceAroundAdditiveOperator;
					break;
				case BinaryOperatorType.Multiply:
				case BinaryOperatorType.Divide:
				case BinaryOperatorType.Modulus:
					forceSpaces = policy.SpaceAroundMultiplicativeOperator;
					break;
				case BinaryOperatorType.ShiftLeft:
				case BinaryOperatorType.ShiftRight:
					forceSpaces = policy.SpaceAroundShiftOperator;
					break;
				case BinaryOperatorType.NullCoalescing:
					forceSpaces = policy.SpaceAroundNullCoalescingOperator;
					break;
			}
			var opToken = binaryOperatorExpression.OperatorToken;
			if (opToken.PrevSibling != null && opToken.PrevSibling.Role != Roles.NewLine) {
				ForceSpacesBefore(opToken, forceSpaces);
			} else {
				ForceSpacesAfter(binaryOperatorExpression.Left, false);
				FixIndentation(opToken);
			}
			ForceSpacesAfter(opToken, opToken.NextSibling != null && opToken.NextSibling.Role != Roles.NewLine && forceSpaces);

			binaryOperatorExpression.Left.AcceptVisitor(this);
			// Handle line breaks in binary opeartor expression.
			if (binaryOperatorExpression.Left.EndLocation.Line != binaryOperatorExpression.Right.StartLocation.Line) {
				if (opToken.StartLocation.Line == binaryOperatorExpression.Right.StartLocation.Line) {
					FixStatementIndentation(opToken.StartLocation);
				} else {
					FixStatementIndentation(binaryOperatorExpression.Right.StartLocation);
				}
			}
			binaryOperatorExpression.Right.AcceptVisitor(this);
		}
            public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
            {
                if (binaryOperatorExpression.Operator == BinaryOperatorType.ConditionalAnd)
                    UnlockWith(binaryOperatorExpression);

                return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data);
            }
            public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
            {
                base.VisitBinaryOperatorExpression (binaryOperatorExpression);

                if (binaryOperatorExpression.Operator != BinaryOperatorType.Equality &&
                    binaryOperatorExpression.Operator != BinaryOperatorType.InEquality)
                    return;

                string floatType;
                if (IsNaN(binaryOperatorExpression.Left, out floatType)) {
                    AddIsNaNIssue (binaryOperatorExpression, binaryOperatorExpression.Right, floatType);
                } else if (IsNaN (binaryOperatorExpression.Right, out floatType)) {
                    AddIsNaNIssue (binaryOperatorExpression, binaryOperatorExpression.Left, floatType);
                } else if (IsFloatingPoint(binaryOperatorExpression.Left) || IsFloatingPoint(binaryOperatorExpression.Right)) {
                    if (IsConstantInfinity(binaryOperatorExpression.Left) || IsConstantInfinity(binaryOperatorExpression.Right))
                        return;
                    AddIssue (binaryOperatorExpression, ctx.TranslateString ("Compare a difference with EPSILON"),
                        script => {
                            // Math.Abs(diff) op EPSILON
                            var builder = ctx.CreateTypeSytemAstBuilder(binaryOperatorExpression);
                            var diff = new BinaryOperatorExpression (binaryOperatorExpression.Left.Clone (),
                                BinaryOperatorType.Subtract, binaryOperatorExpression.Right.Clone ());
                            var abs = builder.ConvertType(new TopLevelTypeName("System", "Math")).Invoke("Abs", diff);
                            var op = binaryOperatorExpression.Operator == BinaryOperatorType.Equality ?
                                BinaryOperatorType.LessThan : BinaryOperatorType.GreaterThan;
                            var epsilon = new IdentifierExpression ("EPSILON");
                            var compare = new BinaryOperatorExpression (abs, op, epsilon);
                            script.Replace (binaryOperatorExpression, compare);
                            script.Link (epsilon);
                        });
                }
            }
Beispiel #5
0
        public override void VisitAssignmentExpression(AssignmentExpression expression)
        {
            base.VisitAssignmentExpression (expression);

            Identifier identifier = expression.FindIdentifier();
            if (identifier == null)
                return;

            switch (expression.Operator)
            {
                case AssignmentOperatorType.BitwiseOr:
                case AssignmentOperatorType.BitwiseAnd:
                case AssignmentOperatorType.ExclusiveOr:
                case AssignmentOperatorType.Add:
                case AssignmentOperatorType.Subtract:
                case AssignmentOperatorType.Divide:
                case AssignmentOperatorType.Modulus:
                case AssignmentOperatorType.Multiply:
                case AssignmentOperatorType.ShiftLeft:
                case AssignmentOperatorType.ShiftRight:
                {
                    BinaryOperatorType op = GetComplexAssignOperator (expression.Operator);
                    Expression right = new BinaryOperatorExpression (new IdentifierExpression (identifier.Name), op, expression.Right.Clone());

                    expression.Operator = AssignmentOperatorType.Assign;
                    expression.Right = GetAssignmentExpression (identifier, right);

                    break;
                }

                case AssignmentOperatorType.Assign:
                    expression.Right = GetAssignmentExpression (identifier, expression.Right);
                    break;
            }
        }
        public void OrIsShortcircuit()
        {
            IExpression trueexpr = new ConstantExpression(true);
            IExpression dividebyzero = new BinaryOperatorExpression(new ConstantExpression(1), new ConstantExpression(0), BinaryOperator.Divide);

            Assert.IsTrue((bool)(new BooleanExpression(trueexpr, dividebyzero, BooleanOperator.Or)).Evaluate(null));
        }
		Expression GenerateTarget(RefactoringContext context, BinaryOperatorExpression bOp)
		{
			var rr = context.Resolver.GetResolverStateBefore(bOp).LookupSimpleNameOrTypeName("Equals", emptyTypes, NameLookupMode.Expression) as MethodGroupResolveResult;
			if (rr == null || rr.IsError || HasDifferentEqualsMethod (rr.Methods)) {
				return new PrimitiveType ("object").Member("Equals");
			}
			return new IdentifierExpression("Equals");
		}
        public void EvaluateSubtractExpression()
        {
            BinaryExpression expression = new BinaryOperatorExpression(new ConstantExpression(1), new ConstantExpression(2), BinaryOperator.Subtract);

            Assert.IsNotNull(expression);
            Assert.IsNotNull(expression.Left);
            Assert.IsNotNull(expression.Right);

            Assert.AreEqual(-1, expression.Evaluate(new BindingEnvironment()));
        }
        public void EvaluateMultiplyExpressionWithLeftString()
        {
            BinaryExpression expression = new BinaryOperatorExpression(new ConstantExpression("spam"), new ConstantExpression(3), BinaryOperator.Multiply);

            Assert.IsNotNull(expression);
            Assert.IsNotNull(expression.Left);
            Assert.IsNotNull(expression.Right);

            Assert.AreEqual("spamspamspam", expression.Evaluate(new BindingEnvironment()));
        }
        public void EvaluateDivideToFloatExpression()
        {
            BinaryExpression expression = new BinaryOperatorExpression(new ConstantExpression(4), new ConstantExpression(5), BinaryOperator.Divide);

            Assert.IsNotNull(expression);
            Assert.IsNotNull(expression.Left);
            Assert.IsNotNull(expression.Right);

            Assert.AreEqual(0.8, expression.Evaluate(new BindingEnvironment()));
        }
			static VariableInitializer GetControlVariable(VariableDeclarationStatement variableDecl, 
														  BinaryOperatorExpression condition)
			{
				var controlVariables = variableDecl.Variables.Where (
					v =>
					{
						var identifier = new IdentifierExpression (v.Name);
						return condition.Left.Match (identifier).Success ||
							condition.Right.Match (identifier).Success;
					}).ToList ();
				return controlVariables.Count == 1 ? controlVariables [0] : null;
			}
            public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
            {
                bool leftdangerous = false;
                bool rightdangerous = false;

                if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality)
                {
                    if (binaryOperatorExpression.Left is PrimitiveExpression)
                    {
                        PrimitiveExpression prim = (PrimitiveExpression)binaryOperatorExpression.Left;
                        if (prim.Value.GetType() == typeof(double) ||
                            prim.Value.GetType() == typeof(float) ||
                            prim.Value.GetType() == typeof(decimal))
                        {
                            leftdangerous = true;
                        }
                    }
                    else if (binaryOperatorExpression.Left is IdentifierExpression)
                    {
                        IdentifierExpression idexpr = (IdentifierExpression)binaryOperatorExpression.Left;
                        if (doublefloatvariables.Contains(idexpr.Identifier))
                        {
                            leftdangerous = true;
                        }
                    }

                    if (binaryOperatorExpression.Right is PrimitiveExpression)
                    {
                        PrimitiveExpression prim = (PrimitiveExpression)binaryOperatorExpression.Right;
                        if (prim.Value.GetType() == typeof(double) ||
                            prim.Value.GetType() == typeof(float) ||
                            prim.Value.GetType() == typeof(decimal))
                        {
                            rightdangerous = true;
                        }
                    }
                    else if (binaryOperatorExpression.Right is IdentifierExpression)
                    {
                        IdentifierExpression idexpr = (IdentifierExpression)binaryOperatorExpression.Right;
                        if (doublefloatvariables.Contains(idexpr.Identifier))
                        {
                            rightdangerous = true;
                        }
                    }

                    if (leftdangerous || rightdangerous)
                    {
                        UnlockWith(binaryOperatorExpression);
                    }
                }
                return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data);
            }
Beispiel #13
0
		internal static Expression GetRightSide(BinaryOperatorExpression expression)
		{
			var parent = expression.Parent as BinaryOperatorExpression;
			if (parent != null) {
				if (parent.Left == expression) {
					var parentClone = (BinaryOperatorExpression)parent.Clone();
					parentClone.Left = expression.Right.Clone();
					return parentClone;
				}

			}
			return expression.Right.Clone();
		}
			void AddIsNaNIssue(BinaryOperatorExpression binaryOperatorExpr, Expression argExpr, string floatType)
			{
				if (ctx.Resolve (argExpr).Type.ReflectionName != "System.Single")
					floatType = "double";
				AddIssue (binaryOperatorExpr, string.Format(ctx.TranslateString ("Use {0}.IsNan()"), floatType),
					script => {
						Expression expr = new InvocationExpression (new MemberReferenceExpression (
							new TypeReferenceExpression (new PrimitiveType (floatType)), "IsNaN"), argExpr.Clone ());
						if (binaryOperatorExpr.Operator == BinaryOperatorType.InEquality)
							expr = new UnaryOperatorExpression (UnaryOperatorType.Not, expr);
						script.Replace (binaryOperatorExpr, expr);
					});
			}
Beispiel #15
0
		static CodeAction CreateAndSplit(RefactoringContext context, IfElseStatement ifStatement, BinaryOperatorExpression bOp)
		{
			return new CodeAction(
				context.TranslateString("Split if"),
				script => {
					var nestedIf = (IfElseStatement)ifStatement.Clone();
					nestedIf.Condition = GetRightSide(bOp); 
					script.Replace(ifStatement.Condition, GetLeftSide(bOp));
					script.Replace(ifStatement.TrueStatement, new BlockStatement { nestedIf });
				},
				bOp.OperatorToken
			);
		}
			public override void VisitConditionalExpression(ConditionalExpression conditionalExpression)
			{
				Match m = pattern.Match(conditionalExpression);
				if (m.Success) {
					var a = m.Get<Expression>("a").Single();
					var other = m.Get<Expression>("other").Single();
					AddIssue(conditionalExpression, ctx.TranslateString("Convert to '??' expression"), script => {
						var expr = new BinaryOperatorExpression (a.Clone (), BinaryOperatorType.NullCoalescing, other.Clone ());
						script.Replace (conditionalExpression, expr);
					});
				}
				base.VisitConditionalExpression (conditionalExpression);
			}
        public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
        {
            base.VisitBinaryOperatorExpression(binaryOperatorExpression);

            var left = binaryOperatorExpression.Left;
            var right = binaryOperatorExpression.Right;

            if (left is IdentifierExpression &&
                right is IdentifierExpression)
            {
                var leftIdent = (left as IdentifierExpression).Identifier;
                var rightIdent = (right as IdentifierExpression).Identifier;
                if (leftIdent == rightIdent)
                {
                    if (binaryOperatorExpression.Operator == BinaryOperatorType.Subtract)
                    {
                        binaryOperatorExpression.ReplaceWith(new PrimitiveExpression(0));
                        return;
                    }
                }
            }

            if (right is PrimitiveExpression &&
                (right as PrimitiveExpression).Value is int &&
                (int)(right as PrimitiveExpression).Value == 0)
            {
                if (binaryOperatorExpression.Operator == BinaryOperatorType.Add ||
                    binaryOperatorExpression.Operator == BinaryOperatorType.Subtract)
                {
                    binaryOperatorExpression.ReplaceWith(left);
                    return;
                }
            }

            if (binaryOperatorExpression.Operator == BinaryOperatorType.ConditionalAnd)
            {
                if (ReplaceConditionalAnd(binaryOperatorExpression, left, right) ||
                    ReplaceConditionalAnd(binaryOperatorExpression, right, left))
                    return;
            }

            if (binaryOperatorExpression.Operator == BinaryOperatorType.ConditionalOr)
            {
                if (ReplaceConditionalOr(binaryOperatorExpression, left, right) ||
                    ReplaceConditionalOr(binaryOperatorExpression, right, left))
                    return;
            }
        }
        protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                        new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit();
                    return true;
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    if (orr.IsLiftedOperator)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.lift(");
                    }

                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    if (orr.IsLiftedOperator)
                    {
                        this.WriteComma();
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    new ExpressionListBlock(this.Emitter,
                        new Expression[] {binaryOperatorExpression.Left, binaryOperatorExpression.Right}, null).Emit();
                    this.WriteCloseParentheses();

                    return true;
                }
            }

            return false;
        }
Beispiel #19
0
		static CodeAction CreateOrSplit(RefactoringContext context, IfElseStatement ifStatement, BinaryOperatorExpression bOp)
		{
			return new CodeAction(
				context.TranslateString("Split if"),
				script => {
					var newElse = (IfElseStatement)ifStatement.Clone();
					newElse.Condition = GetRightSide(bOp); 
					
					var newIf = (IfElseStatement)ifStatement.Clone();
					newIf.Condition = GetLeftSide(bOp); 
					newIf.FalseStatement = newElse;

					script.Replace(ifStatement, newIf);
					script.FormatText(newIf);
				},
				bOp.OperatorToken
			);
		}
		// The following conversions are implemented:
		//   a == null -> a Is Nothing
		//   a != null -> a Is Not Nothing
		//   i++ / ++i as statement: convert to i += 1
		//   i-- / --i as statement: convert to i -= 1
		//   ForStatement -> ForNextStatement when for-loop is simple
		//   if (Event != null) Event(this, bla); -> RaiseEvent Event(this, bla)
		//   Casts to value types are marked as conversions
		
		public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
		{
			if (binaryOperatorExpression.Op == BinaryOperatorType.Equality || binaryOperatorExpression.Op == BinaryOperatorType.InEquality) {
				if (IsNullLiteralExpression(binaryOperatorExpression.Left)) {
					Expression tmp = binaryOperatorExpression.Left;
					binaryOperatorExpression.Left = binaryOperatorExpression.Right;
					binaryOperatorExpression.Right = tmp;
				}
				if (IsNullLiteralExpression(binaryOperatorExpression.Right)) {
					if (binaryOperatorExpression.Op == BinaryOperatorType.Equality) {
						binaryOperatorExpression.Op = BinaryOperatorType.ReferenceEquality;
					} else {
						binaryOperatorExpression.Op = BinaryOperatorType.ReferenceInequality;
					}
				}
			}
			return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data);
		}
Beispiel #21
0
        public ArgumentsInfo(IEmitter emitter, BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult operatorResolveResult)
        {
            this.Emitter = emitter;
            this.Expression = binaryOperatorExpression;
            this.OperatorResolveResult = operatorResolveResult;

            if (operatorResolveResult.UserDefinedOperatorMethod != null)
            {
                this.BuildOperatorArgumentsList(new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right });
                this.BuildOperatorTypedArguments();
            }
            else
            {
                this.ArgumentsExpressions = new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right };
                this.ArgumentsNames = new string[] { "left", "right" };
                this.CreateNamedExpressions(this.ArgumentsNames, this.ArgumentsExpressions);
            }
        }
			public override void VisitBinaryOperatorExpression (BinaryOperatorExpression binaryOperatorExpression)
			{
				base.VisitBinaryOperatorExpression (binaryOperatorExpression);

				var match = pattern.Match (binaryOperatorExpression);
				if (!match.Success)
					return;

				AddIssue (binaryOperatorExpression, ctx.TranslateString ("Simplify boolean comparison"), scrpit => {
					var expr = match.Get<Expression> ("expr").First ().Clone ();
					var boolConstant = (bool)match.Get<PrimitiveExpression> ("const").First ().Value;
					if ((binaryOperatorExpression.Operator == BinaryOperatorType.InEquality && boolConstant) ||
						(binaryOperatorExpression.Operator == BinaryOperatorType.Equality && !boolConstant)) {
						expr = new UnaryOperatorExpression (UnaryOperatorType.Not, expr);
						expr.AcceptVisitor (insertParenthesesVisitor);
					}
					scrpit.Replace (binaryOperatorExpression, expr);
				});
			}
        public void AdditionWithConditional()
        {
            Expression expr = new BinaryOperatorExpression {
                Left = new IdentifierExpression("a"),
                Operator = BinaryOperatorType.Add,
                Right = new ConditionalExpression {
                    Condition = new BinaryOperatorExpression {
                        Left = new IdentifierExpression("b"),
                        Operator = BinaryOperatorType.Equality,
                        Right = new PrimitiveExpression(null)
                    },
                    TrueExpression = new IdentifierExpression("c"),
                    FalseExpression = new IdentifierExpression("d")
                }
            };

            Assert.AreEqual("a + (b == null ? c : d)", InsertRequired(expr));
            Assert.AreEqual("a + ((b == null) ? c : d)", InsertReadable(expr));
        }
Beispiel #24
0
        public override Expression Visit(BinaryOperatorExpression expression)
        {
            var left = expression.Left.Accept(this);
            var right = expression.Right.Accept(this);

            var leftNum = left as NumberExpression;
            var rightNum = right as NumberExpression;

            if (leftNum == null && rightNum == null)
                return new BinaryOperatorExpression(expression.Start, left, right);

            // n <op> n
            Func<int, int, int> simplifyOp;
            if (_simplifyMap.TryGetValue(expression.Operation, out simplifyOp) &&
                leftNum != null &&
                rightNum != null)
            {
                try
                {
                    var result = simplifyOp(leftNum.Value, rightNum.Value);
                    var token = new LoonyToken(expression.Start, LoonyTokenType.Number, null);
                    return new NumberExpression(token, result);
                }
                catch (DivideByZeroException)
                {
                    throw new CompilerException(expression.Start, CompilerError.DivisionByZero);
                }
            }

            // 0 + e || e + 0
            if (expression.Operation == LoonyTokenType.Add)
            {
                if (leftNum != null && leftNum.Value == 0)
                    return right;

                if (rightNum != null && rightNum.Value == 0)
                    return left;
            }

            return new BinaryOperatorExpression(expression.Start, left, right);
        }
        public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
        {
            base.VisitBinaryOperatorExpression(binaryOperatorExpression);

            // Looking for patterns like:
            //
            // 2 - 2
            var valueLeft = AstHelpers.GetValueFromExpression(binaryOperatorExpression.Left);
            var valueRight = AstHelpers.GetValueFromExpression(binaryOperatorExpression.Right);
            if (valueLeft == null || valueRight == null)
                return;

            try
            {
                dynamic valueResult;
                switch (binaryOperatorExpression.Operator)
                {
                    case BinaryOperatorType.Add:
                        valueResult = valueLeft + valueRight;
                        break;
                    case BinaryOperatorType.Subtract:
                        valueResult = valueLeft - valueRight;
                        break;
                    case BinaryOperatorType.Divide:
                        valueResult = valueLeft / valueRight;
                        break;
                    case BinaryOperatorType.Multiply:
                        valueResult = valueLeft * valueRight;
                        break;
                    default:
                        return;
                }

                binaryOperatorExpression.ReplaceWith(new PrimitiveExpression(valueResult));
            }
            catch (Exception)
            {
                // Can't do anything with this value perhaps, so just ignore it and leave
                // the code as-is.
            }
        }
		public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
		{
			bool lhs = binaryOperatorExpression.Left.AcceptVisitor(this, data) == SymbolDefined;
			bool rhs = binaryOperatorExpression.Right.AcceptVisitor(this, data) == SymbolDefined;
			bool result;
			switch (binaryOperatorExpression.Op) {
				case BinaryOperatorType.LogicalAnd:
					result = lhs && rhs;
					break;
				case BinaryOperatorType.LogicalOr:
					result = lhs || rhs;
					break;
				case BinaryOperatorType.Equality:
					result = lhs == rhs;
					break;
				case BinaryOperatorType.InEquality:
					result = lhs != rhs;
					break;
				default:
					return null;
			}
			return result ? SymbolDefined : null;
		}
			public override void VisitBinaryOperatorExpression (BinaryOperatorExpression binaryOperatorExpression)
			{
				base.VisitBinaryOperatorExpression (binaryOperatorExpression);

				var match = pattern.Match (binaryOperatorExpression);
				if (!match.Success)
					return;
				var expr = match.First<Expression>("expr");
				// check if expr is of boolean type
				var exprType = ctx.Resolve (expr).Type.GetDefinition ();
				if (exprType == null || exprType.KnownTypeCode != KnownTypeCode.Boolean)
					return;

				AddIssue (binaryOperatorExpression, ctx.TranslateString ("Simplify boolean comparison"), scrpit => {
                    var boolConstant = (bool)match.First<PrimitiveExpression>("const").Value;
					if ((binaryOperatorExpression.Operator == BinaryOperatorType.InEquality && boolConstant) ||
						(binaryOperatorExpression.Operator == BinaryOperatorType.Equality && !boolConstant)) {
						expr = new UnaryOperatorExpression (UnaryOperatorType.Not, expr.Clone());
						expr.AcceptVisitor (insertParenthesesVisitor);
					}
					scrpit.Replace (binaryOperatorExpression, expr);
				});
			}
Beispiel #28
0
        public ExpressionTree(ParseInfo parseInfo, Scope scope, BinaryOperatorExpression exprContext, bool usedAsValue)
        {
            _parseInfo      = parseInfo;
            ExprContextTree = Flatten(parseInfo.Script, exprContext);

            // Setup
            var usageResolvers = new UsageResolver[ExprContextTree.Length];

            for (int i = 0; i < ExprContextTree.Length; i++)
            {
                usageResolvers[i] = new UsageResolver();

                ParseInfo partInfo = parseInfo.SetUsageResolver(usageResolvers[i], i == 0 ? null : usageResolvers[i - 1]);
                // If this is not the first expression, clear tail data and set the source expression.
                if (i != 0)
                {
                    partInfo = partInfo.ClearTail().SetSourceExpression(ExprContextTree[i - 1]);
                }
                // If this is not the last expression, clear head data.
                if (i != ExprContextTree.Length - 1)
                {
                    partInfo = partInfo.ClearHead();
                }

                ExprContextTree[i].Setup(new TreeContextParseInfo()
                {
                    ParseInfo        = partInfo,
                    Getter           = scope,
                    Scope            = i == 0 ? scope : ExprContextTree[i - 1].GetScope() ?? new Scope(),
                    Parent           = i == 0 ? null : ExprContextTree[i - 1],
                    UsedAsExpression = usedAsValue || i < ExprContextTree.Length - 1,
                    IsLast           = i == ExprContextTree.Length - 1
                });
            }

            for (int i = 0; i < usageResolvers.Length; i++)
            {
                usageResolvers[i].ResolveUnknownIfNotResolved();
            }

            // Get expressions
            Tree = new IExpression[ExprContextTree.Length];
            IExpression current = ExprContextTree[0].GetExpression();

            Tree[0] = current;
            if (current != null)
            {
                for (int i = 1; i < ExprContextTree.Length; i++)
                {
                    current = ExprContextTree[i].GetExpression();

                    Tree[i] = current;

                    if (current == null)
                    {
                        Completed = false;
                        break;
                    }
                }
            }
            else
            {
                Completed = false;
            }

            if (Completed)
            {
                Result = Tree[Tree.Length - 1];
            }

            // Get the completion items for each expression in the path.
            GetCompletion(parseInfo, scope);
        }
Beispiel #29
0
 public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
 {
     binaryOperatorExpression.Left.AcceptVisitor(this);
     binaryOperatorExpression.Right.AcceptVisitor(this);
 }
Beispiel #30
0
        void ProcessInvocationExpression(InvocationExpression invocationExpression)
        {
            var method = invocationExpression.GetSymbol() as IMethod;

            if (method == null)
            {
                return;
            }
            var arguments = invocationExpression.Arguments.ToArray();

            // Reduce "String.Concat(a, b)" to "a + b"
            if (method.Name == "Concat" && method.DeclaringType.FullName == "System.String" && CheckArgumentsForStringConcat(arguments))
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                Expression expr = arguments[0];
                for (int i = 1; i < arguments.Length; i++)
                {
                    expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]);
                }
                expr.CopyAnnotationsFrom(invocationExpression);
                invocationExpression.ReplaceWith(expr);
                return;
            }

            switch (method.FullName)
            {
            case "System.Type.GetTypeFromHandle":
                if (arguments.Length == 1)
                {
                    if (typeHandleOnTypeOfPattern.IsMatch(arguments[0]))
                    {
                        Expression target = ((MemberReferenceExpression)arguments[0]).Target;
                        target.CopyInstructionsFrom(invocationExpression);
                        invocationExpression.ReplaceWith(target);
                        return;
                    }
                }
                break;

            /*
             * case "System.Reflection.FieldInfo.GetFieldFromHandle":
             * // TODO : This is dead code because LdTokenAnnotation is not added anywhere:
             * if (arguments.Length == 1) {
             *      MemberReferenceExpression mre = arguments[0] as MemberReferenceExpression;
             *      if (mre != null && mre.MemberName == "FieldHandle" && mre.Target.Annotation<LdTokenAnnotation>() != null) {
             *              invocationExpression.ReplaceWith(mre.Target);
             *              return;
             *      }
             * } else if (arguments.Length == 2) {
             *      MemberReferenceExpression mre1 = arguments[0] as MemberReferenceExpression;
             *      MemberReferenceExpression mre2 = arguments[1] as MemberReferenceExpression;
             *      if (mre1 != null && mre1.MemberName == "FieldHandle" && mre1.Target.Annotation<LdTokenAnnotation>() != null) {
             *              if (mre2 != null && mre2.MemberName == "TypeHandle" && mre2.Target is TypeOfExpression) {
             *                      Expression oldArg = ((InvocationExpression)mre1.Target).Arguments.Single();
             *                      FieldReference field = oldArg.Annotation<FieldReference>();
             *                      if (field != null) {
             *                              AstType declaringType = ((TypeOfExpression)mre2.Target).Type.Detach();
             *                              oldArg.ReplaceWith(new MemberReferenceExpression(new TypeReferenceExpression(declaringType), field.Name).CopyAnnotationsFrom(oldArg));
             *                              invocationExpression.ReplaceWith(mre1.Target);
             *                              return;
             *                      }
             *              }
             *      }
             * }
             * break;
             */
            case "System.Activator.CreateInstance":
                if (arguments.Length == 0 && method.TypeArguments.Count == 1 && IsInstantiableTypeParameter(method.TypeArguments[0]))
                {
                    invocationExpression.ReplaceWith(new ObjectCreateExpression(context.TypeSystemAstBuilder.ConvertType(method.TypeArguments.First())));
                }
                break;
            }

            BinaryOperatorType?bop = GetBinaryOperatorTypeFromMetadataName(method.Name);

            if (bop != null && arguments.Length == 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                invocationExpression.ReplaceWith(
                    new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).CopyAnnotationsFrom(invocationExpression)
                    );
                return;
            }
            UnaryOperatorType?uop = GetUnaryOperatorTypeFromMetadataName(method.Name);

            if (uop != null && arguments.Length == 1)
            {
                if (uop == UnaryOperatorType.Increment || uop == UnaryOperatorType.Decrement)
                {
                    // `op_Increment(a)` is not equivalent to `++a`,
                    // because it doesn't assign the incremented value to a.
                    if (method.DeclaringType.IsKnownType(KnownTypeCode.Decimal))
                    {
                        // Legacy csc optimizes "d + 1m" to "op_Increment(d)",
                        // so reverse that optimization here:
                        invocationExpression.ReplaceWith(
                            new BinaryOperatorExpression(
                                arguments[0].Detach(),
                                (uop == UnaryOperatorType.Increment ? BinaryOperatorType.Add : BinaryOperatorType.Subtract),
                                new PrimitiveExpression(1m)
                                ).CopyAnnotationsFrom(invocationExpression)
                            );
                    }
                    return;
                }
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    new UnaryOperatorExpression(uop.Value, arguments[0]).CopyAnnotationsFrom(invocationExpression)
                    );
                return;
            }
            if (method.Name == "op_Explicit" && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.ReturnType), arguments[0])
                    .CopyAnnotationsFrom(invocationExpression)
                    );
                return;
            }
            if (method.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition)
            {
                invocationExpression.ReplaceWith(arguments[0]);
                return;
            }

            return;
        }
Beispiel #31
0
 public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
 {
     new BinaryOperatorBlock(this, binaryOperatorExpression).Emit();
 }
Beispiel #32
0
        protected void VisitBinaryOperatorExpression()
        {
            BinaryOperatorExpression binaryOperatorExpression = this.BinaryOperatorExpression;

            if (this.Emitter.IsAsync && (
                    binaryOperatorExpression.Operator == BinaryOperatorType.BitwiseAnd ||
                    binaryOperatorExpression.Operator == BinaryOperatorType.BitwiseOr ||
                    binaryOperatorExpression.Operator == BinaryOperatorType.ConditionalOr ||
                    binaryOperatorExpression.Operator == BinaryOperatorType.ConditionalAnd
                    ) && this.GetAwaiters(binaryOperatorExpression).Length > 0)
            {
                if (this.Emitter.AsyncBlock.WrittenAwaitExpressions.Contains(binaryOperatorExpression))
                {
                    var index = System.Array.IndexOf(this.Emitter.AsyncBlock.AwaitExpressions, binaryOperatorExpression) + 1;
                    this.Write(JS.Vars.ASYNC_TASK_RESULT + index);
                }
                else
                {
                    var index = System.Array.IndexOf(this.Emitter.AsyncBlock.AwaitExpressions, binaryOperatorExpression) + 1;
                    this.WriteAsyncBinaryExpression(index);
                }

                return;
            }

            var  resolveOperator       = this.Emitter.Resolver.ResolveNode(binaryOperatorExpression, this.Emitter);
            var  expectedType          = this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression);
            bool isDecimalExpected     = Helpers.IsDecimalType(expectedType, this.Emitter.Resolver);
            bool isDecimal             = Helpers.IsDecimalType(resolveOperator.Type, this.Emitter.Resolver);
            bool isLongExpected        = Helpers.Is64Type(expectedType, this.Emitter.Resolver);
            bool isLong                = Helpers.Is64Type(resolveOperator.Type, this.Emitter.Resolver);
            OperatorResolveResult orr  = resolveOperator as OperatorResolveResult;
            var    leftResolverResult  = this.Emitter.Resolver.ResolveNode(binaryOperatorExpression.Left, this.Emitter);
            var    rightResolverResult = this.Emitter.Resolver.ResolveNode(binaryOperatorExpression.Right, this.Emitter);
            var    charToString        = -1;
            string variable            = null;
            bool   leftIsNull          = this.BinaryOperatorExpression.Left is NullReferenceExpression;
            bool   rightIsNull         = this.BinaryOperatorExpression.Right is NullReferenceExpression;
            bool   isUint              = resolveOperator.Type.IsKnownType(KnownTypeCode.UInt16) ||
                                         resolveOperator.Type.IsKnownType(KnownTypeCode.UInt32) ||
                                         resolveOperator.Type.IsKnownType(KnownTypeCode.UInt64);

            var isFloatResult    = Helpers.IsFloatType(resolveOperator.Type, this.Emitter.Resolver);
            var leftExpected     = this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Left);
            var rightExpected    = this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Right);
            var strictNullChecks = this.Emitter.AssemblyInfo.StrictNullChecks;

            if (orr != null && orr.Type.IsKnownType(KnownTypeCode.String))
            {
                for (int i = 0; i < orr.Operands.Count; i++)
                {
                    var crr = orr.Operands[i] as ConversionResolveResult;
                    if (crr != null && crr.Input.Type.IsKnownType(KnownTypeCode.Char))
                    {
                        charToString = i;
                    }
                }
            }

            if (resolveOperator is ConstantResolveResult)
            {
                this.WriteScript(((ConstantResolveResult)resolveOperator).ConstantValue);
                return;
            }

            var resultIsString   = expectedType.IsKnownType(KnownTypeCode.String) || resolveOperator.Type.IsKnownType(KnownTypeCode.String);
            var isStringConcat   = resultIsString && binaryOperatorExpression.Operator == BinaryOperatorType.Add;
            var toStringForLeft  = false;
            var toStringForRight = false;

            var  parentBinary   = binaryOperatorExpression.Parent as BinaryOperatorExpression;
            bool parentIsString = resultIsString && parentBinary != null && parentBinary.Operator == BinaryOperatorType.Add;

            if (parentIsString)
            {
                var parentResolveOperator = this.Emitter.Resolver.ResolveNode(binaryOperatorExpression.Parent, this.Emitter) as OperatorResolveResult;

                if (parentResolveOperator != null && parentResolveOperator.UserDefinedOperatorMethod != null)
                {
                    parentIsString = false;
                }
            }

            bool isSimpleConcat = isStringConcat && BinaryOperatorBlock.IsOperatorSimple(binaryOperatorExpression, this.Emitter);

            if (charToString == -1 && isStringConcat && !leftResolverResult.Type.IsKnownType(KnownTypeCode.String))
            {
                toStringForLeft = true;
            }

            if (charToString == -1 && isStringConcat && !rightResolverResult.Type.IsKnownType(KnownTypeCode.String))
            {
                toStringForRight = true;
            }

            if (!isStringConcat && (Helpers.IsDecimalType(leftResolverResult.Type, this.Emitter.Resolver) || Helpers.IsDecimalType(rightResolverResult.Type, this.Emitter.Resolver)))
            {
                isDecimal         = true;
                isDecimalExpected = true;
            }

            if (isDecimal && isDecimalExpected && binaryOperatorExpression.Operator != BinaryOperatorType.NullCoalescing)
            {
                this.HandleDecimal(resolveOperator);
                return;
            }

            var isLeftLong  = Helpers.Is64Type(leftExpected, this.Emitter.Resolver);
            var isRightLong = Helpers.Is64Type(rightExpected, this.Emitter.Resolver);

            if (!isLeftLong && !isRightLong)
            {
                if (leftExpected.Kind == TypeKind.Enum && Helpers.Is64Type(leftExpected.GetDefinition().EnumUnderlyingType, this.Emitter.Resolver))
                {
                    isLeftLong = true;
                }

                if (rightExpected.Kind == TypeKind.Enum && Helpers.Is64Type(rightExpected.GetDefinition().EnumUnderlyingType, this.Emitter.Resolver))
                {
                    isRightLong = true;
                }
            }

            if (!(resultIsString && binaryOperatorExpression.Operator == BinaryOperatorType.Add) && (isLeftLong || isRightLong))
            {
                isLong         = true;
                isLongExpected = true;
            }

            if (isLong && isLongExpected && binaryOperatorExpression.Operator != BinaryOperatorType.NullCoalescing)
            {
                if (!isFloatResult || binaryOperatorExpression.Operator == BinaryOperatorType.Divide && isLeftLong)
                {
                    this.HandleLong(resolveOperator, isUint);
                    return;
                }
            }

            var delegateOperator = false;

            if (this.ResolveOperator(binaryOperatorExpression, orr))
            {
                return;
            }

            if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality || binaryOperatorExpression.Operator == BinaryOperatorType.InEquality)
            {
                if (leftIsNull || rightIsNull)
                {
                    this.WritePart(binaryOperatorExpression.Left, toStringForLeft, leftResolverResult);

                    if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality)
                    {
                        this.Write(strictNullChecks ? " === " : " == ");
                    }
                    else
                    {
                        this.Write(strictNullChecks ? " !== " : " != ");
                    }

                    this.WritePart(binaryOperatorExpression.Right, toStringForRight, rightResolverResult);
                    return;
                }
            }

            var insideOverflowContext = ConversionBlock.InsideOverflowContext(this.Emitter, binaryOperatorExpression);

            if (binaryOperatorExpression.Operator == BinaryOperatorType.Divide &&
                !(this.Emitter.IsJavaScriptOverflowMode && !insideOverflowContext) &&
                (
                    (Helpers.IsIntegerType(leftResolverResult.Type, this.Emitter.Resolver) &&
                     Helpers.IsIntegerType(rightResolverResult.Type, this.Emitter.Resolver)) ||

                    (Helpers.IsIntegerType(this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Left), this.Emitter.Resolver) &&
                     Helpers.IsIntegerType(this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Right), this.Emitter.Resolver))
                ))
            {
                this.Write(JS.Types.BRIDGE_INT + "." + JS.Funcs.Math.DIV + "(");
                this.WritePart(binaryOperatorExpression.Left, toStringForLeft, leftResolverResult);
                this.Write(", ");
                this.WritePart(binaryOperatorExpression.Right, toStringForRight, rightResolverResult);
                this.Write(")");
                return;
            }

            if (binaryOperatorExpression.Operator == BinaryOperatorType.Multiply &&
                !(this.Emitter.IsJavaScriptOverflowMode && !insideOverflowContext) &&
                (
                    (Helpers.IsInteger32Type(leftResolverResult.Type, this.Emitter.Resolver) &&
                     Helpers.IsInteger32Type(rightResolverResult.Type, this.Emitter.Resolver) &&
                     Helpers.IsInteger32Type(resolveOperator.Type, this.Emitter.Resolver)) ||

                    (Helpers.IsInteger32Type(this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Left), this.Emitter.Resolver) &&
                     Helpers.IsInteger32Type(this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Right), this.Emitter.Resolver) &&
                     Helpers.IsInteger32Type(resolveOperator.Type, this.Emitter.Resolver))
                ))
            {
                isUint = NullableType.GetUnderlyingType(resolveOperator.Type).IsKnownType(KnownTypeCode.UInt32);
                this.Write(JS.Types.BRIDGE_INT + "." + (isUint ? JS.Funcs.Math.UMUL : JS.Funcs.Math.MUL) + "(");
                this.WritePart(binaryOperatorExpression.Left, toStringForLeft, leftResolverResult);
                this.Write(", ");
                this.WritePart(binaryOperatorExpression.Right, toStringForRight, rightResolverResult);

                if (ConversionBlock.IsInCheckedContext(this.Emitter, this.BinaryOperatorExpression))
                {
                    this.Write(", 1");
                }

                this.Write(")");
                return;
            }

            if (binaryOperatorExpression.Operator == BinaryOperatorType.Add ||
                binaryOperatorExpression.Operator == BinaryOperatorType.Subtract)
            {
                var add = binaryOperatorExpression.Operator == BinaryOperatorType.Add;

                if (expectedType.Kind == TypeKind.Delegate || this.Emitter.Validator.IsDelegateOrLambda(leftResolverResult) && this.Emitter.Validator.IsDelegateOrLambda(rightResolverResult))
                {
                    delegateOperator = true;
                    this.Write(add ? JS.Funcs.BRIDGE_COMBINE : JS.Funcs.BRIDGE_REMOVE);
                    this.WriteOpenParentheses();
                }
            }

            if (isStringConcat && !parentIsString && !isSimpleConcat)
            {
                this.Write(JS.Types.System.String.CONCAT);
                this.WriteOpenParentheses();
            }

            bool nullable     = orr != null && orr.IsLiftedOperator;
            bool isCoalescing = (this.Emitter.AssemblyInfo.StrictNullChecks ||
                                 NullableType.IsNullable(leftResolverResult.Type) ||
                                 leftResolverResult.Type.IsKnownType(KnownTypeCode.String) ||
                                 leftResolverResult.Type.IsKnownType(KnownTypeCode.Object)
                                 ) && binaryOperatorExpression.Operator == BinaryOperatorType.NullCoalescing;
            string root        = JS.Types.SYSTEM_NULLABLE + ".";
            bool   special     = nullable;
            bool   rootSpecial = nullable;
            bool   isBool      = NullableType.IsNullable(resolveOperator.Type) ? NullableType.GetUnderlyingType(resolveOperator.Type).IsKnownType(KnownTypeCode.Boolean) : resolveOperator.Type.IsKnownType(KnownTypeCode.Boolean);
            bool   toBool      = isBool && !rootSpecial && !delegateOperator && (binaryOperatorExpression.Operator == BinaryOperatorType.BitwiseAnd || binaryOperatorExpression.Operator == BinaryOperatorType.BitwiseOr);
            bool   isRefEquals = !isCoalescing && !strictNullChecks &&
                                 (binaryOperatorExpression.Operator == BinaryOperatorType.InEquality || binaryOperatorExpression.Operator == BinaryOperatorType.Equality) &&
                                 leftExpected.IsReferenceType.HasValue && leftExpected.IsReferenceType.Value &&
                                 rightExpected.IsReferenceType.HasValue && rightExpected.IsReferenceType.Value;

            if (rootSpecial)
            {
                this.Write(root);
            }
            else if (!isRefEquals)
            {
                if (isCoalescing)
                {
                    this.Write("(");
                    variable = this.GetTempVarName();
                    this.Write(variable);
                    this.Write(" = ");
                }
                else if (charToString == 0)
                {
                    this.Write(JS.Funcs.STRING_FROMCHARCODE + "(");
                }

                if (toBool)
                {
                    this.Write("!!(");
                }

                this.WritePart(binaryOperatorExpression.Left, toStringForLeft, leftResolverResult, isCoalescing);

                if (isCoalescing)
                {
                    this.Write(", ");
                    this.Write(variable);

                    this.Write(strictNullChecks ? " !== null" : " != null");

                    this.Write(" ? ");

                    ConversionBlock.expressionMap.Add(binaryOperatorExpression.Left, variable);
                    //this.Write(variable);
                    binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                    ConversionBlock.expressionMap.Remove(binaryOperatorExpression.Left);
                }
                else if (charToString == 0)
                {
                    this.Write(")");
                }
            }

            if (isRefEquals)
            {
                if (binaryOperatorExpression.Operator == BinaryOperatorType.InEquality)
                {
                    this.Write("!");
                }
                this.Write(JS.Funcs.BRIDGE_REFERENCEEQUALS);
                special = true;
            }

            if (!delegateOperator && (!isStringConcat || isSimpleConcat))
            {
                if (!special)
                {
                    this.WriteSpace();
                }

                switch (binaryOperatorExpression.Operator)
                {
                case BinaryOperatorType.Add:
                    this.Write(rootSpecial ? JS.Funcs.Math.ADD : "+");
                    break;

                case BinaryOperatorType.BitwiseAnd:
                    if (isBool)
                    {
                        this.Write(rootSpecial ? JS.Funcs.Math.AND : "&");
                    }
                    else
                    {
                        this.Write(rootSpecial ? JS.Funcs.Math.BAND : "&");
                    }

                    break;

                case BinaryOperatorType.BitwiseOr:
                    if (isBool)
                    {
                        this.Write(rootSpecial ? JS.Funcs.Math.OR : "|");
                    }
                    else
                    {
                        this.Write(rootSpecial ? JS.Funcs.Math.BOR : "|");
                    }
                    break;

                case BinaryOperatorType.ConditionalAnd:
                    this.Write(rootSpecial ? JS.Funcs.Math.AND : "&&");
                    break;

                case BinaryOperatorType.NullCoalescing:
                    this.Write(isCoalescing ? ":" : "||");
                    break;

                case BinaryOperatorType.ConditionalOr:
                    this.Write(rootSpecial ? JS.Funcs.Math.OR : "||");
                    break;

                case BinaryOperatorType.Divide:
                    this.Write(rootSpecial ? JS.Funcs.Math.DIV : "/");
                    break;

                case BinaryOperatorType.Equality:
                    if (!isRefEquals)
                    {
                        this.Write(rootSpecial ? "eq" : "===");
                    }

                    break;

                case BinaryOperatorType.ExclusiveOr:
                    this.Write(rootSpecial ? JS.Funcs.Math.XOR : "^");
                    break;

                case BinaryOperatorType.GreaterThan:
                    this.Write(rootSpecial ? JS.Funcs.Math.GT : ">");
                    break;

                case BinaryOperatorType.GreaterThanOrEqual:
                    this.Write(rootSpecial ? JS.Funcs.Math.GTE : ">=");
                    break;

                case BinaryOperatorType.InEquality:
                    if (!isRefEquals)
                    {
                        this.Write(rootSpecial ? "neq" : "!==");
                    }
                    break;

                case BinaryOperatorType.LessThan:
                    this.Write(rootSpecial ? JS.Funcs.Math.LT : "<");
                    break;

                case BinaryOperatorType.LessThanOrEqual:
                    this.Write(rootSpecial ? JS.Funcs.Math.LTE : "<=");
                    break;

                case BinaryOperatorType.Modulus:
                    this.Write(rootSpecial ? JS.Funcs.Math.MOD : "%");
                    break;

                case BinaryOperatorType.Multiply:
                    this.Write(rootSpecial ? JS.Funcs.Math.MUL : "*");
                    break;

                case BinaryOperatorType.ShiftLeft:
                    this.Write(rootSpecial ? JS.Funcs.Math.SL : "<<");
                    break;

                case BinaryOperatorType.ShiftRight:
                    if (isUint)
                    {
                        this.Write(rootSpecial ? JS.Funcs.Math.SRR : ">>>");
                    }
                    else
                    {
                        this.Write(rootSpecial ? JS.Funcs.Math.SR : ">>");
                    }

                    break;

                case BinaryOperatorType.Subtract:
                    this.Write(rootSpecial ? JS.Funcs.Math.SUB : "-");
                    break;

                default:
                    throw new EmitterException(binaryOperatorExpression, "Unsupported binary operator: " + binaryOperatorExpression.Operator.ToString());
                }
            }
            else
            {
                this.WriteComma();
            }

            if (special)
            {
                this.WriteOpenParentheses();
                if (charToString == 0)
                {
                    this.Write(JS.Funcs.STRING_FROMCHARCODE + "(");
                }

                this.WritePart(binaryOperatorExpression.Left, toStringForLeft, leftResolverResult);

                if (charToString == 0)
                {
                    this.Write(")");
                }

                this.WriteComma();
            }
            else if (!delegateOperator && (!isStringConcat || isSimpleConcat))
            {
                this.WriteSpace();
            }

            if (charToString == 1)
            {
                this.Write(JS.Funcs.STRING_FROMCHARCODE + "(");
            }

            this.WritePart(binaryOperatorExpression.Right, toStringForRight, rightResolverResult);

            if (toBool)
            {
                this.WriteCloseParentheses();
            }

            if (charToString == 1 || isCoalescing)
            {
                this.WriteCloseParentheses();
            }

            if (delegateOperator || special || isStringConcat && !parentIsString && !isSimpleConcat)
            {
                this.WriteCloseParentheses();
            }
        }
        public void ParseOrAndExpressionTest2()
        {
            Action <string> testExpression = delegate(string condition)
            {
                IConditionExpression expression = ConditionExpressionParser.Instance.Parse(
                    condition);
                Assert.IsNotNull(expression, "Expected an expression instance.");

                BinaryOperatorExpression operatorExpression = expression as BinaryOperatorExpression;
                Assert.IsNotNull(operatorExpression, "Expected an operator expression.");
                Assert.AreEqual(BinaryExpressionOperator.Or, operatorExpression.Operator, "Unexpected operator.");

                //
                // Or left
                //
                BinaryOperatorExpression testExpression1 = operatorExpression.Left as BinaryOperatorExpression;
                Assert.IsNotNull(testExpression1, "Expected an operator expression.");
                Assert.AreEqual(BinaryExpressionOperator.Equal, testExpression1.Operator, "Unexpected operator.");

                ElementAttributeExpression test1AttributeExpression = testExpression1.Left as ElementAttributeExpression;
                Assert.IsNotNull(test1AttributeExpression, "Unexpected left node type.");
                Assert.AreEqual(ElementAttributeType.Name, test1AttributeExpression.ElementAttribute,
                                "Attribute expression was not parsed correctly.");

                StringExpression test1StringExpression = testExpression1.Right as StringExpression;
                Assert.IsNotNull(test1StringExpression, "Unexpected right node type.");
                Assert.AreEqual("Test 1", test1StringExpression.Text, "String expression was not parsed correctly.");

                //
                // Or right
                //
                BinaryOperatorExpression andExpression = operatorExpression.Right as BinaryOperatorExpression;
                Assert.IsNotNull(andExpression, "Expected an operator expression.");
                Assert.AreEqual(BinaryExpressionOperator.And, andExpression.Operator, "Unexpected operator.");

                //
                // And Left
                //
                BinaryOperatorExpression testExpression2 = andExpression.Left as BinaryOperatorExpression;
                Assert.IsNotNull(testExpression2, "Expected an operator expression.");
                Assert.AreEqual(BinaryExpressionOperator.Equal, testExpression2.Operator, "Unexpected operator.");

                ElementAttributeExpression test2AttributeExpression = testExpression2.Left as ElementAttributeExpression;
                Assert.IsNotNull(test2AttributeExpression, "Unexpected left node type.");
                Assert.AreEqual(ElementAttributeType.Name, test2AttributeExpression.ElementAttribute,
                                "Attribute expression was not parsed correctly.");

                StringExpression test2StringExpression = testExpression2.Right as StringExpression;
                Assert.IsNotNull(test2StringExpression, "Unexpected right node type.");
                Assert.AreEqual("Test 2", test2StringExpression.Text, "String expression was not parsed correctly.");

                //
                // And Right
                //
                BinaryOperatorExpression testExpression3 = andExpression.Right as BinaryOperatorExpression;
                Assert.IsNotNull(testExpression3, "Expected an operator expression.");
                Assert.AreEqual(BinaryExpressionOperator.Equal, testExpression3.Operator, "Unexpected operator.");

                ElementAttributeExpression test3AttributeExpression = testExpression3.Left as ElementAttributeExpression;
                Assert.IsNotNull(test3AttributeExpression, "Unexpected left node type.");
                Assert.AreEqual(ElementAttributeType.Name, test3AttributeExpression.ElementAttribute,
                                "Attribute expression was not parsed correctly.");

                StringExpression test3StringExpression = testExpression3.Right as StringExpression;
                Assert.IsNotNull(test3StringExpression, "Unexpected right node type.");
                Assert.AreEqual("Test 3", test3StringExpression.Text, "String expression was not parsed correctly.");
            };

            string expressionText;

            expressionText = "(($(Name) == 'Test 1') Or (($(Name) == 'Test 2') And ($(Name) == 'Test 3')))";
            testExpression(expressionText);

            expressionText = "$(Name) == 'Test 1' Or $(Name) == 'Test 2' And $(Name) == 'Test 3'";
            testExpression(expressionText);
        }
Beispiel #34
0
        public int Visit(BinaryOperatorExpression expression)
        {
            if (expression.Operation == ScriptTokenType.EqualTo ||
                expression.Operation == ScriptTokenType.NotEqualTo)
            {
                var leftString  = expression.Left as StringExpression;
                var rightString = expression.Right as StringExpression;

                if ((leftString != null && !leftString.IsSingleQuote) || (rightString != null && !rightString.IsSingleQuote))
                {
                    if (expression.Operation == ScriptTokenType.NotEqualTo)
                    {
                        _writer.Write("!");
                    }

                    expression.Left.Accept(this);
                    _writer.Write(".equals(");
                    expression.Right.Accept(this);
                    _writer.Write(")");

                    return(0);
                }
            }

            if (expression.Operation == ScriptTokenType.Assign)
            {
                var leftIndexer = expression.Left as IndexerExpression;
                if (leftIndexer != null)
                {
                    var leftIdentifier = leftIndexer.Left as IdentifierExpression;
                    if (leftIdentifier != null)
                    {
                        var type = GetType(leftIdentifier.Name);
                        if (type != null && type.IsResizable)
                        {
                            _writer.Write(leftIdentifier.Name);
                            _writer.Write(".set(");
                            leftIndexer.Index.Accept(this);
                            _writer.Write(", ");
                            expression.Right.Accept(this);
                            _writer.Write(")");

                            return(0);
                        }
                    }
                }

                var leftIdent  = expression.Left as IdentifierExpression;
                var rightIdent = expression.Right as IdentifierExpression;
                if (expression.Parent == null && leftIdent != null && rightIdent != null)
                {
                    var leftType  = GetType(leftIdent.Name);
                    var rightType = GetType(rightIdent.Name);
                    if (leftType != null && rightType != null)
                    {
                        if (leftType.IsResizable && (rightType.IsArray && !rightType.IsResizable))
                        {
                            // <vector> = <array>

                            var result = ArrayToResizable(rightIdent.Name);
                            _writer.Write("{0} = {1}", leftIdent.Name, result);

                            return(0);
                        }

                        if ((leftType.IsArray && !leftType.IsResizable) && rightType.IsResizable)
                        {
                            // <array> = <vector>

                            var result = ResizableToArray(rightIdent.Name, leftType);
                            _writer.Write("{0} = {1}", leftIdent.Name, result);

                            return(0);
                        }
                    }
                }
            }

            var needParens = expression.Parent != null;

            if (needParens)
            {
                _writer.Write("(");
            }

            expression.Left.Accept(this);
            _writer.Write(" ");
            _writer.Write(BinaryOperatorMap[expression.Operation]);
            _writer.Write(" ");
            expression.Right.Accept(this);

            if (needParens)
            {
                _writer.Write(")");
            }

            return(0);
        }
 /// <inheritdoc/>
 public virtual void VisitBinaryOperatorExpression(BinaryOperatorExpression syntax)
 {
     VisitNode(syntax);
 }
Beispiel #36
0
		bool ExtractExpression (Statement statement, out Expression leftSide, out Expression rightSide) {
			ExpressionStatement expression = statement as ExpressionStatement;
			if (expression != null) {
				AssignmentExpression assignment = expression.Expression as AssignmentExpression;
				if (assignment != null) {
					if (assignment.Operator == AssignmentOperatorType.Add) {
						leftSide = assignment.Left;
						rightSide = assignment.Right;
						return true;
					}
					if (assignment.Operator == AssignmentOperatorType.Subtract) {
						leftSide = assignment.Left;
						rightSide = new UnaryOperatorExpression(UnaryOperatorType.Minus, assignment.Right.Clone());
						return true;
					}

					leftSide = null;
					rightSide = null;
					return false;
				}

				UnaryOperatorExpression unary = expression.Expression as UnaryOperatorExpression;
				if (unary != null) {
					leftSide = unary.Expression;
					if (unary.Operator == UnaryOperatorType.Increment || unary.Operator == UnaryOperatorType.PostIncrement) {
						rightSide = new PrimitiveExpression(1);
						return true;
					} else if (unary.Operator == UnaryOperatorType.Decrement || unary.Operator == UnaryOperatorType.PostDecrement) {
						rightSide = new PrimitiveExpression(-1);
						return true;
					} else {
						leftSide = null;
						rightSide = null;
						return false;
					}
				}
			}

			if (statement is EmptyStatement || statement.IsNull) {
				leftSide = null;
				rightSide = null;
				return true;
			}

			BlockStatement block = statement as BlockStatement;
			if (block != null) {
				leftSide = null;
				rightSide = null;

				foreach (Statement child in block.Statements) {
					Expression newLeft, newRight;
					if (!ExtractExpression(child, out newLeft, out newRight)) {
						leftSide = null;
						rightSide = null;
						return false;
					}

					if (newLeft == null) {
						continue;
					}

					if (leftSide == null) {
						leftSide = newLeft;
						rightSide = newRight;
					} else if (SameNode(leftSide, newLeft)) {
						rightSide = new BinaryOperatorExpression(ParenthesizeIfNeeded(rightSide).Clone(),
						                                         BinaryOperatorType.Add,
						                                         ParenthesizeIfNeeded(newRight).Clone());
					} else {
						return false;
					}
				}

				return true;
			}

			IfElseStatement condition = statement as IfElseStatement;
			if (condition != null) {
				Expression ifLeft, ifRight;
				if (!ExtractExpression(condition.TrueStatement, out ifLeft, out ifRight)) {
					leftSide = null;
					rightSide = null;
					return false;
				}

				Expression elseLeft, elseRight;
				if (!ExtractExpression(condition.FalseStatement, out elseLeft, out elseRight)) {
					leftSide = null;
					rightSide = null;
					return false;
				}

				if (ifLeft == null && elseLeft == null) {
					leftSide = null;
					rightSide = null;
					return true;
				}

				if (ifLeft != null && elseLeft != null && !SameNode(ifLeft, elseLeft)) {
					leftSide = null;
					rightSide = null;
					return false;
				}

				ifRight = ifRight ?? new PrimitiveExpression(0);
				elseRight = elseRight ?? new PrimitiveExpression(0);

				leftSide = ifLeft ?? elseLeft;
				rightSide = new ConditionalExpression(condition.Condition.Clone(), ifRight.Clone(), elseRight.Clone());
				return true;
			}

			leftSide = null;
			rightSide = null;
			return false;
		}
        public override void GenerateCode(List <AbstractNode> nodes, IList items)
        {
            TypeReference     intReference = new TypeReference("System.Int32", true);
            MethodDeclaration method       = new MethodDeclaration {
                Name          = "GetHashCode",
                Modifier      = Modifiers.Public | Modifiers.Override,
                TypeReference = intReference,
                Body          = new BlockStatement()
            };

            VariableDeclaration var;

            var = new VariableDeclaration("hashCode", new PrimitiveExpression(0, "0"), intReference);
            method.Body.AddChild(new LocalVariableDeclaration(var));

            bool           usePrimeMultiplication = currentClass.ProjectContent.Language == LanguageProperties.CSharp;
            BlockStatement hashCalculationBlock;

            if (usePrimeMultiplication)
            {
                hashCalculationBlock = new BlockStatement();
                method.Body.AddChild(new UncheckedStatement(hashCalculationBlock));
            }
            else
            {
                hashCalculationBlock = method.Body;
            }

            int        fieldIndex = 0;
            Expression expr;

            foreach (IField field in currentClass.Fields)
            {
                if (field.IsStatic)
                {
                    continue;
                }

                expr = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression(field.Name), "GetHashCode"));
                if (usePrimeMultiplication)
                {
                    int prime = largePrimes[fieldIndex++ % largePrimes.Length];
                    expr = new AssignmentExpression(
                        new IdentifierExpression(var.Name),
                        AssignmentOperatorType.Add,
                        new BinaryOperatorExpression(new PrimitiveExpression(prime, prime.ToString()),
                                                     BinaryOperatorType.Multiply,
                                                     expr));
                }
                else
                {
                    expr = new AssignmentExpression(new IdentifierExpression(var.Name),
                                                    AssignmentOperatorType.ExclusiveOr,
                                                    expr);
                }
                if (IsValueType(field.ReturnType))
                {
                    hashCalculationBlock.AddChild(new ExpressionStatement(expr));
                }
                else
                {
                    hashCalculationBlock.AddChild(new IfElseStatement(
                                                      new BinaryOperatorExpression(new IdentifierExpression(field.Name),
                                                                                   BinaryOperatorType.ReferenceInequality,
                                                                                   new PrimitiveExpression(null, "null")),
                                                      new ExpressionStatement(expr)
                                                      ));
                }
            }
            method.Body.AddChild(new ReturnStatement(new IdentifierExpression(var.Name)));
            nodes.Add(method);

            TypeReference boolReference   = new TypeReference("System.Boolean", true);
            TypeReference objectReference = new TypeReference("System.Object", true);

            method = new MethodDeclaration {
                Name          = "Equals",
                Modifier      = Modifiers.Public | Modifiers.Override,
                TypeReference = boolReference
            };
            method.Parameters.Add(new ParameterDeclarationExpression(objectReference, "obj"));
            method.Body = new BlockStatement();

            TypeReference currentType = ConvertType(currentClass.DefaultReturnType);

            if (currentClass.ClassType == Dom.ClassType.Struct)
            {
                // return obj is CurrentType && Equals((CurrentType)obj);
                expr = new TypeOfIsExpression(new IdentifierExpression("obj"), currentType);
                expr = new ParenthesizedExpression(expr);
                expr = new BinaryOperatorExpression(
                    expr, BinaryOperatorType.LogicalAnd,
                    new InvocationExpression(
                        new IdentifierExpression("Equals"),
                        new List <Expression> {
                    new CastExpression(currentType, new IdentifierExpression("obj"), CastType.Cast)
                }));
                method.Body.AddChild(new ReturnStatement(expr));

                nodes.Add(method);

                // IEquatable implementation:
                method = new MethodDeclaration {
                    Name          = "Equals",
                    Modifier      = Modifiers.Public | Modifiers.Override,
                    TypeReference = boolReference
                };
                method.Parameters.Add(new ParameterDeclarationExpression(currentType, "other"));
                method.Body = new BlockStatement();
            }
            else
            {
                method.Body.AddChild(new LocalVariableDeclaration(new VariableDeclaration(
                                                                      "other",
                                                                      new CastExpression(currentType, new IdentifierExpression("obj"), CastType.TryCast),
                                                                      currentType)));
                method.Body.AddChild(new IfElseStatement(
                                         new BinaryOperatorExpression(new IdentifierExpression("other"), BinaryOperatorType.ReferenceEquality, new PrimitiveExpression(null, "null")),
                                         new ReturnStatement(new PrimitiveExpression(false, "false"))));

//				expr = new BinaryOperatorExpression(new ThisReferenceExpression(),
//				                                    BinaryOperatorType.ReferenceEquality,
//				                                    new IdentifierExpression("obj"));
//				method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(true, "true"))));
            }


            expr = null;
            foreach (IField field in currentClass.Fields)
            {
                if (field.IsStatic)
                {
                    continue;
                }

                if (expr == null)
                {
                    expr = TestEquality("other", field);
                }
                else
                {
                    expr = new BinaryOperatorExpression(expr, BinaryOperatorType.LogicalAnd,
                                                        TestEquality("other", field));
                }
            }

            method.Body.AddChild(new ReturnStatement(expr ?? new PrimitiveExpression(true, "true")));

            nodes.Add(method);
        }
Beispiel #38
0
        Expression ConvertEnumValue(IType type, long val)
        {
            ITypeDefinition enumDefinition   = type.GetDefinition();
            TypeCode        enumBaseTypeCode = ReflectionHelper.GetTypeCode(enumDefinition.EnumUnderlyingType);

            foreach (IField field in enumDefinition.Fields)
            {
                if (field.IsConst && object.Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false), val))
                {
                    return(ConvertType(type).Member(field.Name));
                }
            }
            if (IsFlagsEnum(enumDefinition))
            {
                long       enumValue        = val;
                Expression expr             = null;
                long       negatedEnumValue = ~val;
                // limit negatedEnumValue to the appropriate range
                switch (enumBaseTypeCode)
                {
                case TypeCode.Byte:
                case TypeCode.SByte:
                    negatedEnumValue &= byte.MaxValue;
                    break;

                case TypeCode.Int16:
                case TypeCode.UInt16:
                    negatedEnumValue &= ushort.MaxValue;
                    break;

                case TypeCode.Int32:
                case TypeCode.UInt32:
                    negatedEnumValue &= uint.MaxValue;
                    break;
                }
                Expression negatedExpr = null;
                foreach (IField field in enumDefinition.Fields.Where(fld => fld.IsConst))
                {
                    long fieldValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false);
                    if (fieldValue == 0)
                    {
                        continue;                               // skip None enum value
                    }
                    if ((fieldValue & enumValue) == fieldValue)
                    {
                        var fieldExpression = ConvertType(type).Member(field.Name);
                        if (expr == null)
                        {
                            expr = fieldExpression;
                        }
                        else
                        {
                            expr = new BinaryOperatorExpression(expr, BinaryOperatorType.BitwiseOr, fieldExpression);
                        }

                        enumValue &= ~fieldValue;
                    }
                    if ((fieldValue & negatedEnumValue) == fieldValue)
                    {
                        var fieldExpression = ConvertType(type).Member(field.Name);
                        if (negatedExpr == null)
                        {
                            negatedExpr = fieldExpression;
                        }
                        else
                        {
                            negatedExpr = new BinaryOperatorExpression(negatedExpr, BinaryOperatorType.BitwiseOr, fieldExpression);
                        }

                        negatedEnumValue &= ~fieldValue;
                    }
                }
                if (enumValue == 0 && expr != null)
                {
                    if (!(negatedEnumValue == 0 && negatedExpr != null && negatedExpr.Descendants.Count() < expr.Descendants.Count()))
                    {
                        return(expr);
                    }
                }
                if (negatedEnumValue == 0 && negatedExpr != null)
                {
                    return(new UnaryOperatorExpression(UnaryOperatorType.BitNot, negatedExpr));
                }
            }
            return(new PrimitiveExpression(CSharpPrimitiveCast.Cast(enumBaseTypeCode, val, false)).CastTo(ConvertType(type)));
        }
            public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
            {
                base.VisitBinaryOperatorExpression(binaryOperatorExpression);

                if (binaryOperatorExpression.Operator != BinaryOperatorType.Equality &&
                    binaryOperatorExpression.Operator != BinaryOperatorType.InEquality)
                {
                    return;
                }

                string floatType = GetFloatType(binaryOperatorExpression.Left, binaryOperatorExpression.Right);


                if (IsNaN(binaryOperatorExpression.Left))
                {
                    AddIsNaNIssue(binaryOperatorExpression, binaryOperatorExpression.Right, floatType);
                }
                else if (IsNaN(binaryOperatorExpression.Right))
                {
                    AddIsNaNIssue(binaryOperatorExpression, binaryOperatorExpression.Left, floatType);
                }
                else if (IsPositiveInfinity(binaryOperatorExpression.Left))
                {
                    AddIsPositiveInfinityIssue(binaryOperatorExpression, binaryOperatorExpression.Right, floatType);
                }
                else if (IsPositiveInfinity(binaryOperatorExpression.Right))
                {
                    AddIsPositiveInfinityIssue(binaryOperatorExpression, binaryOperatorExpression.Left, floatType);
                }
                else if (IsNegativeInfinity(binaryOperatorExpression.Left))
                {
                    AddIsNegativeInfinityIssue(binaryOperatorExpression, binaryOperatorExpression.Right, floatType);
                }
                else if (IsNegativeInfinity(binaryOperatorExpression.Right))
                {
                    AddIsNegativeInfinityIssue(binaryOperatorExpression, binaryOperatorExpression.Left, floatType);
                }
                else if (IsFloatingPoint(binaryOperatorExpression.Left) || IsFloatingPoint(binaryOperatorExpression.Right))
                {
                    if (IsConstantInfinity(binaryOperatorExpression.Left) || IsConstantInfinity(binaryOperatorExpression.Right))
                    {
                        return;
                    }
                    if (IsZero(binaryOperatorExpression.Left))
                    {
                        AddIsZeroIssue(binaryOperatorExpression, binaryOperatorExpression.Right);
                        return;
                    }
                    if (IsZero(binaryOperatorExpression.Right))
                    {
                        AddIsZeroIssue(binaryOperatorExpression, binaryOperatorExpression.Left);
                        return;
                    }
                    AddIssue(
                        binaryOperatorExpression,
                        ctx.TranslateString("Comparison of floating point numbers can be unequal due to the differing precision of the two values."),
                        ctx.TranslateString("Fix floating point number comparing. Compare a difference with epsilon."),
                        script => {
                        // Math.Abs(diff) op EPSILON
                        var builder = ctx.CreateTypeSystemAstBuilder(binaryOperatorExpression);
                        var diff    = new BinaryOperatorExpression(binaryOperatorExpression.Left.Clone(),
                                                                   BinaryOperatorType.Subtract, binaryOperatorExpression.Right.Clone());
                        var abs = builder.ConvertType(new TopLevelTypeName("System", "Math")).Invoke("Abs", diff);
                        var op  = binaryOperatorExpression.Operator == BinaryOperatorType.Equality ?
                                  BinaryOperatorType.LessThan : BinaryOperatorType.GreaterThan;
                        var epsilon = new IdentifierExpression("EPSILON");
                        var compare = new BinaryOperatorExpression(abs, op, epsilon);
                        script.Replace(binaryOperatorExpression, compare);
                        script.Select(epsilon);
                    }
                        );
                }
            }
        public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
        {
            base.VisitInvocationExpression(invocationExpression, data);

            MethodReference methodRef = invocationExpression.Annotation <MethodReference>();

            if (methodRef == null)
            {
                return(null);
            }
            var arguments = invocationExpression.Arguments.ToArray();

            // Reduce "String.Concat(a, b)" to "a + b"
            if (methodRef != null && methodRef.Name == "Concat" && methodRef.DeclaringType.FullName == "System.String" && arguments.Length >= 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                Expression expr = arguments[0];
                for (int i = 1; i < arguments.Length; i++)
                {
                    expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]);
                }
                invocationExpression.ReplaceWith(expr);
                return(null);
            }

            switch (methodRef.FullName)
            {
            case "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)":
                if (arguments.Length == 1)
                {
                    if (typeHandleOnTypeOfPattern.IsMatch(arguments[0]))
                    {
                        invocationExpression.ReplaceWith(((MemberReferenceExpression)arguments[0]).Target);
                        return(null);
                    }
                }
                break;
            }

            BinaryOperatorType?bop = GetBinaryOperatorTypeFromMetadataName(methodRef.Name);

            if (bop != null && arguments.Length == 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                invocationExpression.ReplaceWith(
                    new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).WithAnnotation(methodRef)
                    );
                return(null);
            }
            UnaryOperatorType?uop = GetUnaryOperatorTypeFromMetadataName(methodRef.Name);

            if (uop != null && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    new UnaryOperatorExpression(uop.Value, arguments[0]).WithAnnotation(methodRef)
                    );
                return(null);
            }
            if (methodRef.Name == "op_Explicit" && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    arguments[0].CastTo(AstBuilder.ConvertType(methodRef.ReturnType, methodRef.MethodReturnType))
                    .WithAnnotation(methodRef)
                    );
                return(null);
            }
            if (methodRef.Name == "op_Implicit" && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(arguments[0]);
                return(null);
            }

            return(null);
        }
Beispiel #41
0
 public BinaryOperatorBlock(IEmitter emitter, BinaryOperatorExpression binaryOperatorExpression)
     : base(emitter, binaryOperatorExpression)
 {
     this.Emitter = emitter;
     this.BinaryOperatorExpression = binaryOperatorExpression;
 }
Beispiel #42
0
 public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
 {
     binaryOperatorExpression.Left.Parent  = binaryOperatorExpression;
     binaryOperatorExpression.Right.Parent = binaryOperatorExpression;
     return(base.VisitBinaryOperatorExpression(binaryOperatorExpression, data));
 }
Beispiel #43
0
        bool ExtractExpression(Statement statement, out Expression leftSide, out Expression rightSide)
        {
            ExpressionStatement expression = statement as ExpressionStatement;

            if (expression != null)
            {
                AssignmentExpression assignment = expression.Expression as AssignmentExpression;
                if (assignment != null)
                {
                    if (assignment.Operator == AssignmentOperatorType.Add)
                    {
                        leftSide  = assignment.Left;
                        rightSide = assignment.Right;
                        return(true);
                    }
                    if (assignment.Operator == AssignmentOperatorType.Subtract)
                    {
                        leftSide  = assignment.Left;
                        rightSide = new UnaryOperatorExpression(UnaryOperatorType.Minus, assignment.Right.Clone());
                        return(true);
                    }

                    leftSide  = null;
                    rightSide = null;
                    return(false);
                }

                UnaryOperatorExpression unary = expression.Expression as UnaryOperatorExpression;
                if (unary != null)
                {
                    leftSide = unary.Expression;
                    if (unary.Operator == UnaryOperatorType.Increment || unary.Operator == UnaryOperatorType.PostIncrement)
                    {
                        rightSide = new PrimitiveExpression(1);
                        return(true);
                    }
                    else if (unary.Operator == UnaryOperatorType.Decrement || unary.Operator == UnaryOperatorType.PostDecrement)
                    {
                        rightSide = new PrimitiveExpression(-1);
                        return(true);
                    }
                    else
                    {
                        leftSide  = null;
                        rightSide = null;
                        return(false);
                    }
                }
            }

            if (statement is EmptyStatement || statement.IsNull)
            {
                leftSide  = null;
                rightSide = null;
                return(true);
            }

            BlockStatement block = statement as BlockStatement;

            if (block != null)
            {
                leftSide  = null;
                rightSide = null;

                foreach (Statement child in block.Statements)
                {
                    Expression newLeft, newRight;
                    if (!ExtractExpression(child, out newLeft, out newRight))
                    {
                        leftSide  = null;
                        rightSide = null;
                        return(false);
                    }

                    if (newLeft == null)
                    {
                        continue;
                    }

                    if (leftSide == null)
                    {
                        leftSide  = newLeft;
                        rightSide = newRight;
                    }
                    else if (SameNode(leftSide, newLeft))
                    {
                        rightSide = new BinaryOperatorExpression(ParenthesizeIfNeeded(rightSide).Clone(),
                                                                 BinaryOperatorType.Add,
                                                                 ParenthesizeIfNeeded(newRight).Clone());
                    }
                    else
                    {
                        return(false);
                    }
                }

                return(true);
            }

            IfElseStatement condition = statement as IfElseStatement;

            if (condition != null)
            {
                Expression ifLeft, ifRight;
                if (!ExtractExpression(condition.TrueStatement, out ifLeft, out ifRight))
                {
                    leftSide  = null;
                    rightSide = null;
                    return(false);
                }

                Expression elseLeft, elseRight;
                if (!ExtractExpression(condition.FalseStatement, out elseLeft, out elseRight))
                {
                    leftSide  = null;
                    rightSide = null;
                    return(false);
                }

                if (ifLeft == null && elseLeft == null)
                {
                    leftSide  = null;
                    rightSide = null;
                    return(true);
                }

                if (ifLeft != null && elseLeft != null && !SameNode(ifLeft, elseLeft))
                {
                    leftSide  = null;
                    rightSide = null;
                    return(false);
                }

                ifRight   = ifRight ?? new PrimitiveExpression(0);
                elseRight = elseRight ?? new PrimitiveExpression(0);

                leftSide  = ifLeft ?? elseLeft;
                rightSide = new ConditionalExpression(condition.Condition.Clone(), ifRight.Clone(), elseRight.Clone());
                return(true);
            }

            leftSide  = null;
            rightSide = null;
            return(false);
        }
        public override object Visit(BinaryOperatorExpression expression, object data)
        {
            CodeBinaryOperatorType op = CodeBinaryOperatorType.Add;

            switch (expression.Op)
            {
            case BinaryOperatorType.Add:
                op = CodeBinaryOperatorType.Add;
                break;

            case BinaryOperatorType.BitwiseAnd:
                op = CodeBinaryOperatorType.BitwiseAnd;
                break;

            case BinaryOperatorType.BitwiseOr:
                op = CodeBinaryOperatorType.BitwiseOr;
                break;

            case BinaryOperatorType.LogicalAnd:
                op = CodeBinaryOperatorType.BooleanAnd;
                break;

            case BinaryOperatorType.LogicalOr:
                op = CodeBinaryOperatorType.BooleanOr;
                break;

            case BinaryOperatorType.Divide:
            case BinaryOperatorType.DivideInteger:
                op = CodeBinaryOperatorType.Divide;
                break;

            case BinaryOperatorType.GreaterThan:
                op = CodeBinaryOperatorType.GreaterThan;
                break;

            case BinaryOperatorType.GreaterThanOrEqual:
                op = CodeBinaryOperatorType.GreaterThanOrEqual;
                break;

            case BinaryOperatorType.Equality:
                op = CodeBinaryOperatorType.IdentityEquality;
                break;

            case BinaryOperatorType.InEquality:
                op = CodeBinaryOperatorType.IdentityInequality;
                break;

            case BinaryOperatorType.LessThan:
                op = CodeBinaryOperatorType.LessThan;
                break;

            case BinaryOperatorType.LessThanOrEqual:
                op = CodeBinaryOperatorType.LessThanOrEqual;
                break;

            case BinaryOperatorType.Modulus:
                op = CodeBinaryOperatorType.Modulus;
                break;

            case BinaryOperatorType.Multiply:
                op = CodeBinaryOperatorType.Multiply;
                break;

            case BinaryOperatorType.Subtract:
                op = CodeBinaryOperatorType.Subtract;
                break;

            //case BinaryOperatorType.ValueEquality:
            //	op = CodeBinaryOperatorType.ValueEquality;
            //	break;
            case BinaryOperatorType.ShiftLeft:
            case BinaryOperatorType.ShiftRight:
                // CodeDOM suxx
                op = CodeBinaryOperatorType.Multiply;
                break;

            case BinaryOperatorType.ReferenceEquality:
                op = CodeBinaryOperatorType.IdentityEquality;
                break;

            case BinaryOperatorType.ReferenceInequality:
                op = CodeBinaryOperatorType.IdentityInequality;
                break;

            case BinaryOperatorType.ExclusiveOr:
                // TODO ExclusiveOr
                op = CodeBinaryOperatorType.BitwiseAnd;
                break;
            }
            return(new CodeBinaryOperatorExpression((CodeExpression)expression.Left.AcceptVisitor(this, data),
                                                    op,
                                                    (CodeExpression)expression.Right.AcceptVisitor(this, data)));
        }
Beispiel #45
0
        public override object Visit(BinaryOperatorExpression node)
        {
            switch (node.Operator)
            {
            case BinaryOperatorExpression.Operators.Multiply:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) * Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.Divide:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) / Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.Modulus:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) % Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.Add:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) + Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.Subtract:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) - Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.ShiftLeft:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) << Convert.ToInt32(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.ShiftRight:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) >> Convert.ToInt32(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.LessThan:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) < Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.GreaterThan:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) > Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.LessThanOrEqual:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) <= Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.GreaterThanOrEqual:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) >= Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.Equality:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) == Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.Inequality:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) != Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.BitwiseAnd:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) & Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.ExclusiveOr:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) ^ Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.BitwiseOr:
                return(Convert.ToInt64(node.Left.AcceptVisitor(this)) | Convert.ToInt64(node.Right.AcceptVisitor(this)));

            case BinaryOperatorExpression.Operators.LogicalAnd:
                return((Convert.ToInt64(node.Left.AcceptVisitor(this)) & Convert.ToInt64(node.Right.AcceptVisitor(this))) == 0 ? 0L : 1L);

            case BinaryOperatorExpression.Operators.LogicalOr:
                return((Convert.ToInt64(node.Left.AcceptVisitor(this)) | Convert.ToInt64(node.Right.AcceptVisitor(this))) == 0 ? 0L : 1L);

            case BinaryOperatorExpression.Operators.Invalid:
            default:
                break;
            }

            return(null);
        }
 public RestoreOriginalAssignOperatorAnnotation(BinaryOperatorExpression binaryOperatorExpression)
 {
     this.binaryOperatorExpression = binaryOperatorExpression;
 }
Beispiel #47
0
        Expression ConvertBinaryOperator(InvocationExpression invocation, BinaryOperatorType op, bool?isChecked = null)
        {
            if (invocation.Arguments.Count < 2)
            {
                return(NotSupported(invocation));
            }

            Expression left = Convert(invocation.Arguments.ElementAt(0));

            if (left == null)
            {
                return(null);
            }
            Expression right = Convert(invocation.Arguments.ElementAt(1));

            if (right == null)
            {
                return(null);
            }

            BinaryOperatorExpression boe = new BinaryOperatorExpression(left, op, right);

            if (isChecked != null)
            {
                boe.AddAnnotation(isChecked.Value ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);
            }

            switch (invocation.Arguments.Count)
            {
            case 2:
                return(boe);

            case 3:
                Match m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(2));
                if (m.Success)
                {
                    return(boe.WithAnnotation(m.Get <AstNode>("method").Single().Annotation <IMethod>()));
                }
                else
                {
                    return(null);
                }

            case 4:
                if (!trueOrFalse.IsMatch(invocation.Arguments.ElementAt(2)))
                {
                    return(null);
                }
                m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(3));
                if (m.Success)
                {
                    return(boe.WithAnnotation(m.Get <AstNode>("method").Single().Annotation <IMethod>()));
                }
                else
                {
                    return(null);
                }

            default:
                return(NotSupported(invocation));
            }
        }
        internal static void ProcessInvocationExpression(InvocationExpression invocationExpression)
        {
            MethodReference methodRef = invocationExpression.Annotation <MethodReference>();

            if (methodRef == null)
            {
                return;
            }
            var arguments = invocationExpression.Arguments.ToArray();

            // Reduce "String.Concat(a, b)" to "a + b"
            if (methodRef.Name == "Concat" && methodRef.DeclaringType.FullName == "System.String" && arguments.Length >= 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                Expression expr = arguments[0];
                for (int i = 1; i < arguments.Length; i++)
                {
                    expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]);
                }
                invocationExpression.ReplaceWith(expr);
                return;
            }

            switch (methodRef.FullName)
            {
            case "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)":
                if (arguments.Length == 1)
                {
                    if (typeHandleOnTypeOfPattern.IsMatch(arguments[0]))
                    {
                        invocationExpression.ReplaceWith(((MemberReferenceExpression)arguments[0]).Target);
                        return;
                    }
                }
                break;

            case "System.Reflection.FieldInfo System.Reflection.FieldInfo::GetFieldFromHandle(System.RuntimeFieldHandle)":
                if (arguments.Length == 1)
                {
                    MemberReferenceExpression mre = arguments[0] as MemberReferenceExpression;
                    if (mre != null && mre.MemberName == "FieldHandle" && mre.Target.Annotation <LdTokenAnnotation>() != null)
                    {
                        invocationExpression.ReplaceWith(mre.Target);
                        return;
                    }
                }
                break;

            case "System.Reflection.FieldInfo System.Reflection.FieldInfo::GetFieldFromHandle(System.RuntimeFieldHandle,System.RuntimeTypeHandle)":
                if (arguments.Length == 2)
                {
                    MemberReferenceExpression mre1 = arguments[0] as MemberReferenceExpression;
                    MemberReferenceExpression mre2 = arguments[1] as MemberReferenceExpression;
                    if (mre1 != null && mre1.MemberName == "FieldHandle" && mre1.Target.Annotation <LdTokenAnnotation>() != null)
                    {
                        if (mre2 != null && mre2.MemberName == "TypeHandle" && mre2.Target is TypeOfExpression)
                        {
                            Expression     oldArg = ((InvocationExpression)mre1.Target).Arguments.Single();
                            FieldReference field  = oldArg.Annotation <FieldReference>();
                            if (field != null)
                            {
                                AstType declaringType = ((TypeOfExpression)mre2.Target).Type.Detach();
                                oldArg.ReplaceWith(declaringType.Member(field.Name).WithAnnotation(field));
                                invocationExpression.ReplaceWith(mre1.Target);
                                return;
                            }
                        }
                    }
                }
                break;
            }

            BinaryOperatorType?bop = GetBinaryOperatorTypeFromMetadataName(methodRef.Name);

            if (bop != null && arguments.Length == 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                invocationExpression.ReplaceWith(
                    new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).WithAnnotation(methodRef)
                    );
                return;
            }
            UnaryOperatorType?uop = GetUnaryOperatorTypeFromMetadataName(methodRef.Name);

            if (uop != null && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    new UnaryOperatorExpression(uop.Value, arguments[0]).WithAnnotation(methodRef)
                    );
                return;
            }
            if (methodRef.Name == "op_Explicit" && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    arguments[0].CastTo(AstBuilder.ConvertType(methodRef.ReturnType, methodRef.MethodReturnType))
                    .WithAnnotation(methodRef)
                    );
                return;
            }
            if (methodRef.Name == "op_Implicit" && arguments.Length == 1)
            {
                invocationExpression.ReplaceWith(arguments[0]);
                return;
            }
            if (methodRef.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition)
            {
                invocationExpression.ReplaceWith(arguments[0]);
                return;
            }

            return;
        }
Beispiel #49
0
 public override DefiniteAssignmentStatus VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, DefiniteAssignmentStatus data)
 {
     if (binaryOperatorExpression.Operator == BinaryOperatorType.ConditionalAnd)
     {
         // Handle constant left side of && expressions (not in the C# spec, but done by the MS compiler)
         bool?cond = analysis.EvaluateCondition(binaryOperatorExpression.Left);
         if (cond == true)
         {
             return(binaryOperatorExpression.Right.AcceptVisitor(this, data));                        // right operand gets evaluated unconditionally
         }
         else if (cond == false)
         {
             return(data);                        // right operand never gets evaluated
         }
         // C# 4.0 spec: §5.3.3.24 Definite Assignment for && expressions
         DefiniteAssignmentStatus afterLeft = binaryOperatorExpression.Left.AcceptVisitor(this, data);
         DefiniteAssignmentStatus beforeRight;
         if (afterLeft == DefiniteAssignmentStatus.AssignedAfterTrueExpression)
         {
             beforeRight = DefiniteAssignmentStatus.DefinitelyAssigned;
         }
         else if (afterLeft == DefiniteAssignmentStatus.AssignedAfterFalseExpression)
         {
             beforeRight = DefiniteAssignmentStatus.PotentiallyAssigned;
         }
         else
         {
             beforeRight = afterLeft;
         }
         DefiniteAssignmentStatus afterRight = binaryOperatorExpression.Right.AcceptVisitor(this, beforeRight);
         if (afterLeft == DefiniteAssignmentStatus.DefinitelyAssigned)
         {
             return(DefiniteAssignmentStatus.DefinitelyAssigned);
         }
         else if (afterRight == DefiniteAssignmentStatus.DefinitelyAssigned && afterLeft == DefiniteAssignmentStatus.AssignedAfterFalseExpression)
         {
             return(DefiniteAssignmentStatus.DefinitelyAssigned);
         }
         else if (afterRight == DefiniteAssignmentStatus.DefinitelyAssigned || afterRight == DefiniteAssignmentStatus.AssignedAfterTrueExpression)
         {
             return(DefiniteAssignmentStatus.AssignedAfterTrueExpression);
         }
         else if (afterLeft == DefiniteAssignmentStatus.AssignedAfterFalseExpression && afterRight == DefiniteAssignmentStatus.AssignedAfterFalseExpression)
         {
             return(DefiniteAssignmentStatus.AssignedAfterFalseExpression);
         }
         else
         {
             return(DefiniteAssignmentStatus.PotentiallyAssigned);
         }
     }
     else if (binaryOperatorExpression.Operator == BinaryOperatorType.ConditionalOr)
     {
         // C# 4.0 spec: §5.3.3.25 Definite Assignment for || expressions
         bool?cond = analysis.EvaluateCondition(binaryOperatorExpression.Left);
         if (cond == false)
         {
             return(binaryOperatorExpression.Right.AcceptVisitor(this, data));                        // right operand gets evaluated unconditionally
         }
         else if (cond == true)
         {
             return(data);                        // right operand never gets evaluated
         }
         DefiniteAssignmentStatus afterLeft = binaryOperatorExpression.Left.AcceptVisitor(this, data);
         DefiniteAssignmentStatus beforeRight;
         if (afterLeft == DefiniteAssignmentStatus.AssignedAfterTrueExpression)
         {
             beforeRight = DefiniteAssignmentStatus.PotentiallyAssigned;
         }
         else if (afterLeft == DefiniteAssignmentStatus.AssignedAfterFalseExpression)
         {
             beforeRight = DefiniteAssignmentStatus.DefinitelyAssigned;
         }
         else
         {
             beforeRight = afterLeft;
         }
         DefiniteAssignmentStatus afterRight = binaryOperatorExpression.Right.AcceptVisitor(this, beforeRight);
         if (afterLeft == DefiniteAssignmentStatus.DefinitelyAssigned)
         {
             return(DefiniteAssignmentStatus.DefinitelyAssigned);
         }
         else if (afterRight == DefiniteAssignmentStatus.DefinitelyAssigned && afterLeft == DefiniteAssignmentStatus.AssignedAfterTrueExpression)
         {
             return(DefiniteAssignmentStatus.DefinitelyAssigned);
         }
         else if (afterRight == DefiniteAssignmentStatus.DefinitelyAssigned || afterRight == DefiniteAssignmentStatus.AssignedAfterFalseExpression)
         {
             return(DefiniteAssignmentStatus.AssignedAfterFalseExpression);
         }
         else if (afterLeft == DefiniteAssignmentStatus.AssignedAfterTrueExpression && afterRight == DefiniteAssignmentStatus.AssignedAfterTrueExpression)
         {
             return(DefiniteAssignmentStatus.AssignedAfterTrueExpression);
         }
         else
         {
             return(DefiniteAssignmentStatus.PotentiallyAssigned);
         }
     }
     else if (binaryOperatorExpression.Operator == BinaryOperatorType.NullCoalescing)
     {
         // C# 4.0 spec: §5.3.3.27 Definite assignment for ?? expressions
         ResolveResult crr = analysis.EvaluateConstant(binaryOperatorExpression.Left);
         if (crr != null && crr.IsCompileTimeConstant && crr.ConstantValue == null)
         {
             return(binaryOperatorExpression.Right.AcceptVisitor(this, data));
         }
         DefiniteAssignmentStatus status = CleanSpecialValues(binaryOperatorExpression.Left.AcceptVisitor(this, data));
         binaryOperatorExpression.Right.AcceptVisitor(this, status);
         return(status);
     }
     else
     {
         // use default logic for other operators
         return(VisitChildren(binaryOperatorExpression, data));
     }
 }
            public override void VisitInvocationExpression(InvocationExpression invocationExpression)
            {
                InvocationExpression outerInvocationExpression = invocationExpression;
                //Note the invocations are in reverse order, so x.Foo().Bar() will have [0] be the Bar() and [1] be the Foo()
                List <InvocationExpression> invocations = new List <InvocationExpression>();
                LinqMethod outerMethod = null;
                Expression target      = null;

                for (;;)
                {
                    var resolveResult = ctx.Resolve(invocationExpression) as MemberResolveResult;
                    if (resolveResult == null || !(resolveResult.Member is IMethod))
                    {
                        break;
                    }

                    var method = LinqMethods.FirstOrDefault(candidate => candidate.FullName == resolveResult.Member.FullName &&
                                                            candidate.ParameterCount == ((IMethod)resolveResult.Member.MemberDefinition).Parameters.Count);
                    if (method == null || (invocations.Any() && method.IsLast))
                    {
                        break;
                    }

                    var mre = invocationExpression.Target as MemberReferenceExpression;
                    if (mre == null)
                    {
                        break;
                    }

                    if (outerMethod == null)
                    {
                        outerMethod = method;
                    }
                    invocations.Add(invocationExpression);

                    target = mre.Target;

                    var newInvocation = target as InvocationExpression;
                    if (newInvocation == null)
                    {
                        break;
                    }

                    invocationExpression = newInvocation;
                }

                if (target == null)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }
                if (!outerMethod.IsPoorStyleAlone && invocations.Count == 1)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                var currentTypeDeclaration   = outerInvocationExpression.GetParent <TypeDeclaration>();
                var currentTypeResolveResult = ctx.Resolve(currentTypeDeclaration) as TypeResolveResult;

                if (currentTypeResolveResult == null)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                var currentTypeDefinition = currentTypeResolveResult.Type.GetDefinition();

                var targetResolveResult = ctx.Resolve(target);

                if (!CanIndex(currentTypeDefinition, targetResolveResult))
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                string countPropertyName = GetCountProperty(currentTypeDefinition, targetResolveResult);

                string lastInvocationName = ((MemberReferenceExpression)invocations[0].Target).MemberName;

                bool endsReversed  = invocations.Count(invocation => ((MemberReferenceExpression)invocation.Target).MemberName == "Reverse") % 2 != 0;
                bool requiresCount = lastInvocationName == "Count" || lastInvocationName == "Any" ||
                                     (endsReversed ? lastInvocationName == "First" || lastInvocationName == "ElementAt" : lastInvocationName == "Last");

                if (countPropertyName == null && requiresCount)
                {
                    base.VisitInvocationExpression(invocationExpression);
                    return;
                }

                AddIssue(new CodeIssue(invocations.Last().LParToken.StartLocation,
                                       invocations.First().RParToken.EndLocation,
                                       ctx.TranslateString("Use of Linq method when there's a better alternative"),
                                       ctx.TranslateString("Replace method by simpler version"),
                                       script => {
                    Expression startOffset = null;
                    Expression endOffset   = null;
                    Expression expression  = null;

                    bool reversed = false;
                    foreach (var invocation in invocations.AsEnumerable().Reverse())
                    {
                        string invocationName = ((MemberReferenceExpression)invocation.Target).MemberName;

                        switch (invocationName)
                        {
                        case "Skip":
                            Expression offset = reversed ? endOffset : startOffset;
                            if (offset == null)
                            {
                                offset = invocation.Arguments.Last().Clone();
                            }
                            else
                            {
                                offset = new BinaryOperatorExpression(offset,
                                                                      BinaryOperatorType.Add,
                                                                      invocation.Arguments.Last().Clone());
                            }

                            if (reversed)
                            {
                                endOffset = offset;
                            }
                            else
                            {
                                startOffset = offset;
                            }

                            break;

                        case "Reverse":
                            reversed = !reversed;
                            break;

                        case "First":
                        case "ElementAt":
                        case "Last":
                            {
                                bool fromEnd          = (invocationName == "Last") ^ reversed;
                                Expression index      = invocationName == "ElementAt" ? invocation.Arguments.Last().Clone() : null;
                                Expression baseOffset = fromEnd ? endOffset : startOffset;
                                //Our indexWithOffset is baseOffset + index
                                //A baseOffset/index of null is considered "0".

                                Expression indexWithOffset = baseOffset == null ? index :
                                                             index == null ? baseOffset :
                                                             new BinaryOperatorExpression(baseOffset, BinaryOperatorType.Add, index);

                                Expression indexerExpression = indexWithOffset;
                                if (fromEnd)
                                {
                                    var endExpression = new BinaryOperatorExpression(new MemberReferenceExpression(target.Clone(), countPropertyName),
                                                                                     BinaryOperatorType.Subtract,
                                                                                     new PrimitiveExpression(1));
                                    if (indexerExpression == null)
                                    {
                                        indexerExpression = endExpression;
                                    }
                                    else
                                    {
                                        indexerExpression = new BinaryOperatorExpression(endExpression,
                                                                                         BinaryOperatorType.Subtract,
                                                                                         new ParenthesizedExpression(indexerExpression));
                                    }
                                }

                                indexerExpression = indexerExpression ?? new PrimitiveExpression(0);

                                var newExpression = new IndexerExpression(target.Clone(),
                                                                          indexerExpression);

                                script.Replace(outerInvocationExpression, newExpression);
                                break;
                            }

                        case "Count":
                        case "Any":
                            {
                                Expression takenMembers;
                                if (startOffset == null)
                                {
                                    takenMembers = endOffset;
                                }
                                else if (endOffset == null)
                                {
                                    takenMembers = startOffset;
                                }
                                else
                                {
                                    takenMembers = new BinaryOperatorExpression(startOffset,
                                                                                BinaryOperatorType.Add,
                                                                                endOffset);
                                }

                                var countExpression = new MemberReferenceExpression(target.Clone(), countPropertyName);

                                Expression newExpression;
                                if (invocationName == "Count")
                                {
                                    if (takenMembers == null)
                                    {
                                        newExpression = countExpression;
                                    }
                                    else
                                    {
                                        newExpression = new BinaryOperatorExpression(countExpression,
                                                                                     BinaryOperatorType.Subtract,
                                                                                     new ParenthesizedExpression(takenMembers));
                                    }
                                }
                                else
                                {
                                    newExpression = new BinaryOperatorExpression(countExpression,
                                                                                 BinaryOperatorType.GreaterThan,
                                                                                 new ParenthesizedExpression(takenMembers));
                                }

                                script.Replace(outerInvocationExpression, newExpression);
                                break;
                            }
                        }
                    }
                }));

                base.VisitInvocationExpression(invocationExpression);
            }
 public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
 {
     Check(binaryOperatorExpression.Left);
     Check(binaryOperatorExpression.Right);
 }
            protected override IEnumerable <string> GenerateCode(List <object> includedMembers)
            {
                // Genereate Equals
                var methodDeclaration = new MethodDeclaration();

                methodDeclaration.Name = "Equals";

                methodDeclaration.ReturnType = new PrimitiveType("bool");
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();
                methodDeclaration.Parameters.Add(new ParameterDeclaration(new PrimitiveType("object"), "obj"));
                var             paramId     = new IdentifierExpression("obj");
                IfElseStatement ifStatement = new IfElseStatement();

                ifStatement.Condition     = new BinaryOperatorExpression(paramId, BinaryOperatorType.Equality, new PrimitiveExpression(null));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement = new IfElseStatement();
                var arguments = new List <Expression> ();

                arguments.Add(new ThisReferenceExpression());
                arguments.Add(paramId.Clone());
                ifStatement.Condition     = new InvocationExpression(new IdentifierExpression("ReferenceEquals"), arguments);
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(true));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement               = new IfElseStatement();
                ifStatement.Condition     = new BinaryOperatorExpression(new InvocationExpression(new MemberReferenceExpression(paramId.Clone(), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression(new SimpleType(Options.EnclosingType.Name)));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                var varType = new SimpleType(Options.EnclosingType.Name);
                var varDecl = new VariableDeclarationStatement(varType, "other", new CastExpression(varType.Clone(), paramId.Clone()));

                methodDeclaration.Body.Statements.Add(varDecl);

                var        otherId = new IdentifierExpression("other");
                Expression binOp   = null;

                foreach (IMember member in includedMembers)
                {
                    Expression right = new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression(otherId.Clone(), member.Name));
                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ConditionalAnd, right);
                    }
                }

                methodDeclaration.Body.Statements.Add(new ReturnStatement(binOp));
                yield return(methodDeclaration.GetText(Options.FormattingOptions));

                methodDeclaration      = new MethodDeclaration();
                methodDeclaration.Name = "GetHashCode";

                methodDeclaration.ReturnType = new PrimitiveType("int");
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();

                binOp = null;
                foreach (IMember member in includedMembers)
                {
                    Expression right;
                    right = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression(member.Name), "GetHashCode"));

                    IType type = member.ReturnType;
                    if (type != null && type.Kind != TypeKind.Struct && type.Kind != TypeKind.Enum)
                    {
                        right = new ParenthesizedExpression(new ConditionalExpression(new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression(null)), right, new PrimitiveExpression(0)));
                    }

                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ExclusiveOr, right);
                    }
                }
                var uncheckedBlock = new BlockStatement();

                uncheckedBlock.Statements.Add(new ReturnStatement(binOp));

                methodDeclaration.Body.Statements.Add(new UncheckedStatement(uncheckedBlock));
                yield return(methodDeclaration.GetText(Options.FormattingOptions));
            }
Beispiel #53
0
 public void RaiseIfRightIsNull()
 {
     BinaryExpression expression = new BinaryOperatorExpression(new ConstantExpression(3), null, BinaryOperator.Divide);
 }
Beispiel #54
0
        protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit();
                    return(true);
                }
                else if (!this.Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition))
                {
                    bool   addClose             = false;
                    string leftInterfaceTempVar = null;

                    if (orr.OperatorType == ExpressionType.OrElse || orr.OperatorType == ExpressionType.AndAlso)
                    {
                        var  orElse         = orr.OperatorType == ExpressionType.OrElse;
                        var  left           = orr.Operands[0];
                        var  memberTargetrr = left as MemberResolveResult;
                        bool isField        = memberTargetrr != null && memberTargetrr.Member is IField &&
                                              (memberTargetrr.TargetResult is ThisResolveResult ||
                                               memberTargetrr.TargetResult is LocalResolveResult);

                        if (!(left is ThisResolveResult || left is TypeResolveResult || left is LocalResolveResult || left is ConstantResolveResult || isField))
                        {
                            this.WriteOpenParentheses();

                            leftInterfaceTempVar = this.GetTempVarName();
                            this.Write(leftInterfaceTempVar);
                            this.Write(" = ");

                            binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);

                            this.WriteComma();

                            addClose = true;
                        }

                        var m = FindOperatorTrueOrFalse(left.Type, orElse);

                        this.Write(BridgeTypes.ToJsName(m.DeclaringType, this.Emitter));
                        this.WriteDot();
                        this.Write(OverloadsCollection.Create(this.Emitter, m).GetOverloadName());

                        this.WriteOpenParentheses();

                        if (leftInterfaceTempVar != null)
                        {
                            this.Write(leftInterfaceTempVar);
                        }
                        else
                        {
                            binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                        }

                        this.WriteCloseParentheses();

                        this.Write(" ? ");

                        if (leftInterfaceTempVar != null)
                        {
                            this.Write(leftInterfaceTempVar);
                        }
                        else
                        {
                            binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                        }

                        this.Write(" : ");
                    }

                    if (orr.IsLiftedOperator)
                    {
                        this.Write(JS.Types.SYSTEM_NULLABLE + ".");

                        string action = JS.Funcs.Math.LIFT;

                        switch (this.BinaryOperatorExpression.Operator)
                        {
                        case BinaryOperatorType.GreaterThan:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;

                        case BinaryOperatorType.GreaterThanOrEqual:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;

                        case BinaryOperatorType.Equality:
                            action = JS.Funcs.Math.LIFTEQ;
                            break;

                        case BinaryOperatorType.InEquality:
                            action = JS.Funcs.Math.LIFTNE;
                            break;

                        case BinaryOperatorType.LessThan:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;

                        case BinaryOperatorType.LessThanOrEqual:
                            action = JS.Funcs.Math.LIFTCMP;
                            break;
                        }

                        this.Write(action + "(");
                    }

                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    if (orr.IsLiftedOperator)
                    {
                        this.WriteComma();
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    if (leftInterfaceTempVar != null)
                    {
                        this.Write(leftInterfaceTempVar);
                        this.Write(", ");
                        binaryOperatorExpression.Right.AcceptVisitor(this.Emitter);
                    }
                    else
                    {
                        new ExpressionListBlock(this.Emitter,
                                                new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }, null, null, 0).Emit();
                    }

                    this.WriteCloseParentheses();

                    if (addClose)
                    {
                        this.WriteCloseParentheses();
                    }

                    return(true);
                }
            }

            return(false);
        }
Beispiel #55
0
        protected void VisitBinaryOperatorExpression()
        {
            BinaryOperatorExpression binaryOperatorExpression = this.BinaryOperatorExpression;
            var  resolveOperator       = this.Emitter.Resolver.ResolveNode(binaryOperatorExpression, this.Emitter);
            var  expectedType          = this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression);
            bool isDecimalExpected     = Helpers.IsDecimalType(expectedType, this.Emitter.Resolver);
            bool isDecimal             = Helpers.IsDecimalType(resolveOperator.Type, this.Emitter.Resolver);
            bool isLongExpected        = Helpers.Is64Type(expectedType, this.Emitter.Resolver);
            bool isLong                = Helpers.Is64Type(resolveOperator.Type, this.Emitter.Resolver);
            OperatorResolveResult orr  = resolveOperator as OperatorResolveResult;
            var    leftResolverResult  = this.Emitter.Resolver.ResolveNode(binaryOperatorExpression.Left, this.Emitter);
            var    rightResolverResult = this.Emitter.Resolver.ResolveNode(binaryOperatorExpression.Right, this.Emitter);
            var    charToString        = -1;
            string variable            = null;
            bool   leftIsNull          = this.BinaryOperatorExpression.Left is NullReferenceExpression;
            bool   rightIsNull         = this.BinaryOperatorExpression.Right is NullReferenceExpression;
            bool   isUint              = resolveOperator.Type.IsKnownType(KnownTypeCode.UInt16) ||
                                         resolveOperator.Type.IsKnownType(KnownTypeCode.UInt32) ||
                                         resolveOperator.Type.IsKnownType(KnownTypeCode.UInt64);

            if ((leftIsNull || rightIsNull) && (binaryOperatorExpression.Operator == BinaryOperatorType.Equality || binaryOperatorExpression.Operator == BinaryOperatorType.InEquality))
            {
                if (binaryOperatorExpression.Operator == BinaryOperatorType.Equality)
                {
                    this.Write("!");
                }

                this.Write("Bridge.hasValue");

                this.WriteOpenParentheses();

                if (leftIsNull)
                {
                    binaryOperatorExpression.Right.AcceptVisitor(this.Emitter);
                }
                else
                {
                    binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                }

                this.WriteCloseParentheses();
                return;
            }

            if (orr != null && orr.Type.IsKnownType(KnownTypeCode.String))
            {
                for (int i = 0; i < orr.Operands.Count; i++)
                {
                    var crr = orr.Operands[i] as ConversionResolveResult;
                    if (crr != null && crr.Input.Type.IsKnownType(KnownTypeCode.Char))
                    {
                        charToString = i;
                    }
                }
            }

            if (resolveOperator is ConstantResolveResult)
            {
                this.WriteScript(((ConstantResolveResult)resolveOperator).ConstantValue);
                return;
            }

            if (!((expectedType.IsKnownType(KnownTypeCode.String) || resolveOperator.Type.IsKnownType(KnownTypeCode.String)) && binaryOperatorExpression.Operator == BinaryOperatorType.Add) && (Helpers.IsDecimalType(leftResolverResult.Type, this.Emitter.Resolver) || Helpers.IsDecimalType(rightResolverResult.Type, this.Emitter.Resolver)))
            {
                isDecimal         = true;
                isDecimalExpected = true;
            }

            if (isDecimal && isDecimalExpected && binaryOperatorExpression.Operator != BinaryOperatorType.NullCoalescing)
            {
                this.HandleDecimal(resolveOperator);
                return;
            }

            var isFloatResult = Helpers.IsFloatType(resolveOperator.Type, this.Emitter.Resolver);
            var leftExpected  = this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Left);
            var rightExpected = this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Right);
            var isLeftLong    = Helpers.Is64Type(leftExpected, this.Emitter.Resolver);
            var isRightLong   = Helpers.Is64Type(rightExpected, this.Emitter.Resolver);

            if (!((expectedType.IsKnownType(KnownTypeCode.String) || resolveOperator.Type.IsKnownType(KnownTypeCode.String)) && binaryOperatorExpression.Operator == BinaryOperatorType.Add) && (isLeftLong || isRightLong))
            {
                isLong         = true;
                isLongExpected = true;
            }

            if (isLong && isLongExpected && binaryOperatorExpression.Operator != BinaryOperatorType.NullCoalescing)
            {
                if (!isFloatResult || binaryOperatorExpression.Operator == BinaryOperatorType.Divide && isLeftLong)
                {
                    this.HandleLong(resolveOperator, isUint);
                    return;
                }
            }

            var delegateOperator = false;

            if (this.ResolveOperator(binaryOperatorExpression, orr))
            {
                return;
            }

            if (binaryOperatorExpression.Operator == BinaryOperatorType.Divide &&
                !(this.Emitter.IsJavaScriptOverflowMode && !ConversionBlock.InsideOverflowContext(this.Emitter, binaryOperatorExpression)) &&
                (
                    (Helpers.IsIntegerType(leftResolverResult.Type, this.Emitter.Resolver) &&
                     Helpers.IsIntegerType(rightResolverResult.Type, this.Emitter.Resolver)) ||

                    (Helpers.IsIntegerType(this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Left), this.Emitter.Resolver) &&
                     Helpers.IsIntegerType(this.Emitter.Resolver.Resolver.GetExpectedType(binaryOperatorExpression.Right), this.Emitter.Resolver))
                ))
            {
                this.Write("Bridge.Int.div(");
                binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);
                this.Write(", ");
                binaryOperatorExpression.Right.AcceptVisitor(this.Emitter);
                this.Write(")");
                return;
            }

            if (binaryOperatorExpression.Operator == BinaryOperatorType.Add ||
                binaryOperatorExpression.Operator == BinaryOperatorType.Subtract)
            {
                var add = binaryOperatorExpression.Operator == BinaryOperatorType.Add;

                if (this.Emitter.Validator.IsDelegateOrLambda(leftResolverResult) && this.Emitter.Validator.IsDelegateOrLambda(rightResolverResult))
                {
                    delegateOperator = true;
                    this.Write(Bridge.Translator.Emitter.ROOT + "." + (add ? Bridge.Translator.Emitter.DELEGATE_COMBINE : Bridge.Translator.Emitter.DELEGATE_REMOVE));
                    this.WriteOpenParentheses();
                }
            }

            bool   nullable     = orr != null && orr.IsLiftedOperator;
            bool   isCoalescing = binaryOperatorExpression.Operator == BinaryOperatorType.NullCoalescing;
            string root         = Bridge.Translator.Emitter.ROOT + ".Nullable.";
            bool   special      = nullable;
            bool   rootSpecial  = nullable;
            bool   isBool       = NullableType.IsNullable(resolveOperator.Type) ? NullableType.GetUnderlyingType(resolveOperator.Type).IsKnownType(KnownTypeCode.Boolean) : resolveOperator.Type.IsKnownType(KnownTypeCode.Boolean);
            bool   toBool       = isBool && !rootSpecial && !delegateOperator && (binaryOperatorExpression.Operator == BinaryOperatorType.BitwiseAnd || binaryOperatorExpression.Operator == BinaryOperatorType.BitwiseOr);

            if (rootSpecial)
            {
                this.Write(root);
            }
            else
            {
                if (isCoalescing)
                {
                    this.Write("(");
                    variable = this.GetTempVarName();
                    this.Write(variable);
                    this.Write(" = ");
                }
                else if (charToString == 0)
                {
                    this.Write("String.fromCharCode(");
                }

                if (toBool)
                {
                    this.Write("!!(");
                }

                binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);

                if (isCoalescing)
                {
                    this.Write(", Bridge.hasValue(");
                    this.Write(variable);
                    this.Write(") ? ");
                    this.Write(variable);
                }
                else if (charToString == 0)
                {
                    this.Write(")");
                }
            }

            if (!delegateOperator)
            {
                if (!special)
                {
                    this.WriteSpace();
                }

                switch (binaryOperatorExpression.Operator)
                {
                case BinaryOperatorType.Add:
                    this.Write(rootSpecial ? "add" : "+");
                    break;

                case BinaryOperatorType.BitwiseAnd:
                    if (isBool)
                    {
                        this.Write(rootSpecial ? "and" : "&");
                    }
                    else
                    {
                        this.Write(rootSpecial ? "band" : "&");
                    }

                    break;

                case BinaryOperatorType.BitwiseOr:
                    if (isBool)
                    {
                        this.Write(rootSpecial ? "or" : "|");
                    }
                    else
                    {
                        this.Write(rootSpecial ? "bor" : "|");
                    }
                    break;

                case BinaryOperatorType.ConditionalAnd:
                    this.Write(rootSpecial ? "and" : "&&");
                    break;

                case BinaryOperatorType.NullCoalescing:
                    this.Write(":");
                    break;

                case BinaryOperatorType.ConditionalOr:
                    this.Write(rootSpecial ? "or" : "||");
                    break;

                case BinaryOperatorType.Divide:
                    this.Write(rootSpecial ? "div" : "/");
                    break;

                case BinaryOperatorType.Equality:
                    this.Write(rootSpecial ? "eq" : "===");
                    break;

                case BinaryOperatorType.ExclusiveOr:
                    this.Write(rootSpecial ? "xor" : "^");
                    break;

                case BinaryOperatorType.GreaterThan:
                    this.Write(rootSpecial ? "gt" : ">");
                    break;

                case BinaryOperatorType.GreaterThanOrEqual:
                    this.Write(rootSpecial ? "gte" : ">=");
                    break;

                case BinaryOperatorType.InEquality:
                    this.Write(rootSpecial ? "neq" : "!==");
                    break;

                case BinaryOperatorType.LessThan:
                    this.Write(rootSpecial ? "lt" : "<");
                    break;

                case BinaryOperatorType.LessThanOrEqual:
                    this.Write(rootSpecial ? "lte" : "<=");
                    break;

                case BinaryOperatorType.Modulus:
                    this.Write(rootSpecial ? "mod" : "%");
                    break;

                case BinaryOperatorType.Multiply:
                    this.Write(rootSpecial ? "mul" : "*");
                    break;

                case BinaryOperatorType.ShiftLeft:
                    this.Write(rootSpecial ? "sl" : "<<");
                    break;

                case BinaryOperatorType.ShiftRight:
                    if (isUint)
                    {
                        this.Write(rootSpecial ? "srr" : ">>>");
                    }
                    else
                    {
                        this.Write(rootSpecial ? "sr" : ">>");
                    }

                    break;

                case BinaryOperatorType.Subtract:
                    this.Write(rootSpecial ? "sub" : "-");
                    break;

                default:
                    throw new EmitterException(binaryOperatorExpression, "Unsupported binary operator: " + binaryOperatorExpression.Operator.ToString());
                }
            }
            else
            {
                this.WriteComma();
            }

            if (special)
            {
                this.WriteOpenParentheses();
                if (charToString == 0)
                {
                    this.Write("String.fromCharCode(");
                }

                binaryOperatorExpression.Left.AcceptVisitor(this.Emitter);

                if (charToString == 0)
                {
                    this.Write(")");
                }

                this.WriteComma();
            }
            else
            {
                this.WriteSpace();
            }

            if (charToString == 1)
            {
                this.Write("String.fromCharCode(");
            }

            binaryOperatorExpression.Right.AcceptVisitor(this.Emitter);

            if (toBool)
            {
                this.WriteCloseParentheses();
            }

            if (charToString == 1 || isCoalescing)
            {
                this.WriteCloseParentheses();
            }

            if (delegateOperator || special)
            {
                this.WriteCloseParentheses();
            }
        }
        void ConvertForStatement(ForStatement forStatement)
        {
            //   ForStatement -> ForNextStatement when for-loop is simple

            // only the following forms of the for-statement are allowed:
            // for (TypeReference name = start; name < oneAfterEnd; name += step)
            // for (name = start; name < oneAfterEnd; name += step)
            // for (TypeReference name = start; name <= end; name += step)
            // for (name = start; name <= end; name += step)
            // for (TypeReference name = start; name > oneAfterEnd; name -= step)
            // for (name = start; name > oneAfterEnd; name -= step)
            // for (TypeReference name = start; name >= end; name -= step)
            // for (name = start; name >= end; name -= step)

            // check if the form is valid and collect TypeReference, name, start, end and step
            if (forStatement.Initializers.Count != 1)
            {
                return;
            }
            if (forStatement.Iterator.Count != 1)
            {
                return;
            }
            ExpressionStatement statement = forStatement.Iterator[0] as ExpressionStatement;

            if (statement == null)
            {
                return;
            }
            AssignmentExpression iterator = statement.Expression as AssignmentExpression;

            if (iterator == null || (iterator.Op != AssignmentOperatorType.Add && iterator.Op != AssignmentOperatorType.Subtract))
            {
                return;
            }
            IdentifierExpression iteratorIdentifier = iterator.Left as IdentifierExpression;

            if (iteratorIdentifier == null)
            {
                return;
            }
            PrimitiveExpression stepExpression = iterator.Right as PrimitiveExpression;

            if (stepExpression == null || !(stepExpression.Value is int))
            {
                return;
            }
            int step = (int)stepExpression.Value;

            if (iterator.Op == AssignmentOperatorType.Subtract)
            {
                step = -step;
            }

            BinaryOperatorExpression condition = forStatement.Condition as BinaryOperatorExpression;

            if (condition == null || !(condition.Left is IdentifierExpression))
            {
                return;
            }
            if ((condition.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier)
            {
                return;
            }
            Expression end;

            if (iterator.Op == AssignmentOperatorType.Subtract)
            {
                if (condition.Op == BinaryOperatorType.GreaterThanOrEqual)
                {
                    end = condition.Right;
                }
                else if (condition.Op == BinaryOperatorType.GreaterThan)
                {
                    end = Expression.AddInteger(condition.Right, 1);
                }
                else
                {
                    return;
                }
            }
            else
            {
                if (condition.Op == BinaryOperatorType.LessThanOrEqual)
                {
                    end = condition.Right;
                }
                else if (condition.Op == BinaryOperatorType.LessThan)
                {
                    end = Expression.AddInteger(condition.Right, -1);
                }
                else
                {
                    return;
                }
            }

            Expression               start;
            TypeReference            typeReference = null;
            LocalVariableDeclaration varDecl       = forStatement.Initializers[0] as LocalVariableDeclaration;

            if (varDecl != null)
            {
                if (varDecl.Variables.Count != 1 ||
                    varDecl.Variables[0].Name != iteratorIdentifier.Identifier ||
                    varDecl.Variables[0].Initializer == null)
                {
                    return;
                }
                typeReference = varDecl.GetTypeForVariable(0);
                start         = varDecl.Variables[0].Initializer;
            }
            else
            {
                statement = forStatement.Initializers[0] as ExpressionStatement;
                if (statement == null)
                {
                    return;
                }
                AssignmentExpression assign = statement.Expression as AssignmentExpression;
                if (assign == null || assign.Op != AssignmentOperatorType.Assign)
                {
                    return;
                }
                if (!(assign.Left is IdentifierExpression))
                {
                    return;
                }
                if ((assign.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier)
                {
                    return;
                }
                start = assign.Right;
            }

            ReplaceCurrentNode(new ForNextStatement(typeReference, iteratorIdentifier.Identifier,
                                                    start, end,
                                                    (step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)),
                                                    forStatement.EmbeddedStatement, null));
        }
Beispiel #57
0
		public void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
		{
			StartNode(binaryOperatorExpression);
			binaryOperatorExpression.Left.AcceptVisitor(this);
			bool spacePolicy;
			switch (binaryOperatorExpression.Operator) {
				case BinaryOperatorType.BitwiseAnd:
				case BinaryOperatorType.BitwiseOr:
				case BinaryOperatorType.ExclusiveOr:
					spacePolicy = policy.SpaceAroundBitwiseOperator;
					break;
				case BinaryOperatorType.ConditionalAnd:
				case BinaryOperatorType.ConditionalOr:
					spacePolicy = policy.SpaceAroundLogicalOperator;
					break;
				case BinaryOperatorType.GreaterThan:
				case BinaryOperatorType.GreaterThanOrEqual:
				case BinaryOperatorType.LessThanOrEqual:
				case BinaryOperatorType.LessThan:
					spacePolicy = policy.SpaceAroundRelationalOperator;
					break;
				case BinaryOperatorType.Equality:
				case BinaryOperatorType.InEquality:
					spacePolicy = policy.SpaceAroundEqualityOperator;
					break;
				case BinaryOperatorType.Add:
				case BinaryOperatorType.Subtract:
					spacePolicy = policy.SpaceAroundAdditiveOperator;
					break;
				case BinaryOperatorType.Multiply:
				case BinaryOperatorType.Divide:
				case BinaryOperatorType.Modulus:
					spacePolicy = policy.SpaceAroundMultiplicativeOperator;
					break;
				case BinaryOperatorType.ShiftLeft:
				case BinaryOperatorType.ShiftRight:
					spacePolicy = policy.SpaceAroundShiftOperator;
					break;
				case BinaryOperatorType.NullCoalescing:
					spacePolicy = true;
					break;
				default:
					throw new NotSupportedException ("Invalid value for BinaryOperatorType");
			}
			Space(spacePolicy);
			WriteToken(BinaryOperatorExpression.GetOperatorRole(binaryOperatorExpression.Operator));
			Space(spacePolicy);
			binaryOperatorExpression.Right.AcceptVisitor(this);
			EndNode(binaryOperatorExpression);
		}
Beispiel #58
0
        protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr)
        {
            var method = orr != null ? orr.UserDefinedOperatorMethod : null;

            if (method != null)
            {
                var inline = this.Emitter.GetInline(method);

                if (!string.IsNullOrWhiteSpace(inline))
                {
                    new InlineArgumentsBlock(this.Emitter,
                                             new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit();
                    return(true);
                }
                else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition))
                {
                    if (orr.IsLiftedOperator)
                    {
                        this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.");

                        string action = "lift";

                        switch (this.BinaryOperatorExpression.Operator)
                        {
                        case BinaryOperatorType.GreaterThan:
                            action = "liftcmp";
                            break;

                        case BinaryOperatorType.GreaterThanOrEqual:
                            action = "liftcmp";
                            break;

                        case BinaryOperatorType.Equality:
                            action = "lifteq";
                            break;

                        case BinaryOperatorType.InEquality:
                            action = "liftne";
                            break;

                        case BinaryOperatorType.LessThan:
                            action = "liftcmp";
                            break;

                        case BinaryOperatorType.LessThanOrEqual:
                            action = "liftcmp";
                            break;
                        }

                        this.Write(action + "(");
                    }

                    this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter));
                    this.WriteDot();

                    this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName());

                    if (orr.IsLiftedOperator)
                    {
                        this.WriteComma();
                    }
                    else
                    {
                        this.WriteOpenParentheses();
                    }

                    new ExpressionListBlock(this.Emitter,
                                            new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }, null).Emit();
                    this.WriteCloseParentheses();

                    return(true);
                }
            }

            return(false);
        }
Beispiel #59
0
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var loop = GetForeachStatement (context);
			if (loop == null) {
				yield break;
			}

			if (context.GetResolverStateBefore(loop)
			    .LookupSimpleNameOrTypeName("Enumerable", new List<IType>(), NameLookupMode.Type)
			    .Type.FullName != "System.Linq.Enumerable") {

				yield break;
			}

			var outputStatement = GetTransformedAssignmentExpression (context, loop);
			if (outputStatement == null) {
				yield break;
			}

			yield return new CodeAction(context.TranslateString("Convert foreach loop to LINQ expression"), script => {

				var prevSibling = loop.GetPrevSibling(node => node is Statement);

				Expression leftSide = outputStatement.Left;
				Expression rightSide = outputStatement.Right;

				Expression expressionToReplace = GetExpressionToReplace(prevSibling, leftSide);

				if (expressionToReplace != null) {
					Expression replacementExpression = rightSide.Clone();
					if (!IsZeroPrimitive(expressionToReplace)) {
						replacementExpression = new BinaryOperatorExpression(ParenthesizeIfNeeded(expressionToReplace).Clone(),
						                                                     BinaryOperatorType.Add,
						                                                     replacementExpression);
					}

					script.Replace(expressionToReplace, replacementExpression);
					script.Remove(loop);
				}
				else {
					script.Replace(loop, new ExpressionStatement(outputStatement));
				}

			}, loop);
		}
Beispiel #60
0
 public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
 {
     HandleExpressionNode(binaryOperatorExpression);
 }