internal void VisitChildren(object cur) { parents_.Push(new parentstate() { parent = cur, is_list = false }); parentstate ps = parents_.Peek(); foreach (var f in TreeInfo.ChildEntries(cur)) { ps.field = f; gen.Visit(this, f.GetValue(cur), true); } ps.is_list = true; foreach (var f in TreeInfo.ChildListEntries(cur)) { ps.field = f; ps.pos = 0; var enumerator = (System.Collections.IList)f.GetValue(cur); for (ps.pos = 0; ps.pos < enumerator.Count; ++ps.pos) { gen.Visit(this, enumerator[ps.pos], true); } } parents_.Pop(); }
internal void VisitChildren(object o) { foreach (object c in TreeInfo.AllChildValues(o)) { gen.Visit(this, c, true); } }
static internal Object CopyNode(object o) { object oprime = FormatterServices.GetUninitializedObject(o.GetType()); foreach (var field in TreeInfo.NonChildEntries(o)) { // value fields (e.g., strings and ints) are shared field.SetValue(oprime, field.GetValue(o)); } foreach (var field in TreeInfo.ChildEntries(o)) { field.SetValue(oprime, CopyNode(field.GetValue(o))); } foreach (var field in TreeInfo.ChildListEntries(o)) { IList newlist = (IList)Activator.CreateInstance(field.GetValue(o).GetType()); var enumerator = (System.Collections.IEnumerable)field.GetValue(o); foreach (object c in enumerator) { newlist.Add(CopyNode(c)); } field.SetValue(oprime, newlist); } return(oprime); }
public static void Check(object o, Func <object, object> gettype) { foreach (var f in TreeInfo.ChildEntries(o)) { object v = f.GetValue(o); AllowTypes[] annots = (AllowTypes[])f.GetCustomAttributes(typeof(AllowTypes), false); bool found = annots.Length == 0; for (int i = 0; i < annots.Length; ++i) { var curlist = annots[i].whichtypes; for (int j = 0; j < curlist.Count; ++j) { var t = gettype(v); if (curlist[j].Equals(t)) { found = true; break; } } if (found) { break; } } if (!found) { throw new TagException(f.Name, o.GetType().Name, gettype(v).ToString()); } MustMatchTag[] constraints = (MustMatchTag[])f.GetCustomAttributes(typeof(MustMatchTag), false); if (constraints.Length == 1) { var f2 = o.GetType().GetField(constraints[0].fieldname); var v2 = f2.GetValue(o); if (!gettype(v).Equals(gettype(v2))) { throw new TagMismatchException(f.Name, f2.Name, o.GetType().Name); } } else if (constraints.Length > 1) { throw new ArgumentOutOfRangeException(); } Check(v, gettype); } foreach (var f in TreeInfo.ChildListEntries(o)) { object v = f.GetValue(o); AllowTypes[] annots = (AllowTypes[])f.GetCustomAttributes(typeof(AllowTypes), false); var enumerator = (System.Collections.IEnumerable)f.GetValue(o); foreach (var elt in enumerator) { bool found = annots.Length == 0; for (int i = 0; i < annots.Length; ++i) { var curlist = annots[i].whichtypes; for (int j = 0; j < curlist.Count; ++j) { if (curlist[j].Equals(gettype(elt))) { found = true; break; } } if (found) { break; } } if (!found) { throw new TagException(f.Name, o.GetType().Name, gettype(elt).ToString()); } Check(elt, gettype); } } }