示例#1
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);
        }
示例#2
0
        static PhpReference notsetOperation(DObject self, string name, DTypeDesc caller, PhpReference 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;
        }
示例#3
0
        static PhpReference notsetOperation(DObject self, string name, DTypeDesc caller, PhpReference 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);
        }
示例#4
0
        /// <summary>
        /// Ensures that a property value is of <see cref="DObject"/> type.
        /// </summary>
        /// <param name="obj">The object whose property is to be checked.</param>
        /// <param name="name">The property name.</param>
        /// <param name="caller"><see cref="Type"/> of the object that request the operation.</param>
        /// <param name="propValue">The property value (might get updated).</param>
        /// <param name="context">The current <see cref="ScriptContext"/>.</param>
        /// <returns>The new property value (dereferenced) or <B>null</B> if evaluation of this compound
        /// statement should not proceed.</returns>
        internal static DObject EnsurePropertyIsObjectInternal(DObject obj, string name, DTypeDesc caller, ref object propValue,
            ScriptContext context)
        {
            DObject result;
            PhpReference reference = propValue as PhpReference;

            object value;
            if (reference != null && !reference.IsSet)
            {
                // this CT property has been unset
                if (obj.TypeDesc.GetMethod(Name.SpecialMethodNames.Set) != null &&
                    obj.TypeDesc.RealType.Namespace != null &&
                    obj.TypeDesc.RealType.Namespace.StartsWith(Namespaces.Library))
                {
                    // create a chain of arguments to be passed to the setter
                    context.BeginSetterChain(obj);
                    context.ExtendSetterChain(new RuntimeChainProperty(name));

                    return ScriptContext.SetterChainSingletonObject;
                }

                // try to invoke __get
                bool getter_exists;
                reference = obj.InvokeGetterRef(name, caller, out getter_exists);
                if (!getter_exists)
                {
                    result = stdClass.CreateDefaultObject(context);
                    propValue = new PhpReference(result);
                    return result;
                }
                else if (reference == null) return null; // error

                value = reference.Value;
            }
            else value = PhpVariable.Dereference(propValue);

            // if property value is a DObject, nothing has to be done
            result = value as DObject;
            if (result != null) return result;

            // if the property is "empty"?
            if (IsEmptyForEnsure(value))
            {
                // create a new stdClass and update the reference
                result = stdClass.CreateDefaultObject(context);
                if (reference != null)
                {
                    reference.Value = result;
                    reference.IsSet = true;
                }
                else propValue = result;
                return result;
            }

            // error - the property is a scalar or a PhpArray or a non-empty string
            PhpException.VariableMisusedAsObject(value, false);
            return null;
        }
示例#5
0
        /// <summary>
        /// Ensures that a property value is of <see cref="PhpArray"/> type.
        /// </summary>
        /// <param name="obj">The object whose property is to be checked.</param>
        /// <param name="name">The property name.</param>
        /// <param name="caller"><see cref="Type"/> of the object that request the operation.</param>
        /// <param name="propValue">The property value (might get updated).</param>
        /// <returns>The new property value (dereferenced) or <B>null</B> if evaluation of this compound
        /// statement should not proceed.</returns>
        internal static PhpArray EnsurePropertyIsArrayInternal(DObject obj, string name, DTypeDesc caller, ref object propValue)
        {
            PhpArray result;
            PhpReference reference = propValue as PhpReference;

            object value;
            if (reference != null && !reference.IsSet)
            {
                // this CT property has been unset
                if (obj.TypeDesc.GetMethod(Name.SpecialMethodNames.Set) != null &&
                    obj.TypeDesc.RealType.Namespace != null &&
                    obj.TypeDesc.RealType.Namespace.StartsWith(Namespaces.Library))
                {
                    ScriptContext context = ScriptContext.CurrentContext;

                    // create a chain of arguments to be passed to the setter
                    context.BeginSetterChain(obj);
                    context.ExtendSetterChain(new RuntimeChainProperty(name));

                    return ScriptContext.SetterChainSingletonArray;
                }

                // try to invoke __get
                bool getter_exists;
                reference = obj.InvokeGetterRef(name, caller, out getter_exists);
                if (!getter_exists)
                {
                    result = new PhpArray();
                    propValue = new PhpReference(result);
                    return result;
                }
                else if (reference == null) return null; // error

                value = reference.Value;
            }
            else value = PhpVariable.Dereference(propValue);

            // try to wrap into PhpArray:
            object new_value;
            var wrappedarray = EnsureObjectIsArray(value, out new_value);
            if (wrappedarray != null)
            {
                if (new_value != null)
                {
                    if (reference != null) reference.Value = new_value;
                    else propValue = new_value;
                }
                return wrappedarray;
            }

            // error - the property is a scalar or a PhpObject:
            PhpException.VariableMisusedAsArray(value, false);
            return null;
        }
示例#6
0
        /// <summary>
        /// Ensures that a property value is of <see cref="PhpArray"/> type.
        /// </summary>
        /// <param name="obj">The object whose property is to be checked.</param>
        /// <param name="name">The property name.</param>
        /// <param name="caller"><see cref="Type"/> of the object that request the operation.</param>
        /// <param name="propValue">The property value (might get updated).</param>
        /// <returns>The new property value (dereferenced) or <B>null</B> if evaluation of this compound
        /// statement should not proceed.</returns>
        internal static PhpArray EnsurePropertyIsArrayInternal(DObject obj, string name, DTypeDesc caller, ref object propValue)
        {
            PhpArray result;
            PhpReference reference = propValue as PhpReference;

            object value;
            if (reference != null && !reference.IsSet)
            {
                // this CT property has been unset
                if (obj.TypeDesc.GetMethod(DObject.SpecialMethodNames.Set) != null &&
                    obj.TypeDesc.RealType.Namespace != null &&
                    obj.TypeDesc.RealType.Namespace.StartsWith(Namespaces.Library))
                {
                    ScriptContext context = ScriptContext.CurrentContext;

                    // create a chain of arguments to be passed to the setter
                    context.BeginSetterChain(obj);
                    context.ExtendSetterChain(new RuntimeChainProperty(name));

                    return ScriptContext.SetterChainSingletonArray;
                }

                // try to invoke __get
                bool getter_exists;
                reference = obj.InvokeGetterRef(name, caller, out getter_exists);
                if (!getter_exists)
                {
                    result = new PhpArray();
                    propValue = new PhpReference(result);
                    return result;
                }
                else if (reference == null) return null; // error

                value = reference.Value;
            }
            else value = PhpVariable.Dereference(propValue);

            // if the property is PhpArray, nothing has to be done
            result = value as PhpArray;
            if (result != null) return result;

            // checks an object behaving like an array:
            DObject dobj = value as DObject;
            if (dobj != null && dobj.RealObject is Library.SPL.ArrayAccess)
                return new Library.SPL.PhpArrayObject(dobj);

            // if the property is "empty"
            if (IsEmptyForEnsure(value))
            {
                // create a new PhpArray and update the reference
                result = new PhpArray();
                if (reference != null)
                {
                    reference.Value = result;
                    reference.IsSet = true;
                }
                else propValue = result;
                return result;
            }

            // non-empty immutable string:
            string str_value = value as string;
            if (str_value != null)
            {
                PhpString str = new PhpString(str_value);

                if (reference != null) reference.Value = str;
                else propValue = str;

                return new PhpArrayString(str);
            }

            // non-empty mutable string:
            if (value is PhpString || value is PhpBytes)
                return new PhpArrayString(value);

            // error - the property is a scalar or a PhpObject:
            PhpException.VariableMisusedAsArray(value, false);
            return null;
        }
示例#7
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;
        }