aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-08 09:05:55 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-08 09:05:55 +0000
commit3f4be819125ce4a22edd86721fa56b5caba99c2e (patch)
treebe93895ddc08c911585d9f7bc64623a3741f32c6 /crates/ra_syntax/src/ast.rs
parent4e444d2bc24d16284401444fd2154f63e0f96070 (diff)
parent122410d7aa34a32d468a3173858cbc8a2bbc68f5 (diff)
Merge #449
449: switch to new rowan API r=matklad a=matklad closes https://github.com/rust-analyzer/rust-analyzer/issues/448 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src/ast.rs')
-rw-r--r--crates/ra_syntax/src/ast.rs210
1 files changed, 103 insertions, 107 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 9ab59738f..0e303ee98 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -1,119 +1,115 @@
1mod generated; 1mod generated;
2 2
3use std::marker::PhantomData; 3use std::marker::PhantomData;
4use std::string::String as RustString;
5 4
6use itertools::Itertools; 5use itertools::Itertools;
7 6
8pub use self::generated::*; 7pub use self::generated::*;
9use crate::{ 8use crate::{
10 yellow::{RefRoot, SyntaxNodeChildren}, 9 yellow::{SyntaxNode, SyntaxNodeChildren, TreePtr, RaTypes},
11 SmolStr, 10 SmolStr,
12 SyntaxKind::*, 11 SyntaxKind::*,
13 SyntaxNodeRef,
14}; 12};
15 13
16/// The main trait to go from untyped `SyntaxNode` to a typed ast. The 14/// The main trait to go from untyped `SyntaxNode` to a typed ast. The
17/// conversion itself has zero runtime cost: ast and syntax nodes have exactly 15/// conversion itself has zero runtime cost: ast and syntax nodes have exactly
18/// the same representation: a pointer to the tree root and a pointer to the 16/// the same representation: a pointer to the tree root and a pointer to the
19/// node itself. 17/// node itself.
20pub trait AstNode<'a>: Clone + Copy + 'a { 18pub trait AstNode: rowan::TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>> {
21 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> 19 fn cast(syntax: &SyntaxNode) -> Option<&Self>
22 where 20 where
23 Self: Sized; 21 Self: Sized;
24 fn syntax(self) -> SyntaxNodeRef<'a>; 22 fn syntax(&self) -> &SyntaxNode;
23 fn to_owned(&self) -> TreePtr<Self>;
25} 24}
26 25
27pub trait NameOwner<'a>: AstNode<'a> { 26pub trait NameOwner: AstNode {
28 fn name(self) -> Option<Name<'a>> { 27 fn name(&self) -> Option<&Name> {
29 child_opt(self) 28 child_opt(self)
30 } 29 }
31} 30}
32 31
33pub trait VisibilityOwner<'a>: AstNode<'a> { 32pub trait VisibilityOwner: AstNode {
34 fn visibility(self) -> Option<Visibility<'a>> { 33 fn visibility(&self) -> Option<&Visibility> {
35 child_opt(self) 34 child_opt(self)
36 } 35 }
37} 36}
38 37
39pub trait LoopBodyOwner<'a>: AstNode<'a> { 38pub trait LoopBodyOwner: AstNode {
40 fn loop_body(self) -> Option<Block<'a>> { 39 fn loop_body(&self) -> Option<&Block> {
41 child_opt(self) 40 child_opt(self)
42 } 41 }
43} 42}
44 43
45pub trait ArgListOwner<'a>: AstNode<'a> { 44pub trait ArgListOwner: AstNode {
46 fn arg_list(self) -> Option<ArgList<'a>> { 45 fn arg_list(&self) -> Option<&ArgList> {
47 child_opt(self) 46 child_opt(self)
48 } 47 }
49} 48}
50 49
51pub trait FnDefOwner<'a>: AstNode<'a> { 50pub trait FnDefOwner: AstNode {
52 fn functions(self) -> AstChildren<'a, FnDef<'a>> { 51 fn functions(&self) -> AstChildren<FnDef> {
53 children(self) 52 children(self)
54 } 53 }
55} 54}
56 55
57// ModuleItem
58#[derive(Debug, Clone, Copy, PartialEq, Eq)] 56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum ItemOrMacro<'a> { 57pub enum ItemOrMacro<'a> {
60 Item(ModuleItem<'a>), 58 Item(&'a ModuleItem),
61 Macro(MacroCall<'a>), 59 Macro(&'a MacroCall),
62} 60}
63 61
64impl<'a> AstNode<'a> for ItemOrMacro<'a> { 62pub trait ModuleItemOwner: AstNode {
65 fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { 63 fn items(&self) -> AstChildren<ModuleItem> {
66 let res = if let Some(item) = ModuleItem::cast(syntax) { 64 children(self)
67 ItemOrMacro::Item(item)
68 } else if let Some(macro_call) = MacroCall::cast(syntax) {
69 ItemOrMacro::Macro(macro_call)
70 } else {
71 return None;
72 };
73 Some(res)
74 } 65 }
75 fn syntax(self) -> SyntaxNodeRef<'a> { 66 fn items_with_macros(&self) -> ItemOrMacroIter {
76 match self { 67 ItemOrMacroIter(self.syntax().children())
77 ItemOrMacro::Item(it) => it.syntax(),
78 ItemOrMacro::Macro(it) => it.syntax(),
79 }
80 } 68 }
81} 69}
82 70
83pub trait ModuleItemOwner<'a>: AstNode<'a> { 71#[derive(Debug)]
84 fn items(self) -> AstChildren<'a, ModuleItem<'a>> { 72pub struct ItemOrMacroIter<'a>(SyntaxNodeChildren<'a>);
85 children(self)
86 }
87 73
88 fn items_with_macros(self) -> AstChildren<'a, ItemOrMacro<'a>> { 74impl<'a> Iterator for ItemOrMacroIter<'a> {
89 children(self) 75 type Item = ItemOrMacro<'a>;
76 fn next(&mut self) -> Option<ItemOrMacro<'a>> {
77 loop {
78 let n = self.0.next()?;
79 if let Some(item) = ModuleItem::cast(n) {
80 return Some(ItemOrMacro::Item(item));
81 }
82 if let Some(call) = MacroCall::cast(n) {
83 return Some(ItemOrMacro::Macro(call));
84 }
85 }
90 } 86 }
91} 87}
92 88
93pub trait TypeParamsOwner<'a>: AstNode<'a> { 89pub trait TypeParamsOwner: AstNode {
94 fn type_param_list(self) -> Option<TypeParamList<'a>> { 90 fn type_param_list(&self) -> Option<&TypeParamList> {
95 child_opt(self) 91 child_opt(self)
96 } 92 }
97 93
98 fn where_clause(self) -> Option<WhereClause<'a>> { 94 fn where_clause(&self) -> Option<&WhereClause> {
99 child_opt(self) 95 child_opt(self)
100 } 96 }
101} 97}
102 98
103pub trait AttrsOwner<'a>: AstNode<'a> { 99pub trait AttrsOwner: AstNode {
104 fn attrs(self) -> AstChildren<'a, Attr<'a>> { 100 fn attrs(&self) -> AstChildren<Attr> {
105 children(self) 101 children(self)
106 } 102 }
107} 103}
108 104
109pub trait DocCommentsOwner<'a>: AstNode<'a> { 105pub trait DocCommentsOwner: AstNode {
110 fn doc_comments(self) -> AstChildren<'a, Comment<'a>> { 106 fn doc_comments(&self) -> AstChildren<Comment> {
111 children(self) 107 children(self)
112 } 108 }
113 109
114 /// Returns the textual content of a doc comment block as a single string. 110 /// Returns the textual content of a doc comment block as a single string.
115 /// That is, strips leading `///` and joins lines 111 /// That is, strips leading `///` and joins lines
116 fn doc_comment_text(self) -> RustString { 112 fn doc_comment_text(&self) -> std::string::String {
117 self.doc_comments() 113 self.doc_comments()
118 .filter(|comment| comment.is_doc_comment()) 114 .filter(|comment| comment.is_doc_comment())
119 .map(|comment| { 115 .map(|comment| {
@@ -130,13 +126,13 @@ pub trait DocCommentsOwner<'a>: AstNode<'a> {
130 } 126 }
131} 127}
132 128
133impl<'a> FnDef<'a> { 129impl FnDef {
134 pub fn has_atom_attr(&self, atom: &str) -> bool { 130 pub fn has_atom_attr(&self, atom: &str) -> bool {
135 self.attrs().filter_map(|x| x.as_atom()).any(|x| x == atom) 131 self.attrs().filter_map(|x| x.as_atom()).any(|x| x == atom)
136 } 132 }
137} 133}
138 134
139impl<'a> Attr<'a> { 135impl Attr {
140 pub fn as_atom(&self) -> Option<SmolStr> { 136 pub fn as_atom(&self) -> Option<SmolStr> {
141 let tt = self.value()?; 137 let tt = self.value()?;
142 let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; 138 let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?;
@@ -147,7 +143,7 @@ impl<'a> Attr<'a> {
147 } 143 }
148 } 144 }
149 145
150 pub fn as_call(&self) -> Option<(SmolStr, TokenTree<'a>)> { 146 pub fn as_call(&self) -> Option<(SmolStr, &TokenTree)> {
151 let tt = self.value()?; 147 let tt = self.value()?;
152 let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; 148 let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?;
153 let args = TokenTree::cast(args)?; 149 let args = TokenTree::cast(args)?;
@@ -159,37 +155,37 @@ impl<'a> Attr<'a> {
159 } 155 }
160} 156}
161 157
162impl<'a> Lifetime<'a> { 158impl Lifetime {
163 pub fn text(&self) -> SmolStr { 159 pub fn text(&self) -> SmolStr {
164 self.syntax().leaf_text().unwrap().clone() 160 self.syntax().leaf_text().unwrap().clone()
165 } 161 }
166} 162}
167 163
168impl<'a> Char<'a> { 164impl Char {
169 pub fn text(&self) -> &SmolStr { 165 pub fn text(&self) -> &SmolStr {
170 &self.syntax().leaf_text().unwrap() 166 &self.syntax().leaf_text().unwrap()
171 } 167 }
172} 168}
173 169
174impl<'a> Byte<'a> { 170impl Byte {
175 pub fn text(&self) -> &SmolStr { 171 pub fn text(&self) -> &SmolStr {
176 &self.syntax().leaf_text().unwrap() 172 &self.syntax().leaf_text().unwrap()
177 } 173 }
178} 174}
179 175
180impl<'a> ByteString<'a> { 176impl ByteString {
181 pub fn text(&self) -> &SmolStr { 177 pub fn text(&self) -> &SmolStr {
182 &self.syntax().leaf_text().unwrap() 178 &self.syntax().leaf_text().unwrap()
183 } 179 }
184} 180}
185 181
186impl<'a> String<'a> { 182impl String {
187 pub fn text(&self) -> &SmolStr { 183 pub fn text(&self) -> &SmolStr {
188 &self.syntax().leaf_text().unwrap() 184 &self.syntax().leaf_text().unwrap()
189 } 185 }
190} 186}
191 187
192impl<'a> Comment<'a> { 188impl Comment {
193 pub fn text(&self) -> &SmolStr { 189 pub fn text(&self) -> &SmolStr {
194 self.syntax().leaf_text().unwrap() 190 self.syntax().leaf_text().unwrap()
195 } 191 }
@@ -251,7 +247,7 @@ impl CommentFlavor {
251 } 247 }
252} 248}
253 249
254impl<'a> Whitespace<'a> { 250impl Whitespace {
255 pub fn text(&self) -> &SmolStr { 251 pub fn text(&self) -> &SmolStr {
256 &self.syntax().leaf_text().unwrap() 252 &self.syntax().leaf_text().unwrap()
257 } 253 }
@@ -265,36 +261,36 @@ impl<'a> Whitespace<'a> {
265 } 261 }
266} 262}
267 263
268impl<'a> Name<'a> { 264impl Name {
269 pub fn text(&self) -> SmolStr { 265 pub fn text(&self) -> SmolStr {
270 let ident = self.syntax().first_child().unwrap(); 266 let ident = self.syntax().first_child().unwrap();
271 ident.leaf_text().unwrap().clone() 267 ident.leaf_text().unwrap().clone()
272 } 268 }
273} 269}
274 270
275impl<'a> NameRef<'a> { 271impl NameRef {
276 pub fn text(&self) -> SmolStr { 272 pub fn text(&self) -> SmolStr {
277 let ident = self.syntax().first_child().unwrap(); 273 let ident = self.syntax().first_child().unwrap();
278 ident.leaf_text().unwrap().clone() 274 ident.leaf_text().unwrap().clone()
279 } 275 }
280} 276}
281 277
282impl<'a> ImplBlock<'a> { 278impl ImplBlock {
283 pub fn target_type(self) -> Option<TypeRef<'a>> { 279 pub fn target_type(&self) -> Option<&TypeRef> {
284 match self.target() { 280 match self.target() {
285 (Some(t), None) | (_, Some(t)) => Some(t), 281 (Some(t), None) | (_, Some(t)) => Some(t),
286 _ => None, 282 _ => None,
287 } 283 }
288 } 284 }
289 285
290 pub fn target_trait(self) -> Option<TypeRef<'a>> { 286 pub fn target_trait(&self) -> Option<&TypeRef> {
291 match self.target() { 287 match self.target() {
292 (Some(t), Some(_)) => Some(t), 288 (Some(t), Some(_)) => Some(t),
293 _ => None, 289 _ => None,
294 } 290 }
295 } 291 }
296 292
297 fn target(self) -> (Option<TypeRef<'a>>, Option<TypeRef<'a>>) { 293 fn target(&self) -> (Option<&TypeRef>, Option<&TypeRef>) {
298 let mut types = children(self); 294 let mut types = children(self);
299 let first = types.next(); 295 let first = types.next();
300 let second = types.next(); 296 let second = types.next();
@@ -302,8 +298,8 @@ impl<'a> ImplBlock<'a> {
302 } 298 }
303} 299}
304 300
305impl<'a> Module<'a> { 301impl Module {
306 pub fn has_semi(self) -> bool { 302 pub fn has_semi(&self) -> bool {
307 match self.syntax().last_child() { 303 match self.syntax().last_child() {
308 None => false, 304 None => false,
309 Some(node) => node.kind() == SEMI, 305 Some(node) => node.kind() == SEMI,
@@ -311,8 +307,8 @@ impl<'a> Module<'a> {
311 } 307 }
312} 308}
313 309
314impl<'a> LetStmt<'a> { 310impl LetStmt {
315 pub fn has_semi(self) -> bool { 311 pub fn has_semi(&self) -> bool {
316 match self.syntax().last_child() { 312 match self.syntax().last_child() {
317 None => false, 313 None => false,
318 Some(node) => node.kind() == SEMI, 314 Some(node) => node.kind() == SEMI,
@@ -320,35 +316,35 @@ impl<'a> LetStmt<'a> {
320 } 316 }
321} 317}
322 318
323impl<'a> IfExpr<'a> { 319impl IfExpr {
324 pub fn then_branch(self) -> Option<Block<'a>> { 320 pub fn then_branch(&self) -> Option<&Block> {
325 self.blocks().nth(0) 321 self.blocks().nth(0)
326 } 322 }
327 pub fn else_branch(self) -> Option<Block<'a>> { 323 pub fn else_branch(&self) -> Option<&Block> {
328 self.blocks().nth(1) 324 self.blocks().nth(1)
329 } 325 }
330 fn blocks(self) -> AstChildren<'a, Block<'a>> { 326 fn blocks(&self) -> AstChildren<Block> {
331 children(self) 327 children(self)
332 } 328 }
333} 329}
334 330
335#[derive(Debug, Clone, Copy, PartialEq, Eq)] 331#[derive(Debug, Clone, Copy, PartialEq, Eq)]
336pub enum PathSegmentKind<'a> { 332pub enum PathSegmentKind<'a> {
337 Name(NameRef<'a>), 333 Name(&'a NameRef),
338 SelfKw, 334 SelfKw,
339 SuperKw, 335 SuperKw,
340 CrateKw, 336 CrateKw,
341} 337}
342 338
343impl<'a> PathSegment<'a> { 339impl PathSegment {
344 pub fn parent_path(self) -> Path<'a> { 340 pub fn parent_path(&self) -> &Path {
345 self.syntax() 341 self.syntax()
346 .parent() 342 .parent()
347 .and_then(Path::cast) 343 .and_then(Path::cast)
348 .expect("segments are always nested in paths") 344 .expect("segments are always nested in paths")
349 } 345 }
350 346
351 pub fn kind(self) -> Option<PathSegmentKind<'a>> { 347 pub fn kind(&self) -> Option<PathSegmentKind> {
352 let res = if let Some(name_ref) = self.name_ref() { 348 let res = if let Some(name_ref) = self.name_ref() {
353 PathSegmentKind::Name(name_ref) 349 PathSegmentKind::Name(name_ref)
354 } else { 350 } else {
@@ -363,20 +359,20 @@ impl<'a> PathSegment<'a> {
363 } 359 }
364} 360}
365 361
366impl<'a> Path<'a> { 362impl Path {
367 pub fn parent_path(self) -> Option<Path<'a>> { 363 pub fn parent_path(&self) -> Option<&Path> {
368 self.syntax().parent().and_then(Path::cast) 364 self.syntax().parent().and_then(Path::cast)
369 } 365 }
370} 366}
371 367
372impl<'a> UseTree<'a> { 368impl UseTree {
373 pub fn has_star(self) -> bool { 369 pub fn has_star(&self) -> bool {
374 self.syntax().children().any(|it| it.kind() == STAR) 370 self.syntax().children().any(|it| it.kind() == STAR)
375 } 371 }
376} 372}
377 373
378impl<'a> UseTreeList<'a> { 374impl UseTreeList {
379 pub fn parent_use_tree(self) -> UseTree<'a> { 375 pub fn parent_use_tree(&self) -> &UseTree {
380 self.syntax() 376 self.syntax()
381 .parent() 377 .parent()
382 .and_then(UseTree::cast) 378 .and_then(UseTree::cast)
@@ -384,22 +380,22 @@ impl<'a> UseTreeList<'a> {
384 } 380 }
385} 381}
386 382
387fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> { 383fn child_opt<P: AstNode, C: AstNode>(parent: &P) -> Option<&C> {
388 children(parent).next() 384 children(parent).next()
389} 385}
390 386
391fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstChildren<'a, C> { 387fn children<P: AstNode, C: AstNode>(parent: &P) -> AstChildren<C> {
392 AstChildren::new(parent.syntax()) 388 AstChildren::new(parent.syntax())
393} 389}
394 390
395#[derive(Debug)] 391#[derive(Debug)]
396pub struct AstChildren<'a, N> { 392pub struct AstChildren<'a, N> {
397 inner: SyntaxNodeChildren<RefRoot<'a>>, 393 inner: SyntaxNodeChildren<'a>,
398 ph: PhantomData<N>, 394 ph: PhantomData<N>,
399} 395}
400 396
401impl<'a, N> AstChildren<'a, N> { 397impl<'a, N> AstChildren<'a, N> {
402 fn new(parent: SyntaxNodeRef<'a>) -> Self { 398 fn new(parent: &'a SyntaxNode) -> Self {
403 AstChildren { 399 AstChildren {
404 inner: parent.children(), 400 inner: parent.children(),
405 ph: PhantomData, 401 ph: PhantomData,
@@ -407,9 +403,9 @@ impl<'a, N> AstChildren<'a, N> {
407 } 403 }
408} 404}
409 405
410impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> { 406impl<'a, N: AstNode + 'a> Iterator for AstChildren<'a, N> {
411 type Item = N; 407 type Item = &'a N;
412 fn next(&mut self) -> Option<N> { 408 fn next(&mut self) -> Option<&'a N> {
413 loop { 409 loop {
414 if let Some(n) = N::cast(self.inner.next()?) { 410 if let Some(n) = N::cast(self.inner.next()?) {
415 return Some(n); 411 return Some(n);
@@ -420,13 +416,13 @@ impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> {
420 416
421#[derive(Debug, Clone, PartialEq, Eq)] 417#[derive(Debug, Clone, PartialEq, Eq)]
422pub enum StructFlavor<'a> { 418pub enum StructFlavor<'a> {
423 Tuple(PosFieldList<'a>), 419 Tuple(&'a PosFieldList),
424 Named(NamedFieldDefList<'a>), 420 Named(&'a NamedFieldDefList),
425 Unit, 421 Unit,
426} 422}
427 423
428impl<'a> StructFlavor<'a> { 424impl StructFlavor<'_> {
429 fn from_node<N: AstNode<'a>>(node: N) -> StructFlavor<'a> { 425 fn from_node<N: AstNode>(node: &N) -> StructFlavor {
430 if let Some(nfdl) = child_opt::<_, NamedFieldDefList>(node) { 426 if let Some(nfdl) = child_opt::<_, NamedFieldDefList>(node) {
431 StructFlavor::Named(nfdl) 427 StructFlavor::Named(nfdl)
432 } else if let Some(pfl) = child_opt::<_, PosFieldList>(node) { 428 } else if let Some(pfl) = child_opt::<_, PosFieldList>(node) {
@@ -437,31 +433,31 @@ impl<'a> StructFlavor<'a> {
437 } 433 }
438} 434}
439 435
440impl<'a> StructDef<'a> { 436impl StructDef {
441 pub fn flavor(self) -> StructFlavor<'a> { 437 pub fn flavor(&self) -> StructFlavor {
442 StructFlavor::from_node(self) 438 StructFlavor::from_node(self)
443 } 439 }
444} 440}
445 441
446impl<'a> EnumVariant<'a> { 442impl EnumVariant {
447 pub fn flavor(self) -> StructFlavor<'a> { 443 pub fn flavor(&self) -> StructFlavor {
448 StructFlavor::from_node(self) 444 StructFlavor::from_node(self)
449 } 445 }
450} 446}
451 447
452impl<'a> PointerType<'a> { 448impl PointerType {
453 pub fn is_mut(&self) -> bool { 449 pub fn is_mut(&self) -> bool {
454 self.syntax().children().any(|n| n.kind() == MUT_KW) 450 self.syntax().children().any(|n| n.kind() == MUT_KW)
455 } 451 }
456} 452}
457 453
458impl<'a> ReferenceType<'a> { 454impl ReferenceType {
459 pub fn is_mut(&self) -> bool { 455 pub fn is_mut(&self) -> bool {
460 self.syntax().children().any(|n| n.kind() == MUT_KW) 456 self.syntax().children().any(|n| n.kind() == MUT_KW)
461 } 457 }
462} 458}
463 459
464impl<'a> RefExpr<'a> { 460impl RefExpr {
465 pub fn is_mut(&self) -> bool { 461 pub fn is_mut(&self) -> bool {
466 self.syntax().children().any(|n| n.kind() == MUT_KW) 462 self.syntax().children().any(|n| n.kind() == MUT_KW)
467 } 463 }
@@ -477,7 +473,7 @@ pub enum PrefixOp {
477 Neg, 473 Neg,
478} 474}
479 475
480impl<'a> PrefixExpr<'a> { 476impl PrefixExpr {
481 pub fn op(&self) -> Option<PrefixOp> { 477 pub fn op(&self) -> Option<PrefixOp> {
482 match self.syntax().first_child()?.kind() { 478 match self.syntax().first_child()?.kind() {
483 STAR => Some(PrefixOp::Deref), 479 STAR => Some(PrefixOp::Deref),
@@ -552,7 +548,7 @@ pub enum BinOp {
552 BitXorAssign, 548 BitXorAssign,
553} 549}
554 550
555impl<'a> BinExpr<'a> { 551impl BinExpr {
556 pub fn op(&self) -> Option<BinOp> { 552 pub fn op(&self) -> Option<BinOp> {
557 self.syntax() 553 self.syntax()
558 .children() 554 .children()
@@ -592,15 +588,15 @@ impl<'a> BinExpr<'a> {
592 .next() 588 .next()
593 } 589 }
594 590
595 pub fn lhs(self) -> Option<Expr<'a>> { 591 pub fn lhs(&self) -> Option<&Expr> {
596 children(self).nth(0) 592 children(self).nth(0)
597 } 593 }
598 594
599 pub fn rhs(self) -> Option<Expr<'a>> { 595 pub fn rhs(&self) -> Option<&Expr> {
600 children(self).nth(1) 596 children(self).nth(1)
601 } 597 }
602 598
603 pub fn sub_exprs(self) -> (Option<Expr<'a>>, Option<Expr<'a>>) { 599 pub fn sub_exprs(&self) -> (Option<&Expr>, Option<&Expr>) {
604 let mut children = children(self); 600 let mut children = children(self);
605 let first = children.next(); 601 let first = children.next();
606 let second = children.next(); 602 let second = children.next();
@@ -618,7 +614,7 @@ pub enum SelfParamFlavor {
618 MutRef, 614 MutRef,
619} 615}
620 616
621impl<'a> SelfParam<'a> { 617impl SelfParam {
622 pub fn flavor(&self) -> SelfParamFlavor { 618 pub fn flavor(&self) -> SelfParamFlavor {
623 let borrowed = self.syntax().children().any(|n| n.kind() == AMP); 619 let borrowed = self.syntax().children().any(|n| n.kind() == AMP);
624 if borrowed { 620 if borrowed {
@@ -641,7 +637,7 @@ impl<'a> SelfParam<'a> {
641 637
642#[test] 638#[test]
643fn test_doc_comment_of_items() { 639fn test_doc_comment_of_items() {
644 let file = SourceFileNode::parse( 640 let file = SourceFile::parse(
645 r#" 641 r#"
646 //! doc 642 //! doc
647 // non-doc 643 // non-doc