[vala/staging] Add support for sealed classes in bindings
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] Add support for sealed classes in bindings
- Date: Wed, 19 Feb 2020 12:30:43 +0000 (UTC)
commit c16b665cb90c66c5ed8362fa70989bde1eaee272
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Sun Jun 16 19:28:24 2019 +0200
Add support for sealed classes in bindings
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 | 13 +++++++++++++
tests/Makefile.am | 3 +++
tests/objects/sealed-abstract-class.test | 7 +++++++
tests/objects/sealed-class.test | 10 ++++++++++
tests/objects/sealed-compact-class.test | 8 ++++++++
vala/valaclass.vala | 29 +++++++++++++++++++++++++++++
vala/valacodewriter.vala | 3 +++
vala/valagirparser.vala | 2 ++
vala/valaparser.vala | 3 +++
9 files changed, 78 insertions(+)
---
diff --git a/libvaladoc/api/class.vala b/libvaladoc/api/class.vala
index 9c003e8ab..02f4917d1 100644
--- a/libvaladoc/api/class.vala
+++ b/libvaladoc/api/class.vala
@@ -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);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e73bc0ac3..c10c72b41 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 000000000..337820a04
--- /dev/null
+++ b/tests/objects/sealed-abstract-class.test
@@ -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
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..006c7fc02
--- /dev/null
+++ b/tests/objects/sealed-compact-class.test
@@ -0,0 +1,8 @@
+Invalid Code
+
+[Compact]
+sealed class Foo {
+}
+
+void main () {
+}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index e9312c415..c4f196c64 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
@@ -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);
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index 2f735e87f..198ee51c2 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 30468323a..6d6f767d8 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,
@@ -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));
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 2b480ce59..62ad72898 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -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;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]