Improved validation

This commit is contained in:
James Westman 2021-11-12 18:01:56 -06:00
parent 981c2e3b7d
commit f1e1811e1f
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6
13 changed files with 51 additions and 13 deletions

View file

@ -72,6 +72,12 @@ class AstNode:
else: else:
return self.parent.parent_by_type(type) return self.parent.parent_by_type(type)
def validate_parent_type(self, ns: str, name: str, err_msg: str):
parent = self.root.gir.get_type(name, ns)
container_type = self.parent_by_type(ast.Object).gir_class
if container_type and not container_type.assignable_to(parent):
raise CompileError(f"{container_type.full_name} is not a {parent.full_name}, so it doesn't have {err_msg}")
@lazy_prop @lazy_prop
def errors(self): def errors(self):
return list(self._get_errors()) return list(self._get_errors())

View file

@ -108,10 +108,7 @@ def _get_docs(gir, name):
class A11y(AstNode): class A11y(AstNode):
@validate("accessibility") @validate("accessibility")
def container_is_widget(self): def container_is_widget(self):
widget = self.root.gir.get_type("Widget", "Gtk") self.validate_parent_type("Gtk", "Widget", "accessibility properties")
container_type = self.parent_by_type(ast.Object).gir_class
if container_type and not container_type.assignable_to(widget):
raise CompileError(f"{container_type.full_name} is not a {widget.full_name}, so it doesn't have accessibility properties")
def emit_xml(self, xml: XmlEmitter): def emit_xml(self, xml: XmlEmitter):

View file

@ -19,7 +19,7 @@
from .. import ast from .. import ast
from ..ast_utils import AstNode from ..ast_utils import AstNode, validate
from ..completions_utils import * from ..completions_utils import *
from ..lsp_utils import Completion, CompletionItemKind from ..lsp_utils import Completion, CompletionItemKind
from ..parse_tree import * from ..parse_tree import *
@ -28,6 +28,10 @@ from ..xml_emitter import XmlEmitter
class Filters(AstNode): class Filters(AstNode):
@validate()
def container_is_file_filter(self):
self.validate_parent_type("Gtk", "FileFilter", "file filter properties")
def emit_xml(self, xml: XmlEmitter): def emit_xml(self, xml: XmlEmitter):
xml.start_tag(self.tokens["tag_name"]) xml.start_tag(self.tokens["tag_name"])
for child in self.children: for child in self.children:
@ -46,7 +50,7 @@ def create_node(tag_name: str, singular: str):
return Group( return Group(
Filters, Filters,
Statement( Statement(
Keyword(tag_name), Keyword(tag_name, True),
UseLiteral("tag_name", tag_name), UseLiteral("tag_name", tag_name),
OpenBracket(), OpenBracket(),
Delimited( Delimited(

View file

@ -30,10 +30,7 @@ from ..xml_emitter import XmlEmitter
class Layout(AstNode): class Layout(AstNode):
@validate("layout") @validate("layout")
def container_is_widget(self): def container_is_widget(self):
widget = self.root.gir.get_type("Widget", "Gtk") self.validate_parent_type("Gtk", "Widget", "layout properties")
container_type = self.parent_by_type(ast.Object).gir_class
if container_type and not container_type.assignable_to(widget):
raise CompileError(f"{container_type.full_name} is not a {widget.full_name}, so it doesn't have layout properties")
def emit_xml(self, xml: XmlEmitter): def emit_xml(self, xml: XmlEmitter):

View file

@ -28,6 +28,10 @@ from ..xml_emitter import XmlEmitter
class Widgets(AstNode): class Widgets(AstNode):
@validate("widgets")
def container_is_size_group(self):
self.validate_parent_type("Gtk", "SizeGroup", "size group properties")
def emit_xml(self, xml: XmlEmitter): def emit_xml(self, xml: XmlEmitter):
xml.start_tag("widgets") xml.start_tag("widgets")
for child in self.children: for child in self.children:
@ -57,7 +61,7 @@ class Widget(AstNode):
widgets = Group( widgets = Group(
Widgets, Widgets,
Statement( Statement(
Keyword("widgets"), Keyword("widgets", True),
OpenBracket(), OpenBracket(),
Delimited( Delimited(
Group( Group(

View file

@ -19,7 +19,7 @@
from .. import ast from .. import ast
from ..ast_utils import AstNode from ..ast_utils import AstNode, validate
from ..completions_utils import * from ..completions_utils import *
from ..lsp_utils import Completion, CompletionItemKind from ..lsp_utils import Completion, CompletionItemKind
from ..parse_tree import * from ..parse_tree import *
@ -28,6 +28,10 @@ from ..xml_emitter import XmlEmitter
class Styles(AstNode): class Styles(AstNode):
@validate("styles")
def container_is_widget(self):
self.validate_parent_type("Gtk", "Widget", "style classes")
def emit_xml(self, xml: XmlEmitter): def emit_xml(self, xml: XmlEmitter):
xml.start_tag("style") xml.start_tag("style")
for child in self.children: for child in self.children:
@ -43,7 +47,7 @@ class StyleClass(AstNode):
styles = Group( styles = Group(
Styles, Styles,
Statement( Statement(
Keyword("styles"), Keyword("styles", True),
OpenBracket(), OpenBracket(),
Delimited( Delimited(
Group( Group(

View file

@ -0,0 +1,7 @@
using Gtk 4.0;
Widget {
mime-types [];
patterns [];
suffixes [];
}

View file

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

View file

@ -0,0 +1,6 @@
using Gtk 4.0;
using GObject 2.0;
GObject.Object {
styles [];
}

View file

@ -0,0 +1 @@
5,3,6,GObject.Object is not a Gtk.Widget, so it doesn't have style classes

View file

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

View file

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

View file

@ -120,6 +120,7 @@ class TestSamples(unittest.TestCase):
self.assert_sample_error("class_dne") self.assert_sample_error("class_dne")
self.assert_sample_error("duplicate_obj_id") self.assert_sample_error("duplicate_obj_id")
self.assert_sample_error("enum_member_dne") self.assert_sample_error("enum_member_dne")
self.assert_sample_error("filters_in_non_file_filter")
self.assert_sample_error("invalid_bool") self.assert_sample_error("invalid_bool")
self.assert_sample_error("layout_in_non_widget") self.assert_sample_error("layout_in_non_widget")
self.assert_sample_error("ns_not_imported") self.assert_sample_error("ns_not_imported")
@ -130,5 +131,7 @@ class TestSamples(unittest.TestCase):
self.assert_sample_error("signal_dne") self.assert_sample_error("signal_dne")
self.assert_sample_error("size_group_non_widget") self.assert_sample_error("size_group_non_widget")
self.assert_sample_error("size_group_obj_dne") self.assert_sample_error("size_group_obj_dne")
self.assert_sample_error("styles_in_non_widget")
self.assert_sample_error("two_templates") self.assert_sample_error("two_templates")
self.assert_sample_error("using_invalid_namespace") self.assert_sample_error("using_invalid_namespace")
self.assert_sample_error("widgets_in_non_size_group")