From 64da41b2688adc8cbbe1a82177dd88c5dbee0d09 Mon Sep 17 00:00:00 2001 From: James Westman Date: Wed, 17 May 2023 09:58:51 -0500 Subject: [PATCH] ExtAdwMessageDialog: Duplicate flag errors --- .../language/adw_message_dialog.py | 49 +++++++++++++++---- .../adw_message_dialog_duplicate_flags.blp | 9 ++++ .../adw_message_dialog_duplicate_flags.err | 2 + 3 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 tests/sample_errors/adw_message_dialog_duplicate_flags.blp create mode 100644 tests/sample_errors/adw_message_dialog_duplicate_flags.err diff --git a/blueprintcompiler/language/adw_message_dialog.py b/blueprintcompiler/language/adw_message_dialog.py index 3cbd3e2..2823f77 100644 --- a/blueprintcompiler/language/adw_message_dialog.py +++ b/blueprintcompiler/language/adw_message_dialog.py @@ -25,31 +25,60 @@ from .gobject_object import ObjectContent, validate_parent_type from .values import StringValue -class Response(AstNode): +class ExtAdwMessageDialogFlag(AstNode): + grammar = AnyOf( + UseExact("flag", "destructive"), + UseExact("flag", "suggested"), + UseExact("flag", "disabled"), + ) + + @property + def flag(self) -> str: + return self.tokens["flag"] + + @validate() + def unique(self): + self.validate_unique_in_parent( + f"Duplicate '{self.flag}' flag", check=lambda child: child.flag == self.flag + ) + + @validate() + def exclusive(self): + if self.flag in ["destructive", "suggested"]: + self.validate_unique_in_parent( + "'suggested' and 'destructive' are exclusive", + check=lambda child: child.flag in ["destructive", "suggested"], + ) + + +class ExtAdwMessageDialogResponse(AstNode): grammar = [ UseIdent("id"), Match(":").expected(), to_parse_node(StringValue).expected("a string or translatable string"), - ZeroOrMore( - AnyOf(Keyword("destructive"), Keyword("suggested"), Keyword("disabled")) - ), + ZeroOrMore(ExtAdwMessageDialogFlag), ] @property def id(self) -> str: return self.tokens["id"] + @property + def flags(self) -> T.List[ExtAdwMessageDialogFlag]: + return self.children[ExtAdwMessageDialogFlag] + @property def appearance(self) -> T.Optional[str]: - if "destructive" in self.tokens: + if any(flag.flag == "destructive" for flag in self.flags): return "destructive" - if "suggested" in self.tokens: + elif any(flag.flag == "suggested" for flag in self.flags): return "suggested" - return None + else: + return None @property def enabled(self) -> bool: - return "disabled" not in self.tokens + return not any(flag.flag == "disabled" for flag in self.flags) @property def value(self) -> StringValue: @@ -71,12 +100,12 @@ class ExtAdwMessageDialog(AstNode): grammar = [ Keyword("responses"), Match("[").expected(), - Delimited(Response, ","), + Delimited(ExtAdwMessageDialogResponse, ","), "]", ] @property - def responses(self) -> T.List[Response]: + def responses(self) -> T.List[ExtAdwMessageDialogResponse]: return self.children @validate("responses") diff --git a/tests/sample_errors/adw_message_dialog_duplicate_flags.blp b/tests/sample_errors/adw_message_dialog_duplicate_flags.blp new file mode 100644 index 0000000..466db6e --- /dev/null +++ b/tests/sample_errors/adw_message_dialog_duplicate_flags.blp @@ -0,0 +1,9 @@ +using Gtk 4.0; +using Adw 1; + +Adw.MessageDialog { + responses [ + cancel: _("Cancel") disabled disabled, + ok: _("Ok") destructive suggested, + ] +} \ No newline at end of file diff --git a/tests/sample_errors/adw_message_dialog_duplicate_flags.err b/tests/sample_errors/adw_message_dialog_duplicate_flags.err new file mode 100644 index 0000000..91f0a3d --- /dev/null +++ b/tests/sample_errors/adw_message_dialog_duplicate_flags.err @@ -0,0 +1,2 @@ +6,34,8,Duplicate 'disabled' flag +7,29,9,'suggested' and 'destructive' are exclusive \ No newline at end of file