// 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); }