GNOME Bugzilla – Bug 607568
Properties not supported in compact classes, but vala showing an unrelated error
Last modified: 2018-01-05 21:19:37 UTC
When trying to compile properties in compact classes you get: test.vala:2.1-2.16: error: Private fields not supported in compact classes I think that properties should be supported for compact classes as well as in GObject based ones (this should be another bug). But the error message should be more descriptive if it is really not going to be supported. This should probably happen in other special types like signal or private data. test code is: ---------8<-------------- [Compact] public class Foo { public string name { get; set; } public Foo (string name) { this.name = name; } } void main() { Foo foo = new Foo ("foo"); foo = null; } -------------->8---------
Actually, the error is correct. Properties are supported for compact classes, but automatic property creates a private variable to store the value, which isn't supported.
Though the error is not obvious and should read something like "Automatic properties not supported for compact classes", I'd be more interested in generally allowing private fields there. Why is it not possible?
Created attachment 151880 [details] [review] Fix auto properties getter/setter on compact classes Fixes
Private fields are not possible as Vala does not add implicit fields such as 'priv' to the struct of a compact class. They are only meant to be used for bindings and few other special cases. I don't see a point in allowing automatic properties here. They are nearly equivalent to public fields, but the fact that you expose a struct field / change the API/ABI is hidden. If anyone thinks there is a use case for this, please comment, otherwise we should just improve the error message.
I agree with that. Compact classes can use public attributes.
Taking following code: [Compact] public class Test { public string name; public string id { get { return name; } set { name = value; } } } public void main () { var c = new Test (); c.id = "Name"; stdout.printf (c.id); } Compact classes' property declaration can be used to declare accessors for a C struct members in the way programmers want their C users do it. Using valac -H to create a header, you will find: typedef struct _Test Test; struct _Test { gchar* name; }; void test_free (Test* self); Test* test_new (void); const gchar* test_get_id (Test* self); void test_set_id (Test* self, const gchar* value); void _vala_main (void); So your C API users can use test_get/set_id() to access your compact class (C struct) members. If you, the author, don't want to expose your struct's members to the public API, you can declare as "internal": [Compact] internal class Test { public string name; } [Compact] public class PublicTest { internal Test test; public PublicTest (string n) { test = new Test (); test.name = n; } public string id { get { return test.name; } set { test.name = value; } } } Your header file will be: typedef struct _PublicTest PublicTest; typedef struct _Test Test; struct _PublicTest { Test* test; }; void public_test_free (PublicTest* self); void test_free (Test* self); PublicTest* public_test_new (const gchar* n); const gchar* public_test_get_id (PublicTest* self); void public_test_set_id (PublicTest* self, const gchar* value); void _vala_main (void); As you can see your Test struct is now sealed and no one can access it, but with PublicTest API exposed. Because this is not a problem for Vala and already rised error for private files not supported, I'm closing this bug for further discussion on bug: https://bugzilla.gnome.org/show_bug.cgi?id=792254