Skip to content

Commit

Permalink
Show version-related syntax errors in the playground (#16419)
Browse files Browse the repository at this point in the history
## Summary

Fixes part of #16417 by
converting `unsupported_syntax_errors` into playground diagnostics.

## Test Plan

A new `ruff_wasm` test, plus trying out the playground locally:

Default settings:

![image](https://github.com/user-attachments/assets/94377ab5-4d4c-44d3-ae63-fe328a53e083)

`target-version = "py310"`:

![image](https://github.com/user-attachments/assets/51c312ce-70e7-43d3-b6ba-098f2750cb28)
  • Loading branch information
ntBre authored Feb 27, 2025
1 parent 764aa0e commit cf83584
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
26 changes: 21 additions & 5 deletions crates/ruff_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ use ruff_python_ast::{Mod, PySourceType};
use ruff_python_codegen::Stylist;
use ruff_python_formatter::{format_module_ast, pretty_comments, PyFormatContext, QuoteStyle};
use ruff_python_index::Indexer;
use ruff_python_parser::{
parse, parse_unchecked, parse_unchecked_source, Mode, ParseOptions, Parsed,
};
use ruff_python_parser::{parse, parse_unchecked, Mode, ParseOptions, Parsed};
use ruff_python_trivia::CommentRanges;
use ruff_source_file::SourceLocation;
use ruff_text_size::Ranged;
Expand Down Expand Up @@ -163,8 +161,14 @@ impl Workspace {
// TODO(dhruvmanila): Support Jupyter Notebooks
let source_kind = SourceKind::Python(contents.to_string());

// Use the unresolved version because we don't have a file path.
let target_version = self.settings.linter.unresolved_target_version;

// Parse once.
let parsed = parse_unchecked_source(source_kind.source_code(), source_type);
let options = ParseOptions::from(source_type).with_target_version(target_version);
let parsed = parse_unchecked(source_kind.source_code(), options)
.try_into_module()
.expect("`PySourceType` always parses to a `ModModule`.");

// Map row and column locations to byte slices (lazily).
let locator = Locator::new(contents);
Expand Down Expand Up @@ -196,7 +200,7 @@ impl Workspace {
&source_kind,
source_type,
&parsed,
self.settings.linter.unresolved_target_version,
target_version,
);

let source_code = locator.to_source_code();
Expand Down Expand Up @@ -238,6 +242,18 @@ impl Workspace {
fix: None,
}
}))
.chain(parsed.unsupported_syntax_errors().iter().map(|error| {
let start_location = source_code.source_location(error.range.start());
let end_location = source_code.source_location(error.range.end());

ExpandedMessage {
code: None,
message: format!("SyntaxError: {error}"),
location: start_location,
end_location,
fix: None,
}
}))
.collect();

serde_wasm_bindgen::to_value(&messages).map_err(into_error)
Expand Down
21 changes: 21 additions & 0 deletions crates/ruff_wasm/tests/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ fn syntax_error() {
);
}

#[wasm_bindgen_test]
fn unsupported_syntax_error() {
check!(
"match 2:\n case 1: ...",
r#"{}"#,
[ExpandedMessage {
code: None,
message: "SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)".to_string(),
location: SourceLocation {
row: OneIndexed::from_zero_indexed(0),
column: OneIndexed::from_zero_indexed(0)
},
end_location: SourceLocation {
row: OneIndexed::from_zero_indexed(0),
column: OneIndexed::from_zero_indexed(5)
},
fix: None,
}]
);
}

#[wasm_bindgen_test]
fn partial_config() {
check!("if (1, 2):\n pass", r#"{"ignore": ["F"]}"#, []);
Expand Down

0 comments on commit cf83584

Please sign in to comment.