Skip to content

Commit cf83584

Browse files
authored
Show version-related syntax errors in the playground (#16419)
## 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)
1 parent 764aa0e commit cf83584

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

crates/ruff_wasm/src/lib.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ use ruff_python_ast::{Mod, PySourceType};
1818
use ruff_python_codegen::Stylist;
1919
use ruff_python_formatter::{format_module_ast, pretty_comments, PyFormatContext, QuoteStyle};
2020
use ruff_python_index::Indexer;
21-
use ruff_python_parser::{
22-
parse, parse_unchecked, parse_unchecked_source, Mode, ParseOptions, Parsed,
23-
};
21+
use ruff_python_parser::{parse, parse_unchecked, Mode, ParseOptions, Parsed};
2422
use ruff_python_trivia::CommentRanges;
2523
use ruff_source_file::SourceLocation;
2624
use ruff_text_size::Ranged;
@@ -163,8 +161,14 @@ impl Workspace {
163161
// TODO(dhruvmanila): Support Jupyter Notebooks
164162
let source_kind = SourceKind::Python(contents.to_string());
165163

164+
// Use the unresolved version because we don't have a file path.
165+
let target_version = self.settings.linter.unresolved_target_version;
166+
166167
// Parse once.
167-
let parsed = parse_unchecked_source(source_kind.source_code(), source_type);
168+
let options = ParseOptions::from(source_type).with_target_version(target_version);
169+
let parsed = parse_unchecked(source_kind.source_code(), options)
170+
.try_into_module()
171+
.expect("`PySourceType` always parses to a `ModModule`.");
168172

169173
// Map row and column locations to byte slices (lazily).
170174
let locator = Locator::new(contents);
@@ -196,7 +200,7 @@ impl Workspace {
196200
&source_kind,
197201
source_type,
198202
&parsed,
199-
self.settings.linter.unresolved_target_version,
203+
target_version,
200204
);
201205

202206
let source_code = locator.to_source_code();
@@ -238,6 +242,18 @@ impl Workspace {
238242
fix: None,
239243
}
240244
}))
245+
.chain(parsed.unsupported_syntax_errors().iter().map(|error| {
246+
let start_location = source_code.source_location(error.range.start());
247+
let end_location = source_code.source_location(error.range.end());
248+
249+
ExpandedMessage {
250+
code: None,
251+
message: format!("SyntaxError: {error}"),
252+
location: start_location,
253+
end_location,
254+
fix: None,
255+
}
256+
}))
241257
.collect();
242258

243259
serde_wasm_bindgen::to_value(&messages).map_err(into_error)

crates/ruff_wasm/tests/api.rs

+21
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,27 @@ fn syntax_error() {
6161
);
6262
}
6363

64+
#[wasm_bindgen_test]
65+
fn unsupported_syntax_error() {
66+
check!(
67+
"match 2:\n case 1: ...",
68+
r#"{}"#,
69+
[ExpandedMessage {
70+
code: None,
71+
message: "SyntaxError: Cannot use `match` statement on Python 3.9 (syntax was added in Python 3.10)".to_string(),
72+
location: SourceLocation {
73+
row: OneIndexed::from_zero_indexed(0),
74+
column: OneIndexed::from_zero_indexed(0)
75+
},
76+
end_location: SourceLocation {
77+
row: OneIndexed::from_zero_indexed(0),
78+
column: OneIndexed::from_zero_indexed(5)
79+
},
80+
fix: None,
81+
}]
82+
);
83+
}
84+
6485
#[wasm_bindgen_test]
6586
fn partial_config() {
6687
check!("if (1, 2):\n pass", r#"{"ignore": ["F"]}"#, []);

0 commit comments

Comments
 (0)