From a5ce9c370634eddabee9574662c9c39863903533 Mon Sep 17 00:00:00 2001
From: Joyless <65855333+Joy-less@users.noreply.github.com>
Date: Sat, 11 Oct 2025 21:20:01 +0100
Subject: [PATCH] Fix IsStaticallyResolvable
---
...edProperties_ScriptProperties.generated.cs | 39 ++++++
...operties_ScriptPropertyDefVal.generated.cs | 8 +-
.../TestData/Sources/ExportedProperties.cs | 14 ++-
.../ScriptPropertyDefValGenerator.cs | 111 +++---------------
4 files changed, 76 insertions(+), 96 deletions(-)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs
index 94d447f61a6..636cd82a118 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs
@@ -37,6 +37,18 @@ partial class ExportedProperties
///
public new static readonly global::Godot.StringName @LamdaPropertyString = "LamdaPropertyString";
///
+ /// Cached name for the 'PrimaryCtorParameter' property.
+ ///
+ public new static readonly global::Godot.StringName @PrimaryCtorParameter = "PrimaryCtorParameter";
+ ///
+ /// Cached name for the 'ConstantMath' property.
+ ///
+ public new static readonly global::Godot.StringName @ConstantMath = "ConstantMath";
+ ///
+ /// Cached name for the 'StaticStringAddition' property.
+ ///
+ public new static readonly global::Godot.StringName @StaticStringAddition = "StaticStringAddition";
+ ///
/// Cached name for the 'PropertyBoolean' property.
///
public new static readonly global::Godot.StringName @PropertyBoolean = "PropertyBoolean";
@@ -317,6 +329,18 @@ partial class ExportedProperties
this.@LamdaPropertyString = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
return true;
}
+ if (name == PropertyName.@PrimaryCtorParameter) {
+ this.@PrimaryCtorParameter = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
+ return true;
+ }
+ if (name == PropertyName.@ConstantMath) {
+ this.@ConstantMath = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
+ return true;
+ }
+ if (name == PropertyName.@StaticStringAddition) {
+ this.@StaticStringAddition = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
+ return true;
+ }
if (name == PropertyName.@PropertyBoolean) {
this.@PropertyBoolean = global::Godot.NativeInterop.VariantUtils.ConvertTo(value);
return true;
@@ -599,6 +623,18 @@ partial class ExportedProperties
value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@LamdaPropertyString);
return true;
}
+ if (name == PropertyName.@PrimaryCtorParameter) {
+ value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@PrimaryCtorParameter);
+ return true;
+ }
+ if (name == PropertyName.@ConstantMath) {
+ value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@ConstantMath);
+ return true;
+ }
+ if (name == PropertyName.@StaticStringAddition) {
+ value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@StaticStringAddition);
+ return true;
+ }
if (name == PropertyName.@PropertyBoolean) {
value = global::Godot.NativeInterop.VariantUtils.CreateFrom(this.@PropertyBoolean);
return true;
@@ -870,6 +906,9 @@ partial class ExportedProperties
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@FullPropertyString_Complex, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@_lamdaPropertyString, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false));
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@LamdaPropertyString, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
+ properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@PrimaryCtorParameter, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
+ properties.Add(new(type: (global::Godot.Variant.Type)3, name: PropertyName.@ConstantMath, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
+ properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@StaticStringAddition, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.@PropertyBoolean, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@PropertyChar, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@PropertySByte, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptPropertyDefVal.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptPropertyDefVal.generated.cs
index 0bf0b0845a4..57829cc226b 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptPropertyDefVal.generated.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptPropertyDefVal.generated.cs
@@ -11,7 +11,7 @@ partial class ExportedProperties
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal new static global::System.Collections.Generic.Dictionary GetGodotPropertyDefaultValues()
{
- var values = new global::System.Collections.Generic.Dictionary(64);
+ var values = new global::System.Collections.Generic.Dictionary(67);
string __NotGenerateComplexLamdaProperty_default_value = default;
values.Add(PropertyName.@NotGenerateComplexLamdaProperty, global::Godot.Variant.From(__NotGenerateComplexLamdaProperty_default_value));
string __NotGenerateLamdaNoFieldProperty_default_value = default;
@@ -26,6 +26,12 @@ partial class ExportedProperties
values.Add(PropertyName.@FullPropertyString_Complex, global::Godot.Variant.From(__FullPropertyString_Complex_default_value));
string __LamdaPropertyString_default_value = "LamdaPropertyString";
values.Add(PropertyName.@LamdaPropertyString, global::Godot.Variant.From(__LamdaPropertyString_default_value));
+ string __PrimaryCtorParameter_default_value = default;
+ values.Add(PropertyName.@PrimaryCtorParameter, global::Godot.Variant.From(__PrimaryCtorParameter_default_value));
+ float __ConstantMath_default_value = 2 * global::Godot.Mathf.Pi;
+ values.Add(PropertyName.@ConstantMath, global::Godot.Variant.From(__ConstantMath_default_value));
+ string __StaticStringAddition_default_value = string.Empty + string.Empty;
+ values.Add(PropertyName.@StaticStringAddition, global::Godot.Variant.From(__StaticStringAddition_default_value));
bool __PropertyBoolean_default_value = true;
values.Add(PropertyName.@PropertyBoolean, global::Godot.Variant.From(__PropertyBoolean_default_value));
char __PropertyChar_default_value = 'f';
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs
index d7fcdc6b1b5..2f55bcf6125 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs
@@ -1,7 +1,7 @@
using Godot;
using System;
-public partial class ExportedProperties : GodotObject
+public partial class ExportedProperties(string primaryCtorParameter) : GodotObject
{
// Do not generate default value
private String _notGeneratePropertyString = new string("not generate");
@@ -91,6 +91,18 @@ public partial class ExportedProperties : GodotObject
set => _lamdaPropertyString = value;
}
+ // Primary Constructor Parameter
+ [Export]
+ public String PrimaryCtorParameter { get; set; } = primaryCtorParameter;
+
+ // Constant Math Expression
+ [Export]
+ public Single ConstantMath { get; set; } = 2 * Mathf.Pi;
+
+ // Static Strings Addition
+ [Export]
+ public string StaticStringAddition { get; set; } = string.Empty + string.Empty;
+
// Auto Property
[Export] private Boolean PropertyBoolean { get; set; } = true;
[Export] private Char PropertyChar { get; set; } = 'f';
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
index e2422ae1ed5..5400115fa44 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
@@ -336,7 +336,11 @@ namespace Godot.SourceGenerators
if (initializer != null)
{
var sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
- value = initializer.Value.FullQualifiedSyntax(sm);
+ var initializerValue = initializer.Value;
+ if (!IsStaticallyResolvable(initializerValue, sm))
+ value = "default";
+ else
+ value = initializer.Value.FullQualifiedSyntax(sm);
}
exportedMembers.Add(new ExportedPropertyMetadata(
@@ -424,109 +428,28 @@ namespace Godot.SourceGenerators
private static bool IsStaticallyResolvable(ExpressionSyntax expression, SemanticModel semanticModel)
{
- // Handle literals (e.g., `10`, `"string"`, `true`, etc.)
- if (expression is LiteralExpressionSyntax)
+ // Find non-static node in expression
+ foreach (SyntaxNode descendant in expression.DescendantNodesAndSelf())
{
- return true;
- }
-
- // Handle negative literals (e.g., `-10`)
- if (expression is PrefixUnaryExpressionSyntax { Operand: LiteralExpressionSyntax } &&
- expression.Kind() == SyntaxKind.UnaryMinusExpression)
- {
- return true;
- }
-
- // Handle identifiers (e.g., variable names)
- if (expression is IdentifierNameSyntax identifier)
- {
- var symbolInfo = semanticModel.GetSymbolInfo(identifier).Symbol;
-
- // Ensure it's a static member
- return symbolInfo is { IsStatic: true };
- }
-
- // Handle member access (e.g., `MyClass.StaticValue`)
- if (expression is MemberAccessExpressionSyntax memberAccess)
- {
- var symbolInfo = semanticModel.GetSymbolInfo(memberAccess).Symbol;
-
- // Ensure it's referring to a static member
- return symbolInfo is { IsStatic: true };
- }
-
- // Handle object creation expressions (e.g., `new Vector2(1.0f, 2.0f)`)
- if (expression is ObjectCreationExpressionSyntax objectCreation)
- {
- // Recursively ensure all its arguments are self-contained
- if (objectCreation.ArgumentList == null)
+ // Constant nodes are static
+ if (semanticModel.GetConstantValue(descendant).HasValue)
{
- return true;
+ continue;
}
- foreach (var argument in objectCreation.ArgumentList.Arguments)
+
+ // Check non-static symbol
+ SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(descendant);
+ if (symbolInfo.Symbol is ISymbol symbol)
{
- if (!IsStaticallyResolvable(argument.Expression, semanticModel))
+ if (symbol.Kind is SymbolKind.Local or SymbolKind.Parameter)
{
return false;
}
}
-
- return true;
}
- if (expression is ImplicitObjectCreationExpressionSyntax)
- {
- return true;
- }
-
- if (expression is InvocationExpressionSyntax invocationExpression)
- {
- // Resolve the method being invoked
- var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression).Symbol;
-
- if (symbolInfo is IMethodSymbol methodSymbol)
- {
- // Ensure the method is static
- if (methodSymbol.IsStatic)
- {
- return true;
- }
- }
- }
-
- if (expression is InterpolatedStringExpressionSyntax interpolatedString)
- {
- foreach (var content in interpolatedString.Contents)
- {
- if (content is not InterpolationSyntax interpolation)
- {
- continue;
- }
- // Analyze the expression inside `${...}`
- var interpolatedExpression = interpolation.Expression;
-
- if (!IsStaticallyResolvable(interpolatedExpression, semanticModel))
- {
- return false;
- }
- }
- return true;
- }
-
- if (expression is InitializerExpressionSyntax initializerExpressionSyntax)
- {
- foreach (var content in initializerExpressionSyntax.Expressions)
- {
- if (!IsStaticallyResolvable(content, semanticModel))
- {
- return false;
- }
- }
- return true;
- }
-
- // Handle other expressions conservatively (e.g., method calls, instance references, etc.)
- return false;
+ // No non-static nodes found
+ return true;
}
private static bool MemberHasNodeType(ITypeSymbol memberType, MarshalType marshalType)