static bool GetStringArrayEnumHint(VariantType elementVariantType, AttributeData exportAttr, out string?hintString) { var constructorArguments = exportAttr.ConstructorArguments; if (constructorArguments.Length > 0) { var presetHintValue = exportAttr.ConstructorArguments[0].Value; PropertyHint presetHint = presetHintValue switch { null => PropertyHint.None, int intValue => (PropertyHint)intValue, _ => (PropertyHint)(long)presetHintValue }; if (presetHint == PropertyHint.Enum) { string?presetHintString = constructorArguments.Length > 1 ? exportAttr.ConstructorArguments[1].Value?.ToString() : null; hintString = (int)elementVariantType + "/" + (int)PropertyHint.Enum + ":"; if (presetHintString != null) { hintString += presetHintString; } return(true); } } hintString = null; return(false); } if (!isTypeArgument && variantType == VariantType.Array) { var elementType = MarshalUtils.GetArrayElementType(type); if (elementType == null) { return(false); // Non-generic Array, so there's no hint to add } var elementMarshalType = MarshalUtils.ConvertManagedTypeToMarshalType(elementType, typeCache) !.Value; var elementVariantType = MarshalUtils.ConvertMarshalTypeToVariantType(elementMarshalType) !.Value; bool isPresetHint = false; if (elementVariantType == VariantType.String) { isPresetHint = GetStringArrayEnumHint(elementVariantType, exportAttr, out hintString); } if (!isPresetHint) { bool hintRes = TryGetMemberExportHint(typeCache, elementType, exportAttr, elementVariantType, isTypeArgument: true, out var elementHint, out var elementHintString); // Format: type/hint:hint_string if (hintRes) { hintString = (int)elementVariantType + "/" + (int)elementHint + ":"; if (elementHintString != null) { hintString += elementHintString; } } else { hintString = (int)elementVariantType + "/" + (int)PropertyHint.None + ":"; } } hint = PropertyHint.TypeString; return(hintString != null); } if (!isTypeArgument && variantType == VariantType.PackedStringArray) { if (GetStringArrayEnumHint(VariantType.String, exportAttr, out hintString)) { hint = PropertyHint.TypeString; return(true); } } if (!isTypeArgument && variantType == VariantType.Dictionary) { // TODO: Dictionaries are not supported in the inspector return(false); } return(false); }
private static PropertyInfo?DeterminePropertyInfo( GeneratorExecutionContext context, MarshalUtils.TypeCache typeCache, ISymbol memberSymbol, MarshalType marshalType ) { var exportAttr = memberSymbol.GetAttributes() .FirstOrDefault(a => a.AttributeClass?.IsGodotExportAttribute() ?? false); var propertySymbol = memberSymbol as IPropertySymbol; var fieldSymbol = memberSymbol as IFieldSymbol; if (exportAttr != null && propertySymbol != null) { if (propertySymbol.GetMethod == null) { // This should never happen, as we filtered WriteOnly properties, but just in case. Common.ReportExportedMemberIsWriteOnly(context, propertySymbol); return(null); } if (propertySymbol.SetMethod == null) { // This should never happen, as we filtered ReadOnly properties, but just in case. Common.ReportExportedMemberIsReadOnly(context, propertySymbol); return(null); } } var memberType = propertySymbol?.Type ?? fieldSymbol !.Type; var memberVariantType = MarshalUtils.ConvertMarshalTypeToVariantType(marshalType) !.Value; string memberName = memberSymbol.Name; if (exportAttr == null) { return(new PropertyInfo(memberVariantType, memberName, PropertyHint.None, hintString: null, PropertyUsageFlags.ScriptVariable, exported: false)); } if (!TryGetMemberExportHint(typeCache, memberType, exportAttr, memberVariantType, isTypeArgument: false, out var hint, out var hintString)) { var constructorArguments = exportAttr.ConstructorArguments; if (constructorArguments.Length > 0) { var hintValue = exportAttr.ConstructorArguments[0].Value; hint = hintValue switch { null => PropertyHint.None, int intValue => (PropertyHint)intValue, _ => (PropertyHint)(long)hintValue }; hintString = constructorArguments.Length > 1 ? exportAttr.ConstructorArguments[1].Value?.ToString() : null; } else { hint = PropertyHint.None; } } var propUsage = PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable; if (memberVariantType == VariantType.Nil) { propUsage |= PropertyUsageFlags.NilIsVariant; } return(new PropertyInfo(memberVariantType, memberName, hint, hintString, propUsage, exported: true)); }