Conversation
e23e59e to
46f35af
Compare
Under the existing debug-info flag, record each element's readable in/out/in-out properties at LLR lowering (SubComponent::element_properties): move_declarations captures the source name and root key of every declaration it hoists, ranking the effective shadowing declaration of a name first (the shadowing_members index is cleared by the move, so this is the last point the information exists), and collect_element_properties resolves the captured and inherited declarations through the regular property-reference mapping. The LLR optimizer filters and remaps the table like every other reference holder. Two new ItemTreeVTable entries expose the table: element_declared_properties enumerates 'name:type' pairs, element_property_value reads one value in the string encoding of the new i-slint-core debug_info module. Their contract is tri-state: false means unsupported, true with an empty result means nothing declared. Generated Rust bakes match arms mirroring item_element_infos; the interpreter serves both entries from the LLR table via eval::load_property; generated C++ emits stubs reporting unsupported until its own implementation. ElementHandle gains declared_properties() and declared_property_value(). Part of slint-ui#13251.
Adds declaredProperties to ElementPropertiesResponse: each element's in/out/in-out properties with name, type, and current value read through the debug-info channel. The MCP layer retypes the string values into JSON booleans and numbers for both get_element_properties and get_element_tree, and reports missing debug info or an unsupported code generator through a note instead of an empty list. Protobuf clients get the raw strings plus an availability flag. Part of slint-ui#13251. ChangeLog: The MCP server's get_element_properties and get_element_tree report declaredProperties — an element's declared in/out/in-out properties with typed current values — and ElementHandle gains declared_properties() and declared_property_value() in the Rust and C++ testing APIs. Requires SLINT_EMIT_DEBUG_INFO=1.
The C++ generator replaces its element_declared_properties and element_property_value stubs with real dispatch. Bool, integer, color, brush, and enum values are encoded by slint::private_api::debug_info_format_* helpers matching i_slint_core::debug_info; float values are formatted by the Rust runtime through a new slint_debug_info_format_float FFI function — GCC 10 (a supported toolchain) has no floating-point std::to_chars, and no local formatter reproduces Rust's f32 Display digits for values like 1e20. The C++ testing API gains ElementHandle::declared_properties() and declared_property_value(). Part of slint-ui#13251.
One source, one set of expected strings: the driver case runs it through generated Rust and generated C++, the interpreter test through the runtime interpretation, so the three value encodings cannot drift apart. Covers every encodable type plus a struct (listed, value unavailable), float edge values (0.1 and 1e20), two-way aliases, inherited and use-site declarations, repeated rows, reactivity, and the exclusions: private declarations and optimizer-removed properties. Part of slint-ui#13251.
46f35af to
071933c
Compare
In the past, this has been indeed the primary concern about this feature. If a new Slint version introduces a new optimisation that optimises a property away that was previously accessible and now isn't anymore, then that would constitute a breaking change - preventing us from making the optimisation. That's why we were thinking of introducing an extra attribute to a property to indicate that this particular property is required for the purpose of system testing. So not necessarily part of the component's public API, but relevant to testing.
Can you elaborate on the follow-up plans? |
|
Right, the PR leans on that limitation being acceptable for now, and the docs' "anchor the property with a
So tests written against pinned properties would get a stability guarantee instead of today's "hope it survives the optimizer", and the introspection channel doesn't need touching when the attribute lands. I'd do it as the next PR, spelling to be bikeshed ( On writing: the sketch is a third vtable entry mirroring the read side. It parses back the same string encoding |
|
The essence:
I can't believe I'm saying this, but perhaps this would go well in a single PR :-) |
An MCP client (and any
ElementHandleuser) can now read an element's declaredin/out/in-outproperties back, so verifying UI state no longer means diffing screenshots.Closes #13251. Addresses gap 1 of #13244.
Design
SLINT_EMIT_DEBUG_INFO=1/with_debug_info), the compiler records each element's readable declared properties at LLR lowering (SubComponent::element_properties).move_declarationscaptures the source name and root key of every declaration it hoists, ranking the effective shadowing declaration first; the LLR optimizer filters and remaps the table like every other reference holder.ItemTreeVTableentries expose the table, following theaccessible_string_propertystringify convention:element_declared_propertiesenumeratesname:typepairs,element_property_valuereads one value in the string encoding of the newi_slint_core::debug_infomodule.The contract is tri-state:
falsemeans unsupported,truewith an empty result means nothing declared, so a runtime without the feature is distinguishable from an element without properties.item_element_infos, the interpreter evaluates througheval::load_property, and generated C++ dispatches throughslint::private_apihelpers.C++ delegates float encoding to the Rust runtime over FFI: GCC 10 (a supported toolchain) has no floating-point
std::to_chars, and no local formatter reproduces Rust'sf32Displaydigits for values like1e20.ElementHandlegainsdeclared_properties()anddeclared_property_value()in the Rust and C++ testing APIs.get_element_propertiesandget_element_treereportdeclaredPropertieswith typed JSON values, and say so through a note when debug info is missing instead of degrading silently.Example response fragment:
Properties the compiler optimized out (constant, or never read) are not listed; private declarations are excluded. Writing declared properties is left to a follow-up.
Testing
tests/cases/testing/declared_properties.slint(generated Rust and C++) andinternal/interpreter/tests/declared_properties.rs(interpreter), covering every encodable type, float edge values (0.1,1e20), aliases, inherited and use-site declarations, repeated rows, reactivity, and the exclusions.@shadowable) is pinned by a compiler unit test.Cost
Measured on a release build of the gallery (macOS arm64):
SLINT_EMIT_DEBUG_INFO=1Flag off, the two vtable entries and their stubs cost +89,632 B (+0.46%); flag on, the tables and value-read code cost +224,240 B (+1.16%).