1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-06 12:20:30 +00:00

Implement typed dictionaries

This commit is contained in:
Thaddeus Crews
2023-06-24 13:03:28 -05:00
parent 906a4e9db9
commit 9853a69144
86 changed files with 3071 additions and 193 deletions

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
@@ -728,8 +729,72 @@ namespace Godot.SourceGenerators
if (!isTypeArgument && variantType == VariantType.Dictionary)
{
// TODO: Dictionaries are not supported in the inspector
return false;
var elementTypes = MarshalUtils.GetGenericElementTypes(type);
if (elementTypes == null)
return false; // Non-generic Dictionary, so there's no hint to add
Debug.Assert(elementTypes.Length == 2);
var keyElementMarshalType = MarshalUtils.ConvertManagedTypeToMarshalType(elementTypes[0], typeCache)!.Value;
var keyElementVariantType = MarshalUtils.ConvertMarshalTypeToVariantType(keyElementMarshalType)!.Value;
var keyIsPresetHint = false;
var keyHintString = (string?)null;
if (keyElementVariantType == VariantType.String || keyElementVariantType == VariantType.StringName)
keyIsPresetHint = GetStringArrayEnumHint(keyElementVariantType, exportAttr, out keyHintString);
if (!keyIsPresetHint)
{
bool hintRes = TryGetMemberExportHint(typeCache, elementTypes[0],
exportAttr, keyElementVariantType, isTypeArgument: true,
out var keyElementHint, out var keyElementHintString);
// Format: type/hint:hint_string
if (hintRes)
{
keyHintString = (int)keyElementVariantType + "/" + (int)keyElementHint + ":";
if (keyElementHintString != null)
keyHintString += keyElementHintString;
}
else
{
keyHintString = (int)keyElementVariantType + "/" + (int)PropertyHint.None + ":";
}
}
var valueElementMarshalType = MarshalUtils.ConvertManagedTypeToMarshalType(elementTypes[1], typeCache)!.Value;
var valueElementVariantType = MarshalUtils.ConvertMarshalTypeToVariantType(valueElementMarshalType)!.Value;
var valueIsPresetHint = false;
var valueHintString = (string?)null;
if (valueElementVariantType == VariantType.String || valueElementVariantType == VariantType.StringName)
valueIsPresetHint = GetStringArrayEnumHint(valueElementVariantType, exportAttr, out valueHintString);
if (!valueIsPresetHint)
{
bool hintRes = TryGetMemberExportHint(typeCache, elementTypes[1],
exportAttr, valueElementVariantType, isTypeArgument: true,
out var valueElementHint, out var valueElementHintString);
// Format: type/hint:hint_string
if (hintRes)
{
valueHintString = (int)valueElementVariantType + "/" + (int)valueElementHint + ":";
if (valueElementHintString != null)
valueHintString += valueElementHintString;
}
else
{
valueHintString = (int)valueElementVariantType + "/" + (int)PropertyHint.None + ":";
}
}
hint = PropertyHint.DictionaryType;
hintString = keyHintString != null && valueHintString != null ? $"{keyHintString};{valueHintString}" : null;
return hintString != null;
}
return false;