add variant support for menus

This commit is contained in:
jgcodes2020 2024-12-14 14:00:09 -05:00
parent f894301571
commit a75adc7d1b
4 changed files with 39 additions and 13 deletions

View file

@ -19,7 +19,7 @@
import typing as T import typing as T
from blueprintcompiler.language.values import StringValue from blueprintcompiler.language.values import StringValue, VariantValue
from .common import * from .common import *
from .contexts import ValueTypeCtx from .contexts import ValueTypeCtx
@ -98,8 +98,12 @@ class MenuAttribute(AstNode):
return self.tokens["name"] return self.tokens["name"]
@property @property
def value(self) -> StringValue: def value(self) -> StringValue | VariantValue:
if len(self.children[StringValue]) > 0:
return self.children[StringValue][0] return self.children[StringValue][0]
elif len(self.children[VariantValue]) > 0:
return self.children[VariantValue][0]
raise CompilerBugError()
@property @property
def document_symbol(self) -> DocumentSymbol: def document_symbol(self) -> DocumentSymbol:
@ -133,7 +137,7 @@ menu_attribute = Group(
[ [
UseIdent("name"), UseIdent("name"),
":", ":",
Err(StringValue, "Expected string or translated string"), Err(AnyOf(StringValue, VariantValue), "Expected string or translated string"),
Match(";").expected(), Match(";").expected(),
], ],
) )

View file

@ -393,7 +393,9 @@ class VariantValue(AstNode):
@validate() @validate()
def validate_for_type(self) -> None: def validate_for_type(self) -> None:
expected_type = self.context[ValueTypeCtx].value_type expected_type = self.context[ValueTypeCtx].value_type
if ( if expected_type is None:
pass
elif (
isinstance(expected_type, gir.IntType) isinstance(expected_type, gir.IntType)
or isinstance(expected_type, gir.UIntType) or isinstance(expected_type, gir.UIntType)
or isinstance(expected_type, gir.FloatType) or isinstance(expected_type, gir.FloatType)
@ -402,7 +404,7 @@ class VariantValue(AstNode):
raise CompileError(f"Cannot convert variant to number") raise CompileError(f"Cannot convert variant to number")
elif isinstance(expected_type, gir.StringType): elif isinstance(expected_type, gir.StringType):
raise CompileError("Cannot convert variant to string") raise CompileError("Cannot convert variant to string")
if isinstance(expected_type, gir.Boxed) and expected_type.full_name == "GLib.Variant": elif isinstance(expected_type, gir.Boxed) and expected_type.full_name == "GLib.Variant":
pass pass
else: else:
raise CompileError(f"Cannot convert variant into {expected_type.full_name}") raise CompileError(f"Cannot convert variant into {expected_type.full_name}")

View file

@ -85,6 +85,7 @@ class XmlOutput(OutputFormat):
if isinstance(child, Menu): if isinstance(child, Menu):
self._emit_menu(child, xml) self._emit_menu(child, xml)
elif isinstance(child, MenuAttribute): elif isinstance(child, MenuAttribute):
if isinstance(child.value, StringValue):
xml.start_tag( xml.start_tag(
"attribute", "attribute",
name=child.name, name=child.name,
@ -92,6 +93,15 @@ class XmlOutput(OutputFormat):
) )
xml.put_text(child.value.string) xml.put_text(child.value.string)
xml.end_tag() xml.end_tag()
elif isinstance(child.value, VariantValue):
xml.start_tag(
"attribute",
name=child.name,
type=child.value.var_type,
)
xml.put_text(child.value.var_value)
xml.end_tag()
else: else:
raise CompilerBugError() raise CompilerBugError()
xml.end_tag() xml.end_tag()

View file

@ -1,5 +1,15 @@
using Gtk 4.0; using Gtk 4.0;
menu root {
submenu {
name: "one";
item {
action: "app.foo_bar";
target: variant<"s">("\"one\"");
}
}
}
Button { Button {
action-name: "app.shave_yak"; action-name: "app.shave_yak";
action-target: variant<"y">("8"); action-target: variant<"y">("8");