public ConstructedValueExpression Compile(MapTypeContext context) { if (!IsSupportedType(context.TargetType)) { return(ConstructedValueExpression.Nothing); } // Element type and constructor should both always be available for Array types, and // we know this is an array type in MapCompiler. Just assume we have these things, but // Debug.Assert them just to be sure. var elementType = context.TargetType.GetElementType(); Debug.Assert(elementType != null); var constructor = context.TargetType.GetConstructor(new[] { typeof(int) }); Debug.Assert(constructor != null); if (elementType.IsMappableCustomObjectType()) { return(CompileArrayOfCustomObject(context, elementType, constructor)); } // In an array, object is always treated as a scalar type if (elementType.IsSupportedPrimitiveType() || elementType == typeof(object)) { var columns = context.GetColumns().ToList(); return(CompileArrayOfScalar(context, constructor, columns, elementType)); } // It's not a type we know how to support, so do nothing return(ConstructedValueExpression.Nothing); }
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)); }
public ConstructedValueExpression Compile(MapTypeContext context) { if (context.TargetType != typeof(object)) { return(ConstructedValueExpression.Nothing); } // At the top-level (name==null) we convert to dictionary to preserve column name information if (context.Name == null) { // Dictionary mapping logic will group by key name and recurse. When we get back to the // ObjectCompiler, we will have a smaller set of columns and we will have a non-null name var dictState = context.ChangeTargetType(typeof(Dictionary <string, object>)); var dictExpr = _dictionaries.Compile(dictState); return(new ConstructedValueExpression(dictExpr.Expressions, Expression.Convert(dictExpr.FinalValue, typeof(object)), dictExpr.Variables)); } var columns = context.GetColumns().ToList(); var numColumns = columns.Count; // If we have no columns, just return null if (numColumns == 0) { return(new ConstructedValueExpression( Expression.Convert( Expression.Constant(null), typeof(object) ) )); } // If we have exactly one column, map the value as a scalar and return a single result if (numColumns == 1) { var firstColumn = columns[0]; var objectState = context.GetSubstateForColumn(firstColumn, typeof(object), null); var asScalar = _scalars.Compile(objectState); return(new ConstructedValueExpression(asScalar.Expressions, Expression.Convert(asScalar.FinalValue, typeof(object)), asScalar.Variables)); } // If we have more than one column, map to object[] var arrayState = context.ChangeTargetType(typeof(object[])); var exprs = _arrays.Compile(arrayState); return(new ConstructedValueExpression(exprs.Expressions, Expression.Convert(exprs.FinalValue, typeof(object)), exprs.Variables)); }