mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-28 21:04:47 +00:00
Compiler: properly transform property access from base expression in state
Fix #5038
This commit is contained in:
parent
aebc7570c8
commit
2c0ba2bc0f
2 changed files with 83 additions and 12 deletions
|
@ -204,27 +204,28 @@ enum ExpressionForProperty {
|
|||
fn expression_for_property(element: &ElementRc, name: &str) -> ExpressionForProperty {
|
||||
let mut element_it = Some(element.clone());
|
||||
let mut in_base = false;
|
||||
while let Some(element) = element_it {
|
||||
if let Some(e) = element.borrow().bindings.get(name) {
|
||||
while let Some(elem) = element_it {
|
||||
if let Some(e) = elem.borrow().bindings.get(name) {
|
||||
let e = e.borrow();
|
||||
if !e.two_way_bindings.is_empty() {
|
||||
return ExpressionForProperty::TwoWayBinding;
|
||||
}
|
||||
if !matches!(e.expression, Expression::Invalid) {
|
||||
let mut expr = e.expression.clone();
|
||||
if !matches!(expr, Expression::Invalid) {
|
||||
if in_base {
|
||||
// Check that the expresison is valid in the new scope
|
||||
let mut has_invalid = false;
|
||||
e.expression.visit_recursive(&mut |ex| match ex {
|
||||
expr.visit_recursive_mut(&mut |ex| match ex {
|
||||
Expression::CallbackReference(nr, _)
|
||||
| Expression::PropertyReference(nr)
|
||||
| Expression::FunctionReference(nr, _) => {
|
||||
let e = nr.element();
|
||||
if !Rc::ptr_eq(&e, &element)
|
||||
&& Weak::ptr_eq(
|
||||
&e.borrow().enclosing_component,
|
||||
&element.borrow().enclosing_component,
|
||||
)
|
||||
{
|
||||
if Rc::ptr_eq(&e, &elem) {
|
||||
*nr = NamedReference::new(element, nr.name());
|
||||
} else if Weak::ptr_eq(
|
||||
&e.borrow().enclosing_component,
|
||||
&elem.borrow().enclosing_component,
|
||||
) {
|
||||
has_invalid = true;
|
||||
}
|
||||
}
|
||||
|
@ -235,10 +236,10 @@ fn expression_for_property(element: &ElementRc, name: &str) -> ExpressionForProp
|
|||
}
|
||||
}
|
||||
|
||||
return ExpressionForProperty::Expression(e.expression.clone());
|
||||
return ExpressionForProperty::Expression(expr);
|
||||
}
|
||||
}
|
||||
element_it = if let ElementType::Component(base) = &element.borrow().base_type {
|
||||
element_it = if let ElementType::Component(base) = &elem.borrow().base_type {
|
||||
in_base = true;
|
||||
Some(base.root_element.clone())
|
||||
} else {
|
||||
|
|
70
tests/cases/properties/issue5038_state_in_base.slint
Normal file
70
tests/cases/properties/issue5038_state_in_base.slint
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||
|
||||
export global Glob {
|
||||
in-out property <bool> cond2;
|
||||
}
|
||||
|
||||
component Base inherits Rectangle {
|
||||
in property <int> value;
|
||||
|
||||
}
|
||||
|
||||
export component R1 inherits Base {
|
||||
|
||||
t := TouchArea { }
|
||||
|
||||
ti := TextInput { text: Glob.cond2 ? "a" : "b"; }
|
||||
|
||||
|
||||
states [
|
||||
xxx when ti.text == "a" : {
|
||||
value: 1;
|
||||
}
|
||||
hover when t.has-hover: {
|
||||
background: white;
|
||||
value: 2;
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export component R2 inherits R1 { }
|
||||
|
||||
export component TestCase inherits Window {
|
||||
in property <bool> cond1;
|
||||
r2 := R2 {
|
||||
states [
|
||||
s1 when cond1: {
|
||||
background: white;
|
||||
value: 3;
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
out property <int> value: r2.value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
```cpp
|
||||
auto handle = TestCase::create();
|
||||
const TestCase &instance = *handle;
|
||||
assert_eq(instance.get_value(), 0);
|
||||
instance.global<Glob>().set_cond2(true);
|
||||
assert_eq(instance.get_value(), 1);
|
||||
instance.set_cond1(true);
|
||||
assert_eq(instance.get_value(), 3);
|
||||
```
|
||||
|
||||
|
||||
```rust
|
||||
let instance = TestCase::new().unwrap();
|
||||
assert_eq!(instance.get_value(), 0);
|
||||
instance.global::<Glob<'_>>().set_cond2(true);
|
||||
assert_eq!(instance.get_value(), 1);
|
||||
instance.set_cond1(true);
|
||||
assert_eq!(instance.get_value(), 3);
|
||||
```
|
||||
|
||||
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue