Merge pull request #111523 from Joy-less/fix-IsStaticallyResolvable

Fix `IsStaticallyResolvable`
This commit is contained in:
Thaddeus Crews 2025-10-16 12:48:03 -05:00
commit 13404515fb
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
4 changed files with 76 additions and 96 deletions

View file

@ -37,6 +37,18 @@ partial class ExportedProperties
/// </summary>
public new static readonly global::Godot.StringName @LamdaPropertyString = "LamdaPropertyString";
/// <summary>
/// Cached name for the 'PrimaryCtorParameter' property.
/// </summary>
public new static readonly global::Godot.StringName @PrimaryCtorParameter = "PrimaryCtorParameter";
/// <summary>
/// Cached name for the 'ConstantMath' property.
/// </summary>
public new static readonly global::Godot.StringName @ConstantMath = "ConstantMath";
/// <summary>
/// Cached name for the 'StaticStringAddition' property.
/// </summary>
public new static readonly global::Godot.StringName @StaticStringAddition = "StaticStringAddition";
/// <summary>
/// Cached name for the 'PropertyBoolean' property.
/// </summary>
public new static readonly global::Godot.StringName @PropertyBoolean = "PropertyBoolean";
@ -317,6 +329,18 @@ partial class ExportedProperties
this.@LamdaPropertyString = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
return true;
}
if (name == PropertyName.@PrimaryCtorParameter) {
this.@PrimaryCtorParameter = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
return true;
}
if (name == PropertyName.@ConstantMath) {
this.@ConstantMath = global::Godot.NativeInterop.VariantUtils.ConvertTo<float>(value);
return true;
}
if (name == PropertyName.@StaticStringAddition) {
this.@StaticStringAddition = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
return true;
}
if (name == PropertyName.@PropertyBoolean) {
this.@PropertyBoolean = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value);
return true;
@ -599,6 +623,18 @@ partial class ExportedProperties
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@LamdaPropertyString);
return true;
}
if (name == PropertyName.@PrimaryCtorParameter) {
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@PrimaryCtorParameter);
return true;
}
if (name == PropertyName.@ConstantMath) {
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<float>(this.@ConstantMath);
return true;
}
if (name == PropertyName.@StaticStringAddition) {
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@StaticStringAddition);
return true;
}
if (name == PropertyName.@PropertyBoolean) {
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<bool>(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));

View file

@ -11,7 +11,7 @@ partial class ExportedProperties
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal new static global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant> GetGodotPropertyDefaultValues()
{
var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(64);
var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(67);
string __NotGenerateComplexLamdaProperty_default_value = default;
values.Add(PropertyName.@NotGenerateComplexLamdaProperty, global::Godot.Variant.From<string>(__NotGenerateComplexLamdaProperty_default_value));
string __NotGenerateLamdaNoFieldProperty_default_value = default;
@ -26,6 +26,12 @@ partial class ExportedProperties
values.Add(PropertyName.@FullPropertyString_Complex, global::Godot.Variant.From<string>(__FullPropertyString_Complex_default_value));
string __LamdaPropertyString_default_value = "LamdaPropertyString";
values.Add(PropertyName.@LamdaPropertyString, global::Godot.Variant.From<string>(__LamdaPropertyString_default_value));
string __PrimaryCtorParameter_default_value = default;
values.Add(PropertyName.@PrimaryCtorParameter, global::Godot.Variant.From<string>(__PrimaryCtorParameter_default_value));
float __ConstantMath_default_value = 2 * global::Godot.Mathf.Pi;
values.Add(PropertyName.@ConstantMath, global::Godot.Variant.From<float>(__ConstantMath_default_value));
string __StaticStringAddition_default_value = string.Empty + string.Empty;
values.Add(PropertyName.@StaticStringAddition, global::Godot.Variant.From<string>(__StaticStringAddition_default_value));
bool __PropertyBoolean_default_value = true;
values.Add(PropertyName.@PropertyBoolean, global::Godot.Variant.From<bool>(__PropertyBoolean_default_value));
char __PropertyChar_default_value = 'f';

View file

@ -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';

View file

@ -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)