## Summary This PR moves `ruff/jupyter` into its own `ruff_notebook` crate. Beyond the move itself, there were a few challenges: 1. `ruff_notebook` relies on the source map abstraction. I've moved the source map into `ruff_diagnostics`, since it doesn't have any dependencies on its own and is used alongside diagnostics. 2. `ruff_notebook` has a couple tests for end-to-end linting and autofixing. I had to leave these tests in `ruff` itself. 3. We had code in `ruff/jupyter` that relied on Python lexing, in order to provide a more targeted error message in the event that a user saves a `.py` file with a `.ipynb` extension. I removed this in order to avoid a dependency on the parser, it felt like it wasn't worth retaining just for that dependency. ## Test Plan `cargo test`
74 lines
2.0 KiB
Rust
74 lines
2.0 KiB
Rust
use ruff_text_size::{Ranged, TextSize};
|
|
|
|
use crate::Edit;
|
|
|
|
/// Lightweight sourcemap marker representing the source and destination
|
|
/// position for an [`Edit`].
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
pub struct SourceMarker {
|
|
/// Position of the marker in the original source.
|
|
source: TextSize,
|
|
/// Position of the marker in the transformed code.
|
|
dest: TextSize,
|
|
}
|
|
|
|
impl SourceMarker {
|
|
pub fn new(source: TextSize, dest: TextSize) -> Self {
|
|
Self { source, dest }
|
|
}
|
|
|
|
pub const fn source(&self) -> TextSize {
|
|
self.source
|
|
}
|
|
|
|
pub const fn dest(&self) -> TextSize {
|
|
self.dest
|
|
}
|
|
}
|
|
|
|
/// A collection of [`SourceMarker`].
|
|
///
|
|
/// Sourcemaps are used to map positions in the original source to positions in
|
|
/// the transformed code. Here, only the boundaries of edits are tracked instead
|
|
/// of every single character.
|
|
#[derive(Default, PartialEq, Eq)]
|
|
pub struct SourceMap(Vec<SourceMarker>);
|
|
|
|
impl SourceMap {
|
|
/// Returns a slice of all the markers in the sourcemap in the order they
|
|
/// were added.
|
|
pub fn markers(&self) -> &[SourceMarker] {
|
|
&self.0
|
|
}
|
|
|
|
/// Push the start marker for an [`Edit`].
|
|
///
|
|
/// The `output_length` is the length of the transformed string before the
|
|
/// edit is applied.
|
|
pub fn push_start_marker(&mut self, edit: &Edit, output_length: TextSize) {
|
|
self.0.push(SourceMarker {
|
|
source: edit.start(),
|
|
dest: output_length,
|
|
});
|
|
}
|
|
|
|
/// Push the end marker for an [`Edit`].
|
|
///
|
|
/// The `output_length` is the length of the transformed string after the
|
|
/// edit has been applied.
|
|
pub fn push_end_marker(&mut self, edit: &Edit, output_length: TextSize) {
|
|
if edit.is_insertion() {
|
|
self.0.push(SourceMarker {
|
|
source: edit.start(),
|
|
dest: output_length,
|
|
});
|
|
} else {
|
|
// Deletion or replacement
|
|
self.0.push(SourceMarker {
|
|
source: edit.end(),
|
|
dest: output_length,
|
|
});
|
|
}
|
|
}
|
|
}
|