After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 725363 - Bindings for GLib.Action include both properties and accessor methods
Bindings for GLib.Action include both properties and accessor methods
Status: RESOLVED OBSOLETE
Product: vala
Classification: Core
Component: Bindings: GLib
0.20.x
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2014-02-28 04:16 UTC by Edward Hennessy
Modified: 2018-05-22 15:05 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Minimum GIR file to reproduce the issue (2.15 KB, application/octet-stream)
2014-03-17 04:20 UTC, Edward Hennessy
  Details
fix overridable getter/setter in girparser (3.06 KB, patch)
2014-04-05 17:03 UTC, Luca Bruno
none Details | Review

Description Edward Hennessy 2014-02-28 04:16:31 UTC
The bindings for GLib.Action include properties and accessor methods for the same properties. Implementing both properties and accessor methods in derived classes results in compile errors.

Deriving a class from Glib.Action and implementing all abstract methods results in compile errors like the following:

CloseProjectAction.c:146:17: error: redefinition of ‘close_project_action_real_get_enabled’
 static gboolean close_project_action_real_get_enabled (GAction* base) {
                 ^
CloseProjectAction.c:71:17: note: previous definition of ‘close_project_action_real_get_enabled’ was here
 static gboolean close_project_action_real_get_enabled (GAction* base) {
                 ^

...and two similar errors for each property.

Bug was encountered on Ubuntu 13.10 using vala 0.20.1 The accessor methods are present in latest source control gio-2.0.vapi.
Comment 1 Edward Hennessy 2014-03-12 04:02:02 UTC
valagirparser.vala line 921 (Shown with debugging code)

    prop.set_attribute ("NoAccessorMethod", false);
    if (prop.get_accessor != null) {
        var m = getter != null ? getter.symbol as Method : null;
        // ensure getter vfunc if the property is abstract
        if (m != null && (m.is_abstract || m.is_virtual || !prop.is_abstract)) {
            getter.process (parser);
            if (m.return_type is VoidType || m.get_parameters().size != 0) {
                prop.set_attribute ("NoAccessorMethod", true);
            } else {
                if (getter.name == name) {
                    stdout.printf("**** Match ****\n");
                    stdout.printf("  getter.name = %s\n", getter.name);
                    stdout.printf("  name =        %s\n", name);
                    foreach (var node in colliding) {
                        if (node.symbol is Method) {
                            node.merged = true;
                        }
                    }
                }
                else {
                    stdout.printf("No match\n");
                }
                prop.get_accessor.value_type.value_owned = m.return_type.value_owned;
            }
        } else {
            prop.set_attribute ("NoAccessorMethod", true);
        }
    }

The (getter.name == name) compares the getter name (get_enabled) to the property name (enabled). I’m not sure this logic is correct. Adding the debugging code, plenty of “No match” are displayed, but no “**** Match ****” outputs are displayed when parsing gio-2.0.

I’m suspecting that the foreach, inside the body of this if, should iterate through the nodes and eliminate methods that match the method name (get_enabled). But, I don’t know what the intended purpose of this code segment.
Comment 2 Luca Bruno 2014-03-12 08:21:04 UTC
You are still reading the same piece code as in the mailing list, look a tad earlier in the file: https://git.gnome.org/browse/vala/tree/vala/valagirparser.vala#n902
Comment 3 Luca Bruno 2014-03-12 08:26:18 UTC
As for getter.name == name, that's wrong yes. Maybe it should simply look like:
getter.merged=true

About: for node in colliding: node.merged=true
This behavior must be kept somehow, as there are cases where a method has the same name of the property.

Thanks for looking into it.This problem has been fixed in the development version. The fix will be available in the next major software release. Thank you for your bug report.
Comment 4 Luca Bruno 2014-03-12 08:27:20 UTC
Also not only methods, especially there are signals that have the same name as the property. This is the priority: property > signal > method.
Comment 5 Luca Bruno 2014-03-12 08:28:08 UTC
Why is this marked as fixed? :S
Comment 6 Luca Bruno 2014-03-12 08:28:59 UTC
Why is this marked as fixed? :S
Comment 7 Edward Hennessy 2014-03-17 04:20:49 UTC
Created attachment 272112 [details]
Minimum GIR file to reproduce the issue

This file is a subset of Gio-2.0.gir for use with testing. The file has been reduced to a single interface with a single property.

To use:

vapigen --library minimum Minimum.gir
Comment 8 Edward Hennessy 2014-03-17 04:29:14 UTC
(In reply to comment #3)
> As for getter.name == name, that's wrong yes. Maybe it should simply look like:
> getter.merged=true
> 

Some properties have two getter methods associated with them. In the gir file attached, get_enabled has two entries -- one is a "method" and the other is a "virtual-method". Do both these entries need to be merged? Both these nodes appear when searching in valagirparser.vala beginning at line 902.
Comment 9 Edward Hennessy 2014-03-17 04:42:13 UTC
(In reply to comment #2)
> You are still reading the same piece code as in the mailing list, look a tad
> earlier in the file:
> https://git.gnome.org/browse/vala/tree/vala/valagirparser.vala#n902

I can't see anything wrong there. I've added debugging code:

Node getter = null;
stdout.printf("Looking for getter for property = %s\n", name);
var getters = parent.lookup_all ("get_%s".printf (name));
if (getters != null) {
    foreach (var g in getters) {
        stdout.printf("    Trying getter.name = %s\n", g.name);
        if ((getter == null || !g.merged) && g.get_cname () == parent.get_lower_case_cprefix() + "get_" + name) {
            stdout.printf("    Found getter.name  = %s\n", g.name);
            getter = g;
        }
    }
}

Here is the output:

Looking for getter for property = enabled
    Trying getter.name = get_enabled
    Found getter.name  = get_enabled
    Trying getter.name = get_enabled
No match
Generation succeeded - 0 warning(s)

This code is finding one of the two methods. So, I think the code is correct.
Comment 10 Edward Hennessy 2014-03-17 04:59:47 UTC
(In reply to comment #8)
> (In reply to comment #3)
> > As for getter.name == name, that's wrong yes. Maybe it should simply look like:
> > getter.merged=true
> > 
> 
> Some properties have two getter methods associated with them. In the gir file
> attached, get_enabled has two entries -- one is a "method" and the other is a
> "virtual-method". Do both these entries need to be merged? Both these nodes
> appear when searching in valagirparser.vala beginning at line 902.

I added more debugging code, and one of the methods is already merged. So, getter.merged=true may be it.
Comment 11 Luca Bruno 2014-03-17 08:36:44 UTC
(In reply to comment #8)
> Some properties have two getter methods associated with them. In the gir file
> attached, get_enabled has two entries -- one is a "method" and the other is a
> "virtual-method". Do both these entries need to be merged? Both these nodes
> appear when searching in valagirparser.vala beginning at line 902.

Yes both must be merged, but if one is a virtual/abstract method this information must be propagated to the property. The gir is a bad guy to parse :S
Comment 12 Edward Hennessy 2014-03-18 02:59:35 UTC
(In reply to comment #8)
> (In reply to comment #3)
> > As for getter.name == name, that's wrong yes. Maybe it should simply look like:
> > getter.merged=true
> > 
> 
> Some properties have two getter methods associated with them. In the gir file
> attached, get_enabled has two entries -- one is a "method" and the other is a
> "virtual-method". Do both these entries need to be merged? Both these nodes
> appear when searching in valagirparser.vala beginning at line 902.

I added more debugging code, and one of the methods is already merged. So, getter.merged=true may be it.
Comment 13 Edward Hennessy 2014-03-18 03:43:52 UTC
(In reply to comment #11)
> Yes both must be merged, but if one is a virtual/abstract method this
> information must be propagated to the property. The gir is a bad guy to parse
> :S

When parsing the file, the virtual-method does take priority over the plain method. With the following test code, I reversed the method and virtual method in the input file:

    stdout.printf("Looking for node property = %s\n", name);
    Node getter = null;
    int unmerge_count = 0;
    var getters = parent.lookup_all ("get_%s".printf (name));
    if (getters != null) {
        foreach (var g in getters) {
            stdout.printf("    Checking node name=%s, cname=%s, merged=%s, element_name=%s\n", g.name, g.get_cname(), g.merged.to_string(), g.element_type);
            if ((getter == null || !g.merged) && g.get_cname () == parent.get_lower_case_cprefix() + "get_" + name) {
                stdout.printf("    Found node name=%s, cname=%s, merged=%s, element_name=%s\n", g.name, g.get_cname(), g.merged.to_string(), g.element_type);
                getter = g;
            }
            if (!g.merged) {
                unmerge_count++;
            }
        }
    }
    if (getter != null) {
        stdout.printf("Result node type = %s\n", getter.element_type);
    }
    stdout.printf("Count of unmerged items = %d\n", unmerge_count);
    assert (unmerge_count <= 1);

And gives the output with the minimum input file and another file where the two elements are reversed:

Looking for node property = enabled
    Checking node name=get_enabled, cname=g_action_get_enabled, merged=false, element_name=virtual-method
    Found node name=get_enabled, cname=g_action_get_enabled, merged=false, element_name=virtual-method
    Checking node name=get_enabled, cname=g_action_get_enabled, merged=true, element_name=method
Result node type = virtual-method
Count of unmerged items = 1
Generation succeeded - 0 warning(s)
Looking for node property = enabled
    Checking node name=get_enabled, cname=g_action_get_enabled, merged=true, element_name=method
    Found node name=get_enabled, cname=g_action_get_enabled, merged=true, element_name=method
    Checking node name=get_enabled, cname=g_action_get_enabled, merged=false, element_name=virtual-method
    Found node name=get_enabled, cname=g_action_get_enabled, merged=false, element_name=virtual-method
Result node type = virtual-method
Count of unmerged items = 1
Generation succeeded - 0 warning(s)

When both files are parsed, the forward and backward, the virtual-method takes precedence. So, I think the search function matches the behavior you describe, in this testcase.

Additionally, when parsing the full gio-2.0, a maximum of one unmerged item was found. If this case hold true in other gir files, the simple getter.merged=true will merge all the remaining getters.

What would be the next step?
Comment 14 Luca Bruno 2014-03-18 08:39:27 UTC
Thanks a lot for digging into it. In the next days I'm going to review your insights and see how we can fix this at best. Feel free to provide a patch if you come with a good solution which keeps compatibility with all other generated vapis.
Comment 15 Luca Bruno 2014-04-05 17:03:17 UTC
Created attachment 273638 [details] [review]
fix overridable getter/setter in girparser

Sorry for the delay. What do you think about the attached patch?
Comment 16 Evan Nemerson 2014-06-28 20:02:11 UTC
(In reply to comment #15)
> Created an attachment (id=273638) [details] [review]
> fix overridable getter/setter in girparser
> 
> Sorry for the delay. What do you think about the attached patch?

This breaks backwards compatibility...  can't we just remove the abstract from the methods instead?  So we would end up with something like

  public interface Action : GLib.Object {
    public bool get_enabled ();
    public abstract bool enabled { get; }
  }
Comment 17 GNOME Infrastructure Team 2018-05-22 15:05:11 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/vala/issues/433.