protected virtual MethodInfo GenerateCallbackMethodIfNecessary(MethodInfo method, Reference invocationTarget) { if (this.Context.HasMixins && this._interface2mixinIndex.Contains(method.DeclaringType)) { return(method); } string name = string.Format("callback__{0}", method.Name); ParameterInfo[] parameters = method.GetParameters(); ArgumentReference[] arguments = new ArgumentReference[parameters.Length]; for (int i = 0; i < arguments.Length; i++) { arguments[i] = new ArgumentReference(parameters[i].ParameterType); } EasyMethod method2 = this.MainTypeBuilder.CreateMethod(name, new ReturnReferenceExpression(method.ReturnType), MethodAttributes.HideBySig | MethodAttributes.Public, arguments); Expression[] args = new Expression[parameters.Length]; for (int j = 0; j < arguments.Length; j++) { args[j] = arguments[j].ToExpression(); } if (invocationTarget == null) { method2.CodeBuilder.AddStatement(new ReturnStatement(new MethodInvocationExpression(method, args))); } else { method2.CodeBuilder.AddStatement(new ReturnStatement(new MethodInvocationExpression(invocationTarget, method, args))); } return(method2.MethodBuilder); }
public void Method2Test_乎較時應回傳結果維10() { var Sut = new EasyMethod(); var expected = 10; var actual = Sut.Method2(); Assert.AreEqual(expected, actual); }
public void Method1Test_乎較時應回傳結果維7() { var Sut = new EasyMethod(); var expected = 7; var actual = Sut.Method1(); Assert.AreEqual(expected, actual); }
private EasyProperty CreateInterceptorProperty(PropertyInfo propertyInfo) { EasyProperty interceptorProperty = MainTypeBuilder.CreateProperty(propertyInfo); EasyMethod getMethod = interceptorProperty.CreateGetMethod(); MethodInfo baseMethod = typeof(MulticastDelegate).GetMethod("get_Interceptor"); getMethod.CodeBuilder.AddStatement(new ReturnStatement(base.InterceptorField)); return(interceptorProperty); }
/// <summary> /// Writes the method implementation. This /// method generates the IL code for property get/set method and /// ordinary methods. /// </summary> /// <param name="method">The method to implement.</param> /// <param name="builder"><see cref="EasyMethod"/> being constructed.</param> protected virtual void WriteInterceptorInvocationMethod(MethodInfo method, EasyMethod builder) { ArgumentReference[] arguments = builder.Arguments; TypeReference[] dereferencedArguments = IndirectReference.WrapIfByRef(builder.Arguments); LocalReference local_inv = builder.CodeBuilder.DeclareLocal(Context.Invocation); EasyCallable callable = _method2Delegate[method] as EasyCallable; FieldReference fieldDelegate = ObtainCallableFieldBuilderDelegate(callable); builder.CodeBuilder.AddStatement( new AssignStatement(local_inv, new MethodInvocationExpression(_method2Invocation, fieldDelegate.ToExpression(), new MethodTokenExpression(GetCorrectMethod(method)), GetPseudoInvocationTarget(method)))); LocalReference ret_local = builder.CodeBuilder.DeclareLocal(typeof(object)); LocalReference args_local = builder.CodeBuilder.DeclareLocal(typeof(object[])); // Store arguments into an object array. builder.CodeBuilder.AddStatement( new AssignStatement(args_local, new ReferencesToObjectArrayExpression(dereferencedArguments))); // Invoke the interceptor. builder.CodeBuilder.AddStatement( new AssignStatement(ret_local, new VirtualMethodInvocationExpression(InterceptorField, Context.Interceptor.GetMethod("Intercept"), local_inv.ToExpression(), args_local.ToExpression()))); // Load possibly modified ByRef arguments from the array. for (int i = 0; i < arguments.Length; i++) { if (arguments[i].Type.IsByRef) { builder.CodeBuilder.AddStatement( new AssignStatement(dereferencedArguments[i], new ConvertExpression(dereferencedArguments[i].Type, new LoadRefArrayElementExpression(i, args_local)))); } } if (builder.ReturnType == typeof(void)) { builder.CodeBuilder.AddStatement(new ReturnStatement()); } else { builder.CodeBuilder.AddStatement(new ReturnStatement( new ConvertExpression(builder.ReturnType, ret_local.ToExpression()))); } }
public void Method2Test_呼叫時應回傳結果為10() { //assert var Sut = new EasyMethod(); var expected = 10; //arrange var actual = Sut.Method2(); //act Assert.AreEqual(expected, actual); }
public void CreateMoreComplexCallable() { EasyType typebuilder = new EasyType(module, "mytype"); ArgumentReference arg1 = new ArgumentReference(typeof(int)); ArgumentReference arg2 = new ArgumentReference(typeof(DateTime)); ArgumentReference arg3 = new ArgumentReference(typeof(object)); EasyCallable callable = typebuilder.CreateCallable( new ReturnReferenceExpression(typeof(string)), arg1, arg2, arg3); FieldReference field1 = typebuilder.CreateField("field1", callable.TypeBuilder); SimpleCallback sc = new SimpleCallback(); ArgumentReference arg = new ArgumentReference(typeof(SimpleCallback)); EasyConstructor constructor = typebuilder.CreateConstructor(arg); constructor.CodeBuilder.InvokeBaseConstructor(); constructor.CodeBuilder.AddStatement(new AssignStatement(field1, new NewInstanceExpression(callable, arg.ToExpression(), new MethodPointerExpression(arg, typeof(SimpleCallback).GetMethod("RunAs"))))); constructor.CodeBuilder.AddStatement(new ReturnStatement()); arg1 = new ArgumentReference(typeof(int)); arg2 = new ArgumentReference(typeof(DateTime)); arg3 = new ArgumentReference(typeof(object)); ReturnReferenceExpression ret1 = new ReturnReferenceExpression(typeof(string)); EasyMethod getField1 = typebuilder.CreateMethod("Exec", ret1, arg1, arg2, arg3); getField1.CodeBuilder.AddStatement( new ReturnStatement( new ConvertExpression(typeof(String), new MethodInvocationExpression(field1, callable.Callmethod, new ReferencesToObjectArrayExpression(arg1, arg2, arg3))))); Type newType = typebuilder.BuildType(); RunPEVerify(); object instance = Activator.CreateInstance(newType, new object[] { sc }); MethodInfo method = instance.GetType().GetMethod("Exec"); object result = method.Invoke(instance, new object[] { 1, DateTime.Now, "" }); Assert.AreEqual("hello2", result); }
static bool AddVisitCode(EasyMethod m, FieldInfo field, CodeExpression var, List <CodeStatement> assertions, bool transformer) { CodeExpression prop = var.Property(GetPropertyName(field.Name)); CodeExpression nodeStack = Easy.Var("nodeStack"); if (field.FieldType.FullName.StartsWith("System.Collections.Generic.List")) { Type elType = field.FieldType.GetGenericArguments()[0]; if (!typeof(INode).IsAssignableFrom(elType)) { return(false); } assertions.Add(IfNullSetFailure(prop)); string code; string propertyName = GetCode(prop); if (transformer) { code = CreateTransformerLoop(propertyName, ConvertType(elType).BaseType); } else { code = "\t\t\tif (" + propertyName + ".Count == data." + GetPropertyName(field.Name) + ".Count) {\n" + "\t\t\tfor (int i=0; i<" + propertyName + ".Count;i++) {\n" + "\t\t\t\t" + ConvertType(elType).BaseType + " o = " + propertyName + "[i];\n" + "\t\t\t\tif(o == null){return SetFailure();}\n" + "\t\t\t\tif((bool)o.AcceptVisitor(this, data." + GetPropertyName(field.Name) + "[i]) == false) return SetFailure();\n" + "\t\t\t}" + "\t\t\t}" + "\t\t\telse { return SetFailure(); }"; } m.Statements.Add(new CodeSnippetStatement(code)); return(true); } if (!typeof(INode).IsAssignableFrom(field.FieldType)) { return(false); } assertions.Add(IfNullSetFailure(prop)); if (transformer) { m.Statements.Add(nodeStack.InvokeMethod("Push", prop)); } m.Statements.Add(prop.InvokeMethod("AcceptVisitor", Easy.This, Easy.Var("data." + var.Property(GetPropertyName(field.Name)).PropertyName))); if (transformer) { m.Body.Assign(prop, nodeStack.InvokeMethod("Pop").CastTo(ConvertType(field.FieldType))); } return(true); }
protected virtual void ImplementCacheInvocationCache() { MethodInfo get_ItemMethod = typeof(HybridDictionary).GetMethod("get_Item", new Type[] { typeof(object) }); MethodInfo set_ItemMethod = typeof(HybridDictionary).GetMethod("Add", new Type[] { typeof(object), typeof(object) }); Type[] args = new Type[] { typeof(ICallable), typeof(MethodInfo) }; Type[] invocation_const_args = new Type[] { typeof(ICallable), typeof(object), typeof(MethodInfo), typeof(object) }; ArgumentReference arg1 = new ArgumentReference(typeof(ICallable)); ArgumentReference arg2 = new ArgumentReference(typeof(MethodInfo)); ArgumentReference arg3 = new ArgumentReference(typeof(object)); _method2Invocation = MainTypeBuilder.CreateMethod("_Method2Invocation", new ReturnReferenceExpression(Context.Invocation), MethodAttributes.Family | MethodAttributes.HideBySig, arg1, arg2, arg3); LocalReference invocation_local = _method2Invocation.CodeBuilder.DeclareLocal(Context.Invocation); LockBlockExpression block = new LockBlockExpression(SelfReference.Self); block.AddStatement(new AssignStatement(invocation_local, new ConvertExpression(Context.Invocation, new VirtualMethodInvocationExpression(CacheField, get_ItemMethod, arg2.ToExpression())))); ConditionExpression cond1 = new ConditionExpression(OpCodes.Brfalse_S, invocation_local.ToExpression()); cond1.AddTrueStatement(new AssignStatement( invocation_local, new NewInstanceExpression(InvocationType.GetConstructor(invocation_const_args), arg1.ToExpression(), SelfReference.Self.ToExpression(), arg2.ToExpression(), arg3.ToExpression()))); cond1.AddTrueStatement(new ExpressionStatement( new VirtualMethodInvocationExpression(CacheField, set_ItemMethod, arg2.ToExpression(), invocation_local.ToExpression()))); block.AddStatement(new ExpressionStatement(cond1)); _method2Invocation.CodeBuilder.AddStatement(new ExpressionStatement(block)); _method2Invocation.CodeBuilder.AddStatement(new ReturnStatement(invocation_local)); }
static bool AddVisitCode(EasyMethod m, FieldInfo field, CodeExpression var, List <CodeStatement> assertions, bool transformer) { CodeExpression prop = var.Property(GetPropertyName(field.Name)); CodeExpression nodeStack = Easy.Var("nodeStack"); if (field.FieldType.FullName.StartsWith("System.Collections.Generic.List")) { Type elType = field.FieldType.GetGenericArguments()[0]; if (!typeof(INode).IsAssignableFrom(elType)) { return(false); } assertions.Add(AssertIsNotNull(prop)); string code; if (transformer) { code = CreateTransformerLoop(GetCode(prop), ConvertType(elType).BaseType); } else { code = "\t\t\tforeach (" + ConvertType(elType).BaseType + " o in " + GetCode(prop) + ") {\n" + "\t\t\t\tDebug.Assert(o != null);\n" + "\t\t\t\to.AcceptVisitor(this, data);\n" + "\t\t\t}"; } m.Statements.Add(new CodeSnippetStatement(code)); return(true); } if (!typeof(INode).IsAssignableFrom(field.FieldType)) { return(false); } assertions.Add(AssertIsNotNull(prop)); if (transformer) { m.Statements.Add(nodeStack.InvokeMethod("Push", prop)); } m.Statements.Add(prop.InvokeMethod("AcceptVisitor", Easy.This, Easy.Var("data"))); if (transformer) { m.Body.Assign(prop, nodeStack.InvokeMethod("Pop").CastTo(ConvertType(field.FieldType))); } return(true); }
public void ArrayRefs() { EasyType typebuilder = new EasyType(module, "mytype"); FieldReference field1 = typebuilder.CreateField("field1", typeof(object)); FieldReference field2 = typebuilder.CreateField("field2", typeof(object)); ArgumentReference arg = new ArgumentReference(typeof(object[])); EasyConstructor constructor = typebuilder.CreateConstructor(arg); constructor.CodeBuilder.InvokeBaseConstructor(); constructor.CodeBuilder.AddStatement(new AssignStatement(field1, new LoadRefArrayElementExpression(0, arg))); constructor.CodeBuilder.AddStatement(new AssignStatement(field2, new LoadRefArrayElementExpression(1, arg))); constructor.CodeBuilder.AddStatement(new ReturnStatement()); ReturnReferenceExpression ret1 = new ReturnReferenceExpression(typeof(object)); EasyMethod getField1 = typebuilder.CreateMethod("GetField1", ret1); getField1.CodeBuilder.AddStatement(new ReturnStatement(field1)); ReturnReferenceExpression ret2 = new ReturnReferenceExpression(typeof(object)); EasyMethod getField2 = typebuilder.CreateMethod("GetField2", ret2); getField2.CodeBuilder.AddStatement(new ReturnStatement(field2)); Type newType = typebuilder.BuildType(); object[] innerArgs = new object[] { "hammett", "verissimo" }; object instance = Activator.CreateInstance(newType, new object[] { innerArgs }); MethodInfo method = instance.GetType().GetMethod("GetField1"); object result = method.Invoke(instance, new object[0]); Assert.AreEqual("hammett", result); method = instance.GetType().GetMethod("GetField2"); result = method.Invoke(instance, new object[0]); Assert.AreEqual("verissimo", result); RunPEVerify(); }
static CodeTypeDeclaration CreateAstVisitorInterface(List <Type> nodeTypes) { CodeTypeDeclaration td = new CodeTypeDeclaration("IAstVisitor"); td.IsInterface = true; foreach (Type t in nodeTypes) { if (!t.IsAbstract) { EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + t.Name); m.AddParameter(ConvertType(t), GetFieldName(t.Name)); m.AddParameter(typeof(object), "data"); } } return(td); }
static void AddFieldVisitCode(EasyMethod m, Type type, CodeExpression var, List <CodeStatement> assertions, bool transformer) { if (type != null) { if (type.BaseType != typeof(StatementWithEmbeddedStatement)) { AddFieldVisitCode(m, type.BaseType, var, assertions, transformer); } foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) { AddVisitCode(m, field, var, assertions, transformer); } if (type.BaseType == typeof(StatementWithEmbeddedStatement)) { AddFieldVisitCode(m, type.BaseType, var, assertions, transformer); } } }
public void FieldsStoreAndLoad() { EasyType typebuilder = new EasyType(module, "mytype"); FieldReference field1 = typebuilder.CreateField("field1", typeof(int)); FieldReference field2 = typebuilder.CreateField("field2", typeof(string)); { ArgumentReference arg1 = new ArgumentReference(typeof(int)); ArgumentReference arg2 = new ArgumentReference(typeof(string)); EasyConstructor constr = typebuilder.CreateConstructor(arg1, arg2); constr.CodeBuilder.InvokeBaseConstructor(); constr.CodeBuilder.AddStatement(new AssignStatement(field1, arg1.ToExpression())); constr.CodeBuilder.AddStatement(new AssignStatement(field2, arg2.ToExpression())); constr.CodeBuilder.AddStatement(new ReturnStatement()); } { ReturnReferenceExpression ret1 = new ReturnReferenceExpression(typeof(int)); EasyMethod m1 = typebuilder.CreateMethod("GetField1", ret1); m1.CodeBuilder.AddStatement(new ReturnStatement(field1)); ReturnReferenceExpression ret2 = new ReturnReferenceExpression(typeof(string)); EasyMethod m2 = typebuilder.CreateMethod("GetField2", ret2); m2.CodeBuilder.AddStatement(new ReturnStatement(field2)); } Type newType = typebuilder.BuildType(); Assert.IsNotNull(newType); object instance = Activator.CreateInstance(newType, new object[] { 10, "hello" }); Assert.IsNotNull(instance); MethodInfo method1 = instance.GetType().GetMethod("GetField1"); MethodInfo method2 = instance.GetType().GetMethod("GetField2"); Assert.AreEqual(10, method1.Invoke(instance, new object[0])); Assert.AreEqual("hello", method2.Invoke(instance, new object[0])); RunPEVerify(); }
public void EmptyMethodReturningInt() { EasyType typebuilder = new EasyType(module, "mytype"); EasyMethod emptyMethod = typebuilder.CreateMethod("DoSomething", new ReturnReferenceExpression(typeof(int))); Type newType = typebuilder.BuildType(); Assert.IsNotNull(newType); object instance = Activator.CreateInstance(newType); Assert.IsNotNull(instance); MethodInfo method = instance.GetType().GetMethod("DoSomething"); Assert.AreEqual(0, method.Invoke(instance, new object[0])); RunPEVerify(); }
public void Conditionals() { EasyType typebuilder = new EasyType(module, "mytype"); FieldReference cachefield = typebuilder.CreateField("cache", typeof(IDictionary)); ArgumentReference arg = new ArgumentReference(typeof(bool)); EasyConstructor constructor = typebuilder.CreateConstructor(arg); constructor.CodeBuilder.InvokeBaseConstructor(); ConditionExpression exp = new ConditionExpression(OpCodes.Brtrue_S, arg.ToExpression()); exp.AddTrueStatement(new AssignStatement(cachefield, new NewInstanceExpression(typeof(HybridDictionary), new Type[0]))); exp.AddFalseStatement(new AssignStatement(cachefield, new NewInstanceExpression(typeof(Hashtable), new Type[0]))); constructor.CodeBuilder.AddStatement(new ExpressionStatement(exp)); constructor.CodeBuilder.AddStatement(new ReturnStatement()); ReturnReferenceExpression ret = new ReturnReferenceExpression(typeof(IDictionary)); EasyMethod getCache = typebuilder.CreateMethod("GetCache", ret); getCache.CodeBuilder.AddStatement(new ReturnStatement(cachefield)); Type newType = typebuilder.BuildType(); object instance = Activator.CreateInstance(newType, new object[] { true }); MethodInfo method = instance.GetType().GetMethod("GetCache"); object dic = method.Invoke(instance, new object[0]); Assert.IsTrue(dic is HybridDictionary); instance = Activator.CreateInstance(newType, new object[] { false }); dic = method.Invoke(instance, new object[0]); Assert.IsTrue(dic is Hashtable); RunPEVerify(); }
public void MethodInvokingMethod() { EasyType typebuilder = new EasyType(module, "mytype"); ArgumentReference rarg1 = new ArgumentReference(typeof(int)); ArgumentReference rarg2 = new ArgumentReference(typeof(int)); ReturnReferenceExpression rret = new ReturnReferenceExpression(typeof(int)); EasyMethod realCalcMethod = typebuilder.CreateMethod("RealCalc", rret, rarg1, rarg2); realCalcMethod.CodeBuilder.AddStatement( new ReturnStatement( new BinaryExpression(BinaryExpression.Add, rarg1.ToExpression(), rarg2.ToExpression()))); ArgumentReference arg1 = new ArgumentReference(typeof(int)); ArgumentReference arg2 = new ArgumentReference(typeof(int)); ReturnReferenceExpression ret = new ReturnReferenceExpression(typeof(int)); EasyMethod calcMethod = typebuilder.CreateMethod("Calc", ret, arg1, arg2); calcMethod.CodeBuilder.AddStatement( new ReturnStatement( new MethodInvocationExpression(realCalcMethod, arg1.ToExpression(), arg2.ToExpression()))); Type newType = typebuilder.BuildType(); Assert.IsNotNull(newType); object instance = Activator.CreateInstance(newType, new object[0]); Assert.IsNotNull(instance); MethodInfo method = instance.GetType().GetMethod("Calc"); Assert.AreEqual(2, method.Invoke(instance, new object[] { 1, 1 })); Assert.AreEqual(5, method.Invoke(instance, new object[] { 3, 2 })); method = instance.GetType().GetMethod("RealCalc"); Assert.AreEqual(2, method.Invoke(instance, new object[] { 1, 1 })); Assert.AreEqual(5, method.Invoke(instance, new object[] { 3, 2 })); RunPEVerify(); }
protected virtual void ImplementCacheInvocationCache() { MethodInfo method = typeof(HybridDictionary).GetMethod("get_Item", new Type[] { typeof(object) }); MethodInfo info2 = typeof(HybridDictionary).GetMethod("Add", new Type[] { typeof(object), typeof(object) }); Type[] types = new Type[] { typeof(ICallable), typeof(object), typeof(MethodInfo), typeof(object) }; ArgumentReference reference = new ArgumentReference(typeof(ICallable)); ArgumentReference reference2 = new ArgumentReference(typeof(MethodInfo)); ArgumentReference reference3 = new ArgumentReference(typeof(object)); this._method2Invocation = this.MainTypeBuilder.CreateMethod("_Method2Invocation", new ReturnReferenceExpression(this.Context.Invocation), MethodAttributes.HideBySig | MethodAttributes.Family, new ArgumentReference[] { reference, reference2, reference3 }); LocalReference target = this._method2Invocation.CodeBuilder.DeclareLocal(this.Context.Invocation); LockBlockExpression expression = new LockBlockExpression(SelfReference.Self); expression.AddStatement(new AssignStatement(target, new ConvertExpression(this.Context.Invocation, new VirtualMethodInvocationExpression(this.CacheField, method, new Expression[] { reference2.ToExpression() })))); ConditionExpression expression2 = new ConditionExpression(OpCodes.Brfalse_S, target.ToExpression()); expression2.AddTrueStatement(new AssignStatement(target, new NewInstanceExpression(this.InvocationType.GetConstructor(types), new Expression[] { reference.ToExpression(), SelfReference.Self.ToExpression(), reference2.ToExpression(), reference3.ToExpression() }))); expression2.AddTrueStatement(new ExpressionStatement(new VirtualMethodInvocationExpression(this.CacheField, info2, new Expression[] { reference2.ToExpression(), target.ToExpression() }))); expression.AddStatement(new ExpressionStatement(expression2)); this._method2Invocation.CodeBuilder.AddStatement(new ExpressionStatement(expression)); this._method2Invocation.CodeBuilder.AddStatement(new ReturnStatement(target)); }
public void BlockWithLock() { EasyType typebuilder = new EasyType(module, "mytype"); FieldReference cachefield = typebuilder.CreateField("cache", typeof(ArrayList)); EasyConstructor constructor = typebuilder.CreateConstructor( ); constructor.CodeBuilder.InvokeBaseConstructor(); LockBlockExpression block = new LockBlockExpression(SelfReference.Self); block.AddStatement(new AssignStatement(cachefield, new NewInstanceExpression(typeof(ArrayList), new Type[0]))); constructor.CodeBuilder.AddStatement(new ExpressionStatement(block)); constructor.CodeBuilder.AddStatement(new ReturnStatement()); ReturnReferenceExpression ret = new ReturnReferenceExpression(typeof(ArrayList)); EasyMethod getCache = typebuilder.CreateMethod("GetCache", ret); getCache.CodeBuilder.AddStatement(new ReturnStatement(cachefield)); Type newType = typebuilder.BuildType(); Assert.IsNotNull(newType); object instance = Activator.CreateInstance(newType, new object[0]); Assert.IsNotNull(instance); MethodInfo method = instance.GetType().GetMethod("GetCache"); Assert.IsNotNull(method.Invoke(instance, new object[0])); RunPEVerify(); }
/// <summary> /// Generates implementation for each method. /// </summary> /// <param name="method"></param> /// <param name="properties"></param> protected void GenerateMethodImplementation(MethodInfo method, EasyProperty[] properties) { if (Context.ShouldSkip(method)) { return; } ParameterInfo[] parametersInfo = method.GetParameters(); Type[] parameters = new Type[parametersInfo.Length]; for (int i = 0; i < parametersInfo.Length; i++) { parameters[i] = parametersInfo[i].ParameterType; } MethodAttributes atts = ObtainMethodAttributes(method); PreProcessMethod(method); EasyMethod easyMethod = null; bool isSetMethod = method.IsSpecialName && method.Name.StartsWith("set_"); bool isGetMethod = method.IsSpecialName && method.Name.StartsWith("get_"); if (!isSetMethod && !isGetMethod) { easyMethod = _typeBuilder.CreateMethod(method.Name, atts, new ReturnReferenceExpression(method.ReturnType), parameters); } else { if (isSetMethod || isGetMethod) { foreach (EasyProperty property in properties) { if (property == null) { break; } if (!property.Name.Equals(method.Name.Substring(4))) { continue; } if (property.IndexParameters != null) { bool signatureMatches = true; int numOfIndexes = parametersInfo.Length; //A set method already has a value parameter, and everything after //that is an indexer. if (isSetMethod) { numOfIndexes--; } if (numOfIndexes != property.IndexParameters.Length) { continue; } for (int i = 0; i < property.IndexParameters.Length; i++) { if (property.IndexParameters[i].ParameterType != parametersInfo[i].ParameterType) { signatureMatches = false; break; } } if (!signatureMatches) { continue; } } if (isSetMethod) { easyMethod = property.CreateSetMethod(atts, parameters); break; } else { easyMethod = property.CreateGetMethod(atts, parameters); break; } } } } easyMethod.DefineParameters(parametersInfo); WriteInterceptorInvocationMethod(method, easyMethod); PostProcessMethod(method); }
static CodeTypeDeclaration CreateAstVisitorClass(List <Type> nodeTypes, bool transformer) { CodeTypeDeclaration td = new CodeTypeDeclaration(transformer ? "AbstractAstTransformer" : "AbstractAstVisitor"); td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract; td.BaseTypes.Add(new CodeTypeReference("IAstVisitor")); if (transformer) { string comment = "The AbstractAstTransformer will iterate through the whole AST,\n " + "just like the AbstractAstVisitor. However, the AbstractAstTransformer allows\n " + "you to modify the AST at the same time: It does not use 'foreach' internally,\n " + "so you can add members to collections of parents of the current node (but\n " + "you cannot insert or delete items as that will make the index used invalid).\n " + "You can use the methods ReplaceCurrentNode and RemoveCurrentNode to replace\n " + "or remove the current node, totally independent from the type of the parent node."; Easy.AddSummary(td, comment); CodeMemberField field = td.AddField(Easy.TypeRef("Stack", "INode"), "nodeStack"); field.InitExpression = Easy.New(field.Type); /* * CodeExpression nodeStack = Easy.Var("nodeStack"); * CodeMemberProperty p = new CodeMemberProperty(); * p.Name = "CurrentNode"; * p.Type = new CodeTypeReference("INode"); * p.Attributes = MemberAttributes.Public | MemberAttributes.Final; * p.GetStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("currentNode"))); * p.SetStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("currentNode"), * new CodePropertySetValueReferenceExpression())); * td.Members.Add(p); */ EasyMethod m = td.AddMethod("ReplaceCurrentNode"); m.AddParameter(Easy.TypeRef("INode"), "newNode"); m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop")); m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Var("newNode"))); m = td.AddMethod("RemoveCurrentNode"); m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop")); m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Null)); } foreach (Type type in nodeTypes) { if (!type.IsAbstract) { EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + type.Name); m.Attributes = MemberAttributes.Public; m.AddParameter(ConvertType(type), GetFieldName(type.Name)); m.AddParameter(typeof(object), "data"); List <CodeStatement> assertions = new List <CodeStatement>(); string varVariableName = GetFieldName(type.Name); CodeExpression var = Easy.Var(varVariableName); assertions.Add(AssertIsNotNull(var)); AddFieldVisitCode(m, type, var, assertions, transformer); if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0) { if (transformer) { m.Statements.Add(new CodeSnippetStatement(CreateTransformerLoop(varVariableName + ".Children", "INode"))); m.Body.Return(Easy.Null); } else { m.Body.Return(var.InvokeMethod("AcceptChildren", Easy.This, Easy.Var("data"))); } } else { CodeExpressionStatement lastStatement = null; if (m.Statements.Count > 0) { lastStatement = m.Statements[m.Statements.Count - 1] as CodeExpressionStatement; } if (lastStatement != null) { m.Statements.RemoveAt(m.Statements.Count - 1); m.Body.Return(lastStatement.Expression); } else { m.Body.Return(Easy.Null); } } for (int i = 0; i < assertions.Count; i++) { m.Statements.Insert(i, assertions[i]); } } } return(td); }
static CodeTypeDeclaration CreateAstComparisonVisitorClass(List <Type> nodeTypes) { CodeTypeDeclaration td = new CodeTypeDeclaration("AstComparisonVisitor"); td.TypeAttributes = TypeAttributes.Public; td.IsPartial = true; //td.BaseTypes.Add(new CodeTypeReference("IAstVisitor")); foreach (Type type in nodeTypes) { if (!type.IsAbstract) { EasyMethod m = td.AddMethod(typeof(bool), VisitPrefix + type.Name); m.Attributes = MemberAttributes.Public; m.AddParameter(ConvertType(type), GetFieldName(type.Name)); const string right_hand_side_name = "d"; m.AddParameter(typeof(object), right_hand_side_name); List <CodeStatement> assertions = new List <CodeStatement>(); string varVariableName = GetFieldName(type.Name); CodeExpression var = Easy.Var(varVariableName); assertions.Add(IfNullSetFailure(var)); if (varVariableName == "using") { varVariableName = "@using"; } CodeExpression r_var = Easy.Var(right_hand_side_name); assertions.Add(IfNullSetFailure(r_var)); // Confirm their types are the same. m.Statements.Add(new CodeSnippetStatement("\t\t\tif(" + varVariableName + ".GetType() != " + right_hand_side_name + ".GetType()) {return SetFailure();}")); // Cast the object parameter to whatever the other parameter is, and call the variable 'data'. // Like so: AddHandlerStatement data = (AddHandlerStatement) d; m.Statements.Add(new CodeSnippetStatement("\t\t\tvar data = (" + ConvertType(type).BaseType + ")d;")); m.Statements.Add(new CodeConditionStatement(new CodeSnippetExpression("!IsMatch(" + varVariableName + ", data)"), new CodeSnippetStatement("\t\t\t\treturn SetFailure();"))); AddFieldVisitCode(m, type, var, assertions, false); if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0) { m.Body.Return(var.InvokeMethod("AcceptChildren", Easy.This, Easy.Var(right_hand_side_name))); } else { CodeExpressionStatement lastStatement = null; if (m.Statements.Count > 0) { lastStatement = m.Statements[m.Statements.Count - 1] as CodeExpressionStatement; } if (lastStatement != null) { m.Statements.RemoveAt(m.Statements.Count - 1); m.Body.Return(lastStatement.Expression); } else { m.Body.Return(new CodeSnippetExpression("true")); } } for (int i = 0; i < assertions.Count; i++) { m.Statements.Insert(i, assertions[i]); } } } return(td); }
public MethodInvocationExpression(Reference owner, EasyMethod method, params Expression[] args) : this(owner, method.MethodBuilder, args) { }
public MethodInvocationExpression(EasyMethod method, params Expression[] args) : this(SelfReference.Self, method.MethodBuilder, args) { }
public VirtualMethodInvocationExpression(Reference owner, EasyMethod method, params Expression[] args) : base(owner, method, args) { }
public VirtualMethodInvocationExpression(EasyMethod method, params Expression[] args) : base(method, args) { }
protected void GenerateMethodImplementation(MethodInfo method, EasyProperty[] properties) { if (!this.Context.ShouldSkip(method)) { ParameterInfo[] parameters = method.GetParameters(); Type[] args = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { args[i] = parameters[i].ParameterType; } MethodAttributes attrs = this.ObtainMethodAttributes(method); this.PreProcessMethod(method); EasyMethod builder = null; bool flag = method.Name.StartsWith("set_"); bool flag2 = method.Name.StartsWith("get_"); if (!flag && !flag2) { builder = this._typeBuilder.CreateMethod(method.Name, attrs, new ReturnReferenceExpression(method.ReturnType), args); } else if (flag || flag2) { foreach (EasyProperty property in properties) { if (property == null) { break; } if (property.Name.Equals(method.Name.Substring(4))) { if (property.IndexParameters != null) { bool flag3 = true; int length = parameters.Length; if (flag) { length--; } if (length != property.IndexParameters.Length) { goto Label_015D; } for (int j = 0; j < property.IndexParameters.Length; j++) { if (property.IndexParameters[j].ParameterType != parameters[j].ParameterType) { flag3 = false; break; } } if (!flag3) { goto Label_015D; } } if (flag) { builder = property.CreateSetMethod(attrs, args); } else { builder = property.CreateGetMethod(attrs, args); } break; Label_015D :; } } } builder.DefineParameters(parameters); this.WriteInterceptorInvocationMethod(method, builder); this.PostProcessMethod(method); } }
static CodeTypeDeclaration CreateNodeTrackingAstVisitorClass(List <Type> nodeTypes) { CodeTypeDeclaration td = new CodeTypeDeclaration("NodeTrackingAstVisitor"); td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Abstract; td.BaseTypes.Add(new CodeTypeReference("AbstractAstVisitor")); string comment = "<summary>\n " + "The NodeTrackingAstVisitor will iterate through the whole AST,\n " + "just like the AbstractAstVisitor, and calls the virtual methods\n " + "BeginVisit and EndVisit for each node being visited.\n " + "</summary>"; td.Comments.Add(new CodeCommentStatement(comment, true)); comment = "<remarks>\n " + "base.Visit(node, data) calls this.TrackedVisit(node, data), so if\n " + "you want to visit child nodes using the default visiting behaviour,\n " + "use base.TrackedVisit(parentNode, data).\n " + "</remarks>"; td.Comments.Add(new CodeCommentStatement(comment, true)); EasyMethod m = td.AddMethod("BeginVisit"); m.Attributes = MemberAttributes.Family; m.AddParameter(Easy.TypeRef("INode"), "node"); m = td.AddMethod("EndVisit"); m.Attributes = MemberAttributes.Family; m.AddParameter(Easy.TypeRef("INode"), "node"); foreach (Type type in nodeTypes) { if (!type.IsAbstract) { m = td.AddMethod(typeof(object), VisitPrefix + type.Name); m.Attributes = MemberAttributes.Public | MemberAttributes.Override; m.AddParameter(ConvertType(type), GetFieldName(type.Name)); m.AddParameter(new CodeTypeReference(typeof(object)), "data"); CodeExpression var = Easy.Var(GetFieldName(type.Name)); m.Body.InvokeMethod(Easy.This, "BeginVisit", var); m.Body.DeclareVariable(typeof(object), "result").InitExpression = Easy.This.InvokeMethod("TrackedVisit" + type.Name, var, Easy.Var("data")); m.Body.InvokeMethod(Easy.This, "EndVisit", var); m.Body.Return(Easy.Var("result")); } } foreach (Type type in nodeTypes) { if (!type.IsAbstract) { m = td.AddMethod(typeof(object), "TrackedVisit" + type.Name); m.Attributes = MemberAttributes.Public; m.AddParameter(ConvertType(type), GetFieldName(type.Name)); m.AddParameter(new CodeTypeReference(typeof(object)), "data"); m.Body.Return(Easy.Base.InvokeMethod(VisitPrefix + type.Name, Easy.Var(GetFieldName(type.Name)), Easy.Var("data"))); } } return(td); }
protected virtual void ImplementGetObjectData(Type[] interfaces) { // To prevent re-implementation of this interface. _generated.Add(typeof(ISerializable)); Type[] get_type_args = new Type[] { typeof(String), typeof(bool), typeof(bool) }; Type[] key_and_object = new Type[] { typeof(String), typeof(Object) }; MethodInfo addValueMethod = typeof(SerializationInfo).GetMethod("AddValue", key_and_object); ArgumentReference arg1 = new ArgumentReference(typeof(SerializationInfo)); ArgumentReference arg2 = new ArgumentReference(typeof(StreamingContext)); EasyMethod getObjectData = MainTypeBuilder.CreateMethod("GetObjectData", new ReturnReferenceExpression(typeof(void)), arg1, arg2); LocalReference typeLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(Type)); getObjectData.CodeBuilder.AddStatement(new AssignStatement( typeLocal, new MethodInvocationExpression(null, typeof(Type).GetMethod("GetType", get_type_args), new FixedReference( Context.ProxyObjectReference. AssemblyQualifiedName).ToExpression(), new FixedReference(1).ToExpression(), new FixedReference(0).ToExpression()))); getObjectData.CodeBuilder.AddStatement(new ExpressionStatement( new VirtualMethodInvocationExpression( arg1, typeof(SerializationInfo).GetMethod("SetType"), typeLocal.ToExpression()))); getObjectData.CodeBuilder.AddStatement(new ExpressionStatement( new VirtualMethodInvocationExpression(arg1, addValueMethod, new FixedReference("__interceptor"). ToExpression(), InterceptorField.ToExpression()))); getObjectData.CodeBuilder.AddStatement(new ExpressionStatement( new VirtualMethodInvocationExpression(arg1, addValueMethod, new FixedReference("__mixins"). ToExpression(), MixinField.ToExpression()))); LocalReference interfacesLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(String[])); getObjectData.CodeBuilder.AddStatement( new AssignStatement(interfacesLocal, new NewArrayExpression(interfaces.Length, typeof(String)))); for (int i = 0; i < interfaces.Length; i++) { getObjectData.CodeBuilder.AddStatement(new AssignArrayStatement( interfacesLocal, i, new FixedReference(interfaces[i].AssemblyQualifiedName).ToExpression())); } getObjectData.CodeBuilder.AddStatement(new ExpressionStatement( new VirtualMethodInvocationExpression(arg1, addValueMethod, new FixedReference("__interfaces"). ToExpression(), interfacesLocal.ToExpression()))); getObjectData.CodeBuilder.AddStatement(new ExpressionStatement( new VirtualMethodInvocationExpression(arg1, addValueMethod, new FixedReference("__baseType"). ToExpression(), new TypeTokenExpression(_baseType)))); CustomizeGetObjectData(getObjectData.CodeBuilder, arg1, arg2); getObjectData.CodeBuilder.AddStatement(new ReturnStatement()); }