Skip to content

Commit 96a83b5

Browse files
committed
Add some doc comments and factor out add_repeat and add_delimited
1 parent 0fd174d commit 96a83b5

File tree

1 file changed

+91
-57
lines changed

1 file changed

+91
-57
lines changed

src/macros.rs

Lines changed: 91 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -465,15 +465,25 @@ fn replace_names(input: &str) -> Option<(String, HashMap<String, String>)> {
465465

466466
#[derive(Debug, Clone)]
467467
enum MacroArgKind {
468+
/// e.g. `$x: expr`.
468469
MetaVariable(ast::Ident, String),
470+
/// e.g. `$($foo: expr),*`
469471
Repeat(
472+
/// `()`, `[]` or `{}`.
470473
DelimToken,
474+
/// Inner arguments inside delimiters.
471475
Vec<ParsedMacroArg>,
476+
/// Something after the closing delimiter and the repeat token, if available.
472477
Option<Box<ParsedMacroArg>>,
478+
/// The repeat token. This could be one of `*`, `+` or `?`.
473479
Token,
474480
),
481+
/// e.g. `[derive(Debug)]`
475482
Delimited(DelimToken, Vec<ParsedMacroArg>),
483+
/// A possible separator. e.g. `,` or `;`.
476484
Separator(String, String),
485+
/// Other random stuff that does not fit to other kinds.
486+
/// e.g. `== foo` in `($x: expr == foo)`.
477487
Other(String, String),
478488
}
479489

@@ -589,13 +599,21 @@ impl ParsedMacroArg {
589599
}
590600
}
591601

602+
/// Parses macro arguments on macro def.
592603
struct MacroArgParser {
604+
/// Holds either a name of the next metavariable, a separator or a junk.
605+
buf: String,
606+
/// The start position on the current buffer.
593607
lo: BytePos,
608+
/// The first token of the current buffer.
609+
start_tok: Token,
610+
/// Set to true if we are parsing a metavariable or a repeat.
611+
is_meta_var: bool,
612+
/// The position of the last token.
594613
hi: BytePos,
595-
buf: String,
596-
is_arg: bool,
614+
/// The last token parsed.
597615
last_tok: Token,
598-
start_tok: Token,
616+
/// Holds the parsed arguments.
599617
result: Vec<ParsedMacroArg>,
600618
}
601619

@@ -612,7 +630,7 @@ impl MacroArgParser {
612630
lo: BytePos(0),
613631
hi: BytePos(0),
614632
buf: String::new(),
615-
is_arg: false,
633+
is_meta_var: false,
616634
last_tok: Token::Eof,
617635
start_tok: Token::Eof,
618636
result: vec![],
@@ -659,12 +677,70 @@ impl MacroArgParser {
659677
});
660678

661679
self.buf.clear();
662-
self.is_arg = false;
680+
self.is_meta_var = false;
663681
}
664682
_ => unreachable!(),
665683
}
666684
}
667685

686+
fn add_delimited(&mut self, inner: Vec<ParsedMacroArg>, delim: DelimToken, span: Span) {
687+
self.result.push(ParsedMacroArg {
688+
kind: MacroArgKind::Delimited(delim, inner),
689+
span,
690+
});
691+
}
692+
693+
// $($foo: expr),?
694+
fn add_repeat(
695+
&mut self,
696+
inner: Vec<ParsedMacroArg>,
697+
delim: DelimToken,
698+
iter: &mut Cursor,
699+
span: Span,
700+
) {
701+
let mut buffer = String::new();
702+
let mut first = false;
703+
let mut lo = span.lo();
704+
let mut hi = span.hi();
705+
706+
// Parse '*', '+' or '?.
707+
while let Some(ref tok) = iter.next() {
708+
self.set_last_tok(tok);
709+
if first {
710+
first = false;
711+
lo = tok.span().lo();
712+
}
713+
714+
match tok {
715+
TokenTree::Token(_, Token::BinOp(BinOpToken::Plus))
716+
| TokenTree::Token(_, Token::Question)
717+
| TokenTree::Token(_, Token::BinOp(BinOpToken::Star)) => {
718+
break;
719+
}
720+
TokenTree::Token(sp, ref t) => {
721+
buffer.push_str(&pprust::token_to_string(t));
722+
hi = sp.hi();
723+
}
724+
_ => unreachable!(),
725+
}
726+
}
727+
728+
// There could be some random stuff between ')' and '*', '+' or '?'.
729+
let another = if buffer.trim().is_empty() {
730+
None
731+
} else {
732+
Some(Box::new(ParsedMacroArg {
733+
kind: MacroArgKind::Other(buffer, "".to_owned()),
734+
span: mk_sp(lo, hi),
735+
}))
736+
};
737+
738+
self.result.push(ParsedMacroArg {
739+
kind: MacroArgKind::Repeat(delim, inner, another, self.last_tok.clone()),
740+
span: mk_sp(self.lo, self.hi),
741+
});
742+
}
743+
668744
fn update_buffer(&mut self, lo: BytePos, t: &Token) {
669745
if self.buf.is_empty() {
670746
self.lo = lo;
@@ -716,15 +792,15 @@ impl MacroArgParser {
716792
}
717793

718794
// Start keeping the name of this metavariable in the buffer.
719-
self.is_arg = true;
795+
self.is_meta_var = true;
720796
self.lo = sp.lo();
721797
self.start_tok = Token::Dollar;
722798
}
723-
TokenTree::Token(_, Token::Colon) if self.is_arg => {
799+
TokenTree::Token(_, Token::Colon) if self.is_meta_var => {
724800
self.add_meta_variable(&mut iter);
725801
}
726802
TokenTree::Token(sp, ref t) => self.update_buffer(sp.lo(), t),
727-
TokenTree::Delimited(sp, ref delimited) => {
803+
TokenTree::Delimited(sp, delimited) => {
728804
if !self.buf.is_empty() {
729805
if next_space(&self.last_tok) == SpaceState::Always {
730806
self.add_separator();
@@ -733,66 +809,24 @@ impl MacroArgParser {
733809
}
734810
}
735811

812+
// Parse the stuff inside delimiters.
736813
let mut parser = MacroArgParser::new();
737814
parser.lo = sp.lo();
738-
let mut delimited_arg = parser.parse(delimited.tts.clone());
739-
740-
if self.is_arg {
741-
// Parse '*' or '+'.
742-
let mut buffer = String::new();
743-
let mut first = false;
744-
let mut lo = sp.lo();
745-
746-
while let Some(ref next_tok) = iter.next() {
747-
self.set_last_tok(next_tok);
748-
if first {
749-
first = false;
750-
lo = next_tok.span().lo();
751-
}
752-
753-
match next_tok {
754-
TokenTree::Token(_, Token::BinOp(BinOpToken::Plus))
755-
| TokenTree::Token(_, Token::Question)
756-
| TokenTree::Token(_, Token::BinOp(BinOpToken::Star)) => {
757-
break;
758-
}
759-
TokenTree::Token(_, ref t) => {
760-
buffer.push_str(&pprust::token_to_string(t))
761-
}
762-
_ => unreachable!(),
763-
}
764-
}
815+
let delimited_arg = parser.parse(delimited.tts.clone());
765816

766-
let another = if buffer.trim().is_empty() {
767-
None
768-
} else {
769-
Some(Box::new(ParsedMacroArg {
770-
kind: MacroArgKind::Other(buffer, "".to_owned()),
771-
span: mk_sp(lo, self.hi),
772-
}))
773-
};
774-
775-
self.result.push(ParsedMacroArg {
776-
kind: MacroArgKind::Repeat(
777-
delimited.delim,
778-
delimited_arg,
779-
another,
780-
self.last_tok.clone(),
781-
),
782-
span: mk_sp(self.lo, self.hi),
783-
});
817+
if self.is_meta_var {
818+
self.add_repeat(delimited_arg, delimited.delim, &mut iter, *sp);
784819
} else {
785-
self.result.push(ParsedMacroArg {
786-
kind: MacroArgKind::Delimited(delimited.delim, delimited_arg),
787-
span: *sp,
788-
});
820+
self.add_delimited(delimited_arg, delimited.delim, *sp);
789821
}
790822
}
791823
}
792824

793825
self.set_last_tok(tok);
794826
}
795827

828+
// We are left with some stuff in the buffer. Since there is nothing
829+
// left to separate, add this as `Other`.
796830
if !self.buf.is_empty() {
797831
self.add_other();
798832
}

0 commit comments

Comments
 (0)