Allow readonly and writeonly C# properties to be accessed from GDScript
This commit is contained in:
parent
7ba79d68bd
commit
41cf94e8b6
@ -0,0 +1,10 @@
|
||||
namespace Godot.SourceGenerators.Sample
|
||||
{
|
||||
public partial class AllReadOnly : GodotObject
|
||||
{
|
||||
public readonly string readonly_field = "foo";
|
||||
public string readonly_auto_property { get; } = "foo";
|
||||
public string readonly_property { get => "foo"; }
|
||||
public string initonly_auto_property { get; init; }
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Godot.SourceGenerators.Sample
|
||||
{
|
||||
public partial class AllWriteOnly : GodotObject
|
||||
{
|
||||
bool writeonly_backing_field = false;
|
||||
public bool writeonly_property { set => writeonly_backing_field = value; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
namespace Godot.SourceGenerators.Sample
|
||||
{
|
||||
public partial class MixedReadonlyWriteOnly : GodotObject
|
||||
{
|
||||
public readonly string readonly_field = "foo";
|
||||
public string readonly_auto_property { get; } = "foo";
|
||||
public string readonly_property { get => "foo"; }
|
||||
public string initonly_auto_property { get; init; }
|
||||
|
||||
bool writeonly_backing_field = false;
|
||||
public bool writeonly_property { set => writeonly_backing_field = value; }
|
||||
}
|
||||
}
|
@ -303,11 +303,6 @@ namespace Godot.SourceGenerators
|
||||
{
|
||||
foreach (var property in properties)
|
||||
{
|
||||
// TODO: We should still restore read-only properties after reloading assembly. Two possible ways: reflection or turn RestoreGodotObjectData into a constructor overload.
|
||||
// Ignore properties without a getter, without a setter or with an init-only setter. Godot properties must be both readable and writable.
|
||||
if (property.IsWriteOnly || property.IsReadOnly || property.SetMethod!.IsInitOnly)
|
||||
continue;
|
||||
|
||||
var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(property.Type, typeCache);
|
||||
|
||||
if (marshalType == null)
|
||||
@ -325,10 +320,6 @@ namespace Godot.SourceGenerators
|
||||
foreach (var field in fields)
|
||||
{
|
||||
// TODO: We should still restore read-only fields after reloading assembly. Two possible ways: reflection or turn RestoreGodotObjectData into a constructor overload.
|
||||
// Ignore properties without a getter or without a setter. Godot properties must be both readable and writable.
|
||||
if (field.IsReadOnly)
|
||||
continue;
|
||||
|
||||
var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(field.Type, typeCache);
|
||||
|
||||
if (marshalType == null)
|
||||
|
@ -212,31 +212,37 @@ namespace Godot.SourceGenerators
|
||||
}
|
||||
|
||||
// Generate GetGodotClassPropertyValue
|
||||
bool allPropertiesAreWriteOnly = godotClassFields.Length == 0 && godotClassProperties.All(pi => pi.PropertySymbol.IsWriteOnly);
|
||||
|
||||
source.Append(" /// <inheritdoc/>\n");
|
||||
source.Append(" [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]\n");
|
||||
source.Append(" protected override bool GetGodotClassPropertyValue(in godot_string_name name, ");
|
||||
source.Append("out godot_variant value)\n {\n");
|
||||
|
||||
isFirstEntry = true;
|
||||
foreach (var property in godotClassProperties)
|
||||
if (!allPropertiesAreWriteOnly)
|
||||
{
|
||||
GeneratePropertyGetter(property.PropertySymbol.Name,
|
||||
property.PropertySymbol.Type, property.Type, source, isFirstEntry);
|
||||
isFirstEntry = false;
|
||||
source.Append(" /// <inheritdoc/>\n");
|
||||
source.Append(" [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]\n");
|
||||
source.Append(" protected override bool GetGodotClassPropertyValue(in godot_string_name name, ");
|
||||
source.Append("out godot_variant value)\n {\n");
|
||||
|
||||
isFirstEntry = true;
|
||||
foreach (var property in godotClassProperties)
|
||||
{
|
||||
if (property.PropertySymbol.IsWriteOnly)
|
||||
continue;
|
||||
|
||||
GeneratePropertyGetter(property.PropertySymbol.Name,
|
||||
property.PropertySymbol.Type, property.Type, source, isFirstEntry);
|
||||
isFirstEntry = false;
|
||||
}
|
||||
|
||||
foreach (var field in godotClassFields)
|
||||
{
|
||||
GeneratePropertyGetter(field.FieldSymbol.Name,
|
||||
field.FieldSymbol.Type, field.Type, source, isFirstEntry);
|
||||
isFirstEntry = false;
|
||||
}
|
||||
|
||||
source.Append(" return base.GetGodotClassPropertyValue(name, out value);\n");
|
||||
|
||||
source.Append(" }\n");
|
||||
}
|
||||
|
||||
foreach (var field in godotClassFields)
|
||||
{
|
||||
GeneratePropertyGetter(field.FieldSymbol.Name,
|
||||
field.FieldSymbol.Type, field.Type, source, isFirstEntry);
|
||||
isFirstEntry = false;
|
||||
}
|
||||
|
||||
source.Append(" return base.GetGodotClassPropertyValue(name, out value);\n");
|
||||
|
||||
source.Append(" }\n");
|
||||
|
||||
// Generate GetGodotPropertyList
|
||||
|
||||
const string dictionaryType = "global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>";
|
||||
|
@ -119,8 +119,14 @@ namespace Godot.SourceGenerators
|
||||
.Where(s => !s.IsStatic && s.Kind == SymbolKind.Field && !s.IsImplicitlyDeclared)
|
||||
.Cast<IFieldSymbol>();
|
||||
|
||||
var godotClassProperties = propertySymbols.WhereIsGodotCompatibleType(typeCache).ToArray();
|
||||
var godotClassFields = fieldSymbols.WhereIsGodotCompatibleType(typeCache).ToArray();
|
||||
// TODO: We should still restore read-only properties after reloading assembly. Two possible ways: reflection or turn RestoreGodotObjectData into a constructor overload.
|
||||
// Ignore properties without a getter, without a setter or with an init-only setter. Godot properties must be both readable and writable.
|
||||
var godotClassProperties = propertySymbols.Where(property => !(property.IsReadOnly || property.IsWriteOnly || property.SetMethod!.IsInitOnly))
|
||||
.WhereIsGodotCompatibleType(typeCache)
|
||||
.ToArray();
|
||||
var godotClassFields = fieldSymbols.Where(property => !property.IsReadOnly)
|
||||
.WhereIsGodotCompatibleType(typeCache)
|
||||
.ToArray();
|
||||
|
||||
var signalDelegateSymbols = members
|
||||
.Where(s => s.Kind == SymbolKind.NamedType)
|
||||
|
Loading…
Reference in New Issue
Block a user