]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Improve handling of "array_length_type" attribute
authorRico Tzschichholz <ricotz@ubuntu.com>
Tue, 17 Mar 2020 14:26:36 +0000 (15:26 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Tue, 17 Mar 2020 14:35:01 +0000 (15:35 +0100)
This affects methods, parameters, field and properties.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/938

codegen/valaccodearraymodule.vala
codegen/valaccodebasemodule.vala
codegen/valaccodedelegatemodule.vala
codegen/valaccodememberaccessmodule.vala
codegen/valaccodemethodcallmodule.vala
codegen/valaccodemethodmodule.vala
codegen/valagasyncmodule.vala
codegen/valagsignalmodule.vala
codegen/valagtypemodule.vala
tests/Makefile.am
tests/methods/array-length-type.vala [new file with mode: 0644]

index c90bae49bf4e0462a7efc3fc7034121fb4bba1c9..f35ac53258285d24f991080dcdc8d106ac994a82 100644 (file)
@@ -806,7 +806,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                }
 
                if (!array_type.fixed_length && get_ccode_array_length (param)) {
-                       var length_ctype = get_ccode_array_length_type (param) ?? get_ccode_array_length_type (array_type);
+                       var length_ctype = get_ccode_array_length_type (param);
                        if (param.direction != ParameterDirection.IN) {
                                length_ctype = "%s*".printf (length_ctype);
                        }
index e04ad34b55948c456a88e8f3931749d9f644517f..27b0ba10154fe300115c42452219b2d1a849e171 100644 (file)
@@ -1054,7 +1054,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        // create fields to store array dimensions
                        var array_type = (ArrayType) f.variable_type;
                        if (!array_type.fixed_length) {
-                               var length_ctype = get_ccode_array_length_type (array_type);
+                               var length_ctype = get_ccode_array_length_type (f);
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        string length_cname = get_variable_array_length_cname (f, dim);
                                        ccode_struct.add_field (length_ctype, length_cname);
@@ -1117,7 +1117,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        var array_type = (ArrayType) f.variable_type;
 
                        if (!array_type.fixed_length) {
-                               var length_ctype = get_ccode_array_length_type (array_type);
+                               var length_ctype = get_ccode_array_length_type (f);
 
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        cdecl = new CCodeDeclaration (length_ctype);
@@ -1322,7 +1322,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        var array_type = (ArrayType) f.variable_type;
 
                                        if (!array_type.fixed_length) {
-                                               var length_ctype = get_ccode_array_length_type (array_type);
+                                               var length_ctype = get_ccode_array_length_type (f);
 
                                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                                        var len_def = new CCodeDeclaration (length_ctype);
@@ -1619,7 +1619,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
                        var array_type = (ArrayType) acc.value_type;
-                       var length_ctype = get_ccode_array_length_type (array_type);
+                       var length_ctype = get_ccode_array_length_type (prop);
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*" : length_ctype));
                        }
@@ -1713,7 +1713,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                        if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
                                var array_type = (ArrayType) acc.value_type;
-                               var length_ctype = get_ccode_array_length_type (array_type);
+                               var length_ctype = get_ccode_array_length_type (prop);
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*": length_ctype));
                                }
@@ -1837,7 +1837,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                        if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
                                var array_type = (ArrayType) acc.value_type;
-                               var length_ctype = get_ccode_array_length_type (array_type);
+                               var length_ctype = get_ccode_array_length_type (prop);
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*" : length_ctype));
                                }
@@ -1894,7 +1894,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        get_call.add_argument (new CCodeIdentifier (is_virtual ? "base" : "self"));
 
                                        if (property_type is ArrayType && get_ccode_array_length (prop)) {
-                                               ccode.add_declaration (get_ccode_array_length_type (property_type), new CCodeVariableDeclarator ("old_value_length"));
+                                               ccode.add_declaration (get_ccode_array_length_type (prop), new CCodeVariableDeclarator ("old_value_length"));
                                                get_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("old_value_length")));
                                                ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_call, new CCodeIdentifier ("value")));
                                        } else if (property_type.compatible (string_type)) {
@@ -1994,7 +1994,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                var deleg_type = param.variable_type as DelegateType;
 
                if (array_type != null && get_ccode_array_length (param)) {
-                       var length_ctype = get_ccode_array_length_type (array_type);
+                       var length_ctype = get_ccode_array_length_type (param);
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                data.add_field (length_ctype, get_variable_array_length_cname (param, dim));
                        }
index d3399f93e3bc017883fb80a3f085dbffdbd50743..fa296623bc1adafbcd0ed6854a27cd309466c43e 100644 (file)
@@ -64,7 +64,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                } else if (get_ccode_array_length (d) && d.return_type is ArrayType) {
                        // return array length if appropriate
                        var array_type = (ArrayType) d.return_type;
-                       var length_ctype = (get_ccode_array_length_type (d) ?? get_ccode_array_length_type (array_type)) + "*";
+                       var length_ctype = get_ccode_array_length_type (d) + "*";
 
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                var cparam = new CCodeParameter (get_array_length_cname ("result", dim), length_ctype);
@@ -222,7 +222,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
                if (get_ccode_array_length (d) && d.return_type is ArrayType) {
                        // return array length if appropriate
                        var array_type = (ArrayType) d.return_type;
-                       var length_ctype = (get_ccode_array_length_type (d) ?? get_ccode_array_length_type (array_type)) + "*";
+                       var length_ctype = get_ccode_array_length_type (d) + "*";
 
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                var cparam = new CCodeParameter (get_array_length_cname ("result", dim), length_ctype);
index 50bd4f12172944b07a6ce01b8687ad406cb2e7c2..0a14420af4b45d68d3bfcfc7c6fd4fc843ed8742 100644 (file)
@@ -289,7 +289,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                                        ccode.add_assignment (temp_value.array_length_cvalues[0], len_call);
                                                } else if (get_ccode_array_length (prop)) {
                                                        for (int dim = 1; dim <= array_type.rank; dim++) {
-                                                               var length_ctype = get_ccode_array_length_type (prop) ?? get_ccode_array_length_type (array_type);
+                                                               var length_ctype = get_ccode_array_length_type (prop);
                                                                var temp_var = get_temp_variable (new CType (length_ctype, "0"), true, null, true);
                                                                var temp_ref = get_variable_cexpression (temp_var.name);
                                                                emit_temp_var (temp_var);
index 07ec2df6ca97eb378786fe926f238a33ae64da03..904e6a83a5dae80b4ac68530e7c99bba1e7a370a 100644 (file)
@@ -374,7 +374,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                        if (unary == null || unary.operator != UnaryOperator.OUT) {
                                                if (get_ccode_array_length (param) && param.variable_type is ArrayType && !((ArrayType) param.variable_type).fixed_length) {
                                                        var array_type = (ArrayType) param.variable_type;
-                                                       var length_ctype = get_ccode_array_length_type (param) ?? get_ccode_array_length_type (array_type);
+                                                       var length_ctype = get_ccode_array_length_type (param);
                                                        if (unary != null && unary.operator == UnaryOperator.REF) {
                                                                length_ctype = "%s*".printf (length_ctype);
                                                        }
@@ -435,7 +435,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                                                if (get_ccode_array_length (param) && param.variable_type is ArrayType && !((ArrayType) param.variable_type).fixed_length) {
                                                        var array_type = (ArrayType) param.variable_type;
-                                                       var length_ctype = get_ccode_array_length_type (param) ?? get_ccode_array_length_type (array_type);
+                                                       var length_ctype = get_ccode_array_length_type (param);
                                                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                                                var temp_array_length = get_temp_variable (new CType (length_ctype, "0"), true, null, true);
                                                                emit_temp_var (temp_array_length);
@@ -541,7 +541,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                                        append_array_length (expr, len_call);
                                } else if (get_ccode_array_length (m)) {
-                                       var length_ctype = get_ccode_array_length_type (m) ?? get_ccode_array_length_type (array_type);
+                                       var length_ctype = get_ccode_array_length_type (m);
                                        var temp_var = get_temp_variable (new CType (length_ctype, "0"), true, null, true);
                                        var temp_ref = get_variable_cexpression (temp_var.name);
 
@@ -608,7 +608,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                                        append_array_length (expr, len_call);
                                } else if (get_ccode_array_length (deleg)) {
-                                       var length_ctype = get_ccode_array_length_type (deleg) ?? get_ccode_array_length_type (array_type);
+                                       var length_ctype = get_ccode_array_length_type (deleg);
                                        var temp_var = get_temp_variable (new CType (length_ctype, "0"), true, null, true);
                                        var temp_ref = get_variable_cexpression (temp_var.name);
 
index 404a6153acbf2d5ae279b005dc3bede9223980b2..03b382ac4ba1667aad5879ad4bd449256bc481d8 100644 (file)
@@ -69,7 +69,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                } else if (get_ccode_array_length (m) && m.return_type is ArrayType) {
                        // return array length if appropriate
                        var array_type = (ArrayType) m.return_type;
-                       var length_ctype = (get_ccode_array_length_type (m) ?? get_ccode_array_length_type (array_type)) + "*";
+                       var length_ctype = get_ccode_array_length_type (m) + "*";
 
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                var cparam = new CCodeParameter (get_array_length_cname ("result", dim), length_ctype);
@@ -567,7 +567,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                                        var array_type = (ArrayType) param.variable_type;
 
                                                        if (!array_type.fixed_length) {
-                                                               var length_ctype = get_ccode_array_length_type (array_type);
+                                                               var length_ctype = get_ccode_array_length_type (param);
                                                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                                                        vardecl = new CCodeVariableDeclarator.zero (get_array_length_cname ("_vala_%s".printf (get_ccode_name (param)), dim), new CCodeConstant ("0"));
                                                                        ccode.add_declaration (length_ctype, vardecl);
index de2e34845b16223b32c94931d5d778b2be7892c9..d74431f71cb3023ed9c6f46427259c34ec311ca0 100644 (file)
@@ -53,7 +53,7 @@ public class Vala.GAsyncModule : GtkModule {
                        if (param.variable_type is ArrayType) {
                                var array_type = (ArrayType) param.variable_type;
                                if (get_ccode_array_length (param)) {
-                                       var length_ctype = get_ccode_array_length_type (array_type);
+                                       var length_ctype = get_ccode_array_length_type (param);
                                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                                data.add_field (length_ctype, get_variable_array_length_cname (param, dim));
                                        }
@@ -80,7 +80,7 @@ public class Vala.GAsyncModule : GtkModule {
                        if (m.return_type is ArrayType) {
                                var array_type = (ArrayType) m.return_type;
                                if (get_ccode_array_length (m)) {
-                                       var length_ctype = get_ccode_array_length_type (array_type);
+                                       var length_ctype = get_ccode_array_length_type (m);
                                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                                data.add_field (length_ctype, get_array_length_cname ("result", dim));
                                        }
index eda9f4bb5bfd01396f73cbac3b7c4fef96b927df..8035bf09bd982296a882c292867a0a586243e763 100644 (file)
@@ -201,7 +201,7 @@ public class Vala.GSignalModule : GObjectModule {
                        n_params++;
                        if (p.variable_type is ArrayType) {
                                var array_type = (ArrayType) p.variable_type;
-                               var length_ctype = get_ccode_array_length_type (array_type);
+                               var length_ctype = get_ccode_array_length_type (p);
                                for (var j = 0; j < array_type.rank; j++) {
                                        callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), length_ctype));
                                        n_params++;
index 777d916c253d6a603e78801e5ed3afec2423a9b1..59af901448dc7f8179fdfb536042cdb29cb66688 100644 (file)
@@ -356,7 +356,7 @@ public class Vala.GTypeModule : GErrorModule {
 
                        var array_type = prop.property_type as ArrayType;
                        if (array_type != null && get_ccode_array_length (prop)) {
-                               var length_ctype = get_ccode_array_length_type (array_type) + "*";
+                               var length_ctype = get_ccode_array_length_type (prop) + "*";
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname ("result", dim), length_ctype));
                                }
@@ -387,7 +387,7 @@ public class Vala.GTypeModule : GErrorModule {
 
                        var array_type = prop.property_type as ArrayType;
                        if (array_type != null && get_ccode_array_length (prop)) {
-                               var length_ctype = get_ccode_array_length_type (array_type);
+                               var length_ctype = get_ccode_array_length_type (prop);
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname ("value", dim), length_ctype));
                                }
index 893392b94ace3e8f91bcdaed73ae1ef075eeec17..464e61647a48d9e5ce95f29ba4dc9f5565b1d180 100644 (file)
@@ -114,6 +114,7 @@ TESTS = \
        chainup/struct-this-foo.vala \
        chainup/bug791785.vala \
        pointers/bug590641.vala \
+       methods/array-length-type.vala \
        methods/lambda.vala \
        methods/closures.vala \
        methods/contains.vala \
diff --git a/tests/methods/array-length-type.vala b/tests/methods/array-length-type.vala
new file mode 100644 (file)
index 0000000..942bd5f
--- /dev/null
@@ -0,0 +1,156 @@
+[CCode (array_length_type = "guint8")]
+delegate int[] FooFunc ([CCode (array_length_type = "guint8")] owned int[] p);
+
+interface IFoo {
+       [CCode (array_length_type = "guint8")]
+       public abstract int[] manam { get; set; }
+
+       [CCode (array_length_type = "guint8")]
+       public abstract int[] get_foo ();
+       public abstract void set_foo ([CCode (array_length_type = "guint8")] out int[] p);
+}
+
+class Foo : IFoo {
+       public int[] manam { get; set; }
+
+       [CCode (array_length_type = "guint8")]
+       public virtual int[] manar { get; set; }
+
+       public int[] get_foo () {
+               var res = new int[255];
+               res[254] = 4711;
+               return res;
+       }
+
+       public void set_foo (out int[] p) {
+               p = new int[255];
+               p[254] = 4711;
+       }
+
+       [CCode (array_length_type = "guint8")]
+       public virtual int[] get_bar () {
+               var res = new int[255];
+               res[254] = 4711;
+               return res;
+       }
+
+       public virtual void set_bar ([CCode (array_length_type = "guint8")] out int[] p) {
+               p = new int[255];
+               p[254] = 4711;
+       }
+
+       public Foo () {
+               {
+                       var a = get_foo ();
+                       assert (a.length == 255);
+                       assert (a[254] == 4711);
+               }
+               {
+                       int[] a = null;
+                       set_foo (out a);
+                       assert (a.length == 255);
+                       assert (a[254] == 4711);
+               }
+       }
+}
+
+class Bar : Foo {
+       public override int[] manar { get; set; }
+
+       public override int[] get_bar () {
+               var res = new int[255];
+               res[254] = 4711;
+               return res;
+       }
+
+       public override void set_bar (out int[] p) {
+               p = new int[255];
+               p[254] = 4711;
+       }
+
+       public Bar () {
+               {
+                       var a = get_foo ();
+                       assert (a.length == 255);
+                       assert (a[254] == 4711);
+               }
+               {
+                       int[] a = null;
+                       set_foo (out a);
+                       assert (a.length == 255);
+                       assert (a[254] == 4711);
+               }
+               {
+                       var a = get_bar ();
+                       assert (a.length == 255);
+                       assert (a[254] == 4711);
+               }
+               {
+                       int[] a = null;
+                       set_bar (out a);
+                       assert (a.length == 255);
+                       assert (a[254] == 4711);
+               }
+       }
+}
+
+[CCode (array_length_type = "guint8")]
+int[] get_foo () {
+       var res = new int[255];
+       res[254] = 4711;
+       return res;
+}
+
+void set_foo ([CCode (array_length_type = "guint8")] out int[] p) {
+       p = new int[255];
+       p[254] = 4711;
+}
+
+[CCode (array_length_type = "guint8")]
+int[] foo_func ([CCode (array_length_type = "guint8")] owned int[] p) {
+       return p;
+}
+
+void main () {
+       {
+               FooFunc f = (a) => { return a; };
+               int[] a = new int[255];
+               a[254] = 4711;
+               a = f ((owned) a);
+               assert (a.length == 255);
+               assert (a[254] == 4711);
+       }
+       {
+               FooFunc f = (FooFunc) foo_func;
+               int[] a = new int[255];
+               a[254] = 4711;
+               a = f ((owned) a);
+               assert (a.length == 255);
+               assert (a[254] == 4711);
+       }
+       {
+               var a = get_foo ();
+               assert (a.length == 255);
+               assert (a[254] == 4711);
+       }
+       {
+               int[] a = null;
+               set_foo (out a);
+               assert (a.length == 255);
+               assert (a[254] == 4711);
+       }
+       {
+               var foo = new Foo ();
+               foo.manam = new int[255];
+               foo.manam[254] = 4711;
+               assert (foo.manam.length == 255);
+               assert (foo.manam[254] == 4711);
+       }
+       {
+               var bar = new Bar ();
+               bar.manar = new int[255];
+               bar.manar[254] = 4711;
+               assert (bar.manar.length == 255);
+               assert (bar.manar[254] == 4711);
+       }
+}