mbe: fix token conversion for doc comments
This commit is contained in:
parent
af3b6a0893
commit
a497e9a05e
@ -850,6 +850,32 @@ fn foo() {}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_through_included_file_struct_with_doc_comment() {
|
||||
check(
|
||||
r#"
|
||||
//- /main.rs
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! include {}
|
||||
|
||||
include!("foo.rs");
|
||||
|
||||
fn f() {
|
||||
let x = Foo$0;
|
||||
}
|
||||
|
||||
mod confuse_index {
|
||||
pub struct Foo;
|
||||
}
|
||||
|
||||
//- /foo.rs
|
||||
/// This is a doc comment
|
||||
pub struct Foo;
|
||||
//^^^
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn goto_for_type_param() {
|
||||
check(
|
||||
|
@ -190,20 +190,13 @@ struct StackEntry {
|
||||
|
||||
let kind = token.kind(conv);
|
||||
if kind == COMMENT {
|
||||
if let Some(tokens) = conv.convert_doc_comment(&token) {
|
||||
// FIXME: There has to be a better way to do this
|
||||
// Add the comments token id to the converted doc string
|
||||
// Since `convert_doc_comment` can fail, we need to peek the next id, so that we can
|
||||
// figure out which token id to use for the doc comment, if it is converted successfully.
|
||||
let next_id = conv.id_alloc().peek_next_id();
|
||||
if let Some(tokens) = conv.convert_doc_comment(&token, next_id) {
|
||||
let id = conv.id_alloc().alloc(range, synth_id);
|
||||
result.extend(tokens.into_iter().map(|mut tt| {
|
||||
if let tt::TokenTree::Subtree(sub) = &mut tt {
|
||||
if let Some(tt::TokenTree::Leaf(tt::Leaf::Literal(lit))) =
|
||||
sub.token_trees.get_mut(2)
|
||||
{
|
||||
lit.span = id
|
||||
}
|
||||
}
|
||||
tt
|
||||
}));
|
||||
debug_assert_eq!(id, next_id);
|
||||
result.extend(tokens);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -382,49 +375,46 @@ fn doc_comment_text(comment: &ast::Comment) -> SmolStr {
|
||||
text.into()
|
||||
}
|
||||
|
||||
fn convert_doc_comment(token: &syntax::SyntaxToken) -> Option<Vec<tt::TokenTree>> {
|
||||
fn convert_doc_comment(
|
||||
token: &syntax::SyntaxToken,
|
||||
span: tt::TokenId,
|
||||
) -> Option<Vec<tt::TokenTree>> {
|
||||
cov_mark::hit!(test_meta_doc_comments);
|
||||
let comment = ast::Comment::cast(token.clone())?;
|
||||
let doc = comment.kind().doc?;
|
||||
|
||||
// Make `doc="\" Comments\""
|
||||
let meta_tkns = vec![mk_ident("doc"), mk_punct('='), mk_doc_literal(&comment)];
|
||||
let meta_tkns =
|
||||
vec![mk_ident("doc", span), mk_punct('=', span), mk_doc_literal(&comment, span)];
|
||||
|
||||
// Make `#![]`
|
||||
let mut token_trees = Vec::with_capacity(3);
|
||||
token_trees.push(mk_punct('#'));
|
||||
token_trees.push(mk_punct('#', span));
|
||||
if let ast::CommentPlacement::Inner = doc {
|
||||
token_trees.push(mk_punct('!'));
|
||||
token_trees.push(mk_punct('!', span));
|
||||
}
|
||||
token_trees.push(tt::TokenTree::from(tt::Subtree {
|
||||
delimiter: tt::Delimiter {
|
||||
open: tt::TokenId::UNSPECIFIED,
|
||||
close: tt::TokenId::UNSPECIFIED,
|
||||
kind: tt::DelimiterKind::Bracket,
|
||||
},
|
||||
delimiter: tt::Delimiter { open: span, close: span, kind: tt::DelimiterKind::Bracket },
|
||||
token_trees: meta_tkns,
|
||||
}));
|
||||
|
||||
return Some(token_trees);
|
||||
|
||||
// Helper functions
|
||||
fn mk_ident(s: &str) -> tt::TokenTree {
|
||||
tt::TokenTree::from(tt::Leaf::from(tt::Ident {
|
||||
text: s.into(),
|
||||
span: tt::TokenId::unspecified(),
|
||||
}))
|
||||
fn mk_ident(s: &str, span: tt::TokenId) -> tt::TokenTree {
|
||||
tt::TokenTree::from(tt::Leaf::from(tt::Ident { text: s.into(), span }))
|
||||
}
|
||||
|
||||
fn mk_punct(c: char) -> tt::TokenTree {
|
||||
fn mk_punct(c: char, span: tt::TokenId) -> tt::TokenTree {
|
||||
tt::TokenTree::from(tt::Leaf::from(tt::Punct {
|
||||
char: c,
|
||||
spacing: tt::Spacing::Alone,
|
||||
span: tt::TokenId::unspecified(),
|
||||
span,
|
||||
}))
|
||||
}
|
||||
|
||||
fn mk_doc_literal(comment: &ast::Comment) -> tt::TokenTree {
|
||||
let lit = tt::Literal { text: doc_comment_text(comment), span: tt::TokenId::unspecified() };
|
||||
fn mk_doc_literal(comment: &ast::Comment, span: tt::TokenId) -> tt::TokenTree {
|
||||
let lit = tt::Literal { text: doc_comment_text(comment), span };
|
||||
|
||||
tt::TokenTree::from(tt::Leaf::from(lit))
|
||||
}
|
||||
@ -480,6 +470,10 @@ fn close_delim(&mut self, idx: usize, close_abs_range: Option<TextRange>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn peek_next_id(&self) -> tt::TokenId {
|
||||
tt::TokenId(self.next_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// A raw token (straight from lexer) converter
|
||||
@ -502,7 +496,11 @@ trait SrcToken<Ctx>: std::fmt::Debug {
|
||||
trait TokenConverter: Sized {
|
||||
type Token: SrcToken<Self>;
|
||||
|
||||
fn convert_doc_comment(&self, token: &Self::Token) -> Option<Vec<tt::TokenTree>>;
|
||||
fn convert_doc_comment(
|
||||
&self,
|
||||
token: &Self::Token,
|
||||
span: tt::TokenId,
|
||||
) -> Option<Vec<tt::TokenTree>>;
|
||||
|
||||
fn bump(&mut self) -> Option<(Self::Token, TextRange)>;
|
||||
|
||||
@ -532,9 +530,9 @@ fn synthetic_id(&self, _ctx: &RawConverter<'a>) -> Option<SyntheticTokenId> {
|
||||
impl<'a> TokenConverter for RawConverter<'a> {
|
||||
type Token = usize;
|
||||
|
||||
fn convert_doc_comment(&self, &token: &usize) -> Option<Vec<tt::TokenTree>> {
|
||||
fn convert_doc_comment(&self, &token: &usize, span: tt::TokenId) -> Option<Vec<tt::TokenTree>> {
|
||||
let text = self.lexed.text(token);
|
||||
convert_doc_comment(&doc_comment(text))
|
||||
convert_doc_comment(&doc_comment(text), span)
|
||||
}
|
||||
|
||||
fn bump(&mut self) -> Option<(Self::Token, TextRange)> {
|
||||
@ -681,8 +679,12 @@ fn synthetic_id(&self, _ctx: &Converter) -> Option<SyntheticTokenId> {
|
||||
|
||||
impl TokenConverter for Converter {
|
||||
type Token = SynToken;
|
||||
fn convert_doc_comment(&self, token: &Self::Token) -> Option<Vec<tt::TokenTree>> {
|
||||
convert_doc_comment(token.token()?)
|
||||
fn convert_doc_comment(
|
||||
&self,
|
||||
token: &Self::Token,
|
||||
span: tt::TokenId,
|
||||
) -> Option<Vec<tt::TokenTree>> {
|
||||
convert_doc_comment(token.token()?, span)
|
||||
}
|
||||
|
||||
fn bump(&mut self) -> Option<(Self::Token, TextRange)> {
|
||||
|
Loading…
Reference in New Issue
Block a user