private static Fields GetFields(TypeAndCustomInfo declaringTypeAndInfo, int cardinality, bool useRawView) { Debug.Assert(declaringTypeAndInfo.Type.GetTupleCardinalityIfAny() == cardinality); var appDomain = declaringTypeAndInfo.ClrType.AppDomain; var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaringTypeAndInfo); var tupleElementNames = customTypeInfoMap.TupleElementNames; var builder = ArrayBuilder <Field> .GetInstance(); Field parent = null; int offset = 0; bool includeRawView = false; while (true) { var declaringType = declaringTypeAndInfo.Type; int n = Math.Min(cardinality, TypeHelpers.TupleFieldRestPosition - 1); for (int index = 0; index < n; index++) { var fieldName = TypeHelpers.GetTupleFieldName(index); var field = declaringType.GetTupleField(fieldName); if (field == null) { // Ignore missing fields. continue; } var fieldTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, field, customTypeInfoMap); if (!useRawView) { var name = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, offset + index); if (name != null) { includeRawView = true; builder.Add(new Field(declaringTypeAndInfo, fieldTypeAndInfo, field, name, parent, isRest: false)); continue; } } builder.Add(new Field( declaringTypeAndInfo, fieldTypeAndInfo, field, (offset == 0) ? fieldName : TypeHelpers.GetTupleFieldName(offset + index), parent, isRest: false)); } cardinality -= n; if (cardinality == 0) { break; } var rest = declaringType.GetTupleField(TypeHelpers.TupleFieldRestName); if (rest == null) { // Ignore remaining fields. break; } var restTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, rest, customTypeInfoMap); var restField = new Field(declaringTypeAndInfo, restTypeAndInfo, rest, TypeHelpers.TupleFieldRestName, parent, isRest: true); if (useRawView) { builder.Add(restField); break; } includeRawView = true; parent = restField; declaringTypeAndInfo = restTypeAndInfo; offset += TypeHelpers.TupleFieldRestPosition - 1; } return(new Fields(builder.ToImmutableAndFree(), includeRawView)); }
private static ReadOnlyCollection <Field> GetFields(TypeAndCustomInfo declaringTypeAndInfo, int cardinality) { Debug.Assert(declaringTypeAndInfo.Type.GetTupleCardinalityIfAny() == cardinality); var appDomain = declaringTypeAndInfo.ClrType.AppDomain; var customTypeInfoMap = CustomTypeInfoTypeArgumentMap.Create(declaringTypeAndInfo); var tupleElementNames = customTypeInfoMap.TupleElementNames; var builder = ArrayBuilder <Field> .GetInstance(); Field parent = null; int offset = 0; while (true) { var declaringType = declaringTypeAndInfo.Type; int n = Math.Min(cardinality, TypeHelpers.TupleFieldRestPosition - 1); for (int index = 0; index < n; index++) { var fieldName = TypeHelpers.GetTupleFieldName(index); var field = declaringType.GetTupleField(fieldName); if (field == null) { // Ignore missing fields. continue; } var fieldTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, field, customTypeInfoMap); var name = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, offset + index); if (name != null) { builder.Add(new Field(declaringTypeAndInfo, fieldTypeAndInfo, field, name, parent)); } builder.Add(new Field( declaringTypeAndInfo, fieldTypeAndInfo, field, (offset == 0) ? fieldName : TypeHelpers.GetTupleFieldName(offset + index), parent)); } cardinality -= n; if (cardinality == 0) { break; } var rest = declaringType.GetTupleField(TypeHelpers.TupleFieldRestName); if (rest == null) { // Ignore remaining fields. break; } var restTypeAndInfo = GetTupleFieldTypeAndInfo(appDomain, rest, customTypeInfoMap); parent = new Field(declaringTypeAndInfo, restTypeAndInfo, rest, TypeHelpers.TupleFieldRestName, parent); declaringTypeAndInfo = restTypeAndInfo; offset += TypeHelpers.TupleFieldRestPosition - 1; } // If there were any nested ValueTuples, // add the Rest field of the outermost. if (parent != null) { while (parent.Parent != null) { parent = parent.Parent; } builder.Add(parent); } return(builder.ToImmutableAndFree()); }