-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C#: Fix Generated ScriptProperty Error. #65907
C#: Fix Generated ScriptProperty Error. #65907
Conversation
I will need some example script code to understand what this fixes. |
These codes generate these errors |
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
Show resolved
Hide resolved
87b0790
to
335f43b
Compare
I still think it would be preferable to always use fully qualified names (and not omitting [Export]
public Array<Node> MyNodes { get; set; } = new Array<Node>(); Generates this code: internal new static System.Collections.Generic.Dictionary<StringName, object> GetGodotPropertyDefaultValues()
{
var values = new System.Collections.Generic.Dictionary<StringName, object>(1);
Godot.Collections.Array<Godot.Node> __MyNodes_default_value = new Array<Node>();
values.Add(PropertyName.MyNodes, __MyNodes_default_value);
return values;
} The issue is the default value expression isn't fully qualified since it's taken as is from the source. This PR intends to fix this by including the same usings in the generated file as the ones declared in the source, this could still conflict and I'd prefer if we didn't omit global either. This code would still fail even with this PR: // using Godot; // <-- No using Godot namespace
public partial class Sprite2D : Godot.Resource {} // <- class with same name as one of the classes in Godot namespace, can be defined in a different file
public partial class MyNode : Godot.Node
{
[Godot.Export]
public Sprite2D Sprite { get; set; } = new Sprite2D();
} This PR also fixes conflicts when the exported members share the same name with a local variable defined in the generated code by adding |
In the latest PR, this paragraph is valid. At the beginning, I really wanted to use the fully qualified name, but after a long time of searching the roslyn document, I couldn't find a good way, so I had to do it first. To cope with various methods, the current solution also has its own advantages A _x = new A();
A _x = A.C();
A _x = A.C(new B());
A _x = new A(new B());
//Other more and more complex
//Find and compare "fully qualified names" for each one 在最新的PR中,这段是有效的. |
335f43b
to
e500057
Compare
A new modification has been added. string _aaa = "test";
[Export]
string AAA
{
get
{
return _aaa;
}
set
{
_aaa = value;
}
}
private string _newAnimation = "xxxxx";
[Godot.Export(Godot.PropertyHint.Enum, "xxxx,xx,xx")]
public string NewAnimation
{
get => _newAnimation;
set
{
_newAnimation = value;
}
} |
e500057
to
5b9b96e
Compare
Adjusted according to #68580 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to work well. Thanks for the contribution!
My main concern is the case where the default value is the result of an expensive operation because it will be executed on each call to GetGodotPropertyDefaultValues
and it can be problematic if the operation has side-effects. However, this was already how it worked before this PR, I just wanted to bring attention to it.
[Export]
public int MyProperty { get; set; } = MyExpensiveMethodWithSideEffects();
Also, we may want to add an example to the Godot.SourceGenerators.Sample
project with the syntax that this PR adds support for:
private int _myProperty = 42;
[Export]
public int MyProperty
{
get => _myProperty;
set => _myProperty = value;
}
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
5b9b96e
to
d808c2a
Compare
Generally speaking, the default value of the attribute should not change. [Export]
public int MyProperty { get; set; } = MyExpensiveMethodWithSideEffects(); //generated
private int __MyProperty = MyExpensiveMethodWithSideEffects();
internal new static System.Collections.Generic.Dictionary<StringName, object> GetGodotPropertyDefaultValues()
{
...
string __MyPropert_default_value = __MyProperty;
...
} 通常来说,属性默认值应该是不太会变动的. |
30167a7
to
8648ee5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good to merge already, @neikeq may to review this too since he self-requested a review.
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
8648ee5
to
5c4b369
Compare
Yes, I'll review this tonight. Property default values are delicate so I want to make sure we're not doing anything undesirable. |
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
Outdated
Show resolved
Hide resolved
} | ||
else | ||
{ | ||
var returnStatementSyntax = propertyGet.DescendantNodes().OfType<ReturnStatementSyntax>().FirstOrDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make sure that the body of the getter is a single return statement, it only looks for that return statement. This can have many problems, even if the return example is just an identifier for a field. For example, a method could have more than one return statement.
IMO, the best we can support here is bodies that contain only a return statement with the identifier (as weird as it would be to write that with a block rather than an expression body). This code should make sure that's all the code does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only generate a single return, which should be applicable to most cases
5c4b369
to
f16c5b5
Compare
134014d
to
950a6d8
Compare
1. Add "this." to prevent errors caused by duplicate variable names. 2. Try to find the default value of property getters.
950a6d8
to
c41196f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to merge.
I think the code to get the initializer and it's value is duplicated in 3 places now, so it's a good candidate to extract to a method. But it's not necessary in order to merge.
Thanks! |
For me, naming the method is a very distressing thing ha.
|
Add "this." to prevent errors caused by duplicate variable names.
Try to find the default value of property getters.
加上"this.",防止和生成的变量名重名导致的错误.
尝试查找属性的默认值.
Bugsquad edit: