[vala/wip/issue/278: 1/2] Add supported for sealed classes



commit 5dc573f5a163e2bd1757a8b82031e1e5aa49dcc3
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sun Jun 16 19:28:24 2019 +0200

    Add supported for sealed classes
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/278

 tests/Makefile.am                        |  4 ++++
 tests/objects/sealed-abstract-class.test |  8 ++++++++
 tests/objects/sealed-class.test          | 10 ++++++++++
 tests/objects/sealed-compact-class.test  |  7 +++++++
 tests/parser/sealed-class.vala           |  8 ++++++++
 vala/valaclass.vala                      | 24 ++++++++++++++++++++++++
 vala/valacodewriter.vala                 |  3 +++
 vala/valagirparser.vala                  |  2 ++
 vala/valaparser.vala                     |  3 +++
 9 files changed, 69 insertions(+)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b67d91c5b..0c0963bed 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -321,6 +321,9 @@ TESTS = \
        objects/property-real-struct-no-accessor.test \
        objects/property-static.vala \
        objects/regex.vala \
+       objects/sealed-abstract-class.test \
+       objects/sealed-class.test \
+       objects/sealed-compact-class.test \
        objects/signals.vala \
        objects/signals-enum-marshal.vala \
        objects/signals-delegate.vala \
@@ -572,6 +575,7 @@ TESTS = \
        parser/property-no-virtual-override.test \
        parser/property-set-must-have-body.test \
        parser/property-set-redefined.test \
+       parser/sealed-class.vala \
        parser/signal-no-class.test \
        parser/signal-no-static.test \
        parser/statement-outside-root.test \
diff --git a/tests/objects/sealed-abstract-class.test b/tests/objects/sealed-abstract-class.test
new file mode 100644
index 000000000..006c7fc02
--- /dev/null
+++ b/tests/objects/sealed-abstract-class.test
@@ -0,0 +1,8 @@
+Invalid Code
+
+[Compact]
+sealed class Foo {
+}
+
+void main () {
+}
diff --git a/tests/objects/sealed-class.test b/tests/objects/sealed-class.test
new file mode 100644
index 000000000..b5ec1f052
--- /dev/null
+++ b/tests/objects/sealed-class.test
@@ -0,0 +1,10 @@
+Invalid Code
+
+sealed class Foo {
+}
+
+class Bar : Foo {
+}
+
+void main () {
+}
diff --git a/tests/objects/sealed-compact-class.test b/tests/objects/sealed-compact-class.test
new file mode 100644
index 000000000..337820a04
--- /dev/null
+++ b/tests/objects/sealed-compact-class.test
@@ -0,0 +1,7 @@
+Invalid Code
+
+sealed abstract class Foo {
+}
+
+void main () {
+}
diff --git a/tests/parser/sealed-class.vala b/tests/parser/sealed-class.vala
new file mode 100644
index 000000000..b6f420703
--- /dev/null
+++ b/tests/parser/sealed-class.vala
@@ -0,0 +1,8 @@
+sealed class Foo {
+}
+
+sealed class Bar : Object {
+}
+
+void main () {
+}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 933a67c26..b9dcd339c 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
+        * sub-classed.
+        */
+       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
@@ -597,6 +603,24 @@ public class Vala.Class : ObjectTypeSymbol {
                        add_constructor (c);
                }
 
+               if (base_class != null && base_class.is_sealed) {
+                       error = true;
+                       Report.error (source_reference, "`%s' cannot inherit from sealed class `%s'".printf 
(get_full_name (), base_class.get_full_name ()));
+               }
+
+               if (is_sealed) {
+                       if (is_compact) {
+                               error = true;
+                               Report.error (source_reference, "Sealed class `%s' cannot be compact".printf 
(get_full_name ()));
+                               return false;
+                       }
+                       if (is_abstract) {
+                               error = true;
+                               Report.error (source_reference, "Sealed class `%s' cannot be abstract".printf 
(get_full_name ()));
+                               return false;
+                       }
+               }
+
                /* process enums first to avoid order problems in C code */
                foreach (Enum en in get_enums ()) {
                        en.check (context);
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index 1f223b6b8..3ced2c11b 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -246,6 +246,9 @@ public class Vala.CodeWriter : CodeVisitor {
                if (cl.is_abstract) {
                        write_string ("abstract ");
                }
+               if (cl.is_sealed) {
+                       write_string ("sealed ");
+               }
                write_string ("class ");
                write_identifier (cl.name);
 
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index fe4a060a8..d61c58342 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -62,6 +62,7 @@ public class Vala.GirParser : CodeVisitor {
                VFUNC_NAME,
                VIRTUAL,
                ABSTRACT,
+               SEALED,
                SCOPE,
                STRUCT,
                THROWS,
@@ -2846,6 +2847,7 @@ public class Vala.GirParser : CodeVisitor {
                if (current.new_symbol) {
                        cl = new Class (current.name, current.source_reference);
                        cl.is_abstract = metadata.get_bool (ArgumentType.ABSTRACT, reader.get_attribute 
("abstract") == "1");
+                       cl.is_sealed = metadata.get_bool (ArgumentType.SEALED, false);
 
                        if (parent != null) {
                                cl.add_base_type (parse_type_from_gir_name (parent));
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 10c42d6d6..fb2c68cc2 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -2576,6 +2576,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 || scanner.source_file.file_type == SourceFileType.PACKAGE) 
{
                        cl.external = true;
                }


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