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()); }
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); } }