mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
Move bindings out of the Value syntax
They're only valid in properties, so they should just be there. Same with object values.
This commit is contained in:
parent
ac2a7d9282
commit
75055ac967
7 changed files with 45 additions and 47 deletions
|
@ -47,11 +47,6 @@ class Binding(AstNode):
|
|||
)
|
||||
return None
|
||||
|
||||
@validate("bind")
|
||||
def not_bindable(self) -> None:
|
||||
if binding_error := self.context[ValueTypeCtx].binding_error:
|
||||
raise binding_error
|
||||
|
||||
|
||||
@dataclass
|
||||
class SimpleBinding:
|
||||
|
|
|
@ -25,4 +25,3 @@ from .common import *
|
|||
@dataclass
|
||||
class ValueTypeCtx:
|
||||
value_type: T.Optional[GirType]
|
||||
binding_error: T.Optional[CompileError] = None
|
||||
|
|
|
@ -22,7 +22,7 @@ from dataclasses import dataclass
|
|||
from .expression import ExprChain
|
||||
from .gobject_object import Object
|
||||
from .gtkbuilder_template import Template
|
||||
from .values import Value, Translated
|
||||
from .values import Value, ObjectValue
|
||||
from .common import *
|
||||
from .contexts import ValueTypeCtx
|
||||
from .property_binding import PropertyBinding
|
||||
|
@ -30,14 +30,16 @@ from .binding import Binding
|
|||
|
||||
|
||||
class Property(AstNode):
|
||||
grammar = Statement(UseIdent("name"), ":", Value)
|
||||
grammar = Statement(
|
||||
UseIdent("name"), ":", AnyOf(PropertyBinding, Binding, ObjectValue, Value)
|
||||
)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self.tokens["name"]
|
||||
|
||||
@property
|
||||
def value(self) -> Value:
|
||||
def value(self) -> T.Union[PropertyBinding, Binding, ObjectValue, Value]:
|
||||
return self.children[0]
|
||||
|
||||
@property
|
||||
|
@ -49,29 +51,26 @@ class Property(AstNode):
|
|||
if self.gir_class is not None and not isinstance(self.gir_class, ExternType):
|
||||
return self.gir_class.properties.get(self.tokens["name"])
|
||||
|
||||
@context(ValueTypeCtx)
|
||||
def value_type(self) -> ValueTypeCtx:
|
||||
@validate()
|
||||
def binding_valid(self):
|
||||
if (
|
||||
(
|
||||
isinstance(self.value.child, PropertyBinding)
|
||||
or isinstance(self.value.child, Binding)
|
||||
)
|
||||
(isinstance(self.value, PropertyBinding) or isinstance(self.value, Binding))
|
||||
and self.gir_property is not None
|
||||
and self.gir_property.construct_only
|
||||
):
|
||||
binding_error = CompileError(
|
||||
raise CompileError(
|
||||
f"{self.gir_property.full_name} can't be bound because it is construct-only",
|
||||
hints=["construct-only properties may only be set to a static value"],
|
||||
)
|
||||
else:
|
||||
binding_error = None
|
||||
|
||||
@context(ValueTypeCtx)
|
||||
def value_type(self) -> ValueTypeCtx:
|
||||
if self.gir_property is not None:
|
||||
type = self.gir_property.type
|
||||
else:
|
||||
type = None
|
||||
|
||||
return ValueTypeCtx(type, binding_error)
|
||||
return ValueTypeCtx(type)
|
||||
|
||||
@validate("name")
|
||||
def property_exists(self):
|
||||
|
|
|
@ -121,11 +121,6 @@ class PropertyBinding(AstNode):
|
|||
f"{gir_class.full_name} does not have a property called {self.property_name}"
|
||||
)
|
||||
|
||||
@validate("bind-property")
|
||||
def not_bindable(self) -> None:
|
||||
if binding_error := self.context[ValueTypeCtx].binding_error:
|
||||
raise binding_error
|
||||
|
||||
@validate("bind")
|
||||
def old_bind(self):
|
||||
if self.tokens["bind"]:
|
||||
|
|
|
@ -361,12 +361,12 @@ class ObjectValue(AstNode):
|
|||
|
||||
|
||||
class Value(AstNode):
|
||||
grammar = AnyOf(PropertyBinding, Binding, Translated, ObjectValue, Flags, Literal)
|
||||
grammar = AnyOf(Translated, Flags, Literal)
|
||||
|
||||
@property
|
||||
def child(
|
||||
self,
|
||||
) -> T.Union[PropertyBinding, Binding, Translated, ObjectValue, Flags, Literal]:
|
||||
) -> T.Union[Translated, Flags, Literal]:
|
||||
return self.children[0]
|
||||
|
||||
|
||||
|
|
|
@ -91,48 +91,58 @@ class XmlOutput(OutputFormat):
|
|||
|
||||
def _emit_property(self, property: Property, xml: XmlEmitter):
|
||||
value = property.value
|
||||
child = value.child
|
||||
|
||||
props: T.Dict[str, T.Optional[str]] = {
|
||||
"name": property.name,
|
||||
}
|
||||
|
||||
if isinstance(value, Value):
|
||||
child = value.child
|
||||
|
||||
if isinstance(child, Translated):
|
||||
xml.start_tag("property", **props, **self._translated_string_attrs(child))
|
||||
xml.start_tag(
|
||||
"property", **props, **self._translated_string_attrs(child)
|
||||
)
|
||||
xml.put_text(child.child.string)
|
||||
xml.end_tag()
|
||||
elif isinstance(child, Object):
|
||||
else:
|
||||
xml.start_tag("property", **props)
|
||||
self._emit_object(child, xml)
|
||||
self._emit_value(value, xml)
|
||||
xml.end_tag()
|
||||
elif isinstance(child, Binding):
|
||||
if simple := child.simple_binding:
|
||||
|
||||
elif isinstance(value, Binding):
|
||||
if simple := value.simple_binding:
|
||||
props["bind-source"] = simple.source
|
||||
props["bind-property"] = simple.property_name
|
||||
props["bind-flags"] = "sync-create"
|
||||
xml.put_self_closing("property", **props)
|
||||
else:
|
||||
xml.start_tag("binding", **props)
|
||||
self._emit_expression(child.expression, xml)
|
||||
self._emit_expression(value.expression, xml)
|
||||
xml.end_tag()
|
||||
elif isinstance(child, PropertyBinding):
|
||||
|
||||
elif isinstance(value, PropertyBinding):
|
||||
bind_flags = []
|
||||
if not child.no_sync_create:
|
||||
if not value.no_sync_create:
|
||||
bind_flags.append("sync-create")
|
||||
if child.inverted:
|
||||
if value.inverted:
|
||||
bind_flags.append("invert-boolean")
|
||||
if child.bidirectional:
|
||||
if value.bidirectional:
|
||||
bind_flags.append("bidirectional")
|
||||
|
||||
props["bind-source"] = child.source
|
||||
props["bind-property"] = child.property_name
|
||||
props["bind-source"] = value.source
|
||||
props["bind-property"] = value.property_name
|
||||
props["bind-flags"] = "|".join(bind_flags) or None
|
||||
xml.put_self_closing("property", **props)
|
||||
else:
|
||||
|
||||
elif isinstance(value, ObjectValue):
|
||||
xml.start_tag("property", **props)
|
||||
self._emit_value(value, xml)
|
||||
self._emit_object(value.object, xml)
|
||||
xml.end_tag()
|
||||
|
||||
else:
|
||||
raise CompilerBugError()
|
||||
|
||||
def _translated_string_attrs(
|
||||
self, translated: T.Union[QuotedLiteral, Translated]
|
||||
) -> T.Dict[str, T.Optional[str]]:
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
4,14,4,ComboBox.has-entry can't be bound because it is construct-only
|
||||
4,3,34,ComboBox.has-entry can't be bound because it is construct-only
|
||||
5,3,12,Widget.scale-factor is not writable
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue