diff options
Diffstat (limited to 'crates/syntax/src/ast/token_ext.rs')
-rw-r--r-- | crates/syntax/src/ast/token_ext.rs | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs index e4e512f2e..ac0326420 100644 --- a/crates/syntax/src/ast/token_ext.rs +++ b/crates/syntax/src/ast/token_ext.rs | |||
@@ -14,16 +14,15 @@ use crate::{ | |||
14 | 14 | ||
15 | impl ast::Comment { | 15 | impl ast::Comment { |
16 | pub fn kind(&self) -> CommentKind { | 16 | pub fn kind(&self) -> CommentKind { |
17 | kind_by_prefix(self.text()) | 17 | CommentKind::from_text(self.text()) |
18 | } | 18 | } |
19 | 19 | ||
20 | pub fn prefix(&self) -> &'static str { | 20 | pub fn prefix(&self) -> &'static str { |
21 | for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() { | 21 | let &(prefix, _kind) = CommentKind::BY_PREFIX |
22 | if *k == self.kind() && self.text().starts_with(prefix) { | 22 | .iter() |
23 | return prefix; | 23 | .find(|&(prefix, kind)| self.kind() == *kind && self.text().starts_with(prefix)) |
24 | } | 24 | .unwrap(); |
25 | } | 25 | prefix |
26 | unreachable!() | ||
27 | } | 26 | } |
28 | } | 27 | } |
29 | 28 | ||
@@ -55,29 +54,25 @@ pub enum CommentPlacement { | |||
55 | Outer, | 54 | Outer, |
56 | } | 55 | } |
57 | 56 | ||
58 | const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = { | 57 | impl CommentKind { |
59 | use {CommentPlacement::*, CommentShape::*}; | 58 | const BY_PREFIX: [(&'static str, CommentKind); 8] = [ |
60 | &[ | 59 | ("/**/", CommentKind { shape: CommentShape::Block, doc: None }), |
61 | ("////", CommentKind { shape: Line, doc: None }), | 60 | ("////", CommentKind { shape: CommentShape::Line, doc: None }), |
62 | ("///", CommentKind { shape: Line, doc: Some(Outer) }), | 61 | ("///", CommentKind { shape: CommentShape::Line, doc: Some(CommentPlacement::Outer) }), |
63 | ("//!", CommentKind { shape: Line, doc: Some(Inner) }), | 62 | ("//!", CommentKind { shape: CommentShape::Line, doc: Some(CommentPlacement::Inner) }), |
64 | ("/**", CommentKind { shape: Block, doc: Some(Outer) }), | 63 | ("/**", CommentKind { shape: CommentShape::Block, doc: Some(CommentPlacement::Outer) }), |
65 | ("/*!", CommentKind { shape: Block, doc: Some(Inner) }), | 64 | ("/*!", CommentKind { shape: CommentShape::Block, doc: Some(CommentPlacement::Inner) }), |
66 | ("//", CommentKind { shape: Line, doc: None }), | 65 | ("//", CommentKind { shape: CommentShape::Line, doc: None }), |
67 | ("/*", CommentKind { shape: Block, doc: None }), | 66 | ("/*", CommentKind { shape: CommentShape::Block, doc: None }), |
68 | ] | 67 | ]; |
69 | }; | ||
70 | 68 | ||
71 | fn kind_by_prefix(text: &str) -> CommentKind { | 69 | pub(crate) fn from_text(text: &str) -> CommentKind { |
72 | if text == "/**/" { | 70 | let &(_prefix, kind) = CommentKind::BY_PREFIX |
73 | return CommentKind { shape: CommentShape::Block, doc: None }; | 71 | .iter() |
74 | } | 72 | .find(|&(prefix, _kind)| text.starts_with(prefix)) |
75 | for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() { | 73 | .unwrap(); |
76 | if text.starts_with(prefix) { | 74 | kind |
77 | return *kind; | ||
78 | } | ||
79 | } | 75 | } |
80 | panic!("bad comment text: {:?}", text) | ||
81 | } | 76 | } |
82 | 77 | ||
83 | impl ast::Whitespace { | 78 | impl ast::Whitespace { |
@@ -336,10 +331,22 @@ pub trait HasFormatSpecifier: AstToken { | |||
336 | } | 331 | } |
337 | c if c == '_' || c.is_alphabetic() => { | 332 | c if c == '_' || c.is_alphabetic() => { |
338 | read_identifier(&mut chars, &mut callback); | 333 | read_identifier(&mut chars, &mut callback); |
334 | |||
335 | if chars.peek().and_then(|next| next.1.as_ref().ok()).copied() | ||
336 | == Some('?') | ||
337 | { | ||
338 | skip_char_and_emit( | ||
339 | &mut chars, | ||
340 | FormatSpecifier::QuestionMark, | ||
341 | &mut callback, | ||
342 | ); | ||
343 | } | ||
344 | |||
339 | // can be either width (indicated by dollar sign, or type in which case | 345 | // can be either width (indicated by dollar sign, or type in which case |
340 | // the next sign has to be `}`) | 346 | // the next sign has to be `}`) |
341 | let next = | 347 | let next = |
342 | chars.peek().and_then(|next| next.1.as_ref().ok()).copied(); | 348 | chars.peek().and_then(|next| next.1.as_ref().ok()).copied(); |
349 | |||
343 | match next { | 350 | match next { |
344 | Some('$') => skip_char_and_emit( | 351 | Some('$') => skip_char_and_emit( |
345 | &mut chars, | 352 | &mut chars, |
@@ -422,6 +429,16 @@ pub trait HasFormatSpecifier: AstToken { | |||
422 | } | 429 | } |
423 | c if c == '_' || c.is_alphabetic() => { | 430 | c if c == '_' || c.is_alphabetic() => { |
424 | read_identifier(&mut chars, &mut callback); | 431 | read_identifier(&mut chars, &mut callback); |
432 | |||
433 | if chars.peek().and_then(|next| next.1.as_ref().ok()).copied() | ||
434 | == Some('?') | ||
435 | { | ||
436 | skip_char_and_emit( | ||
437 | &mut chars, | ||
438 | FormatSpecifier::QuestionMark, | ||
439 | &mut callback, | ||
440 | ); | ||
441 | } | ||
425 | } | 442 | } |
426 | _ => {} | 443 | _ => {} |
427 | } | 444 | } |