i_slint_compiler/parser/
type.rs1use super::document::parse_qualified_name;
7use super::prelude::*;
8
9#[cfg_attr(test, parser_test)]
10pub fn parse_type(p: &mut impl Parser) {
16 let mut p = p.start_node(SyntaxKind::Type);
17 match p.nth(0).kind() {
18 SyntaxKind::LBrace => parse_type_object(&mut *p),
19 SyntaxKind::LBracket => parse_type_array(&mut *p),
20 _ => {
21 parse_qualified_name(&mut *p);
22 }
23 }
24}
25
26#[cfg_attr(test, parser_test)]
27pub fn parse_type_object(p: &mut impl Parser) {
35 let mut p = p.start_node(SyntaxKind::ObjectType);
36 if !p.expect(SyntaxKind::LBrace) {
37 return;
38 }
39 while p.nth(0).kind() != SyntaxKind::RBrace {
40 let mut p = p.start_node(SyntaxKind::ObjectTypeMember);
41 p.expect(SyntaxKind::Identifier);
42 p.expect(SyntaxKind::Colon);
43 parse_type(&mut *p);
44 if p.peek().kind() == SyntaxKind::Semicolon {
45 p.error("Expected ','. Use ',' instead of ';' to separate fields in a struct");
46 p.consume();
47 continue;
48 }
49 if !p.test(SyntaxKind::Comma) {
50 break;
51 }
52 }
53 p.expect(SyntaxKind::RBrace);
54}
55
56#[cfg_attr(test, parser_test)]
57pub fn parse_type_array(p: &mut impl Parser) {
63 let mut p = p.start_node(SyntaxKind::ArrayType);
64 p.expect(SyntaxKind::LBracket);
65 parse_type(&mut *p);
66 p.expect(SyntaxKind::RBracket);
67}
68
69#[cfg_attr(test, parser_test)]
70pub fn parse_struct_declaration<P: Parser>(p: &mut P, checkpoint: Option<P::Checkpoint>) -> bool {
77 debug_assert_eq!(p.peek().as_str(), "struct");
78 let mut p = p.start_node_at(checkpoint, SyntaxKind::StructDeclaration);
79 p.consume(); {
81 let mut p = p.start_node(SyntaxKind::DeclaredIdentifier);
82 p.expect(SyntaxKind::Identifier);
83 }
84
85 if p.peek().kind() == SyntaxKind::ColonEqual {
86 p.warning("':=' to declare a struct is deprecated. Remove the ':='");
87 p.consume();
88 }
89
90 parse_type_object(&mut *p);
91 true
92}
93
94#[cfg_attr(test, parser_test)]
95pub fn parse_enum_declaration<P: Parser>(p: &mut P, checkpoint: Option<P::Checkpoint>) -> bool {
101 debug_assert_eq!(p.peek().as_str(), "enum");
102 let mut p = p.start_node_at(checkpoint, SyntaxKind::EnumDeclaration);
103 p.consume(); {
105 let mut p = p.start_node(SyntaxKind::DeclaredIdentifier);
106 p.expect(SyntaxKind::Identifier);
107 }
108
109 if !p.expect(SyntaxKind::LBrace) {
110 return false;
111 }
112 while p.nth(0).kind() != SyntaxKind::RBrace {
113 {
114 let mut p = p.start_node(SyntaxKind::EnumValue);
115 p.expect(SyntaxKind::Identifier);
116 }
117 if !p.test(SyntaxKind::Comma) {
118 break;
119 }
120 }
121 p.expect(SyntaxKind::RBrace);
122 true
123}
124
125pub fn parse_rustattr(p: &mut impl Parser) -> bool {
130 debug_assert_eq!(p.peek().as_str(), "@");
131 p.consume(); if p.peek().as_str() != "rust-attr" {
133 p.expect(SyntaxKind::AtRustAttr);
134 }
135 p.consume(); p.expect(SyntaxKind::LParent);
137 {
138 let mut p = p.start_node(SyntaxKind::AtRustAttr);
139 let mut level = 1;
140 loop {
141 match p.peek().kind() {
142 SyntaxKind::LParent => level += 1,
143 SyntaxKind::RParent => {
144 level -= 1;
145 if level == 0 {
146 break;
147 }
148 }
149 SyntaxKind::Eof => {
150 p.error("unmatched parentheses in @rust-attr");
151 return false;
152 }
153 _ => {}
154 }
155 p.consume()
156 }
157 }
158 p.expect(SyntaxKind::RParent)
159}