MarshalUtils.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Godot
  4. {
  5. internal static class MarshalUtils
  6. {
  7. /// <summary>
  8. /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
  9. /// is <see cref="Collections.Array{T}"/>; otherwise returns <see langword="false"/>.
  10. /// </summary>
  11. /// <exception cref="InvalidOperationException">
  12. /// Thrown when the given <paramref name="type"/> is not a generic type.
  13. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  14. /// </exception>
  15. private static bool TypeIsGenericArray(Type type) =>
  16. type.GetGenericTypeDefinition() == typeof(Collections.Array<>);
  17. /// <summary>
  18. /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
  19. /// is <see cref="Collections.Dictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
  20. /// </summary>
  21. /// <exception cref="InvalidOperationException">
  22. /// Thrown when the given <paramref name="type"/> is not a generic type.
  23. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  24. /// </exception>
  25. private static bool TypeIsGenericDictionary(Type type) =>
  26. type.GetGenericTypeDefinition() == typeof(Collections.Dictionary<,>);
  27. /// <summary>
  28. /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
  29. /// is <see cref="List{T}"/>; otherwise returns <see langword="false"/>.
  30. /// </summary>
  31. /// <exception cref="InvalidOperationException">
  32. /// Thrown when the given <paramref name="type"/> is not a generic type.
  33. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  34. /// </exception>
  35. private static bool TypeIsSystemGenericList(Type type) =>
  36. type.GetGenericTypeDefinition() == typeof(List<>);
  37. /// <summary>
  38. /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
  39. /// is <see cref="Dictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
  40. /// </summary>
  41. /// <exception cref="InvalidOperationException">
  42. /// Thrown when the given <paramref name="type"/> is not a generic type.
  43. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  44. /// </exception>
  45. private static bool TypeIsSystemGenericDictionary(Type type) =>
  46. type.GetGenericTypeDefinition() == typeof(Dictionary<,>);
  47. /// <summary>
  48. /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
  49. /// is <see cref="IEnumerable{T}"/>; otherwise returns <see langword="false"/>.
  50. /// </summary>
  51. /// <exception cref="InvalidOperationException">
  52. /// Thrown when the given <paramref name="type"/> is not a generic type.
  53. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  54. /// </exception>
  55. private static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
  56. /// <summary>
  57. /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
  58. /// is <see cref="ICollection{T}"/>; otherwise returns <see langword="false"/>.
  59. /// </summary>
  60. /// <exception cref="InvalidOperationException">
  61. /// Thrown when the given <paramref name="type"/> is not a generic type.
  62. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  63. /// </exception>
  64. private static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>);
  65. /// <summary>
  66. /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
  67. /// is <see cref="IDictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
  68. /// </summary>
  69. /// <exception cref="InvalidOperationException">
  70. /// Thrown when the given <paramref name="type"/> is not a generic type.
  71. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  72. /// </exception>
  73. private static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
  74. /// <summary>
  75. /// Gets the element type for the given <paramref name="arrayType"/>.
  76. /// </summary>
  77. /// <param name="arrayType">Type for the generic array.</param>
  78. /// <param name="elementType">Element type for the generic array.</param>
  79. /// <exception cref="InvalidOperationException">
  80. /// Thrown when the given <paramref name="arrayType"/> is not a generic type.
  81. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  82. /// </exception>
  83. private static void ArrayGetElementType(Type arrayType, out Type elementType)
  84. {
  85. elementType = arrayType.GetGenericArguments()[0];
  86. }
  87. /// <summary>
  88. /// Gets the key type and the value type for the given <paramref name="dictionaryType"/>.
  89. /// </summary>
  90. /// <param name="dictionaryType">The type for the generic dictionary.</param>
  91. /// <param name="keyType">Key type for the generic dictionary.</param>
  92. /// <param name="valueType">Value type for the generic dictionary.</param>
  93. /// <exception cref="InvalidOperationException">
  94. /// Thrown when the given <paramref name="dictionaryType"/> is not a generic type.
  95. /// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
  96. /// </exception>
  97. private static void DictionaryGetKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
  98. {
  99. var genericArgs = dictionaryType.GetGenericArguments();
  100. keyType = genericArgs[0];
  101. valueType = genericArgs[1];
  102. }
  103. /// <summary>
  104. /// Constructs a new <see cref="Type"/> from <see cref="Collections.Array{T}"/>
  105. /// where the generic type for the elements is <paramref name="elemType"/>.
  106. /// </summary>
  107. /// <param name="elemType">Element type for the array.</param>
  108. /// <returns>The generic array type with the specified element type.</returns>
  109. private static Type MakeGenericArrayType(Type elemType)
  110. {
  111. return typeof(Collections.Array<>).MakeGenericType(elemType);
  112. }
  113. /// <summary>
  114. /// Constructs a new <see cref="Type"/> from <see cref="Collections.Dictionary{TKey, TValue}"/>
  115. /// where the generic type for the keys is <paramref name="keyType"/> and
  116. /// for the values is <paramref name="valueType"/>.
  117. /// </summary>
  118. /// <param name="keyType">Key type for the dictionary.</param>
  119. /// <param name="valueType">Key type for the dictionary.</param>
  120. /// <returns>The generic dictionary type with the specified key and value types.</returns>
  121. private static Type MakeGenericDictionaryType(Type keyType, Type valueType)
  122. {
  123. return typeof(Collections.Dictionary<,>).MakeGenericType(keyType, valueType);
  124. }
  125. }
  126. }