예제 #1
0
        internal static IExtendedType ChangeNullability(
            IExtendedType type,
            ReadOnlySpan <bool?> nullable,
            TypeCache cache)
        {
            if (nullable.Length == 0)
            {
                return(type);
            }

            ExtendedTypeId id = Tools.CreateId(type, nullable);

            if (cache.TryGetType(id, out ExtendedType? extendedType))
            {
                return(extendedType);
            }

            var pos = 0;

            return(ChangeNullability(id, (ExtendedType)type, nullable, ref pos, cache));
        }
예제 #2
0
 public bool Equals(ExtendedTypeId other) =>
 Type == other.Type &&
 Nullability == other.Nullability &&
 Kind == other.Kind;
예제 #3
0
        private static ExtendedType ChangeNullability(
            ExtendedTypeId id,
            ExtendedType type,
            ReadOnlySpan <bool?> nullable,
            ref int position,
            TypeCache cache)
        {
            if (cache.TryGetType(id, out ExtendedType? cached))
            {
                return(cached);
            }

            var pos = position++;
            var changeNullability =
                nullable.Length > pos &&
                nullable[pos].HasValue &&
                nullable[pos] !.Value != type.IsNullable;
            IReadOnlyList <ExtendedType> typeArguments = type.TypeArguments;

            if (type.TypeArguments.Count > 0 && nullable.Length > position)
            {
                var args = new ExtendedType[type.TypeArguments.Count];

                for (var j = 0; j < type.TypeArguments.Count; j++)
                {
                    ExtendedType   typeArgument   = type.TypeArguments[j];
                    ExtendedTypeId typeArgumentId =
                        Tools.CreateId(typeArgument, nullable.Slice(position));

                    args[j] = nullable.Length > position
                        ? ChangeNullability(
                        typeArgumentId,
                        typeArgument,
                        nullable,
                        ref position,
                        cache)
                        : type.TypeArguments[j];
                }

                typeArguments = args;
            }

            if (changeNullability || !ReferenceEquals(typeArguments, type.TypeArguments))
            {
                ExtendedType?elementType = type.IsArrayOrList
                    ? type.ElementType
                    : null;

                if (elementType is not null &&
                    !ReferenceEquals(typeArguments, type.TypeArguments))
                {
                    for (var e = 0; e < type.TypeArguments.Count; e++)
                    {
                        if (ReferenceEquals(elementType, type.TypeArguments[e]))
                        {
                            elementType = typeArguments[e];
                        }
                    }
                }

                var rewritten = new ExtendedType(
                    type.Type,
                    type.Kind,
                    typeArguments: typeArguments,
                    source: type.Source,
                    definition: type.Definition,
                    elementType: elementType,
                    isList: type.IsList,
                    isNamedType: type.IsNamedType,
                    isNullable: nullable[pos] ?? type.IsNullable);

                return(cache.TryAdd(rewritten)
                    ? rewritten
                    : cache.GetType(rewritten.Id));
            }

            return(type);
        }