internal async Task <JToken> TryGetVariableValue(MessageId msg_id, int scope_id, string expression, bool only_search_on_this, CancellationToken token)
        {
            JToken thisValue = null;
            var    context   = GetContext(msg_id);

            if (context.CallStack == null)
            {
                return(null);
            }

            if (TryFindVariableValueInCache(context, expression, only_search_on_this, out JToken obj))
            {
                return(obj);
            }

            var scope     = context.CallStack.FirstOrDefault(s => s.Id == scope_id);
            var live_vars = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset);
            //get_this
            var res = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, live_vars.Select(lv => lv.Index).ToArray()), token);

            var scope_values = res.Value? ["result"]? ["value"]?.Values <JObject> ()?.ToArray();

            thisValue = scope_values?.FirstOrDefault(v => v ["name"]?.Value <string> () == "this");

            if (!only_search_on_this)
            {
                if (thisValue != null && expression == "this")
                {
                    return(thisValue);
                }

                var value = scope_values.SingleOrDefault(sv => sv ["name"]?.Value <string> () == expression);
                if (value != null)
                {
                    return(value);
                }
            }

            //search in scope
            if (thisValue != null)
            {
                if (!DotnetObjectId.TryParse(thisValue ["value"] ["objectId"], out var objectId))
                {
                    return(null);
                }

                res = await SendMonoCommand(msg_id, MonoCommands.GetDetails(objectId), token);

                scope_values = res.Value? ["result"]? ["value"]?.Values <JObject> ().ToArray();
                var foundValue = scope_values.FirstOrDefault(v => v ["name"].Value <string> () == expression);
                if (foundValue != null)
                {
                    foundValue["fromThis"] = true;
                    context.LocalsCache[foundValue ["name"].Value <string> ()] = foundValue;
                    return(foundValue);
                }
            }
            return(null);
        }
Beispiel #2
0
        async Task <Result> GetScopeProperties(MessageId msg_id, int scope_id, CancellationToken token)
        {
            try {
                var ctx   = GetContext(msg_id);
                var scope = ctx.CallStack.FirstOrDefault(s => s.Id == scope_id);
                if (scope == null)
                {
                    return(Result.Err(JObject.FromObject(new { message = $"Could not find scope with id #{scope_id}" })));
                }

                var vars = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset);

                var var_ids = vars.Select(v => v.Index).ToArray();
                var res     = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, var_ids), token);

                //if we fail we just buble that to the IDE (and let it panic over it)
                if (res.IsErr)
                {
                    return(res);
                }

                var values = res.Value? ["result"]? ["value"]?.Values <JObject> ().ToArray();

                if (values == null)
                {
                    return(Result.OkFromObject(new { result = Array.Empty <object> () }));
                }

                var var_list = new List <object> ();
                int i        = 0;
                for (; i < vars.Length && i < values.Length; i++)
                {
                    // For async methods, we get locals with names, unlike non-async methods
                    // and the order may not match the var_ids, so, use the names that they
                    // come with
                    if (values [i]["name"] != null)
                    {
                        continue;
                    }

                    ctx.LocalsCache[vars [i].Name] = values [i];
                    var_list.Add(new { name = vars [i].Name, value = values [i]["value"] });
                }
                for (; i < values.Length; i++)
                {
                    ctx.LocalsCache[values [i]["name"].ToString()] = values [i];
                    var_list.Add(values [i]);
                }

                return(Result.OkFromObject(new { result = var_list }));
            } catch (Exception exception) {
                Log("verbose", $"Error resolving scope properties {exception.Message}");
                return(Result.Exception(exception));
            }
        }
Beispiel #3
0
        async Task <Result> GetScopeProperties(MessageId msg_id, int scope_id, CancellationToken token)
        {
            try {
                var ctx   = GetContext(msg_id);
                var scope = ctx.CallStack.FirstOrDefault(s => s.Id == scope_id);
                if (scope == null)
                {
                    return(Result.Err(JObject.FromObject(new { message = $"Could not find scope with id #{scope_id}" })));
                }

                var var_ids = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset);
                var res     = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, var_ids), token);

                //if we fail we just buble that to the IDE (and let it panic over it)
                if (res.IsErr)
                {
                    return(res);
                }

                var values = res.Value? ["result"]? ["value"]?.Values <JObject> ().ToArray();

                if (values == null || values.Length == 0)
                {
                    return(Result.OkFromObject(new { result = Array.Empty <object> () }));
                }

                foreach (var value in values)
                {
                    ctx.LocalsCache [value ["name"]?.Value <string> ()] = value;
                }

                return(Result.OkFromObject(new { result = values }));
            } catch (Exception exception) {
                Log("verbose", $"Error resolving scope properties {exception.Message}");
                return(Result.Exception(exception));
            }
        }
Beispiel #4
0
        internal async Task <JToken> TryGetVariableValue(MessageId msg_id, int scope_id, string expression, bool only_search_on_this, CancellationToken token)
        {
            JToken thisValue = null;
            var    context   = GetContext(msg_id);

            if (context.CallStack == null)
            {
                return(null);
            }

            if (TryFindVariableValueInCache(context, expression, only_search_on_this, out JToken obj))
            {
                return(obj);
            }

            var scope = context.CallStack.FirstOrDefault(s => s.Id == scope_id);
            var vars  = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset);

            //get_this
            int [] var_ids = { };
            var    res     = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, var_ids), token);

            var values = res.Value? ["result"]? ["value"]?.Values <JObject> ().ToArray();

            thisValue = values.FirstOrDefault(v => v ["name"].Value <string> () == "this");

            if (!only_search_on_this)
            {
                if (thisValue != null && expression == "this")
                {
                    return(thisValue);
                }
                //search in locals
                var var_id = vars.SingleOrDefault(v => v.Name == expression);
                if (var_id != null)
                {
                    res = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, new int [] { var_id.Index }), token);

                    values = res.Value? ["result"]? ["value"]?.Values <JObject> ().ToArray();
                    return(values [0]);
                }
            }

            //search in scope
            if (thisValue != null)
            {
                var objectId = thisValue ["value"] ["objectId"].Value <string> ();
                var parts    = objectId.Split(new char [] { ':' });
                res = await SendMonoCommand(msg_id, MonoCommands.GetObjectProperties(int.Parse(parts [2]), expandValueTypes: false), token);

                values = res.Value? ["result"]? ["value"]?.Values <JObject> ().ToArray();
                var foundValue = values.FirstOrDefault(v => v ["name"].Value <string> () == expression);
                if (foundValue != null)
                {
                    foundValue["fromThis"] = true;
                    context.LocalsCache[foundValue ["name"].Value <string> ()] = foundValue;
                    return(foundValue);
                }
            }
            return(null);
        }
Beispiel #5
0
        async Task GetScopeProperties(MessageId msg_id, int scope_id, CancellationToken token)
        {
            try {
                var scope = GetContext(msg_id).CallStack.FirstOrDefault(s => s.Id == scope_id);
                var vars  = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset);

                var var_ids = vars.Select(v => v.Index).ToArray();
                var res     = await SendMonoCommand(msg_id, MonoCommands.GetScopeVariables(scope.Id, var_ids), token);

                //if we fail we just buble that to the IDE (and let it panic over it)
                if (res.IsErr)
                {
                    SendResponse(msg_id, res, token);
                    return;
                }

                var values = res.Value? ["result"]? ["value"]?.Values <JObject> ().ToArray();

                if (values == null)
                {
                    SendResponse(msg_id, Result.OkFromObject(new { result = Array.Empty <object> () }), token);
                    return;
                }

                var var_list = new List <object> ();
                int i        = 0;
                // Trying to inspect the stack frame for DotNetDispatcher::InvokeSynchronously
                // results in a "Memory access out of bounds", causing 'values' to be null,
                // so skip returning variable values in that case.
                while (i < vars.Length && i < values.Length)
                {
                    var value = values [i] ["value"];
                    if (((string)value ["description"]) == null)
                    {
                        value ["description"] = value ["value"]?.ToString();
                    }

                    var_list.Add(new {
                        name = vars [i].Name,
                        value
                    });
                    i++;
                }
                //Async methods are special in the way that local variables can be lifted to generated class fields
                //value of "this" comes here either
                while (i < values.Length)
                {
                    String name = values [i] ["name"].ToString();

                    if (name.IndexOf(">", StringComparison.Ordinal) > 0)
                    {
                        name = name.Substring(1, name.IndexOf(">", StringComparison.Ordinal) - 1);
                    }

                    var value = values [i + 1] ["value"];
                    if (((string)value ["description"]) == null)
                    {
                        value ["description"] = value ["value"]?.ToString();
                    }

                    var_list.Add(new {
                        name,
                        value
                    });
                    i = i + 2;
                }

                SendResponse(msg_id, Result.OkFromObject(new { result = var_list }), token);
            } catch (Exception exception) {
                Log("verbose", $"Error resolving scope properties {exception.Message}");
                SendResponse(msg_id, Result.Exception(exception), token);
            }
        }