aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast.rs46
-rw-r--r--crates/ra_syntax/src/ast/generated.rs220
-rw-r--r--crates/ra_syntax/src/grammar.ron23
-rw-r--r--crates/ra_syntax/src/lexer/strings.rs15
-rw-r--r--crates/ra_syntax/src/lib.rs5
-rw-r--r--crates/ra_syntax/src/yellow.rs12
-rw-r--r--crates/ra_syntax/src/yellow/syntax_text.rs11
7 files changed, 315 insertions, 17 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index e6b5e407d..000cfb981 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -618,6 +618,52 @@ impl SelfParam {
618 } 618 }
619} 619}
620 620
621#[derive(Clone, Debug, PartialEq, Eq, Hash)]
622pub enum LiteralFlavor {
623 String,
624 ByteString,
625 Char,
626 Byte,
627 IntNumber { suffix: Option<SmolStr> },
628 FloatNumber { suffix: Option<SmolStr> },
629 Bool,
630}
631
632impl LiteralExpr {
633 pub fn flavor(&self) -> LiteralFlavor {
634 let syntax = self.syntax();
635 match syntax.kind() {
636 INT_NUMBER => {
637 let allowed_suffix_list = [
638 "isize", "i128", "i64", "i32", "i16", "i8", "usize", "u128", "u64", "u32",
639 "u16", "u8",
640 ];
641 let text = syntax.text().to_string();
642 let suffix = allowed_suffix_list
643 .iter()
644 .find(|&s| text.ends_with(s))
645 .map(|&suf| SmolStr::new(suf));
646 LiteralFlavor::IntNumber { suffix: suffix }
647 }
648 FLOAT_NUMBER => {
649 let allowed_suffix_list = ["f64", "f32"];
650 let text = syntax.text().to_string();
651 let suffix = allowed_suffix_list
652 .iter()
653 .find(|&s| text.ends_with(s))
654 .map(|&suf| SmolStr::new(suf));
655 LiteralFlavor::FloatNumber { suffix: suffix }
656 }
657 STRING | RAW_STRING => LiteralFlavor::String,
658 TRUE_KW | FALSE_KW => LiteralFlavor::Bool,
659 BYTE_STRING | RAW_BYTE_STRING => LiteralFlavor::ByteString,
660 CHAR => LiteralFlavor::Char,
661 BYTE => LiteralFlavor::Byte,
662 _ => unreachable!(),
663 }
664 }
665}
666
621#[test] 667#[test]
622fn test_doc_comment_of_items() { 668fn test_doc_comment_of_items() {
623 let file = SourceFile::parse( 669 let file = SourceFile::parse(
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 94842a514..3471d5226 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -793,6 +793,31 @@ impl AstNode for ExternCrateItem {
793 793
794impl ExternCrateItem {} 794impl ExternCrateItem {}
795 795
796// FalseKw
797#[derive(Debug, PartialEq, Eq, Hash)]
798#[repr(transparent)]
799pub struct FalseKw {
800 pub(crate) syntax: SyntaxNode,
801}
802unsafe impl TransparentNewType for FalseKw {
803 type Repr = rowan::SyntaxNode<RaTypes>;
804}
805
806impl AstNode for FalseKw {
807 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
808 match syntax.kind() {
809 FALSE_KW => Some(FalseKw::from_repr(syntax.into_repr())),
810 _ => None,
811 }
812 }
813 fn syntax(&self) -> &SyntaxNode { &self.syntax }
814 fn to_owned(&self) -> TreeArc<FalseKw> { TreeArc::cast(self.syntax.to_owned()) }
815}
816
817
818impl ast::AstToken for FalseKw {}
819impl FalseKw {}
820
796// FieldExpr 821// FieldExpr
797#[derive(Debug, PartialEq, Eq, Hash)] 822#[derive(Debug, PartialEq, Eq, Hash)]
798#[repr(transparent)] 823#[repr(transparent)]
@@ -849,6 +874,31 @@ impl AstNode for FieldPatList {
849 874
850impl FieldPatList {} 875impl FieldPatList {}
851 876
877// FloatNumber
878#[derive(Debug, PartialEq, Eq, Hash)]
879#[repr(transparent)]
880pub struct FloatNumber {
881 pub(crate) syntax: SyntaxNode,
882}
883unsafe impl TransparentNewType for FloatNumber {
884 type Repr = rowan::SyntaxNode<RaTypes>;
885}
886
887impl AstNode for FloatNumber {
888 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
889 match syntax.kind() {
890 FLOAT_NUMBER => Some(FloatNumber::from_repr(syntax.into_repr())),
891 _ => None,
892 }
893 }
894 fn syntax(&self) -> &SyntaxNode { &self.syntax }
895 fn to_owned(&self) -> TreeArc<FloatNumber> { TreeArc::cast(self.syntax.to_owned()) }
896}
897
898
899impl ast::AstToken for FloatNumber {}
900impl FloatNumber {}
901
852// FnDef 902// FnDef
853#[derive(Debug, PartialEq, Eq, Hash)] 903#[derive(Debug, PartialEq, Eq, Hash)]
854#[repr(transparent)] 904#[repr(transparent)]
@@ -1130,6 +1180,31 @@ impl AstNode for IndexExpr {
1130 1180
1131impl IndexExpr {} 1181impl IndexExpr {}
1132 1182
1183// IntNumber
1184#[derive(Debug, PartialEq, Eq, Hash)]
1185#[repr(transparent)]
1186pub struct IntNumber {
1187 pub(crate) syntax: SyntaxNode,
1188}
1189unsafe impl TransparentNewType for IntNumber {
1190 type Repr = rowan::SyntaxNode<RaTypes>;
1191}
1192
1193impl AstNode for IntNumber {
1194 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
1195 match syntax.kind() {
1196 INT_NUMBER => Some(IntNumber::from_repr(syntax.into_repr())),
1197 _ => None,
1198 }
1199 }
1200 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1201 fn to_owned(&self) -> TreeArc<IntNumber> { TreeArc::cast(self.syntax.to_owned()) }
1202}
1203
1204
1205impl ast::AstToken for IntNumber {}
1206impl IntNumber {}
1207
1133// ItemList 1208// ItemList
1134#[derive(Debug, PartialEq, Eq, Hash)] 1209#[derive(Debug, PartialEq, Eq, Hash)]
1135#[repr(transparent)] 1210#[repr(transparent)]
@@ -1327,7 +1402,75 @@ impl AstNode for Literal {
1327} 1402}
1328 1403
1329 1404
1330impl Literal {} 1405impl Literal {
1406 pub fn literal_expr(&self) -> Option<&LiteralExpr> {
1407 super::child_opt(self)
1408 }
1409}
1410
1411// LiteralExpr
1412#[derive(Debug, PartialEq, Eq, Hash)]
1413#[repr(transparent)]
1414pub struct LiteralExpr {
1415 pub(crate) syntax: SyntaxNode,
1416}
1417unsafe impl TransparentNewType for LiteralExpr {
1418 type Repr = rowan::SyntaxNode<RaTypes>;
1419}
1420
1421#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1422pub enum LiteralExprKind<'a> {
1423 String(&'a String),
1424 ByteString(&'a ByteString),
1425 RawString(&'a RawString),
1426 RawByteString(&'a RawByteString),
1427 Char(&'a Char),
1428 Byte(&'a Byte),
1429 IntNumber(&'a IntNumber),
1430 FloatNumber(&'a FloatNumber),
1431 TrueKw(&'a TrueKw),
1432 FalseKw(&'a FalseKw),
1433}
1434
1435impl AstNode for LiteralExpr {
1436 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
1437 match syntax.kind() {
1438 | STRING
1439 | BYTE_STRING
1440 | RAW_STRING
1441 | RAW_BYTE_STRING
1442 | CHAR
1443 | BYTE
1444 | INT_NUMBER
1445 | FLOAT_NUMBER
1446 | TRUE_KW
1447 | FALSE_KW => Some(LiteralExpr::from_repr(syntax.into_repr())),
1448 _ => None,
1449 }
1450 }
1451 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1452 fn to_owned(&self) -> TreeArc<LiteralExpr> { TreeArc::cast(self.syntax.to_owned()) }
1453}
1454
1455impl LiteralExpr {
1456 pub fn kind(&self) -> LiteralExprKind {
1457 match self.syntax.kind() {
1458 STRING => LiteralExprKind::String(String::cast(&self.syntax).unwrap()),
1459 BYTE_STRING => LiteralExprKind::ByteString(ByteString::cast(&self.syntax).unwrap()),
1460 RAW_STRING => LiteralExprKind::RawString(RawString::cast(&self.syntax).unwrap()),
1461 RAW_BYTE_STRING => LiteralExprKind::RawByteString(RawByteString::cast(&self.syntax).unwrap()),
1462 CHAR => LiteralExprKind::Char(Char::cast(&self.syntax).unwrap()),
1463 BYTE => LiteralExprKind::Byte(Byte::cast(&self.syntax).unwrap()),
1464 INT_NUMBER => LiteralExprKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()),
1465 FLOAT_NUMBER => LiteralExprKind::FloatNumber(FloatNumber::cast(&self.syntax).unwrap()),
1466 TRUE_KW => LiteralExprKind::TrueKw(TrueKw::cast(&self.syntax).unwrap()),
1467 FALSE_KW => LiteralExprKind::FalseKw(FalseKw::cast(&self.syntax).unwrap()),
1468 _ => unreachable!(),
1469 }
1470 }
1471}
1472
1473impl LiteralExpr {}
1331 1474
1332// LoopExpr 1475// LoopExpr
1333#[derive(Debug, PartialEq, Eq, Hash)] 1476#[derive(Debug, PartialEq, Eq, Hash)]
@@ -2406,6 +2549,56 @@ impl AstNode for RangePat {
2406 2549
2407impl RangePat {} 2550impl RangePat {}
2408 2551
2552// RawByteString
2553#[derive(Debug, PartialEq, Eq, Hash)]
2554#[repr(transparent)]
2555pub struct RawByteString {
2556 pub(crate) syntax: SyntaxNode,
2557}
2558unsafe impl TransparentNewType for RawByteString {
2559 type Repr = rowan::SyntaxNode<RaTypes>;
2560}
2561
2562impl AstNode for RawByteString {
2563 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
2564 match syntax.kind() {
2565 RAW_BYTE_STRING => Some(RawByteString::from_repr(syntax.into_repr())),
2566 _ => None,
2567 }
2568 }
2569 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2570 fn to_owned(&self) -> TreeArc<RawByteString> { TreeArc::cast(self.syntax.to_owned()) }
2571}
2572
2573
2574impl ast::AstToken for RawByteString {}
2575impl RawByteString {}
2576
2577// RawString
2578#[derive(Debug, PartialEq, Eq, Hash)]
2579#[repr(transparent)]
2580pub struct RawString {
2581 pub(crate) syntax: SyntaxNode,
2582}
2583unsafe impl TransparentNewType for RawString {
2584 type Repr = rowan::SyntaxNode<RaTypes>;
2585}
2586
2587impl AstNode for RawString {
2588 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
2589 match syntax.kind() {
2590 RAW_STRING => Some(RawString::from_repr(syntax.into_repr())),
2591 _ => None,
2592 }
2593 }
2594 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2595 fn to_owned(&self) -> TreeArc<RawString> { TreeArc::cast(self.syntax.to_owned()) }
2596}
2597
2598
2599impl ast::AstToken for RawString {}
2600impl RawString {}
2601
2409// RefExpr 2602// RefExpr
2410#[derive(Debug, PartialEq, Eq, Hash)] 2603#[derive(Debug, PartialEq, Eq, Hash)]
2411#[repr(transparent)] 2604#[repr(transparent)]
@@ -2919,6 +3112,31 @@ impl ast::AttrsOwner for TraitDef {}
2919impl ast::DocCommentsOwner for TraitDef {} 3112impl ast::DocCommentsOwner for TraitDef {}
2920impl TraitDef {} 3113impl TraitDef {}
2921 3114
3115// TrueKw
3116#[derive(Debug, PartialEq, Eq, Hash)]
3117#[repr(transparent)]
3118pub struct TrueKw {
3119 pub(crate) syntax: SyntaxNode,
3120}
3121unsafe impl TransparentNewType for TrueKw {
3122 type Repr = rowan::SyntaxNode<RaTypes>;
3123}
3124
3125impl AstNode for TrueKw {
3126 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
3127 match syntax.kind() {
3128 TRUE_KW => Some(TrueKw::from_repr(syntax.into_repr())),
3129 _ => None,
3130 }
3131 }
3132 fn syntax(&self) -> &SyntaxNode { &self.syntax }
3133 fn to_owned(&self) -> TreeArc<TrueKw> { TreeArc::cast(self.syntax.to_owned()) }
3134}
3135
3136
3137impl ast::AstToken for TrueKw {}
3138impl TrueKw {}
3139
2922// TryExpr 3140// TryExpr
2923#[derive(Debug, PartialEq, Eq, Hash)] 3141#[derive(Debug, PartialEq, Eq, Hash)]
2924#[repr(transparent)] 3142#[repr(transparent)]
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index dfd88bd10..bd8c5b411 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -426,11 +426,32 @@ Grammar(
426 "PrefixExpr": (options: ["Expr"]), 426 "PrefixExpr": (options: ["Expr"]),
427 "RangeExpr": (), 427 "RangeExpr": (),
428 "BinExpr": (), 428 "BinExpr": (),
429
430 "IntNumber": ( traits: ["AstToken"] ),
431 "FloatNumber": ( traits: ["AstToken"] ),
429 "String": ( traits: ["AstToken"] ), 432 "String": ( traits: ["AstToken"] ),
433 "RawString": ( traits: ["AstToken"] ),
430 "Byte": ( traits: ["AstToken"] ), 434 "Byte": ( traits: ["AstToken"] ),
435 "RawByteString": ( traits: ["AstToken"] ),
431 "ByteString": ( traits: ["AstToken"] ), 436 "ByteString": ( traits: ["AstToken"] ),
432 "Char": ( traits: ["AstToken"] ), 437 "Char": ( traits: ["AstToken"] ),
433 "Literal": (), 438 "TrueKw": ( traits: ["AstToken"] ),
439 "FalseKw": ( traits: ["AstToken"] ),
440 "LiteralExpr": (
441 enum: [
442 "String",
443 "ByteString",
444 "RawString",
445 "RawByteString",
446 "Char",
447 "Byte",
448 "IntNumber",
449 "FloatNumber",
450 "TrueKw",
451 "FalseKw",
452 ]
453 ),
454 "Literal": (options: ["LiteralExpr"]),
434 455
435 "Expr": ( 456 "Expr": (
436 enum: [ 457 enum: [
diff --git a/crates/ra_syntax/src/lexer/strings.rs b/crates/ra_syntax/src/lexer/strings.rs
index 5090feae6..0865b7f3b 100644
--- a/crates/ra_syntax/src/lexer/strings.rs
+++ b/crates/ra_syntax/src/lexer/strings.rs
@@ -49,7 +49,7 @@ pub(crate) fn scan_byte_char_or_string(ptr: &mut Ptr) -> SyntaxKind {
49 BYTE_STRING 49 BYTE_STRING
50 } 50 }
51 'r' => { 51 'r' => {
52 scan_raw_byte_string(ptr); 52 scan_raw_string(ptr);
53 RAW_BYTE_STRING 53 RAW_BYTE_STRING
54 } 54 }
55 _ => unreachable!(), 55 _ => unreachable!(),
@@ -108,16 +108,3 @@ fn scan_byte(ptr: &mut Ptr) {
108fn scan_byte_string(ptr: &mut Ptr) { 108fn scan_byte_string(ptr: &mut Ptr) {
109 scan_string(ptr) 109 scan_string(ptr)
110} 110}
111
112fn scan_raw_byte_string(ptr: &mut Ptr) {
113 if !ptr.at('"') {
114 return;
115 }
116 ptr.bump();
117
118 while let Some(c) = ptr.bump() {
119 if c == '"' {
120 return;
121 }
122 }
123}
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 2a095817a..bc311cbbc 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -59,24 +59,29 @@ impl SourceFile {
59 assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); 59 assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
60 TreeArc::cast(root) 60 TreeArc::cast(root)
61 } 61 }
62
62 pub fn parse(text: &str) -> TreeArc<SourceFile> { 63 pub fn parse(text: &str) -> TreeArc<SourceFile> {
63 let tokens = tokenize(&text); 64 let tokens = tokenize(&text);
64 let (green, errors) = 65 let (green, errors) =
65 parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root); 66 parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root);
66 SourceFile::new(green, errors) 67 SourceFile::new(green, errors)
67 } 68 }
69
68 pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { 70 pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
69 self.incremental_reparse(edit) 71 self.incremental_reparse(edit)
70 .unwrap_or_else(|| self.full_reparse(edit)) 72 .unwrap_or_else(|| self.full_reparse(edit))
71 } 73 }
74
72 pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> { 75 pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreeArc<SourceFile>> {
73 reparsing::incremental_reparse(self.syntax(), edit, self.errors()) 76 reparsing::incremental_reparse(self.syntax(), edit, self.errors())
74 .map(|(green_node, errors)| SourceFile::new(green_node, errors)) 77 .map(|(green_node, errors)| SourceFile::new(green_node, errors))
75 } 78 }
79
76 fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> { 80 fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc<SourceFile> {
77 let text = edit.apply(self.syntax().text().to_string()); 81 let text = edit.apply(self.syntax().text().to_string());
78 SourceFile::parse(&text) 82 SourceFile::parse(&text)
79 } 83 }
84
80 pub fn errors(&self) -> Vec<SyntaxError> { 85 pub fn errors(&self) -> Vec<SyntaxError> {
81 let mut errors = self.syntax.root_data().clone(); 86 let mut errors = self.syntax.root_data().clone();
82 errors.extend(validation::validate(self)); 87 errors.extend(validation::validate(self));
diff --git a/crates/ra_syntax/src/yellow.rs b/crates/ra_syntax/src/yellow.rs
index 93621d08a..9b93945cc 100644
--- a/crates/ra_syntax/src/yellow.rs
+++ b/crates/ra_syntax/src/yellow.rs
@@ -128,40 +128,52 @@ impl SyntaxNode {
128 pub(crate) fn root_data(&self) -> &Vec<SyntaxError> { 128 pub(crate) fn root_data(&self) -> &Vec<SyntaxError> {
129 self.0.root_data() 129 self.0.root_data()
130 } 130 }
131
131 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { 132 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
132 self.0.replace_self(replacement) 133 self.0.replace_self(replacement)
133 } 134 }
135
134 pub fn to_owned(&self) -> TreeArc<SyntaxNode> { 136 pub fn to_owned(&self) -> TreeArc<SyntaxNode> {
135 let ptr = TreeArc(self.0.to_owned()); 137 let ptr = TreeArc(self.0.to_owned());
136 TreeArc::cast(ptr) 138 TreeArc::cast(ptr)
137 } 139 }
140
138 pub fn kind(&self) -> SyntaxKind { 141 pub fn kind(&self) -> SyntaxKind {
139 self.0.kind() 142 self.0.kind()
140 } 143 }
144
141 pub fn range(&self) -> TextRange { 145 pub fn range(&self) -> TextRange {
142 self.0.range() 146 self.0.range()
143 } 147 }
148
144 pub fn text(&self) -> SyntaxText { 149 pub fn text(&self) -> SyntaxText {
145 SyntaxText::new(self) 150 SyntaxText::new(self)
146 } 151 }
152
147 pub fn is_leaf(&self) -> bool { 153 pub fn is_leaf(&self) -> bool {
148 self.0.is_leaf() 154 self.0.is_leaf()
149 } 155 }
156
150 pub fn parent(&self) -> Option<&SyntaxNode> { 157 pub fn parent(&self) -> Option<&SyntaxNode> {
151 self.0.parent().map(SyntaxNode::from_repr) 158 self.0.parent().map(SyntaxNode::from_repr)
152 } 159 }
160
153 pub fn first_child(&self) -> Option<&SyntaxNode> { 161 pub fn first_child(&self) -> Option<&SyntaxNode> {
154 self.0.first_child().map(SyntaxNode::from_repr) 162 self.0.first_child().map(SyntaxNode::from_repr)
155 } 163 }
164
156 pub fn last_child(&self) -> Option<&SyntaxNode> { 165 pub fn last_child(&self) -> Option<&SyntaxNode> {
157 self.0.last_child().map(SyntaxNode::from_repr) 166 self.0.last_child().map(SyntaxNode::from_repr)
158 } 167 }
168
159 pub fn next_sibling(&self) -> Option<&SyntaxNode> { 169 pub fn next_sibling(&self) -> Option<&SyntaxNode> {
160 self.0.next_sibling().map(SyntaxNode::from_repr) 170 self.0.next_sibling().map(SyntaxNode::from_repr)
161 } 171 }
172
162 pub fn prev_sibling(&self) -> Option<&SyntaxNode> { 173 pub fn prev_sibling(&self) -> Option<&SyntaxNode> {
163 self.0.prev_sibling().map(SyntaxNode::from_repr) 174 self.0.prev_sibling().map(SyntaxNode::from_repr)
164 } 175 }
176
165 pub fn children(&self) -> SyntaxNodeChildren { 177 pub fn children(&self) -> SyntaxNodeChildren {
166 SyntaxNodeChildren(self.0.children()) 178 SyntaxNodeChildren(self.0.children())
167 } 179 }
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs
index 08dbe57a2..378cd1b2e 100644
--- a/crates/ra_syntax/src/yellow/syntax_text.rs
+++ b/crates/ra_syntax/src/yellow/syntax_text.rs
@@ -15,6 +15,7 @@ impl<'a> SyntaxText<'a> {
15 range: node.range(), 15 range: node.range(),
16 } 16 }
17 } 17 }
18
18 pub fn chunks(&self) -> impl Iterator<Item = &'a str> { 19 pub fn chunks(&self) -> impl Iterator<Item = &'a str> {
19 let range = self.range; 20 let range = self.range;
20 self.node.descendants().filter_map(move |node| { 21 self.node.descendants().filter_map(move |node| {
@@ -24,15 +25,19 @@ impl<'a> SyntaxText<'a> {
24 Some(&text[range]) 25 Some(&text[range])
25 }) 26 })
26 } 27 }
28
27 pub fn push_to(&self, buf: &mut String) { 29 pub fn push_to(&self, buf: &mut String) {
28 self.chunks().for_each(|it| buf.push_str(it)); 30 self.chunks().for_each(|it| buf.push_str(it));
29 } 31 }
32
30 pub fn to_string(&self) -> String { 33 pub fn to_string(&self) -> String {
31 self.chunks().collect() 34 self.chunks().collect()
32 } 35 }
36
33 pub fn contains(&self, c: char) -> bool { 37 pub fn contains(&self, c: char) -> bool {
34 self.chunks().any(|it| it.contains(c)) 38 self.chunks().any(|it| it.contains(c))
35 } 39 }
40
36 pub fn find(&self, c: char) -> Option<TextUnit> { 41 pub fn find(&self, c: char) -> Option<TextUnit> {
37 let mut acc: TextUnit = 0.into(); 42 let mut acc: TextUnit = 0.into();
38 for chunk in self.chunks() { 43 for chunk in self.chunks() {
@@ -44,9 +49,11 @@ impl<'a> SyntaxText<'a> {
44 } 49 }
45 None 50 None
46 } 51 }
52
47 pub fn len(&self) -> TextUnit { 53 pub fn len(&self) -> TextUnit {
48 self.range.len() 54 self.range.len()
49 } 55 }
56
50 pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> { 57 pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> {
51 let range = range.restrict(self.range).unwrap_or_else(|| { 58 let range = range.restrict(self.range).unwrap_or_else(|| {
52 panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) 59 panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range)
@@ -56,8 +63,10 @@ impl<'a> SyntaxText<'a> {
56 range, 63 range,
57 } 64 }
58 } 65 }
59 pub fn char_at(&self, offset: TextUnit) -> Option<char> { 66
67 pub fn char_at(&self, offset: impl Into<TextUnit>) -> Option<char> {
60 let mut start: TextUnit = 0.into(); 68 let mut start: TextUnit = 0.into();
69 let offset = offset.into();
61 for chunk in self.chunks() { 70 for chunk in self.chunks() {
62 let end = start + TextUnit::of_str(chunk); 71 let end = start + TextUnit::of_str(chunk);
63 if start <= offset && offset < end { 72 if start <= offset && offset < end {