예제 #1
0
        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}'");
            }
        }
예제 #2
0
        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}'");
            }
        }