aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/add_missing_impl_members.rs2
-rw-r--r--crates/ra_assists/src/inline_local_variable.rs9
-rw-r--r--crates/ra_fmt/src/lib.rs3
-rw-r--r--crates/ra_ide_api/src/extend_selection.rs12
-rw-r--r--crates/ra_ide_api/src/folding_ranges.rs10
-rw-r--r--crates/ra_ide_api/src/join_lines.rs4
-rw-r--r--crates/ra_ide_api/src/typing.rs2
-rw-r--r--crates/ra_syntax/src/ast.rs106
-rw-r--r--crates/ra_syntax/src/ast/tokens.rs93
-rw-r--r--crates/ra_syntax/src/ast/traits.rs2
10 files changed, 124 insertions, 119 deletions
diff --git a/crates/ra_assists/src/add_missing_impl_members.rs b/crates/ra_assists/src/add_missing_impl_members.rs
index 5b01e898e..19a2d05bc 100644
--- a/crates/ra_assists/src/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/add_missing_impl_members.rs
@@ -5,7 +5,7 @@ use crate::{Assist, AssistId, AssistCtx};
5use hir::Resolver; 5use hir::Resolver;
6use hir::db::HirDatabase; 6use hir::db::HirDatabase;
7use ra_syntax::{SmolStr, SyntaxKind, TextRange, TextUnit, TreeArc}; 7use ra_syntax::{SmolStr, SyntaxKind, TextRange, TextUnit, TreeArc};
8use ra_syntax::ast::{self, AstNode, FnDef, ImplItem, ImplItemKind, NameOwner}; 8use ra_syntax::ast::{self, AstNode, AstToken, FnDef, ImplItem, ImplItemKind, NameOwner};
9use ra_db::FilePosition; 9use ra_db::FilePosition;
10use ra_fmt::{leading_indent, reindent}; 10use ra_fmt::{leading_indent, reindent};
11 11
diff --git a/crates/ra_assists/src/inline_local_variable.rs b/crates/ra_assists/src/inline_local_variable.rs
index 0d7b884b8..950c2910b 100644
--- a/crates/ra_assists/src/inline_local_variable.rs
+++ b/crates/ra_assists/src/inline_local_variable.rs
@@ -1,14 +1,9 @@
1use hir::{ 1use hir::{
2 db::HirDatabase, 2 db::HirDatabase,
3 source_binder::function_from_child_node 3 source_binder::function_from_child_node,
4}; 4};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{ 6 ast::{self, AstNode, AstToken, PatKind, ExprKind},
7 self,
8 AstNode,
9 PatKind,
10 ExprKind
11 },
12 TextRange, 7 TextRange,
13}; 8};
14 9
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs
index ea90dc2b8..85b7ce250 100644
--- a/crates/ra_fmt/src/lib.rs
+++ b/crates/ra_fmt/src/lib.rs
@@ -2,9 +2,8 @@
2//! 2//!
3use itertools::Itertools; 3use itertools::Itertools;
4use ra_syntax::{ 4use ra_syntax::{
5 AstNode,
6 SyntaxNode, SyntaxKind::*, SyntaxToken, SyntaxKind, 5 SyntaxNode, SyntaxKind::*, SyntaxToken, SyntaxKind,
7 ast, 6 ast::{self, AstNode, AstToken},
8 algo::generate, 7 algo::generate,
9}; 8};
10 9
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs
index e743bf0fe..7293ba359 100644
--- a/crates/ra_ide_api/src/extend_selection.rs
+++ b/crates/ra_ide_api/src/extend_selection.rs
@@ -1,9 +1,9 @@
1use ra_db::SourceDatabase; 1use ra_db::SourceDatabase;
2use ra_syntax::{ 2use ra_syntax::{
3 Direction, SyntaxNode, TextRange, TextUnit, AstNode, SyntaxElement, 3 Direction, SyntaxNode, TextRange, TextUnit, SyntaxElement,
4 algo::{find_covering_element, find_token_at_offset, TokenAtOffset}, 4 algo::{find_covering_element, find_token_at_offset, TokenAtOffset},
5 SyntaxKind::*, SyntaxToken, 5 SyntaxKind::*, SyntaxToken,
6 ast::Comment, 6 ast::{self, AstNode, AstToken},
7}; 7};
8 8
9use crate::{FileRange, db::RootDatabase}; 9use crate::{FileRange, db::RootDatabase};
@@ -55,7 +55,7 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange
55 if token.range() != range { 55 if token.range() != range {
56 return Some(token.range()); 56 return Some(token.range());
57 } 57 }
58 if let Some(comment) = Comment::cast(token) { 58 if let Some(comment) = ast::Comment::cast(token) {
59 if let Some(range) = extend_comments(comment) { 59 if let Some(range) = extend_comments(comment) {
60 return Some(range); 60 return Some(range);
61 } 61 }
@@ -176,7 +176,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> {
176 None 176 None
177} 177}
178 178
179fn extend_comments(comment: Comment) -> Option<TextRange> { 179fn extend_comments(comment: ast::Comment) -> Option<TextRange> {
180 let prev = adj_comments(comment, Direction::Prev); 180 let prev = adj_comments(comment, Direction::Prev);
181 let next = adj_comments(comment, Direction::Next); 181 let next = adj_comments(comment, Direction::Next);
182 if prev != next { 182 if prev != next {
@@ -186,14 +186,14 @@ fn extend_comments(comment: Comment) -> Option<TextRange> {
186 } 186 }
187} 187}
188 188
189fn adj_comments(comment: Comment, dir: Direction) -> Comment { 189fn adj_comments(comment: ast::Comment, dir: Direction) -> ast::Comment {
190 let mut res = comment; 190 let mut res = comment;
191 for element in comment.syntax().siblings_with_tokens(dir) { 191 for element in comment.syntax().siblings_with_tokens(dir) {
192 let token = match element.as_token() { 192 let token = match element.as_token() {
193 None => break, 193 None => break,
194 Some(token) => token, 194 Some(token) => token,
195 }; 195 };
196 if let Some(c) = Comment::cast(token) { 196 if let Some(c) = ast::Comment::cast(token) {
197 res = c 197 res = c
198 } else if token.kind() != WHITESPACE || token.text().contains("\n\n") { 198 } else if token.kind() != WHITESPACE || token.text().contains("\n\n") {
199 break; 199 break;
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs
index a6fe8a5d5..eada0b7de 100644
--- a/crates/ra_ide_api/src/folding_ranges.rs
+++ b/crates/ra_ide_api/src/folding_ranges.rs
@@ -1,9 +1,9 @@
1use rustc_hash::FxHashSet; 1use rustc_hash::FxHashSet;
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 AstNode, SourceFile, SyntaxNode, TextRange, Direction, SyntaxElement, 4 SourceFile, SyntaxNode, TextRange, Direction, SyntaxElement,
5 SyntaxKind::{self, *}, 5 SyntaxKind::{self, *},
6 ast::{self, VisibilityOwner, Comment}, 6 ast::{self, AstNode, AstToken, VisibilityOwner},
7}; 7};
8 8
9#[derive(Debug, PartialEq, Eq)] 9#[derive(Debug, PartialEq, Eq)]
@@ -139,8 +139,8 @@ fn contiguous_range_for_group_unless<'a>(
139} 139}
140 140
141fn contiguous_range_for_comment<'a>( 141fn contiguous_range_for_comment<'a>(
142 first: Comment<'a>, 142 first: ast::Comment<'a>,
143 visited: &mut FxHashSet<Comment<'a>>, 143 visited: &mut FxHashSet<ast::Comment<'a>>,
144) -> Option<TextRange> { 144) -> Option<TextRange> {
145 visited.insert(first); 145 visited.insert(first);
146 146
@@ -157,7 +157,7 @@ fn contiguous_range_for_comment<'a>(
157 continue; 157 continue;
158 } 158 }
159 } 159 }
160 if let Some(c) = Comment::cast(token) { 160 if let Some(c) = ast::Comment::cast(token) {
161 if c.flavor() == group_flavor { 161 if c.flavor() == group_flavor {
162 visited.insert(c); 162 visited.insert(c);
163 last = c; 163 last = c;
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs
index 57b6f8384..598717311 100644
--- a/crates/ra_ide_api/src/join_lines.rs
+++ b/crates/ra_ide_api/src/join_lines.rs
@@ -1,9 +1,9 @@
1use itertools::Itertools; 1use itertools::Itertools;
2use ra_syntax::{ 2use ra_syntax::{
3 SourceFile, TextRange, TextUnit, AstNode, SyntaxNode, SyntaxElement, SyntaxToken, 3 SourceFile, TextRange, TextUnit, SyntaxNode, SyntaxElement, SyntaxToken,
4 SyntaxKind::{self, WHITESPACE, COMMA, R_CURLY, R_PAREN, R_BRACK}, 4 SyntaxKind::{self, WHITESPACE, COMMA, R_CURLY, R_PAREN, R_BRACK},
5 algo::{find_covering_element, non_trivia_sibling}, 5 algo::{find_covering_element, non_trivia_sibling},
6 ast, 6 ast::{self, AstNode, AstToken},
7 Direction, 7 Direction,
8}; 8};
9use ra_fmt::{ 9use ra_fmt::{
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index 4510d663d..aeeeea082 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -2,7 +2,7 @@ use ra_syntax::{
2 AstNode, SourceFile, SyntaxKind::*, 2 AstNode, SourceFile, SyntaxKind::*,
3 TextUnit, TextRange, SyntaxToken, 3 TextUnit, TextRange, SyntaxToken,
4 algo::{find_node_at_offset, find_token_at_offset, TokenAtOffset}, 4 algo::{find_node_at_offset, find_token_at_offset, TokenAtOffset},
5 ast::{self}, 5 ast::{self, AstToken},
6}; 6};
7use ra_fmt::leading_indent; 7use ra_fmt::leading_indent;
8use ra_text_edit::{TextEdit, TextEditBuilder}; 8use ra_text_edit::{TextEdit, TextEditBuilder};
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 9950ab12d..beef2c6e2 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -1,6 +1,7 @@
1//! Abstract Syntax Tree, layered on top of untyped `SyntaxNode`s 1//! Abstract Syntax Tree, layered on top of untyped `SyntaxNode`s
2mod generated; 2mod generated;
3mod traits; 3mod traits;
4mod tokens;
4 5
5use std::marker::PhantomData; 6use std::marker::PhantomData;
6 7
@@ -15,6 +16,7 @@ use crate::{
15pub use self::{ 16pub use self::{
16 generated::*, 17 generated::*,
17 traits::*, 18 traits::*,
19 tokens::*,
18}; 20};
19 21
20/// The main trait to go from untyped `SyntaxNode` to a typed ast. The 22/// The main trait to go from untyped `SyntaxNode` to a typed ast. The
@@ -49,6 +51,16 @@ impl<'a, N: AstNode + 'a> Iterator for AstChildren<'a, N> {
49 } 51 }
50} 52}
51 53
54pub trait AstToken<'a> {
55 fn cast(token: SyntaxToken<'a>) -> Option<Self>
56 where
57 Self: Sized;
58 fn syntax(&self) -> SyntaxToken<'a>;
59 fn text(&self) -> &'a SmolStr {
60 self.syntax().text()
61 }
62}
63
52impl Attr { 64impl Attr {
53 pub fn is_inner(&self) -> bool { 65 pub fn is_inner(&self) -> bool {
54 let tt = match self.value() { 66 let tt = match self.value() {
@@ -96,100 +108,6 @@ impl Attr {
96 } 108 }
97} 109}
98 110
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
100pub struct Comment<'a>(SyntaxToken<'a>);
101
102impl<'a> Comment<'a> {
103 pub fn cast(token: SyntaxToken<'a>) -> Option<Self> {
104 if token.kind() == COMMENT {
105 Some(Comment(token))
106 } else {
107 None
108 }
109 }
110
111 pub fn syntax(&self) -> SyntaxToken<'a> {
112 self.0
113 }
114
115 pub fn text(&self) -> &'a SmolStr {
116 self.0.text()
117 }
118
119 pub fn flavor(&self) -> CommentFlavor {
120 let text = self.text();
121 if text.starts_with("///") {
122 CommentFlavor::Doc
123 } else if text.starts_with("//!") {
124 CommentFlavor::ModuleDoc
125 } else if text.starts_with("//") {
126 CommentFlavor::Line
127 } else {
128 CommentFlavor::Multiline
129 }
130 }
131
132 pub fn is_doc_comment(&self) -> bool {
133 self.flavor().is_doc_comment()
134 }
135
136 pub fn prefix(&self) -> &'static str {
137 self.flavor().prefix()
138 }
139}
140
141#[derive(Debug, PartialEq, Eq)]
142pub enum CommentFlavor {
143 Line,
144 Doc,
145 ModuleDoc,
146 Multiline,
147}
148
149impl CommentFlavor {
150 pub fn prefix(&self) -> &'static str {
151 use self::CommentFlavor::*;
152 match *self {
153 Line => "//",
154 Doc => "///",
155 ModuleDoc => "//!",
156 Multiline => "/*",
157 }
158 }
159
160 pub fn is_doc_comment(&self) -> bool {
161 match self {
162 CommentFlavor::Doc | CommentFlavor::ModuleDoc => true,
163 _ => false,
164 }
165 }
166}
167
168pub struct Whitespace<'a>(SyntaxToken<'a>);
169
170impl<'a> Whitespace<'a> {
171 pub fn cast(token: SyntaxToken<'a>) -> Option<Self> {
172 if token.kind() == WHITESPACE {
173 Some(Whitespace(token))
174 } else {
175 None
176 }
177 }
178
179 pub fn syntax(&self) -> SyntaxToken<'a> {
180 self.0
181 }
182
183 pub fn text(&self) -> &'a SmolStr {
184 self.0.text()
185 }
186
187 pub fn spans_multiple_lines(&self) -> bool {
188 let text = self.text();
189 text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n'))
190 }
191}
192
193impl Name { 111impl Name {
194 pub fn text(&self) -> &SmolStr { 112 pub fn text(&self) -> &SmolStr {
195 let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap(); 113 let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap();
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs
new file mode 100644
index 000000000..c830cdccf
--- /dev/null
+++ b/crates/ra_syntax/src/ast/tokens.rs
@@ -0,0 +1,93 @@
1use crate::{
2 SyntaxToken,
3 SyntaxKind::{COMMENT, WHITESPACE},
4 ast::AstToken,
5};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub struct Comment<'a>(SyntaxToken<'a>);
9
10impl<'a> AstToken<'a> for Comment<'a> {
11 fn cast(token: SyntaxToken<'a>) -> Option<Self> {
12 if token.kind() == COMMENT {
13 Some(Comment(token))
14 } else {
15 None
16 }
17 }
18 fn syntax(&self) -> SyntaxToken<'a> {
19 self.0
20 }
21}
22
23impl<'a> Comment<'a> {
24 pub fn flavor(&self) -> CommentFlavor {
25 let text = self.text();
26 if text.starts_with("///") {
27 CommentFlavor::Doc
28 } else if text.starts_with("//!") {
29 CommentFlavor::ModuleDoc
30 } else if text.starts_with("//") {
31 CommentFlavor::Line
32 } else {
33 CommentFlavor::Multiline
34 }
35 }
36
37 pub fn is_doc_comment(&self) -> bool {
38 self.flavor().is_doc_comment()
39 }
40
41 pub fn prefix(&self) -> &'static str {
42 self.flavor().prefix()
43 }
44}
45
46#[derive(Debug, PartialEq, Eq)]
47pub enum CommentFlavor {
48 Line,
49 Doc,
50 ModuleDoc,
51 Multiline,
52}
53
54impl CommentFlavor {
55 pub fn prefix(&self) -> &'static str {
56 use self::CommentFlavor::*;
57 match *self {
58 Line => "//",
59 Doc => "///",
60 ModuleDoc => "//!",
61 Multiline => "/*",
62 }
63 }
64
65 pub fn is_doc_comment(&self) -> bool {
66 match self {
67 CommentFlavor::Doc | CommentFlavor::ModuleDoc => true,
68 _ => false,
69 }
70 }
71}
72
73pub struct Whitespace<'a>(SyntaxToken<'a>);
74
75impl<'a> AstToken<'a> for Whitespace<'a> {
76 fn cast(token: SyntaxToken<'a>) -> Option<Self> {
77 if token.kind() == WHITESPACE {
78 Some(Whitespace(token))
79 } else {
80 None
81 }
82 }
83 fn syntax(&self) -> SyntaxToken<'a> {
84 self.0
85 }
86}
87
88impl<'a> Whitespace<'a> {
89 pub fn spans_multiple_lines(&self) -> bool {
90 let text = self.text();
91 text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n'))
92 }
93}
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index 85fe6d5e1..f9021d7bf 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -2,7 +2,7 @@ use itertools::Itertools;
2 2
3use crate::{ 3use crate::{
4 syntax_node::{SyntaxNodeChildren, SyntaxElementChildren}, 4 syntax_node::{SyntaxNodeChildren, SyntaxElementChildren},
5 ast::{self, child_opt, children, AstNode, AstChildren}, 5 ast::{self, child_opt, children, AstNode, AstToken, AstChildren},
6}; 6};
7 7
8pub trait TypeAscriptionOwner: AstNode { 8pub trait TypeAscriptionOwner: AstNode {