diff --git a/blueprintcompiler/language/__init__.py b/blueprintcompiler/language/__init__.py index 68c3d8a..7673419 100644 --- a/blueprintcompiler/language/__init__.py +++ b/blueprintcompiler/language/__init__.py @@ -21,11 +21,6 @@ from .values import IdentValue, TranslatedStringValue, FlagsValue, LiteralValue from .common import * -OBJECT_HOOKS.children = [ - menu, - Object, -] - OBJECT_CONTENT_HOOKS.children = [ Signal, Property, diff --git a/blueprintcompiler/language/common.py b/blueprintcompiler/language/common.py index 12dbc52..ca5bc9e 100644 --- a/blueprintcompiler/language/common.py +++ b/blueprintcompiler/language/common.py @@ -31,6 +31,5 @@ from ..parser_utils import * from ..xml_emitter import XmlEmitter -OBJECT_HOOKS = AnyOf() OBJECT_CONTENT_HOOKS = AnyOf() VALUE_HOOKS = AnyOf() diff --git a/blueprintcompiler/language/gobject_property.py b/blueprintcompiler/language/gobject_property.py index 99e51fd..b13dd06 100644 --- a/blueprintcompiler/language/gobject_property.py +++ b/blueprintcompiler/language/gobject_property.py @@ -44,7 +44,7 @@ class Property(AstNode): UseIdent("name"), ":", AnyOf( - OBJECT_HOOKS, + Object, VALUE_HOOKS, ).expected("a value"), ), diff --git a/blueprintcompiler/language/gtk_menu.py b/blueprintcompiler/language/gtk_menu.py index 2932e9a..8826036 100644 --- a/blueprintcompiler/language/gtk_menu.py +++ b/blueprintcompiler/language/gtk_menu.py @@ -20,7 +20,6 @@ from .attributes import BaseAttribute from .gobject_object import Object, ObjectContent -from .ui import UI from .common import * @@ -31,6 +30,11 @@ class Menu(Object): child.emit_xml(xml) xml.end_tag() + @validate("menu") + def has_id(self): + if self.tokens["tag"] == "menu" and self.tokens["id"] is None: + raise CompileError("Menu requires an ID") + @property def gir_class(self): return self.root.gir.namespaces["Gtk"].lookup_type("Gio.MenuModel") @@ -39,6 +43,11 @@ class Menu(Object): class MenuAttribute(BaseAttribute): tag_name = "attribute" + @validate() + def not_in_menu(self): + if self.parent.tokens["tag"] == "menu": + raise CompileError("Menu root may not have attributes") + @property def value_type(self): return None @@ -128,16 +137,17 @@ menu_contents.children = [ ), "}"), ] -menu = Group( +menu: Group = Group( Menu, [ - "menu", + Keyword("menu"), UseLiteral("tag", "menu"), Optional(UseIdent("id")), menu_contents ], ) +from .ui import UI @completer( applies_in=[UI], diff --git a/blueprintcompiler/language/ui.py b/blueprintcompiler/language/ui.py index e7020c9..3ced164 100644 --- a/blueprintcompiler/language/ui.py +++ b/blueprintcompiler/language/ui.py @@ -20,6 +20,8 @@ from .. import gir from .imports import GtkDirective, Import +from .gtk_menu import menu +from .gobject_object import Object from .gtkbuilder_template import Template from .common import * @@ -32,7 +34,8 @@ class UI(AstNode): ZeroOrMore(Import), Until(AnyOf( Template, - OBJECT_HOOKS, + menu, + Object, ), Eof()), ] diff --git a/blueprintcompiler/parser.py b/blueprintcompiler/parser.py index 6064481..dc80bc2 100644 --- a/blueprintcompiler/parser.py +++ b/blueprintcompiler/parser.py @@ -22,7 +22,7 @@ from .errors import MultipleErrors, PrintableError from .parse_tree import * from .parser_utils import * from .tokenizer import TokenType -from .language import OBJECT_HOOKS, OBJECT_CONTENT_HOOKS, VALUE_HOOKS, Template, UI +from .language import OBJECT_CONTENT_HOOKS, VALUE_HOOKS, Template, UI def parse(tokens) -> T.Tuple[UI, T.Optional[MultipleErrors], T.List[PrintableError]]: diff --git a/tests/sample_errors/assign_inline_menu.blp b/tests/sample_errors/assign_inline_menu.blp deleted file mode 100644 index 9e5a944..0000000 --- a/tests/sample_errors/assign_inline_menu.blp +++ /dev/null @@ -1,5 +0,0 @@ -using Gtk 4.0; - -Button { - label: menu {}; -} diff --git a/tests/sample_errors/assign_inline_menu.err b/tests/sample_errors/assign_inline_menu.err deleted file mode 100644 index aec5ce9..0000000 --- a/tests/sample_errors/assign_inline_menu.err +++ /dev/null @@ -1 +0,0 @@ -4,3,15,Cannot assign Gio.MenuModel to string diff --git a/tests/sample_errors/assign_menu.blp b/tests/sample_errors/assign_menu.blp new file mode 100644 index 0000000..682ae9c --- /dev/null +++ b/tests/sample_errors/assign_menu.blp @@ -0,0 +1,7 @@ +using Gtk 4.0; + +Button { + label: my_menu; +} + +menu my_menu {} diff --git a/tests/sample_errors/assign_menu.err b/tests/sample_errors/assign_menu.err new file mode 100644 index 0000000..366297c --- /dev/null +++ b/tests/sample_errors/assign_menu.err @@ -0,0 +1 @@ +4,10,7,Cannot assign Gio.MenuModel to string diff --git a/tests/sample_errors/menu_errors.blp b/tests/sample_errors/menu_errors.blp new file mode 100644 index 0000000..05c9c88 --- /dev/null +++ b/tests/sample_errors/menu_errors.blp @@ -0,0 +1,5 @@ +using Gtk 4.0; + +menu { + label: "hi"; +} diff --git a/tests/sample_errors/menu_errors.err b/tests/sample_errors/menu_errors.err new file mode 100644 index 0000000..046dc08 --- /dev/null +++ b/tests/sample_errors/menu_errors.err @@ -0,0 +1,2 @@ +3,1,4,Menu requires an ID +4,3,12,Menu root may not have attributes diff --git a/tests/samples/inline_menu.blp b/tests/samples/inline_menu.blp deleted file mode 100644 index f4ee067..0000000 --- a/tests/samples/inline_menu.blp +++ /dev/null @@ -1,5 +0,0 @@ -using Gtk 4.0; - -MenuButton { - menu-model: menu primary_menu {}; -} diff --git a/tests/samples/inline_menu.ui b/tests/samples/inline_menu.ui deleted file mode 100644 index a6f2bcc..0000000 --- a/tests/samples/inline_menu.ui +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/tests/samples/menu.blp b/tests/samples/menu.blp index f15dbdb..3246d59 100644 --- a/tests/samples/menu.blp +++ b/tests/samples/menu.blp @@ -1,13 +1,12 @@ using Gtk 4.0; -menu { - label: _("menu label"); - test-custom-attribute: 3.1415; +menu my_menu { + section { + label: "test section"; + } submenu { - section { - label: "test section"; - } + label: "test submenu"; item { label: "test item"; diff --git a/tests/samples/menu.ui b/tests/samples/menu.ui index a84fa57..443c048 100644 --- a/tests/samples/menu.ui +++ b/tests/samples/menu.ui @@ -1,13 +1,12 @@ - - menu label - 3.1415 + +
+ test section +
-
- test section -
+ test submenu test item @@ -25,4 +24,4 @@
- \ No newline at end of file + diff --git a/tests/samples/menu_dec.blp b/tests/samples/menu_dec.blp index bc4ddf1..6e1e8b1 100644 --- a/tests/samples/menu_dec.blp +++ b/tests/samples/menu_dec.blp @@ -1,13 +1,12 @@ using Gtk 4.0; -menu { - label: _("menu label"); - test-custom-attribute: "3.1415"; +menu my_menu { + section { + label: "test section"; + } submenu { - section { - label: "test section"; - } + label: "test submenu"; item { label: "test item"; diff --git a/tests/test_samples.py b/tests/test_samples.py index 4c4b17c..e1deec5 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -124,7 +124,6 @@ class TestSamples(unittest.TestCase): self.assert_sample("file_filter") self.assert_sample("flags") self.assert_sample("id_prop") - self.assert_sample("inline_menu") self.assert_sample("layout") self.assert_sample("menu") self.assert_sample("object_prop") @@ -147,7 +146,7 @@ class TestSamples(unittest.TestCase): self.assert_sample_error("a11y_prop_dne") self.assert_sample_error("a11y_prop_obj_dne") self.assert_sample_error("a11y_prop_type") - self.assert_sample_error("assign_inline_menu") + self.assert_sample_error("assign_menu") self.assert_sample_error("action_widget_float_response") self.assert_sample_error("action_widget_have_no_id") self.assert_sample_error("action_widget_multiple_default") @@ -165,6 +164,7 @@ class TestSamples(unittest.TestCase): self.assert_sample_error("filters_in_non_file_filter") self.assert_sample_error("invalid_bool") self.assert_sample_error("layout_in_non_widget") + self.assert_sample_error("menu_errors") self.assert_sample_error("ns_not_imported") self.assert_sample_error("not_a_class") self.assert_sample_error("object_dne")