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