mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Attach comments smartly
This commit is contained in:
parent
b642e6c645
commit
a05e09e9c5
4 changed files with 97 additions and 24 deletions
|
@ -153,6 +153,22 @@ impl S {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_extend_selection_doc_comments() {
|
||||||
|
do_check(
|
||||||
|
r#"
|
||||||
|
struct A;
|
||||||
|
|
||||||
|
/// bla
|
||||||
|
/// bla
|
||||||
|
struct B {
|
||||||
|
<|>
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
&["\n \n", "{\n \n}", "/// bla\n/// bla\nstruct B {\n \n}"]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_extend_selection_comments() {
|
fn test_extend_selection_comments() {
|
||||||
do_check(
|
do_check(
|
||||||
|
|
|
@ -12,7 +12,7 @@ use {
|
||||||
TextUnit, TextRange, SmolStr,
|
TextUnit, TextRange, SmolStr,
|
||||||
lexer::Token,
|
lexer::Token,
|
||||||
parser_impl::Sink,
|
parser_impl::Sink,
|
||||||
SyntaxKind::{self, TOMBSTONE},
|
SyntaxKind::{self, *},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,7 +104,6 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
|
||||||
fn tombstone() -> Event {
|
fn tombstone() -> Event {
|
||||||
Event::Start { kind: TOMBSTONE, forward_parent: None }
|
Event::Start { kind: TOMBSTONE, forward_parent: None }
|
||||||
}
|
}
|
||||||
let mut depth = 0;
|
|
||||||
let mut forward_parents = Vec::new();
|
let mut forward_parents = Vec::new();
|
||||||
|
|
||||||
for i in 0..self.events.len() {
|
for i in 0..self.events.len() {
|
||||||
|
@ -131,25 +130,14 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
for kind in forward_parents.drain(..).rev() {
|
for kind in forward_parents.drain(..).rev() {
|
||||||
if depth > 0 {
|
self.start(kind);
|
||||||
self.eat_ws();
|
|
||||||
}
|
|
||||||
depth += 1;
|
|
||||||
self.sink.start_internal(kind);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Finish => {
|
Event::Finish => {
|
||||||
depth -= 1;
|
let last = i == self.events.len() - 1;
|
||||||
if depth == 0 {
|
self.finish(last);
|
||||||
self.eat_ws();
|
},
|
||||||
}
|
Event::Token { kind, n_raw_tokens } => {
|
||||||
|
|
||||||
self.sink.finish_internal();
|
|
||||||
}
|
|
||||||
Event::Token {
|
|
||||||
kind,
|
|
||||||
n_raw_tokens,
|
|
||||||
} => {
|
|
||||||
self.eat_ws();
|
self.eat_ws();
|
||||||
let n_raw_tokens = n_raw_tokens as usize;
|
let n_raw_tokens = n_raw_tokens as usize;
|
||||||
let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens]
|
let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens]
|
||||||
|
@ -164,6 +152,43 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
|
||||||
self.sink
|
self.sink
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn start(&mut self, kind: SyntaxKind) {
|
||||||
|
if kind == ROOT {
|
||||||
|
self.sink.start_internal(kind);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let n_trivias = self.tokens[self.token_pos..]
|
||||||
|
.iter()
|
||||||
|
.take_while(|it| it.kind.is_trivia())
|
||||||
|
.count();
|
||||||
|
let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias];
|
||||||
|
let mut trivia_end = self.text_pos + leading_trivias
|
||||||
|
.iter()
|
||||||
|
.map(|it| it.len)
|
||||||
|
.sum::<TextUnit>();
|
||||||
|
|
||||||
|
let n_attached_trivias = {
|
||||||
|
let leading_trivias = leading_trivias.iter().rev()
|
||||||
|
.map(|it| {
|
||||||
|
let next_end = trivia_end - it.len;
|
||||||
|
let range = TextRange::from_to(next_end, trivia_end);
|
||||||
|
trivia_end = next_end;
|
||||||
|
(it.kind, &self.text[range])
|
||||||
|
});
|
||||||
|
n_attached_trivias(kind, leading_trivias)
|
||||||
|
};
|
||||||
|
self.eat_n_trivias(n_trivias - n_attached_trivias);
|
||||||
|
self.sink.start_internal(kind);
|
||||||
|
self.eat_n_trivias(n_attached_trivias);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish(&mut self, last: bool) {
|
||||||
|
if last {
|
||||||
|
self.eat_ws()
|
||||||
|
}
|
||||||
|
self.sink.finish_internal();
|
||||||
|
}
|
||||||
|
|
||||||
fn eat_ws(&mut self) {
|
fn eat_ws(&mut self) {
|
||||||
while let Some(&token) = self.tokens.get(self.token_pos) {
|
while let Some(&token) = self.tokens.get(self.token_pos) {
|
||||||
if !token.kind.is_trivia() {
|
if !token.kind.is_trivia() {
|
||||||
|
@ -173,6 +198,14 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn eat_n_trivias(&mut self, n: usize) {
|
||||||
|
for _ in 0..n {
|
||||||
|
let token = self.tokens[self.token_pos];
|
||||||
|
assert!(token.kind.is_trivia());
|
||||||
|
self.leaf(token.kind, token.len, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn leaf(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) {
|
fn leaf(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) {
|
||||||
let range = TextRange::offset_len(self.text_pos, len);
|
let range = TextRange::offset_len(self.text_pos, len);
|
||||||
let text: SmolStr = self.text[range].into();
|
let text: SmolStr = self.text[range].into();
|
||||||
|
@ -181,3 +214,27 @@ impl<'a, S: Sink> EventProcessor<'a, S> {
|
||||||
self.sink.leaf(kind, text);
|
self.sink.leaf(kind, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn n_attached_trivias<'a>(kind: SyntaxKind, trivias: impl Iterator<Item=(SyntaxKind, &'a str)>) -> usize {
|
||||||
|
match kind {
|
||||||
|
STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => {
|
||||||
|
let mut res = 0;
|
||||||
|
for (i, (kind, text)) in trivias.enumerate() {
|
||||||
|
match kind {
|
||||||
|
WHITESPACE => {
|
||||||
|
if text.contains("\n\n") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
COMMENT => {
|
||||||
|
res = i + 1;
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -137,9 +137,9 @@ ROOT@[0; 575)
|
||||||
BLOCK@[306; 459)
|
BLOCK@[306; 459)
|
||||||
L_CURLY@[306; 307)
|
L_CURLY@[306; 307)
|
||||||
WHITESPACE@[307; 316)
|
WHITESPACE@[307; 316)
|
||||||
COMMENT@[316; 329)
|
ENUM_DEF@[316; 453)
|
||||||
WHITESPACE@[329; 338)
|
COMMENT@[316; 329)
|
||||||
ENUM_DEF@[338; 453)
|
WHITESPACE@[329; 338)
|
||||||
ENUM_KW@[338; 342)
|
ENUM_KW@[338; 342)
|
||||||
WHITESPACE@[342; 343)
|
WHITESPACE@[342; 343)
|
||||||
NAME@[343; 348)
|
NAME@[343; 348)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
ROOT@[0; 506)
|
ROOT@[0; 506)
|
||||||
COMMENT@[0; 33)
|
FN_DEF@[0; 505)
|
||||||
WHITESPACE@[33; 34)
|
COMMENT@[0; 33)
|
||||||
FN_DEF@[34; 505)
|
WHITESPACE@[33; 34)
|
||||||
FN_KW@[34; 36)
|
FN_KW@[34; 36)
|
||||||
WHITESPACE@[36; 37)
|
WHITESPACE@[36; 37)
|
||||||
NAME@[37; 41)
|
NAME@[37; 41)
|
||||||
|
|
Loading…
Reference in a new issue