blob: 045840059ad770925b52c82c195d451b07f37073 (
plain)
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
|
use super::*;
pub(super) fn inner_attributes(p: &mut Parser) {
while p.at([POUND, EXCL]) {
attribute(p, true)
}
}
pub(super) fn outer_attributes(p: &mut Parser) {
while p.at(POUND) {
attribute(p, false)
}
}
fn attribute(p: &mut Parser, inner: bool){
let attr = p.start();
assert!(p.at(POUND));
p.bump();
if inner {
assert!(p.at(EXCL));
p.bump();
}
if p.expect(L_BRACK) {
meta_item(p);
p.expect(R_BRACK);
}
attr.complete(p, ATTR);
}
fn meta_item(p: &mut Parser) {
if p.at(IDENT) {
let meta_item = p.start();
p.bump();
match p.current() {
EQ => {
p.bump();
if !expressions::literal(p) {
p.error()
.message("expected literal")
.emit();
}
}
L_PAREN => meta_item_arg_list(p),
_ => (),
}
meta_item.complete(p, META_ITEM);
} else {
p.error()
.message("expected attribute value")
.emit()
}
}
fn meta_item_arg_list(p: &mut Parser) {
assert!(p.at(L_PAREN));
p.bump();
loop {
match p.current() {
EOF | R_PAREN => break,
IDENT => meta_item(p),
c => if !expressions::literal(p) {
let message = "expected attribute";
if items::ITEM_FIRST.contains(c) {
p.error().message(message).emit();
return;
}
let err = p.start();
p.error().message(message).emit();
p.bump();
err.complete(p, ERROR);
continue
}
}
if !p.at(R_PAREN) {
p.expect(COMMA);
}
}
p.expect(R_PAREN);
}
|