protected override NodeBase Expand(Context ctx, bool mustReturn) { var leftType = LeftOperand.Resolve(ctx, mustReturn); // create a lambda expression that passes the result of left function to the right one if (leftType.IsCallableType()) { var leftVar = ctx.Unique.TempVariableName(); var rightVar = ctx.Unique.TempVariableName(); var delegateType = ReflectionHelper.WrapDelegate(leftType); var argDefs = delegateType.ArgumentTypes.Select(x => Expr.Arg(ctx.Unique.AnonymousArgName(), x.FullName)).ToArray(); return(Expr.Lambda( argDefs, Expr.Block( Expr.Let(leftVar, LeftOperand), Expr.Let(rightVar, RightOperand), Expr.Invoke( Expr.Get(rightVar), Expr.Invoke( Expr.Get(leftVar), argDefs.Select(x => Expr.Get(x.Name)).ToArray() ) ) ) )); } return(base.Expand(ctx, mustReturn)); }
public static void Refly() { // creating the Refly.Demo namespace NamespaceDeclaration demo = new NamespaceDeclaration("Refly.Demo"); // create the user class ClassDeclaration user = demo.AddClass("User"); // add name field FieldDeclaration name = user.AddField(typeof(string), "name"); // add constructor ConstructorDeclaration cstr = user.AddConstructor(); // add name parameter ParameterDeclaration pname = cstr.Signature.Parameters.Add(typeof(string), "name", true); // this.name = name; cstr.Body.AddAssign( Expr.This.Field(name), Expr.Arg(pname) ); // add property user.AddProperty(name, true, false, false); }
public override void Generate() { this.Prepare(); // create class ClassDeclaration c = this.NamespaceDeclaration.AddClass(PlaybackClassName); // add field FieldDeclaration f = c.AddField(typeof(SequenceGesture), "gesture"); // add method MethodDeclaration build = c.AddMethod("BuildGesture"); ParameterDeclaration factory = build.Signature.Parameters.Add(typeof(GestureFactory), "factory"); // add calls build.Body.AddAssign( Expr.This.Field(f), Expr.New(typeof(SequenceGesture), Expr.Arg(factory).Prop("Form")) ); foreach (IGesture gesture in this.Gestures.Gestures) { Expression expr = gesture.ToCodeDom(Expr.Arg(factory)); build.Body.Add( Expr.This.Field(f).Method("Add").Invoke(expr) ); } this.Compile(); }
public static void ConstructorTest() { FluentCodeCompileUnit compileUnit = new FluentCodeCompileUnit(); compileUnit.Namespace("TestNamespace") .Class("AClass").Inherits("BaseClass") .Constructor(MemberAttributes.Public) .BaseArgs() .EndConstructor .Constructor(MemberAttributes.Public).Parameter(typeof(int), "IntArg") .ThisArgs(Expr.Arg("IntArg"), Expr.Primitive("Hello")) .EndConstructor .Constructor(MemberAttributes.Public).Parameter(typeof(int), "IntArg").Parameter(typeof(string), "StringArg") .BaseArgs(Expr.Arg("StringArg")) .EndConstructor .EndClass .Class("BaseClass") .Constructor(MemberAttributes.Public) .EndConstructor .Constructor(MemberAttributes.Public).Parameter(typeof(string), "TextToPrint") .CallStatic(typeof(Console), "WriteLine", Expr.Arg("TextToPrint")) .EndConstructor .EndClass .EndFluent(); Assembly assembly = TestGenerated(compileUnit.EndFluent()); object instance = GetClassInstance("TestNamespace.AClass", assembly); instance.GetType().GetConstructor(new Type[] { typeof(int) }).Invoke(instance, new object[] { 32 }); }
/// <summary> /// Creates the body of Equals(T). /// </summary> private void CreateSpecificEquals() { var eq = CreateMethod("Equals", "bool", new[] { Expr.Arg("other", Name) }); // var result = true eq.Body.Add(Expr.Var("result", Expr.True())); foreach (var f in _fields.Values) { var left = Expr.GetMember(Expr.This(), f.Name); var right = Expr.GetMember(Expr.Get("other"), f.Name); var isSeq = f.Type.IsGenericType && f.Type.Implements(typeof(IEnumerable <>), true); var expr = isSeq ? Expr.Invoke("Enumerable", "SequenceEqual", left, right) : Expr.Invoke(Expr.This(), "Equals", Expr.Cast(left, "object"), Expr.Cast(right, "object")); eq.Body.Add( Expr.Set( "result", Expr.And(Expr.Get("result"), expr) ) ); } eq.Body.Add(Expr.Get("result")); }
public void MultilineInvocation() { var src = @" test <| true <| (a:double) -> logger.log a a ** 2 <| false"; var result = Expr.Invoke( "test", Expr.True(), Expr.Lambda ( new [] { Expr.Arg("a", "double") }, Expr.Invoke( Expr.Get("logger"), "log", Expr.Get("a") ), Expr.Pow( Expr.Get("a"), Expr.Int(2) ) ), Expr.False() ); TestParser(src, result); }
public void RefFunction2() { var src = @" fun test (a:int x:ref int) -> x = a * 2 var result = 0 test 21 (ref result) result "; var result = new NodeBase[] { Expr.Fun( "test", new [] { Expr.Arg("a", "int"), Expr.Arg("x", "int", true) }, Expr.Set( "x", Expr.Mult(Expr.Get("a"), Expr.Int(2)) ) ), Expr.Var("result", Expr.Int(0)), Expr.Invoke("test", Expr.Int(21), Expr.Ref(Expr.Get("result"))), Expr.Get("result") }; TestParser(src, result); }
public void FluentCall2() { var src = @" Enumerable::Range 1 100 |> Where (i -> i % 2 == 0) |> Select (i -> i * 2)"; var result = Expr.Invoke( Expr.Invoke( Expr.Invoke(Expr.GetMember("Enumerable", "Range"), Expr.Int(1), Expr.Int(100)), "Where", Expr.Lambda( new[] { Expr.Arg("i") }, Expr.Equal(Expr.Mod(Expr.Get("i"), Expr.Int(2)), Expr.Int()) ) ), "Select", Expr.Lambda( new[] { Expr.Arg("i") }, Expr.Mult(Expr.Get("i"), Expr.Int(2)) ) ); TestParser(src, result); }
/// <summary> /// Converts a value from one type to another /// </summary> /// <param name="value">The value to convert</param> /// <param name="type">The type to convert the value to</param> /// <returns>The value converted to the requested type</returns> public static object ChangeType(object value, Type type) { if (value != null && value.GetType() == type) { return(value); } var expression = (Expression)Expression.Constant(value); // Special case for converting from string to enum for metadata filters if (expression.Type == typeof(SqlString) && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>) && type.GetGenericArguments()[0].IsEnum) { var nullCheck = NullCheck(expression); var nullValue = (Expression)Expression.Constant(null); nullValue = Expression.Convert(nullValue, type); var parsedValue = (Expression)Expression.Convert(expression, typeof(string)); parsedValue = Expr.Call(() => Enum.Parse(Expr.Arg <Type>(), Expr.Arg <string>(), Expr.Arg <bool>()), Expression.Constant(type.GetGenericArguments()[0]), parsedValue, Expression.Constant(true)); parsedValue = Expression.Convert(parsedValue, type); expression = Expression.Condition(nullCheck, nullValue, parsedValue); } else if (expression.Type == typeof(SqlString) && type.IsEnum) { expression = (Expression)Expression.Convert(expression, typeof(string)); expression = Expr.Call(() => Enum.Parse(Expr.Arg <Type>(), Expr.Arg <string>(), Expr.Arg <bool>()), Expression.Constant(type), expression, Expression.Constant(true)); expression = Expression.Convert(expression, type); } else { expression = Expression.Convert(expression, type); } expression = Expression.Convert(expression, typeof(object)); return(Expression.Lambda <Func <object> >(expression).Compile()()); }
public void FunWithIfThenElse() { var src = @" fun part (x:int) -> if x > 100 then (new Large x) as TestType else new Small x"; var result = Expr.Fun( "part", new[] { Expr.Arg("x", "int") }, Expr.If( Expr.Greater(Expr.Get("x"), Expr.Int(100)), Expr.Block( Expr.Cast( Expr.New("Large", Expr.Get("x")), "TestType" ) ), Expr.Block( Expr.New("Small", Expr.Get("x")) ) ) ); TestParser(src, result); }
public NativeMethodInvokeExpression Invoke(params ParameterDeclaration[] parameters) { ArgumentReferenceExpression[] args = new ArgumentReferenceExpression[parameters.Length]; for (int i = 0; i < parameters.Length; ++i) { args[i] = Expr.Arg(parameters[i]); } return(Invoke(args)); }
public void SimpleFunction() { var src = @"fun negate:int (x:int) -> -x"; var result = Expr.Fun( "negate", "int", new[] { Expr.Arg("x", "int") }, Expr.Negate(Expr.Get("x")) ); TestParser(src, result); }
public void Algebraic3() { var src = @" type TestType Small of int Large of int fun part:TestType (x:int) -> if x > 100 then (new Large x) as TestType else new Small x var a = part 10 new [ a is TestType; a is Small; a is Large ]"; var result = new NodeBase[] { Expr.Type( "TestType", Expr.Label("Small", "int"), Expr.Label("Large", "int") ), Expr.Fun( "part", "TestType", new [] { Expr.Arg("x", "int") }, Expr.If( Expr.Greater(Expr.Get("x"), Expr.Int(100)), Expr.Block( Expr.Cast( Expr.New("Large", Expr.Get("x")), "TestType" ) ), Expr.Block( Expr.New("Small", Expr.Get("x")) ) ) ), Expr.Var("a", Expr.Invoke("part", Expr.Int(10))), Expr.Array( Expr.Is(Expr.Get("a"), "TestType"), Expr.Is(Expr.Get("a"), "Small"), Expr.Is(Expr.Get("a"), "Large") ) }; TestParser(src, result); }
public void RefArgDeclaration() { var src = "fun test:object (x:int y:ref int) -> y = x"; var result = Expr.Fun ( "test", new TypeSignature("object"), new [] { Expr.Arg("x", "int"), Expr.Arg("y", "int", true) }, Expr.Set("y", Expr.Get("x")) ); TestParser(src, result); }
protected override NodeBase expand(Context ctx, bool mustReturn) { if (_Wrapper.IsPartiallyApplied) { // (expr) _ a b _ // is transformed into // (pa0:T1 pa1:T2) -> (expr) (pa0) (a) (b) (pa1) var argDefs = new List <FunctionArgument>(); var argExprs = new List <NodeBase>(); for (var idx = 0; idx < _ArgTypes.Length; idx++) { if (_ArgTypes[idx] == typeof(UnspecifiedType)) { var argName = ctx.Unique.AnonymousArgName(); argDefs.Add(Expr.Arg(argName, _Wrapper.ArgumentTypes[idx].FullName)); argExprs.Add(Expr.Get(argName)); } else { argExprs.Add(Arguments[idx]); } } return(Expr.Lambda(argDefs, recreateSelfWithArgs(argExprs))); } if (_Wrapper.IsVariadic) { var srcTypes = _ArgTypes; var dstTypes = _Wrapper.ArgumentTypes; var lastDst = dstTypes[dstTypes.Length - 1]; var lastSrc = srcTypes[srcTypes.Length - 1]; // compress items into an array: // fx a b c d // becomes // fx a b (new[ c as X; d as X ]) if (dstTypes.Length > srcTypes.Length || lastDst != lastSrc) { var elemType = lastDst.GetElementType(); var simpleArgs = Arguments.Take(dstTypes.Length - 1); var combined = Expr.Array(Arguments.Skip(dstTypes.Length - 1).Select(x => Expr.Cast(x, elemType)).ToArray()); return(recreateSelfWithArgs(simpleArgs.Union(new[] { combined }))); } } return(base.expand(ctx, mustReturn)); }
public void ParametricLambda2() { var src = "let div = (a:System.Float b:System.Float) -> a / b"; var result = Expr.Let( "div", Expr.Lambda( new[] { Expr.Arg("a", "System.Float"), Expr.Arg("b", "System.Float") }, Expr.Div( Expr.Get("a"), Expr.Get("b") ) ) ); TestParser(src, result); }
public void ParametricLambda() { var src = "a.Where (x:int -> x < 10)"; var result = Expr.Invoke( Expr.Get("a"), "Where", Expr.Lambda( new [] { Expr.Arg("x", "int") }, Expr.Less( Expr.Get("x"), Expr.Int(10) ) ) ); TestParser(src, result); }
public void LinqCall() { var src = @"new [1; 2].Where (x:int -> x > 1)"; var result = Expr.Invoke( Expr.Array(Expr.Int(1), Expr.Int(2)), "Where", Expr.Lambda( new [] { Expr.Arg("x", "int") }, Expr.Greater( Expr.Get("x"), Expr.Int(1) ) ) ); TestParser(src, result); }
public void PureFunction() { var src = @"pure fun add:int (x:int y:int) -> x + y"; var result = Expr.Fun( "add", "int", true, new[] { Expr.Arg("x", "int"), Expr.Arg("y", "int") }, Expr.Add( Expr.Get("x"), Expr.Get("y") ) ); TestParser(src, result); }
private static TInterface ImplentInterface <TInterface>() { Type interfaceType = typeof(TInterface); FluentCodeNamespace ns = new FluentCodeCompileUnit().Namespace("Sample2"); // public class <Interface>Test : <Interface> string typeName = string.Format("{0}Test", interfaceType.Name); var type = ns.Class(typeName).Inherits(interfaceType); foreach (MethodInfo methodInfo in interfaceType.GetMethods()) { // Console.WriteLine("<Method> called with Parameters:") var method = type.Method(MemberAttributes.Public, methodInfo.Name) .CallStatic(typeof(Console), "WriteLine", Expr.Primitive(string.Format("{0} called with parameters:", methodInfo.Name))); foreach (ParameterInfo paramInfo in methodInfo.GetParameters()) { method.Parameter(paramInfo.ParameterType, paramInfo.Name); // Console.WriteLine("<ParamName>: <Value>") method.CallStatic(typeof(Console), "WriteLine", Expr.CallStatic(typeof(string), "Format", Expr.Primitive(string.Format("{0}: {1}", paramInfo.Name, "{1}")), Expr.CallMember(Expr.Arg(paramInfo.Name), "ToString") ) ); } } CodeCompileUnit compileUnit = ns.EndNamespace.EndFluent(); // Display Code string code = Helper.CodeDomHelper.GenerateCodeAsString(compileUnit, new CSharpCodeProvider()); Console.WriteLine(code); Assembly assembly = Helper.CodeDomHelper.CompileInMemory(compileUnit); return((TInterface)assembly.GetType(string.Format("Sample2.{0}", typeName)) .GetConstructor(Type.EmptyTypes) .Invoke(new object[] { })); }
/// <summary> /// Creates the body of Equals(object). /// </summary> private void CreateGenericEquals() { var eq = CreateMethod( "Equals", "bool", new[] { Expr.Arg <object>("obj") }, false, true ); // if(this.ReferenceEquals null obj) // false // else // (this.ReferenceEquals this obj) || ( (obj.GetType () == this.GetType()) && (this.Equals obj as <Name>)) eq.Body.Add( Expr.If( Expr.Invoke(Expr.This(), "ReferenceEquals", Expr.Null(), Expr.Get("obj")), Expr.Block(Expr.False()), Expr.Block( Expr.Or( Expr.Invoke(Expr.This(), "ReferenceEquals", Expr.This(), Expr.Get("obj")), Expr.And( Expr.Equal( Expr.Invoke(Expr.Get("obj"), "GetType"), Expr.Invoke(Expr.This(), "GetType") ), Expr.Invoke( Expr.This(), "Equals", Expr.Cast(Expr.Get("obj"), Name) ) ) ) ) ) ); }
public void MultilineLambda() { var src = @" (a:double) -> logger.log a a ** 2"; var result = Expr.Lambda ( new [] { Expr.Arg("a", "double") }, Expr.Invoke( Expr.Get("logger"), "log", Expr.Get("a") ), Expr.Pow( Expr.Get("a"), Expr.Int(2) ) ); TestParser(src, result); }
public void ComplexFunction() { var src = @" fun hypo:double (a:int b:int) -> let sq1 = a * a let sq2 = b * b sqrt (sq1 + sq2)"; var result = Expr.Fun( "hypo", "double", new[] { Expr.Arg("a", "int"), Expr.Arg("b", "int") }, Expr.Let( "sq1", Expr.Mult( Expr.Get("a"), Expr.Get("a") ) ), Expr.Let( "sq2", Expr.Mult( Expr.Get("b"), Expr.Get("b") ) ), Expr.Invoke( "sqrt", Expr.Add( Expr.Get("sq1"), Expr.Get("sq2") ) ) ); TestParser(src, result); }
public ClassDeclaration AddClass(NamespaceDeclaration ns) { ClassDeclaration col = ns.AddClass(this.DictionaryName); // set base class as CollectionBase col.Parent = new TypeTypeDeclaration(typeof(DictionaryBase)); // default constructor col.AddConstructor(); // add indexer if (this.ItemGet || this.ItemSet) { IndexerDeclaration index = col.AddIndexer( this.ValueType ); ParameterDeclaration pindex = index.Signature.Parameters.Add(KeyType, "key", false); // get body if (this.ItemGet) { index.Get.Return( (Expr.This.Prop("Dictionary").Item(Expr.Arg(pindex)).Cast(this.ValueType) ) ); } // set body if (this.ItemSet) { index.Set.Add( Stm.Assign( Expr.This.Prop("Dictionary").Item(Expr.Arg(pindex)), Expr.Value ) ); } } // add method if (this.Add) { MethodDeclaration add = col.AddMethod("Add"); ParameterDeclaration pKey = add.Signature.Parameters.Add(this.KeyType, "key", true); ParameterDeclaration pValue = add.Signature.Parameters.Add(this.ValueType, "value", true); add.Body.Add( Expr.This.Prop("Dictionary").Method("Add").Invoke(pKey, pValue) ); } // contains method if (this.Contains) { MethodDeclaration contains = col.AddMethod("Contains"); contains.Signature.ReturnType = new TypeTypeDeclaration(typeof(bool)); ParameterDeclaration pKey = contains.Signature.Parameters.Add(this.KeyType, "key", true); contains.Body.Return( Expr.This.Prop("Dictionary").Method("Contains").Invoke(pKey) ); } // remove method if (this.Remove) { MethodDeclaration remove = col.AddMethod("Remove"); ParameterDeclaration pKey = remove.Signature.Parameters.Add(this.KeyType, "key", true); remove.Body.Add( Expr.This.Prop("Dictionary").Method("Remove").Invoke(pKey) ); } return(col); }
private void AddEnumerator(ClassDeclaration c, FieldDeclaration data, MethodDeclaration close) { c.Interfaces.Add(typeof(IEnumerable)); // create subclass ClassDeclaration en = c.AddClass("Enumerator"); // add wrapped field FieldDeclaration wrapped = en.AddField( c, "wrapped" ); ITypeDeclaration enumeratorType = new TypeTypeDeclaration(typeof(IEnumerator)); ITypeDeclaration disposableType = new TypeTypeDeclaration(typeof(IDisposable)); // add IEnumerator en.Interfaces.Add(enumeratorType); en.Interfaces.Add(disposableType); // add constructor ConstructorDeclaration cs = en.AddConstructor(); ParameterDeclaration collection = cs.Signature.Parameters.Add(c, "collection", true); cs.Body.AddAssign(Expr.This.Field(wrapped), Expr.Arg(collection)); // add current PropertyDeclaration current = en.AddProperty(data.Type, "Current"); current.Get.Return( Expr.This.Field(wrapped).Prop("Data") ); // add explicit interface implementation PropertyDeclaration currentEn = en.AddProperty(typeof(Object), "Current"); currentEn.Get.Return(Expr.This.Prop(current)); currentEn.PrivateImplementationType = enumeratorType; // add reset MethodDeclaration reset = en.AddMethod("Reset"); reset.ImplementationTypes.Add(wrapped.Type); reset.Body.Add(Stm.Throw(typeof(InvalidOperationException), Expr.Prim("Not supported"))); // add movenext MethodDeclaration movenext = en.AddMethod("MoveNext"); movenext.ImplementationTypes.Add(wrapped.Type); movenext.Signature.ReturnType = new TypeTypeDeclaration(typeof(bool)); movenext.Body.Return(Expr.This.Field(wrapped).Method("Read").Invoke()); // add dispose MethodDeclaration disposeEn = en.AddMethod("Dispose"); disposeEn.ImplementationTypes.Add(disposableType); disposeEn.Body.Add( Expr.This.Field(wrapped).Method(close).Invoke() ); disposeEn.Body.AddAssign(Expr.This.Field(wrapped), Expr.Null); // add get enuemrator MethodDeclaration geten = c.AddMethod("GetEnumerator"); geten.Signature.ReturnType = en; geten.Body.Return(Expr.New(en, Expr.This)); MethodDeclaration igeten = c.AddMethod("GetEnumerator"); igeten.PrivateImplementationType = new TypeTypeDeclaration(typeof(IEnumerable)); igeten.Signature.ReturnType = new TypeTypeDeclaration(typeof(IEnumerator)); igeten.Body.Return(Expr.This.Method("GetEnumerator").Invoke()); }
/// <summary> /// Produces the required expression to convert values to a specific type /// </summary> /// <param name="expr">The expression that generates the values to convert</param> /// <param name="to">The type to convert to</param> /// <returns>An expression to generate values of the required type</returns> public static Expression Convert(Expression expr, Type to) { if (expr.Type == typeof(SqlDateTime) && (to == typeof(SqlBoolean) || to == typeof(SqlByte) || to == typeof(SqlInt16) || to == typeof(SqlInt32) || to == typeof(SqlInt64) || to == typeof(SqlDecimal) || to == typeof(SqlSingle) || to == typeof(SqlDouble))) { expr = Expression.Condition( Expression.PropertyOrField(expr, nameof(SqlDateTime.IsNull)), Expression.Constant(SqlDouble.Null), Expression.Convert( Expression.PropertyOrField( Expression.Subtract( Expression.Convert(expr, typeof(DateTime)), Expression.Constant(SqlDateTime.MinValue) ), nameof(TimeSpan.TotalDays) ), typeof(SqlDouble) ) ); } if ((expr.Type == typeof(SqlBoolean) || expr.Type == typeof(SqlByte) || expr.Type == typeof(SqlInt16) || expr.Type == typeof(SqlInt32) || expr.Type == typeof(SqlInt64) || expr.Type == typeof(SqlDecimal) || expr.Type == typeof(SqlSingle) || expr.Type == typeof(SqlDouble)) && to == typeof(SqlDateTime)) { expr = Expression.Condition( NullCheck(expr), Expression.Constant(SqlDateTime.Null), Expression.Convert( Expression.Call( Expression.New( typeof(DateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }), Expression.Constant(1900), Expression.Constant(1), Expression.Constant(1) ), typeof(DateTime).GetMethod(nameof(DateTime.MinValue.AddDays)), Expression.Convert( Expression.Convert(expr, typeof(SqlDouble)), typeof(double) ) ), typeof(SqlDateTime) ) ); } if (expr.Type == typeof(SqlString) && to == typeof(EntityCollection)) { expr = Expr.Call(() => ParseEntityCollection(Expr.Arg <SqlString>()), expr); } if (expr.Type == typeof(SqlString) && to == typeof(OptionSetValueCollection)) { expr = Expr.Call(() => ParseOptionSetValueCollection(Expr.Arg <SqlString>()), expr); } if (expr.Type != to) { if (expr.Type == typeof(object) && expr is ConstantExpression constant && constant.Value == null && typeof(INullable).IsAssignableFrom(to)) { return(Expression.Constant(GetNullValue(to))); } expr = Expression.Convert(expr, to); if (to == typeof(SqlString)) { expr = Expr.Call(() => UseDefaultCollation(Expr.Arg <SqlString>()), expr); } } return(expr); }
public override void Generate() { // generate data this.Data.NamespaceDeclaration = this.NamespaceDeclaration; this.Data.Generate(); // generate the rest this.NamespaceDeclaration.Imports.Add("System.Data"); // create class ClassDeclaration c = this.NamespaceDeclaration.AddClass(this.DataReaderName); // IDisposable c.Interfaces.Add(typeof(IDisposable)); // add datareader field FieldDeclaration dr = c.AddField(typeof(IDataReader), "dr"); // add data field FieldDeclaration data = c.AddField( this.Data.DataName , "data"); data.InitExpression = Expr.New(data.Type); PropertyDeclaration datap = c.AddProperty(data, true, false, false); // foreach field values, add get property foreach (DictionaryEntry de in this.Data.Properties) { DictionaryEntry dde = (DictionaryEntry)de.Key; PropertyDeclaration pd = (PropertyDeclaration)de.Value; PropertyDeclaration pcd = c.AddProperty(pd.Type, pd.Name); pcd.Get.Return( Expr.This.Field(data).Prop(pd) ); } // add constructor ConstructorDeclaration cs = c.AddConstructor(); ParameterDeclaration drp = cs.Signature.Parameters.Add(dr.Type, "dr", false); cs.Body.Add(Stm.ThrowIfNull(drp)); cs.Body.Add( Stm.Assign( Expr.This.Field(dr), Expr.Arg(drp) ) ); // add close method MethodDeclaration close = c.AddMethod("Close"); // if dr ==null return; close.Body.Add( Stm.IfNull(Expr.This.Field(dr), Stm.Return()) ); // dr.Close(); close.Body.Add( Expr.This.Field(dr).Method("Close").Invoke() ); // dr = null; close.Body.AddAssign(Expr.This.Field(dr), Expr.Null); // data = null close.Body.AddAssign(Expr.This.Field(data), Expr.Null); // add read method MethodDeclaration read = c.AddMethod("Read"); read.Signature.ReturnType = new TypeTypeDeclaration(typeof(bool)); // if (!dr.Read()){close and return) ConditionStatement ifnotread = Stm.IfIdentity( Expr.This.Field(dr).Method("Read").Invoke(), Expr.False, Stm.ToStm(Expr.This.Method(close).Invoke()), Stm.Return(Expr.False) ); read.Body.Add(ifnotread); // foreach field values foreach (DictionaryEntry de in this.Data.Properties) { DictionaryEntry dde = (DictionaryEntry)de.Key; PropertyDeclaration pd = (PropertyDeclaration)de.Value; read.Body.AddAssign( Expr.This.Field(data).Prop(pd), ( Expr.This.Field(dr).Item(Expr.Prim(dde.Key.ToString())) ).Cast(dde.Value.ToString()) ); } // return true read.Body.Return(Expr.True); // add dispose method MethodDeclaration dispose = c.AddMethod("Dispose"); dispose.ImplementationTypes.Add(typeof(IDisposable)); // Close(); dispose.Body.Add( Expr.This.Method(close).Invoke() ); if (this.Enumerator) { AddEnumerator(c, data, close); } }
internal static Func <object, object> GetPropertyAccessor(PropertyInfo prop, Type targetType) { var rawParam = Expression.Parameter(typeof(object)); var param = SqlTypeConverter.Convert(rawParam, prop.DeclaringType); var value = (Expression)Expression.Property(param, prop); // Extract base value from complex types if (value.Type.IsGenericType && value.Type.GetGenericTypeDefinition() == typeof(Nullable <>)) { value = Expression.Property(value, nameof(Nullable <bool> .Value)); } if (typeof(OptionMetadata).IsAssignableFrom(value.Type)) { value = Expression.Property(value, nameof(OptionMetadata.Value)); } if (value.Type.BaseType != null && value.Type.BaseType.IsGenericType && value.Type.BaseType.GetGenericTypeDefinition() == typeof(ManagedProperty <>)) { value = Expression.Property(value, nameof(ManagedProperty <bool> .Value)); } if (value.Type.BaseType != null && value.Type.BaseType.IsGenericType && value.Type.BaseType.GetGenericTypeDefinition() == typeof(ConstantsBase <>)) { value = Expression.Property(value, nameof(ConstantsBase <bool> .Value)); } if (value.Type.IsArray) { value = Expr.Call(() => String.Join(Expr.Arg <string>(), Expr.Arg <object[]>()), Expression.Constant(","), value); } if (value.Type == typeof(Label)) { value = Expression.Property(value, nameof(Label.UserLocalizedLabel)); } if (value.Type == typeof(LocalizedLabel)) { value = Expression.Condition(Expression.Equal(value, Expression.Constant(null)), SqlTypeConverter.Convert(Expression.Constant(null), typeof(string)), Expression.Property(value, nameof(LocalizedLabel.Label))); } if (value.Type.IsEnum) { value = Expression.Call(value, nameof(Enum.ToString), Array.Empty <Type>()); } if (typeof(MetadataBase).IsAssignableFrom(value.Type)) { value = Expression.Condition(Expression.Equal(value, Expression.Constant(null)), SqlTypeConverter.Convert(Expression.Constant(null), typeof(Guid?)), Expression.Property(value, nameof(MetadataBase.MetadataId))); } var directConversionType = SqlTypeConverter.NetToSqlType(value.Type); if (directConversionType == typeof(SqlString) && value.Type != typeof(string)) { value = Expression.Call(value, nameof(Object.ToString), Array.Empty <Type>()); } var converted = SqlTypeConverter.Convert(value, directConversionType); if (targetType != directConversionType) { converted = SqlTypeConverter.Convert(converted, targetType); } // Return null literal if final value is null if (!value.Type.IsValueType) { value = Expression.Condition(Expression.Equal(value, Expression.Constant(null)), Expression.Constant(SqlTypeConverter.GetNullValue(targetType)), converted); } else { value = converted; } // Return null literal if original value is null if (!prop.PropertyType.IsValueType || prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { value = Expression.Condition(Expression.Equal(Expression.Property(param, prop), Expression.Constant(null)), Expression.Constant(SqlTypeConverter.GetNullValue(targetType)), value); } // Compile the function value = Expr.Box(value); var func = (Func <object, object>)Expression.Lambda(value, rawParam).Compile(); return(func); }
private void AddArrayField(ClassDeclaration c, FieldInfo f) { // create a collection ClassDeclaration col = c.AddClass(conformer.ToSingular(f.Name) + "Collection"); col.Parent = new TypeTypeDeclaration(typeof(System.Collections.CollectionBase)); // add serializable attribute col.CustomAttributes.Add(typeof(SerializableAttribute)); // default constructor col.AddConstructor(); // default indexer IndexerDeclaration index = col.AddIndexer( typeof(Object) ); ParameterDeclaration pindex = index.Signature.Parameters.Add(typeof(int), "index", false); // getter index.Get.Return( Expr.This.Prop("List").Item(Expr.Arg(pindex)) ); index.Set.AddAssign( Expr.This.Prop("List").Item(Expr.Arg(pindex)), Expr.Value ); // add object method MethodDeclaration addObject = col.AddMethod("Add"); ParameterDeclaration paraObject = addObject.Signature.Parameters.Add(new TypeTypeDeclaration(typeof(Object)), "o", true); addObject.Body.Add( Expr.This.Prop("List").Method("Add").Invoke(paraObject) ); // if typed array add methods for type if (f.FieldType.GetElementType() != typeof(Object)) { AddCollectionMethods( col, MapType(f.FieldType.GetElementType()), this.conformer.ToCapitalized(f.FieldType.GetElementType().Name), "o" ); } foreach (XmlElementAttribute ea in f.GetCustomAttributes(typeof(XmlElementAttribute), true)) { string name = this.conformer.ToCapitalized(ea.ElementName); string pname = this.conformer.ToCamel(name); ITypeDeclaration mappedType = null; if (ea.Type != null) { mappedType = MapType(ea.Type); } if (mappedType == null || mappedType == f.FieldType.GetElementType()) { continue; } AddCollectionMethods(col, mappedType, name, pname); } // add field FieldDeclaration fd = c.AddField(col, f.Name); fd.InitExpression = Expr.New(col); PropertyDeclaration p = c.AddProperty(fd, f.Name, true, true, false); // setting attributes // attach xml text if (TypeHelper.HasCustomAttribute(f, typeof(XmlTextAttribute))) { AttributeDeclaration attr = p.CustomAttributes.Add(typeof(XmlTextAttribute)); attr.Arguments.Add("Type", Expr.TypeOf(typeof(string))); // adding to string to collection MethodDeclaration tostring = col.AddMethod("ToString"); tostring.Signature.ReturnType = new TypeTypeDeclaration(typeof(String)); tostring.Attributes = MemberAttributes.Public | MemberAttributes.Override; VariableDeclarationStatement sw = Stm.Var(typeof(StringWriter), "sw"); sw.InitExpression = Expr.New(typeof(StringWriter)); tostring.Body.Add(sw); ForEachStatement fe = Stm.ForEach( typeof(string), "s", Expr.This.Prop("List"), false); fe.Body.Add( Expr.Var(sw).Method("Write").Invoke(fe.Local) ); tostring.Body.Add(fe); tostring.Body.Return(Expr.Var(sw).Method("ToString").Invoke()); } else if (TypeHelper.HasCustomAttribute(f, typeof(XmlArrayItemAttribute))) { // add xml array attribute AttributeDeclaration attr = p.CustomAttributes.Add(typeof(XmlArrayAttribute)); attr.Arguments.Add("ElementName", Expr.Prim(f.Name)); // add array item attribute XmlArrayItemAttribute arrayItem = (XmlArrayItemAttribute)TypeHelper.GetFirstCustomAttribute(f, typeof(XmlArrayItemAttribute)); attr = p.CustomAttributes.Add(typeof(XmlArrayItemAttribute)); attr.Arguments.Add("ElementName", Expr.Prim(arrayItem.ElementName)); //MMI:attr.Arguments.Add("Type",Expr.Prim(MapType(f.FieldType.GetElementType()).Name)); attr.Arguments.Add("Type", Expr.TypeOf(MapType(f.FieldType.GetElementType()))); if (arrayItem.Type != null) { attr.Arguments.Add("DataType", Expr.Prim(arrayItem.DataType)); } attr.Arguments.Add("IsNullable", Expr.Prim(arrayItem.IsNullable)); if (this.Config.KeepNamespaces) { attr.Arguments.Add("Namespace", Expr.Prim(arrayItem.Namespace)); } } else { AttachXmlElementAttributes(p, f); } }
public ClassDeclaration AddClass(NamespaceDeclaration ns) { ClassDeclaration col = ns.AddClass(this.CollectionName); // set base class as CollectionBase col.Parent = new TypeTypeDeclaration(typeof(CollectionBase)); // default constructor col.AddConstructor(); // add indexer if (this.ItemGet || this.ItemSet) { IndexerDeclaration index = col.AddIndexer( this.Type ); ParameterDeclaration pindex = index.Signature.Parameters.Add(typeof(int), "index", false); // get body if (this.ItemGet) { index.Get.Return( (Expr.This.Prop("List").Item(Expr.Arg(pindex)).Cast(this.Type) ) ); } // set body if (this.ItemSet) { index.Set.Add( Stm.Assign( Expr.This.Prop("List").Item(Expr.Arg(pindex)), Expr.Value ) ); } } string pname = ns.Conformer.ToCamel(this.Type.Name); // add method if (this.Add) { MethodDeclaration add = col.AddMethod("Add"); ParameterDeclaration para = add.Signature.Parameters.Add(this.Type, pname, true); add.Body.Add( Expr.This.Prop("List").Method("Add").Invoke(para) ); } if (this.AddRange) { MethodDeclaration add = col.AddMethod("AddRange"); ParameterDeclaration para = add.Signature.Parameters.Add(col, pname, true); ForEachStatement fe = Stm.ForEach( this.Type, "item", Expr.Arg(para), false ); fe.Body.Add( Expr.This.Prop("List").Method("Add").Invoke(fe.Local) ); add.Body.Add(fe); } // contains method if (this.Contains) { MethodDeclaration contains = col.AddMethod("Contains"); contains.Signature.ReturnType = new TypeTypeDeclaration(typeof(bool)); ParameterDeclaration para = contains.Signature.Parameters.Add(this.Type, pname, true); contains.Body.Return( Expr.This.Prop("List").Method("Contains").Invoke(para) ); } // remove method if (this.Remove) { MethodDeclaration remove = col.AddMethod("Remove"); ParameterDeclaration para = remove.Signature.Parameters.Add(this.Type, pname, true); remove.Doc.Summary.AddText("Removes the first occurrence of a specific ParameterDeclaration from this ParameterDeclarationCollection."); remove.Body.Add( Expr.This.Prop("List").Method("Remove").Invoke(para) ); } // insert if (this.Insert) { MethodDeclaration insert = col.AddMethod("Insert"); ParameterDeclaration index = insert.Signature.Parameters.Add(typeof(int), "index", true); ParameterDeclaration para = insert.Signature.Parameters.Add(this.Type, pname, true); insert.Body.Add( Expr.This.Prop("List").Method("Insert").Invoke(index, para) ); } // indexof if (this.IndexOf) { MethodDeclaration indexof = col.AddMethod("IndexOf"); ParameterDeclaration para = indexof.Signature.Parameters.Add(this.Type, pname, true); indexof.Signature.ReturnType = new TypeTypeDeclaration(typeof(int)); indexof.Body.Return( Expr.This.Prop("List").Method("IndexOf").Invoke(para) ); } if (this.Enumerator) { // create subclass ClassDeclaration en = col.AddClass("Enumerator"); // add wrapped field FieldDeclaration wrapped = en.AddField( typeof(IEnumerator), "wrapped" ); // add IEnumerator en.Interfaces.Add(typeof(IEnumerator)); // add constructor ConstructorDeclaration cs = en.AddConstructor(); ParameterDeclaration collection = cs.Signature.Parameters.Add(col, "collection", true); cs.Body.Add( Stm.Assign( Expr.This.Field(wrapped), Expr.Arg(collection).Cast(typeof(CollectionBase)).Method("GetEnumerator").Invoke() ) ); // add current PropertyDeclaration current = en.AddProperty(this.Type, "Current"); current.Get.Return( (Expr.This.Field(wrapped).Prop("Current")).Cast(this.Type) ); // add explicit interface implementation PropertyDeclaration currentEn = en.AddProperty(typeof(Object), "Current"); currentEn.Get.Return(Expr.This.Prop(current)); currentEn.PrivateImplementationType = wrapped.Type; // add reset MethodDeclaration reset = en.AddMethod("Reset"); reset.ImplementationTypes.Add(wrapped.Type); reset.Body.Add(Expr.This.Field(wrapped).Method("Reset").Invoke()); // add movenext MethodDeclaration movenext = en.AddMethod("MoveNext"); movenext.ImplementationTypes.Add(wrapped.Type); movenext.Signature.ReturnType = new TypeTypeDeclaration(typeof(bool)); movenext.Body.Return(Expr.This.Field(wrapped).Method("MoveNext").Invoke()); // add get enuemrator MethodDeclaration geten = col.AddMethod("GetEnumerator"); geten.Attributes |= MemberAttributes.New; geten.ImplementationTypes.Add(new TypeTypeDeclaration(typeof(IEnumerable))); geten.Signature.ReturnType = en; geten.Body.Return(Expr.New(en, Expr.This)); } return(col); }