コード例 #1
0
ファイル: Operators.cs プロジェクト: ph777/peachpie
        /// <summary>
        /// Implements <c>[]</c> operator on <see cref="string"/>.
        /// </summary>
        public static string GetItemValue(string value, IntStringKey key)
        {
            int index = key.IsInteger
                ? key.Integer
                : (int)Convert.StringToLongInteger(key.String);

            return(GetItemValue(value, index));
        }
コード例 #2
0
        /// <summary>
        /// Gets value at given index.
        /// Gets <c>void</c> value in case the key is not found.
        /// </summary>
        PhpValue IPhpArray.GetItemValue(IntStringKey key)
        {
            int index = key.IsInteger ? key.Integer : (int)Convert.StringToLongInteger(key.String);

            return((index >= 0 && index < this.Length)
                ? PhpValue.Create(this[index].ToString())
                : PhpValue.Create(string.Empty));
        }
コード例 #3
0
 void Accept(IntStringKey name)
 {
     // if variable exists adds a copy of its current value to the result:
     if (_locals.TryGetValue(name, out var value))
     {
         _result.Add(name, value.DeepCopy());
     }
 }
コード例 #4
0
 /// <summary>
 /// Called when an INI section is encountered.
 /// </summary>
 public void ProcessSection(IntStringKey sectionName)
 {
     if (_processSections)
     {
         _currentSection      = new PhpArray();
         _result[sectionName] = (PhpValue)_currentSection;
     }
 }
コード例 #5
0
        /// <summary>
        /// Implements <c>[]</c> operator on <see cref="string"/> with <c>isset</c> semantics.
        /// </summary>
        public static string GetItemValueOrNull(string value, IntStringKey key)
        {
            int index = key.IsInteger
                ? key.Integer
                : (int)Convert.StringToLongInteger(key.String);

            return((value != null && index >= 0 && index < value.Length)
                ? value[index].ToString()
                : null);
        }
コード例 #6
0
 /// <summary>
 /// Returns <see cref="ReflectionReference"/> if array element is a reference, <c>null</c> otherwise.
 /// </summary>
 public static ReflectionReference fromArrayElement(PhpArray array, IntStringKey /*int|string*/ key)
 {
     if (array != null && array.TryGetValue(key, out var value) && value.Object is PhpAlias alias)
     {
         return(new ReflectionReference(alias));
     }
     else
     {
         return(null);
     }
 }
コード例 #7
0
ファイル: Operators.cs プロジェクト: allisterb/peachpie
 public PhpValue GetItemValue(IntStringKey key)
 {
     if (key.IsInteger)
     {
         return(PhpValue.FromClr(_array[key.Integer]));
     }
     else
     {
         throw new ArgumentException(nameof(key));
     }
 }
コード例 #8
0
ファイル: Operators.cs プロジェクト: allisterb/peachpie
 public void RemoveKey(IntStringKey key)
 {
     if (key.IsInteger)
     {
         _array.RemoveAt(key.Integer);
     }
     else
     {
         throw new ArgumentException(nameof(key));
     }
 }
コード例 #9
0
 /// <summary>
 /// Called when an option (i.e. a key-value pair) is encountered.
 /// </summary>
 public void ProcessOption(IntStringKey key, string value)
 {
     if (key.IsString)
     {
         NameValueCollectionUtils.AddVariable(_currentSection, key.String, value, rawname: true);
     }
     else
     {
         _currentSection[key] = value;
     }
 }
コード例 #10
0
ファイル: Operators.cs プロジェクト: allisterb/peachpie
 public void SetItemAlias(IntStringKey key, PhpAlias alias)
 {
     if (key.IsInteger)
     {
         _array[key.Integer] = ToObject(alias.Value);
     }
     else
     {
         throw new ArgumentException(nameof(key));
     }
 }
コード例 #11
0
ファイル: Operators.cs プロジェクト: allisterb/peachpie
 public void SetItemValue(IntStringKey key, PhpValue value)
 {
     if (key.IsInteger)
     {
         _array[key.Integer] = ToObject(value);
     }
     else
     {
         throw new ArgumentException(nameof(key));
     }
 }
コード例 #12
0
            public override PhpAlias EnsureItemAlias(ref PhpValue me, IntStringKey key, bool quiet)
            {
                var arr = me.Object as IPhpArray;

                if (arr != null)
                {
                    return(arr.EnsureItemAlias(key));
                }

                // TODO: Err
                throw new NotSupportedException();
            }
コード例 #13
0
 static IPhpArray EnsureItemArray(IPhpArray array, IntStringKey key)
 {
     if (key.Equals(IntStringKey.EmptyStringKey))
     {
         var newarr = new PhpArray();
         array.AddValue(PhpValue.Create(newarr));
         return(newarr);
     }
     else
     {
         return(array.EnsureItemArray(key));
     }
 }
コード例 #14
0
        /// <summary>
        /// Provides utilities for converting razor data to twig comprehensable format
        /// </summary>
        public static PhpArray DataToPhp <T>(IntStringKey key, KeyValuePair <int, T>[] value) where T : struct
        {
            PhpArray val = new PhpArray(value.Length);

            foreach (var v in value)
            {
                val.Add(v.Key, v.Value);
            }

            PhpArray res = new PhpArray(1);

            res.Add(key, val);
            return(res);
        }
コード例 #15
0
        public static PhpArray EnsureItemArray(PhpArray array, IntStringKey key)
        {
            PhpArray result;

            if (key.IsEmpty)
            {
                result = new PhpArray();
                array.Add(result);
            }
            else
            {
                if (array.TryGetValue(key, out var value) && value.IsPhpArray(out var tmp) && tmp != null)
                {
                    result = tmp;
                }
コード例 #16
0
            /// <summary>
            /// Adds a form file to the <c>$_FILES</c> array.
            /// </summary>
            /// <param name="files">The $_FILES array.</param>
            /// <param name="field_name">Form field name.</param>
            /// <param name="file_name">Original file name, without the directory name.</param>
            /// <param name="type">Content type.</param>
            /// <param name="tmp_name">Local full file path where is the uploaded file temporarily stored.</param>
            /// <param name="error">Error code number.</param>
            /// <param name="file_length">Uploaded file size in bytes.</param>
            public static void AddFormFile(PhpArray /*!*/ files, string field_name, string file_name, string type, string tmp_name, int error, long file_length)
            {
                // field_name
                // field_name[]
                // field_name[key]

                var left = field_name.IndexOf('[');

                if (left > 0 && left < field_name.Length - 1)
                {
                    var right = field_name.IndexOf(']', left + 1);
                    if (right > 0)
                    {
                        // keyed file entry:

                        // the variable name is a key to the "array", dots are replaced by underscores in top-level name:
                        var field_name_key = new IntStringKey(NameValueCollectionUtils.EncodeTopLevelName(field_name.Substring(0, left)));
                        var file_entry     = NameValueCollectionUtils.EnsureItemArray(files, field_name_key);

                        // file entry key,
                        // can be a string, empty or a number
                        var key = Convert.StringToArrayKey(field_name.Substring(left + 1, right - left - 1));

                        NameValueCollectionUtils.EnsureItemArray(file_entry, "name", key, file_name);
                        NameValueCollectionUtils.EnsureItemArray(file_entry, "type", key, type);
                        NameValueCollectionUtils.EnsureItemArray(file_entry, "tmp_name", key, tmp_name);
                        NameValueCollectionUtils.EnsureItemArray(file_entry, "error", key, error);
                        NameValueCollectionUtils.EnsureItemArray(file_entry, "size", key, file_length);

                        //
                        return;
                    }
                }

                // not keyed:
                AddVariable(files, field_name, new PhpArray(5)
                {
                    { "name", file_name },
                    { "type", type },
                    { "tmp_name", tmp_name },
                    { "error", error },
                    { "size", file_length },
                });
            }
コード例 #17
0
        /// <summary>
        /// Tries conversion to an array key.
        /// </summary>
        public static bool TryToIntStringKey(PhpValue value, out IntStringKey key)
        {
            switch (value.TypeCode)
            {
            case PhpTypeCode.Int32:
            case PhpTypeCode.Long:
            case PhpTypeCode.Double:
            case PhpTypeCode.String:
            case PhpTypeCode.WritableString:
            case PhpTypeCode.Boolean:
                key = value.ToIntStringKey();
                return(true);

            case PhpTypeCode.Alias:
                return(TryToIntStringKey(value.Alias.Value, out key));

            default:
                key = default(IntStringKey);
                return(false);
            }
        }
コード例 #18
0
            public override PhpValue GetArrayItem(ref PhpValue me, IntStringKey key, bool quiet)
            {
                // IPhpArray[]
                var arr = me.Object as IPhpArray;

                if (arr != null)
                {
                    return(arr.GetItemValue(key));
                }

                // ArrayAccess.offsetGet()
                var arracces = me.Object as ArrayAccess;

                if (arracces != null)
                {
                    return(arracces.offsetGet(PhpValue.Create(key)));
                }

                // TODO
                throw new NotImplementedException();
            }
        static PhpArray EnsureItemArray(PhpArray array, IntStringKey key)
        {
            PhpArray result;

            if (key.IsEmpty)
            {
                result = new PhpArray();
                array.AddValue(result);
            }
            else
            {
                if (!array.TryGetValue(key, out var value) || (result = value.AsArray()) == null)
                {
                    result = new PhpArray();
                    array.SetItemValue(key, result);
                }
            }

            //

            return(result);
        }
コード例 #20
0
        /// <summary>
        /// Gets descriptor representing a runtime field.
        /// Can be <c>null</c> if type does not support runtime fields.
        /// </summary>
        public static PhpPropertyInfo GetRuntimeProperty(this PhpTypeInfo tinfo, string propertyName, object instance)
        {
            if (tinfo.RuntimeFieldsHolder != null)
            {
                var key = new IntStringKey(propertyName);

                if (instance != null)
                {
                    var runtimefields = tinfo.GetRuntimeFields(instance);
                    if (runtimefields == null || runtimefields.Count == 0 || !runtimefields.ContainsKey(key))
                    {
                        return(null);
                    }
                }

                return(new PhpPropertyInfo.RuntimeProperty(tinfo, key));
            }
            else
            {
                return(null);
            }
        }
コード例 #21
0
ファイル: PhpValue.cs プロジェクト: zhangwenquan/peachpie
 /// <summary>
 /// Accesses the value as an array and gets item at given index.
 /// Gets <c>void</c> value in case the key is not found.
 /// Raises PHP exception in case the value cannot be accessed as an array.
 /// </summary>
 public PhpValue this[IntStringKey key]
 {
     get { return(GetArrayItem(Create(key), false)); }
 }
コード例 #22
0
ファイル: PhpArray.cs プロジェクト: crazyants/peachpie
 public IPhpArray EnsureItemArray(IntStringKey key) => table._ensure_item_array(ref key, this);
コード例 #23
0
ファイル: PhpArray.cs プロジェクト: crazyants/peachpie
 public PhpAlias EnsureItemAlias(IntStringKey key) => table._ensure_item_alias(ref key, this);
コード例 #24
0
ファイル: PhpArray.cs プロジェクト: iolevel/peachpie
 public IPhpArray EnsureItemArray(IntStringKey key) => table._ensure_item_array(ref key, this);
コード例 #25
0
ファイル: PhpString.cs プロジェクト: iolevel/peachpie
        /// <summary>
        /// Sets value at specific index. Value must not be an alias.
        /// </summary>
        void IPhpArray.SetItemValue(IntStringKey key, PhpValue value)
        {
            int index = key.IsInteger ? key.Integer : (int)Convert.StringToLongInteger(key.String);

            char ch;

            switch (value.TypeCode)
            {
                case PhpTypeCode.Long:
                    ch = (char)value.Long;
                    break;

                case PhpTypeCode.String:
                    ch = (value.String.Length != 0) ? value.String[0] : '\0';
                    break;

                case PhpTypeCode.WritableString:
                    ch = value.WritableString[0];
                    break;

                // TODO: other types

                default:
                    throw new NotSupportedException(value.TypeCode.ToString());
            }

            this[key.Integer] = ch;
        }
コード例 #26
0
ファイル: PhpArray.cs プロジェクト: iolevel/peachpie
 public PhpValue GetItemValue(IntStringKey key) => table._get(ref key);
コード例 #27
0
        static PhpReference GetRefMemberNotFound(DObject self, string name, DTypeDesc caller)
        {
            PhpReference reference;
            bool getter_exists;

            // search in RT fields
            if (self.RuntimeFields != null && self.RuntimeFields.ContainsKey(name))
            {
                var namekey = new IntStringKey(name);
                return self.RuntimeFields.table._ensure_item_ref(ref namekey, self.RuntimeFields);
            }

            // property is not present -> try to invoke __get
            reference = self.InvokeGetterRef(name, caller, out getter_exists);
            if (getter_exists) return (reference == null) ? new PhpReference() : reference;

            // (no notice/warning/error thrown by PHP)

            // add the field
            reference = new PhpReference();
            if (self.RuntimeFields == null) self.RuntimeFields = new PhpArray();
            self.RuntimeFields[name] = reference;

            return reference;
        }
コード例 #28
0
ファイル: PhpArray.cs プロジェクト: iolevel/peachpie
 public void SetItemAlias(IntStringKey key, PhpAlias alias)
 {
     this.EnsureWritable();
     table._add_or_update(ref key, PhpValue.Create(alias));
     this.KeyAdded(ref key);
 }
コード例 #29
0
ファイル: PhpArray.cs プロジェクト: iolevel/peachpie
 public void SetItemValue(IntStringKey key, PhpValue value)
 {
     this.EnsureWritable();
     table._add_or_update_preserve_ref(ref key, value);
     this.KeyAdded(ref key);
 }
コード例 #30
0
ファイル: PhpArray.cs プロジェクト: iolevel/peachpie
 public PhpAlias EnsureItemAlias(IntStringKey key) => table._ensure_item_alias(ref key, this);
コード例 #31
0
ファイル: PhpArray.cs プロジェクト: dw4dev/Phalanger
		public PhpHashEntryDebugView(IntStringKey key, object value)
		{
			this.key = key;
			this.value = value;
		}
コード例 #32
0
ファイル: PhpArray.cs プロジェクト: iolevel/peachpie
 public object EnsureItemObject(IntStringKey key) => table._ensure_item_object(ref key, this);
コード例 #33
0
ファイル: PhpValue.cs プロジェクト: zhangwenquan/peachpie
 public static PhpValue Create(IntStringKey value) => value.IsInteger ? Create(value.Integer) : Create(value.String);
コード例 #34
0
        private DynamicMetaObject/*!*/ FallbackInvokeMember(DynamicMetaObject target/*!*/, DynamicMetaObject/*!*/[]/*!*/ args)
        {
            // determine run time values and additional restrictions:
            DTypeDesc classContext = this._classContext;
            string fieldName = this._fieldName;
            BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType); //target.Restrictions;

            int currentArg = 0;
            if (!ClassContextIsKnown)
            {
                Debug.Assert(args.Length > currentArg, "Not enough arguments!");
                Debug.Assert(args[currentArg].Value == null || Types.DTypeDesc[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong class context type!");
                classContext = (DTypeDesc)args[currentArg].Value;
                Debug.Assert(classContext == null || !classContext.IsUnknown, "Class context should be known at run time!");

                restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(args[currentArg].Expression, classContext));
                
                currentArg++;
            }
            if (IsIndirect)
            {
                Debug.Assert(args.Length > currentArg, "Not enough arguments!");
                Debug.Assert(Types.String[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong field name type!");
                fieldName = (string)args[currentArg].Value;

                restrictions = restrictions.Merge(
                    BindingRestrictions.GetExpressionRestriction(
                        Expression.Equal(
                            args[currentArg].Expression,
                            Expression.Constant(fieldName, Types.String[0]))));

                currentArg++;
            }

            // 
            ////Debug.Assert(!(var is PhpReference) && name != null);
            Debug.Assert(target.HasValue && target.LimitType != Types.PhpReference[0], "Target should not be PhpReference!");

            ////if (ReferenceEquals(obj, ScriptContext.SetterChainSingletonObject))
            ////{
            ////    ScriptContext.CurrentContext.AbortSetterChain(false);
            ////    return new PhpReference();
            ////}
            if (WantReference && ReferenceEquals(target.Value, ScriptContext.SetterChainSingletonObject))
            {
                // GetObjectPropertyRef:
                Func<PhpReference> abortSetterChain = () =>
                {
                    ScriptContext.CurrentContext.AbortSetterChain(false);
                    return new PhpReference();
                };

                return new DynamicMetaObject(
                    Expression.Call(abortSetterChain.Method),
                    BindingRestrictions.GetInstanceRestriction(target.Expression, ScriptContext.SetterChainSingletonObject)
                    );
            }

            DObject obj;
            ////// a property of a DObject:
            if ((obj = target.Value as DObject) != null)
            {
                if (obj is ClrObject /*|| obj is IClrValue // IClrValue -> ClrValue<T> -> already in restriction */)
                {
                    // ((DObject)target).RealType == <obj>.RealType
                    restrictions = restrictions.Merge(
                        BindingRestrictions.GetInstanceRestriction(
                            Expression.Property(Expression.Convert(target.Expression, Types.DObject[0]), Properties.DObject_RealType),
                            obj.RealType));
                }

                ////    return GetObjectProperty(obj, name, caller, quiet);
                DPropertyDesc property;
                GetMemberResult result = obj.TypeDesc.GetInstanceProperty(new VariableName(fieldName), classContext, out property);

                switch (result)
                {
                    case GetMemberResult.OK:
                        ////object value = property.Get(this);
                        ////PhpReference reference = value as PhpReference;

                        if (property.Member is PhpField || property.Member is PhpVisibleProperty)
                        {
                            var realType = property.DeclaringType.RealType;
                            FieldInfo realField = (property.Member is PhpField) ? property.PhpField.RealField : null;
                            PropertyInfo realProperty = (property.Member is PhpVisibleProperty) ? ((PhpVisibleProperty)property.Member).RealProperty : null;

                            Debug.Assert(realField != null ^ realProperty != null);

                            MemberExpression getter = null;

                            if (realField != null)
                                getter = Expression.Field(Expression.Convert(target.Expression, realType), realField);
                            else if (realProperty != null)
                                getter = Expression.Property(Expression.Convert(target.Expression, realType), realProperty);


                            if (Types.PhpReference[0].IsAssignableFrom(getter.Type))
                            {
                                var reference = Expression.Variable(Types.PhpReference[0]);
                                var assignment = Expression.Assign(reference, getter);

                                if (WantReference)
                                {
                                    ////value = property.Get(this);
                                    ////reference = value as PhpReference;

                                    var returnLabel = Expression.Label(this._returnType);

                                    ////if (reference != null && reference.IsSet)
                                    ////{
                                    ////    reference.IsAliased = true;
                                    ////    return reference;
                                    ////}

                                    var isset = Expression.IfThen(
                                        Expression.Property(assignment, Properties.PhpReference_IsSet),
                                        Expression.Block(
                                            Expression.Assign(Expression.Property(reference, Properties.PhpReference_IsAliased), Expression.Constant(true)),
                                            Expression.Return(returnLabel, reference)));

                                    ////// the CT property has been unset -> try to invoke __get
                                    ////PhpReference get_ref = InvokeGetterRef(name, caller, out getter_exists);
                                    ////if (getter_exists) return (get_ref == null ? new PhpReference() : get_ref);

                                    ////if (reference == null)
                                    ////{
                                    ////    reference = new PhpReference(value);
                                    ////    property.Set(this, reference);
                                    ////}
                                    ////else
                                    ////{
                                    ////    reference.IsAliased = true;
                                    ////    reference.IsSet = true;
                                    ////}
                                    Func<DObject, string, DTypeDesc, PhpReference, PhpReference> notsetOperation = (self, name, caller, refrnc) =>
                                        {
                                            bool getter_exists;
                                            // the CT property has been unset -> try to invoke __get
                                            PhpReference get_ref = self.InvokeGetterRef(name, caller, out getter_exists);
                                            if (getter_exists) return get_ref ?? new PhpReference();

                                            Debug.Assert(refrnc != null);

                                            refrnc.IsAliased = true;
                                            refrnc.IsSet = true;

                                            return refrnc;
                                        };

                                    ////return reference;

                                    return new DynamicMetaObject(
                                        Expression.Block(this._returnType,
                                            new[]{reference},
                                            new Expression[]{
                                                isset,
                                                Expression.Label(returnLabel,
                                                    Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]), reference))
                                            }),
                                            restrictions);
                                }
                                else
                                {
                                    ////if (reference != null && !reference.IsSet)
                                    ////{
                                    ////    // the property is CT but has been unset
                                    ////    if (issetSemantics)
                                    ////    {
                                    ////        bool handled;
                                    ////        return PropertyIssetHandler(name, caller, out handled);
                                    ////    }
                                    ////    else return GetRuntimeField(name, caller);
                                    ////}
                                    ////else return value;


                                    Func<DObject, string, DTypeDesc, object> notsetOperation;
                                    if (_issetSemantics) notsetOperation = (self, name, caller) =>
                                        {
                                            return PhpVariable.Dereference(self.GetRuntimeField(name, caller));
                                        };
                                    else notsetOperation = (self, name, caller) =>
                                        {
                                            bool handled;
                                            return PhpVariable.Dereference(self.PropertyIssetHandler(name, caller, out handled));
                                        };
                                    var value =
                                        Expression.Block(this._returnType,
                                            new[] { reference },
                                            Expression.Condition(
                                                Expression.Property(assignment, Properties.PhpReference_IsSet),
                                                Expression.Field(reference, Fields.PhpReference_Value),
                                                Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))
                                        ));

                                    return new DynamicMetaObject(value, restrictions);
                                }
                            }
                            else
                            {
                                if (WantReference)
                                {
                                    return new DynamicMetaObject(
                                        Expression.New(Constructors.PhpReference_Object, Expression.Convert(getter, Types.Object[0])),
                                        restrictions);
                                }
                                else
                                {
                                    return new DynamicMetaObject(
                                        Expression.Call(Methods.PhpVariable.Dereference, Expression.Convert(getter, Types.Object[0])),
                                        restrictions);
                                }
                            }
                        }
                        else if (property.Member is ClrProperty)
                        {
                            var realType = property.DeclaringType.RealType;
                            var realProperty = property.ClrProperty.RealProperty;

                            // (target.{RealObject|realValue}).<realProperty>
                            Expression value = Expression.Convert(
                                            BinderHelper.ClrObjectWrapDynamic(
                                                Expression.Property(
                                                    BinderHelper.ClrRealObject(target, realType),
                                                    realProperty)),
                                            Types.Object[0]);

                            if (WantReference) value = BinderHelper.MakePhpReference(value);

                            return new DynamicMetaObject(value, restrictions);
                        }
                        else if (property.Member is ClrField)
                        {
                            var realType = property.DeclaringType.RealType;
                            var realField = property.ClrField.FieldInfo;

                            // (target.{RealObject|realValue}).<realField>
                            Expression value = Expression.Convert(
                                            BinderHelper.ClrObjectWrapDynamic(
                                                Expression.Field(
                                                    BinderHelper.ClrRealObject(target, realType),
                                                    realField)),
                                            Types.Object[0]);

                            if (WantReference) value = BinderHelper.MakePhpReference(value);

                            return new DynamicMetaObject(value, restrictions);
                        }
                        else if (property.Member is ClrEvent)
                        {
                            var clrEvent = (ClrEvent)property.Member;
                            var realType = property.DeclaringType.RealType;

                            // emit stub that Wraps event as [ ClrEventObject<handlerType>.Wrap(<SC>, <event name>, <addMethod>, <removeMethod>) ]
                            var stub = new System.Reflection.Emit.DynamicMethod(
                                string.Format("event<{0}>",fieldName),
                                Types.DObject[0], new[] { realType }, realType);
                            var il = new ILEmitter(stub);
                            clrEvent.EmitGetEventObject(
                                il,
                                new Place(null, Properties.ScriptContext_CurrentContext),
                                new IndexedPlace(PlaceHolder.Argument, 0),
                                false);
                            il.Emit(System.Reflection.Emit.OpCodes.Ret);

                            Expression value = Expression.Call(stub, BinderHelper.ClrRealObject(target, realType));
                            if (WantReference) value = BinderHelper.MakePhpReference(value);
                            return new DynamicMetaObject(value, restrictions);
                        }
                        else
                            throw new NotImplementedException();

                    case GetMemberResult.NotFound:
                        if (WantReference)
                        {
                            Func<DObject, string, DTypeDesc, PhpReference> op = (self, name, caller) =>
                            {
                                PhpReference reference;
                                bool getter_exists;

                                // search in RT fields
                                if (self.RuntimeFields != null && self.RuntimeFields.ContainsKey(name))
                                {
                                    var namekey = new IntStringKey(name);
                                    return self.RuntimeFields.table._ensure_item_ref(ref namekey, self.RuntimeFields);
                                }

                                // property is not present -> try to invoke __get
                                reference = self.InvokeGetterRef(name, caller, out getter_exists);
                                if (getter_exists) return (reference == null) ? new PhpReference() : reference;

                                // (no notice/warning/error thrown by PHP)

                                // add the field
                                reference = new PhpReference();
                                if (self.RuntimeFields == null) self.RuntimeFields = new PhpArray();
                                self.RuntimeFields[name] = reference;

                                return reference;
                            };

                            return new DynamicMetaObject(
                                Expression.Call(null, op.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0])),
                                restrictions);
                        }
                        else
                        {
                            ////if (issetSemantics)
                            ////{
                            ////    OrderedHashtable<string>.Element element;
                            ////    if (RuntimeFields != null && (element = RuntimeFields.GetElement(name)) != null)
                            ////    {
                            ////        return element.Value;
                            ////    }
                            ////    else
                            ////    {
                            ////        bool handled;
                            ////        return PropertyIssetHandler(name, caller, out handled);
                            ////    }
                            ////}
                            ////else return GetRuntimeField(name, caller);

                            if (_issetSemantics)
                            {
                                Func<DObject, string, DTypeDesc, object> notsetOperation = (self, name, caller) =>
                                {
                                    if (self.RuntimeFields != null)
                                    {
                                        object value;
                                        if (self.RuntimeFields.TryGetValue(name, out value))
                                            return value;
                                    }

                                    bool handled;
                                    return self.PropertyIssetHandler(name, caller, out handled);
                                };

                                return new DynamicMetaObject(
                                    Expression.Call(Methods.PhpVariable.Dereference,
                                        Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))),
                                    restrictions);
                            }
                            else
                            {
                                return new DynamicMetaObject(
                                    Expression.Call(
                                        Methods.PhpVariable.Dereference,
                                        Expression.Call(
                                            Expression.Convert(target.Expression, Types.DObject[0]),
                                            Methods.DObject_GetRuntimeField, Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))),
                                    restrictions);
                            };
                            
                            
                        }
                    case GetMemberResult.BadVisibility:
                        {
                            ////PhpException.PropertyNotAccessible(
                            ////    property.DeclaringType.MakeFullName(),
                            ////    name.ToString(),
                            ////    (caller == null ? String.Empty : caller.MakeFullName()),
                            ////    property.IsProtected);

                            string stringResourceKey = property.IsProtected ? "protected_property_accessed" : "private_property_accessed";

                            return new DynamicMetaObject(
                                Expression.Block(this._returnType,
                                    Expression.Call(null, Methods.PhpException.Throw,
                                        Expression.Constant(PhpError.Error, Types.PhpError_String[0]),
                                        Expression.Constant(CoreResources.GetString(stringResourceKey, property.DeclaringType.MakeFullName(), fieldName, (classContext == null ? String.Empty : classContext.MakeFullName())))),
                                    WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null)
                                    ),
                                restrictions);
                        }
                }
            }

            ////// warnings:
            ////if (!quiet) // not in isset() operator only
            ////{
            if (!_issetSemantics)
            {
                ////    if (PhpVariable.IsEmpty(var))
                ////        // empty:
                ////        PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object"));
                ////    else
                ////        // PhpArray, string, scalar type:
                ////        PhpException.VariableMisusedAsObject(var, false);
                
                Action<object> error = (var) =>
                {
                    if (PhpVariable.IsEmpty(var))
                        // empty:
                        PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object"));
                    else
                        // PhpArray, string, scalar type:
                        PhpException.VariableMisusedAsObject(var, false);
                };

                return new DynamicMetaObject(
                    Expression.Block(this._returnType,
                        Expression.Call(error.Method, target.Expression),
                        WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null)),
                    (target.HasValue && target.Value == null) ?
                        BindingRestrictions.GetInstanceRestriction(target.Expression, null) :
                        BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType));
            }
            ////}
            
            ////// property does not exist
            ////return null;
            return new DynamicMetaObject(
                Expression.Constant(null),
                (target.HasValue && target.Value == null) ?
                    BindingRestrictions.GetInstanceRestriction(target.Expression, null) :
                    BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType));
        }
コード例 #35
0
ファイル: PhpArray.cs プロジェクト: dw4dev/Phalanger
        private PhpReference/*!*/ GetArrayItemRef(IntStringKey key)
		{
            return this.table._ensure_item_ref(ref key, this);
		}
コード例 #36
0
ファイル: PhpString.cs プロジェクト: iolevel/peachpie
 /// <summary>
 /// Removes a value matching given key.
 /// In case the value is not found, the method does nothing.
 /// </summary>
 void IPhpArray.RemoveKey(IntStringKey key) { throw new NotSupportedException(); }
コード例 #37
0
ファイル: PhpArray.cs プロジェクト: dw4dev/Phalanger
		private void SetArrayItem(IntStringKey key, object value)
		{
            Debug.Assert(this.GetType() == typeof(PhpArray));

            this.EnsureWritable();
            this.table._add_or_update_preserve_ref(this, ref key, value);
		}
コード例 #38
0
ファイル: PhpString.cs プロジェクト: iolevel/peachpie
 /// <summary>
 /// Ensures the item at given index is array.
 /// </summary>
 IPhpArray IPhpArray.EnsureItemArray(IntStringKey key) { throw new NotSupportedException(); }
コード例 #39
0
ファイル: PhpString.cs プロジェクト: iolevel/peachpie
        /// <summary>
        /// Gets value at given index.
        /// Gets <c>void</c> value in case the key is not found.
        /// </summary>
        PhpValue IPhpArray.GetItemValue(IntStringKey key)
        {
            int index = key.IsInteger ? key.Integer : (int)Convert.StringToLongInteger(key.String);

            return (index >= 0 && index < this.Length)
                ? PhpValue.Create(this[index].ToString())
                : PhpValue.Create(string.Empty);
        }
コード例 #40
0
ファイル: PhpArray.cs プロジェクト: crazyants/peachpie
 public void SetItemValue(IntStringKey key, PhpValue value)
 {
     this.EnsureWritable();
     table._add_or_update_preserve_ref(ref key, value);
     this.KeyAdded(ref key);
 }
コード例 #41
0
ファイル: PhpString.cs プロジェクト: iolevel/peachpie
 /// <summary>
 /// Writes aliased value at given index.
 /// </summary>
 void IPhpArray.SetItemAlias(IntStringKey key, PhpAlias alias) { throw new NotSupportedException(); }
コード例 #42
0
ファイル: PhpArray.cs プロジェクト: iolevel/peachpie
 public void RemoveKey(IntStringKey key) => this.Remove(key);
コード例 #43
0
ファイル: PhpString.cs プロジェクト: iolevel/peachpie
 /// <summary>
 /// Ensures the item at given index is class object.
 /// </summary>
 object IPhpArray.EnsureItemObject(IntStringKey key) { throw new NotSupportedException(); }
コード例 #44
0
ファイル: Session.CLR.cs プロジェクト: hansdude/Phalanger
 public override bool Remove(IntStringKey key)
 {
     state.Remove(key.ToString());
     return true;
 }
コード例 #45
0
ファイル: Operators.cs プロジェクト: kaviarasankk/Phalanger
        public static DObject EnsurePropertyIsObject(DObject obj, string name, DTypeDesc caller,
            ScriptContext context)
        {
            Debug.Assert(name != null);

            if (ReferenceEquals(obj, ScriptContext.SetterChainSingletonObject))
            {
                // extend the setter chain if one already exists
                context.ExtendSetterChain(new RuntimeChainProperty(name));

                return ScriptContext.SetterChainSingletonObject;
            }

            // search in CT properties
            DPropertyDesc property;
            GetMemberResult get_res =
                obj.TypeDesc.GetProperty(new VariableName(name), caller, out property);

            if (get_res == GetMemberResult.BadVisibility)
            {
                DObject.ThrowPropertyVisibilityError(name, property, caller);
                return null;
            }

            DObject ret_val;
            object old_val, value;

            // was a CT property found?
            if (get_res == GetMemberResult.OK)
            {
                old_val = property.Get(obj);
                value = old_val;
                ret_val = EnsurePropertyIsObjectInternal(obj, name, caller, ref value, context);

                if (!Object.ReferenceEquals(value, old_val)) property.Set(obj, value);
            }
            else
            {
                // search in RT fields

                var namekey = new IntStringKey(name);
                if (obj.RuntimeFields != null && obj.RuntimeFields.TryGetValue(namekey, out old_val))
                {
                    //old_val = element.Value;
                }
                else
                {
                    PhpReference reference = new PhpSmartReference();
                    reference.IsSet = false;
                    old_val = reference;
                }

                value = old_val;
                ret_val = EnsurePropertyIsObjectInternal(obj, name, caller, ref value, context);

                if (!Object.ReferenceEquals(value, old_val))
                {
                    if (obj.RuntimeFields == null) obj.RuntimeFields = new PhpArray();
                    
                    obj.RuntimeFields[name] = value;
                }
            }

            return ret_val;
        }
コード例 #46
0
ファイル: Arrays.cs プロジェクト: iolevel/peachpie
        /// <summary>
        /// Checks if a key exists in the array.
        /// </summary>
        /// <param name="key">The key to be searched for.</param>
        /// <param name="array">The array where to search for the key.</param>
        /// <returns>Whether the <paramref name="key"/> exists in the <paramref name="array"/>.</returns>
        /// <remarks><paramref name="key"/> is converted before the search.</remarks>
        /// <exception cref="PhpException"><paramref name="array"/> argument is a <B>null</B> reference (Warning).</exception>
        /// <exception cref="PhpException"><paramref name="key"/> has type which is illegal for array key.</exception>
        public static bool array_key_exists(IntStringKey key, PhpArray array)
        {
            if (array == null)
            {
                // TODO: PhpException.ArgumentNull("array");
                return false;
            }

            return array.ContainsKey(key);

            //if (Core.Convert.ObjectToArrayKey(key, out array_key))
            //    return array.ContainsKey(array_key);

            //PhpException.Throw(PhpError.Warning, CoreResources.GetString("illegal_offset_type"));
            //return false;
        }
コード例 #47
0
ファイル: PhpArray.cs プロジェクト: crazyants/peachpie
 public void SetItemAlias(IntStringKey key, PhpAlias alias)
 {
     this.EnsureWritable();
     table._add_or_update(ref key, PhpValue.Create(alias));
     this.KeyAdded(ref key);
 }
コード例 #48
0
ファイル: Arrays.cs プロジェクト: iolevel/peachpie
 /// <summary>
 /// Alias of <see cref="array_key_exists"/>.
 /// </summary>
 public static bool key_exists(IntStringKey key, PhpArray array) => array_key_exists(key, array);
コード例 #49
0
ファイル: PhpArray.cs プロジェクト: crazyants/peachpie
 public object EnsureItemObject(IntStringKey key) => table._ensure_item_object(ref key, this);
コード例 #50
0
ファイル: PhpRuntimeChain.cs プロジェクト: dw4dev/Phalanger
		/// <summary>
		/// Creates a new <see cref="RuntimeChainItem"/> with a given key.
		/// </summary>
		public RuntimeChainItem(IntStringKey key)
		{
			this.key = key;
		}
コード例 #51
0
ファイル: PhpArray.cs プロジェクト: crazyants/peachpie
 public void RemoveKey(IntStringKey key) => this.Remove(key);
コード例 #52
0
 public PhpHashEntryDebugView(IntStringKey key, PhpValue value)
 {
     _key = key;
     _value = value;
 }
コード例 #53
0
ファイル: PhpValue.cs プロジェクト: zhangwenquan/peachpie
 public bool TryToIntStringKey(out IntStringKey key) => _type.TryToIntStringKey(ref this, out key);
コード例 #54
0
ファイル: Conversions.cs プロジェクト: iolevel/peachpie
        /// <summary>
        /// Tries conversion to an array key.
        /// </summary>
        public static bool TryToIntStringKey(PhpValue value, out IntStringKey key)
        {
            switch (value.TypeCode)
            {
                case PhpTypeCode.Int32:
                case PhpTypeCode.Long:
                case PhpTypeCode.Double:
                case PhpTypeCode.String:
                case PhpTypeCode.WritableString:
                case PhpTypeCode.Boolean:
                    key = value.ToIntStringKey();
                    return true;

                case PhpTypeCode.Alias:
                    return TryToIntStringKey(value.Alias.Value, out key);

                default:
                    key = default(IntStringKey);
                    return false;
            }
        }
コード例 #55
0
ファイル: PhpPropertyInfo.cs プロジェクト: tyty999/peachpie
 public RuntimeProperty(PhpTypeInfo tinfo, IntStringKey name)
     : base(tinfo)
 {
     _name = name;
 }
コード例 #56
0
ファイル: PhpArray.cs プロジェクト: dw4dev/Phalanger
            /// <summary>
            /// Moves to the next entry.
            /// </summary>
            /// <returns>Whether we can continue.</returns>
            public bool MoveNext()
            {
                bool hasMore;

                if (enumerator.CurrentKey.Equals(ref currentKey))
                {
                    // advance to the next position
                    hasMore = enumerator.MoveNext();
                }
                else
                {
                    hasMore = !enumerator.AtEnd;   // user deleted current entry and enumerator was already advanced to the next position
                }

                this.currentKey = enumerator.CurrentKey;

                if (!hasMore)
                    this.Dispose(); // dispose underlaying Enumerator so it can be unregistered from active enumerators list
                
                return hasMore;
            }