private TempComputeResult ComputeCustomConditionalLogic(Type type, string methodXName, string methodYName, object leftValue, object rightValue)
        {
            var methodX = DebugService.GetMethod(type, methodXName, BindingFlags.Public | BindingFlags.Static, methodInfo => CheckConditionalOperatorUnaryMethodParameters(type, methodInfo));

            if (methodX == null)
            {
                return(null);
            }
            var methodY = DebugService.GetMethod(type, methodYName, BindingFlags.Public | BindingFlags.Static, methodInfo => CheckConditionalOperatorBinaryMethodParameters(type, methodInfo));

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

            var condition = (bool)methodX.Invoke(null, new object[1] {
                leftValue
            });
            object obj = leftValue;

            if (!condition)
            {
                obj = methodY.Invoke(null, new object[2] {
                    leftValue, rightValue
                });
            }
            return(CreateComputeResult(obj, type));
        }
        private TempComputeResult ResolveVariable(VariableReference variableReference)
        {
            object variableValue;
            var    variableInfo = DebugService.ResolveVariable(Intepreter.GetHashCode(), 0, variableReference, out variableValue);

            HandleResolveVariableError(variableInfo);
            return(CreateComputeResult(variableValue, variableInfo.ValueObjType));
        }
        public override TempComputeResult VisitBinaryExpression(BinaryExpressionSyntax node)
        {
            var left         = Visit(node.Left);
            var right        = Visit(node.Right);
            var operatorText = node.OperatorToken.Text;

            if (left.Type == null && right.Type == null)
            {
                if (operatorText == "==")
                {
                    return(CreateComputeResult(true, typeof(bool)));
                }
                else
                {
                    return(CreateComputeResult(null, null));
                }
            }

            var    leftType  = left.Type;
            var    rightType = right.Type;
            string methodName;

            if (dic_BinaryOperator_MethodName.TryGetValue(operatorText, out methodName))
            {
                var bindingFlags           = BindingFlags.Public | BindingFlags.Static;
                var overloadOperatorMethod = DebugService.GetMethod(leftType, methodName, bindingFlags, true, leftType, rightType);
                if (overloadOperatorMethod == null)
                {
                    overloadOperatorMethod = DebugService.GetMethod(rightType, methodName, bindingFlags, true, leftType, rightType);
                }
                if (overloadOperatorMethod != null) // 有运算符重载
                {
                    var result = overloadOperatorMethod.Invoke(null, new object[2] {
                        left.Value, right.Value
                    });
                    return(CreateComputeResult(result, overloadOperatorMethod.ReturnType));
                }
                else
                {
                    return(ComputeBinaryNative(leftType, rightType, left.Value, right.Value, operatorText, node));
                }
            }
            else
            {
                var result = ComputeCustomConditionalLogicOperator(leftType, rightType, left.Value, right.Value, operatorText); // 用户定义的条件逻辑运算符,规则为https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/language-specification/expressions#conditional-logical-operators
                if (result != null)
                {
                    return(result);
                }
                return(ComputeBinaryNative(leftType, rightType, left.Value, right.Value, operatorText, node));
                //throw new NotSupportedException("Unknown Binary Operator:" + operatorText);
            }
        }
 public BreakpointConditionExpressionVisitor(DebugService debugService, ILIntepreter intp, VariableInfo[] localVariables)
 {
     DebugService = debugService;
     Intepreter   = intp;
     if (localVariables == null)
     {
         LocalVariables = new Dictionary <string, VariableInfo>();
     }
     else
     {
         LocalVariables = localVariables.ToDictionary(i => i.Name);
     }
 }
        public override TempComputeResult VisitThisExpression(ThisExpressionSyntax node)
        {
            VariableReferenceTuple tuple;

            if (dic_Expression_Variable.TryGetValue(node, out tuple))
            {
                return(ResolveVariable(tuple.Bottom));
            }

            ILMethod currentMethod;
            var      v = DebugService.GetThis(Intepreter, 0, out currentMethod);

            return(CreateComputeResult(v, currentMethod.DeclearingType.ReflectionType));
        }
        public override TempComputeResult VisitConditionalExpression(ConditionalExpressionSyntax node)
        {
            var tuple = GetOrCreateVariableReference(node, "");

            tuple.Top.Type = VariableTypes.Value;

            bool conditionValue;
            var  conditionResult = Visit(node.Condition);

            if (conditionResult.Value is bool)
            {
                conditionValue = (bool)conditionResult.Value;
            }
            else
            {
                // true运算符重载
                var overloadTrueMethod = DebugService.GetMethod(conditionResult.Type, "op_True", BindingFlags.Public | BindingFlags.Static, methodInfo => CheckConditionalOperatorUnaryMethodParameters(conditionResult.Type, methodInfo));
                if (overloadTrueMethod != null)
                {
                    conditionValue = (bool)overloadTrueMethod.Invoke(null, new object[1] {
                        conditionResult.Value
                    });
                }
                else
                {
                    throw new InvalidOperationException(string.Format("\"{0}\" is not conditional expression", node.Condition.ToString()));
                }
            }

            TempComputeResult result;

            if (conditionValue)
            {
                result = Visit(node.WhenTrue);
            }
            else
            {
                result = Visit(node.WhenFalse);
            }

            tuple.Top.Value     = result.Value;
            tuple.Top.ValueType = result.Type;

            return(ResolveVariable(tuple.Bottom));
        }
示例#7
0
        public bool CheckCondition(DebugService debugService, ILIntepreter intp, ref StackFrameInfo[] stackFrameInfos, ref string error)
        {
#if ILRUNTIME_ENABLE_ROSYLN
            if (Condition == null || Condition.Style == BreakpointConditionStyle.None)
            {
                return(true);
            }
            if (Condition.ExpressionError)
            {
                error = "the expression is not conditional expression";
                return(true);
            }
            stackFrameInfos = debugService.GetStackFrameInfo(intp);
            try
            {
                debugService.UsingInfosContext = UsingInfos;
                var visitor     = new BreakpointConditionExpressionVisitor(debugService, intp, stackFrameInfos.Length < 1 ? null : stackFrameInfos[0].LocalVariables);
                var finalResult = visitor.Visit(Condition.ExpressionSyntax);
                if (finalResult.Value is bool)
                {
                    return((bool)finalResult.Value);
                }
                else // TODO:处理表达式值不是bool的报错
                {
                    error = "the expression value is not bool";
                }
            }
            catch (Exception ex)
            {
                error = ex.Message;
            }
            finally
            {
                debugService.UsingInfosContext = null;
            }
#endif
            return(true);
        }
        public TempComputeResult VisitUnaryExpression(ExpressionSyntax operand, string operatorText, bool isPrefix, string nodeText)
        {
            var operandResult = Visit(operand);

            if (operandResult.Type == null)
            {
                return(CreateComputeResult(null, null));
            }

            string methodName;

            if (dic_UnaryOperator_MethodName.TryGetValue(operatorText, out methodName))
            {
                var bindingFlags           = BindingFlags.Public | BindingFlags.Static;
                var overloadOperatorMethod = DebugService.GetMethod(operandResult.Type, methodName, bindingFlags, true, operandResult.Type);
                if (overloadOperatorMethod != null) // 有运算符重载
                {
                    var result = overloadOperatorMethod.Invoke(null, new object[1] {
                        operandResult.Value
                    });
                    return(CreateComputeResult(result, overloadOperatorMethod.ReturnType));
                }
            }

            try
            {
                var expressionText = isPrefix ? "{0}x" : "x{0}";
                var func           = new DynamicExpresso.Interpreter().Parse(string.Format(expressionText, operatorText), new DynamicExpresso.Parameter("x", operandResult.Type.UnWrapper()));
                var result         = func.Invoke(operandResult.Value);
                return(CreateComputeResult(result, result == null ? null : result.GetType()));
            }
            catch
            {
                throw new Exception(string.Format("Fail to calculate '{0}'", nodeText));
            }
        }
示例#9
0
 private Socket udpSocket; // 用于广播本地信息(计算机名,进程名,TcpListener监听端口等)的udp socket
 public DebuggerServer(DebugService ds)
 {
     this.ds  = ds;
     bw       = new System.IO.BinaryWriter(sendStream);
     bwForUdp = new System.IO.BinaryWriter(sendStreamForUdp);
 }