mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-25 22:29:02 +00:00
[red-knot] Detect version-related syntax errors (#16379)
## Summary This PR extends version-related syntax error detection to red-knot. The main changes here are: 1. Passing `ParseOptions` specifying a `PythonVersion` to parser calls 2. Adding a `python_version` method to the `Db` trait to make this possible 3. Converting `UnsupportedSyntaxError`s to `Diagnostic`s 4. Updating existing mdtests to avoid unrelated syntax errors My initial draft of (1) and (2) in #16090 instead tried passing a `PythonVersion` down to every parser call, but @MichaReiser suggested the `Db` approach instead [here](https://github.com/astral-sh/ruff/pull/16090#discussion_r1969198407), and I think it turned out much nicer. All of the new `python_version` methods look like this: ```rust fn python_version(&self) -> ruff_python_ast::PythonVersion { Program::get(self).python_version(self) } ``` with the exception of the `TestDb` in `ruff_db`, which hard-codes `PythonVersion::latest()`. ## Test Plan Existing mdtests, plus a new mdtest to see at least one of the new diagnostics.
This commit is contained in:
parent
d2ebfd6ed7
commit
9c47b6dbb0
43 changed files with 353 additions and 14 deletions
|
|
@ -832,3 +832,16 @@ pub fn create_parse_diagnostic(file: File, err: &ruff_python_parser::ParseError)
|
|||
diag.annotate(Annotation::primary(span).message(&err.error));
|
||||
diag
|
||||
}
|
||||
|
||||
/// Creates a `Diagnostic` from an unsupported syntax error.
|
||||
///
|
||||
/// See [`create_parse_diagnostic`] for more details.
|
||||
pub fn create_unsupported_syntax_diagnostic(
|
||||
file: File,
|
||||
err: &ruff_python_parser::UnsupportedSyntaxError,
|
||||
) -> Diagnostic {
|
||||
let mut diag = Diagnostic::new(DiagnosticId::InvalidSyntax, Severity::Error, "");
|
||||
let span = Span::from(file).with_range(err.range);
|
||||
diag.annotate(Annotation::primary(span).message(err.to_string()));
|
||||
diag
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::hash::BuildHasherDefault;
|
||||
|
||||
use ruff_python_ast::PythonVersion;
|
||||
use rustc_hash::FxHasher;
|
||||
|
||||
use crate::files::Files;
|
||||
|
|
@ -27,6 +28,7 @@ pub trait Db: salsa::Database {
|
|||
fn vendored(&self) -> &VendoredFileSystem;
|
||||
fn system(&self) -> &dyn System;
|
||||
fn files(&self) -> &Files;
|
||||
fn python_version(&self) -> PythonVersion;
|
||||
}
|
||||
|
||||
/// Trait for upcasting a reference to a base trait object.
|
||||
|
|
@ -107,6 +109,10 @@ mod tests {
|
|||
fn files(&self) -> &Files {
|
||||
&self.files
|
||||
}
|
||||
|
||||
fn python_version(&self) -> ruff_python_ast::PythonVersion {
|
||||
ruff_python_ast::PythonVersion::latest()
|
||||
}
|
||||
}
|
||||
|
||||
impl DbWithTestSystem for TestDb {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::ops::Deref;
|
|||
use std::sync::Arc;
|
||||
|
||||
use ruff_python_ast::ModModule;
|
||||
use ruff_python_parser::{parse_unchecked_source, Parsed};
|
||||
use ruff_python_parser::{parse_unchecked, ParseOptions, Parsed};
|
||||
|
||||
use crate::files::File;
|
||||
use crate::source::source_text;
|
||||
|
|
@ -27,7 +27,13 @@ pub fn parsed_module(db: &dyn Db, file: File) -> ParsedModule {
|
|||
let source = source_text(db, file);
|
||||
let ty = file.source_type(db);
|
||||
|
||||
ParsedModule::new(parse_unchecked_source(&source, ty))
|
||||
let target_version = db.python_version();
|
||||
let options = ParseOptions::from(ty).with_target_version(target_version);
|
||||
let parsed = parse_unchecked(&source, options)
|
||||
.try_into_module()
|
||||
.expect("PySourceType always parses into a module");
|
||||
|
||||
ParsedModule::new(parsed)
|
||||
}
|
||||
|
||||
/// Cheap cloneable wrapper around the parsed module.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue