Ejemplo n.º 1
0
        /// Evaluate the operation against stack
        public void Eval(IEvaluationContext context, Stack <object> stack)
        {
            object[] p = OperationHelper.PopArray(stack, _paramCount);

            if (!_thisCall && !_id.Contains(".") && !_isProperty)
            {
                stack.Push(context.CallExternal(_id, p));
                return;
            }

            // ID is smth like x.y.z where we have no idea whether x is namespace,type, or object name. So we split it
            // and ask
            var parts = (!_id.Contains(".") && !string.IsNullOrEmpty(_id) && _paramCount != 0 && _isProperty)?((_id + ".").Split('.')):_id.Split('.');

            IEnumerable <TypeObjectPair> typeAndObjects = null;

            if (_thisCall)
            {
                var o = stack.Pop();
                typeAndObjects = new TypeObjectPair[] { new TypeObjectPair(o.GetType(), o) };
            }

            object sub;
            bool   success = false;

            for (int i = 0; i < parts.Length; ++i)
            {
                string currentPart = parts[i];
                if (typeAndObjects == null)
                {
                    string tn = string.Join(".", parts, 0, i + 1);
                    if (string.IsNullOrEmpty(tn))
                    {
                        typeAndObjects = context.GetNonameObjects();
                    }
                    else
                    {
                        if (context.TryGetExternal(tn, out sub))
                        {
                            success        = true;
                            typeAndObjects = (sub == null) ? null : new[] { new TypeObjectPair(sub.GetType(), sub) };
                        }
                        else
                        {
                            var t = context.FindType(tn);
                            if (t != null)
                            {
                                typeAndObjects = new[] { new TypeObjectPair(t, null) };
                                success        = true;
                            }
                        }
                    }
                }
                else
                {
                    success = false;
                    foreach (var to in typeAndObjects)
                    {
                        if (_isProperty || i != parts.Length - 1)
                        {
                            success = Utils.TryGetProperty(to.Object, to.Type, currentPart, (i == parts.Length - 1) ? p : null, context.AccessPrivate, out sub);
                        }
                        else
                        {
                            success = Utils.TryCallMethod(to.Object, to.Type, currentPart, (i == parts.Length - 1) ? p : null, context.AccessPrivate, out sub);
                        }
                        if (success)
                        {
                            typeAndObjects = null;
                            if (!object.ReferenceEquals(sub, null))
                            {
                                typeAndObjects = new[] { new TypeObjectPair(sub.GetType(), sub) }
                            }
                            ;
                            break;
                        }
                    }
                    if (!success)
                    {
                        // Last possible chance for COM objects where reflection does not work, but calling might!
                        if (i == parts.Length - 1)
                        {
                            foreach (var to in typeAndObjects)
                            {
                                if (to.Object == null)
                                {
                                    continue;
                                }

                                if (_isProperty)
                                {
                                    if (p.Length == 0)
                                    {
                                        stack.Push(Utils.GetProperty(to.Object, currentPart));
                                        return;
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        stack.Push(Utils.CallMethod(to.Object, currentPart, p));
                                    }
                                    catch (Exception e)
                                    {
                                        var comex = e as System.Runtime.InteropServices.COMException;
                                        var miex  = e as MissingMethodException;
                                        if (miex != null || (comex != null && ((uint)comex.ErrorCode == 0x80020006u || (uint)comex.ErrorCode == 0x80020005u)))
                                        {
                                            if (currentPart.StartsWith("set_", StringComparison.OrdinalIgnoreCase) && p.Length == 1)
                                            {
                                                Utils.SetPropertySimple(to.Object, currentPart.Substring(4), p[0]);
                                                stack.Push(null);
                                                return;
                                            }
                                            if (currentPart.StartsWith("get_", StringComparison.OrdinalIgnoreCase) && p.Length == 0)
                                            {
                                                stack.Push(Utils.GetProperty(to.Object, currentPart.Substring(4)));
                                                return;
                                            }
                                        }
                                        if (e is System.Reflection.TargetInvocationException && e.InnerException != null)
                                        {
                                            Utils.Rethrow(e.InnerException);
                                        }
                                        Utils.Rethrow(e);
                                    }
                                    return;
                                }
                            }
                        }
                        throw new MissingMemberException("Failed to resolve '" + currentPart + "' with " + p.Length + " arguments");
                    }
                }
            }
            if (!success)
            {
                throw new MissingMemberException("Failed to resolve '" + _id + "' with " + p.Length + " arguments");
            }
            if (typeAndObjects == null)
            {
                stack.Push(null);
            }
            else
            {
                foreach (var o in typeAndObjects)
                {
                    stack.Push(o.Object);
                    break;
                }
            }
        }
Ejemplo n.º 2
0
        /// Evaluate the operation against stack
        public void Eval(IEvaluationContext context, Stack<object> stack)
        {
            object[] p = OperationHelper.PopArray(stack, _paramCount);

            if (!_thisCall && !_id.Contains(".") && !_isProperty)
            {
                stack.Push(context.CallExternal(_id, p));
                return;
            }

            // ID is smth like x.y.z where we have no idea whether x is namespace,type, or object name. So we split it
            // and ask
            var parts = (!_id.Contains(".") && !string.IsNullOrEmpty(_id) && _paramCount != 0 && _isProperty)?((_id+".").Split('.')):_id.Split('.');

            IEnumerable<TypeObjectPair> typeAndObjects = null;
            if (_thisCall)
            {
                var o=stack.Pop();
                typeAndObjects = new TypeObjectPair[] { new TypeObjectPair(o.GetType(), o) };
            }

            object sub;
            bool success = false;
            for (int i=0;i<parts.Length;++i)
            {
                string currentPart = parts[i];
                if (typeAndObjects == null)
                {
                    string tn = string.Join(".", parts, 0, i + 1);
                    if (string.IsNullOrEmpty(tn))
                        typeAndObjects = context.GetNonameObjects();
                    else
                    {
                        if (context.TryGetExternal(tn, out sub))
                        {
                            success = true;
                            typeAndObjects = (sub == null) ? null : new[] {new TypeObjectPair(sub.GetType(), sub)};
                        }
                        else
                        {
                            var t = context.FindType(tn);
                            if (t != null)
                            {
                                typeAndObjects = new[] { new TypeObjectPair(t, null) };
                                success = true;
                            }
                        }
                    }
                }
                else
                {
                    success = false;
                    foreach (var to in typeAndObjects)
                    {
                        if (_isProperty || i != parts.Length - 1)
                            success = Utils.TryGetProperty(to.Object, to.Type, currentPart, (i == parts.Length - 1) ? p : null, context.AccessPrivate,out sub);
                        else
                            success = Utils.TryCallMethod(to.Object, to.Type, currentPart, (i == parts.Length - 1) ? p : null, context.AccessPrivate, out sub);
                        if (success)
                        {
                            typeAndObjects = null;
                            if (!object.ReferenceEquals(sub, null))
                                typeAndObjects = new[] {new TypeObjectPair(sub.GetType(), sub)};
                            break;
                        }
                    }
                    if (!success)
                    {
                        // Last possible chance for COM objects where reflection does not work, but calling might!
                        if (i==parts.Length-1)
                        {
                            foreach (var to in typeAndObjects)
                            {
                                if (to.Object==null)
                                    continue;

                                if (_isProperty)
                                {
                                    if (p.Length == 0)
                                    {
                                        stack.Push(Utils.GetProperty(to.Object, currentPart));
                                        return;
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        stack.Push(Utils.CallMethod(to.Object, currentPart, p));
                                    }
                                    catch(Exception e)
                                    {
                                        var comex = e as System.Runtime.InteropServices.COMException;
                                        var miex = e as MissingMethodException;
                                        if (miex != null || (comex != null && ((uint)comex.ErrorCode == 0x80020006u || (uint)comex.ErrorCode == 0x80020005u)))
                                        {
                                            if (currentPart.StartsWith("set_", StringComparison.OrdinalIgnoreCase) && p.Length == 1)
                                            {
                                                Utils.SetPropertySimple(to.Object, currentPart.Substring(4), p[0]);
                                                stack.Push(null);
                                                return;
                                            }
                                            if (currentPart.StartsWith("get_", StringComparison.OrdinalIgnoreCase) && p.Length == 0)
                                            {
                                                stack.Push(Utils.GetProperty(to.Object, currentPart.Substring(4)));
                                                return;
                                            }
                                        }
                                        if (e is System.Reflection.TargetInvocationException && e.InnerException!=null)
                                            Utils.Rethrow(e.InnerException);
                                        Utils.Rethrow(e);
                                    }
                                    return;
                                }
                            }
                        }
                        throw new MissingMemberException("Failed to resolve '" + currentPart + "' with "+p.Length+" arguments");
                    }
                }
            }
            if (!success)
                throw new MissingMemberException("Failed to resolve '" + _id + "' with " + p.Length + " arguments");
            if (typeAndObjects==null)
                stack.Push(null);
            else
                foreach (var o in typeAndObjects)
                {
                    stack.Push(o.Object);
                    break;
                }
        }