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