// fieldInfo - the field who's value we want // objNode - the member node corresponding to the field // out topLevelObject - the object that contains the highest level // struct. // s/b protected, stupid compiler internal static StructAccessor GetAccessorObject (IObjectNode objNode, out Object topLevelObject) { Stack structInfoStack = new Stack(); IObjectNode parentObjNode; if (TraceUtil.If(typeof(StructAccessor), TraceLevel.Info)) { TraceUtil.WriteLineInfo (typeof(StructAccessor), "GetAccessor: " + objNode.ObjectInfo.ToString() + " node: " + objNode.ToString()); } // Build up the structFields array, the fields between the // top level object and the object we want to change while (true) { parentObjNode = objNode.ParentObjectNode; if (parentObjNode == null) { throw new Exception("(bug) hit no parent when " + "looking for enclosing object " + "for a struct " + objNode); } // This is an enclosing struct, push the field // information of how to get to the child here FieldInfo fi = parentObjNode.ObjType.GetField (objNode.ObjectInfo.ObjMemberInfo.Name, ReflectionHelper.ALL_BINDINGS); if (fi == null) { throw new Exception("(bug) field " + objNode.ObjType.Name + " not found in " + parentObjNode); } structInfoStack.Push(fi); // Found the containing object, either not a value // type, or this is not a field which means it can't // be inline any more // FIXME - double check the member thing here, is this // the right level to check? if (!parentObjNode.ObjType.IsValueType || !(parentObjNode.ObjectInfo.ObjMemberInfo is FieldInfo)) { break; } // Go up objNode = parentObjNode; } // Ok, at this point, parent is the ObjectInfo for the // object that contains the top-level struct Type objType = parentObjNode.ObjType; topLevelObject = parentObjNode.Obj; if (TraceUtil.If(typeof(StructAccessor), TraceLevel.Info)) { TraceUtil.WriteLineInfo (typeof(StructAccessor), "GetAccessor - top level type/obj: " + objType + "/" + topLevelObject); } int count = structInfoStack.Count; FieldInfo[] structFields = new FieldInfo[structInfoStack.Count]; for (int i = 0; i < count; i++) { structFields[i] = (FieldInfo)structInfoStack.Pop(); } StructAccessor vtAccessor; StringBuilder keyBuilder = new StringBuilder(); String key; keyBuilder.Append(objType.FullName); keyBuilder.Append("."); foreach (FieldInfo fi in structFields) { keyBuilder.Append(fi.Name); keyBuilder.Append("."); } key = keyBuilder.ToString(); if (TraceUtil.If(typeof(StructAccessor), TraceLevel.Info)) { TraceUtil.WriteLineInfo (typeof(StructAccessor), "GetAccessor - key: " + key); } lock (typeof(StructAccessor)) { vtAccessor = (StructAccessor)_accessors[key]; if (vtAccessor != null) { return(vtAccessor); } vtAccessor = new StructAccessor(); vtAccessor.MakeAccessorClass(key, objType, structFields); _accessors.Add(key, vtAccessor); return(vtAccessor); } }
protected void InvokeInternal(ObjectInfo parent, IObjectNode objectNode, Object[] parameterValues, Object fieldPropValue, bool setMember) { if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("Start invoke: " + _objMemberInfo); if (fieldPropValue != null) { Trace.WriteLine(" fieldPropVal: " + fieldPropValue); } if (parameterValues != null) { foreach (Object pval in parameterValues) { Trace.WriteLine(" param: " + pval); } } } switch (_objMemberInfo.MemberType) { case MemberTypes.Method: { MethodInfo m = (MethodInfo)_objMemberInfo; SetObject(m.Invoke(parent._obj, parameterValues)); if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("Called: " + m + " on " + parent._obj + " return: " + _obj); } } break; case MemberTypes.Property: { PropertyInfo p = (PropertyInfo)_objMemberInfo; if (setMember) { p.SetValue(parent._obj, fieldPropValue, parameterValues); } if (p.CanRead) { SetObject(p.GetValue(parent._obj, parameterValues)); } else { // Update the new property value, if we can't // read it from the property (on a set) if (setMember) { SetObject(fieldPropValue); } } // Save these in case we need to set the property, // like with the property propogation code below objectNode.CurrentPropIndexValues = parameterValues; if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("Property: " + p + " of " + parent._obj + " value: " + _obj); } } break; case MemberTypes.Field: { FieldInfo f = (FieldInfo)_objMemberInfo; if (parent._objType.IsValueType) { // This is a struct, its handled a little // different because of the inline value type // issue if (setMember) { StructAccessor.SetValue(objectNode, fieldPropValue); } SetObject(StructAccessor.GetValue(objectNode)); } else { if (setMember) { f.SetValue(parent._obj, fieldPropValue); } SetObject(f.GetValue(parent._obj)); } if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("Field: " + f + " of " + parent._obj + " value: " + _obj); } } break; default: break; } // Everything worked, now lets handle any changes that // superiors need. if (!setMember) { return; } // If the parent member is a property, we want to do // a SetProperty on it with the current value of its object // so that the SetProperty can process the most recently // changed values. We need to do this up the line. while (true) { IObjectNode parentObjNode; parentObjNode = objectNode.ParentObjectNode; if (parentObjNode == null) { break; } // We hit an object node that has no member, we are done if (parentObjNode.ObjectInfo.ObjMemberInfo == null) { break; } // Look at enclosing property members only if (!(parentObjNode.ObjectInfo.ObjMemberInfo is PropertyInfo)) { break; } PropertyInfo propInfo = (PropertyInfo)parentObjNode.ObjectInfo.ObjMemberInfo; // Set the property try { propInfo.SetValue(parentObjNode.ParentObjectNode.Obj, parentObjNode.Obj, parentObjNode.CurrentPropIndexValues); } catch (Exception ex) { // A parent property might not have a set method // for example. TraceUtil.WriteLineInfo (this, "Exception in SetValue in property " + "propagation for prop: " + propInfo + " ex: " + ex); break; } parentObjNode.DoDisplayValue(); objectNode = parentObjNode; } }
// fieldInfo - the field who's value we want // objNode - the member node corresponding to the field // out topLevelObject - the object that contains the highest level // struct. // s/b protected, stupid compiler internal static StructAccessor GetAccessorObject (IObjectNode objNode, out Object topLevelObject) { Stack structInfoStack = new Stack(); IObjectNode parentObjNode; if (TraceUtil.If(typeof(StructAccessor), TraceLevel.Info)) { TraceUtil.WriteLineInfo (typeof(StructAccessor), "GetAccessor: " + objNode.ObjectInfo.ToString() + " node: " + objNode.ToString()); } // Build up the structFields array, the fields between the // top level object and the object we want to change while (true) { parentObjNode = objNode.ParentObjectNode; if (parentObjNode == null) { throw new Exception("(bug) hit no parent when " + "looking for enclosing object " + "for a struct " + objNode); } // This is an enclosing struct, push the field // information of how to get to the child here FieldInfo fi = parentObjNode.ObjType.GetField (objNode.ObjectInfo.ObjMemberInfo.Name, ReflectionHelper.ALL_BINDINGS); if (fi == null) { throw new Exception("(bug) field " + objNode.ObjType.Name + " not found in " + parentObjNode); } structInfoStack.Push(fi); // Found the containing object, either not a value // type, or this is not a field which means it can't // be inline any more // FIXME - double check the member thing here, is this // the right level to check? if (!parentObjNode.ObjType.IsValueType || !(parentObjNode.ObjectInfo.ObjMemberInfo is FieldInfo)) break; // Go up objNode = parentObjNode; } // Ok, at this point, parent is the ObjectInfo for the // object that contains the top-level struct Type objType = parentObjNode.ObjType; topLevelObject = parentObjNode.Obj; if (TraceUtil.If(typeof(StructAccessor), TraceLevel.Info)) { TraceUtil.WriteLineInfo (typeof(StructAccessor), "GetAccessor - top level type/obj: " + objType + "/" + topLevelObject); } int count = structInfoStack.Count; FieldInfo[] structFields = new FieldInfo[structInfoStack.Count]; for (int i = 0; i < count; i++) structFields[i] = (FieldInfo)structInfoStack.Pop(); StructAccessor vtAccessor; StringBuilder keyBuilder = new StringBuilder(); String key; keyBuilder.Append(objType.FullName); keyBuilder.Append("."); foreach (FieldInfo fi in structFields) { keyBuilder.Append(fi.Name); keyBuilder.Append("."); } key = keyBuilder.ToString(); if (TraceUtil.If(typeof(StructAccessor), TraceLevel.Info)) { TraceUtil.WriteLineInfo (typeof(StructAccessor), "GetAccessor - key: " + key); } lock (typeof(StructAccessor)) { vtAccessor = (StructAccessor)_accessors[key]; if (vtAccessor != null) return vtAccessor; vtAccessor = new StructAccessor(); vtAccessor.MakeAccessorClass(key, objType, structFields); _accessors.Add(key, vtAccessor); return vtAccessor; } }