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); }); }
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); }
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); } }
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()); }
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)); }
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)); }
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"); }
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"); }
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); }
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" })); }
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); } }
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); }
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>)); }
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); }
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(); } }
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); }
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); } }
public static ILPointer AsNullable(this ILPointer parameter) { return(new ILNullablePointer(parameter)); }
public static ILPointer Cast(this ILPointer parameter, Type toType) { return(new ILCastPointer(parameter, toType)); }
public static ILPointer Call(this ILPointer instance, MethodInfo method, params ILPointer[] parameters) { return(ILSnippet.Call(instance, method, parameters)); }
public static ILPointer Call(this ILPointer instance, string methodName, params ILPointer[] parameters) { return(ILSnippet.Call(instance, methodName, parameters)); }