Beispiel #1
0
        /// <summary>
        /// Get a mapped object from cache if present. Create it otherwise by using the given delegate.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="targetType"></param>
        /// <param name="includeChain"></param>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static Expression GetOrSet(Expression source, Type targetType, Expression includeChain, Expression builder)
        {
            object dummy;
            ParameterExpression varResult = Expression.Variable(typeof(object));
            var resultExpression          = Expression.Block(
                new[] { varResult },
                Expression.IfThen(Expression.IsFalse(
                                      Expression.Call(
                                          Expression.Field(null, Meta.Field(() => MapperCache.Cache)),
                                          Meta <Dictionary <Tuple <object, Type>, object> > .Method(x => x.TryGetValue(default(Tuple <object, Type>), out dummy)),
                                          Expression.Call(
                                              null,
                                              Meta.Method(() => Tuple.Create <object, Type>(null, default(Type))),
                                              source.Convert(typeof(object)),
                                              Expression.Constant(targetType)
                                              ),
                                          varResult
                                          )),
                                  Expression.Assign(varResult, builder.Convert(typeof(object)))
                                  ),
                varResult.Convert(targetType)
                );

            return(resultExpression);
        }
        /// <summary>
        ///   Gets a function that accepts a <see cref="Tuple"/> and returns an iterator.
        /// </summary>
        /// <param name="tupleType">The type of the tuple.</param>
        /// <returns>A function that takes a <see cref="Tuple"/> and returns the enumerator.</returns>
        public static Func <object, IEnumerable> GetTupleIterator([NotNull] this Type tupleType)
        {
            return(_tupleIterators.GetOrAdd(
                       tupleType,
                       t =>
            {
                // Create extended tuple type
                Type extendedType = typeof(ExtendedTuple <>).MakeGenericType(tupleType);

                // Create parameter
                ParameterExpression tupleObjectParameter = Expression.Parameter(typeof(object), "tuple");

                // Convert parameter from object to tuple type.
                Expression castTuple = tupleObjectParameter.Convert(tupleType);

                // Find constructor that takes the tuple type
                ConstructorInfo constructor = extendedType.GetConstructor(new[] { tupleType });
                Debug.Assert(constructor != null);

                // Create a lambda that creates a new ExtendedTuple<tupletype> and casts it to an IEnumerable.
                return Expression.Lambda <Func <object, IEnumerable> >(
                    Expression.New(constructor, castTuple).Convert(typeof(IEnumerable)),
                    tupleObjectParameter).
                Compile();
            }));
        }
        public static Func <object, int, object> GetTupleIndexer([NotNull] this Type tupleType)
        {
            Func <object, int, object> indexer = _tupleIndexers.GetOrAdd(
                tupleType,
                t =>
            {
                // Create extended tuple type
                Type extendedType = typeof(ExtendedTuple <>).MakeGenericType(tupleType);

                // Create parameters
                ParameterExpression tupleObjectParameter = Expression.Parameter(typeof(object), "tuple");
                ParameterExpression indexParameter       = Expression.Parameter(typeof(int), "index");

                // Convert parameter from object to tuple type.
                Expression castTuple = tupleObjectParameter.Convert(tupleType);

                // Get the indexer lambda and convert to a constant
                Expression lambda = Expression.Constant(
                    // ReSharper disable once PossibleNullReferenceException
                    extendedType.GetField("Indexer", BindingFlags.Static | BindingFlags.Public)
                    .GetValue(null));

                return(Expression.Lambda <Func <object, int, object> >(
                           Expression.Invoke(lambda, castTuple, indexParameter),
                           tupleObjectParameter,
                           indexParameter).Compile());
            });

            Debug.Assert(indexer != null);
            return(indexer);
        }
Beispiel #4
0
        public override Expression Reduce()
        {
            var end_finally = Expression.Label("end_finally");

            return(Expression.Block(
                       new[] { variable },
                       variable.Assign(disposable),
                       Expression.TryFinally(
                           body,
                           Expression.Block(
                               variable.NotEqual(Expression.Constant(null)).Condition(
                                   Expression.Block(
                                       Expression.Call(
                                           variable.Convert(typeof(IDisposable)),
                                           typeof(IDisposable).GetMethod("Dispose")),
                                       Expression.Goto(end_finally)),
                                   Expression.Goto(end_finally)),
                               Expression.Label(end_finally)))));
        }
Beispiel #5
0
        private Expression BuildDeclarationExpression(Stack <Token> stack, ParameterExpression p)
        {
            var token = stack.Pop();

            if (token.Type != TokenType.Identifier)
            {
                throw new XPressionException(token.Source, "Expected an identifier", token.Position);
            }
            var vars = NestedVars.GetVars(stack, Grammar.IgnoreCase);

            if (vars.ContainsKey(token.Lexeme))
            {
                throw new XPressionException(token.Source, "Duplicate variable declaration: " + token.Lexeme, token.Position);
            }
            if (p.Type.GetPropertyOrFieldMember(token.Lexeme, Grammar.IgnoreCase) != null)
            {
                throw new XPressionException(token.Source, "Invalid variable declaration: " + token.Lexeme, token.Position);
            }
            vars.Add(token.Lexeme, null);
            return(Expression.Call(MemberTokens.Variables.Declare, p.Convert <object>(), Expression.Constant(token.Lexeme)));
        }
 /// <summary>
 /// Get the right filler delegate from the cache depending on the real type of the source and the target.
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public static Action <TSource, TTarget, IncludeChain> GetFillerByType(Tuple <Type, Type, MapMode> key)
 {
     return(_CacheFillers.GetOrAdd(key, k =>
     {
         Type sourceType = typeof(TSource);
         Type targetRealType = k.Item2;
         ParameterExpression paramSource = Expression.Parameter(sourceType);
         ParameterExpression paramTarget = Expression.Parameter(typeof(TTarget));
         ParameterExpression paramInclude = Expression.Parameter(typeof(IncludeChain));
         ParameterExpression varRealTypeTarget = Expression.Parameter(targetRealType);
         Dictionary <Type, GenericAssociation> genericTypeAssociation;
         var mapInfo = MapInfo.Get(k.Item1, targetRealType, true, out genericTypeAssociation);
         if (mapInfo == null)
         {
             return (source, target, include) => { }
         }
         ;
         var body = Expression.Block(
             new ParameterExpression[] { varRealTypeTarget },
             Expression.Assign(varRealTypeTarget, paramTarget.Convert(targetRealType)),
             MapBuilder.CreateBuilderExpression(
                 mapMode: k.Item3,
                 mapInfo: mapInfo,
                 genericTypeAssociation: genericTypeAssociation,
                 paramSource: paramSource,
                 varResult: varRealTypeTarget,
                 paramIncludeChain: paramInclude,
                 usedBuilders: null),
             varRealTypeTarget
             );
         return Expression.Lambda <Action <TSource, TTarget, IncludeChain> >(
             body,
             paramSource,
             paramTarget,
             paramInclude
             ).Compile();
     }));
 }
        public RouteDelegate GetRouteDelegate(IStateMember member, Type runtimeMemberType)
        {
            ParameterExpression processor          = Expression.Parameter(typeof(object), "processor");
            ParameterExpression owner              = Expression.Parameter(typeof(object), "owner");
            ParameterExpression skipSpecialMethods = Expression.Parameter(typeof(bool), "skipSpecialMethods");

            var castedProcessor =
                processor.Convert(_processorType);

            DescriptorWriter descriptorWriter = new DescriptorWriter(_climbStore);

            DescriptorVariable descriptor =
                descriptorWriter.GetDescriptor(processor, owner, member, runtimeMemberType);

            MethodInfo methodToCall =
                _methodMapper.GetMethod(_processorType, member, runtimeMemberType, true);

            MethodCallExpression callProcess =
                Expression.Call(castedProcessor, methodToCall, descriptor.Reference);

            Expression callProcessWithSpecialMethods =
                _specialMutator.Mutate(callProcess, castedProcessor, owner, member, descriptor.Reference);

            BlockExpression body =
                Expression.Block(new[] { descriptor.Reference },
                                 descriptor.Declaration,
                                 Expression.Condition(skipSpecialMethods,
                                                      callProcess,
                                                      callProcessWithSpecialMethods));

            Expression <RouteDelegate> lambda =
                Expression.Lambda <RouteDelegate>(body,
                                                  "Route_" + runtimeMemberType.Name,
                                                  new[] { processor, owner, skipSpecialMethods });

            return(_compiler.Compile(lambda));
        }
Beispiel #8
0
        private Expression BuildAssignmentExpression(Stack <Token> stack, ParameterExpression p)
        {
            Type varType;
            Dictionary <string, Type> vars;
            MethodInfo setter;

            var right = PopExpression(stack, p);
            var token = stack.Pop();

            if (token.Type != TokenType.Identifier)
            {
                if (token.Type == TokenType.Expression && Grammar.ImplementsVariables)
                {
                    var expr = token.CastTo <ExpressionToken>().Expression as MethodCallExpression;
                    if (expr != null && expr.Method == MemberTokens.Variables.Declare)
                    {
                        // left token is declaration
                        var name = (string)expr.Arguments[1].CastTo <ConstantExpression>().Value;
                        vars = NestedVars.GetVars(stack, Grammar.IgnoreCase);
                        vars.TryGetValue(name, out varType);
                        if (varType == null)
                        {
                            vars[name] = right.Type;
                        }
                        setter = Grammar.IgnoreCase ? MemberTokens.VariablesIgnoreCase.Set : MemberTokens.Variables.Set;
                        return(Expression.And(expr,
                                              Expression.Call(setter, p.Convert <object>(), Expression.Constant(name),
                                                              right.Convert <object>())));
                    }
                }
                throw new XPressionException(token.Source, "Expected an identifier or declaration", token.Position);
            }

            var segmented = token as SegmentedIdentifierToken;

            var memberExpression = segmented != null
            ? p.GetMemberExpression(segmented.Segments, Grammar.IgnoreCase)
            : p.GetMemberExpression(token.Lexeme, Grammar.IgnoreCase);

            if (memberExpression != null)
            {
                var memberType = memberExpression.Member.GetMemberType();
                if (!right.Type.CanBeConvertedInto(memberType))
                {
                    throw new XPressionException(token.Source, string.Format("Invalid cast. Cannot cast from {0} to {1}", right.Type.Name, memberType.Name), token.Position);
                }
                return(Expression.Call(MemberTokens.Assignment.Set, memberExpression.Expression.Convert <object>(), Expression.Constant(memberExpression.Member), right.Convert <object>()));
            }

            if (!Grammar.ImplementsVariables)
            {
                throw new XPressionException(token.Source, "Member not found: " + token.Lexeme, token.Position);
            }

            vars = NestedVars.GetVars(stack, Grammar.IgnoreCase);

            if (!vars.TryGetValue(token.Lexeme, out varType))
            {
                throw new XPressionException(token.Source, "Variable not declared: " + token.Lexeme, token.Position);
            }
            if (varType == null)
            {
                vars[token.Lexeme] = (varType = right.Type);
            }
            if (!right.Type.CanBeConvertedInto(varType))
            {
                throw new XPressionException(token.Source, string.Format("Invalid cast. Cannot cast from {0} to {1}", right.Type.Name, varType.Name), token.Position);
            }
            setter = Grammar.IgnoreCase ? MemberTokens.VariablesIgnoreCase.Set : MemberTokens.Variables.Set;
            return(Expression.Call(setter, p.Convert <object>(), Expression.Constant(token.Lexeme), right.Convert <object>()));
        }