aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax/src/ast')
-rw-r--r--crates/syntax/src/ast/edit.rs52
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs44
-rw-r--r--crates/syntax/src/ast/expr_ext.rs44
-rw-r--r--crates/syntax/src/ast/make.rs4
-rw-r--r--crates/syntax/src/ast/node_ext.rs28
-rw-r--r--crates/syntax/src/ast/token_ext.rs10
6 files changed, 93 insertions, 89 deletions
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 64fac13a7..18820786a 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -9,7 +9,7 @@ use std::{
9use arrayvec::ArrayVec; 9use arrayvec::ArrayVec;
10 10
11use crate::{ 11use crate::{
12 algo::{self, neighbor, SyntaxRewriter}, 12 algo::{self, SyntaxRewriter},
13 ast::{ 13 ast::{
14 self, 14 self,
15 make::{self, tokens}, 15 make::{self, tokens},
@@ -322,28 +322,6 @@ impl ast::Use {
322 } 322 }
323 self.clone() 323 self.clone()
324 } 324 }
325
326 pub fn remove(&self) -> SyntaxRewriter<'static> {
327 let mut res = SyntaxRewriter::default();
328 res.delete(self.syntax());
329 let next_ws = self
330 .syntax()
331 .next_sibling_or_token()
332 .and_then(|it| it.into_token())
333 .and_then(ast::Whitespace::cast);
334 if let Some(next_ws) = next_ws {
335 let ws_text = next_ws.syntax().text();
336 if ws_text.starts_with('\n') {
337 let rest = &ws_text[1..];
338 if rest.is_empty() {
339 res.delete(next_ws.syntax())
340 } else {
341 res.replace(next_ws.syntax(), &make::tokens::whitespace(rest));
342 }
343 }
344 }
345 res
346 }
347} 325}
348 326
349impl ast::UseTree { 327impl ast::UseTree {
@@ -397,22 +375,6 @@ impl ast::UseTree {
397 Some(res) 375 Some(res)
398 } 376 }
399 } 377 }
400
401 pub fn remove(&self) -> SyntaxRewriter<'static> {
402 let mut res = SyntaxRewriter::default();
403 res.delete(self.syntax());
404 for &dir in [Direction::Next, Direction::Prev].iter() {
405 if let Some(nb) = neighbor(self, dir) {
406 self.syntax()
407 .siblings_with_tokens(dir)
408 .skip(1)
409 .take_while(|it| it.as_node() != Some(nb.syntax()))
410 .for_each(|el| res.delete(&el));
411 return res;
412 }
413 }
414 res
415 }
416} 378}
417 379
418impl ast::MatchArmList { 380impl ast::MatchArmList {
@@ -462,8 +424,7 @@ impl ast::MatchArmList {
462 let end = if let Some(comma) = start 424 let end = if let Some(comma) = start
463 .siblings_with_tokens(Direction::Next) 425 .siblings_with_tokens(Direction::Next)
464 .skip(1) 426 .skip(1)
465 .skip_while(|it| it.kind().is_trivia()) 427 .find(|it| !it.kind().is_trivia())
466 .next()
467 .filter(|it| it.kind() == T![,]) 428 .filter(|it| it.kind() == T![,])
468 { 429 {
469 comma 430 comma
@@ -594,10 +555,17 @@ impl ops::Add<u8> for IndentLevel {
594} 555}
595 556
596impl IndentLevel { 557impl IndentLevel {
558 pub fn from_element(element: &SyntaxElement) -> IndentLevel {
559 match element {
560 rowan::NodeOrToken::Node(it) => IndentLevel::from_node(it),
561 rowan::NodeOrToken::Token(it) => IndentLevel::from_token(it),
562 }
563 }
564
597 pub fn from_node(node: &SyntaxNode) -> IndentLevel { 565 pub fn from_node(node: &SyntaxNode) -> IndentLevel {
598 match node.first_token() { 566 match node.first_token() {
599 Some(it) => Self::from_token(&it), 567 Some(it) => Self::from_token(&it),
600 None => return IndentLevel(0), 568 None => IndentLevel(0),
601 } 569 }
602 } 570 }
603 571
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index b1eed0a2c..529bd0eb1 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -2,13 +2,13 @@
2 2
3use std::iter::empty; 3use std::iter::empty;
4 4
5use ast::{edit::AstNodeEdit, make, GenericParamsOwner, WhereClause};
6use parser::T; 5use parser::T;
7 6
8use crate::{ 7use crate::{
9 ast, 8 algo::neighbor,
9 ast::{self, edit::AstNodeEdit, make, GenericParamsOwner, WhereClause},
10 ted::{self, Position}, 10 ted::{self, Position},
11 AstNode, Direction, 11 AstNode, AstToken, Direction,
12}; 12};
13 13
14use super::NameOwner; 14use super::NameOwner;
@@ -126,3 +126,41 @@ impl ast::TypeBoundList {
126 } 126 }
127 } 127 }
128} 128}
129
130impl ast::UseTree {
131 pub fn remove(&self) {
132 for &dir in [Direction::Next, Direction::Prev].iter() {
133 if let Some(next_use_tree) = neighbor(self, dir) {
134 let separators = self
135 .syntax()
136 .siblings_with_tokens(dir)
137 .skip(1)
138 .take_while(|it| it.as_node() != Some(next_use_tree.syntax()));
139 ted::remove_all_iter(separators);
140 break;
141 }
142 }
143 ted::remove(self.syntax())
144 }
145}
146
147impl ast::Use {
148 pub fn remove(&self) {
149 let next_ws = self
150 .syntax()
151 .next_sibling_or_token()
152 .and_then(|it| it.into_token())
153 .and_then(ast::Whitespace::cast);
154 if let Some(next_ws) = next_ws {
155 let ws_text = next_ws.syntax().text();
156 if let Some(rest) = ws_text.strip_prefix('\n') {
157 if rest.is_empty() {
158 ted::remove(next_ws.syntax())
159 } else {
160 ted::replace(next_ws.syntax(), make::tokens::whitespace(rest))
161 }
162 }
163 }
164 ted::remove(self.syntax())
165 }
166}
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs
index 636ce166d..6317d84ba 100644
--- a/crates/syntax/src/ast/expr_ext.rs
+++ b/crates/syntax/src/ast/expr_ext.rs
@@ -11,16 +11,16 @@ impl ast::AttrsOwner for ast::Expr {}
11 11
12impl ast::Expr { 12impl ast::Expr {
13 pub fn is_block_like(&self) -> bool { 13 pub fn is_block_like(&self) -> bool {
14 match self { 14 matches!(
15 self,
15 ast::Expr::IfExpr(_) 16 ast::Expr::IfExpr(_)
16 | ast::Expr::LoopExpr(_) 17 | ast::Expr::LoopExpr(_)
17 | ast::Expr::ForExpr(_) 18 | ast::Expr::ForExpr(_)
18 | ast::Expr::WhileExpr(_) 19 | ast::Expr::WhileExpr(_)
19 | ast::Expr::BlockExpr(_) 20 | ast::Expr::BlockExpr(_)
20 | ast::Expr::MatchExpr(_) 21 | ast::Expr::MatchExpr(_)
21 | ast::Expr::EffectExpr(_) => true, 22 | ast::Expr::EffectExpr(_)
22 _ => false, 23 )
23 }
24 } 24 }
25 25
26 pub fn name_ref(&self) -> Option<ast::NameRef> { 26 pub fn name_ref(&self) -> Option<ast::NameRef> {
@@ -151,20 +151,20 @@ pub enum BinOp {
151 151
152impl BinOp { 152impl BinOp {
153 pub fn is_assignment(self) -> bool { 153 pub fn is_assignment(self) -> bool {
154 match self { 154 matches!(
155 self,
155 BinOp::Assignment 156 BinOp::Assignment
156 | BinOp::AddAssign 157 | BinOp::AddAssign
157 | BinOp::DivAssign 158 | BinOp::DivAssign
158 | BinOp::MulAssign 159 | BinOp::MulAssign
159 | BinOp::RemAssign 160 | BinOp::RemAssign
160 | BinOp::ShrAssign 161 | BinOp::ShrAssign
161 | BinOp::ShlAssign 162 | BinOp::ShlAssign
162 | BinOp::SubAssign 163 | BinOp::SubAssign
163 | BinOp::BitOrAssign 164 | BinOp::BitOrAssign
164 | BinOp::BitAndAssign 165 | BinOp::BitAndAssign
165 | BinOp::BitXorAssign => true, 166 | BinOp::BitXorAssign
166 _ => false, 167 )
167 }
168 } 168 }
169} 169}
170 170
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 810c8d4c8..c08f2c14f 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -532,7 +532,7 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
532} 532}
533 533
534fn unroot(n: SyntaxNode) -> SyntaxNode { 534fn unroot(n: SyntaxNode) -> SyntaxNode {
535 SyntaxNode::new_root(n.green().to_owned()) 535 SyntaxNode::new_root(n.green())
536} 536}
537 537
538pub mod tokens { 538pub mod tokens {
@@ -560,7 +560,7 @@ pub mod tokens {
560 pub fn whitespace(text: &str) -> SyntaxToken { 560 pub fn whitespace(text: &str) -> SyntaxToken {
561 assert!(text.trim().is_empty()); 561 assert!(text.trim().is_empty());
562 let sf = SourceFile::parse(text).ok().unwrap(); 562 let sf = SourceFile::parse(text).ok().unwrap();
563 sf.syntax().first_child_or_token().unwrap().into_token().unwrap() 563 sf.syntax().clone_for_update().first_child_or_token().unwrap().into_token().unwrap()
564 } 564 }
565 565
566 pub fn doc_comment(text: &str) -> SyntaxToken { 566 pub fn doc_comment(text: &str) -> SyntaxToken {
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 01f580a40..bdf907a21 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -58,10 +58,7 @@ impl From<ast::MacroDef> for Macro {
58 58
59impl AstNode for Macro { 59impl AstNode for Macro {
60 fn can_cast(kind: SyntaxKind) -> bool { 60 fn can_cast(kind: SyntaxKind) -> bool {
61 match kind { 61 matches!(kind, SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF)
62 SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF => true,
63 _ => false,
64 }
65 } 62 }
66 fn cast(syntax: SyntaxNode) -> Option<Self> { 63 fn cast(syntax: SyntaxNode) -> Option<Self> {
67 let res = match syntax.kind() { 64 let res = match syntax.kind() {
@@ -380,6 +377,15 @@ impl fmt::Display for NameOrNameRef {
380 } 377 }
381} 378}
382 379
380impl NameOrNameRef {
381 pub fn text(&self) -> &str {
382 match self {
383 NameOrNameRef::Name(name) => name.text(),
384 NameOrNameRef::NameRef(name_ref) => name_ref.text(),
385 }
386 }
387}
388
383impl ast::RecordPatField { 389impl ast::RecordPatField {
384 pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> { 390 pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> {
385 let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?; 391 let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?;
@@ -453,10 +459,8 @@ impl ast::FieldExpr {
453 pub fn field_access(&self) -> Option<FieldKind> { 459 pub fn field_access(&self) -> Option<FieldKind> {
454 if let Some(nr) = self.name_ref() { 460 if let Some(nr) = self.name_ref() {
455 Some(FieldKind::Name(nr)) 461 Some(FieldKind::Name(nr))
456 } else if let Some(tok) = self.index_token() {
457 Some(FieldKind::Index(tok))
458 } else { 462 } else {
459 None 463 self.index_token().map(FieldKind::Index)
460 } 464 }
461 } 465 }
462} 466}
@@ -473,16 +477,10 @@ impl ast::SlicePat {
473 let prefix = args 477 let prefix = args
474 .peeking_take_while(|p| match p { 478 .peeking_take_while(|p| match p {
475 ast::Pat::RestPat(_) => false, 479 ast::Pat::RestPat(_) => false,
476 ast::Pat::IdentPat(bp) => match bp.pat() { 480 ast::Pat::IdentPat(bp) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
477 Some(ast::Pat::RestPat(_)) => false,
478 _ => true,
479 },
480 ast::Pat::RefPat(rp) => match rp.pat() { 481 ast::Pat::RefPat(rp) => match rp.pat() {
481 Some(ast::Pat::RestPat(_)) => false, 482 Some(ast::Pat::RestPat(_)) => false,
482 Some(ast::Pat::IdentPat(bp)) => match bp.pat() { 483 Some(ast::Pat::IdentPat(bp)) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))),
483 Some(ast::Pat::RestPat(_)) => false,
484 _ => true,
485 },
486 _ => true, 484 _ => true,
487 }, 485 },
488 _ => true, 486 _ => true,
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index 6c242d126..29d25a58a 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -102,8 +102,9 @@ impl CommentKind {
102 kind 102 kind
103 } 103 }
104 104
105 fn prefix(&self) -> &'static str { 105 pub fn prefix(&self) -> &'static str {
106 let &(prefix, _) = CommentKind::BY_PREFIX.iter().find(|(_, kind)| kind == self).unwrap(); 106 let &(prefix, _) =
107 CommentKind::BY_PREFIX.iter().rev().find(|(_, kind)| kind == self).unwrap();
107 prefix 108 prefix
108 } 109 }
109} 110}
@@ -494,9 +495,8 @@ pub trait HasFormatSpecifier: AstToken {
494 } 495 }
495 _ => { 496 _ => {
496 while let Some((_, Ok(next_char))) = chars.peek() { 497 while let Some((_, Ok(next_char))) = chars.peek() {
497 match next_char { 498 if next_char == &'{' {
498 '{' => break, 499 break;
499 _ => {}
500 } 500 }
501 chars.next(); 501 chars.next();
502 } 502 }