From 5287a2506c19b7f886556f8a73510f57dd234857 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Apr 2019 12:18:52 +0300 Subject: [PATCH] More future-proof comment kind --- crates/ra_ide_api/src/folding_ranges.rs | 7 +- crates/ra_ide_api/src/typing.rs | 2 +- crates/ra_syntax/src/ast/tokens.rs | 85 +++++++++++++++---------- crates/ra_syntax/src/ast/traits.rs | 2 +- 4 files changed, 59 insertions(+), 37 deletions(-) diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs index eada0b7ded..6987fcc9ec 100644 --- a/crates/ra_ide_api/src/folding_ranges.rs +++ b/crates/ra_ide_api/src/folding_ranges.rs @@ -145,7 +145,10 @@ fn contiguous_range_for_comment<'a>( visited.insert(first); // Only fold comments of the same flavor - let group_flavor = first.flavor(); + let group_kind = first.kind(); + if !group_kind.shape.is_line() { + return None; + } let mut last = first; for element in first.syntax().siblings_with_tokens(Direction::Next) { @@ -158,7 +161,7 @@ fn contiguous_range_for_comment<'a>( } } if let Some(c) = ast::Comment::cast(token) { - if c.flavor() == group_flavor { + if c.kind() == group_kind { visited.insert(c); last = c; continue; diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs index aeeeea0821..ae53bca776 100644 --- a/crates/ra_ide_api/src/typing.rs +++ b/crates/ra_ide_api/src/typing.rs @@ -15,7 +15,7 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option AstToken<'a> for Comment<'a> { } impl<'a> Comment<'a> { - pub fn flavor(&self) -> CommentFlavor { - let text = self.text(); - if text.starts_with("///") { - CommentFlavor::OuterDoc - } else if text.starts_with("//!") { - CommentFlavor::InnerDoc - } else if text.starts_with("//") { - CommentFlavor::Line - } else { - CommentFlavor::Multiline - } - } - - pub fn is_doc_comment(&self) -> bool { - self.flavor().is_doc_comment() + pub fn kind(&self) -> CommentKind { + kind_by_prefix(self.text()) } pub fn prefix(&self) -> &'static str { - self.flavor().prefix() + prefix_by_kind(self.kind()) } } -#[derive(Debug, PartialEq, Eq)] -pub enum CommentFlavor { +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct CommentKind { + pub shape: CommentShape, + pub doc: Option, +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum CommentShape { Line, - OuterDoc, - InnerDoc, - Multiline, + Block, } -impl CommentFlavor { - pub fn prefix(&self) -> &'static str { - match *self { - CommentFlavor::Line => "//", - CommentFlavor::OuterDoc => "///", - CommentFlavor::InnerDoc => "//!", - CommentFlavor::Multiline => "/*", - } +impl CommentShape { + pub fn is_line(self) -> bool { + self == CommentShape::Line } - pub fn is_doc_comment(&self) -> bool { - match self { - CommentFlavor::OuterDoc | CommentFlavor::InnerDoc => true, - _ => false, + pub fn is_block(self) -> bool { + self == CommentShape::Block + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum CommentPlacement { + Inner, + Outer, +} + +const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = { + use {CommentShape::*, CommentPlacement::*}; + &[ + ("///", CommentKind { shape: Line, doc: Some(Outer) }), + ("//!", CommentKind { shape: Line, doc: Some(Inner) }), + ("/**", CommentKind { shape: Block, doc: Some(Outer) }), + ("/**", CommentKind { shape: Block, doc: Some(Inner) }), + ("//", CommentKind { shape: Line, doc: None }), + ("/*", CommentKind { shape: Block, doc: None }), + ] +}; + +fn kind_by_prefix(text: &str) -> CommentKind { + for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() { + if text.starts_with(prefix) { + return *kind; } } + panic!("bad comment text: {:?}", text) +} + +fn prefix_by_kind(kind: CommentKind) -> &'static str { + for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() { + if *k == kind { + return prefix; + } + } + unreachable!() } pub struct Whitespace<'a>(SyntaxToken<'a>); diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index 43d1509fab..98aa22085a 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs @@ -111,7 +111,7 @@ pub trait DocCommentsOwner: AstNode { let mut has_comments = false; let docs = self .doc_comments() - .filter(|comment| comment.is_doc_comment()) + .filter(|comment| comment.kind().doc.is_some()) .map(|comment| { has_comments = true; let prefix_len = comment.prefix().len();