Fix methods with multiple generic constraints

This commit is contained in:
sinaioutlander 2020-09-19 01:27:33 +10:00
parent c39e097378
commit ad5fc04a3b
3 changed files with 44 additions and 15 deletions

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MelonLoader;
using UnityEngine;
@ -400,9 +401,28 @@ namespace Explorer
for (int i = 0; i < cm.GenericArgs.Length; i++)
{
var type = cm.GenericConstraints[i]?.FullName ?? "Any";
string types = "";
if (cm.GenericConstraints[i].Length > 0)
{
foreach (var constraint in cm.GenericConstraints[i])
{
if (types != "") types += ", ";
string type;
if (constraint == null)
type = "Any";
else
type = constraint.ToString();
types += $"<color={UIStyles.Syntax.Class_Instance}>{type}</color>";
}
}
else
{
types = $"<color={UIStyles.Syntax.Class_Instance}>Any</color>";
}
var input = cm.GenericArgInput[i];
var label = $"<color={UIStyles.Syntax.Class_Instance}>{type}</color>";
GUILayout.BeginHorizontal(null);
@ -410,7 +430,7 @@ namespace Explorer
GUILayout.Label($"<color={UIStyles.Syntax.StructGreen}>{cm.GenericArgs[i].Name}</color>", new GUILayoutOption[] { GUILayout.Width(15) });
cm.GenericArgInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUILayout.Label(label, null);
GUILayout.Label(types, null);
GUILayout.EndHorizontal();
}

View File

@ -14,7 +14,7 @@ namespace Explorer
public override bool HasParameters => base.HasParameters || GenericArgs.Length > 0;
public Type[] GenericArgs { get; private set; }
public Type[] GenericConstraints { get; private set; }
public Type[][] GenericConstraints { get; private set; }
public string[] GenericArgInput = new string[0];
@ -23,8 +23,7 @@ namespace Explorer
var mi = (MemInfo as MethodInfo);
GenericArgs = mi.GetGenericArguments();
GenericConstraints = GenericArgs.Select(x => x.GetGenericParameterConstraints()
.FirstOrDefault())
GenericConstraints = GenericArgs.Select(x => x.GetGenericParameterConstraints())
.ToArray();
GenericArgInput = new string[GenericArgs.Length];
@ -86,21 +85,22 @@ namespace Explorer
var input = GenericArgInput[i];
if (ReflectionHelpers.GetTypeByName(input) is Type t)
{
if (GenericConstraints[i] == null)
if (GenericConstraints[i].Length == 0)
{
list.Add(t);
}
else
{
if (GenericConstraints[i].IsAssignableFrom(t))
foreach (var constraint in GenericConstraints[i].Where(x => x != null))
{
list.Add(t);
}
else
{
MelonLogger.LogWarning($"Generic argument #{i} '{input}', is not assignable from the generic constraint!");
return null;
if (!constraint.IsAssignableFrom(t))
{
MelonLogger.LogWarning($"Generic argument #{i}, '{input}' is not assignable from the constraint '{constraint}'!");
return null;
}
}
list.Add(t);
}
}
else

View File

@ -3,6 +3,14 @@ using System.Collections.Generic;
using System;
using UnityEngine;
// used to test multiple generic constraints
public class TestGeneric : IComparable<string>
{
public TestGeneric() { }
public int CompareTo(string other) => throw new NotImplementedException();
}
namespace Explorer.Tests
{
public class TestClass
@ -22,7 +30,8 @@ namespace Explorer.Tests
public static int StaticField = 5;
public int NonStaticField;
public static string TestGeneric<C, T>(string arg0) where C : Component
public static string TestGeneric<C, T>(string arg0) where C : Component where T : TestGeneric, IComparable<string>
{
return $"C: '{typeof(C).FullName}', T: '{typeof(T).FullName}', arg0: '{arg0}'";
}