Example #1
0
        private void AppendTupleElements(
            StringBuilder builder,
            Type type,
            int cardinality,
            ReadOnlyCollection <byte> dynamicFlags,
            ref int dynamicFlagIndex,
            ReadOnlyCollection <string> tupleElementNames,
            ref int tupleElementIndex,
            bool escapeKeywordIdentifiers,
            out bool sawInvalidIdentifier)
        {
            sawInvalidIdentifier = false;
            int nameIndex = tupleElementIndex;

            tupleElementIndex += cardinality;
            builder.Append('(');
            bool any = false;

            while (true)
            {
                var typeArguments = type.GetGenericArguments();
                int nTypeArgs     = typeArguments.Length;
                Debug.Assert(nTypeArgs > 0);
                Debug.Assert(nTypeArgs <= TypeHelpers.TupleFieldRestPosition);
                int nFields = Math.Min(nTypeArgs, TypeHelpers.TupleFieldRestPosition - 1);
                for (int i = 0; i < nFields; i++)
                {
                    if (any)
                    {
                        builder.Append(", ");
                    }
                    bool sawSingleInvalidIdentifier;
                    var  name = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, nameIndex);
                    nameIndex++;
                    AppendTupleElement(
                        builder,
                        typeArguments[i],
                        name,
                        dynamicFlags,
                        ref dynamicFlagIndex,
                        tupleElementNames,
                        ref tupleElementIndex,
                        escapeKeywordIdentifiers,
                        sawInvalidIdentifier: out sawSingleInvalidIdentifier);
                    sawInvalidIdentifier |= sawSingleInvalidIdentifier;
                    any = true;
                }
                if (nTypeArgs < TypeHelpers.TupleFieldRestPosition)
                {
                    break;
                }
                Debug.Assert(!DynamicFlagsCustomTypeInfo.GetFlag(dynamicFlags, dynamicFlagIndex));
                dynamicFlagIndex++;
                type = typeArguments[nTypeArgs - 1];
            }
            builder.Append(')');
        }
Example #2
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));
        }
Example #3
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());
        }