validation: Disallow instantiating abstract classes

This commit is contained in:
James Westman 2022-04-28 23:07:32 -05:00
parent f78478bea1
commit 99e428d93c
17 changed files with 35 additions and 13 deletions

View file

@ -236,6 +236,10 @@ class Class(GirNode, GirType):
self.own_properties = {child["name"]: Property(self, child) for child in xml.get_elements("property")} self.own_properties = {child["name"]: Property(self, child) for child in xml.get_elements("property")}
self.own_signals = {child["name"]: Signal(self, child) for child in xml.get_elements("glib:signal")} self.own_signals = {child["name"]: Signal(self, child) for child in xml.get_elements("glib:signal")}
@property
def abstract(self):
return self.xml["abstract"] == "1"
@property @property
def signature(self): def signature(self):
result = f"class {self.container.name}.{self.name}" result = f"class {self.container.name}.{self.name}"

View file

@ -61,6 +61,14 @@ class Object(AstNode):
if self.tokens["class_name"] and not self.tokens["ignore_gir"] and self.gir_ns is not None: if self.tokens["class_name"] and not self.tokens["ignore_gir"] and self.gir_ns is not None:
self.root.gir.validate_class(self.tokens["class_name"], self.tokens["namespace"]) self.root.gir.validate_class(self.tokens["class_name"], self.tokens["namespace"])
@validate("namespace", "class_name")
def not_abstract(self):
if self.gir_class is not None and self.gir_class.abstract:
raise CompileError(
f"{self.gir_class.full_name} can't be instantiated because it's abstract",
hints=[f"did you mean to use a subclass of {self.gir_class.full_name}?"]
)
@property @property
def gir_ns(self): def gir_ns(self):
if not self.tokens["ignore_gir"]: if not self.tokens["ignore_gir"]:

View file

@ -33,7 +33,7 @@ class Menu(Object):
@property @property
def gir_class(self): def gir_class(self):
return self.root.gir.namespaces["Gtk"].lookup_type("Gio.MenuModel") return self.root.gir.namespaces["Gtk"].lookup_type("Gio.Menu")
class MenuAttribute(BaseAttribute): class MenuAttribute(BaseAttribute):

View file

@ -33,6 +33,10 @@ class Template(Object):
ObjectContent, ObjectContent,
] ]
@validate()
def not_abstract(self):
pass # does not apply to templates
def emit_xml(self, xml: XmlEmitter): def emit_xml(self, xml: XmlEmitter):
if self.gir_class: if self.gir_class:
parent = self.gir_class.glib_type_name parent = self.gir_class.glib_type_name

View file

@ -1,6 +1,6 @@
using Gtk 4.0; using Gtk 4.0;
Widget { Button {
accessibility { accessibility {
not_a_prop: "Hello, world!"; not_a_prop: "Hello, world!";
} }

View file

@ -1,6 +1,6 @@
using Gtk 4.0; using Gtk 4.0;
Widget { Button {
accessibility { accessibility {
labelled-by: not_an_object; labelled-by: not_an_object;
} }

View file

@ -1,6 +1,6 @@
using Gtk 4.0; using Gtk 4.0;
Widget { Button {
accessibility { accessibility {
orientation: 1; orientation: 1;
} }

View file

@ -0,0 +1,4 @@
using Gtk 4.0;
template MyWidget : Gtk.Widget {}
Gtk.Widget {}

View file

@ -0,0 +1 @@
4,1,10,Gtk.Widget can't be instantiated because it's abstract

View file

@ -1 +1 @@
4,3,15,Cannot assign Gio.MenuModel to string 4,3,15,Cannot assign Gio.Menu to string

View file

@ -1,6 +1,6 @@
using Gtk 4.0; using Gtk 4.0;
Widget { Button {
mime-types [] mime-types []
patterns [] patterns []
suffixes [] suffixes []

View file

@ -1,3 +1,3 @@
4,3,13,Gtk.Widget is not a Gtk.FileFilter, so it doesn't have file filter properties 4,3,13,Gtk.Button is not a Gtk.FileFilter, so it doesn't have file filter properties
5,3,11,Gtk.Widget is not a Gtk.FileFilter, so it doesn't have file filter properties 5,3,11,Gtk.Button is not a Gtk.FileFilter, so it doesn't have file filter properties
6,3,11,Gtk.Widget is not a Gtk.FileFilter, so it doesn't have file filter properties 6,3,11,Gtk.Button is not a Gtk.FileFilter, so it doesn't have file filter properties

View file

@ -6,4 +6,4 @@ StringList {
] ]
} }
Widget id {} Button id {}

View file

@ -1 +1 @@
5,5,2,Cannot assign Gtk.Widget to string 5,5,2,Cannot assign Gtk.Button to string

View file

@ -1,5 +1,5 @@
using Gtk 4.0; using Gtk 4.0;
Widget { Button {
widgets [] widgets []
} }

View file

@ -1 +1 @@
4,3,7,Gtk.Widget is not a Gtk.SizeGroup, so it doesn't have size group properties 4,3,7,Gtk.Button is not a Gtk.SizeGroup, so it doesn't have size group properties

View file

@ -164,6 +164,7 @@ class TestSamples(unittest.TestCase):
self.assert_sample_error("a11y_prop_dne") self.assert_sample_error("a11y_prop_dne")
self.assert_sample_error("a11y_prop_obj_dne") self.assert_sample_error("a11y_prop_obj_dne")
self.assert_sample_error("a11y_prop_type") self.assert_sample_error("a11y_prop_type")
self.assert_sample_error("abstract_class")
self.assert_sample_error("assign_inline_menu") self.assert_sample_error("assign_inline_menu")
self.assert_sample_error("action_widget_float_response") self.assert_sample_error("action_widget_float_response")
self.assert_sample_error("action_widget_have_no_id") self.assert_sample_error("action_widget_have_no_id")