mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 10:22:24 +00:00
Replace row/column based Location
with byte-offsets. (#3931)
This commit is contained in:
parent
ee91598835
commit
cab65b25da
418 changed files with 6203 additions and 7040 deletions
|
@ -26,6 +26,7 @@ ruff = { path = "../ruff", features = ["clap"] }
|
|||
ruff_cache = { path = "../ruff_cache" }
|
||||
ruff_diagnostics = { path = "../ruff_diagnostics" }
|
||||
ruff_python_ast = { path = "../ruff_python_ast" }
|
||||
ruff_text_size = { workspace = true }
|
||||
|
||||
annotate-snippets = { version = "0.9.1", features = ["color"] }
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
@ -8,12 +8,13 @@ use anyhow::Result;
|
|||
use filetime::FileTime;
|
||||
use log::error;
|
||||
use path_absolutize::Absolutize;
|
||||
use ruff::message::{Location, Message};
|
||||
use ruff::message::Message;
|
||||
use ruff::settings::{flags, AllSettings, Settings};
|
||||
use ruff_cache::{CacheKey, CacheKeyHasher};
|
||||
use ruff_diagnostics::{DiagnosticKind, Fix};
|
||||
use ruff_python_ast::imports::ImportMap;
|
||||
use ruff_python_ast::source_code::SourceFileBuilder;
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
use serde::ser::{SerializeSeq, SerializeStruct};
|
||||
use serde::{Deserialize, Serialize, Serializer};
|
||||
#[cfg(unix)]
|
||||
|
@ -22,8 +23,8 @@ use std::os::unix::fs::PermissionsExt;
|
|||
const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
/// Vec storing all source files. The tuple is (filename, source code).
|
||||
type Files<'a> = Vec<(&'a str, Option<&'a str>)>;
|
||||
type FilesBuf = Vec<(String, Option<String>)>;
|
||||
type Files<'a> = Vec<(&'a str, &'a str)>;
|
||||
type FilesBuf = Vec<(String, String)>;
|
||||
|
||||
struct CheckResultRef<'a> {
|
||||
imports: &'a ImportMap,
|
||||
|
@ -100,19 +101,17 @@ impl Serialize for SerializeMessage<'_> {
|
|||
{
|
||||
let Message {
|
||||
kind,
|
||||
location,
|
||||
end_location,
|
||||
range,
|
||||
fix,
|
||||
// Serialized manually for all files
|
||||
file: _,
|
||||
noqa_row,
|
||||
noqa_offset: noqa_row,
|
||||
} = self.message;
|
||||
|
||||
let mut s = serializer.serialize_struct("Message", 6)?;
|
||||
let mut s = serializer.serialize_struct("Message", 5)?;
|
||||
|
||||
s.serialize_field("kind", &kind)?;
|
||||
s.serialize_field("location", &location)?;
|
||||
s.serialize_field("end_location", &end_location)?;
|
||||
s.serialize_field("range", &range)?;
|
||||
s.serialize_field("fix", &fix)?;
|
||||
s.serialize_field("file_id", &self.file_id)?;
|
||||
s.serialize_field("noqa_row", &noqa_row)?;
|
||||
|
@ -124,11 +123,10 @@ impl Serialize for SerializeMessage<'_> {
|
|||
#[derive(Deserialize)]
|
||||
struct MessageHeader {
|
||||
kind: DiagnosticKind,
|
||||
location: Location,
|
||||
end_location: Location,
|
||||
range: TextRange,
|
||||
fix: Fix,
|
||||
file_id: usize,
|
||||
noqa_row: usize,
|
||||
noqa_row: TextSize,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -223,15 +221,7 @@ pub fn get(
|
|||
|
||||
let source_files: Vec<_> = sources
|
||||
.into_iter()
|
||||
.map(|(filename, text)| {
|
||||
let mut builder = SourceFileBuilder::from_string(filename);
|
||||
|
||||
if let Some(text) = text {
|
||||
builder.set_source_text_string(text);
|
||||
}
|
||||
|
||||
builder.finish()
|
||||
})
|
||||
.map(|(filename, text)| SourceFileBuilder::new(filename, text).finish())
|
||||
.collect();
|
||||
|
||||
for header in headers {
|
||||
|
@ -242,11 +232,10 @@ pub fn get(
|
|||
|
||||
messages.push(Message {
|
||||
kind: header.kind,
|
||||
location: header.location,
|
||||
end_location: header.end_location,
|
||||
range: header.range,
|
||||
fix: header.fix,
|
||||
file: source_file.clone(),
|
||||
noqa_row: header.noqa_row,
|
||||
noqa_offset: header.noqa_row,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@ use ignore::Error;
|
|||
use log::{debug, error, warn};
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
use rayon::prelude::*;
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
|
||||
use ruff::message::{Location, Message};
|
||||
use ruff::message::Message;
|
||||
use ruff::registry::Rule;
|
||||
use ruff::resolver::PyprojectDiscovery;
|
||||
use ruff::settings::{flags, AllSettings};
|
||||
use ruff::{fs, packaging, resolver, warn_user_once, IOError, Range};
|
||||
use ruff::{fs, packaging, resolver, warn_user_once, IOError};
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::imports::ImportMap;
|
||||
use ruff_python_ast::source_code::SourceFileBuilder;
|
||||
|
@ -117,16 +118,14 @@ pub fn run(
|
|||
);
|
||||
let settings = resolver.resolve(path, pyproject_strategy);
|
||||
if settings.rules.enabled(Rule::IOError) {
|
||||
let file = SourceFileBuilder::new(&path.to_string_lossy()).finish();
|
||||
let file =
|
||||
SourceFileBuilder::new(path.to_string_lossy().as_ref(), "").finish();
|
||||
|
||||
Diagnostics::new(
|
||||
vec![Message::from_diagnostic(
|
||||
Diagnostic::new(
|
||||
IOError { message },
|
||||
Range::new(Location::default(), Location::default()),
|
||||
),
|
||||
Diagnostic::new(IOError { message }, TextRange::default()),
|
||||
file,
|
||||
1,
|
||||
TextSize::default(),
|
||||
)],
|
||||
ImportMap::default(),
|
||||
)
|
||||
|
|
|
@ -9,16 +9,18 @@ use std::path::Path;
|
|||
use anyhow::{anyhow, Result};
|
||||
use colored::Colorize;
|
||||
use log::{debug, error};
|
||||
use ruff_text_size::TextSize;
|
||||
use rustc_hash::FxHashMap;
|
||||
use similar::TextDiff;
|
||||
|
||||
use ruff::fs;
|
||||
use ruff::jupyter::{is_jupyter_notebook, JupyterIndex, JupyterNotebook};
|
||||
use ruff::linter::{lint_fix, lint_only, FixTable, FixerResult, LinterResult};
|
||||
use ruff::logging::DisplayParseError;
|
||||
use ruff::message::Message;
|
||||
use ruff::settings::{flags, AllSettings, Settings};
|
||||
use ruff_python_ast::imports::ImportMap;
|
||||
use ruff_python_ast::source_code::SourceFileBuilder;
|
||||
use ruff_python_ast::source_code::{LineIndex, SourceCode, SourceFileBuilder};
|
||||
|
||||
use crate::cache;
|
||||
|
||||
|
@ -86,8 +88,8 @@ fn load_jupyter_notebook(path: &Path) -> Result<(String, JupyterIndex), Box<Diag
|
|||
return Err(Box::new(Diagnostics {
|
||||
messages: vec![Message::from_diagnostic(
|
||||
*diagnostic,
|
||||
SourceFileBuilder::new(&path.to_string_lossy()).finish(),
|
||||
1,
|
||||
SourceFileBuilder::new(path.to_string_lossy().as_ref(), "").finish(),
|
||||
TextSize::default(),
|
||||
)],
|
||||
..Diagnostics::default()
|
||||
}));
|
||||
|
@ -197,12 +199,12 @@ pub fn lint_path(
|
|||
let imports = imports.unwrap_or_default();
|
||||
|
||||
if let Some(err) = parse_error {
|
||||
// Notify the user of any parse errors.
|
||||
error!(
|
||||
"{}{}{} {err}",
|
||||
"Failed to parse ".bold(),
|
||||
fs::relativize_path(path).bold(),
|
||||
":".bold()
|
||||
"{}",
|
||||
DisplayParseError::new(
|
||||
err,
|
||||
SourceCode::new(&contents, &LineIndex::from_source_text(&contents))
|
||||
)
|
||||
);
|
||||
|
||||
// Purge the cache.
|
||||
|
|
|
@ -113,6 +113,8 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
|
|||
return Ok(ExitStatus::Success);
|
||||
}
|
||||
|
||||
let top_level_settings = pyproject_strategy.top_level_settings();
|
||||
|
||||
// Extract options that are included in `Settings`, but only apply at the top
|
||||
// level.
|
||||
let CliSettings {
|
||||
|
@ -122,7 +124,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
|
|||
show_fixes,
|
||||
update_check,
|
||||
..
|
||||
} = pyproject_strategy.top_level_settings().cli.clone();
|
||||
} = top_level_settings.cli.clone();
|
||||
|
||||
// Autofix rules are as follows:
|
||||
// - If `--fix` or `--fix-only` is set, always apply fixes to the filesystem (or
|
||||
|
@ -153,6 +155,10 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitStatus> {
|
|||
printer_flags |= PrinterFlags::SHOW_FIXES;
|
||||
}
|
||||
|
||||
if top_level_settings.lib.show_source {
|
||||
printer_flags |= PrinterFlags::SHOW_SOURCE;
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if cache {
|
||||
// `--no-cache` doesn't respect code changes, and so is often confusing during
|
||||
|
|
|
@ -30,6 +30,7 @@ bitflags! {
|
|||
pub(crate) struct Flags: u8 {
|
||||
const SHOW_VIOLATIONS = 0b0000_0001;
|
||||
const SHOW_FIXES = 0b0000_0010;
|
||||
const SHOW_SOURCE = 0b000_0100;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +181,7 @@ impl Printer {
|
|||
SerializationFormat::Text => {
|
||||
TextEmitter::default()
|
||||
.with_show_fix_status(show_fix_status(self.autofix_level))
|
||||
.with_show_source(self.flags.contains(Flags::SHOW_SOURCE))
|
||||
.emit(writer, &diagnostics.messages, &context)?;
|
||||
|
||||
if self.flags.contains(Flags::SHOW_FIXES) {
|
||||
|
@ -194,6 +196,7 @@ impl Printer {
|
|||
}
|
||||
SerializationFormat::Grouped => {
|
||||
GroupedEmitter::default()
|
||||
.with_show_source(self.flags.contains(Flags::SHOW_SOURCE))
|
||||
.with_show_fix_status(show_fix_status(self.autofix_level))
|
||||
.emit(writer, &diagnostics.messages, &context)?;
|
||||
|
||||
|
@ -346,6 +349,7 @@ impl Printer {
|
|||
let context = EmitterContext::new(&diagnostics.jupyter_index);
|
||||
TextEmitter::default()
|
||||
.with_show_fix_status(show_fix_status(self.autofix_level))
|
||||
.with_show_source(self.flags.contains(Flags::SHOW_SOURCE))
|
||||
.emit(&mut stdout, &diagnostics.messages, &context)?;
|
||||
}
|
||||
stdout.flush()?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue