[vala/staging] vala: Improve context check whether property is writeable on assignments




commit e2087ad110493278d80a12274f7240b951cefcb8
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Fri Feb 26 15:55:09 2021 +0100

    vala: Improve context check whether property is writeable on assignments

 tests/Makefile.am                                  |  4 ++
 .../objects_property_construct_only.vala           | 46 ++++++++++++++++++++++
 .../property-construct-only-write-after.test       | 10 +++++
 tests/objects/property-construct-only.vala         | 46 ++++++++++++++++++++++
 tests/objects/property-read-only-member-write.test | 15 +++++++
 tests/objects/property-write-only-member-read.test | 10 +++++
 vala/valaassignment.vala                           | 20 ----------
 vala/valamemberaccess.vala                         | 16 ++++++++
 8 files changed, 147 insertions(+), 20 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5ca793613..449171ca2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -469,8 +469,11 @@ TESTS = \
        objects/property-notify-owned-getter.vala \
        objects/property-ownership.vala \
        objects/property-read-only-auto.vala \
+       objects/property-read-only-member-write.test \
        objects/property-read-only-write.test \
+       objects/property-construct-only.vala \
        objects/property-construct-only-write.test \
+       objects/property-construct-only-write-after.test \
        objects/property-construct-only-write-foreign.test \
        objects/property-delegate.vala \
        objects/property-delegate-owned.vala \
@@ -480,6 +483,7 @@ TESTS = \
        objects/property-simple-type-struct-nullable.vala \
        objects/property-static.vala \
        objects/property-struct-no-gtype.vala \
+       objects/property-write-only-member-read.test \
        objects/regex.vala \
        objects/sealed-abstract-class.test \
        objects/sealed-class.test \
diff --git a/tests/_test.828475/objects_property_construct_only.vala 
b/tests/_test.828475/objects_property_construct_only.vala
new file mode 100644
index 000000000..0dd541f16
--- /dev/null
+++ b/tests/_test.828475/objects_property_construct_only.vala
@@ -0,0 +1,46 @@
+class Foo : GLib.Object {
+       public string manam { get; construct; }
+
+       construct {
+               manam = "foo";
+       }
+}
+
+class Bar : Foo {
+       construct {
+               manam = "bar";
+       }
+}
+
+class Faz : GLib.Object {
+       public string manam { get; construct; }
+
+       public Faz () {
+               Object (manam : "faz");
+       }
+}
+
+class Baz : Faz {
+       public Bar () {
+               Object (manam : "baz");
+       }
+}
+
+void main () {
+       {
+               var foo = new Foo ();
+               assert (foo.manam == "foo");
+       }
+       {
+               var bar = new Bar ();
+               assert (bar.manam == "bar");
+       }
+       {
+               var faz = new Faz ();
+               assert (faz.manam == "faz");
+       }
+       {
+               var baz = new Baz ();
+               assert (baz.manam == "baz");
+       }
+}
diff --git a/tests/objects/property-construct-only-write-after.test 
b/tests/objects/property-construct-only-write-after.test
new file mode 100644
index 000000000..446145f08
--- /dev/null
+++ b/tests/objects/property-construct-only-write-after.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+class Foo : GLib.Object {
+       public string manam { get; construct; }
+}
+
+void main () {
+       var foo = new Foo ();
+       foo.manam = "manam";
+}
diff --git a/tests/objects/property-construct-only.vala b/tests/objects/property-construct-only.vala
new file mode 100644
index 000000000..700980315
--- /dev/null
+++ b/tests/objects/property-construct-only.vala
@@ -0,0 +1,46 @@
+class Foo : GLib.Object {
+       public string manam { get; construct; }
+
+       construct {
+               manam = "foo";
+       }
+}
+
+class Bar : Foo {
+       construct {
+               manam = "bar";
+       }
+}
+
+class Faz : GLib.Object {
+       public string manam { get; construct; }
+
+       public Faz () {
+               Object (manam : "faz");
+       }
+}
+
+class Baz : Faz {
+       public Baz () {
+               Object (manam : "baz");
+       }
+}
+
+void main () {
+       {
+               var foo = new Foo ();
+               assert (foo.manam == "foo");
+       }
+       {
+               var bar = new Bar ();
+               assert (bar.manam == "bar");
+       }
+       {
+               var faz = new Faz ();
+               assert (faz.manam == "faz");
+       }
+       {
+               var baz = new Baz ();
+               assert (baz.manam == "baz");
+       }
+}
diff --git a/tests/objects/property-read-only-member-write.test 
b/tests/objects/property-read-only-member-write.test
new file mode 100644
index 000000000..6696454e1
--- /dev/null
+++ b/tests/objects/property-read-only-member-write.test
@@ -0,0 +1,15 @@
+Invalid Code
+
+class Foo : GLib.Object {
+       public string manam { get; construct; }
+}
+
+class Bar : GLib.Object {
+       construct {
+               var foo = new Foo ();
+               foo.manam = "manam";
+       }
+}
+
+void main () {
+}
diff --git a/tests/objects/property-write-only-member-read.test 
b/tests/objects/property-write-only-member-read.test
new file mode 100644
index 000000000..213387c35
--- /dev/null
+++ b/tests/objects/property-write-only-member-read.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+class Foo : GLib.Object {
+       public string manam { set; }
+}
+
+void main () {
+       var foo = new Foo ();
+       var s = foo.manam;
+}
diff --git a/vala/valaassignment.vala b/vala/valaassignment.vala
index 4ffc75735..8902aedf3 100644
--- a/vala/valaassignment.vala
+++ b/vala/valaassignment.vala
@@ -276,26 +276,6 @@ public class Vala.Assignment : Expression {
                                        dynamic_prop.property_type = right.value_type.copy ();
                                        left.value_type = dynamic_prop.property_type.copy ();
                                }
-
-                               if (prop.set_accessor == null
-                                   || (!prop.set_accessor.writable && !(context.analyzer.find_current_method 
() is CreationMethod || context.analyzer.is_in_constructor ()))) {
-                                       ma.error = true;
-                                       Report.error (ma.source_reference, "Property `%s' is read-only", 
prop.get_full_name ());
-                                       return false;
-                               } else if (!context.deprecated
-                                          && !prop.set_accessor.writable
-                                          && context.analyzer.find_current_method () is CreationMethod) {
-                                       if (ma.inner.symbol_reference != context.analyzer.find_current_method 
().this_parameter) {
-                                               // trying to set construct-only property in creation method 
for foreign instance
-                                               error = true;
-                                               Report.error (ma.source_reference, "Property `%s' is 
read-only", prop.get_full_name ());
-                                               return false;
-                                       } else {
-                                               error = true;
-                                               Report.error (ma.source_reference, "Cannot assign to 
construct-only properties, use Object (property: value) constructor chain up");
-                                               return false;
-                                       }
-                               }
                        } else if (ma.symbol_reference is ArrayLengthField && ((ArrayType) 
ma.inner.value_type).inline_allocated) {
                                error = true;
                                Report.error (source_reference, "`length' field of fixed length arrays is 
read-only");
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index d56f7ba93..16484a6fd 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -798,6 +798,22 @@ public class Vala.MemberAccess : Expression {
                                        error = true;
                                        Report.error (source_reference, "Property `%s' is read-only", 
prop.get_full_name ());
                                        return false;
+                               } else if (!prop.set_accessor.writable && prop.set_accessor.construction) {
+                                       if (context.analyzer.find_current_method () is CreationMethod) {
+                                               error = true;
+                                               Report.error (source_reference, "Cannot assign to 
construct-only properties, use Object (property: value) constructor chain up");
+                                               return false;
+                                       } else if (context.analyzer.is_in_constructor ()) {
+                                               if (!context.analyzer.current_type_symbol.is_subtype_of 
((TypeSymbol) prop.parent_symbol)) {
+                                                       error = true;
+                                                       Report.error (source_reference, "Cannot assign to 
construct-only property `%s' in `construct' of `%s'", prop.get_full_name (), 
context.analyzer.current_type_symbol.get_full_name ());
+                                                       return false;
+                                               }
+                                       } else {
+                                               error = true;
+                                               Report.error (source_reference, "Cannot assign to 
construct-only property in this context");
+                                               return false;
+                                       }
                                }
                                if (prop.access == SymbolAccessibility.PUBLIC) {
                                        access = prop.set_accessor.access;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]