public void TestCanEmit_FunctorAssignmentToDelegate()
        {
            const int    kArg1 = 123;
            const string kArg2 = "fghbsajdnkmf";

            var voidType   = assemblyEmitter.TypeSystem.Void;
            var intType    = assemblyEmitter.TypeSystem.Int32;
            var stringType = assemblyEmitter.TypeSystem.String;
            var arguments  = new TypeReference[]
            {
                intType,
                stringType
            };

            var functorType  = AssemblyRegistry.GetFunctorType(assemblyEmitter, voidType, arguments);
            var functorField = new FieldDefinition("myFunction", FieldAttributes.Public | FieldAttributes.Static, functorType);

            typeEmitter.AddField(functorField);

            typeEmitter.AddFieldInitializer(functorField, new FunctionNode()
            {
                Method = EmitMethodToOutputArgs(null, arguments),
                ExpressionReturnType = functorType
            });

            var declaringType = (TypeDefinition)typeEmitter.Get(assemblyEmitter);
            var delegateType  = DelegateEmitter.Create(assemblyEmitter, declaringType, voidType, arguments);

            declaringType.NestedTypes.Add(delegateType);

            var delegateField = new FieldDefinition("myDelegate", FieldAttributes.Public | FieldAttributes.Static, delegateType);

            typeEmitter.AddField(delegateField);

            BodyCodeBlock = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(delegateField),
                        RightOperand = new FieldNode(functorField)
                    },
                    new MethodCallNode()
                    {
                        ExpressionReturnType = voidType,
                        Function             = new FieldNode(delegateField),
                        Args = new IExpressionNode[]
                        {
                            new LiteralNode(intType, kArg1),
                            new LiteralNode(stringType, kArg2)
                        }
                    }
                }
            };

            ExpectedOutput = string.Format("{0}\r\n{1}", kArg1, kArg2);
            AssertSuccessByExecution();
        }
Beispiel #2
0
        private DelegateMetadata BuildDelegateMetadata()
        {
            var parameters = CompileParameters();

            var emitter = new DelegateEmitter(Compiler, Name, parameters);
            var lambda  = emitter.Compile();

            var builder = new DelegateMetadataBuilder(lambda, Name, parameters);

            return(builder.Build());
        }
        public void TestCanEmit_FunctionAssignmentToDelegate()
        {
            var voidType = assemblyEmitter.TypeSystem.Void;

            var targetMethod = new MethodEmitter(typeEmitter, "TargetMethod", voidType, MethodAttributes.Private | MethodAttributes.Static);

            targetMethod.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    CallConsoleWriteLine(new LiteralNode(assemblyEmitter.TypeSystem.String, "Inside target method"))
                }
            });

            var declaringType = (TypeDefinition)typeEmitter.Get(assemblyEmitter);
            var delegateType  = DelegateEmitter.Create(assemblyEmitter, "MyDelegate", declaringType, voidType, new TypeReference[0]);

            declaringType.NestedTypes.Add(delegateType);

            var delegateField = new FieldDefinition("myDelegate", FieldAttributes.Public | FieldAttributes.Static, delegateType);

            typeEmitter.AddField(delegateField);

            BodyCodeBlock = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(delegateField),
                        RightOperand = new FunctionNode()
                        {
                            ExpressionReturnType = delegateType,
                            Method = targetMethod.Get()
                        }
                    },
                    new MethodCallNode()
                    {
                        ExpressionReturnType = voidType,
                        Function             = new FieldNode(delegateField),
                        Args = new IExpressionNode[0]
                    }
                }
            };

            ExpectedOutput = "Inside target method";
            AssertSuccessByExecution();
        }
        public void TestCanEmit_FunctorPropertyAssignmentToDelegate()
        {
            const int    kArg1 = 485613;
            const string kArg2 = "FASD4FSAD14asdf";

            var intType    = assemblyEmitter.TypeSystem.Int32;
            var stringType = assemblyEmitter.TypeSystem.String;

            var voidType  = assemblyEmitter.TypeSystem.Void;
            var arguments = new TypeReference[]
            {
                intType,
                stringType
            };

            #region Functor Property Setup

            var functorType = AssemblyRegistry.GetFunctorType(assemblyEmitter, voidType, arguments);

            var functorField = new FieldDefinition("myFunction_BackingField", FieldAttributes.Public | FieldAttributes.Static, functorType);
            typeEmitter.AddField(functorField);

            #region Setter

            var functorSetter         = new MethodEmitter(typeEmitter, "set_MyFunction", voidType, MethodAttributes.Public | MethodAttributes.Static);
            var functorSetterArgument = functorSetter.AddArgument(functorType, "value");

            functorSetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(functorField),
                        RightOperand = new ParameterNode(functorSetterArgument)
                    }
                }
            });

            #endregion

            #region Getter

            var functorGetter = new MethodEmitter(typeEmitter, "get_MyFunction", functorType, MethodAttributes.Public | MethodAttributes.Static);
            functorGetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new ReturnNode()
                    {
                        Expression = new FieldNode(functorField)
                    }
                }
            });

            #endregion

            var functorProperty = new PropertyDefinition("MyFunction", PropertyAttributes.None, functorType);
            functorProperty.SetMethod = functorSetter.Get().Resolve();
            functorProperty.GetMethod = functorGetter.Get().Resolve();
            typeEmitter.AddProperty(functorProperty);

            #endregion

            #region Delegate Property setup

            var declaringType = (TypeDefinition)typeEmitter.Get(assemblyEmitter);
            var delegateType  = DelegateEmitter.Create(assemblyEmitter, declaringType, voidType, arguments);
            declaringType.NestedTypes.Add(delegateType);

            var delegateField = new FieldDefinition("myDelegate_BackingField", FieldAttributes.Private | FieldAttributes.Static, delegateType);
            typeEmitter.AddField(delegateField);

            #region Setter

            var delegateSetter         = new MethodEmitter(typeEmitter, "set_MyDelegate", voidType, MethodAttributes.Public | MethodAttributes.Static);
            var delegateSetterArgument = delegateSetter.AddArgument(delegateType, "value");

            delegateSetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(delegateField),
                        RightOperand = new ParameterNode(delegateSetterArgument)
                    }
                }
            });

            #endregion

            #region Getter

            var delegateGetter = new MethodEmitter(typeEmitter, "get_MyDelegate", delegateType, MethodAttributes.Public | MethodAttributes.Static);
            delegateGetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new ReturnNode()
                    {
                        Expression = new FieldNode(delegateField)
                    }
                }
            });

            #endregion

            var delegateProperty = new PropertyDefinition("MyDelegate", PropertyAttributes.None, delegateType);
            delegateProperty.SetMethod = delegateSetter.Get().Resolve();
            delegateProperty.GetMethod = delegateGetter.Get().Resolve();
            typeEmitter.AddProperty(delegateProperty);

            #endregion

            BodyCodeBlock = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new PropertyNode(assemblyEmitter, functorProperty),
                        RightOperand = new FunctionNode()
                        {
                            ExpressionReturnType = functorType,
                            Method = EmitMethodToOutputArgs(null, arguments)
                        }
                    },

                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new PropertyNode(assemblyEmitter, delegateProperty),
                        RightOperand = new PropertyNode(assemblyEmitter, functorProperty)
                    },

                    new MethodCallNode()
                    {
                        ExpressionReturnType = voidType,
                        Function             = new PropertyNode(assemblyEmitter, delegateProperty),
                        Args = new IExpressionNode[]
                        {
                            new LiteralNode(intType, kArg1),
                            new LiteralNode(stringType, kArg2)
                        }
                    }
                }
            };

            ExpectedOutput = string.Format("{0}\r\n{1}", kArg1, kArg2);
            AssertSuccessByExecution();
        }