Browse Source

Merge pull request #65907 from magian1127/4.0FixPropertiesGenerator

C#: Fix Generated ScriptProperty Error.
Ignacio Roldán Etcheverry 2 years ago
parent
commit
4a82d71d73

+ 89 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs

@@ -12,6 +12,95 @@ namespace Godot.SourceGenerators.Sample
     [SuppressMessage("ReSharper", "InconsistentNaming")]
     [SuppressMessage("ReSharper", "InconsistentNaming")]
     public partial class ExportedProperties : Godot.Object
     public partial class ExportedProperties : Godot.Object
     {
     {
+        // Do not generate default value
+        private String _notGenerate_Property_String = new string("not generate");
+        [Export]
+        public String NotGenerate_Complex_Lamda_Property
+        {
+            get => _notGenerate_Property_String + Convert.ToInt32("1");
+            set => _notGenerate_Property_String = value;
+        }
+
+        [Export]
+        public String NotGenerate_Lamda_NoField_Property
+        {
+            get => new string("not generate");
+            set => _notGenerate_Property_String = value;
+        }
+
+        [Export]
+        public String NotGenerate_Complex_Return_Property
+        {
+            get
+            {
+                return _notGenerate_Property_String + Convert.ToInt32("1");
+            }
+            set
+            {
+                _notGenerate_Property_String = value;
+            }
+        }
+
+        private int _notGenerate_Property_Int = 1;
+        [Export]
+        public string NotGenerate_Returns_Property
+        {
+            get
+            {
+                if (_notGenerate_Property_Int == 1)
+                {
+                    return "a";
+                }
+                else
+                {
+                    return "b";
+                }
+            }
+            set
+            {
+                _notGenerate_Property_Int = value == "a" ? 1 : 2;
+            }
+        }
+
+        // Full Property
+        private String _fullProperty_String = "FullProperty_String";
+        [Export]
+        public String FullProperty_String
+        {
+            get
+            {
+                return _fullProperty_String;
+            }
+            set
+            {
+                _fullProperty_String = value;
+            }
+        }
+
+        private String _fullProperty_String_Complex = new string("FullProperty_String_Complex") + Convert.ToInt32("1");
+        [Export]
+        public String FullProperty_String_Complex
+        {
+            get
+            {
+                return _fullProperty_String_Complex;
+            }
+            set
+            {
+                _fullProperty_String_Complex = value;
+            }
+        }
+
+        // Lamda Property
+        private String _lamdaProperty_String = "LamdaProperty_String";
+        [Export]
+        public String LamdaProperty_String
+        {
+            get => _lamdaProperty_String;
+            set => _lamdaProperty_String = value;
+        }
+
+        // Auto Property
         [Export] private Boolean property_Boolean { get; set; } = true;
         [Export] private Boolean property_Boolean { get; set; } = true;
         [Export] private Char property_Char { get; set; } = 'f';
         [Export] private Char property_Char { get; set; } = 'f';
         [Export] private SByte property_SByte { get; set; } = 10;
         [Export] private SByte property_SByte { get; set; } = 10;

+ 2 - 2
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs

@@ -292,7 +292,7 @@ namespace Godot.SourceGenerators
             source.Append("if (name == PropertyName.")
             source.Append("if (name == PropertyName.")
                 .Append(propertyMemberName)
                 .Append(propertyMemberName)
                 .Append(") {\n")
                 .Append(") {\n")
-                .Append("            ")
+                .Append("            this.")
                 .Append(propertyMemberName)
                 .Append(propertyMemberName)
                 .Append(" = ")
                 .Append(" = ")
                 .AppendNativeVariantToManagedExpr("value", propertyTypeSymbol, propertyMarshalType)
                 .AppendNativeVariantToManagedExpr("value", propertyTypeSymbol, propertyMarshalType)
@@ -317,7 +317,7 @@ namespace Godot.SourceGenerators
                 .Append(propertyMemberName)
                 .Append(propertyMemberName)
                 .Append(") {\n")
                 .Append(") {\n")
                 .Append("            value = ")
                 .Append("            value = ")
-                .AppendManagedToNativeVariantExpr(propertyMemberName, propertyMarshalType)
+                .AppendManagedToNativeVariantExpr("this." + propertyMemberName, propertyMarshalType)
                 .Append(";\n")
                 .Append(";\n")
                 .Append("            return true;\n")
                 .Append("            return true;\n")
                 .Append("        }\n");
                 .Append("        }\n");

+ 59 - 9
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs

@@ -2,6 +2,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using Microsoft.CodeAnalysis.Text;
 using Microsoft.CodeAnalysis.Text;
 
 
@@ -163,19 +164,68 @@ namespace Godot.SourceGenerators
                     continue;
                     continue;
                 }
                 }
 
 
-                // TODO: Detect default value from simple property getters (currently we only detect from initializers)
-
-                EqualsValueClauseSyntax? initializer = property.DeclaringSyntaxReferences
-                    .Select(r => r.GetSyntax() as PropertyDeclarationSyntax)
-                    .Select(s => s?.Initializer ?? null)
-                    .FirstOrDefault();
+                var propertyDeclarationSyntax = property.DeclaringSyntaxReferences
+                    .Select(r => r.GetSyntax() as PropertyDeclarationSyntax).FirstOrDefault();
 
 
                 // Fully qualify the value to avoid issues with namespaces.
                 // Fully qualify the value to avoid issues with namespaces.
                 string? value = null;
                 string? value = null;
-                if (initializer != null)
+                if (propertyDeclarationSyntax != null)
                 {
                 {
-                    var sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
-                    value = initializer.Value.FullQualifiedSyntax(sm);
+                    if (propertyDeclarationSyntax.Initializer != null)
+                    {
+                        var sm = context.Compilation.GetSemanticModel(propertyDeclarationSyntax.Initializer.SyntaxTree);
+                        value = propertyDeclarationSyntax.Initializer.Value.FullQualifiedSyntax(sm);
+                    }
+                    else
+                    {
+                        var propertyGet = propertyDeclarationSyntax.AccessorList?.Accessors.Where(a => a.Keyword.IsKind(SyntaxKind.GetKeyword)).FirstOrDefault();
+                        if (propertyGet != null)
+                        {
+                            if (propertyGet.ExpressionBody != null)
+                            {
+                                if (propertyGet.ExpressionBody.Expression is IdentifierNameSyntax identifierNameSyntax)
+                                {
+                                    var sm = context.Compilation.GetSemanticModel(identifierNameSyntax.SyntaxTree);
+                                    var fieldSymbol = sm.GetSymbolInfo(identifierNameSyntax).Symbol as IFieldSymbol;
+                                    EqualsValueClauseSyntax? initializer = fieldSymbol?.DeclaringSyntaxReferences
+                                        .Select(r => r.GetSyntax())
+                                        .OfType<VariableDeclaratorSyntax>()
+                                        .Select(s => s.Initializer)
+                                        .FirstOrDefault(i => i != null);
+
+                                    if (initializer != null)
+                                    {
+                                        sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
+                                        value = initializer.Value.FullQualifiedSyntax(sm);
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                var returns = propertyGet.DescendantNodes().OfType<ReturnStatementSyntax>();
+                                if (returns.Count() == 1)
+                                {// Generate only single return
+                                    var returnStatementSyntax = returns.Single();
+                                    if (returnStatementSyntax.Expression is IdentifierNameSyntax identifierNameSyntax)
+                                    {
+                                        var sm = context.Compilation.GetSemanticModel(identifierNameSyntax.SyntaxTree);
+                                        var fieldSymbol = sm.GetSymbolInfo(identifierNameSyntax).Symbol as IFieldSymbol;
+                                        EqualsValueClauseSyntax? initializer = fieldSymbol?.DeclaringSyntaxReferences
+                                            .Select(r => r.GetSyntax())
+                                            .OfType<VariableDeclaratorSyntax>()
+                                            .Select(s => s.Initializer)
+                                            .FirstOrDefault(i => i != null);
+
+                                        if (initializer != null)
+                                        {
+                                            sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
+                                            value = initializer.Value.FullQualifiedSyntax(sm);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
                 }
                 }
 
 
                 exportedMembers.Add(new ExportedPropertyMetadata(
                 exportedMembers.Add(new ExportedPropertyMetadata(