mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-22 03:14:41 +00:00
[red-knot] Add support for untitled files (#12492)
## Summary This PR adds support for untitled files in the Red Knot project. Refer to the [design discussion](https://github.com/astral-sh/ruff/discussions/12336) for more details. ### Changes * The `parsed_module` always assumes that the `SystemVirtual` path is of `PySourceType::Python`. * For the module resolver, as suggested, I went ahead by adding a new `SystemOrVendoredPath` enum and renamed `FilePathRef` to `SystemOrVendoredPathRef` (happy to consider better names here). * The `file_to_module` query would return if it's a `FilePath::SystemVirtual` variant because a virtual file doesn't belong to any module. * The sync implementation for the system virtual path is basically the same as that of system path except that it uses the `virtual_path_metadata`. The reason for this is that the system (language server) would provide the metadata on whether it still exists or not and if it exists, the corresponding metadata. For point (1), VS Code would use `Untitled-1` for Python files and `Untitled-1.ipynb` for Jupyter Notebooks. We could use this distinction to determine whether the source type is `Python` or `Ipynb`. ## Test Plan Added test cases in #12526
This commit is contained in:
parent
71f7aa4971
commit
6f4db8675b
11 changed files with 534 additions and 63 deletions
|
@ -8,7 +8,7 @@ use ruff_notebook::Notebook;
|
|||
use ruff_python_ast::PySourceType;
|
||||
use ruff_source_file::LineIndex;
|
||||
|
||||
use crate::files::File;
|
||||
use crate::files::{File, FilePath};
|
||||
use crate::Db;
|
||||
|
||||
/// Reads the source text of a python text file (must be valid UTF8) or notebook.
|
||||
|
@ -16,25 +16,33 @@ use crate::Db;
|
|||
pub fn source_text(db: &dyn Db, file: File) -> SourceText {
|
||||
let _span = tracing::trace_span!("source_text", ?file).entered();
|
||||
|
||||
if let Some(path) = file.path(db).as_system_path() {
|
||||
if path.extension().is_some_and(|extension| {
|
||||
let is_notebook = match file.path(db) {
|
||||
FilePath::System(system) => system.extension().is_some_and(|extension| {
|
||||
PySourceType::try_from_extension(extension) == Some(PySourceType::Ipynb)
|
||||
}) {
|
||||
// TODO(micha): Proper error handling and emit a diagnostic. Tackle it together with `source_text`.
|
||||
let notebook = file.read_to_notebook(db).unwrap_or_else(|error| {
|
||||
tracing::error!("Failed to load notebook: {error}");
|
||||
Notebook::empty()
|
||||
});
|
||||
|
||||
return SourceText {
|
||||
inner: Arc::new(SourceTextInner {
|
||||
kind: SourceTextKind::Notebook(notebook),
|
||||
count: Count::new(),
|
||||
}),
|
||||
};
|
||||
}),
|
||||
FilePath::SystemVirtual(system_virtual) => {
|
||||
system_virtual.extension().is_some_and(|extension| {
|
||||
PySourceType::try_from_extension(extension) == Some(PySourceType::Ipynb)
|
||||
})
|
||||
}
|
||||
FilePath::Vendored(_) => false,
|
||||
};
|
||||
|
||||
if is_notebook {
|
||||
// TODO(micha): Proper error handling and emit a diagnostic. Tackle it together with `source_text`.
|
||||
let notebook = file.read_to_notebook(db).unwrap_or_else(|error| {
|
||||
tracing::error!("Failed to load notebook: {error}");
|
||||
Notebook::empty()
|
||||
});
|
||||
|
||||
return SourceText {
|
||||
inner: Arc::new(SourceTextInner {
|
||||
kind: SourceTextKind::Notebook(notebook),
|
||||
count: Count::new(),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
let content = file.read_to_string(db).unwrap_or_else(|error| {
|
||||
tracing::error!("Failed to load file: {error}");
|
||||
String::default()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue