[vala/tintou/sealed] vala: Add support for sealed classes
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/tintou/sealed] vala: Add support for sealed classes
- Date: Wed, 8 Jan 2020 09:23:48 +0000 (UTC)
commit b96215c14c7a27e5a782018a0cb4eb33577e1cff
Author: Corentin Noël <corentin elementary io>
Date: Tue Jan 7 21:41:39 2020 +0100
vala: Add support for sealed classes
tests/Makefile.am | 2 ++
tests/objects/sealed-subclass.test | 16 ++++++++++++++++
tests/objects/sealed.vala | 9 +++++++++
vala/valaclass.vala | 10 ++++++++++
vala/valacodewriter.vala | 4 ++++
vala/valagirparser.vala | 10 ++++++++++
vala/valaparser.vala | 27 +++++++++++++++++++++------
7 files changed, 72 insertions(+), 6 deletions(-)
---
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/valacodewriter.vala b/vala/valacodewriter.vala
index 2f735e87f..50c4878e6 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -246,6 +246,10 @@ 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 17b41b1e5..5f9aa5f5c 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -1184,6 +1184,10 @@ public class Vala.GirParser : CodeVisitor {
// set the interface struct name
iface.symbol.set_attribute_string ("CCode",
"type_cname", get_cname ());
}
+ var cls = iface.symbol as Class;
+ if (iface != null && cls != null && !cls.is_abstract
&& girdata["disguised"] != "1") {
+ cls.is_sealed = true;
+ }
merged = true;
}
}
@@ -2813,6 +2817,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..538d92550 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;
}
@@ -2695,8 +2698,9 @@ public class Vala.Parser : CodeVisitor {
if (ModifierFlags.ABSTRACT in flags
|| ModifierFlags.VIRTUAL in flags
- || ModifierFlags.OVERRIDE in flags) {
- Report.error (f.source_reference, "abstract, virtual, and override modifiers are not
applicable to fields");
+ || ModifierFlags.OVERRIDE in flags
+ || ModifierFlags.SEALED in flags) {
+ Report.error (f.source_reference, "abstract, virtual, override, and modifiers are not
applicable to fields");
}
if (ModifierFlags.EXTERN in flags) {
f.is_extern = true;
@@ -2772,6 +2776,9 @@ public class Vala.Parser : CodeVisitor {
if (ModifierFlags.OVERRIDE in flags) {
method.overrides = true;
}
+ if (ModifierFlags.SEALED in flags) {
+ throw new ParseError.SYNTAX ("the modifier `sealed' is not valid for
methods");
+ }
if ((method.is_abstract && method.is_virtual)
|| (method.is_abstract && method.overrides)
|| (method.is_virtual && method.overrides)) {
@@ -2780,8 +2787,9 @@ public class Vala.Parser : CodeVisitor {
} else {
if (ModifierFlags.ABSTRACT in flags
|| ModifierFlags.VIRTUAL in flags
- || ModifierFlags.OVERRIDE in flags) {
- throw new ParseError.SYNTAX ("the modifiers `abstract', `virtual', and
`override' are not valid for %s methods", (ModifierFlags.CLASS in flags) ? "class" : "static");
+ || ModifierFlags.OVERRIDE in flags
+ || ModifierFlags.SEALED in flags) {
+ throw new ParseError.SYNTAX ("the modifiers `abstract', `virtual',
`override', and `sealed' are not valid for %s methods", (ModifierFlags.CLASS in flags) ? "class" : "static");
}
}
@@ -2847,6 +2855,9 @@ public class Vala.Parser : CodeVisitor {
if (ModifierFlags.OVERRIDE in flags) {
prop.overrides = true;
}
+ if (ModifierFlags.SEALED in flags) {
+ throw new ParseError.SYNTAX ("the modifier `sealed' is not valid for properties");
+ }
if (ModifierFlags.NEW in flags) {
prop.hides = true;
}
@@ -2952,6 +2963,9 @@ public class Vala.Parser : CodeVisitor {
} else if (ModifierFlags.CLASS in flags) {
throw new ParseError.SYNTAX ("`class' modifier not allowed on signals");
}
+ if (ModifierFlags.SEALED in flags) {
+ throw new ParseError.SYNTAX ("`sealed' modifier not allowed on signals");
+ }
if (ModifierFlags.VIRTUAL in flags) {
sig.is_virtual = true;
}
@@ -3388,8 +3402,9 @@ public class Vala.Parser : CodeVisitor {
}
if (ModifierFlags.ABSTRACT in flags
|| ModifierFlags.VIRTUAL in flags
- || ModifierFlags.OVERRIDE in flags) {
- Report.error (method.source_reference, "abstract, virtual, and override modifiers are
not applicable to creation methods");
+ || ModifierFlags.OVERRIDE in flags
+ || ModifierFlags.SEALED in flags) {
+ Report.error (method.source_reference, "abstract, virtual, override, and sealed
modifiers are not applicable to creation methods");
}
if (ModifierFlags.ASYNC in flags) {
method.coroutine = true;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]