]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
girparser: Improve instance method detection
authorRico Tzschichholz <ricotz@ubuntu.com>
Tue, 3 Aug 2021 16:11:06 +0000 (18:11 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 5 Aug 2021 13:30:34 +0000 (15:30 +0200)
See https://gitlab.gnome.org/GNOME/vala/issues/1210

vala/valagirparser.vala

index ee28f83508568ee6d9e9269482b93a56bdbfebb7..7203a88aacf157244d45592c43516195f2185586 100644 (file)
@@ -1326,7 +1326,9 @@ public class Vala.GirParser : CodeVisitor {
                                        }
 
                                        if (node.new_symbol && !node.merged && !metadata.get_bool (ArgumentType.HIDDEN)) {
-                                               add_symbol_to_container (symbol, node.symbol);
+                                               if (symbol.name == null || node.lookup (symbol.name) == null) {
+                                                       add_symbol_to_container (symbol, node.symbol);
+                                               }
                                        }
                                }
 
@@ -2570,7 +2572,7 @@ public class Vala.GirParser : CodeVisitor {
                return type;
        }
 
-       Parameter parse_parameter (out int array_length_idx = null, out int closure_idx = null, out int destroy_idx = null, out string? scope = null, out Comment? comment = null, string? default_name = null) {
+       Parameter parse_parameter (out bool caller_allocates, out int array_length_idx = null, out int closure_idx = null, out int destroy_idx = null, out string? scope = null, out Comment? comment = null, string? default_name = null) {
                var begin = this.begin;
                Parameter param;
 
@@ -2609,6 +2611,7 @@ public class Vala.GirParser : CodeVisitor {
                string nullable = reader.get_attribute ("nullable");
                string allow_none = reader.get_attribute ("allow-none");
 
+               caller_allocates = reader.get_attribute ("caller-allocates") == "1";
                scope = element_get_string ("scope", ArgumentType.SCOPE);
 
                string closure = reader.get_attribute ("closure");
@@ -3223,6 +3226,7 @@ public class Vala.GirParser : CodeVisitor {
                public bool is_async;
                public bool is_async_result;
                public bool is_error;
+               public bool caller_allocates;
        }
 
        void parse_function (string element_name) {
@@ -3454,12 +3458,13 @@ public class Vala.GirParser : CodeVisitor {
                                        continue;
                                }
 
+                               bool caller_allocates;
                                int array_length_idx, closure_idx, destroy_idx;
                                string scope;
                                string default_param_name = null;
                                Comment? param_comment;
                                default_param_name = "arg%d".printf (parameters.size);
-                               var param = parse_parameter (out array_length_idx, out closure_idx, out destroy_idx, out scope, out param_comment, default_param_name);
+                               var param = parse_parameter (out caller_allocates, out array_length_idx, out closure_idx, out destroy_idx, out scope, out param_comment, default_param_name);
 
                                if (is_instance_parameter) {
                                        unowned Method? m = s as Method;
@@ -3509,6 +3514,7 @@ public class Vala.GirParser : CodeVisitor {
                                }
 
                                var info = new ParameterInfo (param, array_length_idx, closure_idx, destroy_idx, scope == "async");
+                               info.caller_allocates = caller_allocates;
                                parameters.add (info);
                                pop_metadata ();
                        }
@@ -3995,6 +4001,7 @@ public class Vala.GirParser : CodeVisitor {
                        }
                }
 
+               bool first_param = true;
                foreach (ParameterInfo info in parameters) {
                        unowned DataType type = info.param.variable_type;
 
@@ -4045,6 +4052,25 @@ public class Vala.GirParser : CodeVisitor {
                                        info.keep = false;
                                }
                        }
+
+                       // Try to transform static function to instance method
+                       if (first_param && info.keep && type != null && s is Method && ((Method) s).binding == MemberBinding.STATIC) {
+                               Symbol? sym;
+                               if (type is UnresolvedType) {
+                                       sym = resolve_symbol (node.parent, ((UnresolvedType) type).unresolved_symbol);
+                               } else {
+                                       sym = type.type_symbol;
+                               }
+                               if (sym == node.parent.symbol && !type.nullable
+                                   && ((sym is TypeSymbol && info.param.direction == ParameterDirection.IN)
+                                   || (info.caller_allocates && info.param.direction == ParameterDirection.OUT
+                                       && (sym is Struct || (sym is Class && ((Class) sym).is_compact))))) {
+                                       ((Method) s).binding = MemberBinding.INSTANCE;
+                                       info.keep = false;
+                               }
+                       }
+
+                       first_param = false;
                }
 
                // Add null-literal as default-value for trailing GLib.Cancellable parameters