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); }
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); }
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(); }
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); }
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); }
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"); }
public ILEnumerateCode(ILCodeParameter enumerable, Action<ILExpressed, ILCodeVariable> iterateBody) { _enumerable = enumerable; _iterateBody = iterateBody; }
public void Invoke(ILCodeParameter instance, params ILCodeParameter[] parameters) { _il.Snippets.InvokeMethod(instance, _method, parameters); }
public ILCodeParameter AsParameter(ILCodeParameter instance, params ILCodeParameter[] parameters) { return new CallMethodILCode(instance, _method, parameters); }
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); }
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); } }
public void Throw(ILCodeParameter exception) { if (exception == null) throw new ArgumentNullException("exception"); ((IILCodeParameter) exception).Load(_il); _il.Throw(); }
public void SetVariable(ILCodeVariable variable, ILCodeParameter valueToSet) { if (valueToSet == null) valueToSet = ILCodeParameter.Null; ((IILCodeParameter) valueToSet).Load(_il); _il.Var.Set(variable); }
public ILChainIfCondition IfNotEqual(ILCodeParameter left, ILCodeParameter right) { return new ILChainIfCondition(this, () => { Snippets.AreEqual(left, right); Negate(); }); }
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); }
public void InvokeMethod(ILCodeParameter instance, MethodInfo method, params ILCodeParameter[] parameters) { _il.Generate(new CallMethodILCode(instance, method, parameters)); }