aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/Cargo.toml1
-rw-r--r--crates/ra_syntax/src/lib.rs8
-rw-r--r--crates/ra_syntax/src/reparsing.rs38
-rw-r--r--crates/ra_syntax/src/text_utils.rs6
-rw-r--r--crates/ra_syntax/src/yellow/syntax_text.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs38
6 files changed, 35 insertions, 59 deletions
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml
index 8ad8ed196..8c9a7e238 100644
--- a/crates/ra_syntax/Cargo.toml
+++ b/crates/ra_syntax/Cargo.toml
@@ -15,6 +15,7 @@ drop_bomb = "0.1.4"
15parking_lot = "0.6.0" 15parking_lot = "0.6.0"
16rowan = "0.1.2" 16rowan = "0.1.2"
17text_unit = "0.1.5" 17text_unit = "0.1.5"
18ra_text_edit = { path = "../ra_text_edit" }
18 19
19[dev-dependencies] 20[dev-dependencies]
20test_utils = { path = "../test_utils" } 21test_utils = { path = "../test_utils" }
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 0e5c9baad..34a3aabef 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -41,13 +41,13 @@ pub use rowan::{SmolStr, TextRange, TextUnit};
41pub use crate::{ 41pub use crate::{
42 ast::AstNode, 42 ast::AstNode,
43 lexer::{tokenize, Token}, 43 lexer::{tokenize, Token},
44 reparsing::AtomEdit,
45 syntax_kinds::SyntaxKind, 44 syntax_kinds::SyntaxKind,
46 yellow::{ 45 yellow::{
47 Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, Location, 46 Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, Location,
48 }, 47 },
49}; 48};
50 49
50use ra_text_edit::AtomTextEdit;
51use crate::yellow::GreenNode; 51use crate::yellow::GreenNode;
52 52
53/// `SourceFileNode` represents a parse tree for a single Rust file. 53/// `SourceFileNode` represents a parse tree for a single Rust file.
@@ -68,15 +68,15 @@ impl SourceFileNode {
68 parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root); 68 parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root);
69 SourceFileNode::new(green, errors) 69 SourceFileNode::new(green, errors)
70 } 70 }
71 pub fn reparse(&self, edit: &AtomEdit) -> SourceFileNode { 71 pub fn reparse(&self, edit: &AtomTextEdit) -> SourceFileNode {
72 self.incremental_reparse(edit) 72 self.incremental_reparse(edit)
73 .unwrap_or_else(|| self.full_reparse(edit)) 73 .unwrap_or_else(|| self.full_reparse(edit))
74 } 74 }
75 pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<SourceFileNode> { 75 pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<SourceFileNode> {
76 reparsing::incremental_reparse(self.syntax(), edit, self.errors()) 76 reparsing::incremental_reparse(self.syntax(), edit, self.errors())
77 .map(|(green_node, errors)| SourceFileNode::new(green_node, errors)) 77 .map(|(green_node, errors)| SourceFileNode::new(green_node, errors))
78 } 78 }
79 fn full_reparse(&self, edit: &AtomEdit) -> SourceFileNode { 79 fn full_reparse(&self, edit: &AtomTextEdit) -> SourceFileNode {
80 let text = 80 let text =
81 text_utils::replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert); 81 text_utils::replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert);
82 SourceFileNode::parse(&text) 82 SourceFileNode::parse(&text)
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs
index 732fb0e4a..208cae5c8 100644
--- a/crates/ra_syntax/src/reparsing.rs
+++ b/crates/ra_syntax/src/reparsing.rs
@@ -6,33 +6,11 @@ use crate::parser_impl;
6use crate::text_utils::replace_range; 6use crate::text_utils::replace_range;
7use crate::yellow::{self, GreenNode, SyntaxError, SyntaxNodeRef}; 7use crate::yellow::{self, GreenNode, SyntaxError, SyntaxNodeRef};
8use crate::{SyntaxKind::*, TextRange, TextUnit}; 8use crate::{SyntaxKind::*, TextRange, TextUnit};
9 9use ra_text_edit::AtomTextEdit;
10#[derive(Debug, Clone)]
11pub struct AtomEdit {
12 pub delete: TextRange,
13 pub insert: String,
14}
15
16impl AtomEdit {
17 pub fn replace(range: TextRange, replace_with: String) -> AtomEdit {
18 AtomEdit {
19 delete: range,
20 insert: replace_with,
21 }
22 }
23
24 pub fn delete(range: TextRange) -> AtomEdit {
25 AtomEdit::replace(range, String::new())
26 }
27
28 pub fn insert(offset: TextUnit, text: String) -> AtomEdit {
29 AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text)
30 }
31}
32 10
33pub(crate) fn incremental_reparse( 11pub(crate) fn incremental_reparse(
34 node: SyntaxNodeRef, 12 node: SyntaxNodeRef,
35 edit: &AtomEdit, 13 edit: &AtomTextEdit,
36 errors: Vec<SyntaxError>, 14 errors: Vec<SyntaxError>,
37) -> Option<(GreenNode, Vec<SyntaxError>)> { 15) -> Option<(GreenNode, Vec<SyntaxError>)> {
38 let (node, green, new_errors) = 16 let (node, green, new_errors) =
@@ -44,7 +22,7 @@ pub(crate) fn incremental_reparse(
44 22
45fn reparse_leaf<'node>( 23fn reparse_leaf<'node>(
46 node: SyntaxNodeRef<'node>, 24 node: SyntaxNodeRef<'node>,
47 edit: &AtomEdit, 25 edit: &AtomTextEdit,
48) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> { 26) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> {
49 let node = algo::find_covering_node(node, edit.delete); 27 let node = algo::find_covering_node(node, edit.delete);
50 match node.kind() { 28 match node.kind() {
@@ -70,7 +48,7 @@ fn reparse_leaf<'node>(
70 48
71fn reparse_block<'node>( 49fn reparse_block<'node>(
72 node: SyntaxNodeRef<'node>, 50 node: SyntaxNodeRef<'node>,
73 edit: &AtomEdit, 51 edit: &AtomTextEdit,
74) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> { 52) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> {
75 let (node, reparser) = find_reparsable_node(node, edit.delete)?; 53 let (node, reparser) = find_reparsable_node(node, edit.delete)?;
76 let text = get_text_after_edit(node, &edit); 54 let text = get_text_after_edit(node, &edit);
@@ -83,7 +61,7 @@ fn reparse_block<'node>(
83 Some((node, green, new_errors)) 61 Some((node, green, new_errors))
84} 62}
85 63
86fn get_text_after_edit(node: SyntaxNodeRef, edit: &AtomEdit) -> String { 64fn get_text_after_edit(node: SyntaxNodeRef, edit: &AtomTextEdit) -> String {
87 replace_range( 65 replace_range(
88 node.text().to_string(), 66 node.text().to_string(),
89 edit.delete - node.range().start(), 67 edit.delete - node.range().start(),
@@ -161,7 +139,7 @@ fn merge_errors(
161 old_errors: Vec<SyntaxError>, 139 old_errors: Vec<SyntaxError>,
162 new_errors: Vec<SyntaxError>, 140 new_errors: Vec<SyntaxError>,
163 old_node: SyntaxNodeRef, 141 old_node: SyntaxNodeRef,
164 edit: &AtomEdit, 142 edit: &AtomTextEdit,
165) -> Vec<SyntaxError> { 143) -> Vec<SyntaxError> {
166 let mut res = Vec::new(); 144 let mut res = Vec::new();
167 for e in old_errors { 145 for e in old_errors {
@@ -188,7 +166,7 @@ mod tests {
188 where 166 where
189 for<'a> F: Fn( 167 for<'a> F: Fn(
190 SyntaxNodeRef<'a>, 168 SyntaxNodeRef<'a>,
191 &AtomEdit, 169 &AtomTextEdit,
192 ) -> Option<(SyntaxNodeRef<'a>, GreenNode, Vec<SyntaxError>)>, 170 ) -> Option<(SyntaxNodeRef<'a>, GreenNode, Vec<SyntaxError>)>,
193 { 171 {
194 let (range, before) = extract_range(before); 172 let (range, before) = extract_range(before);
@@ -197,7 +175,7 @@ mod tests {
197 let fully_reparsed = SourceFileNode::parse(&after); 175 let fully_reparsed = SourceFileNode::parse(&after);
198 let incrementally_reparsed = { 176 let incrementally_reparsed = {
199 let f = SourceFileNode::parse(&before); 177 let f = SourceFileNode::parse(&before);
200 let edit = AtomEdit { 178 let edit = AtomTextEdit {
201 delete: range, 179 delete: range,
202 insert: replace_with.to_string(), 180 insert: replace_with.to_string(),
203 }; 181 };
diff --git a/crates/ra_syntax/src/text_utils.rs b/crates/ra_syntax/src/text_utils.rs
index a90f8a083..417d43e1b 100644
--- a/crates/ra_syntax/src/text_utils.rs
+++ b/crates/ra_syntax/src/text_utils.rs
@@ -1,8 +1,4 @@
1use crate::{TextRange, TextUnit}; 1use crate::TextRange;
2
3pub fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool {
4 range.start() <= offset && offset <= range.end()
5}
6 2
7pub fn intersect(r1: TextRange, r2: TextRange) -> Option<TextRange> { 3pub fn intersect(r1: TextRange, r2: TextRange) -> Option<TextRange> {
8 let start = r1.start().max(r2.start()); 4 let start = r1.start().max(r2.start());
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs
index 5395ca90b..46bde9a08 100644
--- a/crates/ra_syntax/src/yellow/syntax_text.rs
+++ b/crates/ra_syntax/src/yellow/syntax_text.rs
@@ -1,7 +1,8 @@
1use std::{fmt, ops}; 1use std::{fmt, ops};
2 2
3use ra_text_edit::text_utils::contains_offset_nonstrict;
3use crate::{ 4use crate::{
4 text_utils::{contains_offset_nonstrict, intersect}, 5 text_utils::intersect,
5 SyntaxNodeRef, TextRange, TextUnit, 6 SyntaxNodeRef, TextRange, TextUnit,
6}; 7};
7 8
diff --git a/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs b/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs
index 53c93d9e9..59cd11495 100644
--- a/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs
+++ b/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs
@@ -10,10 +10,10 @@
10 ); 10 );
11 File::new(green, errors) 11 File::new(green, errors)
12 } 12 }
13 pub fn reparse(&self, edit: &AtomEdit) -> File { 13 pub fn reparse(&self, edit: &AtomTextEdit) -> File {
14 self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) 14 self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
15 } 15 }
16 pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> { 16 pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<File> {
17 let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?; 17 let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?;
18 let text = replace_range( 18 let text = replace_range(
19 node.text().to_string(), 19 node.text().to_string(),
@@ -31,7 +31,7 @@
31 let errors = merge_errors(self.errors(), new_errors, node, edit); 31 let errors = merge_errors(self.errors(), new_errors, node, edit);
32 Some(File::new(green_root, errors)) 32 Some(File::new(green_root, errors))
33 } 33 }
34 fn full_reparse(&self, edit: &AtomEdit) -> File { 34 fn full_reparse(&self, edit: &AtomTextEdit) -> File {
35 let text = replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert); 35 let text = replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert);
36 File::parse(&text) 36 File::parse(&text)
37 } 37 }
@@ -58,22 +58,22 @@
58} 58}
59 59
60#[derive(Debug, Clone)] 60#[derive(Debug, Clone)]
61pub struct AtomEdit { 61pub struct AtomTextEdit {
62 pub delete: TextRange, 62 pub delete: TextRange,
63 pub insert: String, 63 pub insert: String,
64} 64}
65 65
66impl AtomEdit { 66impl AtomTextEdit {
67 pub fn replace(range: TextRange, replace_with: String) -> AtomEdit { 67 pub fn replace(range: TextRange, replace_with: String) -> AtomTextEdit {
68 AtomEdit { delete: range, insert: replace_with } 68 AtomTextEdit { delete: range, insert: replace_with }
69 } 69 }
70 70
71 pub fn delete(range: TextRange) -> AtomEdit { 71 pub fn delete(range: TextRange) -> AtomTextEdit {
72 AtomEdit::replace(range, String::new()) 72 AtomTextEdit::replace(range, String::new())
73 } 73 }
74 74
75 pub fn insert(offset: TextUnit, text: String) -> AtomEdit { 75 pub fn insert(offset: TextUnit, text: String) -> AtomTextEdit {
76 AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text) 76 AtomTextEdit::replace(TextRange::offset_len(offset, 0.into()), text)
77 } 77 }
78} 78}
79 79
@@ -114,17 +114,17 @@ fn is_balanced(tokens: &[Token]) -> bool {
114 pub insert: String, 114 pub insert: String,
115} 115}
116 116
117impl AtomEdit { 117impl AtomTextEdit {
118 pub fn replace(range: TextRange, replace_with: String) -> AtomEdit { 118 pub fn replace(range: TextRange, replace_with: String) -> AtomTextEdit {
119 AtomEdit { delete: range, insert: replace_with } 119 AtomTextEdit { delete: range, insert: replace_with }
120 } 120 }
121 121
122 pub fn delete(range: TextRange) -> AtomEdit { 122 pub fn delete(range: TextRange) -> AtomTextEdit {
123 AtomEdit::replace(range, String::new()) 123 AtomTextEdit::replace(range, String::new())
124 } 124 }
125 125
126 pub fn insert(offset: TextUnit, text: String) -> AtomEdit { 126 pub fn insert(offset: TextUnit, text: String) -> AtomTextEdit {
127 AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text) 127 AtomTextEdit::replace(TextRange::offset_len(offset, 0.into()), text)
128 } 128 }
129} 129}
130 130
@@ -176,7 +176,7 @@ fn merge_errors(
176 old_errors: Vec<SyntaxError>, 176 old_errors: Vec<SyntaxError>,
177 new_errors: Vec<SyntaxError>, 177 new_errors: Vec<SyntaxError>,
178 old_node: SyntaxNodeRef, 178 old_node: SyntaxNodeRef,
179 edit: &AtomEdit, 179 edit: &AtomTextEdit,
180) -> Vec<SyntaxError> { 180) -> Vec<SyntaxError> {
181 let mut res = Vec::new(); 181 let mut res = Vec::new();
182 for e in old_errors { 182 for e in old_errors {