public NullableTypeTree Create(Type t, NullabilityTypeKind kind, NullableTypeTree[] subTypes, Type[]?genericArguments = null)
 {
     if (genericArguments?.Length == 2)
     {
         var tGen = t.GetGenericTypeDefinition();
         if (tGen == typeof(IDictionary <,>) || tGen == typeof(Dictionary <,>))
         {
             var tKey = subTypes[0];
             if (tKey.Kind.IsNullable() && tKey.Kind.IsReferenceType())
             {
                 subTypes[0] = tKey.ToAbnormalNull();
             }
         }
     }
     return(new NullableTypeTree(t, kind, subTypes));
 }
 /// <summary>
 /// Initializes a new <see cref="NullableTypeTree"/>.
 /// No checks are done on the parameters (except ArgumentNullException and the fact that <paramref name="t"/> must not be Nullable&lt;&gt;):
 /// they must be coherent otherwise behavior is undefined.
 /// </summary>
 /// <param name="t">The Type.</param>
 /// <param name="k">The <see cref="NullabilityTypeKind"/>.</param>
 /// <param name="subTypes">The sub types (generic parameters or array element).</param>
 public NullableTypeTree(Type t, NullabilityTypeKind k, NullableTypeTree[] subTypes)
 {
     if (t == null)
     {
         throw new ArgumentNullException(nameof(t));
     }
     if (subTypes == null)
     {
         throw new ArgumentNullException(nameof(subTypes));
     }
     if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>))
     {
         throw new ArgumentException("Cannot be a Nullable<>.", nameof(t));
     }
     Type         = t;
     Kind         = k;
     _rawSubTypes = subTypes;
 }
Exemple #3
0
 public bool IsAssignableFrom(Type target, NullabilityTypeKind targetNullability, Type from, NullabilityTypeKind fromNullability)
 {
     if (from == null)
     {
         throw new ArgumentNullException(nameof(from));
     }
     if (target == null)
     {
         throw new ArgumentNullException(nameof(target));
     }
     // A non nullable cannot be assigned from a nullable.
     if (!targetNullability.IsNullable() && fromNullability.IsNullable())
     {
         return(false);
     }
     return(target == from ||
            target.IsAssignableFrom(from) ||
            (AllInterfaces.TryGetValue(target, out var tP) &&
             AllInterfaces.TryGetValue(from, out var fP) &&
             tP.Root == fP.Root));
 }
Exemple #4
0
        /// <summary>
        /// Gets a readable string.
        /// </summary>
        /// <param name="this">This info.</param>
        /// <returns>A readable string.</returns>
        public static string ToStringClear(this NullabilityTypeKind @this)
        {
            var s = (@this & ~(NullabilityTypeKind.NRTFullNonNullable | NullabilityTypeKind.NRTFullNullable)).ToString();

            if (@this.IsNRTAware())
            {
                s += " (NRT";
                if (@this.IsNRTFullNonNullable())
                {
                    s += ":FullNonNull)";
                }
                else if (@this.IsNRTFullNullable())
                {
                    s += ":FullNull)";
                }
                else
                {
                    s += ":Profile)";
                }
            }
            return(s);
        }
Exemple #5
0
 public bool IsAssignableFrom(IPocoPropertyInfo target, Type from, NullabilityTypeKind fromNullability)
 {
     if (from == null)
     {
         throw new ArgumentNullException(nameof(from));
     }
     if (target == null)
     {
         throw new ArgumentNullException(nameof(target));
     }
     if (target.PropertyUnionTypes.Any())
     {
         foreach (var t in target.PropertyUnionTypes)
         {
             if (IsAssignableFrom(t.Type, t.Kind, from, fromNullability))
             {
                 return(true);
             }
         }
         return(false);
     }
     return(IsAssignableFrom(target.PropertyType, target.PropertyNullableTypeTree.Kind, from, fromNullability));
 }
Exemple #6
0
 bool IPocoSupportResult.IsAssignableFrom(Type target, NullabilityTypeKind targetNullability, Type from, NullabilityTypeKind fromNullability) => false;
Exemple #7
0
 bool IPocoSupportResult.IsAssignableFrom(IPocoPropertyInfo target, Type from, NullabilityTypeKind fromNullability) => false;
Exemple #8
0
        static NullableTypeTree GetNullableTypeTreeWithProfile(Type t, IEnumerator <byte> annotations, NullabilityTypeKind known, INullableTypeTreeBuilder?builder)
        {
            if (t.DeclaringType != null && t.DeclaringType.IsGenericType)
            {
                throw new ArgumentException($"Type '{t.Name}' is nested in a generic type ({t.DeclaringType.ToCSharpName()}). Only nested types in non generic types are supported.", nameof(t));
            }
            NullableTypeTree[] sub = Array.Empty <NullableTypeTree>();
            bool isInside;

            if (isInside = (known == NullabilityTypeKind.None))
            {
                known = t.GetNullabilityKind();
            }
            if (known.IsNullableValueType())
            {
                // Lift the Nullable<T>.
                t = Nullable.GetUnderlyingType(t) !;
            }
            if (isInside && !known.IsNonGenericValueType())
            {
                // Consume our annotation.
                if (!annotations.MoveNext())
                {
                    throw new InvalidOperationException($"Byte annotations too short.");
                }
                var thisOne = annotations.Current;
                // Annotations only apply to reference types. Only 1 (not null!) is of interest.
                if (thisOne == 1 && known.IsReferenceType())
                {
                    Debug.Assert(known.IsNullable());
                    known &= ~NullabilityTypeKind.IsNullable;
                }
            }
            Type[]? genArgs = null;
            if (t.HasElementType)
            {
                Debug.Assert(known.IsReferenceType());
                sub = new[] { GetNullableTypeTreeWithProfile(t.GetElementType() !, annotations, default, builder) };
Exemple #9
0
 /// <summary>
 /// Gets whether this is a nullable value type.
 /// Byte annotation is skipped and the inner type must be lifted: <see cref="NullabilityTypeKind.IsGenericType"/> and <see cref="NullabilityTypeKind.IsTupleType"/>
 /// apply to the inner type.
 /// </summary>
 /// <param name="this">This <see cref="NullabilityTypeKind"/>.</param>
 /// <returns>True for nullable value type.</returns>
 public static bool IsNullableValueType(this NullabilityTypeKind @this) => (@this & (NullabilityTypeKind.IsNullable | NullabilityTypeKind.IsValueType)) == (NullabilityTypeKind.IsNullable | NullabilityTypeKind.IsValueType);
Exemple #10
0
 /// <summary>
 /// Gets whether this is a technically nullable type.
 /// Challenging null on a variable of this type should be done either because it is a nullable value type
 /// or a reference type (be it NRT nullable or not).
 /// </summary>
 /// <param name="this">This <see cref="NullabilityTypeKind"/>.</param>
 /// <returns>True for type that can be null (even if they shouldn't).</returns>
 public static bool IsTechnicallyNullable(this NullabilityTypeKind @this) => (@this & (NullabilityTypeKind.IsNullable | NullabilityTypeKind.IsReferenceType)) != 0;
Exemple #11
0
 /// <summary>
 /// Gets whether this is a value type.
 /// This simply check the <see cref="NullabilityTypeKind.IsValueType"/> bit.
 /// </summary>
 /// <param name="this">This <see cref="NullabilityTypeKind"/>.</param>
 /// <returns>True for value type.</returns>
 public static bool IsValueType(this NullabilityTypeKind @this) => (@this & NullabilityTypeKind.IsValueType) != 0;
Exemple #12
0
 /// <summary>
 /// Gets whether this is a NRT that is fully non nullable.
 /// See <see cref="NullabilityTypeKind.NRTFullNonNullable"/>.
 /// </summary>
 /// <param name="this">This <see cref="NullabilityTypeKind"/>.</param>
 /// <returns>True for Nullable Reference Type fully null.</returns>
 public static bool IsNRTFullNonNullable(this NullabilityTypeKind @this) => (@this & (NullabilityTypeKind.NRTFullNonNullable | NullabilityTypeKind.NRTFullNullable)) == NullabilityTypeKind.NRTFullNonNullable;
Exemple #13
0
 /// <summary>
 /// Gets whether this is a non generic value type.
 /// Byte annotation is skipped.
 /// </summary>
 /// <param name="this">This <see cref="NullabilityTypeKind"/>.</param>
 /// <returns>True for non generic value types.</returns>
 public static bool IsNonGenericValueType(this NullabilityTypeKind @this) => (@this & (NullabilityTypeKind.IsValueType | NullabilityTypeKind.IsGenericType)) == NullabilityTypeKind.IsValueType;
Exemple #14
0
 /// <summary>
 /// Gets whether this has the <see cref="NullabilityTypeKind.IsReferenceType"/> flag.
 /// </summary>
 /// <param name="this">This <see cref="NullabilityTypeKind"/>.</param>
 /// <returns>True for reference types.</returns>
 public static bool IsReferenceType(this NullabilityTypeKind @this) => (@this & NullabilityTypeKind.IsReferenceType) != 0;
 /// <summary>
 /// Initializes a new <see cref="NullabilityTypeInfo"/>.
 /// </summary>
 /// <param name="kind">The <see cref="Kind"/>.</param>
 /// <param name="nullableProfile">The optional <see cref="NullableProfile"/>.</param>
 /// <param name="fromContext">See <see cref="FromContext"/>.</param>
 public NullabilityTypeInfo(NullabilityTypeKind kind, byte[]?nullableProfile, bool fromContext)
 {
     Kind        = kind;
     _profile    = nullableProfile;
     FromContext = fromContext;
 }