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); }
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; }
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); }
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; }
/// <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; }
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; }