private ConstructedValueExpression MapTupleParameters(MapTypeContext context, MethodInfo factoryMethod, Type[] typeParams) { var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); var args = new Expression[typeParams.Length]; // We need to assign a value to every parameter. Loop over each parameter and map values where // available. When we run out of columns or have a column we cannot map, fill in a default value. // Where a value type may consume many columns (a custom object type, for example) it will // greedily consume as much as possible before moving to the next parameter. for (var i = 0; i < typeParams.Length; i++) { if (!context.HasColumns()) { args[i] = typeParams[i].GetDefaultValueExpression(); continue; } var elementState = context.ChangeTargetType(typeParams[i]); var expr = _values.Compile(elementState); if (expr.IsNothing) { args[i] = typeParams[i].GetDefaultValueExpression(); continue; } expressions.AddRange(expr.Expressions); variables.AddRange(expr.Variables); args[i] = expr.FinalValue; } return(new ConstructedValueExpression(expressions, Expression.Call(null, factoryMethod, args), variables)); }
public static ConstructedValueExpression GetCollectionPopulateStatements(ICompiler scalars, ICompiler nonScalars, MapTypeContext context, Type elementType, Expression listVar, MethodInfo addMethod) { if (!context.HasColumns()) { return(new ConstructedValueExpression(null)); } var expressions = new List <Expression>(); var variables = new List <ParameterExpression>(); // For scalar types (object is treated like a scalar here), map each column to an entry in the // array, consuming all remaining columns. if (elementType.IsSupportedPrimitiveType() || elementType == typeof(object)) { var columns = context.GetColumns(); foreach (var column in columns) { var columnState = context.GetSubstateForColumn(column, elementType, null); var result = scalars.Compile(columnState); expressions.AddRange(result.Expressions); expressions.Add( Expression.Call( listVar, addMethod, result.FinalValue ) ); variables.AddRange(result.Variables); } return(new ConstructedValueExpression(expressions, null, variables)); } // For all non-scalar types // loop so long as we have columns and consume columns every iteration. var elementState = context.ChangeTargetType(elementType); var numberOfColumns = context.NumberOfColumns(); while (numberOfColumns > 0) { var result = nonScalars.Compile(elementState); var newNumberOfColumns = context.NumberOfColumns(); // We haven't consumed any new columns, so we're done. if (newNumberOfColumns == numberOfColumns) { break; } expressions.AddRange(result.Expressions); expressions.Add( Expression.Call(listVar, addMethod, result.FinalValue) ); variables.AddRange(result.Variables); numberOfColumns = newNumberOfColumns; } return(new ConstructedValueExpression(expressions, null, variables)); }