mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
Compare commits
6 commits
0ec342bdad
...
8b9614bf0c
Author | SHA1 | Date | |
---|---|---|---|
|
8b9614bf0c | ||
|
d6f4b88d35 | ||
|
a6d57cebec | ||
|
e07da3c339 | ||
|
2ae41020ab | ||
|
f48b840cfa |
14 changed files with 84 additions and 12 deletions
|
@ -27,6 +27,7 @@ from .gtkbuilder_template import Template
|
|||
class SignalFlag(AstNode):
|
||||
grammar = AnyOf(
|
||||
UseExact("flag", "swapped"),
|
||||
UseExact("flag", "not-swapped"),
|
||||
UseExact("flag", "after"),
|
||||
)
|
||||
|
||||
|
@ -40,6 +41,27 @@ class SignalFlag(AstNode):
|
|||
f"Duplicate flag '{self.flag}'", lambda x: x.flag == self.flag
|
||||
)
|
||||
|
||||
@validate()
|
||||
def swapped_exclusive(self):
|
||||
if self.flag in ["swapped", "not-swapped"]:
|
||||
self.validate_unique_in_parent(
|
||||
"'swapped' and 'not-swapped' flags cannot be used together",
|
||||
lambda x: x.flag in ["swapped", "not-swapped"],
|
||||
)
|
||||
|
||||
@validate()
|
||||
def swapped_unnecessary(self):
|
||||
if self.flag == "not-swapped" and self.parent.object_id is None:
|
||||
raise CompileWarning(
|
||||
"'not-swapped' is the default for handlers that do not specify an object",
|
||||
actions=[CodeAction("Remove 'not-swapped' flag", "")],
|
||||
)
|
||||
elif self.flag == "swapped" and self.parent.object_id is not None:
|
||||
raise CompileWarning(
|
||||
"'swapped' is the default for handlers that specify an object",
|
||||
actions=[CodeAction("Remove 'swapped' flag", "")],
|
||||
)
|
||||
|
||||
@docs()
|
||||
def ref_docs(self):
|
||||
return get_docs_section("Syntax Signal")
|
||||
|
@ -92,9 +114,17 @@ class Signal(AstNode):
|
|||
def flags(self) -> T.List[SignalFlag]:
|
||||
return self.children[SignalFlag]
|
||||
|
||||
# Returns True if the "swapped" flag is present, False if "not-swapped" is present, and None if neither are present.
|
||||
# GtkBuilder's default if swapped is not specified is to not swap the arguments if no object is specified, and to
|
||||
# swap them if an object is specified.
|
||||
@property
|
||||
def is_swapped(self) -> bool:
|
||||
return any(x.flag == "swapped" for x in self.flags)
|
||||
def is_swapped(self) -> T.Optional[bool]:
|
||||
for flag in self.flags:
|
||||
if flag.flag == "swapped":
|
||||
return True
|
||||
elif flag.flag == "not-swapped":
|
||||
return False
|
||||
return None
|
||||
|
||||
@property
|
||||
def is_after(self) -> bool:
|
||||
|
@ -113,12 +143,13 @@ class Signal(AstNode):
|
|||
|
||||
@property
|
||||
def document_symbol(self) -> DocumentSymbol:
|
||||
detail = self.ranges["detail_start", "detail_end"]
|
||||
return DocumentSymbol(
|
||||
self.full_name,
|
||||
SymbolKind.Event,
|
||||
self.range,
|
||||
self.group.tokens["name"].range,
|
||||
self.ranges["detail_start", "detail_end"].text,
|
||||
detail.text if detail is not None else None,
|
||||
)
|
||||
|
||||
def get_reference(self, idx: int) -> T.Optional[LocationLink]:
|
||||
|
@ -194,15 +225,16 @@ class Signal(AstNode):
|
|||
|
||||
|
||||
@decompiler("signal")
|
||||
def decompile_signal(
|
||||
ctx, gir, name, handler, swapped="false", after="false", object=None
|
||||
):
|
||||
def decompile_signal(ctx, gir, name, handler, swapped=None, after="false", object=None):
|
||||
object_name = object or ""
|
||||
name = name.replace("_", "-")
|
||||
line = f"{name} => ${handler}({object_name})"
|
||||
|
||||
if decompile.truthy(swapped):
|
||||
line += " swapped"
|
||||
elif swapped is not None:
|
||||
line += " not-swapped"
|
||||
|
||||
if decompile.truthy(after):
|
||||
line += " after"
|
||||
|
||||
|
|
|
@ -211,12 +211,12 @@ class Flag(AstNode):
|
|||
return self.tokens["value"]
|
||||
|
||||
@property
|
||||
def value(self) -> T.Optional[int]:
|
||||
def value(self) -> T.Optional[str]:
|
||||
type = self.context[ValueTypeCtx].value_type
|
||||
if not isinstance(type, Enumeration):
|
||||
return None
|
||||
elif member := type.members.get(self.name):
|
||||
return member.value
|
||||
return member.nick
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ class XmlOutput(OutputFormat):
|
|||
"signal",
|
||||
name=name,
|
||||
handler=signal.handler,
|
||||
swapped=signal.is_swapped or None,
|
||||
swapped=signal.is_swapped,
|
||||
after=signal.is_after or None,
|
||||
object=(
|
||||
self._object_id(signal, signal.object_id) if signal.object_id else None
|
||||
|
|
|
@ -91,7 +91,7 @@ Signal Handlers
|
|||
.. rst-class:: grammar-block
|
||||
|
||||
Signal = <name::ref:`IDENT<Syntax IDENT>`> ('::' <detail::ref:`IDENT<Syntax IDENT>`>)? '=>' '$' <handler::ref:`IDENT<Syntax IDENT>`> '(' <object::ref:`IDENT<Syntax IDENT>`>? ')' (SignalFlag)* ';'
|
||||
SignalFlag = 'after' | 'swapped'
|
||||
SignalFlag = 'after' | 'swapped' | 'not-swapped'
|
||||
|
||||
Signals are one way to respond to user input (another is `actions <https://docs.gtk.org/gtk4/actions.html>`_, which use the `action-name property <https://docs.gtk.org/gtk4/property.Actionable.action-name.html>`_).
|
||||
|
||||
|
@ -99,6 +99,8 @@ Signals provide a handle for your code to listen to events in the UI. The handle
|
|||
|
||||
Optionally, you can provide an object ID to use when connecting the signal.
|
||||
|
||||
The ``swapped`` flag is used to swap the order of the object and userdata arguments in C applications. If an object argument is specified, then this is the default behavior, so the ``not-swapped`` flag can be used to prevent the swap.
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
|
@ -108,7 +110,6 @@ Example
|
|||
clicked => $on_button_clicked();
|
||||
}
|
||||
|
||||
|
||||
.. _Syntax Child:
|
||||
|
||||
Children
|
||||
|
|
5
tests/sample_errors/incomplete_signal.blp
Normal file
5
tests/sample_errors/incomplete_signal.blp
Normal file
|
@ -0,0 +1,5 @@
|
|||
using Gtk 4.0;
|
||||
|
||||
Label {
|
||||
notify::
|
||||
}
|
2
tests/sample_errors/incomplete_signal.err
Normal file
2
tests/sample_errors/incomplete_signal.err
Normal file
|
@ -0,0 +1,2 @@
|
|||
5,1,0,Expected a signal detail name
|
||||
4,9,3,Unexpected tokens
|
5
tests/sample_errors/signal_exclusive_flags.blp
Normal file
5
tests/sample_errors/signal_exclusive_flags.blp
Normal file
|
@ -0,0 +1,5 @@
|
|||
using Gtk 4.0;
|
||||
|
||||
$MyObject obj {
|
||||
signal1 => $handler() swapped not-swapped;
|
||||
}
|
1
tests/sample_errors/signal_exclusive_flags.err
Normal file
1
tests/sample_errors/signal_exclusive_flags.err
Normal file
|
@ -0,0 +1 @@
|
|||
4,33,11,'swapped' and 'not-swapped' flags cannot be used together
|
6
tests/sample_errors/signal_unnecessary_flags.blp
Normal file
6
tests/sample_errors/signal_unnecessary_flags.blp
Normal file
|
@ -0,0 +1,6 @@
|
|||
using Gtk 4.0;
|
||||
|
||||
$MyObject obj {
|
||||
signal1 => $handler() not-swapped;
|
||||
signal2 => $handler(obj) swapped;
|
||||
}
|
2
tests/sample_errors/signal_unnecessary_flags.err
Normal file
2
tests/sample_errors/signal_unnecessary_flags.err
Normal file
|
@ -0,0 +1,2 @@
|
|||
4,25,11,'not-swapped' is the default for handlers that do not specify an object
|
||||
5,28,7,'swapped' is the default for handlers that specify an object
|
|
@ -7,7 +7,7 @@ corresponding .blp file and regenerate this file with blueprint-compiler.
|
|||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<object class="GApplication">
|
||||
<property name="flags">1|4</property>
|
||||
<property name="flags">is-service|handles-open</property>
|
||||
</object>
|
||||
<object class="GtkEventControllerScroll">
|
||||
<property name="flags">1</property>
|
||||
|
|
5
tests/samples/signal_not_swapped.blp
Normal file
5
tests/samples/signal_not_swapped.blp
Normal file
|
@ -0,0 +1,5 @@
|
|||
using Gtk 4.0;
|
||||
|
||||
Button obj {
|
||||
clicked => $handler(obj) not-swapped;
|
||||
}
|
12
tests/samples/signal_not_swapped.ui
Normal file
12
tests/samples/signal_not_swapped.ui
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
DO NOT EDIT!
|
||||
This file was @generated by blueprint-compiler. Instead, edit the
|
||||
corresponding .blp file and regenerate this file with blueprint-compiler.
|
||||
-->
|
||||
<interface>
|
||||
<requires lib="gtk" version="4.0"/>
|
||||
<object class="GtkButton" id="obj">
|
||||
<signal name="clicked" handler="handler" swapped="False" object="obj"/>
|
||||
</object>
|
||||
</interface>
|
|
@ -200,6 +200,7 @@ class TestSamples(unittest.TestCase):
|
|||
"expr_closure_args",
|
||||
"parseable",
|
||||
"signal",
|
||||
"signal_not_swapped",
|
||||
"template",
|
||||
"template_binding",
|
||||
"template_binding_extern",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue