Rename FileMap to File

This commit is contained in:
Brendan Zabarauskas
2019-05-31 16:06:17 +10:00
parent 7049eaa571
commit 753200eb85
6 changed files with 106 additions and 120 deletions
+34 -43
View File
@@ -1,8 +1,8 @@
//! Utilities for translating from codespan types into Language Server Protocol (LSP) types
use codespan::{
ByteIndex, ByteIndexError, ByteOffset, CodeMap, ColumnIndex, FileMap, LineIndex,
LineIndexError, LocationError, RawIndex, RawOffset, Span,
ByteIndex, ByteIndexError, ByteOffset, CodeMap, ColumnIndex, File, LineIndex, LineIndexError,
LocationError, RawIndex, RawOffset, Span,
};
use codespan_reporting::{Diagnostic, Severity};
use lsp_types as lsp;
@@ -88,31 +88,25 @@ fn location_to_position(
}
}
pub fn byte_index_to_position<S>(
source: &FileMap<S>,
pos: ByteIndex,
) -> Result<lsp::Position, Error>
pub fn byte_index_to_position<S>(file: &File<S>, pos: ByteIndex) -> Result<lsp::Position, Error>
where
S: AsRef<str>,
{
let line = source.find_line(pos)?;
let line_span = source.line_span(line).unwrap();
let line_str = source.src_slice(line_span).unwrap();
let line = file.find_line(pos)?;
let line_span = file.line_span(line).unwrap();
let line_str = file.src_slice(line_span).unwrap();
let column = ColumnIndex::from((pos - line_span.start()).0 as RawIndex);
location_to_position(line_str, line, column, pos)
}
pub fn byte_span_to_range<S>(
source: &FileMap<S>,
span: Span<ByteIndex>,
) -> Result<lsp::Range, Error>
pub fn byte_span_to_range<S>(file: &File<S>, span: Span<ByteIndex>) -> Result<lsp::Range, Error>
where
S: AsRef<str>,
{
Ok(lsp::Range {
start: byte_index_to_position(source, span.start())?,
end: byte_index_to_position(source, span.end())?,
start: byte_index_to_position(file, span.start())?,
end: byte_index_to_position(file, span.end())?,
})
}
@@ -145,29 +139,26 @@ pub fn character_to_line_offset(line: &str, character: u64) -> Result<ByteOffset
}
pub fn position_to_byte_index<S>(
source: &FileMap<S>,
file: &File<S>,
position: &lsp::Position,
) -> Result<ByteIndex, Error>
where
S: AsRef<str>,
{
let line_span = source.line_span(LineIndex::from(position.line as RawIndex))?;
let src_slice = source.src_slice(line_span).unwrap();
let line_span = file.line_span(LineIndex::from(position.line as RawIndex))?;
let src_slice = file.src_slice(line_span).unwrap();
let byte_offset = character_to_line_offset(src_slice, position.character)?;
Ok(line_span.start() + byte_offset)
}
pub fn range_to_byte_span<S>(
source: &FileMap<S>,
range: &lsp::Range,
) -> Result<Span<ByteIndex>, Error>
pub fn range_to_byte_span<S>(file: &File<S>, range: &lsp::Range) -> Result<Span<ByteIndex>, Error>
where
S: AsRef<str>,
{
Ok(Span::new(
position_to_byte_index(source, &range.start)?,
position_to_byte_index(source, &range.end)?,
position_to_byte_index(file, &range.start)?,
position_to_byte_index(file, &range.end)?,
))
}
@@ -195,7 +186,7 @@ const UNKNOWN_RANGE: lsp::Range = lsp::Range {
/// Since the language client requires `Url`s to locate the errors `codespan_name_to_file` is
/// necessary to resolve codespan `FileName`s
///
/// `code` and `source` are left empty by this function
/// `code` and `file` are left empty by this function
pub fn make_lsp_diagnostic<F>(
code_map: &CodeMap,
diagnostic: Diagnostic,
@@ -211,8 +202,8 @@ where
};
// We need a position for the primary error so take the span from the first primary label
let primary_file_map = find_file(diagnostic.primary_label.span.start())?;
let primary_label_range = byte_span_to_range(&primary_file_map, diagnostic.primary_label.span)?;
let primary_file = find_file(diagnostic.primary_label.span.start())?;
let primary_label_range = byte_span_to_range(&primary_file, diagnostic.primary_label.span)?;
let related_information = diagnostic
.secondary_labels
@@ -220,17 +211,17 @@ where
.map(|label| {
// If the label's span does not point anywhere, assume it comes from the same file
// as the primary label
let (file_map, range) = if label.span.start() == ByteIndex::none() {
(primary_file_map, UNKNOWN_RANGE)
let (file, range) = if label.span.start() == ByteIndex::none() {
(primary_file, UNKNOWN_RANGE)
} else {
let file_map = find_file(label.span.start())?;
let range = byte_span_to_range(file_map, label.span)?;
let file = find_file(label.span.start())?;
let range = byte_span_to_range(file, label.span)?;
(file_map, range)
(file, range)
};
let uri = codespan_name_to_file(file_map.name())
.map_err(|()| Error::UnableToCorrelateFilename(file_map.name().to_owned()))?;
let uri = codespan_name_to_file(file.name())
.map_err(|()| Error::UnableToCorrelateFilename(file.name().to_owned()))?;
Ok(lsp::DiagnosticRelatedInformation {
location: lsp::Location { uri, range },
@@ -265,16 +256,16 @@ let test = 2
let test1 = ""
te
"#;
let source = FileMap::new("".into(), text);
let file = File::new("".into(), text);
let pos = position_to_byte_index(
&source,
&file,
&lsp::Position {
line: 3,
character: 2,
},
)
.unwrap();
assert_eq!(Location::new(3, 2), source.location(pos).unwrap());
assert_eq!(Location::new(3, 2), file.location(pos).unwrap());
}
// The protocol specifies that each `character` in position is a UTF-16 character.
@@ -283,10 +274,10 @@ te
#[test]
fn unicode_get_byte_index() {
let source = FileMap::new("".into(), UNICODE);
let file = File::new("".into(), UNICODE);
let result = position_to_byte_index(
&source,
&file,
&lsp::Position {
line: 0,
character: 3,
@@ -295,7 +286,7 @@ te
assert_eq!(result, Ok(ByteIndex::from(6)));
let result = position_to_byte_index(
&source,
&file,
&lsp::Position {
line: 0,
character: 6,
@@ -306,9 +297,9 @@ te
#[test]
fn unicode_get_position() {
let source = FileMap::new("".into(), UNICODE);
let file = File::new("".into(), UNICODE);
let result = byte_index_to_position(&source, ByteIndex::from(6));
let result = byte_index_to_position(&file, ByteIndex::from(6));
assert_eq!(
result,
Ok(lsp::Position {
@@ -317,7 +308,7 @@ te
})
);
let result = byte_index_to_position(&source, ByteIndex::from(11));
let result = byte_index_to_position(&file, ByteIndex::from(11));
assert_eq!(
result,
Ok(lsp::Position {
+3 -3
View File
@@ -28,9 +28,9 @@ fn main() {
3) ()
()
"##;
let file_map = code_map.add_filemap("test".into(), source.to_string());
let file = code_map.add_file("test".into(), source.to_string());
let str_start = file_map.byte_index(3.into(), 6.into()).unwrap();
let str_start = file.byte_index(3.into(), 6.into()).unwrap();
let error = Diagnostic::new_error(
"Unexpected type in `+` application",
Label::new(
@@ -44,7 +44,7 @@ fn main() {
"Expected integer but got string",
)]);
let line_start = file_map.byte_index(2.into(), 3.into()).unwrap();
let line_start = file.byte_index(2.into(), 3.into()).unwrap();
let warning = Diagnostic::new_warning(
"`+` function has no effect unless its result is used",
Label::new(Span::from_offset(line_start, 27.into()), "Value discarded"),
+4 -4
View File
@@ -1,4 +1,4 @@
use codespan::{ByteIndex, CodeMap, FileMap, LineIndex, RawIndex};
use codespan::{ByteIndex, CodeMap, File, LineIndex, RawIndex};
use std::io;
use termcolor::{Color, ColorSpec, WriteColor};
@@ -197,13 +197,13 @@ enum MarkStyle {
/// ╵
/// ```
struct MarkedSource<'a, S: AsRef<str>> {
file: &'a FileMap<S>,
file: &'a File<S>,
label: &'a Label,
mark_style: MarkStyle,
}
impl<'a, S: AsRef<str>> MarkedSource<'a, S> {
fn new_primary(file: &'a FileMap<S>, diagnostic: &'a Diagnostic) -> MarkedSource<'a, S> {
fn new_primary(file: &'a File<S>, diagnostic: &'a Diagnostic) -> MarkedSource<'a, S> {
MarkedSource {
file,
label: &diagnostic.primary_label,
@@ -211,7 +211,7 @@ impl<'a, S: AsRef<str>> MarkedSource<'a, S> {
}
}
fn new_secondary(file: &'a FileMap<S>, label: &'a Label) -> MarkedSource<'a, S> {
fn new_secondary(file: &'a File<S>, label: &'a Label) -> MarkedSource<'a, S> {
MarkedSource {
file,
label,
+19 -21
View File
@@ -6,7 +6,7 @@ use std::sync::Arc;
use itertools::Itertools;
use crate::{
filemap::FileMap,
file::File,
index::{ByteIndex, ByteOffset, RawIndex},
};
@@ -14,7 +14,7 @@ use crate::{
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct CodeMap<S = String> {
files: Vec<Arc<FileMap<S>>>,
files: Vec<Arc<File<S>>>,
}
impl<S> CodeMap<S> {
@@ -23,13 +23,13 @@ impl<S> CodeMap<S> {
CodeMap::default()
}
pub fn iter(&self) -> impl Iterator<Item = &Arc<FileMap<S>>> {
pub fn iter(&self) -> impl Iterator<Item = &Arc<File<S>>> {
self.files.iter()
}
}
impl<S: AsRef<str>> CodeMap<S> {
/// The next start index to use for a new filemap
/// The next start index to use for a new file
fn next_start_index(&self) -> ByteIndex {
let end_index = self
.files
@@ -41,19 +41,19 @@ impl<S: AsRef<str>> CodeMap<S> {
end_index + ByteOffset(1)
}
/// Adds a filemap to the codemap with the given name and source string
pub fn add_filemap(&mut self, name: String, src: S) -> Arc<FileMap<S>> {
let file = Arc::new(FileMap::with_index(name, src, self.next_start_index()));
/// Adds a file to the codemap with the given name and source string
pub fn add_file(&mut self, name: String, src: S) -> Arc<File<S>> {
let file = Arc::new(File::with_index(name, src, self.next_start_index()));
self.files.push(file.clone());
file
}
/// Looks up the `File` that contains the specified byte index.
pub fn find_file(&self, index: ByteIndex) -> Option<&Arc<FileMap<S>>> {
pub fn find_file(&self, index: ByteIndex) -> Option<&Arc<File<S>>> {
self.find_index(index).map(|i| &self.files[i])
}
pub fn update(&mut self, index: ByteIndex, src: S) -> Option<Arc<FileMap<S>>> {
pub fn update(&mut self, index: ByteIndex, src: S) -> Option<Arc<File<S>>> {
self.find_index(index).map(|i| {
let min = if i == 0 {
ByteIndex(1)
@@ -63,14 +63,12 @@ impl<S: AsRef<str>> CodeMap<S> {
let max = self
.files
.get(i + 1)
.map_or(ByteIndex(RawIndex::max_value()), |file_map| {
file_map.span().start()
})
.map_or(ByteIndex(RawIndex::max_value()), |file| file.span().start())
- ByteOffset(1);
if src.as_ref().len() <= (max - min).to_usize() {
let start_index = self.files[i].span().start();
let name = self.files[i].name().to_owned();
let new_file = Arc::new(FileMap::with_index(name, src, start_index));
let new_file = Arc::new(File::with_index(name, src, start_index));
self.files[i] = new_file.clone();
new_file
} else {
@@ -93,11 +91,11 @@ impl<S: AsRef<str>> CodeMap<S> {
self.files[j - 1].span().end() + ByteOffset(1)
};
let name = file.name().to_owned();
let new_file = Arc::new(FileMap::with_index(name, src, start_index));
let new_file = Arc::new(File::with_index(name, src, start_index));
self.files.insert(j, new_file.clone());
new_file
},
None => self.add_filemap(file.name().to_owned(), src),
None => self.add_file(file.name().to_owned(), src),
}
}
})
@@ -117,9 +115,9 @@ impl<S: AsRef<str>> CodeMap<S> {
}
impl<S: AsRef<str> + From<String>> CodeMap<S> {
/// Adds a filemap to the codemap with the given name and source string
pub fn add_filemap_from_disk(&mut self, name: String) -> io::Result<Arc<FileMap<S>>> {
let file = Arc::new(FileMap::from_disk(name, self.next_start_index())?);
/// Adds a file to the codemap with the given name and source string
pub fn add_file_from_disk(&mut self, name: String) -> io::Result<Arc<File<S>>> {
let file = Arc::new(File::from_disk(name, self.next_start_index())?);
self.files.push(file.clone());
Ok(file)
}
@@ -156,9 +154,9 @@ mod tests {
fn update() {
let mut code_map = CodeMap::new();
let a_span = code_map.add_filemap("a".into(), "a".into()).span();
let b_span = code_map.add_filemap("b".into(), "b".into()).span();
let c_span = code_map.add_filemap("c".into(), "c".into()).span();
let a_span = code_map.add_file("a".into(), "a".into()).span();
let b_span = code_map.add_file("b".into(), "b".into()).span();
let c_span = code_map.add_file("c".into(), "c".into()).span();
code_map.update(a_span.start(), "aa".into()).unwrap();
check_maps(&code_map, &[(3, "b", "b"), (5, "c", "c"), (7, "a", "aa")]);
@@ -102,7 +102,7 @@ impl fmt::Display for SpanError {
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
/// Some source code
pub struct FileMap<S = String> {
pub struct File<S = String> {
/// The name of the file that the source came from, to be used when
/// displaying diagnostics
name: String,
@@ -114,33 +114,30 @@ pub struct FileMap<S = String> {
lines: Vec<ByteOffset>,
}
impl<S: AsRef<str> + From<String>> FileMap<S> {
/// Read some source code from a file, loading it into a filemap
pub(crate) fn from_disk(name: String, start: ByteIndex) -> io::Result<FileMap<S>> {
use std::fs::File;
use std::io::Read;
impl<S: AsRef<str> + From<String>> File<S> {
/// Read some source code from a file, loading it into a file
pub(crate) fn from_disk(name: String, start: ByteIndex) -> io::Result<File<S>> {
use std::fs;
let mut file = File::open(&name)?;
let mut src = String::new();
file.read_to_string(&mut src)?;
let src = fs::read_to_string(&name)?;
Ok(FileMap::with_index(name, src.into(), start))
Ok(File::with_index(name, src.into(), start))
}
}
impl<S> FileMap<S>
impl<S> File<S>
where
S: AsRef<str>,
{
/// Construct a new, standalone filemap.
/// Construct a new, standalone file.
///
/// This can be useful for tests that consist of a single source file. Production code should however
/// use `CodeMap::add_filemap` or `CodeMap::add_filemap_from_disk` instead.
pub fn new(name: String, src: S) -> FileMap<S> {
FileMap::with_index(name, src, ByteIndex(1))
/// use `CodeMap::add_file` or `CodeMap::add_file_from_disk` instead.
pub fn new(name: String, src: S) -> File<S> {
File::with_index(name, src, ByteIndex(1))
}
pub(crate) fn with_index(name: String, src: S, start: ByteIndex) -> FileMap<S> {
pub(crate) fn with_index(name: String, src: S, start: ByteIndex) -> File<S> {
use std::iter;
let span = ByteSpan::from_offset(start, ByteOffset::from_str(src.as_ref()));
@@ -154,7 +151,7 @@ where
iter::once(ByteOffset(0)).chain(offsets).collect()
};
FileMap {
File {
name,
src,
span,
@@ -309,7 +306,7 @@ mod tests {
use crate::CodeMap;
struct TestData {
filemap: Arc<FileMap>,
file: Arc<File>,
lines: &'static [&'static str],
}
@@ -324,9 +321,9 @@ mod tests {
"bloop\n",
"goopey\r\n",
];
let filemap = codemap.add_filemap("test".to_owned(), lines.concat());
let file = codemap.add_file("test".to_owned(), lines.concat());
TestData { filemap, lines }
TestData { file, lines }
}
fn byte_offsets(&self) -> Vec<ByteOffset> {
@@ -373,14 +370,14 @@ mod tests {
fn offset() {
let test_data = TestData::new();
assert!(test_data
.filemap
.file
.offset(
(test_data.lines.len() as u32 - 1).into(),
(test_data.lines.last().unwrap().len() as u32).into()
)
.is_ok());
assert!(test_data
.filemap
.file
.offset(
(test_data.lines.len() as u32 - 1).into(),
(test_data.lines.last().unwrap().len() as u32 + 1).into()
@@ -394,7 +391,7 @@ mod tests {
let offsets: Vec<_> = test_data
.line_indices()
.iter()
.map(|&i| test_data.filemap.line_offset(i))
.map(|&i| test_data.file.line_offset(i))
.collect();
assert_eq!(
@@ -421,19 +418,19 @@ mod tests {
let offsets: Vec<_> = test_data
.line_indices()
.iter()
.map(|&i| test_data.filemap.line_byte_index(i))
.map(|&i| test_data.file.line_byte_index(i))
.collect();
assert_eq!(
offsets,
vec![
Ok(test_data.filemap.span().start() + ByteOffset(0)),
Ok(test_data.filemap.span().start() + ByteOffset(7)),
Ok(test_data.filemap.span().start() + ByteOffset(13)),
Ok(test_data.filemap.span().start() + ByteOffset(15)),
Ok(test_data.filemap.span().start() + ByteOffset(21)),
Ok(test_data.filemap.span().start() + ByteOffset(27)),
Ok(test_data.filemap.span().start() + ByteOffset(35)),
Ok(test_data.file.span().start() + ByteOffset(0)),
Ok(test_data.file.span().start() + ByteOffset(7)),
Ok(test_data.file.span().start() + ByteOffset(13)),
Ok(test_data.file.span().start() + ByteOffset(15)),
Ok(test_data.file.span().start() + ByteOffset(21)),
Ok(test_data.file.span().start() + ByteOffset(27)),
Ok(test_data.file.span().start() + ByteOffset(35)),
Err(LineIndexError::OutOfBounds {
given: LineIndex(7),
max: LineIndex(6),
@@ -444,16 +441,16 @@ mod tests {
// #[test]
// fn line_span() {
// let filemap = filemap();
// let start = filemap.span().start();
// let file = file();
// let start = file.span().start();
// assert_eq!(filemap.line_byte_index(Li(0)), Some(start + BOff(0)));
// assert_eq!(filemap.line_byte_index(Li(1)), Some(start + BOff(7)));
// assert_eq!(filemap.line_byte_index(Li(2)), Some(start + BOff(13)));
// assert_eq!(filemap.line_byte_index(Li(3)), Some(start + BOff(14)));
// assert_eq!(filemap.line_byte_index(Li(4)), Some(start + BOff(20)));
// assert_eq!(filemap.line_byte_index(Li(5)), Some(start + BOff(26)));
// assert_eq!(filemap.line_byte_index(Li(6)), None);
// assert_eq!(file.line_byte_index(Li(0)), Some(start + BOff(0)));
// assert_eq!(file.line_byte_index(Li(1)), Some(start + BOff(7)));
// assert_eq!(file.line_byte_index(Li(2)), Some(start + BOff(13)));
// assert_eq!(file.line_byte_index(Li(3)), Some(start + BOff(14)));
// assert_eq!(file.line_byte_index(Li(4)), Some(start + BOff(20)));
// assert_eq!(file.line_byte_index(Li(5)), Some(start + BOff(26)));
// assert_eq!(file.line_byte_index(Li(6)), None);
// }
#[test]
@@ -462,7 +459,7 @@ mod tests {
let lines: Vec<_> = test_data
.byte_indices()
.iter()
.map(|&index| test_data.filemap.location(index))
.map(|&index| test_data.file.location(index))
.collect();
assert_eq!(
@@ -470,7 +467,7 @@ mod tests {
vec![
Err(ByteIndexError::OutOfBounds {
given: ByteIndex(0),
span: test_data.filemap.span(),
span: test_data.file.span(),
}),
Ok(Location::new(0, 0)),
Ok(Location::new(0, 6)),
@@ -487,7 +484,7 @@ mod tests {
Ok(Location::new(6, 0)),
Err(ByteIndexError::OutOfBounds {
given: ByteIndex(37),
span: test_data.filemap.span()
span: test_data.file.span()
}),
],
);
@@ -499,7 +496,7 @@ mod tests {
let lines: Vec<_> = test_data
.byte_indices()
.iter()
.map(|&index| test_data.filemap.find_line(index))
.map(|&index| test_data.file.find_line(index))
.collect();
assert_eq!(
@@ -507,7 +504,7 @@ mod tests {
vec![
Err(ByteIndexError::OutOfBounds {
given: ByteIndex(0),
span: test_data.filemap.span(),
span: test_data.file.span(),
}),
Ok(LineIndex(0)),
Ok(LineIndex(0)),
@@ -524,7 +521,7 @@ mod tests {
Ok(LineIndex(6)),
Err(ByteIndexError::OutOfBounds {
given: ByteIndex(37),
span: test_data.filemap.span(),
span: test_data.file.span(),
}),
],
);
+3 -3
View File
@@ -12,14 +12,14 @@
//! `heapsize` crate
mod codemap;
mod filemap;
mod file;
mod index;
mod location;
mod span;
pub use crate::codemap::CodeMap;
pub use crate::filemap::FileMap;
pub use crate::filemap::{ByteIndexError, LineIndexError, LocationError, SpanError};
pub use crate::file::File;
pub use crate::file::{ByteIndexError, LineIndexError, LocationError, SpanError};
pub use crate::index::{ByteIndex, ByteOffset};
pub use crate::index::{ColumnIndex, ColumnNumber, ColumnOffset};
pub use crate::index::{Index, Offset};