]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Add support for sealed classes in bindings
authorRico Tzschichholz <ricotz@ubuntu.com>
Sun, 16 Jun 2019 17:28:24 +0000 (19:28 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 19 Feb 2020 12:29:33 +0000 (13:29 +0100)
The "sealed" keyword was available and parsed for a long time. So simply
pick it up information and expose it in the AST.

Issue an error when it is used in vala source.

See https://gitlab.gnome.org/GNOME/vala/issues/278

libvaladoc/api/class.vala
tests/Makefile.am
tests/objects/sealed-abstract-class.test [new file with mode: 0644]
tests/objects/sealed-class.test [new file with mode: 0644]
tests/objects/sealed-compact-class.test [new file with mode: 0644]
vala/valaclass.vala
vala/valacodewriter.vala
vala/valagirparser.vala
vala/valaparser.vala

index 9c003e8ab79b9e112fe10b74ca98fd1786c83ea0..02f4917d16f6ae6682f7ce8f2ea6c61bcd9b991b 100644 (file)
@@ -78,6 +78,7 @@ public class Valadoc.Api.Class : TypeSymbol {
 
                this.is_fundamental = data.is_fundamental ();
                this.is_abstract = data.is_abstract;
+               this.is_sealed = data.is_sealed;
        }
 
        string? _get_private_cname (Vala.Class element) {
@@ -257,6 +258,15 @@ public class Valadoc.Api.Class : TypeSymbol {
                get;
        }
 
+       /**
+        * Specifies whether this class is sealed. Sealed classes may not be
+        * sub-classed.
+        */
+       public bool is_sealed {
+               private set;
+               get;
+       }
+
        /**
         * Specifies whether this class is fundamental.
         */
@@ -322,6 +332,9 @@ public class Valadoc.Api.Class : TypeSymbol {
                if (is_abstract) {
                        signature.append_keyword ("abstract");
                }
+               if (is_sealed) {
+                       signature.append_keyword ("sealed");
+               }
                signature.append_keyword ("class");
                signature.append_symbol (this);
 
index e73bc0ac360c0c1cd93c23a42972610a3ca6a5df..c10c72b41f0ea916383790c32e7f81e52189f3ca 100644 (file)
@@ -385,6 +385,9 @@ TESTS = \
        objects/property-simple-type-struct-nullable.vala \
        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 \
diff --git a/tests/objects/sealed-abstract-class.test b/tests/objects/sealed-abstract-class.test
new file mode 100644 (file)
index 0000000..337820a
--- /dev/null
@@ -0,0 +1,7 @@
+Invalid Code
+
+sealed abstract class Foo {
+}
+
+void main () {
+}
diff --git a/tests/objects/sealed-class.test b/tests/objects/sealed-class.test
new file mode 100644 (file)
index 0000000..b5ec1f0
--- /dev/null
@@ -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 (file)
index 0000000..006c7fc
--- /dev/null
@@ -0,0 +1,8 @@
+Invalid Code
+
+[Compact]
+sealed class Foo {
+}
+
+void main () {
+}
index e9312c4158bae50b85d8d3030b5ff6b0272f9c75..c4f196c64a67bc0b30db99632c323266f8fa8d52 100644 (file)
@@ -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
@@ -582,6 +588,29 @@ 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;
+                       }
+                       if (!external_package) {
+                               error = true;
+                               Report.error (source_reference, "Sealed classes are not fully supported yet");
+                               return false;
+                       }
+               }
+
                /* process enums first to avoid order problems in C code */
                foreach (Enum en in get_enums ()) {
                        en.check (context);
index 2f735e87fd41eedcf1803a31e0bcae281ea45708..198ee51c273b3d38af888b3611fe183294543682 100644 (file)
@@ -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);
 
index 30468323a4552b37877f16c86c2fd14406eea0f6..6d6f767d870450eeac7f0b90f0559e38584c6101 100644 (file)
@@ -62,6 +62,7 @@ public class Vala.GirParser : CodeVisitor {
                VFUNC_NAME,
                VIRTUAL,
                ABSTRACT,
+               SEALED,
                SCOPE,
                STRUCT,
                THROWS,
@@ -2884,6 +2885,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));
index 2b480ce599a4d9363e3abe4c6a93ce16d70a889c..62ad72898caff0e4500ce68b1e755892af8425e3 100644 (file)
@@ -2636,6 +2636,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;
                }