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

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

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

                                    _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, collectionParameter, Members.VisitArgsCollectionInCollection);
                                }
                                else {
                                    GenerateEnumerateContentCode(new CallMethodILCode(collectionParameter, target.Ref.GetMethod("Get"), r0, r1), LevelType.CollectionItem);
                                }
                            });
                        _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, collectionParameter, Members.VisitArgsCollectionInCollection);
                    });
            }
            else {
                var part = new ILEnumerateCode(collectionParameter, (il, it) => GenerateEnumerateContentCode(it, LevelType.CollectionItem));
                _il.Generate(part);
            }
        }
        private void GenerateChildCall(ILCodeParameter child)
        {
            var childTravellerInfo = _context.GetTraveller(child.ParameterType);

            var field = _il.Var.Field(_il.Var.This(), childTravellerInfo.Field);
            _il.Snippets.InvokeMethod(field, childTravellerInfo.TravelWriteMethod, _visitorVariable, child);
        }
Пример #3
0
 public void ForLoop(ILCodeParameter initialValue, ILCodeParameter lesserThan, ILCodeParameter increment, ILGenerationHandler<ILCodeParameter> body)
 {
     var loop = new ForLoopILCode(initialValue, value => {
         _il.Var.Load(value);
         _il.Var.Load(lesserThan);
         _il.Gen.Emit(OpCodes.Clt);
     }, body, increment);
     _il.Generate(loop);
 }
Пример #4
0
        public void AreEqual(ILCodeParameter left, ILCodeParameter right)
        {
            if (left == null) left = ILCodeParameter.Null;
            if (right == null) right = ILCodeParameter.Null;

            ((IILCodeParameter) left).Load(_il);
            ((IILCodeParameter) right).Load(_il);
            _il.CompareEquals();
        }
Пример #5
0
        public void Increment(ILCodeVariable value, ILCodeParameter valueToAdd)
        {
            if (value == null) throw new ArgumentNullException("value");
            if (valueToAdd == null) throw new ArgumentNullException("valueToAdd");

            _il.Var.Load(value);
            ((IILCodeParameter) valueToAdd).Load(_il);
            _il.Gen.Emit(OpCodes.Add);
            _il.Var.Set(value);
        }
Пример #6
0
        public ForLoopILCode(ILCodeParameter initialValue, ILGenerationHandler<ILCodeParameter> conditionHandler,
            ILGenerationHandler<ILCodeParameter> bodyHandler, ILCodeParameter increment)
        {
            if (initialValue.ParameterType != increment.ParameterType)
                throw new ArgumentException("The type of the initial value and the increment value must match");

            _initialValue = initialValue;
            _increment = increment;
            _conditionHandler = new DelegatedILHandler<ILCodeParameter>(conditionHandler);
            _bodyHandler = new DelegatedILHandler<ILCodeParameter>(bodyHandler);
        }
Пример #7
0
        public CallMethodILCode(ILCodeParameter instance, MethodInfo method, params ILCodeParameter[] parameters)
        {
            if (instance == null && !method.IsStatic)
                throw new ArgumentException("Instance must be provided for instance methods");
            if (instance != null && method.IsStatic)
                throw new ArgumentException("Static method may not be invoked with an instance");

            _methodParameters = method.GetParameters();

            if (_methodParameters.Length < parameters.Length)
                throw new ArgumentException("The parameter length supplied is greater than the method supports");

            _instance = instance;
            _method = method;
            _parameters = parameters;
            _returnType = method.ReturnType;
        }
        public DynamicReadTravellerMembers()
        {
            var visitArgsType = typeof(VisitArgs);
            VisitArgsCollectionItem = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionItem"));
            VisitArgsDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryKey"));
            VisitArgsDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryValue"));
            VisitArgsCollectionInCollection = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInCollection"));
            VisitArgsDictionaryInCollection = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInCollection"));
            VisitArgsDictionaryInDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInDictionaryKey"));
            VisitArgsDictionaryInDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInDictionaryValue"));
            VisitArgsCollectionInDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInDictionaryKey"));
            VisitArgsCollectionInDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInDictionaryValue"));

            var readVisitorType = typeof(IReadVisitor);
            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 = valueType.Extend();

                VisitorTryVisitValue.Add(valueType, method);
                if (valueTypeExt.Class == TypeClass.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).GetMethod("MoveNext");
            DisposableDispose = typeof(IDisposable).GetMethod("Dispose");

            ExceptionNoDictionaryValue = typeof (InvalidGraphException).GetMethod("NoDictionaryValue");
        }
        public DynamicWriteTravellerMembers()
        {
            var visitArgsType = typeof (VisitArgs);
            VisitArgsCollectionItem = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionItem"));
            VisitArgsDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryKey"));
            VisitArgsDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryValue"));
            VisitArgsCollectionInCollection = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInCollection"));
            VisitArgsDictionaryInCollection = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInCollection"));
            VisitArgsDictionaryInDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInDictionaryKey"));
            VisitArgsDictionaryInDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("DictionaryInDictionaryValue"));
            VisitArgsCollectionInDictionaryKey = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInDictionaryKey"));
            VisitArgsCollectionInDictionaryValue = new StaticFieldILCodeVariable(visitArgsType.GetField("CollectionInDictionaryValue"));

            var writeVisitorType = typeof (IWriteVisitor);
            VisitorVisit = writeVisitorType.GetMethod("Visit");
            VisitorLeave = writeVisitorType.GetMethod("Leave");

            VisitorVisitValue = new Dictionary<Type, MethodInfo>();
            NullableConstructors = new Dictionary<Type, ConstructorInfo>();
            var nullableType = typeof (Nullable<>);
            foreach (var method in writeVisitorType.GetMethods()
                .Where(m => m.Name == "VisitValue")) {

                var valueType = method.GetParameters()[0].ParameterType;
                var valueTypeExt = valueType.Extend();

                VisitorVisitValue.Add(valueType, method);
                if (valueTypeExt.Class == TypeClass.Nullable) {
                    var innerType = valueTypeExt.Container.AsNullable().ElementType;
                    VisitorVisitValue.Add(innerType, method);
                    NullableConstructors.Add(innerType, nullableType.MakeGenericType(innerType).GetConstructor(new []{innerType}));
                }
            }

            EnumeratorMoveNext = typeof (IEnumerator).GetMethod("MoveNext");
            DisposableDispose = typeof (IDisposable).GetMethod("Dispose");
            ArrayGetLength = typeof (Array).GetMethod("GetLength");
        }
Пример #10
0
 public ILEnumerateCode(ILCodeParameter enumerable, Action<ILExpressed, ILCodeVariable> iterateBody)
 {
     _enumerable = enumerable;
     _iterateBody = iterateBody;
 }
Пример #11
0
 public void Invoke(ILCodeParameter instance, params ILCodeParameter[] parameters)
 {
     _il.Snippets.InvokeMethod(instance, _method, parameters);
 }
Пример #12
0
 public ILCodeParameter AsParameter(ILCodeParameter instance, params ILCodeParameter[] parameters)
 {
     return new CallMethodILCode(instance, _method, parameters);
 }
Пример #13
0
        public void SetPropertyValue(ILCodeVariable instance, PropertyInfo property, ILCodeParameter value)
        {
            if (!property.CanWrite) throw new InvalidOperationException("Can not set value from a property with no setter");

            if (value == null) value = ILCodeParameter.Null;
            var setMethod = property.GetSetMethod();
            InvokeMethod(instance, setMethod, value);
        }
Пример #14
0
 public ILChainIfCondition IfEqual(ILCodeParameter left, ILCodeParameter right)
 {
     return new ILChainIfCondition(this, () => Snippets.AreEqual(left, right));
 }
        private void GenerateEnumerateContentCode(ILCodeParameter valueParam, LevelType level)
        {
            var type = valueParam.ParameterType;
            var extType = _il.TypeCache.Extend(type);

            var visitArgs = GetContentVisitArgs(extType, level);

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

                var dictionaryType = container.DictionaryInterfaceType;

                var dictionaryLocal = _il.DeclareLocal("dictionary", dictionaryType);
                _il.Snippets.SetVariable(dictionaryLocal, valueParam.Cast(dictionaryType));

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

                var part = new ILEnumerateCode(dictionaryLocal, (il, it) => {
                    GenerateEnumerateContentCode(new InstancePropertyILCodeVariable(it, elementType.GetProperty("Key")), LevelType.DictionaryKey);
                    GenerateEnumerateContentCode(new InstancePropertyILCodeVariable(it, elementType.GetProperty("Value")), LevelType.DictionaryValue);
                });
                _il.Generate(part);

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

                var collectionLocal = _il.DeclareLocal("collection", collectionType);
                _il.Snippets.SetVariable(collectionLocal, valueParam.Cast(collectionType));

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

                GenerateEnumerateCollectionContentCode(extType, collectionLocal);

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

                GenerateChildCall(valueParam);

                _il.Snippets.InvokeMethod(_visitorVariable, Members.VisitorLeave, valueParam, visitArgs);
            }
        }
Пример #16
0
        public void Throw(ILCodeParameter exception)
        {
            if (exception == null) throw new ArgumentNullException("exception");

            ((IILCodeParameter) exception).Load(_il);
            _il.Throw();
        }
Пример #17
0
        public void SetVariable(ILCodeVariable variable, ILCodeParameter valueToSet)
        {
            if (valueToSet == null) valueToSet = ILCodeParameter.Null;

            ((IILCodeParameter) valueToSet).Load(_il);
            _il.Var.Set(variable);
        }
Пример #18
0
 public ILChainIfCondition IfNotEqual(ILCodeParameter left, ILCodeParameter right)
 {
     return new ILChainIfCondition(this, () => {
         Snippets.AreEqual(left, right);
         Negate();
     });
 }
Пример #19
0
 public void LoadAddress(ILCodeParameter parameter)
 {
     if (parameter == null) throw new ArgumentNullException("parameter");
     ((IILCodeParameter)parameter).LoadAddress(_il);
 }
        private void GenerateLoadParamValueCode(ILCodeParameter param)
        {
            var type = param.ParameterType;
            var extType = type.Extend();
            if (extType.Class == TypeClass.Nullable)
                type = extType.Container.AsNullable().ElementType;

            if (type.IsValueType)
                _il.Snippets.InvokeMethod(param, Members.Nullable[type].GetValue);
            else
                _il.Var.Load(param);
        }
Пример #21
0
 public void InvokeMethod(ILCodeParameter instance, MethodInfo method, params ILCodeParameter[] parameters)
 {
     _il.Generate(new CallMethodILCode(instance, method, parameters));
 }