1+ using System . Collections . Generic ;
2+ using System . Collections . ObjectModel ;
3+ using System . Reflection ;
4+ using System ;
5+ using System . Linq ;
6+
7+ namespace TypeScriptBuilder . Helper
8+ {
9+ public class NullableHelper
10+ {
11+ public static bool IsNullable ( PropertyInfo property ) =>
12+ IsNullableHelper ( property . PropertyType , property . DeclaringType , property . CustomAttributes ) ;
13+
14+ public static bool IsNullable ( FieldInfo field ) =>
15+ IsNullableHelper ( field . FieldType , field . DeclaringType , field . CustomAttributes ) ;
16+
17+ public static bool IsNullable ( ParameterInfo parameter ) =>
18+ IsNullableHelper ( parameter . ParameterType , parameter . Member , parameter . CustomAttributes ) ;
19+
20+ private static bool IsNullableHelper ( Type memberType , MemberInfo declaringType , IEnumerable < CustomAttributeData > customAttributes )
21+ {
22+ if ( memberType . IsValueType )
23+ return Nullable . GetUnderlyingType ( memberType ) != null ;
24+
25+ var nullable = customAttributes
26+ . FirstOrDefault ( x => x . AttributeType . FullName == "System.Runtime.CompilerServices.NullableAttribute" ) ;
27+ if ( nullable != null && nullable . ConstructorArguments . Count == 1 )
28+ {
29+ var attributeArgument = nullable . ConstructorArguments [ 0 ] ;
30+ if ( attributeArgument . ArgumentType == typeof ( byte [ ] ) )
31+ {
32+ var args = ( ReadOnlyCollection < CustomAttributeTypedArgument > ) attributeArgument . Value ;
33+ if ( args . Count > 0 && args [ 0 ] . ArgumentType == typeof ( byte ) )
34+ {
35+ return ( byte ) args [ 0 ] . Value == 2 ;
36+ }
37+ }
38+ else if ( attributeArgument . ArgumentType == typeof ( byte ) )
39+ {
40+ return ( byte ) attributeArgument . Value == 2 ;
41+ }
42+ }
43+
44+ for ( var type = declaringType ; type != null ; type = type . DeclaringType )
45+ {
46+ var context = type . CustomAttributes
47+ . FirstOrDefault ( x => x . AttributeType . FullName == "System.Runtime.CompilerServices.NullableContextAttribute" ) ;
48+ if ( context != null &&
49+ context . ConstructorArguments . Count == 1 &&
50+ context . ConstructorArguments [ 0 ] . ArgumentType == typeof ( byte ) )
51+ {
52+ return ( byte ) context . ConstructorArguments [ 0 ] . Value ! == 2 ;
53+ }
54+ }
55+
56+ // Couldn't find a suitable attribute
57+ return false ;
58+ }
59+ }
60+ }
0 commit comments