private void GenerateEnumerateCollectionContentCode(ExtendedType target, ILPointer collectionParameter)
        {
            if (target.TryGetArrayTypeInfo(out var arrayTypeInfo) && arrayTypeInfo.Ranks > 1)
            {
                if (arrayTypeInfo.Ranks > 3)
                {
                    throw new NotSupportedException("The serialization engine is limited to 3 ranks in arrays");
                }

                _il.ForLoop(0, new ILCallMethodSnippet(collectionParameter, Members.ArrayGetLength, 0), 1,
                            r0 => {
                    _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, collectionParameter, Members.VisitArgsCollectionInCollection);
                    _il.ForLoop(0, new ILCallMethodSnippet(collectionParameter, Members.ArrayGetLength, 1), 1,
                                r1 => {
                        if (arrayTypeInfo.Ranks > 2)
                        {
                            _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, collectionParameter, Members.VisitArgsCollectionInCollection);

                            _il.ForLoop(0, new ILCallMethodSnippet(collectionParameter, Members.ArrayGetLength, 1), 1,
                                        r2 => GenerateEnumerateContentCode(
                                            new ILCallMethodSnippet(collectionParameter, target.Info.GetMethod("Get"), r0, r1, r2),
                                            LevelType.CollectionItem));

                            _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, collectionParameter, Members.VisitArgsCollectionInCollection);
                        }
                        else
                        {
                            GenerateEnumerateContentCode(new ILCallMethodSnippet(collectionParameter, target.Info.GetMethod("Get"), r0, r1), LevelType.CollectionItem);
                        }
                    });
                    _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, collectionParameter, Members.VisitArgsCollectionInCollection);
                });
            }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        private Action <TInstance, object[]> GetPropertySetter(PropertyInfo[] properties, ITypeProvider provider)
        {
            var type = typeof(TInstance);

            var methodName = string.Concat(
                "D$PropertySetter$",
                type.FullName.Replace(".", "_"),
                "$",
                Guid.NewGuid());

            var method = new DynamicMethod(methodName, typeof(void), new[] { type, typeof(object[]) });

            var il       = method.GetILGenerator();
            var instance = ILPointer.Arg(0, type);
            var props    = ILPointer.Arg(1, typeof(object[]));

            for (var i = 0; i < properties.Length; i++)
            {
                var property = properties[i];
                var value    = props
                               .ElementAt(i)
                               .Cast(property.PropertyType);

                il.Set(instance, property, value);
            }
            il.Emit(OpCodes.Ret);

            return((Action <TInstance, object[]>)
                   method.CreateDelegate(typeof(Action <TInstance, object[]>)));
        }
 public DynamicWriteTravellerBuilder(MethodBuilder builder, SerializableType target, TravellerContext context, ITypeProvider typeProvider)
 {
     _target          = target;
     _context         = context;
     _typeProvider    = typeProvider;
     _il              = builder.IL;
     _visitorVariable = new ILArgPointer(typeof(IWriteVisitor), 1);
 }
        private void GenerateDictionaryCode(ILVariable dictionary, Type elementType)
        {
            var elementTypeInfo = elementType.GetTypeInfo();

            _il.Enumerate(dictionary, it => {
                GenerateEnumerateContentCode(ILPointer.Property(it, elementTypeInfo.GetProperty("Key")), LevelType.DictionaryKey);
                GenerateEnumerateContentCode(ILPointer.Property(it, elementTypeInfo.GetProperty("Value")), LevelType.DictionaryValue);
            });
        }
        private void GenerateEnumerateContentCode(ILPointer valueParam, LevelType level)
        {
            var type    = valueParam.Type;
            var extType = _typeProvider.Extend(type);

            var visitArgs = GetContentVisitArgs(extType, level);

            if (extType.IsValueOrNullableOfValue())
            {
                _il.InvokeMethod(_visitorVariable, Members.VisitorVisitValue[type], valueParam.AsNullable(), visitArgs);
            }
            else if (extType.Classification == TypeClassification.Dictionary)
            {
                var container   = extType.Container.AsDictionary();
                var elementType = container.ElementType;

                var dictionaryType = container.DictionaryInterfaceType;

                var dictionaryLocal = _il.NewLocal(dictionaryType);
                _il.Set(dictionaryLocal, valueParam.Cast(dictionaryType));

                _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, dictionaryLocal, visitArgs);

                var elementTypeInfo = elementType.GetTypeInfo();
                _il.Enumerate(dictionaryLocal, it => {
                    GenerateEnumerateContentCode(ILPointer.Property(it, elementTypeInfo.GetProperty("Key")), LevelType.DictionaryKey);
                    GenerateEnumerateContentCode(ILPointer.Property(it, elementTypeInfo.GetProperty("Value")), LevelType.DictionaryValue);
                });

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, dictionaryLocal, visitArgs);
            }
            else if (extType.Classification == TypeClassification.Collection)
            {
                var container      = extType.Container.AsCollection();
                var collectionType = type.IsArray && extType.Container.AsArray().Ranks > 1
                    ? type
                    : container.CollectionInterfaceType;

                var collectionLocal = _il.NewLocal(collectionType);
                _il.Set(collectionLocal, valueParam.Cast(collectionType));

                _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, collectionLocal, visitArgs);

                GenerateEnumerateCollectionContentCode(extType, collectionLocal);

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, collectionLocal, visitArgs);
            }
            else
            {
                _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, valueParam, visitArgs);

                GenerateChildCall(valueParam);

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, valueParam, visitArgs);
            }
        }
Exemplo n.º 7
0
        public void CreateTestClassInstance()
        {
            var mt       = new DynamicMethod("Test$" + Guid.NewGuid(), typeof(string), Type.EmptyTypes);
            var il       = mt.GetILGenerator();
            var instance = ILPointer.New(EmitTestClass.ConstructorInfo, "Hello World");
            var property = ILPointer.Property(instance, typeof(IEmitTest).GetProperty("Message"));

            il.Load(property);
            il.Emit(OpCodes.Ret);
            var m = (Func <string>)mt.CreateDelegate(typeof(Func <string>));

            Assert.Equal("Hello World", m.Invoke());
        }
Exemplo n.º 8
0
        public static ILAddPointer Add(this IILPointer left, ILPointer right)
        {
            if (left == null)
            {
                throw new ArgumentNullException(nameof(left));
            }
            if (right == null)
            {
                throw new ArgumentNullException(nameof(right));
            }

            return(new ILAddPointer(left, right));
        }
Exemplo n.º 9
0
        public static ILEqualPointer Equal(this IILPointer left, ILPointer right)
        {
            if (left == null)
            {
                left = ILPointer.Null;
            }
            if (right == null)
            {
                right = ILPointer.Null;
            }

            return(new ILEqualPointer(left, right));
        }
Exemplo n.º 10
0
        public DynamicReadTravellerMembers(ITypeProvider provider)
        {
            var visitArgsType = typeof(VisitArgs).GetTypeInfo();

            VisitArgsCollectionItem              = new ILStaticFieldVariable(visitArgsType.GetField("CollectionItem"));
            VisitArgsDictionaryKey               = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryKey"));
            VisitArgsDictionaryValue             = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryValue"));
            VisitArgsCollectionInCollection      = new ILStaticFieldVariable(visitArgsType.GetField("CollectionInCollection"));
            VisitArgsDictionaryInCollection      = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryInCollection"));
            VisitArgsDictionaryInDictionaryKey   = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryInDictionaryKey"));
            VisitArgsDictionaryInDictionaryValue = new ILStaticFieldVariable(visitArgsType.GetField("DictionaryInDictionaryValue"));
            VisitArgsCollectionInDictionaryKey   = new ILStaticFieldVariable(visitArgsType.GetField("CollectionInDictionaryKey"));
            VisitArgsCollectionInDictionaryValue = new ILStaticFieldVariable(visitArgsType.GetField("CollectionInDictionaryValue"));

            var readVisitorType = typeof(IReadVisitor).GetTypeInfo();

            VisitorTryVisit = readVisitorType.GetMethod("TryVisit");
            VisitorLeave    = readVisitorType.GetMethod("Leave");

            VisitorTryVisitValue = new Dictionary <Type, MethodInfo>();
            Nullable             = new Dictionary <Type, NullableMembers>();

            foreach (var method in readVisitorType.GetMethods()
                     .Where(m => m.Name == "TryVisitValue"))
            {
                var valueType = method.GetParameters()[1].ParameterType;
                if (valueType.IsByRef)
                {
                    valueType = valueType.GetElementType();
                }
                var valueTypeExt = provider.Extend(valueType);

                VisitorTryVisitValue.Add(valueType, method);
                if (valueTypeExt.Classification == TypeClassification.Nullable)
                {
                    var innerType = valueTypeExt.Container.AsNullable().ElementType;
                    VisitorTryVisitValue.Add(innerType, method);

                    var nullableMembers = new NullableMembers(innerType);
                    Nullable.Add(innerType, nullableMembers);
                    Nullable.Add(valueType, nullableMembers);
                }
            }

            EnumeratorMoveNext = typeof(IEnumerator).GetTypeInfo().GetMethod("MoveNext");
            DisposableDispose  = typeof(IDisposable).GetTypeInfo().GetMethod("Dispose");

            ExceptionNoDictionaryValue = typeof(InvalidGraphException).GetTypeInfo().GetMethod("NoDictionaryValue");
        }
Exemplo n.º 11
0
        public DynamicWriteTravellerMembers(ITypeProvider provider)
        {
            var visitArgsType     = typeof(VisitArgs);
            var visitArgsTypeInfo = visitArgsType.GetTypeInfo();

            VisitArgsCollectionItem              = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("CollectionItem"));
            VisitArgsDictionaryKey               = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("DictionaryKey"));
            VisitArgsDictionaryValue             = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("DictionaryValue"));
            VisitArgsCollectionInCollection      = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("CollectionInCollection"));
            VisitArgsDictionaryInCollection      = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("DictionaryInCollection"));
            VisitArgsDictionaryInDictionaryKey   = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("DictionaryInDictionaryKey"));
            VisitArgsDictionaryInDictionaryValue = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("DictionaryInDictionaryValue"));
            VisitArgsCollectionInDictionaryKey   = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("CollectionInDictionaryKey"));
            VisitArgsCollectionInDictionaryValue = new ILStaticFieldVariable(visitArgsTypeInfo.GetField("CollectionInDictionaryValue"));

            var writeVisitorType     = typeof(IWriteVisitor);
            var writeVisitorTypeInfo = writeVisitorType.GetTypeInfo();

            VisitorVisit = writeVisitorTypeInfo.GetMethod("Visit");
            VisitorLeave = writeVisitorTypeInfo.GetMethod("Leave");

            VisitorVisitValue    = new Dictionary <Type, MethodInfo>();
            NullableConstructors = new Dictionary <Type, ConstructorInfo>();
            var nullableType = typeof(Nullable <>);

            foreach (var method in writeVisitorTypeInfo.GetMethods()
                     .Where(m => m.Name == "VisitValue"))
            {
                var valueType    = method.GetParameters()[0].ParameterType;
                var valueTypeExt = provider.Extend(valueType);

                VisitorVisitValue.Add(valueType, method);
                if (valueTypeExt.Classification == TypeClassification.Nullable)
                {
                    var innerType = valueTypeExt.Container.AsNullable().ElementType;
                    VisitorVisitValue.Add(innerType, method);

                    var nullableTypeInfo = nullableType.MakeGenericType(innerType).GetTypeInfo();
                    NullableConstructors.Add(innerType, nullableTypeInfo.GetConstructor(new [] { innerType }));
                }
            }

            EnumeratorMoveNext = typeof(IEnumerator).GetTypeInfo().GetMethod("MoveNext");
            DisposableDispose  = typeof(IDisposable).GetTypeInfo().GetMethod("Dispose");
            ArrayGetLength     = typeof(Array).GetTypeInfo().GetMethod("GetLength");
        }
Exemplo n.º 12
0
        private void BuildReadMethods(SerializableType target, TravellerContext context)
        {
            var typedMethodBuilder = _travelReadMethod;
            var readBuilder        = new DynamicReadTravellerBuilder(typedMethodBuilder, target, context, _typeProvider.Provider);

            readBuilder.BuildTravelReadMethod();

            var untypedMethodBuilder = _classBuilder.DefineOverloadMethod("Travel", typeof(void), new[] { typeof(IReadVisitor), typeof(object) });
            var il = untypedMethodBuilder.IL;

            il.InvokeMethod(ILPointer.This(),
                            typedMethodBuilder.Method,
                            ILPointer.Arg(1, typeof(IReadVisitor)),
                            ILPointer.Arg(2, typeof(object)).Cast(target.Type));

            il.Emit(OpCodes.Ret);
        }
Exemplo n.º 13
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"
            }));
        }
Exemplo n.º 14
0
        private void GenerateLoadParamValueCode(ILPointer param)
        {
            var type    = param.Type;
            var extType = _typeProvider.Extend(type);

            if (extType.Classification == TypeClassification.Nullable)
            {
                type = extType.Container.AsNullable().ElementType;
            }

            if (extType.Info.IsValueType)
            {
                _il.InvokeMethod(param, Members.Nullable[type].GetValue);
            }
            else
            {
                _il.Load(param);
            }
        }
Exemplo n.º 15
0
        public DynamicTravellerBuilder(DynamicTravellerContext dtContext, ClassBuilder classBuilder, SerializableTypeProvider typeProvider, Type type)
        {
            _dtContext          = dtContext;
            _classBuilder       = classBuilder;
            _typeProvider       = typeProvider;
            _type               = type;
            _constructorBuilder = _classBuilder.DefineConstructor(typeof(IVisitArgsFactory));

            var baseConstructor = typeof(object).GetTypeInfo().GetConstructor(Type.EmptyTypes);
            var il = _constructorBuilder.IL;

            il.Load(ILPointer.This());
            il.Emit(OpCodes.Call, baseConstructor);

            _travelWriteMethod = _classBuilder.DefineOverloadMethod("Travel", typeof(void), new[] { typeof(IWriteVisitor), _type });
            _travelReadMethod  = _classBuilder.DefineOverloadMethod("Travel", typeof(void), new[] { typeof(IReadVisitor), _type });

            DynamicTraveller = new DynamicTraveller(_classBuilder.Type, _constructorBuilder.Reference, _travelWriteMethod.Method, _travelReadMethod.Method, dtContext.Members);
        }
Exemplo n.º 16
0
        public DynamicActivator(ConstructorInfo constructor, ITypeProvider provider)
        {
            if (constructor == null)
            {
                throw new ArgumentNullException(nameof(constructor));
            }
            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }
            Type = constructor.DeclaringType;

            var methodName = string.Concat(
                "D$Activator$",
                Type.FullName.Replace(".", "_"),
                "$",
                constructor.GetParameters().Length,
                Guid.NewGuid());
            var method = new DynamicMethod(methodName, typeof(object), DynConstructorTypes);

            var il           = method.GetILGenerator();
            var methodParams = ILPointer.Arg(0, typeof(object[]));

            var parameters = constructor.GetParameters();

            var constructParameters = new ILPointer[parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                var parameter      = parameters[i];
                var constructParam = methodParams
                                     .ElementAt(i)
                                     .Cast(parameter.ParameterType);

                constructParameters[i] = constructParam;
            }

            il.Construct(constructor, constructParameters);
            il.Emit(OpCodes.Ret);

            _activate = (Func <object[], object>)
                        method.CreateDelegate(typeof(Func <object[], object>));
        }
Exemplo n.º 17
0
        private void GenerateCreateAndChildCallCode(ILLocalVariable local)
        {
            var type = local.Type;

            var constructor = type.GetTypeInfo().GetConstructor(Type.EmptyTypes);

            if (constructor == null)
            {
                throw InvalidGraphException.NoParameterLessConstructor(type);
            }

            _il.Construct(constructor);
            _il.Set(local);

            var childTravellerInfo = _context.GetTraveller(type);

            var field = ILPointer.Field(ILPointer.This(), childTravellerInfo.Field);

            _il.InvokeMethod(field, childTravellerInfo.TravelReadMethod, _visitorVariable, local);
        }
Exemplo n.º 18
0
        private void GeneratePropertyCode(ILArgPointer graphArg, SerializableProperty target)
        {
            var extPropertyType   = target.Ext;
            var argsField         = _context.GetArgsField(target);
            var argsFieldVariable = ILPointer.Field(ILPointer.This(), argsField);

            if (extPropertyType.IsValueOrNullableOfValue())
            {
                var isNullable  = extPropertyType.Classification == TypeClassification.Nullable;
                var isEnum      = extPropertyType.IsEnum();
                var isValueType = extPropertyType.Info.IsValueType;

                var mediatorPropertyType = isEnum ? extPropertyType.GetUnderlyingEnumType() : extPropertyType.Ref;
                var valueType            = !isNullable && isValueType ? Members.Nullable[mediatorPropertyType].NullableType : mediatorPropertyType;

                var valueLocal = _il.NewLocal(valueType);

                _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisitValue[valueType], argsFieldVariable, valueLocal);

                if (isValueType && !isNullable)
                {
                    var labelValueNotFound = _il.NewLabel();
                    labelValueNotFound.TransferLongIfFalse();

                    _il.Load(valueLocal
                             .Call(Members.Nullable[mediatorPropertyType].GetHasValue)
                             .Negate());

                    var nullableHasValueLabel = _il.NewLabel();
                    nullableHasValueLabel.TransferLong();

                    labelValueNotFound.Mark();
                    _il.Load(true);
                    nullableHasValueLabel.Mark();
                }
                else
                {
                    _il.Negate();
                }

                var skipSetValueLabel = _il.NewLabel();
                skipSetValueLabel.TransferLongIfTrue();

                var valueToAdd = isValueType && !isNullable
                    ? valueLocal.Call(Members.Nullable[mediatorPropertyType].GetValue)
                    : valueLocal;

                _il.Set(graphArg, target.Ref, valueToAdd);

                skipSetValueLabel.Mark();
            }
            else if (extPropertyType.Classification == TypeClassification.Dictionary)
            {
                var stateLocal = _il.NewLocal(typeof(ValueState));
                _il.Set(stateLocal, _visitorVariable.Call(Members.VisitorTryVisit, argsFieldVariable));

                var endLabel = _il.NewLabel();
                endLabel.TransferLongIfTrue(stateLocal.Equal((int)ValueState.NotFound));

                _il.AreEqual(stateLocal, (int)ValueState.Found);

                var nullLabel = _il.NewLabel();
                nullLabel.TransferLongIfFalse();

                var dictionaryLocal = GenerateDictionaryEnumerateCode(target.Ref.PropertyType, target.Ref.Name);

                _il.Set(graphArg, target.Ref, dictionaryLocal.Cast(target.Ref.PropertyType));

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, argsFieldVariable);

                endLabel.TransferLong();

                nullLabel.Mark();
                _il.Set(graphArg, target.Ref, null);

                endLabel.Mark();
            }
            else if (extPropertyType.Classification == TypeClassification.Collection)
            {
                _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisit, argsFieldVariable);
                var stateLocal = _il.NewLocal(typeof(ValueState));
                _il.Set(stateLocal);

                _il.AreEqual(stateLocal, (int)ValueState.NotFound);

                var endLabel = _il.NewLabel();
                endLabel.TransferLongIfTrue();

                _il.AreEqual(stateLocal, (int)ValueState.Found);

                var nullLabel = _il.NewLabel();
                nullLabel.TransferLongIfFalse();

                var collectionParam = GenerateCollectionContent(extPropertyType, target.Ref.Name);

                _il.Set(graphArg, target.Ref, collectionParam);
                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, argsFieldVariable);
                endLabel.TransferLong();

                nullLabel.Mark();
                _il.Set(graphArg, target.Ref, null);

                endLabel.Mark();
            }
            else
            {
                _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisit, argsFieldVariable);
                var stateLocal = _il.NewLocal(typeof(ValueState));
                _il.Set(stateLocal);

                _il.IfNotEqual(stateLocal, (int)ValueState.NotFound)
                .Then(() => {
                    _il.IfEqual(stateLocal, (int)ValueState.Found)
                    .Then(() => {
                        var singleLocal = _il.NewLocal(extPropertyType.Ref);
                        GenerateCreateAndChildCallCode(singleLocal);

                        _il.Set(graphArg, target.Ref, singleLocal);
                        _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, argsFieldVariable);
                    }).Else(() => {
                        _il.Set(graphArg, target.Ref, null);
                    }).End();
                }).End();
            }
        }
Exemplo n.º 19
0
        private ILPointer GenerateCollectionContent(ExtendedType target, string refName)
        {
            var collectionMembers = new CollectionMembers(target);
            var isValueType       = collectionMembers.ElementType.GetTypeInfo().IsValueType;

            var collectionLocal = _il.NewLocal(collectionMembers.VariableType);
            var collection      = ILPointer.New(collectionMembers.Constructor)
                                  .Cast(collectionMembers.VariableType);

            _il.Set(collectionLocal, collection);

            var valueLocal = DeclareCollectionItemLocal(collectionMembers.ElementType);;

            if (collectionMembers.ElementTypeExt.IsValueOrNullableOfValue())
            {
                _il.WhileLoop(il => { // While condition
                    _il.InvokeMethod(_visitorVariable, Members.VisitorTryVisitValue[collectionMembers.ElementType], Members.VisitArgsCollectionItem, valueLocal);

                    var valueNotFoundLabel = _il.NewLabel();
                    valueNotFoundLabel.TransferLongIfFalse();

                    if (isValueType)
                    {
                        _il.InvokeMethod(valueLocal, Members.Nullable[collectionMembers.ElementType].GetHasValue);
                    }
                    else
                    {
                        _il.AreEqual(valueLocal, ILPointer.Null);
                        _il.Negate();
                    }

                    var isNullLabel = _il.NewLabel();
                    isNullLabel.TransferLong();

                    valueNotFoundLabel.Mark();
                    _il.Load(0);
                    isNullLabel.Mark();
                }, il => {
                    _il.Load(collectionLocal);

                    GenerateLoadParamValueCode(valueLocal);

                    _il.EmitCall(OpCodes.Callvirt, collectionMembers.Add, null);
                });
            }
            else if (collectionMembers.ElementTypeExt.Classification == TypeClassification.Dictionary)
            {
                _il.WhileLoop(il => { // Condition
                    var callTryVisit = new ILCallMethodSnippet(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsDictionaryInCollection);
                    _il.AreEqual(callTryVisit, (int)ValueState.Found);
                }, il => {
                    var contentParam = GenerateDictionaryEnumerateCode(collectionMembers.ElementType, refName);
                    _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsDictionaryInCollection);
                    _il.InvokeMethod(collectionLocal, collectionMembers.Add, contentParam);
                });
            }
            else if (collectionMembers.ElementTypeExt.Classification == TypeClassification.Collection)
            {
                _il.WhileLoop(il => { // Condition
                    var callTryVisit = new ILCallMethodSnippet(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsCollectionInCollection);
                    _il.AreEqual(callTryVisit, (int)ValueState.Found);
                }, il => {
                    var contentParam = GenerateCollectionContent(collectionMembers.ElementTypeExt, refName);
                    _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsCollectionInCollection);
                    _il.InvokeMethod(collectionLocal, collectionMembers.Add, contentParam);
                });
            }
            else
            {
                _il.WhileLoop(il => {
                    var callTryVisit = new ILCallMethodSnippet(_visitorVariable, Members.VisitorTryVisit, Members.VisitArgsCollectionItem);
                    _il.AreEqual(callTryVisit, (int)ValueState.Found);
                }, il => {
                    GenerateCreateAndChildCallCode(valueLocal);
                    _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, Members.VisitArgsCollectionItem);
                    _il.InvokeMethod(collectionLocal, collectionMembers.Add, valueLocal);
                });
            }
            if (target.Ref.IsArray)
            {
                return(new ILCallMethodSnippet(collectionMembers.ToArray, collectionLocal));
            }

            return(collectionLocal);
        }
Exemplo n.º 20
0
        private void GeneratePropertyCode(ILPointer graphPointer, SerializableProperty target)
        {
            var extPropertyType   = target.Ext;
            var argsField         = _context.GetArgsField(target);
            var argsFieldVariable = ILPointer.Field(ILPointer.This(), argsField);

            if (target.Ext.IsValueOrNullableOfValue())
            {
                var valueType = target.Ext.IsEnum()
                    ? target.Ext.GetUnderlyingEnumType()
                    : target.Ref.PropertyType;

                var propertyParameter = ILPointer.Property(graphPointer, target.Ref).AsNullable();

                _il.InvokeMethod(_visitorVariable, Members.VisitorVisitValue[valueType], propertyParameter, argsFieldVariable);
            }
            else if (extPropertyType.Classification == TypeClassification.Dictionary)
            {
                var container = extPropertyType.Container.AsDictionary();

                var dictionaryType = container.DictionaryInterfaceType;
                var cLocal         = _il.NewLocal(dictionaryType);
                _il.Set(cLocal, ILPointer.Property(graphPointer, target.Ref).Cast(dictionaryType));

                _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, cLocal, argsFieldVariable);

                _il.IfNotEqual(cLocal, null)
                .Then(() => GenerateDictionaryCode(cLocal, container.ElementType))
                .End();

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, cLocal, argsFieldVariable);
            }
            else if (extPropertyType.Classification == TypeClassification.Collection)
            {
                var container = extPropertyType.Container.AsCollection();

                var collectionType = extPropertyType.Ref.IsArray && extPropertyType.Container.AsArray().Ranks > 1
                    ? extPropertyType.Ref
                    : container.CollectionInterfaceType;

                var cLocal = _il.NewLocal(collectionType);

                _il.Set(cLocal, ILPointer.Property(graphPointer, target.Ref).Cast(collectionType));

                _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, cLocal, argsFieldVariable);

                _il.IfNotEqual(cLocal, null)
                .Then(() => GenerateEnumerateCollectionContentCode(extPropertyType, cLocal))
                .End();

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, cLocal, argsFieldVariable);
            }
            else
            {
                var singleLocal = _il.NewLocal(target.Ref.PropertyType);
                _il.Set(singleLocal, ILPointer.Property(graphPointer, target.Ref));

                _il.InvokeMethod(_visitorVariable, Members.VisitorVisit, singleLocal, argsFieldVariable);

                var checkIfNullLabel = _il.NewLabel();
                checkIfNullLabel.TransferIfNull(singleLocal);

                GenerateChildCall(singleLocal);

                checkIfNullLabel.Mark();

                _il.InvokeMethod(_visitorVariable, Members.VisitorLeave, singleLocal, argsFieldVariable);
            }
        }
Exemplo n.º 21
0
 public static ILPointer AsNullable(this ILPointer parameter)
 {
     return(new ILNullablePointer(parameter));
 }
Exemplo n.º 22
0
 public static ILPointer Cast(this ILPointer parameter, Type toType)
 {
     return(new ILCastPointer(parameter, toType));
 }
Exemplo n.º 23
0
 public static ILPointer Call(this ILPointer instance, MethodInfo method, params ILPointer[] parameters)
 {
     return(ILSnippet.Call(instance, method, parameters));
 }
Exemplo n.º 24
0
 public static ILPointer Call(this ILPointer instance, string methodName, params ILPointer[] parameters)
 {
     return(ILSnippet.Call(instance, methodName, parameters));
 }