aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-09 21:23:27 +0100
committerGitHub <[email protected]>2020-04-09 21:23:27 +0100
commiteb07803e8106a66edfd80d078337dae240e92828 (patch)
treeae30dc5d6752f765b1ccefdcfd8af079a630133e
parent33df20868da38ca47f22f8bfab36dd4c965cf333 (diff)
parente07d3c94de4694f38aa87316018c0d4cf28be941 (diff)
Merge #3922
3922: Remove code duplication r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ra_syntax/src/ast.rs42
-rw-r--r--crates/ra_syntax/src/ast/edit.rs3
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs22
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs16
-rw-r--r--crates/ra_syntax/src/ast/traits.rs26
5 files changed, 49 insertions, 60 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 15a8279f3..cb701f7f6 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -42,11 +42,6 @@ pub trait AstNode {
42 fn syntax(&self) -> &SyntaxNode; 42 fn syntax(&self) -> &SyntaxNode;
43} 43}
44 44
45#[test]
46fn assert_ast_is_object_safe() {
47 fn _f(_: &dyn AstNode, _: &dyn NameOwner) {}
48}
49
50/// Like `AstNode`, but wraps tokens rather than interior nodes. 45/// Like `AstNode`, but wraps tokens rather than interior nodes.
51pub trait AstToken { 46pub trait AstToken {
52 fn can_cast(token: SyntaxKind) -> bool 47 fn can_cast(token: SyntaxKind) -> bool
@@ -64,22 +59,6 @@ pub trait AstToken {
64 } 59 }
65} 60}
66 61
67mod support {
68 use super::{AstChildren, AstNode, AstToken, SyntaxNode};
69
70 pub(super) fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
71 parent.children().find_map(N::cast)
72 }
73
74 pub(super) fn children<N: AstNode>(parent: &SyntaxNode) -> AstChildren<N> {
75 AstChildren::new(parent)
76 }
77
78 pub(super) fn token<T: AstToken>(parent: &SyntaxNode) -> Option<T> {
79 parent.children_with_tokens().filter_map(|it| it.into_token()).find_map(T::cast)
80 }
81}
82
83/// An iterator over `SyntaxNode` children of a particular AST type. 62/// An iterator over `SyntaxNode` children of a particular AST type.
84#[derive(Debug, Clone)] 63#[derive(Debug, Clone)]
85pub struct AstChildren<N> { 64pub struct AstChildren<N> {
@@ -100,12 +79,25 @@ impl<N: AstNode> Iterator for AstChildren<N> {
100 } 79 }
101} 80}
102 81
103fn child_opt<P: AstNode + ?Sized, C: AstNode>(parent: &P) -> Option<C> { 82mod support {
104 children(parent).next() 83 use super::{AstChildren, AstNode, AstToken, SyntaxNode};
84
85 pub(super) fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
86 parent.children().find_map(N::cast)
87 }
88
89 pub(super) fn children<N: AstNode>(parent: &SyntaxNode) -> AstChildren<N> {
90 AstChildren::new(parent)
91 }
92
93 pub(super) fn token<T: AstToken>(parent: &SyntaxNode) -> Option<T> {
94 parent.children_with_tokens().filter_map(|it| it.into_token()).find_map(T::cast)
95 }
105} 96}
106 97
107fn children<P: AstNode + ?Sized, C: AstNode>(parent: &P) -> AstChildren<C> { 98#[test]
108 AstChildren::new(parent.syntax()) 99fn assert_ast_is_object_safe() {
100 fn _f(_: &dyn AstNode, _: &dyn NameOwner) {}
109} 101}
110 102
111#[test] 103#[test]
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index 069c6ee82..3d428fab3 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -6,7 +6,7 @@ use std::{iter, ops::RangeInclusive};
6use arrayvec::ArrayVec; 6use arrayvec::ArrayVec;
7 7
8use crate::{ 8use crate::{
9 algo, 9 algo::{self, neighbor, SyntaxRewriter},
10 ast::{ 10 ast::{
11 self, 11 self,
12 make::{self, tokens}, 12 make::{self, tokens},
@@ -16,7 +16,6 @@ use crate::{
16 SyntaxKind::{ATTR, COMMENT, WHITESPACE}, 16 SyntaxKind::{ATTR, COMMENT, WHITESPACE},
17 SyntaxNode, SyntaxToken, T, 17 SyntaxNode, SyntaxToken, T,
18}; 18};
19use algo::{neighbor, SyntaxRewriter};
20 19
21impl ast::BinExpr { 20impl ast::BinExpr {
22 #[must_use] 21 #[must_use]
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index 40c8fca3b..003ee00b3 100644
--- a/crates/ra_syntax/src/ast/expr_extensions.rs
+++ b/crates/ra_syntax/src/ast/expr_extensions.rs
@@ -1,7 +1,7 @@
1//! Various extension methods to ast Expr Nodes, which are hard to code-generate. 1//! Various extension methods to ast Expr Nodes, which are hard to code-generate.
2 2
3use crate::{ 3use crate::{
4 ast::{self, child_opt, children, AstChildren, AstNode}, 4 ast::{self, support, AstChildren, AstNode},
5 SmolStr, 5 SmolStr,
6 SyntaxKind::*, 6 SyntaxKind::*,
7 SyntaxToken, T, 7 SyntaxToken, T,
@@ -36,7 +36,7 @@ impl ast::IfExpr {
36 let res = match self.blocks().nth(1) { 36 let res = match self.blocks().nth(1) {
37 Some(block) => ElseBranch::Block(block), 37 Some(block) => ElseBranch::Block(block),
38 None => { 38 None => {
39 let elif: ast::IfExpr = child_opt(self)?; 39 let elif: ast::IfExpr = support::child(self.syntax())?;
40 ElseBranch::IfExpr(elif) 40 ElseBranch::IfExpr(elif)
41 } 41 }
42 }; 42 };
@@ -44,7 +44,7 @@ impl ast::IfExpr {
44 } 44 }
45 45
46 fn blocks(&self) -> AstChildren<ast::BlockExpr> { 46 fn blocks(&self) -> AstChildren<ast::BlockExpr> {
47 children(self) 47 support::children(self.syntax())
48 } 48 }
49} 49}
50 50
@@ -212,15 +212,15 @@ impl ast::BinExpr {
212 } 212 }
213 213
214 pub fn lhs(&self) -> Option<ast::Expr> { 214 pub fn lhs(&self) -> Option<ast::Expr> {
215 children(self).next() 215 support::children(self.syntax()).next()
216 } 216 }
217 217
218 pub fn rhs(&self) -> Option<ast::Expr> { 218 pub fn rhs(&self) -> Option<ast::Expr> {
219 children(self).nth(1) 219 support::children(self.syntax()).nth(1)
220 } 220 }
221 221
222 pub fn sub_exprs(&self) -> (Option<ast::Expr>, Option<ast::Expr>) { 222 pub fn sub_exprs(&self) -> (Option<ast::Expr>, Option<ast::Expr>) {
223 let mut children = children(self); 223 let mut children = support::children(self.syntax());
224 let first = children.next(); 224 let first = children.next();
225 let second = children.next(); 225 let second = children.next();
226 (first, second) 226 (first, second)
@@ -275,10 +275,10 @@ impl ast::RangeExpr {
275 275
276impl ast::IndexExpr { 276impl ast::IndexExpr {
277 pub fn base(&self) -> Option<ast::Expr> { 277 pub fn base(&self) -> Option<ast::Expr> {
278 children(self).next() 278 support::children(self.syntax()).next()
279 } 279 }
280 pub fn index(&self) -> Option<ast::Expr> { 280 pub fn index(&self) -> Option<ast::Expr> {
281 children(self).nth(1) 281 support::children(self.syntax()).nth(1)
282 } 282 }
283} 283}
284 284
@@ -291,11 +291,11 @@ impl ast::ArrayExpr {
291 pub fn kind(&self) -> ArrayExprKind { 291 pub fn kind(&self) -> ArrayExprKind {
292 if self.is_repeat() { 292 if self.is_repeat() {
293 ArrayExprKind::Repeat { 293 ArrayExprKind::Repeat {
294 initializer: children(self).next(), 294 initializer: support::children(self.syntax()).next(),
295 repeat: children(self).nth(1), 295 repeat: support::children(self.syntax()).nth(1),
296 } 296 }
297 } else { 297 } else {
298 ArrayExprKind::ElementList(children(self)) 298 ArrayExprKind::ElementList(support::children(self.syntax()))
299 } 299 }
300 } 300 }
301 301
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index b50a89864..fc252e79c 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -5,9 +5,7 @@ use itertools::Itertools;
5use ra_parser::SyntaxKind; 5use ra_parser::SyntaxKind;
6 6
7use crate::{ 7use crate::{
8 ast::{ 8 ast::{self, support, AstNode, AstToken, AttrInput, NameOwner, SyntaxNode},
9 self, child_opt, children, support, AstNode, AstToken, AttrInput, NameOwner, SyntaxNode,
10 },
11 SmolStr, SyntaxElement, SyntaxToken, T, 9 SmolStr, SyntaxElement, SyntaxToken, T,
12}; 10};
13 11
@@ -161,7 +159,7 @@ impl ast::ImplDef {
161 } 159 }
162 160
163 fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) { 161 fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) {
164 let mut types = children(self); 162 let mut types = support::children(self.syntax());
165 let first = types.next(); 163 let first = types.next();
166 let second = types.next(); 164 let second = types.next();
167 (first, second) 165 (first, second)
@@ -177,9 +175,9 @@ pub enum StructKind {
177 175
178impl StructKind { 176impl StructKind {
179 fn from_node<N: AstNode>(node: &N) -> StructKind { 177 fn from_node<N: AstNode>(node: &N) -> StructKind {
180 if let Some(nfdl) = child_opt::<_, ast::RecordFieldDefList>(node) { 178 if let Some(nfdl) = support::child::<ast::RecordFieldDefList>(node.syntax()) {
181 StructKind::Record(nfdl) 179 StructKind::Record(nfdl)
182 } else if let Some(pfl) = child_opt::<_, ast::TupleFieldDefList>(node) { 180 } else if let Some(pfl) = support::child::<ast::TupleFieldDefList>(node.syntax()) {
183 StructKind::Tuple(pfl) 181 StructKind::Tuple(pfl)
184 } else { 182 } else {
185 StructKind::Unit 183 StructKind::Unit
@@ -322,9 +320,9 @@ pub enum TypeBoundKind {
322 320
323impl ast::TypeBound { 321impl ast::TypeBound {
324 pub fn kind(&self) -> TypeBoundKind { 322 pub fn kind(&self) -> TypeBoundKind {
325 if let Some(path_type) = children(self).next() { 323 if let Some(path_type) = support::children(self.syntax()).next() {
326 TypeBoundKind::PathType(path_type) 324 TypeBoundKind::PathType(path_type)
327 } else if let Some(for_type) = children(self).next() { 325 } else if let Some(for_type) = support::children(self.syntax()).next() {
328 TypeBoundKind::ForType(for_type) 326 TypeBoundKind::ForType(for_type)
329 } else if let Some(lifetime) = self.lifetime_token() { 327 } else if let Some(lifetime) = self.lifetime_token() {
330 TypeBoundKind::Lifetime(lifetime) 328 TypeBoundKind::Lifetime(lifetime)
@@ -364,7 +362,7 @@ pub enum VisibilityKind {
364 362
365impl ast::Visibility { 363impl ast::Visibility {
366 pub fn kind(&self) -> VisibilityKind { 364 pub fn kind(&self) -> VisibilityKind {
367 if let Some(path) = children(self).next() { 365 if let Some(path) = support::children(self.syntax()).next() {
368 VisibilityKind::In(path) 366 VisibilityKind::In(path)
369 } else if self.crate_kw_token().is_some() { 367 } else if self.crate_kw_token().is_some() {
370 VisibilityKind::PubCrate 368 VisibilityKind::PubCrate
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index 870e83804..f6c786e44 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -5,69 +5,69 @@
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use crate::{ 7use crate::{
8 ast::{self, child_opt, children, support, AstChildren, AstNode, AstToken}, 8 ast::{self, support, AstChildren, AstNode, AstToken},
9 syntax_node::SyntaxElementChildren, 9 syntax_node::SyntaxElementChildren,
10}; 10};
11 11
12pub trait TypeAscriptionOwner: AstNode { 12pub trait TypeAscriptionOwner: AstNode {
13 fn ascribed_type(&self) -> Option<ast::TypeRef> { 13 fn ascribed_type(&self) -> Option<ast::TypeRef> {
14 child_opt(self) 14 support::child(self.syntax())
15 } 15 }
16} 16}
17 17
18pub trait NameOwner: AstNode { 18pub trait NameOwner: AstNode {
19 fn name(&self) -> Option<ast::Name> { 19 fn name(&self) -> Option<ast::Name> {
20 child_opt(self) 20 support::child(self.syntax())
21 } 21 }
22} 22}
23 23
24pub trait VisibilityOwner: AstNode { 24pub trait VisibilityOwner: AstNode {
25 fn visibility(&self) -> Option<ast::Visibility> { 25 fn visibility(&self) -> Option<ast::Visibility> {
26 child_opt(self) 26 support::child(self.syntax())
27 } 27 }
28} 28}
29 29
30pub trait LoopBodyOwner: AstNode { 30pub trait LoopBodyOwner: AstNode {
31 fn loop_body(&self) -> Option<ast::BlockExpr> { 31 fn loop_body(&self) -> Option<ast::BlockExpr> {
32 child_opt(self) 32 support::child(self.syntax())
33 } 33 }
34 34
35 fn label(&self) -> Option<ast::Label> { 35 fn label(&self) -> Option<ast::Label> {
36 child_opt(self) 36 support::child(self.syntax())
37 } 37 }
38} 38}
39 39
40pub trait ArgListOwner: AstNode { 40pub trait ArgListOwner: AstNode {
41 fn arg_list(&self) -> Option<ast::ArgList> { 41 fn arg_list(&self) -> Option<ast::ArgList> {
42 child_opt(self) 42 support::child(self.syntax())
43 } 43 }
44} 44}
45 45
46pub trait FnDefOwner: AstNode { 46pub trait FnDefOwner: AstNode {
47 fn functions(&self) -> AstChildren<ast::FnDef> { 47 fn functions(&self) -> AstChildren<ast::FnDef> {
48 children(self) 48 support::children(self.syntax())
49 } 49 }
50} 50}
51 51
52pub trait ModuleItemOwner: AstNode { 52pub trait ModuleItemOwner: AstNode {
53 fn items(&self) -> AstChildren<ast::ModuleItem> { 53 fn items(&self) -> AstChildren<ast::ModuleItem> {
54 children(self) 54 support::children(self.syntax())
55 } 55 }
56} 56}
57 57
58pub trait TypeParamsOwner: AstNode { 58pub trait TypeParamsOwner: AstNode {
59 fn type_param_list(&self) -> Option<ast::TypeParamList> { 59 fn type_param_list(&self) -> Option<ast::TypeParamList> {
60 child_opt(self) 60 support::child(self.syntax())
61 } 61 }
62 62
63 fn where_clause(&self) -> Option<ast::WhereClause> { 63 fn where_clause(&self) -> Option<ast::WhereClause> {
64 child_opt(self) 64 support::child(self.syntax())
65 } 65 }
66} 66}
67 67
68pub trait TypeBoundsOwner: AstNode { 68pub trait TypeBoundsOwner: AstNode {
69 fn type_bound_list(&self) -> Option<ast::TypeBoundList> { 69 fn type_bound_list(&self) -> Option<ast::TypeBoundList> {
70 child_opt(self) 70 support::child(self.syntax())
71 } 71 }
72 72
73 fn colon(&self) -> Option<ast::Colon> { 73 fn colon(&self) -> Option<ast::Colon> {
@@ -77,7 +77,7 @@ pub trait TypeBoundsOwner: AstNode {
77 77
78pub trait AttrsOwner: AstNode { 78pub trait AttrsOwner: AstNode {
79 fn attrs(&self) -> AstChildren<ast::Attr> { 79 fn attrs(&self) -> AstChildren<ast::Attr> {
80 children(self) 80 support::children(self.syntax())
81 } 81 }
82 fn has_atom_attr(&self, atom: &str) -> bool { 82 fn has_atom_attr(&self, atom: &str) -> bool {
83 self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom) 83 self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom)