public void TestCanEmit_InstancePropertyInitializer() { var stringType = assemblyEmitter.TypeSystem.String; var voidType = assemblyEmitter.TypeSystem.Void; var initializer = new LiteralNode(stringType, "aaa"); var backingField = new FieldDefinition("testProperty_backingField", FieldAttributes.Private, stringType); var setter = new MethodEmitter(typeEmitter, "set_testProperty", voidType, MethodAttributes.Public); var value = new ParameterDefinition("value", ParameterAttributes.None, stringType); var setterBody = new CodeBlockNode() { Nodes = new List <IParserNode>() { new AssignmentOperatorNode() { LeftOperand = new FieldNode() { ObjectInstance = new ThisNode() { ExpressionReturnType = backingField.DeclaringType }, Field = backingField }, RightOperand = new ParameterNode(value) } } }; setter.AddArgument(value); setter.ParseTree(setterBody); var property = new PropertyDefinition("testProperty", PropertyAttributes.None, stringType); property.SetMethod = (MethodDefinition)setter.Get(); typeEmitter.AddField(backingField); typeEmitter.AddProperty(property, initializer); var loadFieldExpression = new FieldNode() { ObjectInstance = ConstructTypeEmitterInstance(), Field = backingField }; GenerateBodyToOutputExpression(loadFieldExpression); ExpectedOutput = "aaa"; AssertSuccessByExecution(); }
private void ParseHeader(Modifiers mods, IAbstractSyntaxTree lexerNode, string methodName) { Contract.Requires(lexerNode.Type == Lexer.TokenType.Type); var point = Parser.GetSequencePoint(lexerNode); var builder = new TypeNode.TypeBuilder(Parent); int count = lexerNode.Children.Count; var paramz = ParseParams(Parser, lexerNode.Children[count - 1]); for (int i = 0; i < count - 1; i++) { builder.Append(lexerNode.Children[i]); } MethodReturnType = builder.Type; emitter = new MethodEmitter(GetClass().TypeEmitter, methodName, MethodReturnType, AttributesFromModifiers(Parser.GetSequencePoint(lexerNode), mods)); foreach (var p in paramz) { var param = ParseParameter(Parent, p.Type, p.Name); if (param.ParameterType.IsVoid()) { ErrorCode.IllegalMethodParam.ReportAndThrow(point, "Illegal method parameter type void"); } if (symbols.ContainsKey(param.Name)) { ErrorCode.ParamAlreadyDeclared.ReportAndThrow(point, "Parameter with name {0} is already declared", param.Name); } emitter.AddArgument(param); symbols.Add(param.Name, param); } ParamTypes = symbols.Values.Select(p => p.ParameterType); if (mods.HasFlag(Modifiers.Entry)) { if (MethodReturnType != Parser.Int32 && MethodReturnType != Parser.UInt32 && MethodReturnType != Parser.Void) { InvalidEntryReturn(SequencePoint, MethodReturnType); } emitter.SetAsEntryPoint(); if (!ValidParametersForMain(ParamTypes)) { InvalidEntryParams(point, ParamTypes); } } }
internal MethodReference EmitMethodToOutputArgs(IExpressionNode returnValue, params TypeReference[] args) { var returnType = returnValue != null ? returnValue.ExpressionReturnType : assemblyEmitter.TypeSystem.Void; var targetMethod = new MethodEmitter(typeEmitter, "TargetMethod", returnType, MethodAttributes.Static | MethodAttributes.Private); var nodes = new List <IParserNode>(); if (args.Length > 0) { var consoleWriteLineArgs = new List <IExpressionNode>(); var parameters = args.Select(a => targetMethod.AddArgument(new ParameterDefinition(a))).ToArray(); var formatString = new StringBuilder(); for (int i = 0; i < parameters.Length; i++) { formatString.Append(string.Format("{{{0}}}", i)); if (i != parameters.Length - 1) { formatString.Append("\r\n"); } } consoleWriteLineArgs.Add(new LiteralNode(assemblyEmitter.TypeSystem.String, formatString.ToString())); consoleWriteLineArgs.AddRange(parameters.Select(p => new ParameterNode(p))); nodes.Add(CallConsoleWriteLine(consoleWriteLineArgs.ToArray())); } if (returnValue != null) { nodes.Add(new ReturnNode() { Expression = returnValue }); } targetMethod.ParseTree(new CodeBlockNode() { Nodes = nodes }); return(targetMethod.Get()); }
public void TestCanEmit_StaticPropertyInitializer() { var boolType = assemblyEmitter.TypeSystem.Boolean; var voidType = assemblyEmitter.TypeSystem.Void; var initializer = new LiteralNode(boolType, true); var backingField = new FieldDefinition("testProperty_backingField", FieldAttributes.Private | FieldAttributes.Static, boolType); var setter = new MethodEmitter(typeEmitter, "set_testProperty", voidType, MethodAttributes.Public | MethodAttributes.Static); var value = new ParameterDefinition("value", ParameterAttributes.None, boolType); var setterBody = new CodeBlockNode() { Nodes = new List <IParserNode>() { new AssignmentOperatorNode() { LeftOperand = new FieldNode(backingField), RightOperand = new ParameterNode(value) } } }; setter.AddArgument(value); setter.ParseTree(setterBody); var property = new PropertyDefinition("testProperty", PropertyAttributes.None, boolType); property.SetMethod = (MethodDefinition)setter.Get(); typeEmitter.AddField(backingField); typeEmitter.AddProperty(property, initializer); GenerateBodyToOutputExpression(new FieldNode(backingField)); ExpectedOutput = true.ToString(); AssertSuccessByExecution(); }
public void Test_FunctorsGetIncludedToAssembly() { var intType = assemblyEmitter.TypeSystem.Int32; var stringType = assemblyEmitter.TypeSystem.String; var floatType = assemblyEmitter.TypeSystem.Single; var boolType = assemblyEmitter.TypeSystem.Boolean; var functor1 = GetFunctorType(intType, stringType, floatType, boolType); var functor2 = GetFunctorType(stringType, intType, floatType, boolType); var functor3 = GetFunctorType(stringType, floatType, intType, boolType); var functor4 = GetFunctorType(stringType, floatType, boolType, intType); var functor5 = GetFunctorType(stringType, boolType, floatType, intType); var method1 = new MethodEmitter(typeEmitter, "ReturnsFunctor", functor1, MethodAttributes.Static | MethodAttributes.Private); method1.ParseTree(new CodeBlockNode() { Nodes = new IParserNode[] { CallConsoleWriteLine(new LiteralNode(stringType, "Inside method that returns functor.")), new ReturnNode() { Expression = new NullNode() } } }); var field = new FieldDefinition("functorField", FieldAttributes.Static | FieldAttributes.Private, functor2); typeEmitter.AddField(field); var method2 = new MethodEmitter(typeEmitter, "TakesFunctorAsArgument", assemblyEmitter.TypeSystem.Void, MethodAttributes.Static | MethodAttributes.Private); var parameter = method2.AddArgument(functor3, "param"); method2.ParseTree(new CodeBlockNode() { Nodes = new IParserNode[] { CallConsoleWriteLine(new LiteralNode(stringType, "Inside method that takes functor parameter. Its value: {0}."), new ParameterNode(parameter)) } }); var localVariable = new VariableDefinition(functor4); BodyCodeBlock = new CodeBlockNode() { Nodes = new IParserNode[] { new SymbolDeclarationNode() { Variable = localVariable }, CallConsoleWriteLine(new LiteralNode(stringType, "Value of functor field: {0}."), new FieldNode(field)), CallConsoleWriteLine(new LiteralNode(stringType, "Value of functor local variable: {0}."), new LocalVariableNode(localVariable)), CallConsoleWriteLine(new LiteralNode(stringType, "Value of null cast to functor: {0}."), new CastNode(new NullNode(), functor5)), new MethodCallNode() { Function = new FunctionNode() { Method = method1.Get() }, Args = new IExpressionNode[0] }, new MethodCallNode() { Function = new FunctionNode() { Method = method2.Get() }, Args = new IExpressionNode[] { new NullNode() } } } }; ExpectedOutput = string.Format("Value of functor field: .{0}Value of functor local variable: .{0}Value of null cast to functor: .{0}Inside method that returns functor.{0}Inside method that takes functor parameter. Its value: .", Environment.NewLine); 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(); }