public ResolveBinaryOperator ( BinaryOperatorType op, ResolveResult lhs, ResolveResult rhs ) : ResolveResult | ||
op | BinaryOperatorType | |
lhs | ResolveResult | |
rhs | ResolveResult | |
return | ResolveResult |
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); }
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"); }
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"); }
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); }
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)))); }
public override ResolveResult Resolve(CSharpResolver resolver) { ResolveResult lhs = left.Resolve(resolver); ResolveResult rhs = right.Resolve(resolver); return resolver.ResolveBinaryOperator(operatorType, lhs, rhs); }
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); }
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)); } }
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(); }