i_slint_compiler/parser/
type.rs1use super::document::parse_qualified_name;
7use super::expressions::parse_expression;
8use super::prelude::*;
9
10#[cfg_attr(test, parser_test)]
11pub fn parse_type(p: &mut impl Parser) {
17 let mut p = p.start_node(SyntaxKind::Type);
18 match p.nth(0).kind() {
19 SyntaxKind::LBrace => parse_type_object(&mut *p),
20 SyntaxKind::LBracket => parse_type_array(&mut *p),
21 _ => {
22 parse_qualified_name(&mut *p);
23 }
24 }
25}
26
27#[cfg_attr(test, parser_test)]
28pub fn parse_type_object(p: &mut impl Parser) {
38 let mut p = p.start_node(SyntaxKind::ObjectType);
39 if !p.expect(SyntaxKind::LBrace) {
40 return;
41 }
42 while p.nth(0).kind() != SyntaxKind::RBrace {
43 let mut p = p.start_node(SyntaxKind::ObjectTypeMember);
44 p.expect(SyntaxKind::Identifier);
45 p.expect(SyntaxKind::Colon);
46 parse_type(&mut *p);
47 if p.test(SyntaxKind::Equal) {
48 parse_expression(&mut *p);
49 }
50 if p.peek().kind() == SyntaxKind::Semicolon {
51 p.error("Expected ','. Use ',' instead of ';' to separate fields in a struct");
52 p.consume();
53 continue;
54 }
55 if !p.test(SyntaxKind::Comma) {
56 break;
57 }
58 }
59 p.expect(SyntaxKind::RBrace);
60}
61
62#[cfg_attr(test, parser_test)]
63pub fn parse_type_array(p: &mut impl Parser) {
69 let mut p = p.start_node(SyntaxKind::ArrayType);
70 p.expect(SyntaxKind::LBracket);
71 parse_type(&mut *p);
72 p.expect(SyntaxKind::RBracket);
73}
74
75#[cfg_attr(test, parser_test)]
76pub fn parse_struct_declaration<P: Parser>(p: &mut P, checkpoint: Option<P::Checkpoint>) -> bool {
84 debug_assert_eq!(p.peek().as_str(), "struct");
85 let mut p = p.start_node_at(checkpoint, SyntaxKind::StructDeclaration);
86 p.consume(); {
88 let mut p = p.start_node(SyntaxKind::DeclaredIdentifier);
89 p.expect(SyntaxKind::Identifier);
90 }
91
92 if p.peek().kind() == SyntaxKind::ColonEqual {
93 p.warning("':=' to declare a struct is deprecated. Remove the ':='");
94 p.consume();
95 }
96
97 parse_type_object(&mut *p);
98 true
99}
100
101#[cfg_attr(test, parser_test)]
102pub fn parse_enum_declaration<P: Parser>(p: &mut P, checkpoint: Option<P::Checkpoint>) -> bool {
108 debug_assert_eq!(p.peek().as_str(), "enum");
109 let mut p = p.start_node_at(checkpoint, SyntaxKind::EnumDeclaration);
110 p.consume(); {
112 let mut p = p.start_node(SyntaxKind::DeclaredIdentifier);
113 p.expect(SyntaxKind::Identifier);
114 }
115
116 if !p.expect(SyntaxKind::LBrace) {
117 return false;
118 }
119 while p.nth(0).kind() != SyntaxKind::RBrace {
120 {
121 let mut p = p.start_node(SyntaxKind::EnumValue);
122 p.expect(SyntaxKind::Identifier);
123 }
124 if !p.test(SyntaxKind::Comma) {
125 break;
126 }
127 }
128 p.expect(SyntaxKind::RBrace);
129 true
130}
131
132pub fn parse_rustattr(p: &mut impl Parser) -> bool {
137 debug_assert_eq!(p.peek().as_str(), "@");
138 p.consume(); if p.peek().as_str() != "rust-attr" {
140 p.expect(SyntaxKind::AtRustAttr);
141 }
142 p.consume(); p.expect(SyntaxKind::LParent);
144 {
145 let mut p = p.start_node(SyntaxKind::AtRustAttr);
146 let mut level = 1;
147 loop {
148 match p.peek().kind() {
149 SyntaxKind::LParent => level += 1,
150 SyntaxKind::RParent => {
151 level -= 1;
152 if level == 0 {
153 break;
154 }
155 }
156 SyntaxKind::Eof => {
157 p.error("unmatched parentheses in @rust-attr");
158 return false;
159 }
160 _ => {}
161 }
162 p.consume()
163 }
164 }
165 p.expect(SyntaxKind::RParent)
166}