Field() 개인적인 메소드

private Field ( Expression expression, FieldInfo field ) : MemberExpression
expression Expression
field System.Reflection.FieldInfo
리턴 MemberExpression
예제 #1
0
        /// <summary>
        /// Takes current result and wraps it into try-filter(MethodUnwinder)-finally block that ensures correct "break" behavior for
        /// Ruby method calls with a block given in arguments.
        ///
        /// Sets up a RFC frame similarly to MethodDeclaration.
        /// </summary>
        internal static void ApplyBlockFlowHandlingInternal(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            // TODO (improvement):
            // We don't special case null block here, although we could (we would need a test for that then).
            // We could also statically know (via call-site flag) that the current method is not a proc-converter (passed by ref),
            // which would make such calls faster.
            if (metaBuilder.Error || !args.Signature.HasBlock)
            {
                return;
            }

            Expression          rfcVariable    = metaBuilder.GetTemporary(typeof(RuntimeFlowControl), "#rfc");
            ParameterExpression methodUnwinder = metaBuilder.GetTemporary(typeof(MethodUnwinder), "#unwinder");
            Expression          resultVariable = metaBuilder.GetTemporary(typeof(object), "#result");

            metaBuilder.Result = Ast.Block(
                // initialize frame (RFC):
                Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)))),
                AstUtils.Try(
                    Ast.Assign(resultVariable, metaBuilder.Result)
                    ).Filter(methodUnwinder, Ast.Equal(Ast.Field(methodUnwinder, MethodUnwinder.TargetFrameField), rfcVariable),

                             // return unwinder.ReturnValue;
                             Ast.Assign(resultVariable, Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField))

                             ).Finally(
                    // we need to mark the RFC dead snce the block might escape and break later:
                    Ast.Assign(Ast.Field(rfcVariable, RuntimeFlowControl.IsActiveMethodField), Ast.Constant(false))
                    ),
                resultVariable
                );
        }
예제 #2
0
 public TExSB(Expression ex) : base(ex)
 {
     bpi       = TExPI.Box(Ex.Field(ex, "bpi"));
     scale     = Ex.Field(ex, "scale");
     direction = new TExV2(Ex.Field(ex, "direction"));
     velocity  = new TExMov(Ex.Field(ex, "movement"));
 }
예제 #3
0
 protected TExSB(ExMode m, string?name) : base(m, name)
 {
     bpi       = TExPI.Box(Ex.Field(ex, "bpi"));
     scale     = Ex.Field(ex, "scale");
     direction = new TExV2(Ex.Field(ex, "direction"));
     velocity  = new TExMov(Ex.Field(ex, "movement"));
 }
예제 #4
0
        public static Func <T, TR> FieldGet <T, TR>(this Type type, string fieldName)
        {
            var param  = Expression.Parameter(type, "arg");
            var member = Expression.Field(param, fieldName);
            var lambda = Expression.Lambda(member, param);

            return((Func <T, TR>)lambda.Compile());
        }
예제 #5
0
 public TExRV2(Expression ex) : base(ex)
 {
     nx    = Ex.Field(ex, "nx");
     ny    = Ex.Field(ex, "ny");
     rx    = Ex.Field(ex, "rx");
     ry    = Ex.Field(ex, "ry");
     angle = Ex.Field(ex, "angle");
 }
예제 #6
0
 public TExRV2(ExMode m, string?name) : base(m, name)
 {
     nx    = Ex.Field(ex, "nx");
     ny    = Ex.Field(ex, "ny");
     rx    = Ex.Field(ex, "rx");
     ry    = Ex.Field(ex, "ry");
     angle = Ex.Field(ex, "angle");
 }
예제 #7
0
        public static Getter <TG> FieldGet <TG>(string fieldName)
        {
            var type   = Expression.Parameter(typeof(T), "type");
            var field  = Expression.Field(type, fieldName);
            var lambda = Expression.Lambda(field, type);

            return((Getter <TG>)lambda.Compile());
        }
        public void MemberAccess_field_expression()
        {
            var expression =
                LinqExpression.Field(
                    LinqExpression.Parameter(typeof(SampleClass)),
                    nameof(SampleClass.InstanceField));

            ShouldRoundrip(expression);
        }
        public void MemberAccess_field_type()
        {
            var expression =
                LinqExpression.Field(
                    null,
                    typeof(SampleClass),
                    nameof(SampleClass.StaticField));

            ShouldRoundrip(expression);
        }
예제 #10
0
        public static Func <object, object> FieldGet(this Type type, string fieldName)
        {
            var param      = Expression.Parameter(typeof(object), "arg");
            var paramCast  = Expression.Convert(param, type);
            var member     = Expression.Field(paramCast, fieldName);
            var memberCast = Expression.Convert(member, typeof(object));
            var lambda     = Expression.Lambda(memberCast, param);

            return((Func <object, object>)lambda.Compile());
        }
예제 #11
0
 protected TExPI(ExMode m, string?name) : base(m, name)
 {
     id     = Ex.Field(ex, "id");
     t      = Ex.Field(ex, "t");
     loc    = Ex.Field(ex, "loc");
     locx   = Ex.Field(loc, "x");
     locy   = Ex.Field(loc, "y");
     index  = Ex.Field(ex, "index");
     findex = Ex.Convert(index, ExUtils.tfloat);
 }
예제 #12
0
파일: Py.cs 프로젝트: alexphaus/py
 Exp Call(Exp obj, string name, Exp arg0)
 {
     return(Exp.Call(obj, Callvirt, Exp.Constant(name),
                     Exp.Block
                     (
                         Exp.Assign(Exp.Field(arg1, "self"), obj),
                         Exp.Assign(Exp.ArrayAccess(Exp.Field(arg1, "Input"), Exp.Constant(0)), arg0),
                         arg1
                     )));
 }
예제 #13
0
        /// <summary>Generate a specific member getter for a specific type</summary>
        /// <typeparam name="T">The type which contains the member</typeparam>
        /// <typeparam name="TResult">The static member's actual type</typeparam>
        /// <param name="memberName">The member's name as defined in <typeparamref name="T"/></param>
        /// <returns>A compiled lambda which can access (get) the static member</returns>
        /// <remarks>Generates a method similar to this:
        /// <code>
        /// TResult GetMethod()
        /// {
        ///     return T.memberName;
        /// }
        /// </code>
        /// </remarks>
        public static Func <TResult> GenerateStaticFieldGetter <T, TResult>(string memberName)
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(memberName));
            Contract.Ensures(Contract.Result <Func <TResult> >() != null);

            var member = Expr.Field(null, typeof(T), memberName);                       // basically 'T.memberName'
            var lambda = Expr.Lambda <Func <TResult> >(member);

            return(lambda.Compile());
        }
예제 #14
0
 public TExPI(Expression ex) : base(ex)
 {
     id     = Ex.Field(ex, "id");
     t      = Ex.Field(ex, "t");
     loc    = Ex.Field(ex, "loc");
     locx   = Ex.Field(loc, "x");
     locy   = Ex.Field(loc, "y");
     index  = Ex.Field(ex, "index");
     findex = Ex.Convert(index, ExUtils.tfloat);
 }
예제 #15
0
 public TExGCX(Expression ex_) : base(ex_)
 {
     fs       = Ex.Field(ex, "fs");
     v2s      = Ex.Field(ex, "v2s");
     v3s      = Ex.Field(ex, "v3s");
     rv2s     = Ex.Field(ex, "rv2s");
     index    = Ex.Field(ex, "index");
     i_float  = Ex.Field(ex, "i").As <float>();
     pi_float = Ex.Field(ex, "pi").As <float>();
     beh_loc  = Ex.Property(ex, "Loc");
     bpi      = Ex.Property(ex, "AsBPI");
 }
예제 #16
0
        public static Setter <TS> FieldSet <TS>(string fieldName)
        {
            var type  = Expression.Parameter(typeof(T), "type");
            var value = Expression.Parameter(typeof(TS), "value");
            var field = Expression.Field(type, fieldName);

#if NET_40 && !WINDOWS_PHONE
            var assign = Expression.Assign(field, value);
#else
            var assign = Expression.Call(MethodInfoAssign, field, value);
#endif
            var lambda = Expression.Lambda(assign, type, value);
            return((Setter <TS>)lambda.Compile());
        }
예제 #17
0
        public void ReplaceMember()
        {
            var x  = V <Vector2>("x");
            var y  = VF("y");
            var ex = Ex.Block(new[] { x }, Ex.Assign(x, ExC(new Vector2(2f, 3f))), Ex.Field(x, "x").Add(ExC(6f)));

            AreEqual("((x=(2.0, 3.0));\n(x.x+6);)", ex.Debug());
            AreEqual("((x=(2.0, 3.0));\n8;)", ex.FlatDebug());
            AreEqual(Compile(ex.Flatten()), 8f);
            ex = Ex.Block(new[] { x }, Ex.Assign(x, ExC(new Vector2(2f, 3f))), Ex.IfThen(y.GT(E1), x.Is(ExC(Vector2.right))), Ex.Add(Ex.Field(x, "x"), ExC(6f)));
            AreEqual("((x=(2.0, 3.0));\nif(y>1){(x=(1.0, 0.0))}else{};\n(x.x+6);)", ex.FlatDebug());
            ex = Ex.Block(new[] { x }, x.Is(ExC(new Vector2(2f, 3f))), Ex.IfThen(y.GT(E1), Ex.Field(x, "x").Is(ExC(6f))), Ex.Add(Ex.Field(x, "x"), ExC(6f)));
            AreEqual("((x=(2.0, 3.0));\nif(y>1){(x.x=6)}else{};\n(x.x+6);)", ex.FlatDebug());
        }
예제 #18
0
        /// <summary>
        /// Takes current result and wraps it into try-filter(MethodUnwinder)-finally block that ensures correct "break" behavior for
        /// library method calls with block given in bfcVariable (BlockParam).
        /// </summary>
        internal static void ApplyBlockFlowHandlingInternal(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            if (metaBuilder.Error)
            {
                return;
            }

            Expression expression  = metaBuilder.Result;
            Expression bfcVariable = metaBuilder.BfcVariable;

            // Method call with proc can invoke control flow that returns an arbitrary value from the call, so we need to type result to Object.
            // Otherwise, the result could only be result of targetExpression unless its return type is void.
            Type resultType = (bfcVariable != null) ? typeof(object) : expression.Type;

            Expression resultVariable;

            if (resultType != typeof(void))
            {
                resultVariable = metaBuilder.GetTemporary(resultType, "#result");
            }
            else
            {
                resultVariable = Expression.Empty();
            }

            if (expression.Type != typeof(void))
            {
                expression = Ast.Assign(resultVariable, AstUtils.Convert(expression, resultType));
            }

            // a non-null proc is being passed to the callee:
            if (bfcVariable != null)
            {
                ParameterExpression methodUnwinder = metaBuilder.GetTemporary(typeof(MethodUnwinder), "#unwinder");

                expression = AstFactory.Block(
                    Ast.Assign(bfcVariable, Methods.CreateBfcForLibraryMethod.OpCall(AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)))),
                    AstUtils.Try(
                        expression
                        ).Filter(methodUnwinder, Methods.IsProcConverterTarget.OpCall(bfcVariable, methodUnwinder),
                                 Ast.Assign(resultVariable, Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField))
                                 ).Finally(
                        Methods.LeaveProcConverter.OpCall(bfcVariable)
                        ),
                    resultVariable
                    );
            }

            metaBuilder.Result = expression;
        }
예제 #19
0
        /// <summary>Generate a specific static field setter for a specific reference type</summary>
        /// <typeparam name="T">The type which contains the member</typeparam>
        /// <typeparam name="TValue">The static member's actual type</typeparam>
        /// <param name="memberName">The member's name as defined in <typeparamref name="T"/></param>
        /// <returns>A compiled lambda which can access (set) the member</returns>
        /// <exception cref="MemberAccessException"><paramref name="memberName"/> is readonly</exception>
        /// <remarks>Generates a method similar to this:
        /// <code>
        /// void SetMethod(TValue value)
        /// {
        ///     T.memberName = value;
        /// }
        /// </code>
        /// </remarks>
        public static Action <TValue> GenerateStaticFieldSetter <T, TValue>(string memberName)
            where T : class
        {
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(memberName));
            Contract.Ensures(Contract.Result <Action <TValue> >() != null);

            var param_value = Expr.Parameter(typeof(TValue), kValueName);                       // the member's new value
            var member      = Expr.Field(null, typeof(T), memberName);                          // i.e., 'T.memberName'

            ValidateMemberForGenerateSetter(member.Member);

            var assign = Expr.Assign(member, param_value);                                              // i.e., 'T.memberName = value'
            var lambda = Expr.Lambda <Action <TValue> >(assign, param_value);

            return(lambda.Compile());
        }
예제 #20
0
        public static Func <object, object, object> FieldSet(this Type type, string fieldName)
        {
            var param     = Expression.Parameter(typeof(object), "arg");
            var paramCast = Expression.Convert(param, type);
            var member    = Expression.Field(paramCast, fieldName);
            var value     = Expression.Parameter(typeof(object), "value");

#if NET_40 && !WINDOWS_PHONE
            var valueCast  = Expression.Convert(value, member.Type);
            var assign     = Expression.Assign(member, valueCast);
            var memberCast = Expression.Convert(assign, typeof(object));
            var lambda     = Expression.Lambda(memberCast, param, value);
#else
            // TODO: Check this alternative
            var memberCast = Expression.Convert(member, typeof(object));
            var assign     = Expression.Call(Class <object> .MethodInfoAssign, memberCast, value);
            var lambda     = Expression.Lambda(assign, param, value);
#endif
            return((Func <object, object, object>)lambda.Compile());
        }
예제 #21
0
 public GlobalExpr()
 {
     expr = LinqExpr.Field(LinqExpr.Constant(this), typeof(GlobalExpr <T>), "x");
 }
예제 #22
0
        /// <summary>
        /// Creates verifier which checks object public properties.
        /// </summary>
        /// <typeparam name="TVerifier">Verifier type.</typeparam>
        /// <param name="propertyFilter">Object public properties filter; can be null to generate code for all the properties.</param>
        /// <param name="checkExprFunc">Function which generates property value check expression (if returns true then check is failed).
        /// Function obtains variable which holds property value and additional arguments.</param>
        /// <param name="createExceptionExpr">New exception creation expression used when check is failed.</param>
        /// <returns>Verifier instance.</returns>
        public static TVerifier Create <TVerifier>(
            Func <Type, bool> propertyFilter,
            Func <Expression, IList <ParameterExpression>, Expr> checkExprFunc,
            LambdaExpression createExceptionExpr) where TVerifier : class
        {
            VerifyUtil.NotNull(checkExprFunc, "checkExprFunc");
            VerifyUtil.NotNull(createExceptionExpr, "createExceptionExpr");

            Type argumentsType = typeof(TVerifier).GetGenericArguments()[0];
            Type type          = argumentsType.GetGenericArguments()[0];

            // Prepare lambda action parameters - first is Argument<T>, others are additionalParamTypes
            var objectParam      = Expr.Parameter(argumentsType);
            var objectVar        = Expr.Parameter(type);
            var genericArguments = typeof(TVerifier).GetGenericArguments();
            var additionalParams = genericArguments.Skip(1).Take(genericArguments.Length - 2).Select(Expr.Parameter).ToList();

            Expr lambdaBody;

            if (type.IsAnonymous())
            {
                // Take createExceptionExpr lambda, extract first parameter from it and replace additional parameters in body
                var exceptionNameParam   = createExceptionExpr.Parameters[0];
                var exceptionObjectParam = createExceptionExpr.Parameters[1];
                var exceptionBody        = createExceptionExpr.ReplaceParams(additionalParams);

                // Obtain type public properties to check
                propertyFilter = propertyFilter ?? (_ => true);
                var properties = type.GetProperties().OrderBy(pi => pi.Name).Where(pi => propertyFilter(pi.PropertyType));

                // Obtain argument values from fields since it's faster
                var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(fi => fi.Name).Where(fi => propertyFilter(fi.FieldType)).ToList();

                // Generate "if (checkExpr) then throw createExceptionExpr;" for each of the properties
                var propertyChecks = properties
                                     .Select(
                    (pi, i) =>
                {
                    var valueVar = Expr.Field(objectVar, fields[i]);
                    return((Expr)Expr.IfThen(
                               checkExprFunc(valueVar, additionalParams),
                               Expr.Throw(
                                   exceptionBody
                                   .Replace(exceptionNameParam, Expr.Constant(pi.Name))
                                   .Replace(exceptionObjectParam, valueVar.ConvertIfNeeded(exceptionObjectParam.Type)))));
                })
                                     .ToList();

                // Prepare null check - if null is supplied then all checks are passed since nothing to check
                var checksBody = propertyChecks.Any()
                                        ? Expr.IfThen(
                    Expr.ReferenceNotEqual(objectVar, Expr.Constant(null, type)),
                    propertyChecks.Count > 1 ? Expr.Block(propertyChecks) : propertyChecks[0])
                                        : null;

                lambdaBody = propertyChecks.Any()
                                        ? (Expr)Expr.Block(
                    new[] { objectVar },
                    new Expr[] { Expr.Assign(objectVar, Expr.Field(objectParam, "Holder")) }
                    .Concat(new[] { checksBody })
                    .Concat(new[] { objectParam }))
                                        : objectParam;
            }
            else
            {
                // Not anonymous type - throw an exception
                lambdaBody = Expr.Block(
                    Expr.Throw(
                        Expr.New(
                            VerifyArgsExceptionCtor,
                            Expr.Constant(string.Format(ErrorMessages.NotAnonymousType, type)))),
                    objectParam);
            }

            // Pull it all together, execute checks only if supplied object is not null
            var lambda = Expr.Lambda <TVerifier>(
                lambdaBody,
                new[] { objectParam }.Concat(additionalParams));

            return(lambda.Compile());
        }
예제 #23
0
 public TExV2(ExMode m, string?name) : base(m, name)
 {
     x = Ex.Field(ex, "x");
     y = Ex.Field(ex, "y");
 }
예제 #24
0
 public TExV2(Expression ex) : base(ex)
 {
     x = Ex.Field(ex, "x");
     y = Ex.Field(ex, "y");
 }
예제 #25
0
        protected override LExpression GetExpressionTreeIfPossible(
            LExpression contextExpression,
            LExpression evalContext)
        {
            // TODO: odczyt const-ów! jak to zrobiæ! bo nie chc¹ siê emitowaæ! kurwa! co za gówno!


            // TODO: czy lock jest potrzebny? tutaj? chyba nie?
            // TODO: czy czasami nie bêdzie tak, ¿e kompilacja ZAWSZE bêdzie w locku???
            lock (this)
            {
                IValueAccessor acc  = null;
                var            name = getText();

                var finalContextExpression = contextExpression;

                var contextExpressionType = contextExpression.Type;
                if (contextExpressionType == typeof(Type) &&
                    contextExpression.NodeType == ExpressionType.Constant)
                {
                    // System.Type or type that it represents (e.g. Int32)
                    contextExpressionType  = (Type)((ConstantExpression)contextExpression).Value;
                    finalContextExpression = null;

                    // try inner type (e.g. Int32)
                    acc = GetPropertyOrFieldAccessor(contextExpressionType, name, BINDING_FLAGS);
                    if (acc == null)
                    {
                        // not found - going back to System.Type
                        contextExpressionType  = contextExpression.Type;
                        finalContextExpression = contextExpression;
                    }
                }

                if (acc == null)
                {
                    acc = GetPropertyOrFieldAccessor(contextExpressionType, name, BINDING_FLAGS);
                }

                var propertyAcc = acc as PropertyValueAccessor;

                if (propertyAcc != null)
                {
                    return(LExpression.Property(
                               finalContextExpression,
                               (PropertyInfo)propertyAcc.MemberInfo));
                }

                var fieldAcc = acc as FieldValueAccessor;
                if (fieldAcc != null)
                {
                    if (fieldAcc.FieldInfo.IsStatic && fieldAcc.FieldInfo.IsLiteral)
                    {
                        // const field - have to JIT a value!
                        object fieldValue = fieldAcc.Get(null);

                        return(LExpression.Constant(
                                   fieldValue,
                                   fieldAcc.FieldInfo.FieldType));
                    }


                    return(LExpression.Field(
                               finalContextExpression,
                               (FieldInfo)fieldAcc.MemberInfo));
                }

                // final call - Type!
                {
                    var type = TypeResolutionUtils.ResolveType(name);
                    if (type != null)
                    {
//                        if (!type.IsValueType)
//                        {
                        return(LExpression.Constant(type, typeof(Type)));
//                        }
//                        else
//                        {
//                            return
//                                LExpression.Convert(
//                                    LExpression.Constant(type, typeof(Type)),
//                                    typeof(object));
//                        }
                    }
                }

                return(null);
            }
        }
예제 #26
0
 public override SysExpr ToExpression() => SysExpr.Field(Expression.ToExpression(), FieldInfo);
예제 #27
0
        private static CloneDelegate <T> GetObjectCloner <T>(Type type, CloneContext context)
        {
            Delegate result;
            var      cache = context.Cache;

            var key = new CacheKey(typeof(T), type);

            if (!cache.TryGetValue(key, out result))
            {
                var statements = new List <LinqExpression>();

                var param        = LinqExpression.Parameter(typeof(T).MakeByRefType(), "input");
                var output       = LinqExpression.Parameter(typeof(T).MakeByRefType(), "output");
                var contextParam = LinqExpression.Parameter(typeof(CloneContext), "context");

                ParameterExpression localCast;
                ParameterExpression localOutput;
                ParameterExpression localObj;
                bool isStruct = type.IsValueType && typeof(T) == type;
                bool isArray  = type.IsArray;

                if (isStruct || isArray)
                {
                    localCast   = param;
                    localOutput = output;
                    localObj    = null;
                }
                else
                {
                    localObj    = LinqExpression.Variable(typeof(object), "localObj");
                    localCast   = LinqExpression.Variable(type, "localCast");
                    localOutput = LinqExpression.Variable(type, "localOut");

                    statements.Add(LinqExpression.Assign(localCast, LinqExpression.Convert(param, type)));

                    if (context.IsSelfClone)
                    {
                        statements.Add(LinqExpression.Call(contextParam, MethodAdd, param, param));
                        statements.Add(LinqExpression.Assign(output, localCast));
                    }
                    else
                    {
                        // NOTE: this can fail if there is no default constructor for type.
                        // for example Dictionary<K,T>.ValueCollection, which is created when a access to members Keys or Values is performed on the dicitonary.
                        statements.Add(LinqExpression.Assign(localOutput, LinqExpression.New(type)));


                        statements.Add(LinqExpression.Assign(output, localOutput));
                        statements.Add(LinqExpression.Call(contextParam, MethodAdd, param, localOutput));
                    }
                }

                var fields = GetFields(type);

                // If we have a struct with primitive only
                if (isArray)
                {
                    var genericCloneMethod = DeepcloneArray.GetGenericMethodDefinition();
                    genericCloneMethod = genericCloneMethod.MakeGenericMethod(new[] { type.GetElementType() });

                    statements.Add(LinqExpression.Call(genericCloneMethod, localCast, localOutput, contextParam));
                }
                else if (isStruct && fields.All(field => IsPrimitive(field.FieldType)))
                {
                    statements.Add(LinqExpression.Assign(localOutput, param));
                }
                else
                {
                    foreach (var field in fields)
                    {
                        if (field.IsInitOnly)
                        {
                            throw new InvalidOperationException(String.Format("Field [{0}] in [{1}] is readonly, which is not supported in DeepClone", field.Name, type));
                        }

                        var t = field.FieldType;
                        if (t.IsSubclassOf(typeof(Delegate)))
                        {
                            continue;
                        }

                        var value = LinqExpression.Field(localCast, field);

                        LinqExpression cloneField = null;
                        if (IsPrimitive(t))
                        {
                            if (!context.IsSelfClone)
                            {
                                cloneField = LinqExpression.Assign(LinqExpression.Field(localOutput, field), value);
                            }
                        }
                        else
                        {
                            MethodInfo genericCloneMethod;
                            if (field.FieldType.IsArray)
                            {
                                genericCloneMethod = DeepcloneArray.GetGenericMethodDefinition();
                                genericCloneMethod = genericCloneMethod.MakeGenericMethod(new[] { field.FieldType.GetElementType() });
                            }
                            else
                            {
                                genericCloneMethod = DeepcloneObject.GetGenericMethodDefinition();
                                genericCloneMethod = genericCloneMethod.MakeGenericMethod(new[] { field.FieldType });
                            }

                            cloneField = LinqExpression.Call(genericCloneMethod, value, context.IsSelfClone ? value : LinqExpression.Field(localOutput, field), contextParam);
                        }

                        if (cloneField != null)
                        {
                            statements.Add(cloneField);
                        }
                    }
                }

                LinqExpression body;
                if (isStruct || isArray)
                {
                    if (statements.Count == 0)
                    {
                        body = LinqExpression.Empty();
                    }
                    else
                    {
                        body = LinqExpression.Block(statements);
                    }
                }
                else
                {
                    var innerBody = LinqExpression.Block(new[] { localCast, localOutput }, statements);

                    body = LinqExpression.Block(
                        new[] { localObj },
                        LinqExpression.IfThenElse(
                            LinqExpression.Call(contextParam, MethodTryGetValue, param, localObj), LinqExpression.Assign(output, LinqExpression.Convert(localObj, typeof(T))), innerBody));
                }

                var tempLambda = LinqExpression.Lambda <CloneDelegate <T> >(body, param, output, contextParam);
                result = tempLambda.Compile();
                cache.Add(key, result);
            }

            return((CloneDelegate <T>)result);
        }
예제 #28
0
 public static Ex dLookupSinDeg(TEx <double> angleDeg) => Ex.Field(dLookupCosSinDeg(angleDeg), "y");
예제 #29
0
        /// <summary>
        /// Builds the childrens iterator.
        /// </summary>
        /// <param name="rootType">Type of the root.</param>
        /// <returns>
        /// A function that is able to process childrens from a node
        /// </returns>
        private static NodeProcessor BuildChildrensIterator(Type rootType)
        {
            var sourceParameter           = LinqExpression.Parameter(typeof(Node), "source");
            var explorerParameter         = LinqExpression.Parameter(typeof(NodeProcessorContext).MakeByRefType(), "nodeProcessorContext");
            var variableNodeProcessor     = LinqExpression.Variable(typeof(NodeProcessor), "nodeProcessor");
            var variableNodeListProcessor = LinqExpression.Variable(typeof(NodeListProcessor), "listProcessor");
            var statements = new List <LinqExpression>();

            // Cast source variable
            var castVar   = LinqExpression.Variable(rootType, "cast");
            var variables = new List <ParameterExpression> {
                castVar, variableNodeProcessor, variableNodeListProcessor
            };

            statements.Add(LinqExpression.Assign(castVar, LinqExpression.Convert(sourceParameter, rootType)));

            statements.Add(LinqExpression.Assign(variableNodeProcessor, LinqExpression.Field(explorerParameter, nodeProcessorProperty)));
            statements.Add(LinqExpression.Assign(variableNodeListProcessor, LinqExpression.Field(explorerParameter, nodeListProcessorProperty)));

            // Get all types from most inherited
            var types = new List <Type>();

            for (var type = rootType; type != null; type = type.GetTypeInfo().BaseType)
            {
                types.Add(type);
            }
            types.Reverse();

            // Iterate on inherited types
            foreach (var type in types)
            {
                // Iterate on all properties in order to create the iterator.
                foreach (var sourceField in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic))
                {
                    // If the property is not read-writable or contains a visitor ignore attribute, skip it
                    if (sourceField.GetCustomAttribute <VisitorIgnoreAttribute>(true) != null)
                    {
                        continue;
                    }

                    var propertyType = sourceField.FieldType;

                    var interfaces = propertyType.GetTypeInfo().ImplementedInterfaces;

                    // Get the property type and check if the property inherit from IList<>
                    if (!typeof(StatementList).GetTypeInfo().IsAssignableFrom(propertyType.GetTypeInfo()))
                    {
                        foreach (var interfaceBase in interfaces)
                        {
                            if (interfaceBase.GetTypeInfo().IsGenericType&& interfaceBase.GetTypeInfo().GetGenericTypeDefinition() == typeof(IList <>))
                            {
                                var parameterType = interfaceBase.GetTypeInfo().GenericTypeArguments[0];
                                if (typeof(Node).GetTypeInfo().IsAssignableFrom(parameterType.GetTypeInfo()))
                                {
                                    statements.Add(
                                        LinqExpression.Invoke(variableNodeListProcessor, LinqExpression.Field(castVar, sourceField), explorerParameter));
                                }
                                break;
                            }
                        }
                    }

                    if (typeof(Node).GetTypeInfo().IsAssignableFrom(propertyType.GetTypeInfo()))
                    {
                        statements.Add(
                            LinqExpression.Assign(
                                LinqExpression.Field(castVar, sourceField),
                                LinqExpression.Convert(LinqExpression.Invoke(variableNodeProcessor, LinqExpression.Field(castVar, sourceField), explorerParameter), propertyType)));
                    }
                }
            }

            // Return source parameter
            statements.Add(sourceParameter);

            // Lambda body
            var block = LinqExpression.Block(variables, statements);

            // Create lambda and return a compiled version
            var lambda = LinqExpression.Lambda <NodeProcessor>(block, sourceParameter, explorerParameter);

            return(lambda.Compile());
        }
예제 #30
0
 public static Ex dLookupSinRad(TEx <double> angleRad) => Ex.Field(dLookupCosSinRad(angleRad), "y");