about summary refs log tree commit diff
path: root/src/changes.rs
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-02-02 21:59:03 +1300
committerNick Cameron <ncameron@mozilla.com>2015-02-02 21:59:03 +1300
commitf1e698c838defa9535750312d3fc11ebf3a830e9 (patch)
tree4f0598da7db4eba36d9674a7494ce0454aa335c9 /src/changes.rs
parent5caf49ff63ef84961f0b489706d6fcf3bcc0c6f0 (diff)
Save changes in the rope.
Also changes to using the new rustc interface
Diffstat (limited to 'src/changes.rs')
-rw-r--r--src/changes.rs158
1 files changed, 19 insertions, 139 deletions
diff --git a/src/changes.rs b/src/changes.rs
index ba2b90d185d..22fdc0ff51d 100644
--- a/src/changes.rs
+++ b/src/changes.rs
@@ -15,9 +15,8 @@
 // docs
 
 use rope::{Rope, RopeSlice};
-use std::collections::{HashMap, BTreeMap};
-use std::collections::Bound::{Included, Unbounded};
-use syntax::codemap::{CodeMap, Span, Pos};
+use std::collections::HashMap;
+use syntax::codemap::{CodeMap, Span, Pos, BytePos};
 use std::fmt;
 
 pub struct ChangeSet<'a> {
@@ -27,34 +26,6 @@ pub struct ChangeSet<'a> {
     // out into an adaptor.
     codemap: &'a CodeMap,
     pub count: u64,
-    // TODO we need to map the start and end of spans differently
-    // TODO needs to be per file
-    adjusts: BTreeMap<usize, Adjustment>,
-}
-
-// An extent over which we must adjust the position values.
-#[derive(Show, Clone, Eq, PartialEq)]
-struct Adjustment {
-    // Start is implicit, given by its position in the map.
-    end: usize,
-    delta: isize,
-}
-
-impl Adjustment {
-    fn chop_left(&self, new_end: usize) -> Adjustment {
-        Adjustment {
-            end: new_end,
-            delta: self.delta,
-        }
-    }
-
-    fn move_left(&self, mov: usize) -> Adjustment {
-        assert!(self.delta > mov);
-        Adjustment {
-            end: self.end,
-            delta: self.delta - mov,
-        }
-    }
 }
 
 pub struct FileIterator<'c, 'a: 'c> {
@@ -69,7 +40,6 @@ impl<'a> ChangeSet<'a> {
             file_map: HashMap::new(),
             codemap: codemap,
             count: 0,
-            adjusts: BTreeMap::new(),
         };
 
         for f in codemap.files.borrow().iter() {
@@ -84,100 +54,21 @@ impl<'a> ChangeSet<'a> {
     pub fn change(&mut self, file_name: &str, start: usize, end: usize, text: String) {
         println!("change: {}:{}-{} \"{}\"", file_name, start, end, text);
 
-        let new_len = text.len();
         self.count += 1;
 
-        let (key_start, adj_start, abs_start): (Option<usize>, Option<Adjustment>, usize) = {
-            let before_start = self.adjusts.range(Unbounded, Included(&start)).next_back();
-            match before_start {
-                Some((k, a)) if a.end > start => (Some(*k), Some(a.clone()), (start as isize + a.delta) as usize),
-                _ => (None, None, start)
-            }
-        };
-        let (key_end, adj_end, abs_end) = {
-            let before_end = self.adjusts.range(Unbounded, Included(&end)).next_back();
-            match before_end {
-                Some((k, a)) if a.end > end => (Some(*k), Some(a.clone()), (end as isize + a.delta) as usize),
-                _ => (None, None, end)
-            }
-        };
-
-        {
-            let file = &mut self.file_map[*file_name];
-
-            println!("change: absolute values {}-{}, replaces \"{}\"",
-                   abs_start, abs_end, file.slice(abs_start..abs_end));
-
-            file.remove(abs_start, abs_end);
-            file.insert(abs_start, text);
-
-            // Record the changed locations.
-            // TODO what if there is a change to the right of end? - need to iterate over all changes to the right :-(
-            match (key_start, key_end) {
-                (None, None) => {
-                    // Factor this out?
-                    let old_len = end as isize - start as isize;
-                    let delta = new_len as isize - old_len;
-                    self.adjusts.insert(end, Adjustment { end: file.len(), delta: delta });
-                }
-                (Some(k), None) => {
-                    // Adjust the old change.
-                    self.adjusts[k] = adj_start.unwrap().chop_left(end);
-
-                    // Add the new one.
-                    let old_len = end as isize - start as isize;
-                    let delta = new_len as isize - old_len;
-                    self.adjusts.insert(end, Adjustment { end: file.len(), delta: delta });
-                }
-                (None, Some(k)) => {
-                    let old_len = end as isize - start as isize;
-                    let delta = new_len as isize - old_len;
-
-                    // Adjust the old change.
-                    // TODO only if we move left, but what if moving right?
-                    self.adjusts[abs_end] = adj_end.unwrap().move_left(TODO);
-                    self.adjusts.remove(&k);
-
-                    // Add the new one.
-                    self.adjusts.insert(end, Adjustment { end: file.len(), delta: delta });
-                }
-                _ => {
-                    println!("{}", file);
-                    panic!();
-                }
-            }
-        }
-
-        debug_assert!(self.verify_adjustments(), "Bad change, created an overlapping adjustment");
-    }
+        let file = &mut self.file_map[*file_name];
 
-    // Intended for debugging.
-    fn verify_adjustments(&self) -> bool {
-        let mut prev_end = 0;
-        let mut prev_delta = 0;
-        for (&k, a) in self.adjusts.iter() {
-            if k < prev_end {
-                debug!("Found bad adjustment at start {}, overlaps with previous adjustment", k);
-                return false;
-            }
-            if k as isize + a.delta < 0 {
-                debug!("Found bad adjustment at start {}, absolute start < 0", k);
-                return false;
-            }
-            if k as isize + a.delta < prev_end as isize + prev_delta {
-                debug!("Found bad adjustment at start {}, \
-                        projection overlaps with previous projection", k);
-                return false;
-            }
-            // TODO Check end + delta <= file.len - needs per file
-
-            prev_end = a.end;
-            prev_delta = a.delta;
+        if end - start == text.len() {
+            // TODO
+            panic!();
+            file.replace_str(start, &text[]);
+        } else {
+            // TODO if we do this in one op, could we get better change info?
+            file.src_remove(start, end);
+            file.src_insert(start, text);
         }
-        true
     }
 
-    // span is unadjusted.
     pub fn change_span(&mut self, span: Span, text: String) {
         let l_loc = self.codemap.lookup_char_pos(span.lo);
         let file_offset = l_loc.file.start_pos.0;
@@ -187,29 +78,11 @@ impl<'a> ChangeSet<'a> {
                     text)
     }
 
-    // start and end are unadjusted.
     pub fn slice(&self, file_name: &str, start: usize, end: usize) -> RopeSlice {
-        // TODO refactor with change?
-        let abs_start = {
-            let before_start = self.adjusts.range(Unbounded, Included(&start)).next_back();
-            match before_start {
-                Some((k, ref a)) if a.end > start => (start as isize + a.delta) as usize,
-                _ => start
-            }
-        };
-        let abs_end = {
-            let before_end = self.adjusts.range(Unbounded, Included(&end)).next_back();
-            match before_end {
-                Some((k, ref a)) if a.end > end => (end as isize + a.delta) as usize,
-                _ => end
-            }
-        };
-
         let file = &self.file_map[*file_name];
-        file.slice(abs_start..abs_end)
+        file.src_slice(start..end)
     }
 
-    // span is unadjusted.
     pub fn slice_span(&self, span:Span) -> RopeSlice {
         let l_loc = self.codemap.lookup_char_pos(span.lo);
         let file_offset = l_loc.file.start_pos.0;
@@ -225,6 +98,13 @@ impl<'a> ChangeSet<'a> {
             cur_key: 0,
         }
     }
+
+    pub fn col(&self, loc: BytePos) -> usize {
+        let l_loc = self.codemap.lookup_char_pos(loc);
+        let file_offset = l_loc.file.start_pos.0;
+        let file = &self.file_map[l_loc.file.name[]];
+        file.col_for_src_loc(loc.0 as usize - file_offset as usize)
+    }
 }
 
 impl<'c, 'a> Iterator for FileIterator<'c, 'a> {