Add StringValue

Makes the grammar more specific in a few places that take only a string
literal or translated string.
This commit is contained in:
James Westman 2023-04-11 21:26:37 -05:00
parent 5bfed72674
commit ac2a7d9282
8 changed files with 66 additions and 42 deletions

View file

@ -37,6 +37,7 @@ from .values import (
NumberLiteral, NumberLiteral,
ObjectValue, ObjectValue,
QuotedLiteral, QuotedLiteral,
StringValue,
Translated, Translated,
TranslatedWithContext, TranslatedWithContext,
TranslatedWithoutContext, TranslatedWithoutContext,

View file

@ -22,14 +22,14 @@ from ..decompiler import truthy, decompile_translatable
from .common import * from .common import *
from .contexts import ValueTypeCtx from .contexts import ValueTypeCtx
from .gobject_object import ObjectContent, validate_parent_type from .gobject_object import ObjectContent, validate_parent_type
from .values import QuotedLiteral, Translated from .values import StringValue
class Response(AstNode): class Response(AstNode):
grammar = [ grammar = [
UseIdent("id"), UseIdent("id"),
Match(":").expected(), Match(":").expected(),
AnyOf(QuotedLiteral, Translated).expected("a value"), to_parse_node(StringValue).expected("a string or translatable string"),
ZeroOrMore( ZeroOrMore(
AnyOf(Keyword("destructive"), Keyword("suggested"), Keyword("disabled")) AnyOf(Keyword("destructive"), Keyword("suggested"), Keyword("disabled"))
), ),
@ -52,7 +52,7 @@ class Response(AstNode):
return "disabled" not in self.tokens return "disabled" not in self.tokens
@property @property
def value(self) -> T.Union[QuotedLiteral, Translated]: def value(self) -> StringValue:
return self.children[0] return self.children[0]
@context(ValueTypeCtx) @context(ValueTypeCtx)

View file

@ -22,7 +22,7 @@ from .attributes import BaseTypedAttribute
from .gobject_object import ObjectContent, validate_parent_type from .gobject_object import ObjectContent, validate_parent_type
from .common import * from .common import *
from .contexts import ValueTypeCtx from .contexts import ValueTypeCtx
from .values import Value from .values import StringValue
class Item(AstNode): class Item(AstNode):
@ -31,12 +31,8 @@ class Item(AstNode):
return self.tokens["name"] return self.tokens["name"]
@property @property
def value(self) -> Value: def value(self) -> StringValue:
return self.children[Value][0] return self.children[StringValue][0]
@context(ValueTypeCtx)
def value_type(self) -> ValueTypeCtx:
return ValueTypeCtx(StringType())
item = Group( item = Group(
@ -48,7 +44,7 @@ item = Group(
":", ":",
] ]
), ),
Value, StringValue,
], ],
) )

View file

@ -19,7 +19,7 @@
import typing as T import typing as T
from blueprintcompiler.language.values import Value from blueprintcompiler.language.values import StringValue
from .attributes import BaseAttribute from .attributes import BaseAttribute
from .gobject_object import Object, ObjectContent from .gobject_object import Object, ObjectContent
@ -58,8 +58,8 @@ class MenuAttribute(AstNode):
return self.tokens["name"] return self.tokens["name"]
@property @property
def value(self) -> Value: def value(self) -> StringValue:
return self.children[Value][0] return self.children[StringValue][0]
@context(ValueTypeCtx) @context(ValueTypeCtx)
def value_type(self) -> ValueTypeCtx: def value_type(self) -> ValueTypeCtx:
@ -85,7 +85,7 @@ menu_attribute = Group(
[ [
UseIdent("name"), UseIdent("name"),
":", ":",
Err(Value, "Expected a value"), Err(StringValue, "Expected string or translated string"),
Match(";").expected(), Match(";").expected(),
], ],
) )
@ -109,7 +109,7 @@ menu_item_shorthand = Group(
"(", "(",
Group( Group(
MenuAttribute, MenuAttribute,
[UseLiteral("name", "label"), Value], [UseLiteral("name", "label"), StringValue],
), ),
Optional( Optional(
[ [
@ -118,14 +118,14 @@ menu_item_shorthand = Group(
[ [
Group( Group(
MenuAttribute, MenuAttribute,
[UseLiteral("name", "action"), Value], [UseLiteral("name", "action"), StringValue],
), ),
Optional( Optional(
[ [
",", ",",
Group( Group(
MenuAttribute, MenuAttribute,
[UseLiteral("name", "icon"), Value], [UseLiteral("name", "icon"), StringValue],
), ),
] ]
), ),

View file

@ -20,17 +20,16 @@
from .attributes import BaseTypedAttribute from .attributes import BaseTypedAttribute
from .gobject_object import ObjectContent, validate_parent_type from .gobject_object import ObjectContent, validate_parent_type
from .values import Value, Translated from .values import StringValue
from .common import * from .common import *
from .contexts import ValueTypeCtx
class Item(AstNode): class Item(AstNode):
grammar = Value grammar = StringValue
@context(ValueTypeCtx) @property
def value_type(self) -> ValueTypeCtx: def child(self) -> StringValue:
return ValueTypeCtx(StringType()) return self.children[StringValue][0]
class Strings(AstNode): class Strings(AstNode):

View file

@ -368,3 +368,24 @@ class Value(AstNode):
self, self,
) -> T.Union[PropertyBinding, Binding, Translated, ObjectValue, Flags, Literal]: ) -> T.Union[PropertyBinding, Binding, Translated, ObjectValue, Flags, Literal]:
return self.children[0] return self.children[0]
class StringValue(AstNode):
grammar = AnyOf(Translated, QuotedLiteral)
@property
def child(
self,
) -> T.Union[Translated, QuotedLiteral]:
return self.children[0]
@property
def string(self) -> str:
if isinstance(self.child, Translated):
return self.child.child.string
else:
return self.child.value
@context(ValueTypeCtx)
def value_type(self) -> ValueTypeCtx:
return ValueTypeCtx(StringType())

View file

@ -78,7 +78,13 @@ 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):
self._emit_attribute("attribute", "name", child.name, child.value, xml) xml.start_tag(
"attribute",
name=child.name,
**self._translated_string_attrs(child.value.child),
)
xml.put_text(child.value.string)
xml.end_tag()
else: else:
raise CompilerBugError() raise CompilerBugError()
xml.end_tag() xml.end_tag()
@ -235,7 +241,12 @@ class XmlOutput(OutputFormat):
xml.end_tag() xml.end_tag()
def _emit_attribute( def _emit_attribute(
self, tag: str, attr: str, name: str, value: Value, xml: XmlEmitter self,
tag: str,
attr: str,
name: str,
value: T.Union[Value, StringValue],
xml: XmlEmitter,
): ):
attrs = {attr: name} attrs = {attr: name}
@ -243,6 +254,10 @@ class XmlOutput(OutputFormat):
xml.start_tag(tag, **attrs, **self._translated_string_attrs(value.child)) xml.start_tag(tag, **attrs, **self._translated_string_attrs(value.child))
xml.put_text(value.child.child.string) xml.put_text(value.child.child.string)
xml.end_tag() xml.end_tag()
elif isinstance(value.child, QuotedLiteral):
xml.start_tag(tag, **attrs)
xml.put_text(value.child.value)
xml.end_tag()
else: else:
xml.start_tag(tag, **attrs) xml.start_tag(tag, **attrs)
self._emit_value(value, xml) self._emit_value(value, xml)
@ -282,29 +297,21 @@ class XmlOutput(OutputFormat):
xml.start_tag( xml.start_tag(
"response", "response",
id=response.id, id=response.id,
**self._translated_string_attrs(response.value), **self._translated_string_attrs(response.value.child),
enabled=None if response.enabled else "false", enabled=None if response.enabled else "false",
appearance=response.appearance, appearance=response.appearance,
) )
if isinstance(response.value, Translated): xml.put_text(response.value.string)
xml.put_text(response.value.child.string)
else:
xml.put_text(response.value.value)
xml.end_tag() xml.end_tag()
xml.end_tag() xml.end_tag()
elif isinstance(extension, Strings): elif isinstance(extension, Strings):
xml.start_tag("items") xml.start_tag("items")
for prop in extension.children: for string in extension.children:
value = prop.children[Value][0] value = string.child
if isinstance(value.child, Translated): xml.start_tag("item", **self._translated_string_attrs(value.child))
xml.start_tag("item", **self._translated_string_attrs(value)) xml.put_text(value.string)
xml.put_text(value.child.child.string) xml.end_tag()
xml.end_tag()
else:
xml.start_tag("item")
self._emit_value(value, xml)
xml.end_tag()
xml.end_tag() xml.end_tag()
elif isinstance(extension, ListItemFactory): elif isinstance(extension, ListItemFactory):
child_xml = XmlEmitter() child_xml = XmlEmitter()

View file

@ -1 +1 @@
5,5,2,Cannot assign Gtk.Button to string 4,3,22,Unexpected tokens