TypeCompleter: Allow generics, support shorthand names

This commit is contained in:
Sinai 2022-04-22 09:07:51 +10:00
parent f174c7543a
commit 75bd654a94

View File

@ -28,30 +28,52 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public Type[] GenericConstraints { get; set; } public Type[] GenericConstraints { get; set; }
public bool AllTypes { get; set; } public bool AllTypes { get; set; }
private readonly bool allowAbstract;
private readonly bool allowEnum;
public InputFieldRef InputField { get; } public InputFieldRef InputField { get; }
public bool AnchorToCaretPosition => false; public bool AnchorToCaretPosition => false;
private readonly List<Suggestion> suggestions = new(); readonly bool allowAbstract;
private readonly HashSet<string> suggestedNames = new(); readonly bool allowEnum;
readonly bool allowGeneric;
private HashSet<Type> allowedTypes; private HashSet<Type> allowedTypes;
private HashSet<Type> allAllowedTypes;
readonly List<Suggestion> suggestions = new();
readonly HashSet<string> suggestedNames = new();
private string chosenSuggestion; private string chosenSuggestion;
bool ISuggestionProvider.AllowNavigation => false; bool ISuggestionProvider.AllowNavigation => false;
public TypeCompleter(Type baseType, InputFieldRef inputField) : this(baseType, inputField, true, true) { } static readonly Dictionary<string, Type> shorthandToType = new()
{
{ "object", typeof(object) },
{ "string", typeof(string) },
{ "bool", typeof(bool) },
{ "byte", typeof(byte) },
{ "sbyte", typeof(sbyte) },
{ "char", typeof(char) },
{ "decimal", typeof(decimal) },
{ "double", typeof(double) },
{ "float", typeof(float) },
{ "int", typeof(int) },
{ "uint", typeof(uint) },
{ "long", typeof(long) },
{ "ulong", typeof(ulong) },
{ "short", typeof(short) },
{ "ushort", typeof(ushort) },
{ "void", typeof(void) },
};
public TypeCompleter(Type baseType, InputFieldRef inputField, bool allowAbstract, bool allowEnum) public TypeCompleter(Type baseType, InputFieldRef inputField) : this(baseType, inputField, true, true, true) { }
public TypeCompleter(Type baseType, InputFieldRef inputField, bool allowAbstract, bool allowEnum, bool allowGeneric)
{ {
BaseType = baseType; BaseType = baseType;
InputField = inputField; InputField = inputField;
this.allowAbstract = allowAbstract; this.allowAbstract = allowAbstract;
this.allowEnum = allowEnum; this.allowEnum = allowEnum;
this.allowGeneric = allowGeneric;
inputField.OnValueChanged += OnInputFieldChanged; inputField.OnValueChanged += OnInputFieldChanged;
@ -62,10 +84,16 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public void CacheTypes() public void CacheTypes()
{ {
if (!AllTypes) if (!AllTypes)
allowedTypes = ReflectionUtility.GetImplementationsOf(BaseType, allowAbstract, allowEnum, false); allowedTypes = ReflectionUtility.GetImplementationsOf(BaseType, allowAbstract, allowGeneric, allowEnum);
else else
allowedTypes = GetAllAllowedTypes();
}
HashSet<Type> GetAllAllowedTypes()
{ {
allowedTypes = new(); if (allAllowedTypes == null)
{
allAllowedTypes = new();
foreach (KeyValuePair<string, Type> entry in ReflectionUtility.AllTypes) foreach (KeyValuePair<string, Type> entry in ReflectionUtility.AllTypes)
{ {
// skip <PrivateImplementationDetails> and <AnonymousClass> classes // skip <PrivateImplementationDetails> and <AnonymousClass> classes
@ -76,9 +104,11 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
{ {
continue; continue;
} }
allowedTypes.Add(type); allAllowedTypes.Add(type);
} }
} }
return allAllowedTypes;
} }
public void OnSuggestionClicked(Suggestion suggestion) public void OnSuggestionClicked(Suggestion suggestion)
@ -110,24 +140,37 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
} }
} }
private void GetSuggestions(string value) private void GetSuggestions(string input)
{ {
suggestions.Clear(); suggestions.Clear();
suggestedNames.Clear(); suggestedNames.Clear();
if (BaseType == null) if (!AllTypes && BaseType == null)
{ {
ExplorerCore.LogWarning("Autocompleter Base type is null!"); ExplorerCore.LogWarning("Autocompleter Base type is null!");
return; return;
} }
// shorthand types all inherit from System.Object
if (AllTypes || BaseType == typeof(object))
{
if (shorthandToType.TryGetValue(input, out Type shorthand))
AddSuggestion(shorthand);
foreach (KeyValuePair<string, Type> entry in shorthandToType)
{
if (entry.Key.StartsWith(input, StringComparison.InvariantCultureIgnoreCase))
AddSuggestion(entry.Value);
}
}
// Check for exact match first // Check for exact match first
if (ReflectionUtility.GetTypeByName(value) is Type t && allowedTypes.Contains(t)) if (ReflectionUtility.GetTypeByName(input) is Type t && allowedTypes.Contains(t))
AddSuggestion(t); AddSuggestion(t);
foreach (Type entry in allowedTypes) foreach (Type entry in allowedTypes)
{ {
if (entry.FullName.ContainsIgnoreCase(value)) if (entry.FullName.ContainsIgnoreCase(input))
AddSuggestion(entry); AddSuggestion(entry);
} }
} }