Beispiel #1
0
        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));
        }
Beispiel #2
0
        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());
        }