aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-10-31 08:43:20 +0000
committerSeivan Heidari <[email protected]>2019-10-31 08:43:20 +0000
commit8edda0e7b164009d6c03bb3d4be603fb38ad2e2a (patch)
tree744cf81075d394e2f9c06afb07642a2601800dda /crates/ra_syntax/src
parent49562d36b97ddde34cf7585a8c2e8f232519b657 (diff)
parentd067afb064a7fa67b172abf561b7d80740cd6f18 (diff)
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast.rs24
-rw-r--r--crates/ra_syntax/src/ast/make.rs6
-rw-r--r--crates/ra_syntax/src/ast/traits.rs19
-rw-r--r--crates/ra_syntax/src/lib.rs14
4 files changed, 51 insertions, 12 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 1b2ce921a..a12da5be2 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -173,7 +173,7 @@ fn test_doc_comment_single_line_block_strips_suffix_whitespace() {
173 .ok() 173 .ok()
174 .unwrap(); 174 .unwrap();
175 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 175 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
176 assert_eq!("this is mod foo", module.doc_comment_text().unwrap()); 176 assert_eq!("this is mod foo ", module.doc_comment_text().unwrap());
177} 177}
178 178
179#[test] 179#[test]
@@ -191,7 +191,27 @@ fn test_doc_comment_multi_line_block_strips_suffix() {
191 .ok() 191 .ok()
192 .unwrap(); 192 .unwrap();
193 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 193 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
194 assert_eq!(" this\n is\n mod foo", module.doc_comment_text().unwrap()); 194 assert_eq!(
195 " this\n is\n mod foo\n ",
196 module.doc_comment_text().unwrap()
197 );
198}
199
200#[test]
201fn test_comments_preserve_trailing_whitespace() {
202 let file = SourceFile::parse(
203 r#"
204/// Representation of a Realm.
205/// In the specification these are called Realm Records.
206struct Realm {}"#,
207 )
208 .ok()
209 .unwrap();
210 let def = file.syntax().descendants().find_map(StructDef::cast).unwrap();
211 assert_eq!(
212 "Representation of a Realm. \nIn the specification these are called Realm Records.",
213 def.doc_comment_text().unwrap()
214 );
195} 215}
196 216
197#[test] 217#[test]
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index 00422ea91..3d5f18bfa 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -77,7 +77,7 @@ pub fn tuple_struct_pat(
77 77
78pub fn record_pat(path: ast::Path, pats: impl Iterator<Item = ast::Pat>) -> ast::RecordPat { 78pub fn record_pat(path: ast::Path, pats: impl Iterator<Item = ast::Pat>) -> ast::RecordPat {
79 let pats_str = pats.map(|p| p.syntax().to_string()).join(", "); 79 let pats_str = pats.map(|p| p.syntax().to_string()).join(", ");
80 return from_text(&format!("{}{{ {} }}", path.syntax(), pats_str)); 80 return from_text(&format!("{} {{ {} }}", path.syntax(), pats_str));
81 81
82 fn from_text(text: &str) -> ast::RecordPat { 82 fn from_text(text: &str) -> ast::RecordPat {
83 ast_from_text(&format!("fn f({}: ())", text)) 83 ast_from_text(&format!("fn f({}: ())", text))
@@ -129,11 +129,11 @@ pub fn where_clause(preds: impl Iterator<Item = ast::WherePred>) -> ast::WhereCl
129} 129}
130 130
131pub fn if_expression(condition: &ast::Expr, statement: &str) -> ast::IfExpr { 131pub fn if_expression(condition: &ast::Expr, statement: &str) -> ast::IfExpr {
132 return ast_from_text(&format!( 132 ast_from_text(&format!(
133 "fn f() {{ if !{} {{\n {}\n}}\n}}", 133 "fn f() {{ if !{} {{\n {}\n}}\n}}",
134 condition.syntax().text(), 134 condition.syntax().text(),
135 statement 135 statement
136 )); 136 ))
137} 137}
138 138
139fn ast_from_text<N: AstNode>(text: &str) -> N { 139fn ast_from_text<N: AstNode>(text: &str) -> N {
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index f275a4955..c2b005886 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -6,6 +6,7 @@ use itertools::Itertools;
6 6
7use crate::{ 7use crate::{
8 ast::{self, child_opt, children, AstChildren, AstNode, AstToken}, 8 ast::{self, child_opt, children, AstChildren, AstNode, AstToken},
9 match_ast,
9 syntax_node::{SyntaxElementChildren, SyntaxNodeChildren}, 10 syntax_node::{SyntaxElementChildren, SyntaxNodeChildren},
10}; 11};
11 12
@@ -68,11 +69,12 @@ impl Iterator for ItemOrMacroIter {
68 fn next(&mut self) -> Option<ItemOrMacro> { 69 fn next(&mut self) -> Option<ItemOrMacro> {
69 loop { 70 loop {
70 let n = self.0.next()?; 71 let n = self.0.next()?;
71 if let Some(item) = ast::ModuleItem::cast(n.clone()) { 72 match_ast! {
72 return Some(ItemOrMacro::Item(item)); 73 match n {
73 } 74 ast::ModuleItem(it) => { return Some(ItemOrMacro::Item(it)) },
74 if let Some(call) = ast::MacroCall::cast(n) { 75 ast::MacroCall(it) => { return Some(ItemOrMacro::Macro(it)) },
75 return Some(ItemOrMacro::Macro(call)); 76 _ => {},
77 }
76 } 78 }
77 } 79 }
78 } 80 }
@@ -120,7 +122,7 @@ pub trait DocCommentsOwner: AstNode {
120 has_comments = true; 122 has_comments = true;
121 let prefix_len = comment.prefix().len(); 123 let prefix_len = comment.prefix().len();
122 124
123 let line = comment.text().as_str(); 125 let line: &str = comment.text().as_str();
124 126
125 // Determine if the prefix or prefix + 1 char is stripped 127 // Determine if the prefix or prefix + 1 char is stripped
126 let pos = 128 let pos =
@@ -136,7 +138,10 @@ pub trait DocCommentsOwner: AstNode {
136 line.len() 138 line.len()
137 }; 139 };
138 140
139 line[pos..end].trim_end().to_owned() 141 // Note that we do not trim the end of the line here
142 // since whitespace can have special meaning at the end
143 // of a line in markdown.
144 line[pos..end].to_owned()
140 }) 145 })
141 .join("\n"); 146 .join("\n");
142 147
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index c315ba552..5dcb6a95a 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -160,6 +160,20 @@ impl SourceFile {
160 } 160 }
161} 161}
162 162
163/// Matches a `SyntaxNode` against an `ast` type.
164///
165/// # Example:
166///
167/// ```ignore
168/// match_ast! {
169/// match node {
170/// ast::CallExpr(it) => { ... },
171/// ast::MethodCallExpr(it) => { ... },
172/// ast::MacroCall(it) => { ... },
173/// _ => None,
174/// }
175/// }
176/// ```
163#[macro_export] 177#[macro_export]
164macro_rules! match_ast { 178macro_rules! match_ast {
165 (match $node:ident { 179 (match $node:ident {