ResolveBinaryOperator() public method

public ResolveBinaryOperator ( BinaryOperatorType op, ResolveResult lhs, ResolveResult rhs ) : ResolveResult
op BinaryOperatorType
lhs ResolveResult
rhs ResolveResult
return ResolveResult
コード例 #1
0
        public void EnumBitwiseOrWithMissingBaseType()
        {
            var resolver = new CSharpResolver(enumWithMissingBaseType.Compilation);
            var lhs      = new ConstantResolveResult(enumWithMissingBaseType, 1);
            var rhs      = new ConstantResolveResult(enumWithMissingBaseType, 2);
            var rr       = (ConstantResolveResult)resolver.ResolveBinaryOperator(BinaryOperatorType.BitwiseOr, lhs, rhs);

            Assert.AreEqual(enumWithMissingBaseType, rr.Type);
            Assert.AreEqual(3, rr.ConstantValue);
        }
コード例 #2
0
        protected void TestOperator(ResolveResult lhs, BinaryOperatorType op, ResolveResult rhs,
                                    Conversion expectedLeftConversion, Conversion expectedRightConversion, Type expectedResultType)
        {
            var rr = resolver.ResolveBinaryOperator(op, lhs, rhs);

            AssertType(expectedResultType, rr);
            Assert.AreEqual(typeof(BinaryOperatorResolveResult), rr.GetType());
            var borr = (BinaryOperatorResolveResult)rr;

            AssertConversion(borr.Left, lhs, expectedLeftConversion, "Left conversion");
            AssertConversion(borr.Right, rhs, expectedRightConversion, "Right conversion");
        }
コード例 #3
0
        protected void TestOperator(ResolveResult lhs, BinaryOperatorType op, ResolveResult rhs,
                                    Conversion expectedLeftConversion, Conversion expectedRightConversion, Type expectedResultType)
        {
            CSharpResolver resolver = new CSharpResolver(compilation);
            var            rr       = resolver.ResolveBinaryOperator(op, lhs, rhs);

            AssertType(expectedResultType, rr);
            Assert.AreEqual(typeof(OperatorResolveResult), rr.GetType());
            var borr = (OperatorResolveResult)rr;

            AssertConversion(borr.Operands[0], lhs, expectedLeftConversion, "Left conversion");
            AssertConversion(borr.Operands[1], rhs, expectedRightConversion, "Right conversion");
        }
コード例 #4
0
		public void EnumBitwiseOrWithMissingBaseType()
		{
			var resolver = new CSharpResolver(enumWithMissingBaseType.Compilation);
			var lhs = new ConstantResolveResult(enumWithMissingBaseType, 1);
			var rhs = new ConstantResolveResult(enumWithMissingBaseType, 2);
			var rr = (ConstantResolveResult)resolver.ResolveBinaryOperator(BinaryOperatorType.BitwiseOr, lhs, rhs);
			Assert.AreEqual(enumWithMissingBaseType, rr.Type);
			Assert.AreEqual(3, rr.ConstantValue);
		}
コード例 #5
0
        public void Multiplication()
        {
            TestOperator(MakeResult(typeof(int)), BinaryOperatorType.Multiply, MakeResult(typeof(int)),
                         Conversion.IdentityConversion, Conversion.IdentityConversion, typeof(int));

            TestOperator(MakeResult(typeof(int)), BinaryOperatorType.Multiply, MakeConstant(0.0f),
                         Conversion.ImplicitNumericConversion, Conversion.IdentityConversion, typeof(float));

            AssertConstant(3.0f, resolver.ResolveBinaryOperator(
                               BinaryOperatorType.Multiply, MakeConstant(1.5f), MakeConstant(2)));

            AssertConstant(6, resolver.ResolveBinaryOperator(
                               BinaryOperatorType.Multiply, MakeConstant((byte)2), MakeConstant((byte)3)));

            TestOperator(MakeResult(typeof(uint?)), BinaryOperatorType.Multiply, MakeResult(typeof(int?)),
                         Conversion.ImplicitNullableConversion, Conversion.ImplicitNullableConversion, typeof(long?));

            AssertError(typeof(decimal), resolver.ResolveBinaryOperator(
                            BinaryOperatorType.Multiply, MakeResult(typeof(float)), MakeResult(typeof(decimal))));
        }
コード例 #6
0
		public override ResolveResult Resolve(CSharpResolver resolver)
		{
			ResolveResult lhs = left.Resolve(resolver);
			ResolveResult rhs = right.Resolve(resolver);
			return resolver.ResolveBinaryOperator(operatorType, lhs, rhs);
		}
コード例 #7
0
		Value VisitConditionalOperator(OperatorResolveResult result, BinaryOperatorType bitwiseOperatorType)
		{
			Debug.Assert(result.Operands.Count == 2);
			var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem);
			Value condVal;
			if (bitwiseOperatorType == BinaryOperatorType.BitwiseAnd)
				condVal = Convert(resolver.ResolveConditionFalse(lhs.ToResolveResult(context)));
			else
				condVal = Convert(resolver.ResolveCondition(lhs.ToResolveResult(context)));
			if ((bool)condVal.PrimitiveValue)
				return lhs;
			var rhs = Convert(result.Operands[1]);
			var val = resolver.ResolveBinaryOperator(bitwiseOperatorType, lhs.ToResolveResult(context), rhs.ToResolveResult(context));
			return Convert(val);
		}
コード例 #8
0
		Value VisitBinaryOperator(OperatorResolveResult result, BinaryOperatorType operatorType, bool checkForOverflow = false)
		{
			Debug.Assert(result.Operands.Count == 2);
			Debug.Assert(operatorType != BinaryOperatorType.ConditionalAnd && operatorType != BinaryOperatorType.ConditionalOr && operatorType != BinaryOperatorType.NullCoalescing);
			var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread);
			var rhs = Convert(result.Operands[1]).GetPermanentReference(evalThread);
			if (result.UserDefinedOperatorMethod != null)
				return InvokeMethod(null, result.UserDefinedOperatorMethod, lhs, rhs);
			var lhsRR = lhs.ToResolveResult(context);
			var rhsRR = rhs.ToResolveResult(context);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow);
			var val = resolver.ResolveBinaryOperator(operatorType, lhsRR, rhsRR);
			if (val.IsCompileTimeConstant)
				return Convert(val);
			switch (operatorType) {
				case BinaryOperatorType.Equality:
				case BinaryOperatorType.InEquality:
					bool equality = (operatorType == BinaryOperatorType.Equality);
					if (lhsRR.Type.IsKnownType(KnownTypeCode.String) && rhsRR.Type.IsKnownType(KnownTypeCode.String)) {
						if (lhs.IsNull || rhs.IsNull) {
							bool bothNull = lhs.IsNull && rhs.IsNull;
							return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull);
						} else {
							bool equal = (string)lhs.PrimitiveValue == (string)rhs.PrimitiveValue;
							return Eval.CreateValue(evalThread, equality ? equal : !equal);
						}
					}
					if (lhsRR.Type.IsReferenceType != false && rhsRR.Type.IsReferenceType != false) {
						// Reference comparison
						if (lhs.IsNull || rhs.IsNull) {
							bool bothNull = lhs.IsNull && rhs.IsNull;
							return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull);
						} else {
							bool equal = lhs.Address == rhs.Address;
							return Eval.CreateValue(evalThread, equality ? equal : !equal);
						}
					}
					goto default;
				case BinaryOperatorType.Add:
					if (lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String)) {
						var method = debuggerTypeSystem.FindType(KnownTypeCode.String)
							.GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2)
							.Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object)));
						return InvokeMethod(null, method, lhs, rhs);
					}
					goto default;
				default:
					throw new GetValueException("Operator {0} is not supported for {1} and {2}!", operatorType, new CSharpAmbience().ConvertType(lhsRR.Type), new CSharpAmbience().ConvertType(rhsRR.Type));
			}
		}
コード例 #9
0
		Value VisitBinaryOperator(OperatorResolveResult result, BinaryOperatorType operatorType, bool checkForOverflow = false)
		{
			Debug.Assert(result.Operands.Count == 2);
			Debug.Assert(operatorType != BinaryOperatorType.ConditionalAnd && operatorType != BinaryOperatorType.ConditionalOr && operatorType != BinaryOperatorType.NullCoalescing);
			var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread);
			var rhs = Convert(result.Operands[1]).GetPermanentReference(evalThread);
			if (result.UserDefinedOperatorMethod != null)
				return InvokeMethod(null, result.UserDefinedOperatorMethod, lhs, rhs);
			var lhsRR = lhs.ToResolveResult(context);
			var rhsRR = rhs.ToResolveResult(context);
			CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow);
			var val = resolver.ResolveBinaryOperator(operatorType, lhsRR, rhsRR);
			if (val.IsCompileTimeConstant)
				return Convert(val);
			if (operatorType == BinaryOperatorType.Add &&
			    (lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String))) {
				var method = debuggerTypeSystem.FindType(KnownTypeCode.String)
					.GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2)
					.Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object)));
				return InvokeMethod(null, method, lhs, rhs);
			}
			throw new InvalidOperationException();
		}