forked from argotorg/fe
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstruct_.rs
More file actions
118 lines (101 loc) · 3.84 KB
/
Copy pathstruct_.rs
File metadata and controls
118 lines (101 loc) · 3.84 KB
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
use crate::{ExpectedKind, SyntaxKind};
use super::{
ErrProof, Parser, Recovery,
attr::parse_attr_list,
define_scope,
func::FuncScope,
item::parse_vis_restriction,
param::{parse_generic_params_opt, parse_where_clause_opt},
parse_list,
token_stream::TokenStream,
type_::parse_type,
};
define_scope! { pub(crate) StructScope, Struct }
impl super::Parse for StructScope {
type Error = Recovery<ErrProof>;
fn parse<S: TokenStream>(&mut self, parser: &mut Parser<S>) -> Result<(), Self::Error> {
parser.bump_expected(SyntaxKind::StructKw);
parser.set_scope_recovery_stack(&[
SyntaxKind::Ident,
SyntaxKind::Lt,
SyntaxKind::WhereKw,
SyntaxKind::LBrace,
]);
if parser.find_and_pop(SyntaxKind::Ident, ExpectedKind::Name(SyntaxKind::Struct))? {
parser.bump();
}
parser.expect_and_pop_recovery_stack()?;
parse_generic_params_opt(parser, false)?;
parser.expect_and_pop_recovery_stack()?;
parse_where_clause_opt(parser)?;
if parser.find_and_pop(SyntaxKind::LBrace, ExpectedKind::Body(SyntaxKind::Struct))? {
parser.parse(RecordFieldDefListScope::default())?;
}
Ok(())
}
}
define_scope! {
pub(crate) RecordFieldDefListScope,
RecordFieldDefList,
(RBrace, Comma, Newline)
}
impl super::Parse for RecordFieldDefListScope {
type Error = Recovery<ErrProof>;
fn parse<S: TokenStream>(&mut self, parser: &mut Parser<S>) -> Result<(), Self::Error> {
parse_list(
parser,
true,
SyntaxKind::RecordFieldDefList,
(SyntaxKind::LBrace, SyntaxKind::RBrace),
|parser| parser.parse(RecordFieldDefScope::default()),
)
}
}
define_scope! { pub(crate) RecordFieldDefScope, RecordFieldDef }
impl super::Parse for RecordFieldDefScope {
type Error = Recovery<ErrProof>;
fn parse<S: TokenStream>(&mut self, parser: &mut Parser<S>) -> Result<(), Self::Error> {
parser.set_newline_as_trivia(false);
parse_attr_list(parser)?;
if parser.bump_if(SyntaxKind::PubKw) {
// Check for visibility restriction: pub(ingot), pub(super), pub(in path)
if parser.current_kind() == Some(SyntaxKind::LParen) {
parser.bump(); // (
parse_vis_restriction(parser);
}
}
// Since the Fe-V2 doesn't support method definition in a struct, we add an
// ad-hoc check for the method definition in a struct to avoid the confusing
// error message.
// The reason that justifies this ad-hoc check is
// 1. This error is difficult to recover properly with the current parser
// design, and the emitted error message is confusing.
// 2. We anticipate that this error would happen often in the transition period
// to Fe-V2.
if parser.current_kind() == Some(SyntaxKind::FnKw) {
parser.error_msg_on_current_token("function definition in struct is not allowed");
let checkpoint = parser.enter(super::ErrorScope::new(), None);
let result = parser.parse(FuncScope::default());
parser.leave(checkpoint);
result?;
return Ok(());
}
parser.set_scope_recovery_stack(&[SyntaxKind::Colon]);
// Optional `mut` marker for fields (e.g. `mut field: Type`)
parser.bump_if(SyntaxKind::MutKw);
if parser.find(
SyntaxKind::Ident,
ExpectedKind::Name(SyntaxKind::RecordField),
)? {
parser.bump();
}
if parser.find(
SyntaxKind::Colon,
ExpectedKind::TypeSpecifier(SyntaxKind::RecordField),
)? {
parser.bump();
parse_type(parser, None).map(|_| ())?;
}
Ok(())
}
}