public async Task <JObject> GetValueFromObject(JToken objRet, CancellationToken token) { if (objRet["value"]?["className"]?.Value <string>() == "System.Exception") { if (DotnetObjectId.TryParse(objRet?["value"]?["objectId"]?.Value <string>(), out DotnetObjectId objectId)) { var exceptionObject = await context.SdbAgent.GetObjectValues(objectId.Value, GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.OwnProperties, token); var exceptionObjectMessage = exceptionObject.FirstOrDefault(attr => attr["name"].Value <string>().Equals("_message")); exceptionObjectMessage["value"]["value"] = objRet["value"]?["className"]?.Value <string>() + ": " + exceptionObjectMessage["value"]?["value"]?.Value <string>(); return(exceptionObjectMessage["value"]?.Value <JObject>()); } return(objRet["value"]?.Value <JObject>()); } if (objRet["value"]?.Value <JObject>() != null) { return(objRet["value"]?.Value <JObject>()); } if (objRet["get"]?.Value <JObject>() != null) { if (DotnetObjectId.TryParse(objRet?["get"]?["objectIdValue"]?.Value <string>(), out DotnetObjectId objectId)) { using var commandParamsWriter = new MonoBinaryWriter(); commandParamsWriter.WriteObj(objectId, context.SdbAgent); var ret = await context.SdbAgent.InvokeMethod(commandParamsWriter.GetParameterBuffer(), objRet["get"]["methodId"].Value <int>(), objRet["name"].Value <string>(), token); return(await GetValueFromObject(ret, token)); } } return(null); }
public async Task <JObject> GetValueFromObject(JToken objRet, CancellationToken token) { if (objRet["value"]?["className"]?.Value <string>() == "System.Exception") { if (DotnetObjectId.TryParse(objRet?["value"]?["objectId"]?.Value <string>(), out DotnetObjectId objectId)) { var exceptionObject = await proxy.SdbHelper.GetObjectValues(sessionId, int.Parse(objectId.Value), true, false, false, true, token); var exceptionObjectMessage = exceptionObject.FirstOrDefault(attr => attr["name"].Value <string>().Equals("_message")); exceptionObjectMessage["value"]["value"] = objRet["value"]?["className"]?.Value <string>() + ": " + exceptionObjectMessage["value"]?["value"]?.Value <string>(); return(exceptionObjectMessage["value"]?.Value <JObject>()); } return(objRet["value"]?.Value <JObject>()); } if (objRet["value"]?.Value <JObject>() != null) { return(objRet["value"]?.Value <JObject>()); } if (objRet["get"]?.Value <JObject>() != null) { if (DotnetObjectId.TryParse(objRet?["get"]?["objectIdValue"]?.Value <string>(), out DotnetObjectId objectId)) { var commandParams = new MemoryStream(); var commandParamsWriter = new MonoBinaryWriter(commandParams); commandParamsWriter.WriteObj(objectId, proxy.SdbHelper); var ret = await proxy.SdbHelper.InvokeMethod(sessionId, commandParams.ToArray(), objRet["get"]["methodId"].Value <int>(), objRet["name"].Value <string>(), token); return(await GetValueFromObject(ret, token)); } } return(null); }
public async Task <JObject> Resolve(InvocationExpressionSyntax method, Dictionary <string, JObject> memberAccessValues, CancellationToken token) { var methodName = ""; int isTryingLinq = 0; try { JObject rootObject = null; var expr = method.Expression; if (expr is MemberAccessExpressionSyntax) { var memberAccessExpressionSyntax = expr as MemberAccessExpressionSyntax; rootObject = await Resolve(memberAccessExpressionSyntax.Expression.ToString(), token); methodName = memberAccessExpressionSyntax.Name.ToString(); } else if (expr is IdentifierNameSyntax) { if (scopeCache.ObjectFields.TryGetValue("this", out JObject valueRet)) { rootObject = await GetValueFromObject(valueRet, token); methodName = expr.ToString(); } } if (rootObject != null) { DotnetObjectId.TryParse(rootObject?["objectId"]?.Value <string>(), out DotnetObjectId objectId); var typeIds = await sdbHelper.GetTypeIdFromObject(sessionId, int.Parse(objectId.Value), true, token); int methodId = await sdbHelper.GetMethodIdByName(sessionId, typeIds[0], methodName, token); var className = await sdbHelper.GetTypeNameOriginal(sessionId, typeIds[0], token); if (methodId == 0) //try to search on System.Linq.Enumerable { if (linqTypeId == -1) { linqTypeId = await sdbHelper.GetTypeByName(sessionId, "System.Linq.Enumerable", token); } methodId = await sdbHelper.GetMethodIdByName(sessionId, linqTypeId, methodName, token); if (methodId != 0) { foreach (var typeId in typeIds) { var genericTypeArgs = await sdbHelper.GetTypeParamsOrArgsForGenericType(sessionId, typeId, token); if (genericTypeArgs.Count > 0) { isTryingLinq = 1; methodId = await sdbHelper.MakeGenericMethod(sessionId, methodId, genericTypeArgs, token); break; } } } } if (methodId == 0) { var typeName = await sdbHelper.GetTypeName(sessionId, typeIds[0], token); throw new Exception($"Method '{methodName}' not found in type '{typeName}'"); } var commandParamsObj = new MemoryStream(); var commandParamsObjWriter = new MonoBinaryWriter(commandParamsObj); if (isTryingLinq == 0) { commandParamsObjWriter.WriteObj(objectId, sdbHelper); } if (method.ArgumentList != null) { commandParamsObjWriter.Write((int)method.ArgumentList.Arguments.Count + isTryingLinq); if (isTryingLinq == 1) { commandParamsObjWriter.WriteObj(objectId, sdbHelper); } foreach (var arg in method.ArgumentList.Arguments) { if (arg.Expression is LiteralExpressionSyntax) { if (!await commandParamsObjWriter.WriteConst(sessionId, arg.Expression as LiteralExpressionSyntax, sdbHelper, token)) { return(null); } } if (arg.Expression is IdentifierNameSyntax) { var argParm = arg.Expression as IdentifierNameSyntax; if (!await commandParamsObjWriter.WriteJsonValue(sessionId, memberAccessValues[argParm.Identifier.Text], sdbHelper, token)) { return(null); } } } var retMethod = await sdbHelper.InvokeMethod(sessionId, commandParamsObj.ToArray(), methodId, "methodRet", token); return(await GetValueFromObject(retMethod, token)); } } return(null); } catch (Exception) { throw new Exception($"Unable to evaluate method '{methodName}'"); } }
public async Task <JObject> Resolve(InvocationExpressionSyntax method, Dictionary <string, JObject> memberAccessValues, CancellationToken token) { var methodName = ""; try { JObject rootObject = null; var expr = method.Expression; if (expr is MemberAccessExpressionSyntax) { var memberAccessExpressionSyntax = expr as MemberAccessExpressionSyntax; rootObject = await Resolve(memberAccessExpressionSyntax.Expression.ToString(), token); methodName = memberAccessExpressionSyntax.Name.ToString(); } else if (expr is IdentifierNameSyntax) { if (scopeCache.ObjectFields.TryGetValue("this", out JObject valueRet)) { rootObject = await GetValueFromObject(valueRet, token); methodName = expr.ToString(); } } if (rootObject != null) { DotnetObjectId.TryParse(rootObject?["objectId"]?.Value <string>(), out DotnetObjectId objectId); var typeId = await proxy.SdbHelper.GetTypeIdFromObject(sessionId, int.Parse(objectId.Value), true, token); int methodId = await proxy.SdbHelper.GetMethodIdByName(sessionId, typeId[0], methodName, token); if (methodId == 0) { var typeName = await proxy.SdbHelper.GetTypeName(sessionId, typeId[0], token); throw new Exception($"Method '{methodName}' not found in type '{typeName}'"); } var command_params_obj = new MemoryStream(); var commandParamsObjWriter = new MonoBinaryWriter(command_params_obj); commandParamsObjWriter.WriteObj(objectId, proxy.SdbHelper); if (method.ArgumentList != null) { commandParamsObjWriter.Write((int)method.ArgumentList.Arguments.Count); foreach (var arg in method.ArgumentList.Arguments) { if (arg.Expression is LiteralExpressionSyntax) { if (!await commandParamsObjWriter.WriteConst(sessionId, arg.Expression as LiteralExpressionSyntax, proxy.SdbHelper, token)) { return(null); } } if (arg.Expression is IdentifierNameSyntax) { var argParm = arg.Expression as IdentifierNameSyntax; if (!await commandParamsObjWriter.WriteJsonValue(sessionId, memberAccessValues[argParm.Identifier.Text], proxy.SdbHelper, token)) { return(null); } } } var retMethod = await proxy.SdbHelper.InvokeMethod(sessionId, command_params_obj.ToArray(), methodId, "methodRet", token); return(await GetValueFromObject(retMethod, token)); } } return(null); } catch (Exception) { throw new Exception($"Unable to evaluate method '{methodName}'"); } }
public async Task <JObject> Resolve(ElementAccessExpressionSyntax elementAccess, Dictionary <string, JObject> memberAccessValues, JObject indexObject, CancellationToken token) { try { JObject rootObject = null; string elementAccessStrExpression = elementAccess.Expression.ToString(); rootObject = await Resolve(elementAccessStrExpression, token); if (rootObject == null) { rootObject = indexObject; indexObject = null; } if (rootObject != null) { string elementIdxStr; int elementIdx = 0; // x[1] or x[a] or x[a.b] if (indexObject == null) { if (elementAccess.ArgumentList != null) { var commandParamsObj = new MemoryStream(); var commandParamsObjWriter = new MonoBinaryWriter(commandParamsObj); foreach (var arg in elementAccess.ArgumentList.Arguments) { // e.g. x[1] if (arg.Expression is LiteralExpressionSyntax) { var argParm = arg.Expression as LiteralExpressionSyntax; elementIdxStr = argParm.ToString(); int.TryParse(elementIdxStr, out elementIdx); } // e.g. x[a] or x[a.b] if (arg.Expression is IdentifierNameSyntax) { var argParm = arg.Expression as IdentifierNameSyntax; // x[a.b] memberAccessValues.TryGetValue(argParm.Identifier.Text, out indexObject); // x[a] if (indexObject == null) { indexObject = await Resolve(argParm.Identifier.Text, token); } elementIdxStr = indexObject["value"].ToString(); int.TryParse(elementIdxStr, out elementIdx); } } } } // e.g. x[a[0]], x[a[b[1]]] etc. else { elementIdxStr = indexObject["value"].ToString(); int.TryParse(elementIdxStr, out elementIdx); } if (elementIdx >= 0) { DotnetObjectId.TryParse(rootObject?["objectId"]?.Value <string>(), out DotnetObjectId objectId); switch (objectId.Scheme) { case "array": rootObject["value"] = await sdbHelper.GetArrayValues(sessionId, int.Parse(objectId.Value), token); return((JObject)rootObject["value"][elementIdx]["value"]); case "object": var typeIds = await sdbHelper.GetTypeIdFromObject(sessionId, int.Parse(objectId.Value), true, token); int methodId = await sdbHelper.GetMethodIdByName(sessionId, typeIds[0], "ToArray", token); var commandParamsObj = new MemoryStream(); var commandParamsObjWriter = new MonoBinaryWriter(commandParamsObj); commandParamsObjWriter.WriteObj(objectId, sdbHelper); var toArrayRetMethod = await sdbHelper.InvokeMethod(sessionId, commandParamsObj.ToArray(), methodId, elementAccess.Expression.ToString(), token); rootObject = await GetValueFromObject(toArrayRetMethod, token); DotnetObjectId.TryParse(rootObject?["objectId"]?.Value <string>(), out DotnetObjectId arrayObjectId); rootObject["value"] = await sdbHelper.GetArrayValues(sessionId, int.Parse(arrayObjectId.Value), token); return((JObject)rootObject["value"][elementIdx]["value"]); default: throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of type '{objectId.Scheme}'"); } } } return(null); } catch (Exception ex) { var e = ex; throw new Exception($"Unable to evaluate method '{elementAccess}'"); } }