mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 14:51:15 +00:00
Allow to give a name to for
and if
This commit is contained in:
parent
52e85933ed
commit
42c25248a8
8 changed files with 121 additions and 49 deletions
|
@ -728,26 +728,14 @@ impl Element {
|
|||
|
||||
for se in node.children() {
|
||||
if se.kind() == SyntaxKind::SubElement {
|
||||
let id = identifier_text(&se).unwrap_or_default();
|
||||
if matches!(id.as_ref(), "parent" | "self" | "root") {
|
||||
diag.push_error(
|
||||
format!("'{}' is a reserved id", id),
|
||||
&se.child_token(SyntaxKind::Identifier).unwrap(),
|
||||
)
|
||||
}
|
||||
if let Some(element_node) = se.child_node(SyntaxKind::Element) {
|
||||
let parent_type = r.borrow().base_type.clone();
|
||||
r.borrow_mut().children.push(Element::from_node(
|
||||
element_node.into(),
|
||||
id,
|
||||
parent_type,
|
||||
component_child_insertion_point,
|
||||
diag,
|
||||
tr,
|
||||
));
|
||||
} else {
|
||||
assert!(diag.has_error());
|
||||
}
|
||||
let parent_type = r.borrow().base_type.clone();
|
||||
r.borrow_mut().children.push(Element::from_sub_element_node(
|
||||
se.into(),
|
||||
parent_type,
|
||||
component_child_insertion_point,
|
||||
diag,
|
||||
tr,
|
||||
));
|
||||
} else if se.kind() == SyntaxKind::RepeatedElement {
|
||||
let rep = Element::from_repeated_node(
|
||||
se.into(),
|
||||
|
@ -832,6 +820,30 @@ impl Element {
|
|||
r
|
||||
}
|
||||
|
||||
fn from_sub_element_node(
|
||||
node: syntax_nodes::SubElement,
|
||||
parent_type: Type,
|
||||
component_child_insertion_point: &mut Option<ChildrenInsertionPoint>,
|
||||
diag: &mut BuildDiagnostics,
|
||||
tr: &TypeRegister,
|
||||
) -> ElementRc {
|
||||
let id = identifier_text(&node).unwrap_or_default();
|
||||
if matches!(id.as_ref(), "parent" | "self" | "root") {
|
||||
diag.push_error(
|
||||
format!("'{}' is a reserved id", id),
|
||||
&node.child_token(SyntaxKind::Identifier).unwrap(),
|
||||
)
|
||||
}
|
||||
Element::from_node(
|
||||
node.Element(),
|
||||
id,
|
||||
parent_type,
|
||||
component_child_insertion_point,
|
||||
diag,
|
||||
tr,
|
||||
)
|
||||
}
|
||||
|
||||
fn from_repeated_node(
|
||||
node: syntax_nodes::RepeatedElement,
|
||||
parent: &ElementRc,
|
||||
|
@ -860,10 +872,9 @@ impl Element {
|
|||
is_conditional_element: false,
|
||||
is_listview,
|
||||
};
|
||||
let e = Element::from_node(
|
||||
node.Element(),
|
||||
String::new(),
|
||||
parent.borrow().base_type.to_owned(),
|
||||
let e = Element::from_sub_element_node(
|
||||
node.SubElement(),
|
||||
parent.borrow().base_type.clone(),
|
||||
component_child_insertion_point,
|
||||
diag,
|
||||
tr,
|
||||
|
@ -886,9 +897,8 @@ impl Element {
|
|||
is_conditional_element: true,
|
||||
is_listview: None,
|
||||
};
|
||||
let e = Element::from_node(
|
||||
node.Element(),
|
||||
String::new(),
|
||||
let e = Element::from_sub_element_node(
|
||||
node.SubElement(),
|
||||
parent_type,
|
||||
component_child_insertion_point,
|
||||
diag,
|
||||
|
|
|
@ -323,9 +323,9 @@ declare_syntax! {
|
|||
Element -> [ ?QualifiedName, *PropertyDeclaration, *Binding, *CallbackConnection,
|
||||
*CallbackDeclaration, *SubElement, *RepeatedElement, *PropertyAnimation,
|
||||
*TwoWayBinding, *States, *Transitions, ?ChildrenPlaceholder ],
|
||||
RepeatedElement -> [ ?DeclaredIdentifier, ?RepeatedIndex, Expression , Element],
|
||||
RepeatedElement -> [ ?DeclaredIdentifier, ?RepeatedIndex, Expression , SubElement],
|
||||
RepeatedIndex -> [],
|
||||
ConditionalElement -> [ Expression , Element],
|
||||
ConditionalElement -> [ Expression , SubElement],
|
||||
CallbackDeclaration -> [ DeclaredIdentifier, *Type, ?ReturnType, ?TwoWayBinding ],
|
||||
/// `-> type` (but without the ->)
|
||||
ReturnType -> [Type],
|
||||
|
|
|
@ -125,7 +125,7 @@ pub fn parse_element_content(p: &mut impl Parser) {
|
|||
fn parse_sub_element(p: &mut impl Parser) {
|
||||
let mut p = p.start_node(SyntaxKind::SubElement);
|
||||
if p.nth(1).kind() == SyntaxKind::ColonEqual {
|
||||
assert!(p.expect(SyntaxKind::Identifier));
|
||||
p.expect(SyntaxKind::Identifier);
|
||||
p.expect(SyntaxKind::ColonEqual);
|
||||
}
|
||||
parse_element(&mut *p);
|
||||
|
@ -136,6 +136,7 @@ fn parse_sub_element(p: &mut impl Parser) {
|
|||
/// for xx in mm: Elem { }
|
||||
/// for [idx] in mm: Elem { }
|
||||
/// for xx [idx] in foo.bar: Elem { }
|
||||
/// for _ in (xxx()): blah := Elem { Elem{} }
|
||||
/// ```
|
||||
/// Must consume at least one token
|
||||
fn parse_repeated_element(p: &mut impl Parser) {
|
||||
|
@ -155,19 +156,20 @@ fn parse_repeated_element(p: &mut impl Parser) {
|
|||
if p.peek().as_str() != "in" {
|
||||
p.error("Invalid 'for' syntax: there should be a 'in' token");
|
||||
drop(p.start_node(SyntaxKind::Expression));
|
||||
drop(p.start_node(SyntaxKind::Element));
|
||||
drop(p.start_node(SyntaxKind::SubElement).start_node(SyntaxKind::Element));
|
||||
return;
|
||||
}
|
||||
p.consume(); // "in"
|
||||
parse_expression(&mut *p);
|
||||
p.expect(SyntaxKind::Colon);
|
||||
parse_element(&mut *p);
|
||||
parse_sub_element(&mut *p);
|
||||
}
|
||||
|
||||
#[cfg_attr(test, parser_test)]
|
||||
/// ```test,ConditionalElement
|
||||
/// if (condition) : Elem { }
|
||||
/// if (foo ? bar : xx) : Elem { foo:bar; Elem {}}
|
||||
/// if (true) : foo := Elem {}
|
||||
/// ```
|
||||
/// Must consume at least one token
|
||||
fn parse_if_element(p: &mut impl Parser) {
|
||||
|
@ -176,15 +178,15 @@ fn parse_if_element(p: &mut impl Parser) {
|
|||
p.consume(); // "if"
|
||||
if !p.expect(SyntaxKind::LParent) {
|
||||
drop(p.start_node(SyntaxKind::Expression));
|
||||
drop(p.start_node(SyntaxKind::Element));
|
||||
drop(p.start_node(SyntaxKind::SubElement).start_node(SyntaxKind::Element));
|
||||
return;
|
||||
}
|
||||
parse_expression(&mut *p);
|
||||
if !p.expect(SyntaxKind::RParent) || !p.expect(SyntaxKind::Colon) {
|
||||
drop(p.start_node(SyntaxKind::Element));
|
||||
drop(p.start_node(SyntaxKind::SubElement).start_node(SyntaxKind::Element));
|
||||
return;
|
||||
}
|
||||
parse_element(&mut *p);
|
||||
parse_sub_element(&mut *p);
|
||||
}
|
||||
|
||||
#[cfg_attr(test, parser_test)]
|
||||
|
|
|
@ -29,5 +29,12 @@ SubElements := Rectangle {
|
|||
self := Rectangle {}
|
||||
// ^error{'self' is a reserved id}
|
||||
}
|
||||
|
||||
if (true) : root := Rectangle {
|
||||
// ^error{'root' is a reserved id}
|
||||
|
||||
for _ in 1 : self := Rectangle { }
|
||||
// ^error{'self' is a reserved id}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,16 @@ Hello := Rectangle {
|
|||
// ^error{Cannot access id 'ccc'}
|
||||
}
|
||||
|
||||
Text { text: ccc.text; }
|
||||
// ^error{Cannot access id 'ccc'}
|
||||
for plop in 0 : named_for := Rectangle {
|
||||
Text { color: named_for.background; }
|
||||
}
|
||||
|
||||
Text {
|
||||
text: ccc.text;
|
||||
// ^error{Cannot access id 'ccc'}
|
||||
color: named_for.background;
|
||||
// ^error{Cannot access id 'named_for'}
|
||||
}
|
||||
|
||||
for aaa in aaa.text: Rectangle {
|
||||
// ^error{Cannot convert string to model}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue