Bike.Interpreter.Interpreter.AccessOneByOne C# (CSharp) Метод

AccessOneByOne() приватный Метод

private AccessOneByOne ( object currentTarget, object previousTarget, List suffixes ) : object
currentTarget object
previousTarget object
suffixes List
Результат object
        private object AccessOneByOne(object currentTarget, object previousTarget, List<Node> suffixes)
        {
            if (suffixes.Count == 0)
                return currentTarget;

            if (currentTarget == null)
                throw ErrorFactory.CreateNullError("Object");

            var currentSuffix = suffixes[0];

            // bike function, .NET ctor or .NET delegate
            if (currentSuffix is Arguments)
            {
                var arguments = (Arguments) currentSuffix;
                // bike function
                if (currentTarget is BikeFunction)
                {
                    previousTarget = CallBikeFunction((BikeFunction)currentTarget,
                                                      previousTarget, arguments);
                }
                // ctor
                else if (currentTarget is Type)
                {
                    var argValues = GetArgumentValues(arguments);
                    previousTarget = CreateInstance((Type)currentTarget, argValues);
                }
                // delegate
                else
                {
                    var args = GetArgumentValues(arguments);
                    previousTarget = CallDelegate((Delegate)currentTarget, args);
                }
                return AccessOneByOne(previousTarget, currentTarget, suffixes.ExceptFirst());
            }
            if (currentSuffix is PropertyReferenceSuffix ||
                currentSuffix is IndexSuffix ||
                currentSuffix is TypeDescriptorSuffix)
            {
                if (currentTarget is BikeObject)
                {
                    var currentSuffixStr = currentSuffix.SuffixValue(this);
                    previousTarget = ((BikeObject)currentTarget).Resolve(currentSuffixStr);
                }
                else if (currentTarget is Type) // Static context
                {
                    var currentSuffixStr = currentSuffix.SuffixValue(this);

                    // Static generic call
                    if (suffixes.Count > 2 &&
                        suffixes[1] is TypeDescriptorSuffix &&
                        suffixes[2] is Arguments
                        )
                    {
                        var typeParams = (Type[])suffixes[1].Accept(this);
                        var args = GetArgumentValues((Arguments)suffixes[2]);
                        previousTarget = CallStaticFunction((Type)currentTarget, typeParams, currentSuffixStr, args);
                        suffixes = suffixes.ExceptFirst().ExceptFirst();
                    }

                    // Static method or delegate
                    else if (suffixes.Count > 1 && suffixes[1] is Arguments)
                    {
                        try
                        {
                            // delegate?
                            previousTarget = GetStaticProperty((Type)currentTarget, currentSuffixStr);
                        }
                        catch (BikeObject bo)
                        {
                            if (!ErrorFactory.IsClrError(bo))
                                throw;
                            // method?  invoke immediately to avoid saving MethodInfo
                            var args = GetArgumentValues((Arguments)suffixes[1]);
                            previousTarget = CallStaticFunction((Type)currentTarget, currentSuffixStr, args);
                            suffixes = suffixes.ExceptFirst();
                        }
                    }
                    else // .NET static property, invoke immediately
                    {
                        previousTarget = GetStaticProperty((Type)currentTarget, currentSuffixStr);
                    }
                }

                // Must be .NET generic instance method
                else if (suffixes.Count > 2 &&
                        suffixes[1] is TypeDescriptorSuffix &&
                        suffixes[2] is Arguments)
                {
                    var currentSuffixStr = currentSuffix.SuffixValue(this);
                    var typeParams = (Type[])suffixes[1].Accept(this);
                    var args = GetArgumentValues((Arguments)suffixes[2]);
                    previousTarget = CallInstanceFunction(currentTarget, typeParams, currentSuffixStr, args);
                    suffixes = suffixes.ExceptFirst().ExceptFirst();
                }

                // .NET instance method or delegate
                else if (suffixes.Count > 1 && suffixes[1] is Arguments)
                {
                    try
                    {
                        // delegate?
                        var currentSuffixStr = currentSuffix.SuffixValue(this);
                        previousTarget = GetInstanceProperty(currentTarget, currentSuffixStr);
                    }
                    catch (BikeObject bo)
                    {
                        if (!ErrorFactory.IsClrError(bo))
                            throw;
                        // method?
                        var currentSuffixStr = currentSuffix.SuffixValue(this);
                        var args = GetArgumentValues((Arguments)suffixes[1]);
                        previousTarget = CallInstanceFunction(currentTarget, currentSuffixStr, args);
                        suffixes = suffixes.ExceptFirst();
                    }
                }

                // .NET instance property
                else if (currentSuffix is PropertyReferenceSuffix)
                {
                    var currentSuffixStr = currentSuffix.SuffixValue(this);
                    previousTarget = GetInstanceProperty(currentTarget, currentSuffixStr);
                }

                // .NET indexer
                else
                {
                    previousTarget = GetInstanceIndexer(currentTarget, currentSuffix.Arguments(this));
                }
                return AccessOneByOne(previousTarget, currentTarget, suffixes.ExceptFirst());
            }
            throw ErrorFactory.CreateError(string.Format("Invalid suffix type {0}", currentSuffix));
        }