Skip to content

Commit d6397c4

Browse files
committed
feat(parser): add impl statement.
1 parent 6614827 commit d6397c4

File tree

12 files changed

+795
-5
lines changed

12 files changed

+795
-5
lines changed

crates/fuse-ast/src/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ pub enum ConstructionField {
423423
pub struct ImplStatement {
424424
pub span: Span,
425425
pub target: TypeAnnotation,
426-
pub r#trait: Option<()>,
426+
pub r#trait: Option<TypeAnnotation>,
427427
pub methods: Vec<ImplMethod>,
428428
}
429429

crates/fuse-parser/src/parsers/binding.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@ impl<'a> Parser<'a> {
3333
}
3434

3535
let identifier = self.parse_binding_identifier();
36-
Ok(self.ast.binding_identifier_pattern(identifier, None, false))
36+
let type_annotation = if self.consume_if(TokenKind::Colon).is_some() {
37+
Some(self.parse_type_annotation()?)
38+
} else {
39+
None
40+
};
41+
42+
Ok(self
43+
.ast
44+
.binding_identifier_pattern(identifier, type_annotation, false))
3745
}
3846

3947
pub(crate) fn parse_binding_identifier(&mut self) -> BindingIdentifier {

crates/fuse-parser/src/parsers/statements.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,18 @@ impl<'a> Parser<'a> {
9191
}
9292

9393
fn parse_impl_statement(&mut self) -> ParserResult<Statement> {
94-
debug_assert!(self.at(TokenKind::Trait));
94+
debug_assert!(self.at(TokenKind::Impl));
9595
let start = self.start_span();
9696
// Consume the struct keyword.
9797
self.consume();
9898

99-
let target = self.parse_type_annotation()?;
99+
let (target, r#trait) = {
100+
let first_type = self.parse_type_annotation()?;
101+
match self.consume_if(TokenKind::For) {
102+
Some(_) => (self.parse_type_annotation()?, Some(first_type)),
103+
None => (first_type, None),
104+
}
105+
};
100106
let mut methods: Vec<ImplMethod> = Vec::new();
101107
while !self.at(TokenKind::End) {
102108
let modifier = self.try_parse_visibility_modifier();
@@ -108,7 +114,7 @@ impl<'a> Parser<'a> {
108114
Ok(self.ast.impl_statement(ImplStatement {
109115
span: self.end_span(start),
110116
target,
111-
r#trait: None,
117+
r#trait,
112118
methods,
113119
}))
114120
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
source: crates/fuse-parser/tests/cases/mod.rs
3+
description: "impl Test\nend\n"
4+
expression: parsed.chunk
5+
input_file: crates/fuse-parser/tests/cases/pass/impl-statement-01/case.fuse
6+
---
7+
Some(Chunk(
8+
span: Span(
9+
start: 0,
10+
end: 14,
11+
),
12+
body: Block(
13+
statements: [
14+
ImplStatement(ImplStatement(
15+
span: Span(
16+
start: 0,
17+
end: 13,
18+
),
19+
target: TypeAnnotation(
20+
identifier: Identifier(
21+
span: Span(
22+
start: 5,
23+
end: 9,
24+
),
25+
name: Atom("Test"),
26+
),
27+
),
28+
trait: None,
29+
methods: [],
30+
)),
31+
],
32+
),
33+
))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
impl Test
2+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
source: crates/fuse-parser/tests/cases/mod.rs
3+
description: "impl Test\nend\n"
4+
expression: tokens
5+
input_file: crates/fuse-parser/tests/cases/pass/impl-statement-01/case.fuse
6+
---
7+
[
8+
TokenReference(
9+
token: Token(
10+
span: Span(
11+
start: 0,
12+
end: 4,
13+
),
14+
kind: Impl,
15+
),
16+
leading_trivia: [],
17+
trailing_trivia: [
18+
Token(
19+
span: Span(
20+
start: 4,
21+
end: 5,
22+
),
23+
kind: Whitespace,
24+
),
25+
],
26+
),
27+
TokenReference(
28+
token: Token(
29+
span: Span(
30+
start: 5,
31+
end: 9,
32+
),
33+
kind: Identifier,
34+
),
35+
leading_trivia: [],
36+
trailing_trivia: [
37+
Token(
38+
span: Span(
39+
start: 9,
40+
end: 10,
41+
),
42+
kind: Whitespace,
43+
),
44+
],
45+
),
46+
TokenReference(
47+
token: Token(
48+
span: Span(
49+
start: 10,
50+
end: 13,
51+
),
52+
kind: End,
53+
),
54+
leading_trivia: [],
55+
trailing_trivia: [
56+
Token(
57+
span: Span(
58+
start: 13,
59+
end: 14,
60+
),
61+
kind: Whitespace,
62+
),
63+
],
64+
),
65+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
source: crates/fuse-parser/tests/cases/mod.rs
3+
description: "impl Trait for Test\nend\n"
4+
expression: parsed.chunk
5+
input_file: crates/fuse-parser/tests/cases/pass/impl-statement-02/case.fuse
6+
---
7+
Some(Chunk(
8+
span: Span(
9+
start: 0,
10+
end: 24,
11+
),
12+
body: Block(
13+
statements: [
14+
ImplStatement(ImplStatement(
15+
span: Span(
16+
start: 0,
17+
end: 23,
18+
),
19+
target: TypeAnnotation(
20+
identifier: Identifier(
21+
span: Span(
22+
start: 15,
23+
end: 19,
24+
),
25+
name: Atom("Test"),
26+
),
27+
),
28+
trait: Some(TypeAnnotation(
29+
identifier: Identifier(
30+
span: Span(
31+
start: 5,
32+
end: 10,
33+
),
34+
name: Atom("Trait"),
35+
),
36+
)),
37+
methods: [],
38+
)),
39+
],
40+
),
41+
))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
impl Trait for Test
2+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
source: crates/fuse-parser/tests/cases/mod.rs
3+
description: "impl Trait for Test\nend\n"
4+
expression: tokens
5+
input_file: crates/fuse-parser/tests/cases/pass/impl-statement-02/case.fuse
6+
---
7+
[
8+
TokenReference(
9+
token: Token(
10+
span: Span(
11+
start: 0,
12+
end: 4,
13+
),
14+
kind: Impl,
15+
),
16+
leading_trivia: [],
17+
trailing_trivia: [
18+
Token(
19+
span: Span(
20+
start: 4,
21+
end: 5,
22+
),
23+
kind: Whitespace,
24+
),
25+
],
26+
),
27+
TokenReference(
28+
token: Token(
29+
span: Span(
30+
start: 5,
31+
end: 10,
32+
),
33+
kind: Identifier,
34+
),
35+
leading_trivia: [],
36+
trailing_trivia: [
37+
Token(
38+
span: Span(
39+
start: 10,
40+
end: 11,
41+
),
42+
kind: Whitespace,
43+
),
44+
],
45+
),
46+
TokenReference(
47+
token: Token(
48+
span: Span(
49+
start: 11,
50+
end: 14,
51+
),
52+
kind: For,
53+
),
54+
leading_trivia: [],
55+
trailing_trivia: [
56+
Token(
57+
span: Span(
58+
start: 14,
59+
end: 15,
60+
),
61+
kind: Whitespace,
62+
),
63+
],
64+
),
65+
TokenReference(
66+
token: Token(
67+
span: Span(
68+
start: 15,
69+
end: 19,
70+
),
71+
kind: Identifier,
72+
),
73+
leading_trivia: [],
74+
trailing_trivia: [
75+
Token(
76+
span: Span(
77+
start: 19,
78+
end: 20,
79+
),
80+
kind: Whitespace,
81+
),
82+
],
83+
),
84+
TokenReference(
85+
token: Token(
86+
span: Span(
87+
start: 20,
88+
end: 23,
89+
),
90+
kind: End,
91+
),
92+
leading_trivia: [],
93+
trailing_trivia: [
94+
Token(
95+
span: Span(
96+
start: 23,
97+
end: 24,
98+
),
99+
kind: Whitespace,
100+
),
101+
],
102+
),
103+
]

0 commit comments

Comments
 (0)