static bool AddVisitCode(EasyMethod m, FieldInfo field, EasyExpression var, List<CodeStatement> assertions, bool transformer) { EasyExpression prop = var.Property(GetPropertyName(field.Name)); EasyExpression nodeStack = Easy.Var("nodeStack"); if (field.FieldType.FullName.StartsWith("System.Collections.Generic.List")) { Type elType = field.FieldType.GetGenericArguments()[0]; if (!typeof(INode).IsAssignableFrom(elType)) return false; assertions.Add(AssertIsNotNull(prop)); string code; if (transformer) { code = CreateTransformerLoop(GetCode(prop), ConvertType(elType).BaseType); } else { code = "\t\t\tforeach (" + ConvertType(elType).BaseType + " o in " + GetCode(prop) + ") {\n" + "\t\t\t\tDebug.Assert(o != null);\n" + "\t\t\t\to.AcceptVisitor(this, data);\n" + "\t\t\t}"; } m.Statements.Add(new CodeSnippetStatement(code)); return true; } if (!typeof(INode).IsAssignableFrom(field.FieldType)) return false; assertions.Add(AssertIsNotNull(prop)); if (transformer) { m.Statements.Add(nodeStack.InvokeMethod("Push", prop)); } m.Statements.Add(prop.InvokeMethod("AcceptVisitor", Easy.This, Easy.Var("data"))); if (transformer) { m.Body.Assign(prop, nodeStack.InvokeMethod("Pop").CastTo(ConvertType(field.FieldType))); } return true; }
static void AddFieldVisitCode(EasyMethod m, Type type, EasyExpression var, List<CodeStatement> assertions, bool transformer) { if (type != null) { if (type.BaseType != typeof(StatementWithEmbeddedStatement)) { AddFieldVisitCode(m, type.BaseType, var, assertions, transformer); } foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) { AddVisitCode(m, field, var, assertions, transformer); } if (type.BaseType == typeof(StatementWithEmbeddedStatement)) { AddFieldVisitCode(m, type.BaseType, var, assertions, transformer); } } }