TypeReference InferType()

in packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs [335:425]


        TypeReference InferType(IReferenceMap referenceMap, Type type)
        {
            type = type ?? throw new ArgumentNullException(nameof(type));

            var classAttribute = ReflectionUtils.GetClassAttribute(type);
            if (classAttribute != null)
            {
                return new TypeReference(classAttribute.FullyQualifiedName);
            }

            var enumAttribute = type.GetCustomAttribute<JsiiEnumAttribute>();
            if (enumAttribute != null)
            {
                return new TypeReference(enumAttribute.FullyQualifiedName);
            }

            var interfaceAttribute = type.GetCustomAttribute<JsiiInterfaceAttribute>();
            if (interfaceAttribute != null)
            {
                return new TypeReference(interfaceAttribute.FullyQualifiedName);
            }

            var structAttribute = type.GetCustomAttribute<JsiiByValueAttribute>();
            if (structAttribute != null)
            {
                return new TypeReference(structAttribute.FullyQualifiedName);
            }

            if (typeof(string).IsAssignableFrom(type))
            {
                return new TypeReference(primitive: PrimitiveType.String);
            }

            if (typeof(bool).IsAssignableFrom(type))
            {
                return new TypeReference(primitive: PrimitiveType.Boolean);
            }

            if (IsNumeric(type))
            {
                return new TypeReference(primitive: PrimitiveType.Number);
            }

            if (typeof(DateTime).IsAssignableFrom(type))
            {
                return new TypeReference(primitive: PrimitiveType.Date);
            }

            if (typeof(JObject).IsAssignableFrom(type) || typeof(JArray).IsAssignableFrom(type))
            {
                return new TypeReference(primitive: PrimitiveType.Json);
            }

            if (type.IsArray)
            {
                return new TypeReference
                (
                    collection: new CollectionTypeReference
                    (
                        kind: CollectionKind.Array,
                        elementType: typeof(Object) == type.GetElementType()
                            ? new TypeReference(primitive: PrimitiveType.Any)
                            : InferType(referenceMap, type.GetElementType()!)
                    )
                );
            }

            Type? dictionaryInterface = type.GetInterfaces()
                .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>));
            if (dictionaryInterface != null)
            {
                if (!typeof(string).IsAssignableFrom(dictionaryInterface.GetGenericArguments()[0]))
                {
                    throw new ArgumentException("All dictionaries must have string keys", nameof(type));
                }

                Type elementType = dictionaryInterface.GetGenericArguments()[1];
                return new TypeReference
                (
                    collection: new CollectionTypeReference
                    (
                        kind: CollectionKind.Map,
                        elementType: typeof(Object) == elementType
                            ? new TypeReference(primitive: PrimitiveType.Any)
                            : InferType(referenceMap, elementType)
                    )
                );
            }

            throw new ArgumentException($"Could not infer JSII type for .NET type '{type.Name}'", nameof(type));
        }