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)); }
public bool Equals(ExtendedTypeId other) => Type == other.Type && Nullability == other.Nullability && Kind == other.Kind;
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); }