示例#1
0
        // Checks Locals, followed by `this`
        public async Task <JObject> Resolve(string var_name, CancellationToken token)
        {
            if (scopeCache.Locals.Count == 0 && !locals_fetched)
            {
                Result scope_res = await proxy.GetScopeProperties(sessionId, scopeId, token);

                if (scope_res.IsErr)
                {
                    throw new Exception($"BUG: Unable to get properties for scope: {scopeId}. {scope_res}");
                }
                locals_fetched = true;
            }

            if (scopeCache.Locals.TryGetValue(var_name, out JObject obj))
            {
                return(obj["value"]?.Value <JObject>());
            }

            if (scopeCache.MemberReferences.TryGetValue(var_name, out JObject ret))
            {
                return(ret);
            }

            if (varIds == null)
            {
                Frame scope = ctx.CallStack.FirstOrDefault(s => s.Id == scopeId);
                varIds = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset);
            }

            Result res = await proxy.SendMonoCommand(sessionId, MonoCommands.EvaluateMemberAccess(scopeId, var_name, varIds), token);

            if (res.IsOk)
            {
                ret = res.Value?["result"]?["value"]?["value"]?.Value <JObject>();
                scopeCache.MemberReferences[var_name] = ret;
            }
            else
            {
                logger.LogDebug(res.Error.ToString());
            }

            return(ret);
        }
        // Checks Locals, followed by `this`
        public async Task <JObject> Resolve(string varName, CancellationToken token)
        {
            //has method calls
            if (varName.Contains('('))
            {
                return(null);
            }

            string[] parts      = varName.Split(".");
            JObject  rootObject = null;

            if (scopeCache.MemberReferences.TryGetValue(varName, out JObject ret))
            {
                return(ret);
            }

            if (scopeCache.ObjectFields.TryGetValue(varName, out JObject valueRet))
            {
                return(await GetValueFromObject(valueRet, token));
            }

            foreach (string part in parts)
            {
                string partTrimmed = part.Trim();
                if (partTrimmed == "")
                {
                    return(null);
                }
                if (rootObject != null)
                {
                    if (rootObject?["subtype"]?.Value <string>() == "null")
                    {
                        return(null);
                    }
                    if (DotnetObjectId.TryParse(rootObject?["objectId"]?.Value <string>(), out DotnetObjectId objectId))
                    {
                        var rootResObj = await proxy.RuntimeGetPropertiesInternal(sessionId, objectId, null, token);

                        var objRet = rootResObj.FirstOrDefault(objPropAttr => objPropAttr["name"].Value <string>() == partTrimmed);
                        if (objRet == null)
                        {
                            return(null);
                        }

                        rootObject = await GetValueFromObject(objRet, token);
                    }
                    continue;
                }
                if (scopeCache.Locals.Count == 0 && !localsFetched)
                {
                    Result scope_res = await proxy.GetScopeProperties(sessionId, scopeId, token);

                    if (scope_res.IsErr)
                    {
                        throw new Exception($"BUG: Unable to get properties for scope: {scopeId}. {scope_res}");
                    }
                    localsFetched = true;
                }
                if (scopeCache.Locals.TryGetValue(partTrimmed, out JObject obj))
                {
                    rootObject = obj["value"]?.Value <JObject>();
                }
                else if (scopeCache.Locals.TryGetValue("this", out JObject objThis))
                {
                    if (partTrimmed == "this")
                    {
                        rootObject = objThis?["value"].Value <JObject>();
                    }
                    else if (DotnetObjectId.TryParse(objThis?["value"]?["objectId"]?.Value <string>(), out DotnetObjectId objectId))
                    {
                        var rootResObj = await proxy.RuntimeGetPropertiesInternal(sessionId, objectId, null, token);

                        var objRet = rootResObj.FirstOrDefault(objPropAttr => objPropAttr["name"].Value <string>() == partTrimmed);
                        if (objRet != null)
                        {
                            rootObject = await GetValueFromObject(objRet, token);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
            }
            scopeCache.MemberReferences[varName] = rootObject;
            return(rootObject);
        }