public static BuiltInType GetBuiltInType()

in rd-net/RdFramework.Reflection/BuiltInSerializers.cs [75:147]


    public static BuiltInType GetBuiltInType(TypeInfo t)
    {
      if (HasBuiltInAttribute(t))
        return BuiltInType.MarshallerAttribute;

      try
      {
        var writeMethod = t.GetMethod("Write", BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
        if (writeMethod != null)
        {
          return CheckWriteMethod(t, writeMethod);
        }
      }
      catch (AmbiguousMatchException)
      {
        // More than one Write method exist. We should enumerate members to find appropriate overload. 
        // not a default branch because of array allocation.
        foreach (var member in t.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly))
        {
          if (member is MethodInfo writeMethod && StringComparer.Ordinal.Equals("Write", writeMethod.Name))
          {
            var type = CheckWriteMethod(t, writeMethod);
            if (type != BuiltInType.None)
              return type;
          }
        }
      }

      var fieldInfo = t.GetField("Write", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
      if (fieldInfo != null)
      {
        return BuiltInType.StaticFields;
      }

      return BuiltInType.None;

      static BuiltInType CheckWriteMethod(Type ownerType, MethodInfo methodInfo)
      {
        var genericLength = ownerType.GetGenericArguments().Length;
        var parameters = methodInfo.GetParameters();
        if (genericLength == 1 || genericLength == 2)
        {
          // more than one Read is defined for RdMap. We can't query method by name directly and have to allocate array.
          var likeReadMethods = ownerType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
          foreach (var likeReadMethod in likeReadMethods)
          {
            if (!StringComparer.Ordinal.Equals("Read", likeReadMethod.Name))
              continue;

            var readParameters = likeReadMethod.GetParameters();
            if (readParameters.Length == 2 + genericLength * 2 && readParameters[0].ParameterType == typeof(SerializationCtx))
              return genericLength == 1 ? BuiltInType.ProtocolCollectionLike1 : BuiltInType.ProtocolCollectionLike2;
          }
        }

        var likeProtocol = parameters.Length == 2 + (methodInfo.IsStatic ? 1 : 0) &&
                           parameters[0].ParameterType == typeof(SerializationCtx) &&
                           parameters[1].ParameterType == typeof(UnsafeWriter);
        var likeMethods = parameters.Length == 1 + (methodInfo.IsStatic ? 1 : 0) &&
                          parameters[0].ParameterType == typeof(UnsafeWriter);
        if (methodInfo.IsStatic)
        {
          if (likeProtocol) return BuiltInType.StaticProtocolMethods;
          if (likeMethods) return BuiltInType.StaticMethods;
        }
        else
        {
          if (likeProtocol) return BuiltInType.ProtocolMethods;
          if (likeMethods) return BuiltInType.Methods;
        }
        return BuiltInType.None;
      }
    }