1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Struct parsing — extracted from item_parser.rs
use crate::lexer::Token;
use crate::parser::ast::*;
use crate::parser_impl::Parser;
impl Parser {
pub(crate) fn parse_struct(&mut self, is_extern: bool) -> Result<StructDecl<'static>, String> {
// Token::Struct already consumed in parse_item
let name = if let Token::Ident(n) = self.current_token() {
let name = n.clone();
self.advance();
name
} else {
return Err("Expected struct name".to_string());
};
// Parse type parameters: struct Box<T> { ... }
let type_params = self.parse_type_params()?;
// Parse where clause (optional): where T: Clone, U: Debug
let where_clause = self.parse_where_clause()?;
// Check for tuple struct: struct Name(T1, T2)
if self.current_token() == &Token::LParen {
self.advance(); // consume '('
let mut tuple_types = Vec::new();
while self.current_token() != &Token::RParen {
let is_pub = if self.current_token() == &Token::Pub {
self.advance();
true
} else {
false
};
let _ = is_pub; // visibility tracked but not used in tuple field types
let field_type = self.parse_type()?;
tuple_types.push(field_type);
if self.current_token() == &Token::Comma {
self.advance();
}
}
self.expect(Token::RParen)?;
return Ok(StructDecl {
name,
is_pub: false,
is_extern,
type_params,
where_clause,
fields: Vec::new(),
tuple_fields: Some(tuple_types),
decorators: Vec::new(),
doc_comment: None,
});
}
// Check for unit struct: struct Name;
let fields = if self.current_token() == &Token::Semicolon {
// Unit struct with no fields
self.advance(); // consume semicolon
Vec::new()
} else {
// Regular struct with fields
self.expect(Token::LBrace)?;
let mut fields = Vec::new();
while self.current_token() != &Token::RBrace {
// Collect doc comment for field (if any)
let field_doc_comment = if let Token::DocComment(comment) = self.current_token() {
let doc = comment.clone();
self.advance();
Some(doc)
} else {
None
};
// Parse decorators on fields
let mut field_decorators = Vec::new();
while let Token::Decorator(_dec_name) = self.current_token() {
let decorator = self.parse_decorator()?;
field_decorators.push(decorator);
}
// Parse pub keyword for fields
let is_pub = if self.current_token() == &Token::Pub {
self.advance();
true
} else {
false
};
let field_name = if let Token::Ident(n) = self.current_token() {
let name = n.clone();
self.advance();
name
} else {
return Err("Expected field name".to_string());
};
self.expect(Token::Colon)?;
let field_type = self.parse_type()?;
fields.push(StructField {
name: field_name,
field_type,
decorators: field_decorators,
is_pub,
doc_comment: field_doc_comment,
});
if self.current_token() == &Token::Comma {
self.advance();
}
}
self.expect(Token::RBrace)?;
fields
};
Ok(StructDecl {
name,
is_pub: false, // Will be set by parse_item() if pub keyword present
is_extern,
type_params,
where_clause,
fields,
tuple_fields: None,
decorators: Vec::new(),
doc_comment: None, // Set by parse_item if doc comments present
})
}
}