/// <summary>
            /// Performs autoload.
            /// </summary>
            public PhpTypeInfo AutoloadTypeByName(string fullName)
            {
                PhpTypeInfo resolved = null;

                // remove leading \ from the type name
                if (fullName.Length != 0 && fullName[0] == '\\')
                {
                    fullName = fullName.Substring(1);
                }

                //
                using (var token = new Context.RecursionCheckToken(_ctx, fullName))
                {
                    if (!token.IsInRecursion)
                    {
                        var args = new[] { (PhpValue)fullName };

                        for (var node = _autoloaders.First; node != null && resolved == null; node = node.Next)
                        {
                            node.Value.Invoke(_ctx, args);
                            resolved = _ctx.GetDeclaredType(fullName);
                        }
                    }
                }

                //
                return(resolved);
            }
Beispiel #2
0
            /// <summary>
            /// Performs autoload.
            /// </summary>
            public PhpTypeInfo AutoloadTypeByName(string fullName)
            {
                PhpTypeInfo resolved = null;

                using (var token = new Context.RecursionCheckToken(_ctx, fullName))
                {
                    if (!token.IsInRecursion)
                    {
                        var args = new[] { (PhpValue)fullName };

                        for (var node = _autoloaders.First; node != null && resolved == null; node = node.Next)
                        {
                            node.Value.Invoke(_ctx, args);
                            resolved = _ctx.GetDeclaredType(fullName);
                        }
                    }
                }

                //
                return(resolved);
            }
Beispiel #3
0
        public PhpAlias GetAlias(ref PhpValue value, Context ctx, Type classContext)
        {
            var receiver = PhpValue.EnsureObject(ref value);
            var t        = receiver.GetPhpTypeInfo();

            PhpValue tmp;

            if (BinderHelpers.TryResolveDeclaredProperty(t, classContext, false, Name, out var prop))
            {
                switch (Next.Operation)
                {
                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(prop.EnsureObject(ctx, receiver));
                    break;

                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.Create(prop.EnsureArray(ctx, receiver));
                    break;

                case RuntimeChainOperation.End:
                    return(prop.EnsureAlias(ctx, receiver));

                default:
                    throw new InvalidOperationException();
                }
            }
            else
            {
                // Template: runtimeflds.Contains(key) ? runtimeflds.EnsureObject(key) : ( __get(key) ?? runtimeflds.EnsureObject(key))

                var runtimeFields = t.GetRuntimeFields(receiver);
                if (runtimeFields == null || !runtimeFields.Contains(Name))
                {
                    //
                    var __get = t.RuntimeMethods[TypeMethods.MagicMethods.__get];
                    if (__get != null)
                    {
                        // NOTE: magic methods must have public visibility, therefore the visibility check is unnecessary

                        // int subkey1 = access.Write() ? 1 : access.Unset() ? 2 : access.Isset() ? 3 : 4;
                        int subkey = Name.GetHashCode() ^ (1 << 4 /*subkey1*/);

                        using (var token = new Context.RecursionCheckToken(ctx, receiver, subkey))
                        {
                            if (!token.IsInRecursion)
                            {
                                tmp = __get.Invoke(ctx, receiver, Name);
                                return(Next.GetAlias(ref tmp, ctx, classContext));
                            }
                        }
                    }
                }

                if (runtimeFields == null)
                {
                    runtimeFields = t.EnsureRuntimeFields(receiver);
                }

                //

                switch (Next.Operation)
                {
                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(runtimeFields.EnsureItemObject(Name));
                    break;

                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.Create(runtimeFields.EnsureItemArray(Name));
                    break;

                case RuntimeChainOperation.End:
                    return(runtimeFields.EnsureItemAlias(Name));

                default:
                    throw new InvalidOperationException();
                }
            }

            // chain:
            return(Next.GetAlias(ref tmp, ctx, classContext));
        }