[vala/tintou/sealed] vala: Make sure that sealed classes can't be subclassed



commit b43f1a4235931991ac88747572d90172b6330df8
Author: Corentin Noël <corentin elementary io>
Date:   Tue Jan 7 21:41:39 2020 +0100

    vala: Make sure that sealed classes can't be subclassed

 tests/Makefile.am                  |  2 ++
 tests/objects/sealed-subclass.test | 16 ++++++++++++++++
 tests/objects/sealed.vala          |  9 +++++++++
 vala/valaclass.vala                | 10 ++++++++++
 vala/valagirparser.vala            |  6 ++++++
 vala/valaparser.vala               |  3 +++
 6 files changed, 46 insertions(+)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ebeeed0ef..c5301ca05 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -363,6 +363,8 @@ TESTS = \
        objects/property-simple-type-struct-nullable.vala \
        objects/property-static.vala \
        objects/regex.vala \
+       objects/sealed.vala \
+       objects/sealed-subclass.test \
        objects/signals.vala \
        objects/signals-enum-marshal.vala \
        objects/signals-delegate.vala \
diff --git a/tests/objects/sealed-subclass.test b/tests/objects/sealed-subclass.test
new file mode 100644
index 000000000..da189d5a9
--- /dev/null
+++ b/tests/objects/sealed-subclass.test
@@ -0,0 +1,16 @@
+Invalid Code
+
+sealed class Foo : GLib.Object {
+       public void do_action () {
+               stdout.printf (" 1");
+       }
+}
+
+class Bar : Foo {
+       public void do_other_action () {
+               stdout.printf (" 2");
+       }
+}
+
+void main () {
+}
diff --git a/tests/objects/sealed.vala b/tests/objects/sealed.vala
new file mode 100644
index 000000000..8112fc49f
--- /dev/null
+++ b/tests/objects/sealed.vala
@@ -0,0 +1,9 @@
+sealed class Foo : GLib.Object {
+       public void do_action () {
+               stdout.printf (" 2");
+       }
+}
+
+void main () {
+       var foo = new Foo ();
+}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index e9312c415..d0720dde1 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -37,6 +37,12 @@ public class Vala.Class : ObjectTypeSymbol {
         */
        public bool is_abstract { get; set; }
 
+       /**
+        * Specifies whether this class is sealed. Sealed classes may not be
+        * subclassed.
+        */
+       public bool is_sealed { get; set; }
+
        /**
         * Instances of compact classes are fast to create and have a
         * compact memory layout. Compact classes don't support runtime
@@ -791,6 +797,10 @@ public class Vala.Class : ObjectTypeSymbol {
                                }
                        }
 
+                       if (base_class != null && base_class.is_sealed) {
+                               Report.error (source_reference, "`%s' subclasses a `%s' which is a sealed 
class".printf (get_full_name (), base_class.get_full_name ()));
+                       }
+
                        /* all abstract symbols defined in base classes have to be implemented in 
non-abstract classes */
                        if (!is_abstract) {
                                unowned Class? base_class = base_class;
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 17b41b1e5..a657ba706 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -2813,6 +2813,12 @@ public class Vala.GirParser : CodeVisitor {
                        unresolved_gir_symbols.add (current.gtype_struct_for);
                }
 
+               var disguised = reader.get_attribute ("disguised");
+               if (disguised != null) {
+                       current.gtype_struct_for = parse_symbol_from_string (gtype_struct_for, 
current.source_reference);
+                       unresolved_gir_symbols.add (current.gtype_struct_for);
+               }
+
                bool first_field = true;
                next ();
 
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 45a420955..3719f7f7c 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -2587,6 +2587,9 @@ public class Vala.Parser : CodeVisitor {
                if (ModifierFlags.ABSTRACT in flags) {
                        cl.is_abstract = true;
                }
+               if (ModifierFlags.SEALED in flags) {
+                       cl.is_sealed = true;
+               }
                if (ModifierFlags.EXTERN in flags) {
                        cl.is_extern = true;
                }


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