public void BuildTraveller()
        {
            if (_classBuilder.IsSealed)
            {
                throw new InvalidOperationException("Classification builder is sealed");
            }
            var target          = _typeProvider.GetOrCreate(_type);
            var members         = _dtContext.Members;
            var factoryArgument = new ILArgPointer(members.VisitArgsFactoryType, 1);


            var childTravellers = new Dictionary <Type, ChildTravellerInfo>();
            var argFields       = new Dictionary <SerializableProperty, FieldInfo>();

            var il             = _constructorBuilder.IL;
            var travellerIndex = 0;

            foreach (var property in target.Properties)
            {
                var argField      = _classBuilder.DefinePrivateField("_arg" + property.Ref.Name, members.VisitArgsType);
                var visitArgsCode = new ILCallMethodSnippet(factoryArgument, members.ConstructVisitArgsMethod, property.Ref.Name);
                il.Set(ILPointer.This(), argField, visitArgsCode);
                argFields.Add(property, argField);

                if (!ReflectionAnalyzer.TryGetComplexTypes(property.Ext, out var types))
                {
                    continue;
                }

                foreach (var type in types)
                {
                    if (childTravellers.ContainsKey(type))
                    {
                        continue;
                    }

                    var dynamicTraveller = _dtContext.Get(type);
                    var interfaceType    = typeof(IGraphTraveller <>).MakeGenericType(type);
                    var fieldBuilder     = _classBuilder.DefinePrivateField(string.Concat("_traveller", type.Name, ++travellerIndex), interfaceType);
                    childTravellers.Add(type, new ChildTravellerInfo {
                        Field             = fieldBuilder,
                        TravelWriteMethod = dynamicTraveller.TravelWriteMethod,
                        TravelReadMethod  = dynamicTraveller.TravelReadMethod
                    });

                    var getFactoryCode = ILSnippet.Call(factoryArgument, members.ConstructVisitArgsWithTypeMethod, type);
                    var newTraveller   = ILPointer.New(dynamicTraveller.Constructor, getFactoryCode);
                    il.Set(ILPointer.This(), fieldBuilder, newTraveller);
                }
            }
            il.Emit(OpCodes.Ret);

            var context = new TravellerContext(childTravellers, argFields);

            BuildWriteMethods(target, context);
            BuildReadMethods(target, context);

            _classBuilder.Seal();
            DynamicTraveller.Complete(_classBuilder.Type);
        }
Example #2
0
        public void IterateList()
        {
            var mt   = new DynamicMethod("Test$" + Guid.NewGuid(), typeof(string), new [] { typeof(List <string>) });
            var il   = mt.GetILGenerator();
            var list = ILPointer.Arg(0, typeof(List <string>));

            var concatMethod = typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) });
            var res          = il.NewLocal(typeof(string));

            il.Enumerate(list, cur => il.Set(res, ILSnippet.Call(concatMethod, res, cur)));
            il.Load(res);
            il.Emit(OpCodes.Ret);
            var m = (Func <List <string>, string>)mt.CreateDelegate(typeof(Func <List <string>, string>));

            Assert.Equal("HelloWorld", m.Invoke(new List <string> {
                "Hello", "World"
            }));
        }
Example #3
0
 public static ILPointer Call(this ILPointer instance, string methodName, params ILPointer[] parameters)
 {
     return(ILSnippet.Call(instance, methodName, parameters));
 }
Example #4
0
 public static ILPointer Call(this ILPointer instance, MethodInfo method, params ILPointer[] parameters)
 {
     return(ILSnippet.Call(instance, method, parameters));
 }