Beispiel #1
0
        protected override DObject EnsureItemIsObjectOverride(object key, ScriptContext /*!*/ context)
        {
            IntStringKey array_key;

            if (!Convert.ObjectToArrayKey(key, out array_key))
            {
                PhpException.IllegalOffsetType();
                context.AbortSetterChain(true);
                return(null);
            }

            // extend the setter chain if one already exists
            context.ExtendSetterChain(new RuntimeChainItem(array_key));

            return(ScriptContext.SetterChainSingletonObject);
        }
Beispiel #2
0
        protected override void SetArrayItemOverride(object key, object value)
        {
            IntStringKey  array_key;
            ScriptContext context = ScriptContext.CurrentContext;             // TODO: context -> field

            // extend and finish the setter chain if one already exists
            if (!Convert.ObjectToArrayKey(key, out array_key))
            {
                PhpException.IllegalOffsetType();
                context.AbortSetterChain(true);
                return;
            }

            context.ExtendSetterChain(new RuntimeChainItem(array_key));
            context.FinishSetterChain(value);
            return;
        }
Beispiel #3
0
        protected override PhpArray EnsureItemIsArrayOverride(object key)
        {
            ScriptContext context = ScriptContext.CurrentContext;

            IntStringKey array_key;

            if (!Convert.ObjectToArrayKey(key, out array_key))
            {
                PhpException.IllegalOffsetType();
                context.AbortSetterChain(true);
                return(null);
            }

            // extend the setter chain if one already exists:
            context.ExtendSetterChain(new RuntimeChainItem(array_key));

            return(this);
        }
Beispiel #4
0
        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;
        }
Beispiel #5
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;
        }
Beispiel #6
0
        protected override DObject EnsureItemIsObjectOverride(object key, ScriptContext/*!*/ context)
		{
			IntStringKey array_key;

			if (!Convert.ObjectToArrayKey(key, out array_key))
			{
				PhpException.IllegalOffsetType();
				context.AbortSetterChain(true);
				return null;
			}
			
			// extend the setter chain if one already exists
			context.ExtendSetterChain(new RuntimeChainItem(array_key));

			return ScriptContext.SetterChainSingletonObject;

		}