Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ all = "deny"
[dependencies]
lsp-types = { version = "0", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
base64 = { version = "0.21", optional = true }
codespan-reporting = { version = "0.11", optional = true }
self-rust-tokenize = { version = "0.3", optional = true }
base64 = { version = "0.22", optional = true }
codespan-reporting = { version = "0.12", optional = true }
self-rust-tokenize = { version = "0", optional = true }

[target.'cfg(target_family = "wasm")'.dependencies]
wasm-bindgen = "0.2"
tsify = "0.4.5"
tsify = "0.5"

[features]
default = ["global-source-filesystem"]
Expand Down
2 changes: 1 addition & 1 deletion examples/source_map_creation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main() {
};
output.add_mapping(&base_span);
output.push_str(chunk);
output.push(' ');
output.push_char(' ');

const WORDS_PER_LINE: usize = 5;
if idx % WORDS_PER_LINE + 1 == WORDS_PER_LINE {
Expand Down
49 changes: 6 additions & 43 deletions src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,11 @@ use crate::{lines_columns_indexes::LineStarts, SourceId, SpanWithSource};
pub struct Source {
pub path: PathBuf,
pub content: String,
/// This is computed ahead of time for fast conversion for byte-indexes to line-column indexes
/// which is needed for source map generation and also printing code blocks in diagnostics
pub(crate) line_starts: LineStarts,
}

#[cfg(feature = "global-source-filesystem")]
pub mod global_store {
use super::*;

pub struct GlobalStore;

#[cfg(feature = "global-source-filesystem")]
static SOURCE_IDS_TO_FILES: std::sync::RwLock<MapFileStore<NoPathMap>> =
std::sync::RwLock::new(MapFileStore {
sources: Vec::new(),
mappings: NoPathMap,
});

impl FileSystem for GlobalStore {
fn new_source_id_with_line_starts(
&mut self,
path: PathBuf,
content: String,
) -> (SourceId, LineStarts) {
SOURCE_IDS_TO_FILES
.write()
.unwrap()
.new_source_id_with_line_starts(path, content)
}

fn get_source_by_id<T, F: for<'a> FnOnce(&'a Source) -> T>(
&self,
source_id: SourceId,
f: F,
) -> T {
SOURCE_IDS_TO_FILES
.read()
.unwrap()
.get_source_by_id(source_id, f)
}
}
}

#[derive(Default)]
pub struct MapFileStore<T> {
sources: Vec<Source>,
Expand Down Expand Up @@ -133,11 +97,10 @@ impl<M: PathMap> FileSystem for MapFileStore<M> {
(source_id, line_starts)
}

fn get_source_by_id<T, F: for<'a> FnOnce(&'a Source) -> T>(
&self,
source_id: SourceId,
f: F,
) -> T {
fn get_source_by_id<T, F>(&self, source_id: SourceId, f: F) -> T
where
F: for<'a> FnOnce(&'a Source) -> T,
{
f(&self.sources[source_id.0 as usize - 1])
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn vlq_encode_integer_to_buffer(buf: &mut String, mut value: isize) {
if value > 0 {
clamped |= 32;
}
buf.push(BASE64_ALPHABET[clamped as usize] as char);
buf.push_char(BASE64_ALPHABET[clamped as usize] as char);
if value <= 0 {
break;
}
Expand Down Expand Up @@ -150,7 +150,7 @@ impl SourceMapBuilder {
}

if let Some(false) = last_was_break {
mappings.push(',');
mappings.push_char(',');
}

let output_column =
Expand Down Expand Up @@ -187,7 +187,7 @@ impl SourceMapBuilder {
last_was_break = Some(false);
}
MappingOrBreak::Break => {
mappings.push(';');
mappings.push_char(';');
last_was_break = Some(true);
last_mapped_output_column = 0;
}
Expand Down Expand Up @@ -232,8 +232,8 @@ impl SourceMap {
.enumerate()
{
if idx != 0 {
sources.push(',');
sources_content.push(',');
sources.push_char(',');
sources_content.push_char(',');
}
write!(
sources,
Expand Down
6 changes: 6 additions & 0 deletions src/source_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ impl SourceId {
pub fn new(filesystem: &mut impl FileSystem, path: PathBuf, content: String) -> Self {
filesystem.new_source_id(path, content)
}

/// Construct a `SourceId` from a custom `FileSystem` implementation
#[doc(hidden)]
pub fn new_from_u16(id: u16) -> Self {
Self(id)
}
}

#[cfg(feature = "self-rust-tokenize")]
Expand Down
78 changes: 65 additions & 13 deletions src/to_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@ use crate::{
/// A trait for defining behavior of adding content to a buffer. As well as register markers for source maps
pub trait ToString {
/// Append character
fn push(&mut self, chr: char);
fn push_u8(&mut self, chr: u8);

/// Append character
fn push_char(&mut self, chr: char);

/// Append a new line character
fn push_new_line(&mut self);

/// Use [ToString::push_str_contains_new_line] if `string` could contain new lines
fn push_str(&mut self, string: &str);
fn push_str(&mut self, string: &str) {
self.push_slice(string.as_bytes())
}

/// Use [ToString::push_str_contains_new_line] if `string` could contain new lines
fn push_slice(&mut self, slice: &[u8]);

/// Used to push strings that may contain new lines
fn push_str_contains_new_line(&mut self, string: &str);
Expand All @@ -36,18 +44,26 @@ pub trait ToString {

// TODO clarify calls
impl ToString for String {
fn push(&mut self, chr: char) {
fn push_u8(&mut self, chr: u8) {
self.push(chr as char);
}

fn push_char(&mut self, chr: char) {
self.push(chr);
}

fn push_new_line(&mut self) {
self.push('\n');
self.push_char('\n');
}

fn push_str(&mut self, string: &str) {
self.push_str(string)
}

fn push_slice(&mut self, slice: &[u8]) {
self.push_str(str::from_utf8(slice).unwrap())
}

fn push_str_contains_new_line(&mut self, string: &str) {
self.push_str(string)
}
Expand All @@ -67,7 +83,13 @@ pub struct Writable<T: std::io::Write> {
}

impl<T: std::io::Write> ToString for Writable<T> {
fn push(&mut self, chr: char) {
fn push_u8(&mut self, item: u8) {
self.length += 1;
self.since_new_line += 1;
self.writable.write_all(&[item]).unwrap();
}

fn push_char(&mut self, chr: char) {
let mut buf = [0u8; 4]; // A char can be at most 4 bytes in UTF-8
let buf = chr.encode_utf8(&mut buf).as_bytes();
let char_size = chr.len_utf8();
Expand All @@ -78,7 +100,7 @@ impl<T: std::io::Write> ToString for Writable<T> {

fn push_new_line(&mut self) {
self.length += 1;
self.writable.write_all(&[b'\n']).unwrap();
self.writable.write_all(b"\n").unwrap();
}

fn push_str(&mut self, string: &str) {
Expand All @@ -87,6 +109,12 @@ impl<T: std::io::Write> ToString for Writable<T> {
self.writable.write_all(string.as_bytes()).unwrap();
}

fn push_slice(&mut self, slice: &[u8]) {
self.length += slice.len() as u32;
self.since_new_line += slice.len() as u32;
self.writable.write_all(slice).unwrap();
}

fn push_str_contains_new_line(&mut self, slice: &str) {
self.length += slice.len() as u32;
self.writable.write_all(slice.as_bytes()).unwrap();
Expand Down Expand Up @@ -158,16 +186,24 @@ impl StringWithOptionalSourceMap {
}

impl ToString for StringWithOptionalSourceMap {
fn push(&mut self, chr: char) {
self.source.push(chr);
fn push_u8(&mut self, item: u8) {
self.source.push_u8(item);
if let Some(ref mut sm) = self.source_map {
sm.add_to_column(1);
}
self.since_new_line += 1;
}

fn push_char(&mut self, chr: char) {
self.source.push_char(chr);
if let Some(ref mut sm) = self.source_map {
sm.add_to_column(chr.len_utf16());
}
self.since_new_line += chr.len_utf8() as u32;
}

fn push_new_line(&mut self) {
self.source.push('\n');
self.source.push_char('\n');
if let Some(ref mut sm) = self.source_map {
sm.add_new_line();
}
Expand All @@ -182,6 +218,14 @@ impl ToString for StringWithOptionalSourceMap {
self.since_new_line += slice.len() as u32;
}

fn push_slice(&mut self, slice: &[u8]) {
self.source.push_slice(slice);
if let Some(ref mut sm) = self.source_map {
sm.add_to_column(slice.len());
}
self.since_new_line += slice.len() as u32;
}

fn push_str_contains_new_line(&mut self, slice: &str) {
self.source.push_str(slice);
if let Some(ref mut sm) = self.source_map {
Expand All @@ -201,7 +245,7 @@ impl ToString for StringWithOptionalSourceMap {

fn should_halt(&self) -> bool {
self.quit_after
.map_or(false, |quit_after| self.source.len() > quit_after)
.is_some_and(|quit_after| self.source.len() > quit_after)
}

fn characters_on_current_line(&self) -> u32 {
Expand Down Expand Up @@ -230,18 +274,26 @@ impl Counter {
}

impl ToString for Counter {
fn push(&mut self, chr: char) {
fn push_u8(&mut self, _item: u8) {
self.acc += 1;
}

fn push_char(&mut self, chr: char) {
self.acc += chr.len_utf8();
}

fn push_new_line(&mut self) {
self.push('\n');
self.push_char('\n');
}

fn push_str(&mut self, string: &str) {
self.acc += string.len();
}

fn push_slice(&mut self, slice: &[u8]) {
self.acc += slice.len();
}

fn push_str_contains_new_line(&mut self, string: &str) {
self.acc += string.len();
}
Expand All @@ -267,7 +319,7 @@ mod to_string_tests {

fn serializer<T: ToString>(t: &mut T) {
t.push_str("Hello");
t.push(' ');
t.push_char(' ');
t.push_str("World");
}

Expand Down
Loading