/// <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); }
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))))); }
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)); }
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>())); }