Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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();
        }
Пример #4
0
        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 });
        }
Пример #5
0
        /// <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"));
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        /// <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()());
        }
Пример #10
0
        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);
        }
Пример #11
0
 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));
 }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
        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);
        }
Пример #15
0
        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));
        }
Пример #16
0
        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);
        }
Пример #17
0
        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);
        }
Пример #18
0
        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);
        }
Пример #19
0
        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);
        }
Пример #20
0
        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[] { }));
        }
Пример #21
0
        /// <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)
                                    )
                                )
                            )
                        )
                    )
                );
        }
Пример #22
0
        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);
        }
Пример #23
0
        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);
        }
Пример #25
0
        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());
        }
Пример #26
0
        /// <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);
        }
Пример #27
0
        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);
            }
        }
Пример #28
0
        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);
        }
Пример #29
0
        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);
        }