Automatic fixing of deprecations and use non-quoted default planes by default (#5902)

* Automatic fixing of deprecations and use non-quoted default planes by default

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

* A snapshot a day keeps the bugs away! 📷🐛

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Nick Cameron
2025-03-21 22:39:12 +13:00
committed by GitHub
parent 06b35b76ff
commit e8feb0309b
235 changed files with 1227 additions and 1097 deletions

View File

@ -726,7 +726,7 @@ async fn test_kcl_lsp_completions_tags() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> startProfileAt([11.19, 28.35], %)
|> line(end = [28.67, -13.25], tag = $here)
|> line(end = [-4.12, -22.81])
@ -1078,7 +1078,7 @@ async fn test_kcl_lsp_signature_help() {
content_changes: vec![tower_lsp::lsp_types::TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: "startSketchOn('XY')".to_string(),
text: "startSketchOn(XY)".to_string(),
}],
})
.await;
@ -1123,7 +1123,7 @@ async fn test_kcl_lsp_semantic_tokens() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: "startSketchOn('XY')".to_string(),
text: "startSketchOn(XY)".to_string(),
},
})
.await;
@ -1153,13 +1153,13 @@ async fn test_kcl_lsp_semantic_tokens() {
.get_semantic_token_type_index(&SemanticTokenType::FUNCTION)
.unwrap()
);
assert_eq!(semantic_tokens.data[1].length, 4);
assert_eq!(semantic_tokens.data[1].length, 2);
assert_eq!(semantic_tokens.data[1].delta_start, 14);
assert_eq!(semantic_tokens.data[1].delta_line, 0);
assert_eq!(
semantic_tokens.data[1].token_type,
server
.get_semantic_token_type_index(&SemanticTokenType::STRING)
.get_semantic_token_type_index(&SemanticTokenType::VARIABLE)
.unwrap()
);
} else {
@ -1216,7 +1216,7 @@ async fn test_kcl_lsp_semantic_tokens_with_modifiers() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20], tag = $seg01)
@ -1479,7 +1479,7 @@ async fn test_kcl_lsp_document_symbol() {
language_id: "kcl".to_string(),
version: 1,
text: r#"myVar = 1
startSketchOn('XY')"#
startSketchOn(XY)"#
.to_string(),
},
})
@ -1518,7 +1518,7 @@ async fn test_kcl_lsp_document_symbol_tag() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> startProfileAt([11.19, 28.35], %)
|> line(end = [28.67, -13.25], tag = $here)
|> line(end = [-4.12, -22.81])
@ -1564,7 +1564,7 @@ async fn test_kcl_lsp_formatting() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: r#"startSketchOn('XY')
text: r#"startSketchOn(XY)
|> startProfileAt([0,0], %)"#
.to_string(),
},
@ -1595,7 +1595,7 @@ async fn test_kcl_lsp_formatting() {
assert_eq!(formatting.len(), 1);
assert_eq!(
formatting[0].new_text,
r#"startSketchOn('XY')
r#"startSketchOn(XY)
|> startProfileAt([0, 0], %)"#
);
}
@ -1621,7 +1621,7 @@ thickness = 0.25
overHangLength = .4
// Sketch and revolve the inside bearing piece
insideRevolve = startSketchOn('XZ')
insideRevolve = startSketchOn(XZ)
|> startProfileAt([insideDia / 2, 0], %)
|> line(end = [0, thickness + sphereDia / 2])
|> line(end = [overHangLength, 0])
@ -1635,7 +1635,7 @@ insideRevolve = startSketchOn('XZ')
|> revolve({ axis: 'y' }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn('XZ')
sphere = startSketchOn(XZ)
|> startProfileAt([
0.05 + insideDia / 2 + thickness,
0 - 0.05
@ -1657,7 +1657,7 @@ sphere = startSketchOn('XZ')
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')
outsideRevolve = startSketchOn(XZ)
|> startProfileAt([
insideDia / 2 + thickness + sphereDia,
0
@ -1721,7 +1721,7 @@ thickness = 0.25
overHangLength = .4
// Sketch and revolve the inside bearing piece
insideRevolve = startSketchOn('XZ')
insideRevolve = startSketchOn(XZ)
|> startProfileAt([insideDia / 2, 0], %)
|> line(end = [0, thickness + sphereDia / 2])
|> line(end = [overHangLength, 0])
@ -1735,7 +1735,7 @@ insideRevolve = startSketchOn('XZ')
|> revolve({ axis = 'y' }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn('XZ')
sphere = startSketchOn(XZ)
|> startProfileAt([
0.05 + insideDia / 2 + thickness,
0 - 0.05
@ -1757,7 +1757,7 @@ sphere = startSketchOn('XZ')
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')
outsideRevolve = startSketchOn(XZ)
|> startProfileAt([
insideDia / 2 + thickness + sphereDia,
0
@ -2007,7 +2007,7 @@ async fn test_copilot_lsp_completions_raw() {
let completions = server
.get_completions(
"kcl".to_string(),
r#"bracket = startSketchOn('XY')
r#"bracket = startSketchOn(XY)
|> startProfileAt([0, 0], %)
"#
.to_string(),
@ -2026,7 +2026,7 @@ async fn test_copilot_lsp_completions_raw() {
let completions_hit_cache = server
.get_completions(
"kcl".to_string(),
r#"bracket = startSketchOn('XY')
r#"bracket = startSketchOn(XY)
|> startProfileAt([0, 0], %)
"#
.to_string(),
@ -2066,7 +2066,7 @@ async fn test_copilot_lsp_completions() {
path: "file:///test.copilot".to_string(),
position: crate::lsp::copilot::types::CopilotPosition { line: 3, character: 3 },
relative_path: "test.copilot".to_string(),
source: r#"bracket = startSketchOn('XY')
source: r#"bracket = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> close()
@ -2325,7 +2325,7 @@ async fn kcl_test_kcl_lsp_update_units() {
let server = kcl_lsp_server(true).await.unwrap();
let same_text = r#"fn cube = (pos, scale) => {
sg = startSketchOn('XY')
sg = startSketchOn(XY)
|> startProfileAt(pos, %)
|> line(end = [0, scale])
|> line(end = [scale, 0])
@ -2460,7 +2460,7 @@ async fn kcl_test_kcl_lsp_diagnostics_on_execution_error() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2481,7 +2481,7 @@ async fn kcl_test_kcl_lsp_diagnostics_on_execution_error() {
assert_diagnostic_count(server.diagnostics_map.get("file:///test.kcl").as_deref(), 1);
// Update the text.
let new_text = r#"part001 = startSketchOn('XY')
let new_text = r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2519,7 +2519,7 @@ async fn kcl_test_kcl_lsp_full_to_empty_file_updates_ast_and_memory() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2562,7 +2562,7 @@ async fn kcl_test_kcl_lsp_full_to_empty_file_updates_ast_and_memory() {
async fn kcl_test_kcl_lsp_code_unchanged_but_has_diagnostics_reexecute() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"part001 = startSketchOn('XY')
let code = r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2648,7 +2648,7 @@ async fn kcl_test_kcl_lsp_code_unchanged_but_has_diagnostics_reexecute() {
async fn kcl_test_kcl_lsp_code_and_ast_unchanged_but_has_diagnostics_reexecute() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"part001 = startSketchOn('XY')
let code = r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2723,7 +2723,7 @@ async fn kcl_test_kcl_lsp_code_and_ast_unchanged_but_has_diagnostics_reexecute()
async fn kcl_test_kcl_lsp_code_and_ast_units_unchanged_but_has_diagnostics_reexecute_on_unit_change() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"part001 = startSketchOn('XY')
let code = r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2801,7 +2801,7 @@ async fn kcl_test_kcl_lsp_code_and_ast_units_unchanged_but_has_diagnostics_reexe
async fn kcl_test_kcl_lsp_code_and_ast_units_unchanged_but_has_memory_reexecute_on_unit_change() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"part001 = startSketchOn('XY')
let code = r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2858,7 +2858,7 @@ async fn kcl_test_kcl_lsp_code_and_ast_units_unchanged_but_has_memory_reexecute_
async fn kcl_test_kcl_lsp_cant_execute_set() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"part001 = startSketchOn('XY')
let code = r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -2988,7 +2988,7 @@ async fn test_kcl_lsp_folding() {
uri: "file:///test.kcl".try_into().unwrap(),
language_id: "kcl".to_string(),
version: 1,
text: r#"startSketchOn('XY')
text: r#"startSketchOn(XY)
|> startProfileAt([0,0], %)"#
.to_string(),
},
@ -3013,12 +3013,12 @@ async fn test_kcl_lsp_folding() {
assert_eq!(
folding.first().unwrap().clone(),
tower_lsp::lsp_types::FoldingRange {
start_line: 19,
start_line: 17,
start_character: None,
end_line: 67,
end_line: 65,
end_character: None,
kind: Some(tower_lsp::lsp_types::FoldingRangeKind::Region),
collapsed_text: Some("startSketchOn('XY')".to_string())
collapsed_text: Some("startSketchOn(XY)".to_string())
}
);
}
@ -3027,7 +3027,7 @@ async fn test_kcl_lsp_folding() {
async fn kcl_test_kcl_lsp_code_with_parse_error_and_ast_unchanged_but_has_diagnostics_reparse() {
let server = kcl_lsp_server(false).await.unwrap();
let code = r#"part001 = startSketchOn('XY')
let code = r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -3082,7 +3082,7 @@ async fn kcl_test_kcl_lsp_code_with_lint_and_ast_unchanged_but_has_diagnostics_r
let server = kcl_lsp_server(false).await.unwrap();
let code = r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -3136,7 +3136,7 @@ async fn kcl_test_kcl_lsp_code_with_lint_and_parse_error_and_ast_unchanged_but_h
let server = kcl_lsp_server(false).await.unwrap();
let code = r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -3191,7 +3191,7 @@ async fn kcl_test_kcl_lsp_code_lint_and_ast_unchanged_but_has_diagnostics_reexec
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20], tag = $seg01)
@ -3250,7 +3250,7 @@ async fn kcl_test_kcl_lsp_code_lint_reexecute_new_lint() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20], tag = $seg01)
@ -3289,7 +3289,7 @@ part001 = startSketchOn('XY')
content_changes: vec![tower_lsp::lsp_types::TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20], tag = $seg01)
@ -3317,7 +3317,7 @@ async fn kcl_test_kcl_lsp_code_lint_reexecute_new_ast_error() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20], tag = $seg01)
@ -3356,7 +3356,7 @@ part001 = startSketchOn('XY')
content_changes: vec![tower_lsp::lsp_types::TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> ^^^^startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20], tag = $seg01)
@ -3384,7 +3384,7 @@ async fn kcl_test_kcl_lsp_code_lint_reexecute_had_lint_new_parse_error() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -3431,7 +3431,7 @@ part001 = startSketchOn('XY')
content_changes: vec![tower_lsp::lsp_types::TextDocumentContentChangeEvent {
range: None,
range_length: None,
text: r#"part001 = startSketchOn('XY')
text: r#"part001 = startSketchOn(XY)
|> ^^^^startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -3467,7 +3467,7 @@ async fn kcl_test_kcl_lsp_code_lint_reexecute_had_lint_new_execution_error() {
let server = kcl_lsp_server(true).await.unwrap();
let code = r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0])
|> line(end = [0, 20])
@ -3519,7 +3519,7 @@ part001 = startSketchOn('XY')
range: None,
range_length: None,
text: r#"LINT = 1
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line(end = [20, 0], tag = $seg01)
|> line(end = [0, 20], tag = $seg01)

View File

@ -25,6 +25,13 @@ impl LiteralValue {
suffix: NumericSuffix::None,
}
}
pub fn string_value(&self) -> Option<&str> {
match self {
Self::String(s) => Some(s),
_ => None,
}
}
}
impl fmt::Display for LiteralValue {

View File

@ -2192,8 +2192,13 @@ impl Node<Identifier> {
/// Get the constraint level for this identifier.
/// Identifier are always fully constrained.
pub fn get_constraint_level(&self) -> ConstraintLevel {
ConstraintLevel::Full {
source_ranges: vec![self.into()],
match &*self.name {
"XY" | "XZ" | "YZ" => ConstraintLevel::None {
source_ranges: vec![self.into()],
},
_ => ConstraintLevel::Full {
source_ranges: vec![self.into()],
},
}
}
}
@ -3484,11 +3489,11 @@ mod tests {
#[test]
fn test_get_lsp_folding_ranges() {
let code = r#"const part001 = startSketchOn('XY')
let code = r#"const part001 = startSketchOn(XY)
|> startProfileAt([0.0000000000, 5.0000000000], %)
|> line([0.4900857016, -0.0240763666], %)
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([0.0000000000, 5.0000000000], %)
|> line([0.4900857016, -0.0240763666], %)
@ -3507,20 +3512,17 @@ ghi("things")
let program = crate::parsing::top_level_parse(code).unwrap();
let folding_ranges = program.get_lsp_folding_ranges();
assert_eq!(folding_ranges.len(), 3);
assert_eq!(folding_ranges[0].start_line, 29);
assert_eq!(folding_ranges[0].end_line, 134);
assert_eq!(folding_ranges[0].start_line, 27);
assert_eq!(folding_ranges[0].end_line, 132);
assert_eq!(
folding_ranges[0].collapsed_text,
Some("part001 = startSketchOn('XY')".to_string())
Some("part001 = startSketchOn(XY)".to_string())
);
assert_eq!(folding_ranges[1].start_line, 155);
assert_eq!(folding_ranges[1].end_line, 254);
assert_eq!(
folding_ranges[1].collapsed_text,
Some("startSketchOn('XY')".to_string())
);
assert_eq!(folding_ranges[2].start_line, 384);
assert_eq!(folding_ranges[2].end_line, 403);
assert_eq!(folding_ranges[1].start_line, 151);
assert_eq!(folding_ranges[1].end_line, 250);
assert_eq!(folding_ranges[1].collapsed_text, Some("startSketchOn(XY)".to_string()));
assert_eq!(folding_ranges[2].start_line, 380);
assert_eq!(folding_ranges[2].end_line, 399);
assert_eq!(folding_ranges[2].collapsed_text, Some("fn ghi(x) {".to_string()));
}
@ -3986,7 +3988,7 @@ const cylinder = startSketchOn('-XZ')
async fn test_parse_get_meta_settings_inch() {
let some_program_string = r#"@settings(defaultLengthUnit = inch)
startSketchOn('XY')"#;
startSketchOn(XY)"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let result = program.meta_settings().unwrap();
assert!(result.is_some());
@ -4002,7 +4004,7 @@ startSketchOn('XY')"#;
async fn test_parse_get_meta_settings_inch_to_mm() {
let some_program_string = r#"@settings(defaultLengthUnit = inch)
startSketchOn('XY')"#;
startSketchOn(XY)"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let result = program.meta_settings().unwrap();
assert!(result.is_some());
@ -4033,14 +4035,14 @@ startSketchOn('XY')"#;
formatted,
r#"@settings(defaultLengthUnit = mm)
startSketchOn('XY')
startSketchOn(XY)
"#
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_parse_get_meta_settings_nothing_to_mm() {
let some_program_string = r#"startSketchOn('XY')"#;
let some_program_string = r#"startSketchOn(XY)"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let result = program.meta_settings().unwrap();
assert!(result.is_none());
@ -4065,7 +4067,7 @@ startSketchOn('XY')
formatted,
r#"@settings(defaultLengthUnit = mm)
startSketchOn('XY')
startSketchOn(XY)
"#
);
}

View File

@ -146,6 +146,32 @@ impl From<KclError> for ParseResult {
}
}
const STR_DEPRECATIONS: [(&str, &str); 6] = [
("XY", "XY"),
("XZ", "XZ"),
("YZ", "YZ"),
("-XY", "-XY"),
("-XZ", "-XZ"),
("-YZ", "-YZ"),
];
const FN_DEPRECATIONS: [(&str, &str); 3] = [("pi", "PI"), ("e", "E"), ("tau", "TAU")];
const CONST_DEPRECATIONS: [(&str, &str); 0] = [];
#[derive(Clone, Copy)]
pub enum DeprecationKind {
String,
Function,
Const,
}
pub fn deprecation(s: &str, kind: DeprecationKind) -> Option<&'static str> {
match kind {
DeprecationKind::String => STR_DEPRECATIONS.iter().find_map(|(a, b)| (*a == s).then_some(*b)),
DeprecationKind::Function => FN_DEPRECATIONS.iter().find_map(|(a, b)| (*a == s).then_some(*b)),
DeprecationKind::Const => CONST_DEPRECATIONS.iter().find_map(|(a, b)| (*a == s).then_some(*b)),
}
}
#[cfg(test)]
mod tests {
macro_rules! parse_and_lex {

View File

@ -15,6 +15,7 @@ use winnow::{
use super::{
ast::types::{Ascription, ImportPath, LabelledExpression},
token::{NumericSuffix, RESERVED_WORDS},
DeprecationKind,
};
use crate::{
docs::StdLibFn,
@ -477,7 +478,8 @@ fn string_literal(i: &mut TokenSlice) -> PResult<Node<Literal>> {
})
.context(expected("string literal (like \"myPart\""))
.parse_next(i)?;
Ok(Node::new(
let result = Node::new(
Literal {
value,
raw: token.value.clone(),
@ -486,7 +488,32 @@ fn string_literal(i: &mut TokenSlice) -> PResult<Node<Literal>> {
token.start,
token.end,
token.module_id,
))
);
if let Some(suggestion) = super::deprecation(result.value.string_value().unwrap(), DeprecationKind::String) {
ParseContext::warn(
CompilationError::err(
result.as_source_range(),
format!(
"Using `\"{}\"` is deprecated, prefer using `{}`.",
result.value.string_value().unwrap(),
suggestion
),
)
.with_suggestion(
format!(
"Replace `\"{}\"` with `{}`",
result.value.string_value().unwrap(),
suggestion
),
suggestion,
None,
Tag::Deprecated,
),
);
}
Ok(result)
}
/// Parse a KCL literal number, with no - sign.
@ -2315,6 +2342,21 @@ fn nameable_identifier(i: &mut TokenSlice) -> PResult<Node<Identifier>> {
));
}
if let Some(suggestion) = super::deprecation(&result.name, DeprecationKind::Const) {
ParseContext::warn(
CompilationError::err(
result.as_source_range(),
format!("Using `{}` is deprecated, prefer using `{}`.", result.name, suggestion),
)
.with_suggestion(
format!("Replace `{}` with `{}`", result.name, suggestion),
suggestion,
None,
Tag::Deprecated,
),
);
}
Ok(result)
}
@ -3016,7 +3058,7 @@ fn fn_call(i: &mut TokenSlice) -> PResult<Node<CallExpression>> {
}
let end = preceded(opt(whitespace), close_paren).parse_next(i)?.end;
Ok(Node::new_node(
let result = Node::new_node(
fn_name.start,
end,
fn_name.module_id,
@ -3025,7 +3067,27 @@ fn fn_call(i: &mut TokenSlice) -> PResult<Node<CallExpression>> {
arguments: args,
digest: None,
},
))
);
if let Some(suggestion) = super::deprecation(&result.callee.name, DeprecationKind::Function) {
ParseContext::warn(
CompilationError::err(
result.as_source_range(),
format!(
"Calling `{}` is deprecated, prefer using `{}`.",
result.callee.name, suggestion
),
)
.with_suggestion(
format!("Replace `{}` with `{}`", result.callee.name, suggestion),
suggestion,
None,
Tag::Deprecated,
),
);
}
Ok(result)
}
fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
@ -3097,7 +3159,7 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
non_code_nodes,
..Default::default()
};
Ok(Node::new_node(
let result = Node::new_node(
fn_name.start,
end,
fn_name.module_id,
@ -3108,7 +3170,27 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
digest: None,
non_code_meta,
},
))
);
if let Some(suggestion) = super::deprecation(&result.callee.name, DeprecationKind::Function) {
ParseContext::warn(
CompilationError::err(
result.as_source_range(),
format!(
"Calling `{}` is deprecated, prefer using `{}`.",
result.callee.name, suggestion
),
)
.with_suggestion(
format!("Replace `{}` with `{}`", result.callee.name, suggestion),
suggestion,
None,
Tag::Deprecated,
),
);
}
Ok(result)
}
#[cfg(test)]
@ -3326,7 +3408,7 @@ mySk1 = startSketchOn(XY)
#[test]
fn inline_comment_pipe_expression() {
let test_input = r#"a('XY')
let test_input = r#"a(XY)
|> b(%)
|> c(%) // inline-comment
|> d(%)"#;

View File

@ -8,7 +8,7 @@ expression: actual
"commentStart": 0,
"declaration": {
"commentStart": 6,
"end": 106,
"end": 104,
"id": {
"commentStart": 6,
"end": 14,
@ -22,12 +22,11 @@ expression: actual
"arguments": [
{
"commentStart": 31,
"end": 35,
"raw": "'XY'",
"end": 33,
"name": "XY",
"start": 31,
"type": "Literal",
"type": "Literal",
"value": "XY"
"type": "Identifier",
"type": "Identifier"
}
],
"callee": {
@ -38,7 +37,7 @@ expression: actual
"type": "Identifier"
},
"commentStart": 17,
"end": 36,
"end": 34,
"start": 17,
"type": "CallExpression",
"type": "CallExpression"
@ -48,20 +47,20 @@ expression: actual
{
"type": "LabeledArg",
"label": {
"commentStart": 51,
"end": 57,
"commentStart": 49,
"end": 55,
"name": "center",
"start": 51,
"start": 49,
"type": "Identifier"
},
"arg": {
"commentStart": 59,
"commentStart": 57,
"elements": [
{
"commentStart": 60,
"end": 61,
"commentStart": 58,
"end": 59,
"raw": "0",
"start": 60,
"start": 58,
"type": "Literal",
"type": "Literal",
"value": {
@ -70,10 +69,10 @@ expression: actual
}
},
{
"commentStart": 63,
"end": 64,
"commentStart": 61,
"end": 62,
"raw": "0",
"start": 63,
"start": 61,
"type": "Literal",
"type": "Literal",
"value": {
@ -82,8 +81,8 @@ expression: actual
}
}
],
"end": 65,
"start": 59,
"end": 63,
"start": 57,
"type": "ArrayExpression",
"type": "ArrayExpression"
}
@ -91,17 +90,17 @@ expression: actual
{
"type": "LabeledArg",
"label": {
"commentStart": 67,
"end": 73,
"commentStart": 65,
"end": 71,
"name": "radius",
"start": 67,
"start": 65,
"type": "Identifier"
},
"arg": {
"commentStart": 75,
"end": 77,
"commentStart": 73,
"end": 75,
"raw": "22",
"start": 75,
"start": 73,
"type": "Literal",
"type": "Literal",
"value": {
@ -112,15 +111,15 @@ expression: actual
}
],
"callee": {
"commentStart": 44,
"end": 50,
"commentStart": 42,
"end": 48,
"name": "circle",
"start": 44,
"start": 42,
"type": "Identifier"
},
"commentStart": 44,
"end": 78,
"start": 44,
"commentStart": 42,
"end": 76,
"start": 42,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
@ -130,17 +129,17 @@ expression: actual
{
"type": "LabeledArg",
"label": {
"commentStart": 94,
"end": 100,
"commentStart": 92,
"end": 98,
"name": "length",
"start": 94,
"start": 92,
"type": "Identifier"
},
"arg": {
"commentStart": 103,
"end": 105,
"commentStart": 101,
"end": 103,
"raw": "14",
"start": 103,
"start": 101,
"type": "Literal",
"type": "Literal",
"value": {
@ -151,22 +150,22 @@ expression: actual
}
],
"callee": {
"commentStart": 86,
"end": 93,
"commentStart": 84,
"end": 91,
"name": "extrude",
"start": 86,
"start": 84,
"type": "Identifier"
},
"commentStart": 86,
"end": 106,
"start": 86,
"commentStart": 84,
"end": 104,
"start": 84,
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": null
}
],
"commentStart": 17,
"end": 106,
"end": 104,
"start": 17,
"type": "PipeExpression",
"type": "PipeExpression"
@ -174,7 +173,7 @@ expression: actual
"start": 6,
"type": "VariableDeclarator"
},
"end": 106,
"end": 104,
"kind": "const",
"start": 0,
"type": "VariableDeclaration",
@ -182,6 +181,6 @@ expression: actual
}
],
"commentStart": 0,
"end": 107,
"end": 105,
"start": 0
}

View File

@ -8,8 +8,9 @@ use crate::parsing::{
LiteralValue, MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter,
PipeExpression, Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration, VariableKind,
},
deprecation,
token::NumericSuffix,
PIPE_OPERATOR,
DeprecationKind, PIPE_OPERATOR,
};
impl Program {
@ -292,7 +293,10 @@ impl Expr {
}
Expr::CallExpression(call_exp) => call_exp.recast(options, indentation_level, ctxt),
Expr::CallExpressionKw(call_exp) => call_exp.recast(options, indentation_level, ctxt),
Expr::Identifier(ident) => ident.name.to_string(),
Expr::Identifier(ident) => match deprecation(&ident.name, DeprecationKind::Const) {
Some(suggestion) => suggestion.to_owned(),
None => ident.name.to_owned(),
},
Expr::TagDeclarator(tag) => tag.recast(),
Expr::PipeExpression(pipe_exp) => pipe_exp.recast(options, indentation_level),
Expr::UnaryExpression(unary_exp) => unary_exp.recast(options),
@ -321,7 +325,10 @@ impl BinaryPart {
fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
match &self {
BinaryPart::Literal(literal) => literal.recast(),
BinaryPart::Identifier(identifier) => identifier.name.to_string(),
BinaryPart::Identifier(ident) => match deprecation(&ident.name, DeprecationKind::Const) {
Some(suggestion) => suggestion.to_owned(),
None => ident.name.to_owned(),
},
BinaryPart::BinaryExpression(binary_expression) => binary_expression.recast(options),
BinaryPart::CallExpression(call_expression) => {
call_expression.recast(options, indentation_level, ExprContext::Other)
@ -376,6 +383,11 @@ impl CallExpressionKw {
options.get_indentation(indentation_level)
};
let name = &self.callee.name;
if let Some(suggestion) = deprecation(name, DeprecationKind::Function) {
return format!("{indent}{suggestion}");
}
let arg_list = self.recast_args(options, indentation_level, ctxt);
let args = arg_list.clone().join(", ");
let has_lots_of_args = arg_list.len() >= 4;
@ -480,6 +492,9 @@ impl Literal {
}
}
LiteralValue::String(ref s) => {
if let Some(suggestion) = deprecation(s, DeprecationKind::String) {
return suggestion.to_owned();
}
let quote = if self.raw.trim().starts_with('"') { '"' } else { '\'' };
format!("{quote}{s}{quote}")
}
@ -1078,7 +1093,7 @@ s = 1 // s = 1 -> height of Z is 13.4mm
d = 1
fn rect(x, y, w, h) {
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([x, y], %)
|> xLine(length = w)
|> yLine(length = h)
@ -1088,7 +1103,7 @@ fn rect(x, y, w, h) {
}
fn quad(x1, y1, x2, y2, x3, y3, x4, y4) {
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([x1, y1], %)
|> line(endAbsolute = [x2, y2])
|> line(endAbsolute = [x3, y3])
@ -1098,7 +1113,7 @@ fn quad(x1, y1, x2, y2, x3, y3, x4, y4) {
}
fn crosshair(x, y) {
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([x, y], %)
|> yLine(length = 1)
|> yLine(length = -2)
@ -1144,7 +1159,7 @@ fn o(c_x, c_y) {
// crosshair(c_x, c_y)
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([o_x1, o_y1], %)
|> arc({
radius = o_r,
@ -1160,7 +1175,7 @@ fn o(c_x, c_y) {
|> close()
|> extrude(d, %)
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([o_x2, o_y2], %)
|> arc({
radius = o_r,
@ -1203,7 +1218,7 @@ thickness = 0.25
overHangLength = .4
// Sketch and revolve the inside bearing piece
insideRevolve = startSketchOn('XZ')
insideRevolve = startSketchOn(XZ)
|> startProfileAt([insideDia / 2, 0], %)
|> line([0, thickness + sphereDia / 2], %)
|> line([overHangLength, 0], %)
@ -1217,7 +1232,7 @@ insideRevolve = startSketchOn('XZ')
|> revolve({ axis: 'y' }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn('XZ')
sphere = startSketchOn(XZ)
|> startProfileAt([
0.05 + insideDia / 2 + thickness,
0 - 0.05
@ -1239,7 +1254,7 @@ sphere = startSketchOn('XZ')
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')
outsideRevolve = startSketchOn(XZ)
|> startProfileAt([
insideDia / 2 + thickness + sphereDia,
0
@ -1269,7 +1284,7 @@ thickness = 0.25
overHangLength = .4
// Sketch and revolve the inside bearing piece
insideRevolve = startSketchOn('XZ')
insideRevolve = startSketchOn(XZ)
|> startProfileAt([insideDia / 2, 0], %)
|> line([0, thickness + sphereDia / 2], %)
|> line([overHangLength, 0], %)
@ -1283,7 +1298,7 @@ insideRevolve = startSketchOn('XZ')
|> revolve({ axis = 'y' }, %)
// Sketch and revolve one of the balls and duplicate it using a circular pattern. (This is currently a workaround, we have a bug with rotating on a sketch that touches the rotation axis)
sphere = startSketchOn('XZ')
sphere = startSketchOn(XZ)
|> startProfileAt([
0.05 + insideDia / 2 + thickness,
0 - 0.05
@ -1305,7 +1320,7 @@ sphere = startSketchOn('XZ')
)
// Sketch and revolve the outside bearing
outsideRevolve = startSketchOn('XZ')
outsideRevolve = startSketchOn(XZ)
|> startProfileAt([
insideDia / 2 + thickness + sphereDia,
0
@ -1455,7 +1470,7 @@ myNestedVar = [
#[test]
fn test_recast_shebang() {
let some_program_string = r#"#!/usr/local/env zoo kcl
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
@ -1470,7 +1485,7 @@ part001 = startSketchOn('XY')
recasted,
r#"#!/usr/local/env zoo kcl
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
@ -1486,7 +1501,7 @@ part001 = startSketchOn('XY')
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
@ -1501,7 +1516,7 @@ part001 = startSketchOn('XY')
recasted,
r#"#!/usr/local/env zoo kcl
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
@ -1516,7 +1531,7 @@ part001 = startSketchOn('XY')
let some_program_string = r#"#!/usr/local/env zoo kcl
// Yo yo my comments.
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
@ -1532,7 +1547,7 @@ part001 = startSketchOn('XY')
r#"#!/usr/local/env zoo kcl
// Yo yo my comments.
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([-10, -10], %)
|> line([20, 0], %)
|> line([0, 20], %)
@ -1795,7 +1810,7 @@ tabs_l = startSketchOn({
#[test]
fn test_recast_nested_var_declaration_in_fn_body() {
let some_program_string = r#"fn cube = (pos, scale) => {
sg = startSketchOn('XY')
sg = startSketchOn(XY)
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
@ -1809,7 +1824,7 @@ tabs_l = startSketchOn({
assert_eq!(
recasted,
r#"fn cube(pos, scale) {
sg = startSketchOn('XY')
sg = startSketchOn(XY)
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
@ -1826,7 +1841,7 @@ tabs_l = startSketchOn({
let some_program_string = r#"fn cube(pos, scale) {
x = dfsfs + dfsfsd as y
sg = startSketchOn('XY')
sg = startSketchOn(XY)
|> startProfileAt(pos, %) as foo
|> line([0, scale], %)
|> line([scale, 0], %) as bar
@ -1845,7 +1860,7 @@ cube(0, 0) as cub
#[test]
fn test_recast_with_bad_indentation() {
let some_program_string = r#"part001 = startSketchOn('XY')
let some_program_string = r#"part001 = startSketchOn(XY)
|> startProfileAt([0.0, 5.0], %)
|> line([0.4900857016, -0.0240763666], %)
|> line([0.6804562304, 0.9087880491], %)"#;
@ -1854,7 +1869,7 @@ cube(0, 0) as cub
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"part001 = startSketchOn('XY')
r#"part001 = startSketchOn(XY)
|> startProfileAt([0.0, 5.0], %)
|> line([0.4900857016, -0.0240763666], %)
|> line([0.6804562304, 0.9087880491], %)
@ -1864,7 +1879,7 @@ cube(0, 0) as cub
#[test]
fn test_recast_with_bad_indentation_and_inline_comment() {
let some_program_string = r#"part001 = startSketchOn('XY')
let some_program_string = r#"part001 = startSketchOn(XY)
|> startProfileAt([0.0, 5.0], %)
|> line([0.4900857016, -0.0240763666], %) // hello world
|> line([0.6804562304, 0.9087880491], %)"#;
@ -1873,7 +1888,7 @@ cube(0, 0) as cub
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"part001 = startSketchOn('XY')
r#"part001 = startSketchOn(XY)
|> startProfileAt([0.0, 5.0], %)
|> line([0.4900857016, -0.0240763666], %) // hello world
|> line([0.6804562304, 0.9087880491], %)
@ -1882,7 +1897,7 @@ cube(0, 0) as cub
}
#[test]
fn test_recast_with_bad_indentation_and_line_comment() {
let some_program_string = r#"part001 = startSketchOn('XY')
let some_program_string = r#"part001 = startSketchOn(XY)
|> startProfileAt([0.0, 5.0], %)
|> line([0.4900857016, -0.0240763666], %)
// hello world
@ -1892,7 +1907,7 @@ cube(0, 0) as cub
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"part001 = startSketchOn('XY')
r#"part001 = startSketchOn(XY)
|> startProfileAt([0.0, 5.0], %)
|> line([0.4900857016, -0.0240763666], %)
// hello world
@ -2047,7 +2062,7 @@ mySk1 = startSketchOn(XY)
#[test]
fn test_recast_lots_of_comments() {
let some_program_string = r#"// comment at start
mySk1 = startSketchOn('XY')
mySk1 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [1, 1])
// comment here
@ -2068,7 +2083,7 @@ mySk1 = startSketchOn('XY')
assert_eq!(
recasted,
r#"// comment at start
mySk1 = startSketchOn('XY')
mySk1 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line(endAbsolute = [1, 1])
// comment here
@ -2088,7 +2103,7 @@ mySk1 = startSketchOn('XY')
#[test]
fn test_recast_multiline_object() {
let some_program_string = r#"part001 = startSketchOn('XY')
let some_program_string = r#"part001 = startSketchOn(XY)
|> startProfileAt([-0.01, -0.08], %)
|> line([0.62, 4.15], %, $seg01)
|> line([2.77, -1.24], %)
@ -2170,7 +2185,7 @@ myVar2 = 5
myVar3 = 6
myAng = 40
myAng2 = 134
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line([1, 3.82], %, $seg01) // ln-should-get-tag
|> angledLineToX([
@ -2194,7 +2209,7 @@ myVar2 = 5
myVar3 = 6
myAng = 40
myAng2 = 134
part001 = startSketchOn('XY')
part001 = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line([1, 3.82], %, $seg01) // ln-should-get-tag
|> angledLineToX([
@ -2221,7 +2236,7 @@ part001 = startSketchOn('XY')
#[test]
fn test_recast_after_rename_std() {
let some_program_string = r#"part001 = startSketchOn('XY')
let some_program_string = r#"part001 = startSketchOn(XY)
|> startProfileAt([0.0000000000, 5.0000000000], %)
|> line([0.4900857016, -0.0240763666], %)
@ -2241,7 +2256,7 @@ fn ghi = (part001) => {
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"mySuperCoolPart = startSketchOn('XY')
r#"mySuperCoolPart = startSketchOn(XY)
|> startProfileAt([0.0, 5.0], %)
|> line([0.4900857016, -0.0240763666], %)
@ -2278,7 +2293,7 @@ fn ghi(part001) {
#[test]
fn test_recast_trailing_comma() {
let some_program_string = r#"startSketchOn('XY')
let some_program_string = r#"startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> arc({
radius = 1,
@ -2290,7 +2305,7 @@ fn ghi(part001) {
let recasted = program.recast(&Default::default(), 0);
assert_eq!(
recasted,
r#"startSketchOn('XY')
r#"startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> arc({
radius = 1,
@ -2307,7 +2322,7 @@ fn ghi(part001) {
l = 8
h = 10
firstExtrude = startSketchOn('XY')
firstExtrude = startSketchOn(XY)
|> startProfileAt([0,0], %)
|> line([0, l], %)
|> line([w, 0], %)
@ -2324,7 +2339,7 @@ firstExtrude = startSketchOn('XY')
l = 8
h = 10
firstExtrude = startSketchOn('XY')
firstExtrude = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line([0, l], %)
|> line([w, 0], %)
@ -2344,7 +2359,7 @@ h = 10
// This is my comment
// It has multiple lines
// And it's really long
firstExtrude = startSketchOn('XY')
firstExtrude = startSketchOn(XY)
|> startProfileAt([0,0], %)
|> line([0, l], %)
|> line([w, 0], %)
@ -2364,7 +2379,7 @@ h = 10
// This is my comment
// It has multiple lines
// And it's really long
firstExtrude = startSketchOn('XY')
firstExtrude = startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line([0, l], %)
|> line([w, 0], %)
@ -2389,7 +2404,7 @@ firstExtrude = startSketchOn('XY')
let some_program_string = r#"wallMountL = 3.82
thickness = 0.5
startSketchOn('XY')
startSketchOn(XY)
|> startProfileAt([0, 0], %)
|> line([0, -(wallMountL - thickness)], %)
|> line([0, -(5 - thickness)], %)