Skip to content

Commit c6320d8

Browse files
committed
Lex doc comments as attributes
This means they no longer round trip but it should be more faithful to what macro_rules! is doing Closes #73
1 parent 99d9630 commit c6320d8

File tree

3 files changed

+61
-58
lines changed

3 files changed

+61
-58
lines changed

src/stable.rs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -591,10 +591,32 @@ impl fmt::Display for Literal {
591591
}
592592
}
593593

594-
named!(token_stream -> ::TokenStream, map!(
595-
many0!(token_tree),
596-
|trees| ::TokenStream::_new(TokenStream { inner: trees })
597-
));
594+
fn token_stream(mut input: Cursor) -> PResult<::TokenStream> {
595+
let mut trees = Vec::new();
596+
loop {
597+
let input_no_ws = skip_whitespace(input);
598+
if input_no_ws.rest.len() == 0 {
599+
break
600+
}
601+
if let Ok((a, comment)) = doc_comment(input_no_ws) {
602+
input = a;
603+
trees.push(TokenTree::Op(Op::new('#', Spacing::Alone)));
604+
let stream = vec![
605+
TokenTree::Term(::Term::new("doc", ::Span::call_site())),
606+
TokenTree::Op(Op::new('=', Spacing::Alone)),
607+
TokenTree::Literal(::Literal::string(comment)),
608+
];
609+
let stream = stream.into_iter().collect();
610+
trees.push(TokenTree::Group(Group::new(Delimiter::Bracket, stream)));
611+
continue
612+
}
613+
614+
let (a, tt) = token_tree(input_no_ws)?;
615+
trees.push(tt);
616+
input = a;
617+
}
618+
Ok((input, ::TokenStream::_new(TokenStream { inner: trees })))
619+
}
598620

599621
#[cfg(not(procmacro2_semver_exempt))]
600622
fn token_tree(input: Cursor) -> PResult<TokenTree> {
@@ -721,8 +743,6 @@ named!(literal_nocapture -> (), alt!(
721743
float
722744
|
723745
int
724-
|
725-
doc_comment
726746
));
727747

728748
named!(string -> (), alt!(
@@ -1146,31 +1166,31 @@ fn op_char(input: Cursor) -> PResult<char> {
11461166
}
11471167
}
11481168

1149-
named!(doc_comment -> (), alt!(
1169+
named!(doc_comment -> &str, alt!(
11501170
do_parse!(
11511171
punct!("//!") >>
1152-
take_until_newline_or_eof!() >>
1153-
(())
1172+
s: take_until_newline_or_eof!() >>
1173+
(s)
11541174
)
11551175
|
11561176
do_parse!(
11571177
option!(whitespace) >>
11581178
peek!(tag!("/*!")) >>
1159-
block_comment >>
1160-
(())
1179+
s: block_comment >>
1180+
(s)
11611181
)
11621182
|
11631183
do_parse!(
11641184
punct!("///") >>
11651185
not!(tag!("/")) >>
1166-
take_until_newline_or_eof!() >>
1167-
(())
1186+
s: take_until_newline_or_eof!() >>
1187+
(s)
11681188
)
11691189
|
11701190
do_parse!(
11711191
option!(whitespace) >>
11721192
peek!(tuple!(tag!("/**"), not!(tag!("*")))) >>
1173-
block_comment >>
1174-
(())
1193+
s: block_comment >>
1194+
(s)
11751195
)
11761196
));

src/strnom.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ macro_rules! take_until_newline_or_eof {
268268
} else {
269269
match $i.find('\n') {
270270
Some(i) => Ok(($i.advance(i), &$i.rest[..i])),
271-
None => Ok(($i.advance($i.len()), "")),
271+
None => Ok(($i.advance($i.len()), &$i.rest[..$i.len()])),
272272
}
273273
}
274274
}};
@@ -389,37 +389,3 @@ macro_rules! map {
389389
map!($i, call!($f), $g)
390390
};
391391
}
392-
393-
macro_rules! many0 {
394-
($i:expr, $f:expr) => {{
395-
let ret;
396-
let mut res = ::std::vec::Vec::new();
397-
let mut input = $i;
398-
399-
loop {
400-
if input.is_empty() {
401-
ret = Ok((input, res));
402-
break;
403-
}
404-
405-
match $f(input) {
406-
Err(LexError) => {
407-
ret = Ok((input, res));
408-
break;
409-
}
410-
Ok((i, o)) => {
411-
// loop trip must always consume (otherwise infinite loops)
412-
if i.len() == input.len() {
413-
ret = Err(LexError);
414-
break;
415-
}
416-
417-
res.push(o);
418-
input = i;
419-
}
420-
}
421-
}
422-
423-
ret
424-
}};
425-
}

tests/test.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ fn roundtrip() {
2929
roundtrip("a");
3030
roundtrip("<<");
3131
roundtrip("<<=");
32-
roundtrip(
33-
"
34-
/// a
35-
wut
36-
",
37-
);
3832
roundtrip(
3933
"
4034
1
@@ -192,11 +186,34 @@ fn tricky_doc_comment() {
192186

193187
let stream = "/// doc".parse::<proc_macro2::TokenStream>().unwrap();
194188
let tokens = stream.into_iter().collect::<Vec<_>>();
195-
assert!(tokens.len() == 1, "not length 1 -- {:?}", tokens);
189+
assert!(tokens.len() == 2, "not length 1 -- {:?}", tokens);
196190
match tokens[0] {
197-
proc_macro2::TokenTree::Literal(_) => {}
191+
proc_macro2::TokenTree::Op(ref tt) => assert_eq!(tt.op(), '#'),
198192
_ => panic!("wrong token {:?}", tokens[0]),
199193
}
194+
let mut tokens = match tokens[1] {
195+
proc_macro2::TokenTree::Group(ref tt) => {
196+
assert_eq!(tt.delimiter(), proc_macro2::Delimiter::Bracket);
197+
tt.stream().into_iter()
198+
}
199+
_ => panic!("wrong token {:?}", tokens[0]),
200+
};
201+
202+
match tokens.next().unwrap() {
203+
proc_macro2::TokenTree::Term(ref tt) => assert_eq!(tt.as_str(), "doc"),
204+
t => panic!("wrong token {:?}", t),
205+
}
206+
match tokens.next().unwrap() {
207+
proc_macro2::TokenTree::Op(ref tt) => assert_eq!(tt.op(), '='),
208+
t => panic!("wrong token {:?}", t),
209+
}
210+
match tokens.next().unwrap() {
211+
proc_macro2::TokenTree::Literal(ref tt) => {
212+
assert_eq!(tt.to_string(), "\" doc\"");
213+
}
214+
t => panic!("wrong token {:?}", t),
215+
}
216+
assert!(tokens.next().is_none());
200217
}
201218

202219
#[test]

0 commit comments

Comments
 (0)