Bump cargo to 1.88; 2024 edition for kcl-lib (#7618)
This is a big one because the edition changes a fair number of things.
This commit is contained in:
18
flake.lock
generated
18
flake.lock
generated
@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1745998881,
|
||||
"narHash": "sha256-vonyYAKJSlsX4n9GCsS0pHxR6yCrfqBIuGvANlkwG6U=",
|
||||
"lastModified": 1750865895,
|
||||
"narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "423d2df5b04b4ee7688c3d71396e872afa236a89",
|
||||
"rev": "61c0f513911459945e2cb8bf333dc849f1b976ff",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -36,11 +36,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1745998881,
|
||||
"narHash": "sha256-vonyYAKJSlsX4n9GCsS0pHxR6yCrfqBIuGvANlkwG6U=",
|
||||
"lastModified": 1750865895,
|
||||
"narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "423d2df5b04b4ee7688c3d71396e872afa236a89",
|
||||
"rev": "61c0f513911459945e2cb8bf333dc849f1b976ff",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -78,11 +78,11 @@
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1745980514,
|
||||
"narHash": "sha256-CITAeiuXGjDvT5iZBXr6vKVWQwsUQLJUMFO91bfJFC4=",
|
||||
"lastModified": 1750964660,
|
||||
"narHash": "sha256-YQ6EyFetjH1uy5JhdhRdPe6cuNXlYpMAQePFfZj4W7M=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "7fbdae44b0f40ea432e46fd152ad8be0f8f41ad6",
|
||||
"rev": "04f0fcfb1a50c63529805a798b4b5c21610ff390",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -42,7 +42,7 @@ impl Build {
|
||||
.to_string();
|
||||
|
||||
if !stable {
|
||||
version = format!("{}-nightly", version);
|
||||
version = format!("{version}-nightly");
|
||||
}
|
||||
|
||||
let release_tag = if stable {
|
||||
@ -59,10 +59,7 @@ impl Build {
|
||||
if stable && !release_tag.contains(&version) {
|
||||
// bail early if the tag doesn't match the version
|
||||
// TODO: error here when we use the tags with kcl
|
||||
println!(
|
||||
"Tag {} doesn't match version {}. Did you forget to update Cargo.toml?",
|
||||
release_tag, version
|
||||
);
|
||||
println!("Tag {release_tag} doesn't match version {version}. Did you forget to update Cargo.toml?");
|
||||
}
|
||||
|
||||
build_server(sh, &version, &target)?;
|
||||
|
@ -95,10 +95,10 @@ async fn main() -> Result<()> {
|
||||
// Format fields using the provided closure.
|
||||
// We want to make this very concise otherwise the logs are not able to be read by humans.
|
||||
let format = tracing_subscriber::fmt::format::debug_fn(|writer, field, value| {
|
||||
if format!("{}", field) == "message" {
|
||||
write!(writer, "{}: {:?}", field, value)
|
||||
if format!("{field}") == "message" {
|
||||
write!(writer, "{field}: {value:?}")
|
||||
} else {
|
||||
write!(writer, "{}", field)
|
||||
write!(writer, "{field}")
|
||||
}
|
||||
})
|
||||
// Separate each field with a comma.
|
||||
|
@ -87,10 +87,10 @@ async fn main() -> Result<()> {
|
||||
// Format fields using the provided closure.
|
||||
// We want to make this very concise otherwise the logs are not able to be read by humans.
|
||||
let format = tracing_subscriber::fmt::format::debug_fn(|writer, field, value| {
|
||||
if format!("{}", field) == "message" {
|
||||
write!(writer, "{}: {:?}", field, value)
|
||||
if format!("{field}") == "message" {
|
||||
write!(writer, "{field}: {value:?}")
|
||||
} else {
|
||||
write!(writer, "{}", field)
|
||||
write!(writer, "{field}")
|
||||
}
|
||||
})
|
||||
// Separate each field with a comma.
|
||||
@ -151,7 +151,7 @@ async fn run_cmd(opts: &Opts) -> Result<()> {
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Some(sig) = signals.forever().next() {
|
||||
log::info!("received signal: {:?}", sig);
|
||||
log::info!("received signal: {sig:?}");
|
||||
log::info!("triggering cleanup...");
|
||||
|
||||
// Exit the process.
|
||||
|
@ -2,10 +2,10 @@
|
||||
name = "kcl-lib"
|
||||
description = "KittyCAD Language implementation and tools"
|
||||
version = "0.2.83"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
rust-version = "1.83"
|
||||
rust-version = "1.88"
|
||||
authors = ["Jess Frazelle", "Adam Chalmers", "KittyCAD, Inc"]
|
||||
keywords = ["kcl", "KittyCAD", "CAD"]
|
||||
exclude = ["tests/*", "benches/*", "examples/*", "e2e/*", "bindings/*", "fuzz/*"]
|
||||
|
@ -4,7 +4,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
|
||||
const IGNORE_DIRS: [&str; 2] = ["step", "screenshots"];
|
||||
|
||||
@ -61,7 +61,7 @@ fn run_benchmarks(c: &mut Criterion) {
|
||||
|
||||
// Read the file content (panic on failure)
|
||||
let input_content = fs::read_to_string(&input_file)
|
||||
.unwrap_or_else(|e| panic!("Failed to read main.kcl in directory {}: {}", dir_name, e));
|
||||
.unwrap_or_else(|e| panic!("Failed to read main.kcl in directory {dir_name}: {e}"));
|
||||
|
||||
// Create a benchmark group for this directory
|
||||
let mut group = c.benchmark_group(&dir_name);
|
||||
@ -72,12 +72,12 @@ fn run_benchmarks(c: &mut Criterion) {
|
||||
#[cfg(feature = "benchmark-execution")]
|
||||
let program = kcl_lib::Program::parse_no_errs(&input_content).unwrap();
|
||||
|
||||
group.bench_function(format!("parse_{}", dir_name), |b| {
|
||||
group.bench_function(format!("parse_{dir_name}"), |b| {
|
||||
b.iter(|| kcl_lib::Program::parse_no_errs(black_box(&input_content)).unwrap())
|
||||
});
|
||||
|
||||
#[cfg(feature = "benchmark-execution")]
|
||||
group.bench_function(format!("execute_{}", dir_name), |b| {
|
||||
group.bench_function(format!("execute_{dir_name}"), |b| {
|
||||
b.iter(|| {
|
||||
if let Err(err) = rt.block_on(async {
|
||||
let ctx = kcl_lib::ExecutorContext::new_with_default_client().await?;
|
||||
@ -86,7 +86,7 @@ fn run_benchmarks(c: &mut Criterion) {
|
||||
ctx.close().await;
|
||||
Ok::<(), anyhow::Error>(())
|
||||
}) {
|
||||
panic!("Failed to execute program: {}", err);
|
||||
panic!("Failed to execute program: {err}");
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::hint::black_box;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
|
||||
pub fn bench_parse(c: &mut Criterion) {
|
||||
for (name, file) in [
|
||||
|
@ -1,4 +1,4 @@
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
|
||||
pub fn bench_digest(c: &mut Criterion) {
|
||||
for (name, file) in [
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::hint::black_box;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
|
||||
use kcl_lib::kcl_lsp_server;
|
||||
use tokio::runtime::Runtime;
|
||||
use tower_lsp::LanguageServer;
|
||||
|
@ -1,9 +1,9 @@
|
||||
//! Cache testing framework.
|
||||
|
||||
use kcl_lib::{bust_cache, ExecError, ExecOutcome};
|
||||
use kcl_lib::{ExecError, ExecOutcome, bust_cache};
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
use kcl_lib::{exec::Operation, NodePathStep};
|
||||
use kcmc::{each_cmd as mcmd, ModelingCmd};
|
||||
use kcl_lib::{NodePathStep, exec::Operation};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
@ -38,7 +38,7 @@ async fn cache_test(
|
||||
if !variation.other_files.is_empty() {
|
||||
let tmp_dir = std::env::temp_dir();
|
||||
let tmp_dir = tmp_dir
|
||||
.join(format!("kcl_test_{}", test_name))
|
||||
.join(format!("kcl_test_{test_name}"))
|
||||
.join(uuid::Uuid::new_v4().to_string());
|
||||
|
||||
// Create a temporary file for each of the other files.
|
||||
@ -56,7 +56,7 @@ async fn cache_test(
|
||||
Err(error) => {
|
||||
let report = error.clone().into_miette_report_with_outputs(variation.code).unwrap();
|
||||
let report = miette::Report::new(report);
|
||||
panic!("{:?}", report);
|
||||
panic!("{report:?}");
|
||||
}
|
||||
};
|
||||
|
||||
@ -69,7 +69,7 @@ async fn cache_test(
|
||||
.and_then(|x| x.decode().map_err(|e| ExecError::BadPng(e.to_string())))
|
||||
.unwrap();
|
||||
// Save the snapshot.
|
||||
let path = crate::assert_out(&format!("cache_{}_{}", test_name, index), &img);
|
||||
let path = crate::assert_out(&format!("cache_{test_name}_{index}"), &img);
|
||||
|
||||
img_results.push((path, img, outcome));
|
||||
}
|
||||
@ -337,8 +337,7 @@ extrude001 = extrude(profile001, length = 4)
|
||||
// 0] as a more lenient check.
|
||||
.map(|c| !c.range.is_synthetic() && c.node_path.is_empty())
|
||||
.unwrap_or(false),
|
||||
"artifact={:?}",
|
||||
artifact
|
||||
"artifact={artifact:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
mod cache;
|
||||
|
||||
use kcl_lib::{
|
||||
test_server::{execute_and_export_step, execute_and_snapshot, execute_and_snapshot_no_auth},
|
||||
BacktraceItem, ExecError, ModuleId, SourceRange,
|
||||
test_server::{execute_and_export_step, execute_and_snapshot, execute_and_snapshot_no_auth},
|
||||
};
|
||||
|
||||
/// The minimum permissible difference between asserted twenty-twenty images.
|
||||
@ -869,11 +869,13 @@ async fn kcl_test_revolve_bad_angle_low() {
|
||||
let result = execute_and_snapshot(code, None).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert!(result
|
||||
.err()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.contains("Expected angle to be between -360 and 360 and not 0, found `-455`"));
|
||||
assert!(
|
||||
result
|
||||
.err()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.contains("Expected angle to be between -360 and 360 and not 0, found `-455`")
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
@ -895,11 +897,13 @@ async fn kcl_test_revolve_bad_angle_high() {
|
||||
let result = execute_and_snapshot(code, None).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert!(result
|
||||
.err()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.contains("Expected angle to be between -360 and 360 and not 0, found `455`"));
|
||||
assert!(
|
||||
result
|
||||
.err()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.contains("Expected angle to be between -360 and 360 and not 0, found `455`")
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
@ -2090,7 +2094,10 @@ async fn kcl_test_better_type_names() {
|
||||
},
|
||||
None => todo!(),
|
||||
};
|
||||
assert_eq!(err, "This function expected the input argument to be one or more Solids or ImportedGeometry but it's actually of type Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`");
|
||||
assert_eq!(
|
||||
err,
|
||||
"This function expected the input argument to be one or more Solids or ImportedGeometry but it's actually of type Sketch. You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
|
@ -101,7 +101,7 @@ pub trait CoreDump: Clone {
|
||||
.meta()
|
||||
.create_debug_uploads(vec![kittycad::types::multipart::Attachment {
|
||||
name: "".to_string(),
|
||||
filepath: Some(format!(r#"modeling-app/coredump-{}.json"#, coredump_id).into()),
|
||||
filepath: Some(format!(r#"modeling-app/coredump-{coredump_id}.json"#).into()),
|
||||
content_type: Some("application/json".to_string()),
|
||||
data,
|
||||
}])
|
||||
|
@ -189,7 +189,7 @@ fn generate_example(index: usize, src: &str, props: &ExampleProperties, file_nam
|
||||
index
|
||||
);
|
||||
let image_data =
|
||||
std::fs::read(&image_path).unwrap_or_else(|_| panic!("Failed to read image file: {}", image_path));
|
||||
std::fs::read(&image_path).unwrap_or_else(|_| panic!("Failed to read image file: {image_path}"));
|
||||
base64::engine::general_purpose::STANDARD.encode(&image_data)
|
||||
};
|
||||
|
||||
@ -225,7 +225,7 @@ fn generate_type_from_kcl(ty: &TyData, file_name: String, example_name: String,
|
||||
|
||||
let output = hbs.render("kclType", &data)?;
|
||||
let output = cleanup_types(&output, kcl_std);
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{}.md", file_name), &output);
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{file_name}.md"), &output);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -267,7 +267,7 @@ fn generate_mod_from_kcl(m: &ModData, file_name: String) -> Result<()> {
|
||||
});
|
||||
|
||||
let output = hbs.render("module", &data)?;
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{}.md", file_name), &output);
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{file_name}.md"), &output);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -334,7 +334,7 @@ fn generate_function_from_kcl(
|
||||
|
||||
let output = hbs.render("function", &data)?;
|
||||
let output = &cleanup_types(&output, kcl_std);
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{}.md", file_name), output);
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{file_name}.md"), output);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -378,7 +378,7 @@ fn generate_const_from_kcl(cnst: &ConstData, file_name: String, example_name: St
|
||||
|
||||
let output = hbs.render("const", &data)?;
|
||||
let output = cleanup_types(&output, kcl_std);
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{}.md", file_name), &output);
|
||||
expectorate::assert_contents(format!("../../docs/kcl-std/{file_name}.md"), &output);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use tower_lsp::lsp_types::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ModuleId,
|
||||
execution::annotations,
|
||||
parsing::{
|
||||
ast::types::{
|
||||
@ -15,7 +16,6 @@ use crate::{
|
||||
},
|
||||
token::NumericSuffix,
|
||||
},
|
||||
ModuleId,
|
||||
};
|
||||
|
||||
pub fn walk_prelude() -> ModData {
|
||||
@ -97,7 +97,7 @@ fn visit_module(name: &str, preferred_prefix: &str, names: WalkForNames) -> Resu
|
||||
ImportSelector::None { .. } => {
|
||||
let name = import.module_name().unwrap();
|
||||
if names.contains(&name) {
|
||||
Some(visit_module(&path[1], &format!("{}::", name), WalkForNames::All)?)
|
||||
Some(visit_module(&path[1], &format!("{name}::"), WalkForNames::All)?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -451,7 +451,7 @@ impl ModData {
|
||||
let (name, qual_name, module_name) = if name == "prelude" {
|
||||
("std", "std".to_owned(), String::new())
|
||||
} else {
|
||||
(name, format!("std::{}", name), "std".to_owned())
|
||||
(name, format!("std::{name}"), "std".to_owned())
|
||||
};
|
||||
Self {
|
||||
preferred_name: format!("{preferred_prefix}{name}"),
|
||||
@ -767,14 +767,12 @@ impl ArgData {
|
||||
for s in &arr.elements {
|
||||
let Expr::Literal(lit) = s else {
|
||||
panic!(
|
||||
"Invalid value in `snippetArray`, all items must be string literals but found {:?}",
|
||||
s
|
||||
"Invalid value in `snippetArray`, all items must be string literals but found {s:?}"
|
||||
);
|
||||
};
|
||||
let LiteralValue::String(litstr) = &lit.inner.value else {
|
||||
panic!(
|
||||
"Invalid value in `snippetArray`, all items must be string literals but found {:?}",
|
||||
s
|
||||
"Invalid value in `snippetArray`, all items must be string literals but found {s:?}"
|
||||
);
|
||||
};
|
||||
items.push(litstr.to_owned());
|
||||
@ -816,7 +814,7 @@ impl ArgData {
|
||||
}
|
||||
match self.ty.as_deref() {
|
||||
Some("Sketch") if self.kind == ArgKind::Special => None,
|
||||
Some(s) if s.starts_with("number") => Some((index, format!(r#"{label}${{{}:10}}"#, index))),
|
||||
Some(s) if s.starts_with("number") => Some((index, format!(r#"{label}${{{index}:10}}"#))),
|
||||
Some("Point2d") => Some((index + 1, format!(r#"{label}[${{{}:0}}, ${{{}:0}}]"#, index, index + 1))),
|
||||
Some("Point3d") => Some((
|
||||
index + 2,
|
||||
@ -831,7 +829,7 @@ impl ArgData {
|
||||
Some("Sketch") | Some("Sketch | Helix") => Some((index, format!(r#"{label}${{{index}:sketch000}}"#))),
|
||||
Some("Edge") => Some((index, format!(r#"{label}${{{index}:tag_or_edge_fn}}"#))),
|
||||
Some("[Edge; 1+]") => Some((index, format!(r#"{label}[${{{index}:tag_or_edge_fn}}]"#))),
|
||||
Some("Plane") | Some("Solid | Plane") => Some((index, format!(r#"{label}${{{}:XY}}"#, index))),
|
||||
Some("Plane") | Some("Solid | Plane") => Some((index, format!(r#"{label}${{{index}:XY}}"#))),
|
||||
Some("[TaggedFace; 2]") => Some((
|
||||
index + 1,
|
||||
format!(r#"{label}[${{{}:tag}}, ${{{}:tag}}]"#, index, index + 1),
|
||||
@ -841,10 +839,10 @@ impl ArgData {
|
||||
if self.name == "color" {
|
||||
Some((index, format!(r"{label}${{{}:{}}}", index, "\"#ff0000\"")))
|
||||
} else {
|
||||
Some((index, format!(r#"{label}${{{}:"string"}}"#, index)))
|
||||
Some((index, format!(r#"{label}${{{index}:"string"}}"#)))
|
||||
}
|
||||
}
|
||||
Some("bool") => Some((index, format!(r#"{label}${{{}:false}}"#, index))),
|
||||
Some("bool") => Some((index, format!(r#"{label}${{{index}:false}}"#))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -1298,7 +1296,10 @@ mod test {
|
||||
continue;
|
||||
}
|
||||
let name = format!("{}-{i}", f.qual_name.replace("::", "-"));
|
||||
assert!(TEST_NAMES.contains(&&*name), "Missing test for example \"{name}\", maybe need to update kcl-derive-docs/src/example_tests.rs?")
|
||||
assert!(
|
||||
TEST_NAMES.contains(&&*name),
|
||||
"Missing test for example \"{name}\", maybe need to update kcl-derive-docs/src/example_tests.rs?"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1334,7 +1335,9 @@ mod test {
|
||||
};
|
||||
|
||||
let Some(DocData::Fn(d)) = data.children.get(&format!("I:{qualname}")) else {
|
||||
panic!("Could not find data for {NAME} (missing a child entry for {qualname}), maybe need to update kcl-derive-docs/src/example_tests.rs?");
|
||||
panic!(
|
||||
"Could not find data for {NAME} (missing a child entry for {qualname}), maybe need to update kcl-derive-docs/src/example_tests.rs?"
|
||||
);
|
||||
};
|
||||
|
||||
for (i, eg) in d.examples.iter().enumerate() {
|
||||
@ -1362,6 +1365,8 @@ mod test {
|
||||
return;
|
||||
}
|
||||
|
||||
panic!("Could not find data for {NAME} (no example {number}), maybe need to update kcl-derive-docs/src/example_tests.rs?");
|
||||
panic!(
|
||||
"Could not find data for {NAME} (no example {number}), maybe need to update kcl-derive-docs/src/example_tests.rs?"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
//! tasks.
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
use tokio::sync::{mpsc, Notify};
|
||||
use tokio::sync::{Notify, mpsc};
|
||||
|
||||
use crate::errors::KclError;
|
||||
|
||||
|
@ -3,26 +3,26 @@
|
||||
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::{Result, anyhow};
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use indexmap::IndexMap;
|
||||
use kcmc::{
|
||||
ModelingCmd,
|
||||
websocket::{
|
||||
BatchResponse, FailureWebSocketResponse, ModelingCmdReq, ModelingSessionData, OkWebSocketResponseData,
|
||||
SuccessWebSocketResponse, WebSocketRequest, WebSocketResponse,
|
||||
},
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds::{self as kcmc};
|
||||
use tokio::sync::{mpsc, oneshot, RwLock};
|
||||
use tokio::sync::{RwLock, mpsc, oneshot};
|
||||
use tokio_tungstenite::tungstenite::Message as WsMsg;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
engine::{AsyncTasks, EngineManager, EngineStats},
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{DefaultPlanes, IdGenerator},
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -85,7 +85,7 @@ impl TcpRead {
|
||||
let msg = match msg {
|
||||
Ok(msg) => msg,
|
||||
Err(e) if matches!(e, tokio_tungstenite::tungstenite::Error::Protocol(_)) => {
|
||||
return Err(WebSocketReadError::Read(e))
|
||||
return Err(WebSocketReadError::Read(e));
|
||||
}
|
||||
Err(e) => return Err(anyhow::anyhow!("Error reading from engine's WebSocket: {e}").into()),
|
||||
};
|
||||
@ -427,7 +427,7 @@ impl EngineManager for EngineConnection {
|
||||
request_sent: tx,
|
||||
})
|
||||
.await
|
||||
.map_err(|e| KclError::new_engine(KclErrorDetails::new(format!("Failed to send debug: {}", e), vec![])))?;
|
||||
.map_err(|e| KclError::new_engine(KclErrorDetails::new(format!("Failed to send debug: {e}"), vec![])))?;
|
||||
|
||||
let _ = rx.await;
|
||||
Ok(())
|
||||
@ -463,7 +463,7 @@ impl EngineManager for EngineConnection {
|
||||
.await
|
||||
.map_err(|e| {
|
||||
KclError::new_engine(KclErrorDetails::new(
|
||||
format!("Failed to send modeling command: {}", e),
|
||||
format!("Failed to send modeling command: {e}"),
|
||||
vec![source_range],
|
||||
))
|
||||
})?;
|
||||
@ -533,7 +533,7 @@ impl EngineManager for EngineConnection {
|
||||
}
|
||||
|
||||
Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("Modeling command timed out `{}`", id),
|
||||
format!("Modeling command timed out `{id}`"),
|
||||
vec![source_range],
|
||||
)))
|
||||
}
|
||||
|
@ -12,16 +12,16 @@ use kcmc::{
|
||||
WebSocketResponse,
|
||||
},
|
||||
};
|
||||
use kittycad_modeling_cmds::{self as kcmc, websocket::ModelingCmdReq, ImportFiles, ModelingCmd};
|
||||
use kittycad_modeling_cmds::{self as kcmc, ImportFiles, ModelingCmd, websocket::ModelingCmdReq};
|
||||
use tokio::sync::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
engine::{AsyncTasks, EngineStats},
|
||||
errors::KclError,
|
||||
exec::DefaultPlanes,
|
||||
execution::IdGenerator,
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -11,10 +11,10 @@ use uuid::Uuid;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
engine::{AsyncTasks, EngineStats},
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{DefaultPlanes, IdGenerator},
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
#[wasm_bindgen(module = "/../../src/lang/std/engineConnection.ts")]
|
||||
|
@ -12,15 +12,15 @@ pub mod conn_wasm;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
},
|
||||
};
|
||||
|
||||
pub use async_tasks::AsyncTasks;
|
||||
use indexmap::IndexMap;
|
||||
use kcmc::{
|
||||
each_cmd as mcmd,
|
||||
ModelingCmd, each_cmd as mcmd,
|
||||
length_unit::LengthUnit,
|
||||
ok_response::OkModelingCmdResponse,
|
||||
shared::Color,
|
||||
@ -28,7 +28,6 @@ use kcmc::{
|
||||
BatchResponse, ModelingBatch, ModelingCmdReq, ModelingSessionData, OkWebSocketResponseData, WebSocketRequest,
|
||||
WebSocketResponse,
|
||||
},
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use parse_display::{Display, FromStr};
|
||||
@ -39,9 +38,9 @@ use uuid::Uuid;
|
||||
use web_time::Instant;
|
||||
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{types::UnitLen, DefaultPlanes, IdGenerator, PlaneInfo, Point3d},
|
||||
SourceRange,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{DefaultPlanes, IdGenerator, PlaneInfo, Point3d, types::UnitLen},
|
||||
};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
@ -291,7 +290,10 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
// the artifact graph won't care either if its gone since you can't select it
|
||||
// anymore anyways.
|
||||
if let Err(err) = self.async_tasks().join_all().await {
|
||||
crate::log::logln!("Error waiting for async tasks (this is typically fine and just means that an edge became something else): {:?}", err);
|
||||
crate::log::logln!(
|
||||
"Error waiting for async tasks (this is typically fine and just means that an edge became something else): {:?}",
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
// Flush the batch to make sure nothing remains.
|
||||
@ -499,7 +501,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
}
|
||||
_ => {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("The request is not a modeling command: {:?}", req),
|
||||
format!("The request is not a modeling command: {req:?}"),
|
||||
vec![*range],
|
||||
)));
|
||||
}
|
||||
@ -529,7 +531,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
} else {
|
||||
// We should never get here.
|
||||
Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("Failed to get batch response: {:?}", response),
|
||||
format!("Failed to get batch response: {response:?}"),
|
||||
vec![source_range],
|
||||
)))
|
||||
}
|
||||
@ -544,7 +546,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
// an error.
|
||||
let source_range = id_to_source_range.get(cmd_id.as_ref()).cloned().ok_or_else(|| {
|
||||
KclError::new_engine(KclErrorDetails::new(
|
||||
format!("Failed to get source range for command ID: {:?}", cmd_id),
|
||||
format!("Failed to get source range for command ID: {cmd_id:?}"),
|
||||
vec![],
|
||||
))
|
||||
})?;
|
||||
@ -554,7 +556,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
self.parse_websocket_response(ws_resp, source_range)
|
||||
}
|
||||
_ => Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("The final request is not a modeling command: {:?}", final_req),
|
||||
format!("The final request is not a modeling command: {final_req:?}"),
|
||||
vec![source_range],
|
||||
))),
|
||||
}
|
||||
@ -663,7 +665,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
let info = DEFAULT_PLANE_INFO.get(&name).ok_or_else(|| {
|
||||
// We should never get here.
|
||||
KclError::new_engine(KclErrorDetails::new(
|
||||
format!("Failed to get default plane info for: {:?}", name),
|
||||
format!("Failed to get default plane info for: {name:?}"),
|
||||
vec![source_range],
|
||||
))
|
||||
})?;
|
||||
@ -739,7 +741,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
// Get the source range for the command.
|
||||
let source_range = id_to_source_range.get(cmd_id).cloned().ok_or_else(|| {
|
||||
KclError::new_engine(KclErrorDetails::new(
|
||||
format!("Failed to get source range for command ID: {:?}", cmd_id),
|
||||
format!("Failed to get source range for command ID: {cmd_id:?}"),
|
||||
vec![],
|
||||
))
|
||||
})?;
|
||||
@ -754,7 +756,7 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
||||
// Return an error that we did not get an error or the response we wanted.
|
||||
// This should never happen but who knows.
|
||||
Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("Failed to find response for command ID: {:?}", id),
|
||||
format!("Failed to find response for command ID: {id:?}"),
|
||||
vec![],
|
||||
)))
|
||||
}
|
||||
|
@ -7,11 +7,11 @@ use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
use crate::execution::{ArtifactCommand, ArtifactGraph, Operation};
|
||||
use crate::{
|
||||
ModuleId,
|
||||
execution::DefaultPlanes,
|
||||
lsp::IntoDiagnostic,
|
||||
modules::{ModulePath, ModuleSource},
|
||||
source_range::SourceRange,
|
||||
ModuleId,
|
||||
};
|
||||
|
||||
/// How did the KCL execution fail
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use kittycad_modeling_cmds::coord::{System, KITTYCAD, OPENGL, VULKAN};
|
||||
use kittycad_modeling_cmds::coord::{KITTYCAD, OPENGL, System, VULKAN};
|
||||
|
||||
use crate::{
|
||||
KclError, SourceRange,
|
||||
errors::KclErrorDetails,
|
||||
execution::types::{UnitAngle, UnitLen},
|
||||
parsing::ast::types::{Annotation, Expr, LiteralValue, Node, ObjectProperty},
|
||||
KclError, SourceRange,
|
||||
};
|
||||
|
||||
/// Annotations which should cause re-execution if they change.
|
||||
|
@ -1,20 +1,19 @@
|
||||
use fnv::FnvHashMap;
|
||||
use indexmap::IndexMap;
|
||||
use kittycad_modeling_cmds::{
|
||||
self as kcmc,
|
||||
self as kcmc, EnableSketchMode, ModelingCmd,
|
||||
ok_response::OkModelingCmdResponse,
|
||||
shared::ExtrusionFaceCapType,
|
||||
websocket::{BatchResponse, OkWebSocketResponseData, WebSocketResponse},
|
||||
EnableSketchMode, ModelingCmd,
|
||||
};
|
||||
use serde::{ser::SerializeSeq, Serialize};
|
||||
use serde::{Serialize, ser::SerializeSeq};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
KclError, NodePath, SourceRange,
|
||||
errors::KclErrorDetails,
|
||||
execution::ArtifactId,
|
||||
parsing::ast::types::{Node, Program},
|
||||
KclError, NodePath, SourceRange,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
@ -893,7 +892,10 @@ fn artifacts_to_update(
|
||||
),
|
||||
};
|
||||
if original_path_ids.len() != face_edge_infos.len() {
|
||||
internal_error!(range, "EntityMirror or EntityMirrorAcrossEdge response has different number face edge info than original mirrored paths: id={id:?}, cmd={cmd:?}, response={response:?}");
|
||||
internal_error!(
|
||||
range,
|
||||
"EntityMirror or EntityMirrorAcrossEdge response has different number face edge info than original mirrored paths: id={id:?}, cmd={cmd:?}, response={response:?}"
|
||||
);
|
||||
}
|
||||
let mut return_arr = Vec::new();
|
||||
for (face_edge_info, original_path_id) in face_edge_infos.iter().zip(original_path_ids) {
|
||||
@ -909,7 +911,10 @@ fn artifacts_to_update(
|
||||
// of its info.
|
||||
let Some(Artifact::Path(original_path)) = artifacts.get(&original_path_id) else {
|
||||
// We couldn't find the original path. This is a bug.
|
||||
internal_error!(range, "Couldn't find original path for mirror2d: original_path_id={original_path_id:?}, cmd={cmd:?}");
|
||||
internal_error!(
|
||||
range,
|
||||
"Couldn't find original path for mirror2d: original_path_id={original_path_id:?}, cmd={cmd:?}"
|
||||
);
|
||||
};
|
||||
Path {
|
||||
id: path_id,
|
||||
|
@ -268,7 +268,7 @@ impl ArtifactGraph {
|
||||
for (group_id, artifact_ids) in groups {
|
||||
let group_id = *stable_id_map.get(&group_id).unwrap();
|
||||
writeln!(output, "{prefix}subgraph path{group_id} [Path]")?;
|
||||
let indented = format!("{} ", prefix);
|
||||
let indented = format!("{prefix} ");
|
||||
for artifact_id in artifact_ids {
|
||||
let artifact = self.map.get(&artifact_id).unwrap();
|
||||
let id = *stable_id_map.get(&artifact_id).unwrap();
|
||||
@ -353,7 +353,7 @@ impl ArtifactGraph {
|
||||
node_path_display(output, prefix, None, &segment.code_ref)?;
|
||||
}
|
||||
Artifact::Solid2d(_solid2d) => {
|
||||
writeln!(output, "{prefix}{}[Solid2d]", id)?;
|
||||
writeln!(output, "{prefix}{id}[Solid2d]")?;
|
||||
}
|
||||
Artifact::StartSketchOnFace(StartSketchOnFace { code_ref, .. }) => {
|
||||
writeln!(
|
||||
@ -494,24 +494,24 @@ impl ArtifactGraph {
|
||||
match edge.flow {
|
||||
EdgeFlow::SourceToTarget => match edge.direction {
|
||||
EdgeDirection::Forward => {
|
||||
writeln!(output, "{prefix}{source_id} x{}--> {}", extra, target_id)?;
|
||||
writeln!(output, "{prefix}{source_id} x{extra}--> {target_id}")?;
|
||||
}
|
||||
EdgeDirection::Backward => {
|
||||
writeln!(output, "{prefix}{source_id} <{}--x {}", extra, target_id)?;
|
||||
writeln!(output, "{prefix}{source_id} <{extra}--x {target_id}")?;
|
||||
}
|
||||
EdgeDirection::Bidirectional => {
|
||||
writeln!(output, "{prefix}{source_id} {}--- {}", extra, target_id)?;
|
||||
writeln!(output, "{prefix}{source_id} {extra}--- {target_id}")?;
|
||||
}
|
||||
},
|
||||
EdgeFlow::TargetToSource => match edge.direction {
|
||||
EdgeDirection::Forward => {
|
||||
writeln!(output, "{prefix}{target_id} x{}--> {}", extra, source_id)?;
|
||||
writeln!(output, "{prefix}{target_id} x{extra}--> {source_id}")?;
|
||||
}
|
||||
EdgeDirection::Backward => {
|
||||
writeln!(output, "{prefix}{target_id} <{}--x {}", extra, source_id)?;
|
||||
writeln!(output, "{prefix}{target_id} <{extra}--x {source_id}")?;
|
||||
}
|
||||
EdgeDirection::Bidirectional => {
|
||||
writeln!(output, "{prefix}{target_id} {}--- {}", extra, source_id)?;
|
||||
writeln!(output, "{prefix}{target_id} {extra}--- {source_id}")?;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -6,15 +6,14 @@ use itertools::{EitherOrBoth, Itertools};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use crate::{
|
||||
ExecOutcome, ExecutorContext,
|
||||
execution::{
|
||||
annotations,
|
||||
EnvironmentRef, ExecutorSettings, annotations,
|
||||
memory::Stack,
|
||||
state::{self as exec_state, ModuleInfoMap},
|
||||
EnvironmentRef, ExecutorSettings,
|
||||
},
|
||||
parsing::ast::types::{Annotation, Node, Program},
|
||||
walk::Node as WalkNode,
|
||||
ExecOutcome, ExecutorContext,
|
||||
};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
@ -337,7 +336,7 @@ mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
use crate::execution::{parse_execute, parse_execute_with_project_dir, ExecTestResults};
|
||||
use crate::execution::{ExecTestResults, parse_execute, parse_execute_with_project_dir};
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_get_changed_program_same_code() {
|
||||
@ -755,7 +754,7 @@ extrude(profile001, length = 100)"#
|
||||
.await;
|
||||
|
||||
let CacheResult::CheckImportsOnly { reapply_settings, .. } = result else {
|
||||
panic!("Expected CheckImportsOnly, got {:?}", result);
|
||||
panic!("Expected CheckImportsOnly, got {result:?}");
|
||||
};
|
||||
|
||||
assert_eq!(reapply_settings, false);
|
||||
@ -839,7 +838,7 @@ extrude(profile001, length = 100)
|
||||
.await;
|
||||
|
||||
let CacheResult::CheckImportsOnly { reapply_settings, .. } = result else {
|
||||
panic!("Expected CheckImportsOnly, got {:?}", result);
|
||||
panic!("Expected CheckImportsOnly, got {result:?}");
|
||||
};
|
||||
|
||||
assert_eq!(reapply_settings, false);
|
||||
|
@ -1,10 +1,10 @@
|
||||
use indexmap::IndexMap;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{types::NumericType, ArtifactId, KclValue};
|
||||
use super::{ArtifactId, KclValue, types::NumericType};
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
use crate::parsing::ast::types::{Node, Program};
|
||||
use crate::{parsing::ast::types::ItemVisibility, ModuleId, NodePath, SourceRange};
|
||||
use crate::{ModuleId, NodePath, SourceRange, parsing::ast::types::ItemVisibility};
|
||||
|
||||
/// A CAD modeling operation for display in the feature tree, AKA operations
|
||||
/// timeline.
|
||||
@ -57,7 +57,7 @@ impl Operation {
|
||||
/// If the variant is `StdLibCall`, set the `is_error` field.
|
||||
pub(crate) fn set_std_lib_call_is_error(&mut self, is_err: bool) {
|
||||
match self {
|
||||
Self::StdLibCall { ref mut is_error, .. } => *is_error = is_err,
|
||||
Self::StdLibCall { is_error, .. } => *is_error = is_err,
|
||||
Self::VariableDeclaration { .. } | Self::GroupBegin { .. } | Self::GroupEnd => {}
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,17 @@ use std::collections::HashMap;
|
||||
use async_recursion::async_recursion;
|
||||
|
||||
use crate::{
|
||||
CompilationError, NodePath,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
annotations,
|
||||
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, ModelingCmdMeta, ModuleArtifactState,
|
||||
Operation, PlaneType, StatementKind, TagIdentifier, annotations,
|
||||
cad_op::OpKclValue,
|
||||
fn_call::Args,
|
||||
kcl_value::{FunctionSource, TypeDef},
|
||||
memory,
|
||||
state::ModuleState,
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, ModelingCmdMeta, ModuleArtifactState,
|
||||
Operation, PlaneType, StatementKind, TagIdentifier,
|
||||
},
|
||||
fmt,
|
||||
modules::{ModuleId, ModulePath, ModuleRepr},
|
||||
@ -28,7 +28,6 @@ use crate::{
|
||||
},
|
||||
source_range::SourceRange,
|
||||
std::args::TyF64,
|
||||
CompilationError, NodePath,
|
||||
};
|
||||
|
||||
impl<'a> StatementKind<'a> {
|
||||
@ -198,19 +197,23 @@ impl ExecutorContext {
|
||||
}
|
||||
|
||||
if ty.is_ok() && !module_exports.contains(&ty_name) {
|
||||
ty = Err(KclError::new_semantic(KclErrorDetails::new(format!(
|
||||
"Cannot import \"{}\" from module because it is not exported. Add \"export\" before the definition to export it.",
|
||||
import_item.name.name
|
||||
),
|
||||
vec![SourceRange::from(&import_item.name)],)));
|
||||
ty = Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!(
|
||||
"Cannot import \"{}\" from module because it is not exported. Add \"export\" before the definition to export it.",
|
||||
import_item.name.name
|
||||
),
|
||||
vec![SourceRange::from(&import_item.name)],
|
||||
)));
|
||||
}
|
||||
|
||||
if mod_value.is_ok() && !module_exports.contains(&mod_name) {
|
||||
mod_value = Err(KclError::new_semantic(KclErrorDetails::new(format!(
|
||||
"Cannot import \"{}\" from module because it is not exported. Add \"export\" before the definition to export it.",
|
||||
import_item.name.name
|
||||
),
|
||||
vec![SourceRange::from(&import_item.name)],)));
|
||||
mod_value = Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!(
|
||||
"Cannot import \"{}\" from module because it is not exported. Add \"export\" before the definition to export it.",
|
||||
import_item.name.name
|
||||
),
|
||||
vec![SourceRange::from(&import_item.name)],
|
||||
)));
|
||||
}
|
||||
|
||||
if value.is_err() && ty.is_err() && mod_value.is_err() {
|
||||
@ -270,7 +273,7 @@ impl ExecutorContext {
|
||||
.get_from(name, env_ref, source_range, 0)
|
||||
.map_err(|_err| {
|
||||
KclError::new_internal(KclErrorDetails::new(
|
||||
format!("{} is not defined in module (but was exported?)", name),
|
||||
format!("{name} is not defined in module (but was exported?)"),
|
||||
vec![source_range],
|
||||
))
|
||||
})?
|
||||
@ -431,7 +434,7 @@ impl ExecutorContext {
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
"User-defined types are not yet supported.".to_owned(),
|
||||
vec![metadata.source_range],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -792,11 +795,12 @@ fn var_in_own_ref_err(e: KclError, being_declared: &Option<String>) -> KclError
|
||||
// TODO after June 26th: replace this with a let-chain,
|
||||
// which will be available in Rust 1.88
|
||||
// https://rust-lang.github.io/rfcs/2497-if-let-chains.html
|
||||
match (&being_declared, &name) {
|
||||
(Some(name0), Some(name1)) if name0 == name1 => {
|
||||
details.message = format!("You can't use `{name0}` because you're currently trying to define it. Use a different variable here instead.");
|
||||
}
|
||||
_ => {}
|
||||
if let (Some(name0), Some(name1)) = (&being_declared, &name)
|
||||
&& name0 == name1
|
||||
{
|
||||
details.message = format!(
|
||||
"You can't use `{name0}` because you're currently trying to define it. Use a different variable here instead."
|
||||
);
|
||||
}
|
||||
KclError::UndefinedValue { details, name }
|
||||
}
|
||||
@ -1077,7 +1081,7 @@ impl Node<BinaryExpression> {
|
||||
(&left_value, &right_value)
|
||||
{
|
||||
return Ok(KclValue::String {
|
||||
value: format!("{}{}", left, right),
|
||||
value: format!("{left}{right}"),
|
||||
meta,
|
||||
});
|
||||
}
|
||||
@ -1237,7 +1241,9 @@ impl Node<BinaryExpression> {
|
||||
exec_state.clear_units_warnings(&sr);
|
||||
let mut err = CompilationError::err(
|
||||
sr,
|
||||
format!("{} numbers which have unknown or incompatible units.\nYou can probably fix this error by specifying the units using type ascription, e.g., `len: number(mm)` or `(a * b): number(deg)`.", verb),
|
||||
format!(
|
||||
"{verb} numbers which have unknown or incompatible units.\nYou can probably fix this error by specifying the units using type ascription, e.g., `len: number(mm)` or `(a * b): number(deg)`."
|
||||
),
|
||||
);
|
||||
err.tag = crate::errors::Tag::UnknownNumericUnits;
|
||||
exec_state.warn(err);
|
||||
@ -1417,7 +1423,7 @@ async fn inner_execute_pipe_body(
|
||||
for expression in body {
|
||||
if let Expr::TagDeclarator(_) = expression {
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!("This cannot be in a PipeExpression: {:?}", expression),
|
||||
format!("This cannot be in a PipeExpression: {expression:?}"),
|
||||
vec![expression.into()],
|
||||
)));
|
||||
}
|
||||
@ -1699,9 +1705,15 @@ fn jvalue_to_prop(value: &KclValue, property_sr: Vec<SourceRange>, name: &str) -
|
||||
let make_err =
|
||||
|message: String| Err::<Property, _>(KclError::new_semantic(KclErrorDetails::new(message, property_sr)));
|
||||
match value {
|
||||
n @ KclValue::Number{value: num, ty, .. } => {
|
||||
if !matches!(ty, NumericType::Known(crate::exec::UnitType::Count) | NumericType::Default { .. } | NumericType::Any ) {
|
||||
return make_err(format!("arrays can only be indexed by non-dimensioned numbers, found {}", n.human_friendly_type()));
|
||||
n @ KclValue::Number { value: num, ty, .. } => {
|
||||
if !matches!(
|
||||
ty,
|
||||
NumericType::Known(crate::exec::UnitType::Count) | NumericType::Default { .. } | NumericType::Any
|
||||
) {
|
||||
return make_err(format!(
|
||||
"arrays can only be indexed by non-dimensioned numbers, found {}",
|
||||
n.human_friendly_type()
|
||||
));
|
||||
}
|
||||
let num = *num;
|
||||
if num < 0.0 {
|
||||
@ -1711,13 +1723,15 @@ fn jvalue_to_prop(value: &KclValue, property_sr: Vec<SourceRange>, name: &str) -
|
||||
if let Some(nearest_int) = nearest_int {
|
||||
Ok(Property::UInt(nearest_int))
|
||||
} else {
|
||||
make_err(format!("'{num}' is not an integer, so you can't index an array with it"))
|
||||
make_err(format!(
|
||||
"'{num}' is not an integer, so you can't index an array with it"
|
||||
))
|
||||
}
|
||||
}
|
||||
KclValue::String{value: x, meta:_} => Ok(Property::String(x.to_owned())),
|
||||
_ => {
|
||||
make_err(format!("{name} is not a valid property/index, you can only use a string to get the property of an object, or an int (>= 0) to get an item in an array"))
|
||||
}
|
||||
KclValue::String { value: x, meta: _ } => Ok(Property::String(x.to_owned())),
|
||||
_ => make_err(format!(
|
||||
"{name} is not a valid property/index, you can only use a string to get the property of an object, or an int (>= 0) to get an item in an array"
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1745,9 +1759,9 @@ mod test {
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
exec::UnitType,
|
||||
execution::{parse_execute, ContextType},
|
||||
ExecutorSettings, UnitLen,
|
||||
exec::UnitType,
|
||||
execution::{ContextType, parse_execute},
|
||||
};
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
@ -1777,7 +1791,7 @@ arr1 = [42]: [number(cm)]
|
||||
.get_from("arr1", result.mem_env, SourceRange::default(), 0)
|
||||
.unwrap();
|
||||
if let KclValue::HomArray { value, ty } = arr1 {
|
||||
assert_eq!(value.len(), 1, "Expected Vec with specific length: found {:?}", value);
|
||||
assert_eq!(value.len(), 1, "Expected Vec with specific length: found {value:?}");
|
||||
assert_eq!(*ty, RuntimeType::known_length(UnitLen::Cm));
|
||||
// Compare, ignoring meta.
|
||||
if let KclValue::Number { value, ty, .. } = &value[0] {
|
||||
@ -1946,7 +1960,7 @@ d = b + c
|
||||
.await
|
||||
.map_err(|err| {
|
||||
KclError::new_internal(KclErrorDetails::new(
|
||||
format!("Failed to create mock engine connection: {}", err),
|
||||
format!("Failed to create mock engine connection: {err}"),
|
||||
vec![SourceRange::default()],
|
||||
))
|
||||
})
|
||||
|
@ -2,19 +2,19 @@ use async_recursion::async_recursion;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use crate::{
|
||||
CompilationError, NodePath,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, StatementKind, TagEngineInfo,
|
||||
TagIdentifier,
|
||||
cad_op::{Group, OpArg, OpKclValue, Operation},
|
||||
kcl_value::FunctionSource,
|
||||
memory,
|
||||
types::RuntimeType,
|
||||
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, StatementKind, TagEngineInfo,
|
||||
TagIdentifier,
|
||||
},
|
||||
parsing::ast::types::{CallExpressionKw, DefaultParamVal, FunctionExpression, Node, Program, Type},
|
||||
source_range::SourceRange,
|
||||
std::StdFn,
|
||||
CompilationError, NodePath,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -269,7 +269,7 @@ impl Node<CallExpressionKw> {
|
||||
};
|
||||
KclError::new_undefined_value(
|
||||
KclErrorDetails::new(
|
||||
format!("Result of user-defined function {} is undefined", fn_name),
|
||||
format!("Result of user-defined function {fn_name} is undefined"),
|
||||
source_ranges,
|
||||
),
|
||||
None,
|
||||
@ -445,7 +445,7 @@ fn update_memory_for_tags_of_geometry(result: &mut KclValue, exec_state: &mut Ex
|
||||
}
|
||||
}
|
||||
}
|
||||
KclValue::Solid { ref mut value } => {
|
||||
KclValue::Solid { value } => {
|
||||
for v in &value.value {
|
||||
if let Some(tag) = v.get_tag() {
|
||||
// Get the past tag and update it.
|
||||
@ -555,9 +555,9 @@ fn type_err_str(expected: &Type, found: &KclValue, source_range: &SourceRange, e
|
||||
let found_human = found.human_friendly_type();
|
||||
let found_ty = found.principal_type_string();
|
||||
let found_str = if found_human == found_ty || found_human == format!("a {}", strip_backticks(&found_ty)) {
|
||||
format!("a value with type {}", found_ty)
|
||||
format!("a value with type {found_ty}")
|
||||
} else {
|
||||
format!("{found_human} (with type {})", found_ty)
|
||||
format!("{found_human} (with type {found_ty})")
|
||||
};
|
||||
|
||||
let mut result = format!("{expected_str}, but found {found_str}.");
|
||||
@ -626,7 +626,7 @@ fn type_check_params_kw(
|
||||
format!(
|
||||
"`{label}` is not an argument of {}",
|
||||
fn_name
|
||||
.map(|n| format!("`{}`", n))
|
||||
.map(|n| format!("`{n}`"))
|
||||
.unwrap_or_else(|| "this function".to_owned()),
|
||||
),
|
||||
));
|
||||
@ -676,7 +676,7 @@ fn type_check_params_kw(
|
||||
format!(
|
||||
"The input argument of {} requires {}",
|
||||
fn_name
|
||||
.map(|n| format!("`{}`", n))
|
||||
.map(|n| format!("`{n}`"))
|
||||
.unwrap_or_else(|| "this function".to_owned()),
|
||||
type_err_str(ty, &arg.1.value, &arg.1.source_range, exec_state),
|
||||
),
|
||||
@ -691,7 +691,7 @@ fn type_check_params_kw(
|
||||
format!(
|
||||
"{} expects an unlabeled first argument (`@{name}`), but it is labelled in the call",
|
||||
fn_name
|
||||
.map(|n| format!("The function `{}`", n))
|
||||
.map(|n| format!("The function `{n}`"))
|
||||
.unwrap_or_else(|| "This function".to_owned()),
|
||||
),
|
||||
));
|
||||
@ -721,7 +721,7 @@ fn assign_args_to_params_kw(
|
||||
)?;
|
||||
}
|
||||
None => match default {
|
||||
Some(ref default_val) => {
|
||||
Some(default_val) => {
|
||||
let value = KclValue::from_default_param(default_val.clone(), exec_state);
|
||||
exec_state
|
||||
.mut_stack()
|
||||
@ -729,10 +729,7 @@ fn assign_args_to_params_kw(
|
||||
}
|
||||
None => {
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!(
|
||||
"This function requires a parameter {}, but you haven't passed it one.",
|
||||
name
|
||||
),
|
||||
format!("This function requires a parameter {name}, but you haven't passed it one."),
|
||||
source_ranges,
|
||||
)));
|
||||
}
|
||||
@ -746,7 +743,9 @@ fn assign_args_to_params_kw(
|
||||
let Some(unlabeled) = unlabelled else {
|
||||
return Err(if args.kw_args.labeled.contains_key(param_name) {
|
||||
KclError::new_semantic(KclErrorDetails::new(
|
||||
format!("The function does declare a parameter named '{param_name}', but this parameter doesn't use a label. Try removing the `{param_name}:`"),
|
||||
format!(
|
||||
"The function does declare a parameter named '{param_name}', but this parameter doesn't use a label. Try removing the `{param_name}:`"
|
||||
),
|
||||
source_ranges,
|
||||
))
|
||||
} else {
|
||||
@ -799,7 +798,7 @@ mod test {
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
execution::{memory::Stack, parse_execute, types::NumericType, ContextType},
|
||||
execution::{ContextType, memory::Stack, parse_execute, types::NumericType},
|
||||
parsing::ast::types::{DefaultParamVal, Identifier, Parameter},
|
||||
};
|
||||
|
||||
|
@ -3,16 +3,16 @@ use std::ops::{Add, AddAssign, Mul};
|
||||
use anyhow::Result;
|
||||
use indexmap::IndexMap;
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use kittycad_modeling_cmds::{each_cmd as mcmd, length_unit::LengthUnit, websocket::ModelingCmdReq, ModelingCmd};
|
||||
use kittycad_modeling_cmds::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, websocket::ModelingCmdReq};
|
||||
use parse_display::{Display, FromStr};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
engine::{PlaneName, DEFAULT_PLANE_INFO},
|
||||
engine::{DEFAULT_PLANE_INFO, PlaneName},
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::NumericType, ArtifactId, ExecState, ExecutorContext, Metadata, TagEngineInfo, TagIdentifier, UnitLen,
|
||||
ArtifactId, ExecState, ExecutorContext, Metadata, TagEngineInfo, TagIdentifier, UnitLen, types::NumericType,
|
||||
},
|
||||
parsing::ast::types::{Node, NodeRef, TagDeclarator, TagNode},
|
||||
std::{args::TyF64, sketch::PlaneData},
|
||||
@ -472,7 +472,7 @@ impl TryFrom<PlaneData> for PlaneInfo {
|
||||
PlaneData::Plane(_) => {
|
||||
// We will never get here since we already checked for PlaneData::Plane.
|
||||
return Err(KclError::new_internal(KclErrorDetails::new(
|
||||
format!("PlaneData {:?} not found", value),
|
||||
format!("PlaneData {value:?} not found"),
|
||||
Default::default(),
|
||||
)));
|
||||
}
|
||||
@ -480,7 +480,7 @@ impl TryFrom<PlaneData> for PlaneInfo {
|
||||
|
||||
let info = DEFAULT_PLANE_INFO.get(&name).ok_or_else(|| {
|
||||
KclError::new_internal(KclErrorDetails::new(
|
||||
format!("Plane {} not found", name),
|
||||
format!("Plane {name} not found"),
|
||||
Default::default(),
|
||||
))
|
||||
})?;
|
||||
@ -815,8 +815,8 @@ impl EdgeCut {
|
||||
|
||||
pub fn set_id(&mut self, id: uuid::Uuid) {
|
||||
match self {
|
||||
EdgeCut::Fillet { id: ref mut i, .. } => *i = id,
|
||||
EdgeCut::Chamfer { id: ref mut i, .. } => *i = id,
|
||||
EdgeCut::Fillet { id: i, .. } => *i = id,
|
||||
EdgeCut::Chamfer { id: i, .. } => *i = id,
|
||||
}
|
||||
}
|
||||
|
||||
@ -829,8 +829,8 @@ impl EdgeCut {
|
||||
|
||||
pub fn set_edge_id(&mut self, id: uuid::Uuid) {
|
||||
match self {
|
||||
EdgeCut::Fillet { edge_id: ref mut i, .. } => *i = id,
|
||||
EdgeCut::Chamfer { edge_id: ref mut i, .. } => *i = id,
|
||||
EdgeCut::Fillet { edge_id: i, .. } => *i = id,
|
||||
EdgeCut::Chamfer { edge_id: i, .. } => *i = id,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@ use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{
|
||||
coord::{System, KITTYCAD},
|
||||
ImportFile, ModelingCmd,
|
||||
coord::{KITTYCAD, System},
|
||||
each_cmd as mcmd,
|
||||
format::InputFormat3d,
|
||||
shared::FileImportFormat,
|
||||
units::UnitLength,
|
||||
ImportFile, ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -16,8 +16,8 @@ use uuid::Uuid;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
annotations, typed_path::TypedPath, types::UnitLen, ExecState, ExecutorContext, ImportedGeometry,
|
||||
ModelingCmdMeta,
|
||||
ExecState, ExecutorContext, ImportedGeometry, ModelingCmdMeta, annotations, typed_path::TypedPath,
|
||||
types::UnitLen,
|
||||
},
|
||||
fs::FileSystem,
|
||||
parsing::ast::types::{Annotation, Node},
|
||||
@ -184,7 +184,7 @@ pub(super) fn format_from_annotations(
|
||||
annotations::IMPORT_LENGTH_UNIT
|
||||
),
|
||||
vec![p.as_source_range()],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,7 +225,7 @@ fn set_coords(fmt: &mut InputFormat3d, coords_str: &str, source_range: SourceRan
|
||||
annotations::IMPORT_COORDS
|
||||
),
|
||||
vec![source_range],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ fn set_length_unit(fmt: &mut InputFormat3d, units_str: &str, source_range: Sourc
|
||||
annotations::IMPORT_LENGTH_UNIT
|
||||
),
|
||||
vec![source_range],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,7 +291,9 @@ fn get_import_format_from_extension(ext: &str) -> Result<InputFormat3d> {
|
||||
} else if ext == "glb" {
|
||||
FileImportFormat::Gltf
|
||||
} else {
|
||||
anyhow::bail!("unknown source format for file extension: {ext}. Try setting the `--src-format` flag explicitly or use a valid format.")
|
||||
anyhow::bail!(
|
||||
"unknown source format for file extension: {ext}. Try setting the `--src-format` flag explicitly or use a valid format."
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -6,12 +6,12 @@ use std::{
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{
|
||||
ExecState, ExecutorContext, KclError, ModuleId, SourceRange,
|
||||
errors::KclErrorDetails,
|
||||
execution::typed_path::TypedPath,
|
||||
modules::{ModulePath, ModuleRepr},
|
||||
parsing::ast::types::{ImportPath, ImportStatement, Node as AstNode},
|
||||
walk::{Node, Visitable},
|
||||
ExecState, ExecutorContext, KclError, ModuleId, SourceRange,
|
||||
};
|
||||
|
||||
/// Specific dependency between two modules. The 0th element of this info
|
||||
@ -147,7 +147,7 @@ fn import_dependencies(
|
||||
ret.lock()
|
||||
.map_err(|err| {
|
||||
KclError::new_internal(KclErrorDetails::new(
|
||||
format!("Failed to lock mutex: {}", err),
|
||||
format!("Failed to lock mutex: {err}"),
|
||||
Default::default(),
|
||||
))
|
||||
})?
|
||||
@ -157,7 +157,7 @@ fn import_dependencies(
|
||||
ret.lock()
|
||||
.map_err(|err| {
|
||||
KclError::new_internal(KclErrorDetails::new(
|
||||
format!("Failed to lock mutex: {}", err),
|
||||
format!("Failed to lock mutex: {err}"),
|
||||
Default::default(),
|
||||
))
|
||||
})?
|
||||
@ -179,7 +179,7 @@ fn import_dependencies(
|
||||
|
||||
let ret = ret.lock().map_err(|err| {
|
||||
KclError::new_internal(KclErrorDetails::new(
|
||||
format!("Failed to lock mutex: {}", err),
|
||||
format!("Failed to lock mutex: {err}"),
|
||||
Default::default(),
|
||||
))
|
||||
})?;
|
||||
@ -224,7 +224,7 @@ pub(crate) async fn import_universe(
|
||||
let repr = {
|
||||
let Some(module_info) = exec_state.get_module(module_id) else {
|
||||
return Err(KclError::new_internal(KclErrorDetails::new(
|
||||
format!("Module {} not found", module_id),
|
||||
format!("Module {module_id} not found"),
|
||||
vec![import_stmt.into()],
|
||||
)));
|
||||
};
|
||||
@ -244,9 +244,7 @@ mod tests {
|
||||
use crate::parsing::ast::types::{ImportSelector, Program};
|
||||
|
||||
macro_rules! kcl {
|
||||
( $kcl:expr ) => {{
|
||||
$crate::parsing::top_level_parse($kcl).unwrap()
|
||||
}};
|
||||
( $kcl:expr_2021 ) => {{ $crate::parsing::top_level_parse($kcl).unwrap() }};
|
||||
}
|
||||
|
||||
fn into_module_info(program: AstNode<Program>) -> DependencyInfo {
|
||||
|
@ -5,18 +5,18 @@ use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
CompilationError, KclError, ModuleId, SourceRange,
|
||||
errors::KclErrorDetails,
|
||||
execution::{
|
||||
annotations::{SETTINGS, SETTINGS_UNIT_LENGTH},
|
||||
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
|
||||
EnvironmentRef, ExecState, Face, Geometry, GeometryWithImportedGeometry, Helix, ImportedGeometry, MetaSettings,
|
||||
Metadata, Plane, Sketch, Solid, TagIdentifier,
|
||||
annotations::{SETTINGS, SETTINGS_UNIT_LENGTH},
|
||||
types::{NumericType, PrimitiveType, RuntimeType, UnitLen},
|
||||
},
|
||||
parsing::ast::types::{
|
||||
DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, TagDeclarator, TagNode,
|
||||
},
|
||||
std::{args::TyF64, StdFnProps},
|
||||
CompilationError, KclError, ModuleId, SourceRange,
|
||||
std::{StdFnProps, args::TyF64},
|
||||
};
|
||||
|
||||
pub type KclObjectFields = HashMap<String, KclValue>;
|
||||
@ -136,9 +136,9 @@ impl JsonSchema for FunctionSource {
|
||||
"FunctionSource".to_owned()
|
||||
}
|
||||
|
||||
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
fn json_schema(r#gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
// TODO: Actually generate a reasonable schema.
|
||||
gen.subschema_for::<()>()
|
||||
r#gen.subschema_for::<()>()
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,7 +587,7 @@ impl KclValue {
|
||||
match self {
|
||||
KclValue::TagIdentifier(t) => Ok(*t.clone()),
|
||||
_ => Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!("Not a tag identifier: {:?}", self),
|
||||
format!("Not a tag identifier: {self:?}"),
|
||||
self.clone().into(),
|
||||
))),
|
||||
}
|
||||
@ -598,7 +598,7 @@ impl KclValue {
|
||||
match self {
|
||||
KclValue::TagDeclarator(t) => Ok((**t).clone()),
|
||||
_ => Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!("Not a tag declarator: {:?}", self),
|
||||
format!("Not a tag declarator: {self:?}"),
|
||||
self.clone().into(),
|
||||
))),
|
||||
}
|
||||
|
@ -207,8 +207,8 @@ use std::{
|
||||
fmt,
|
||||
pin::Pin,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
Arc,
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
},
|
||||
};
|
||||
|
||||
@ -489,7 +489,7 @@ impl ProgramMemory {
|
||||
}
|
||||
|
||||
Err(KclError::new_undefined_value(
|
||||
KclErrorDetails::new(format!("`{}` is not defined", var), vec![]),
|
||||
KclErrorDetails::new(format!("`{var}` is not defined"), vec![]),
|
||||
Some(var.to_owned()),
|
||||
))
|
||||
}
|
||||
@ -647,7 +647,7 @@ impl Stack {
|
||||
let env = self.memory.get_env(self.current_env.index());
|
||||
if env.contains_key(&key) {
|
||||
return Err(KclError::new_value_already_defined(KclErrorDetails::new(
|
||||
format!("Cannot redefine `{}`", key),
|
||||
format!("Cannot redefine `{key}`"),
|
||||
vec![source_range],
|
||||
)));
|
||||
}
|
||||
@ -1047,7 +1047,7 @@ mod env {
|
||||
}
|
||||
|
||||
/// Take all bindings from the environment.
|
||||
pub(super) fn take_bindings(self: Pin<&mut Self>) -> impl Iterator<Item = (String, (usize, KclValue))> {
|
||||
pub(super) fn take_bindings(self: Pin<&mut Self>) -> impl Iterator<Item = (String, (usize, KclValue))> + use<> {
|
||||
// SAFETY: caller must have unique access since self is mut. We're not moving or invalidating `self`.
|
||||
let bindings = std::mem::take(unsafe { self.bindings.get().as_mut().unwrap() });
|
||||
bindings.into_iter()
|
||||
|
@ -16,10 +16,9 @@ pub(crate) use import::PreImportedGeometry;
|
||||
use indexmap::IndexMap;
|
||||
pub use kcl_value::{KclObjectFields, KclValue};
|
||||
use kcmc::{
|
||||
each_cmd as mcmd,
|
||||
ok_response::{output::TakeSnapshot, OkModelingCmdResponse},
|
||||
ImageFormat, ModelingCmd, each_cmd as mcmd,
|
||||
ok_response::{OkModelingCmdResponse, output::TakeSnapshot},
|
||||
websocket::{ModelingSessionData, OkWebSocketResponseData},
|
||||
ImageFormat, ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds::{self as kcmc, id::ModelingCmdId};
|
||||
pub use memory::EnvironmentRef;
|
||||
@ -31,6 +30,7 @@ pub use state::{ExecState, MetaSettings};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
CompilationError, ExecError, KclErrorWithOutputs,
|
||||
engine::{EngineManager, GridScaleBehavior},
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
@ -43,7 +43,6 @@ use crate::{
|
||||
modules::{ModuleId, ModulePath, ModuleRepr},
|
||||
parsing::ast::types::{Expr, ImportPath, NodeRef},
|
||||
source_range::SourceRange,
|
||||
CompilationError, ExecError, KclErrorWithOutputs,
|
||||
};
|
||||
|
||||
pub(crate) mod annotations;
|
||||
@ -1329,7 +1328,7 @@ impl ExecutorContext {
|
||||
created: if deterministic_time {
|
||||
Some("2021-01-01T00:00:00Z".parse().map_err(|e| {
|
||||
KclError::new_internal(crate::errors::KclErrorDetails::new(
|
||||
format!("Failed to parse date: {}", e),
|
||||
format!("Failed to parse date: {e}"),
|
||||
vec![SourceRange::default()],
|
||||
))
|
||||
})?)
|
||||
@ -1409,7 +1408,7 @@ pub(crate) async fn parse_execute_with_project_dir(
|
||||
engine: Arc::new(Box::new(
|
||||
crate::engine::conn_mock::EngineConnection::new().await.map_err(|err| {
|
||||
KclError::new_internal(crate::errors::KclErrorDetails::new(
|
||||
format!("Failed to create mock engine connection: {}", err),
|
||||
format!("Failed to create mock engine connection: {err}"),
|
||||
vec![SourceRange::default()],
|
||||
))
|
||||
})?,
|
||||
@ -1446,7 +1445,7 @@ mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
use crate::{errors::KclErrorDetails, execution::memory::Stack, ModuleId};
|
||||
use crate::{ModuleId, errors::KclErrorDetails, execution::memory::Stack};
|
||||
|
||||
/// Convenience function to get a JSON value from memory and unwrap.
|
||||
#[track_caller]
|
||||
@ -2045,8 +2044,7 @@ notFunction = !x";
|
||||
fn_err
|
||||
.message()
|
||||
.starts_with("Cannot apply unary operator ! to non-boolean value: "),
|
||||
"Actual error: {:?}",
|
||||
fn_err
|
||||
"Actual error: {fn_err:?}"
|
||||
);
|
||||
|
||||
let code8 = "
|
||||
@ -2059,8 +2057,7 @@ notTagDeclarator = !myTagDeclarator";
|
||||
tag_declarator_err
|
||||
.message()
|
||||
.starts_with("Cannot apply unary operator ! to non-boolean value: a tag declarator"),
|
||||
"Actual error: {:?}",
|
||||
tag_declarator_err
|
||||
"Actual error: {tag_declarator_err:?}"
|
||||
);
|
||||
|
||||
let code9 = "
|
||||
@ -2073,8 +2070,7 @@ notTagIdentifier = !myTag";
|
||||
tag_identifier_err
|
||||
.message()
|
||||
.starts_with("Cannot apply unary operator ! to non-boolean value: a tag identifier"),
|
||||
"Actual error: {:?}",
|
||||
tag_identifier_err
|
||||
"Actual error: {tag_identifier_err:?}"
|
||||
);
|
||||
|
||||
let code10 = "notPipe = !(1 |> 2)";
|
||||
@ -2226,7 +2222,7 @@ w = f() + f()
|
||||
if let Err(err) = ctx.run_with_caching(old_program).await {
|
||||
let report = err.into_miette_report_with_outputs(code).unwrap();
|
||||
let report = miette::Report::new(report);
|
||||
panic!("Error executing program: {:?}", report);
|
||||
panic!("Error executing program: {report:?}");
|
||||
}
|
||||
|
||||
// Get the id_generator from the first execution.
|
||||
|
@ -8,10 +8,10 @@ use uuid::Uuid;
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
use crate::exec::ArtifactCommand;
|
||||
use crate::{
|
||||
ExecState, ExecutorContext, KclError, SourceRange,
|
||||
exec::{IdGenerator, KclValue},
|
||||
execution::Solid,
|
||||
std::Args,
|
||||
ExecState, ExecutorContext, KclError, SourceRange,
|
||||
};
|
||||
|
||||
/// Context and metadata needed to send a single modeling command.
|
||||
|
@ -9,20 +9,19 @@ use uuid::Uuid;
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
use crate::execution::{Artifact, ArtifactCommand, ArtifactGraph, ArtifactId};
|
||||
use crate::{
|
||||
CompilationError, EngineManager, ExecutorContext, KclErrorWithOutputs,
|
||||
errors::{KclError, KclErrorDetails, Severity},
|
||||
exec::DefaultPlanes,
|
||||
execution::{
|
||||
annotations,
|
||||
EnvironmentRef, ExecOutcome, ExecutorSettings, KclValue, UnitAngle, UnitLen, annotations,
|
||||
cad_op::Operation,
|
||||
id_generator::IdGenerator,
|
||||
memory::{ProgramMemory, Stack},
|
||||
types::{self, NumericType},
|
||||
EnvironmentRef, ExecOutcome, ExecutorSettings, KclValue, UnitAngle, UnitLen,
|
||||
},
|
||||
modules::{ModuleId, ModuleInfo, ModuleLoader, ModulePath, ModuleRepr, ModuleSource},
|
||||
parsing::ast::types::{Annotation, NodeRef},
|
||||
source_range::SourceRange,
|
||||
CompilationError, EngineManager, ExecutorContext, KclErrorWithOutputs,
|
||||
};
|
||||
|
||||
/// State for executing a program.
|
||||
@ -555,7 +554,7 @@ impl MetaSettings {
|
||||
annotations::SETTINGS_UNIT_ANGLE
|
||||
),
|
||||
vec![annotation.as_source_range()],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,9 +220,9 @@ impl schemars::JsonSchema for TypedPath {
|
||||
"TypedPath".to_owned()
|
||||
}
|
||||
|
||||
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
fn json_schema(r#gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
// TODO: Actually generate a reasonable schema.
|
||||
gen.subschema_for::<std::path::PathBuf>()
|
||||
r#gen.subschema_for::<std::path::PathBuf>()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,17 +5,17 @@ use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
CompilationError, SourceRange,
|
||||
execution::{
|
||||
ExecState, Plane, PlaneInfo, Point3d,
|
||||
kcl_value::{KclValue, TypeDef},
|
||||
memory::{self},
|
||||
ExecState, Plane, PlaneInfo, Point3d,
|
||||
},
|
||||
parsing::{
|
||||
ast::types::{PrimitiveType as AstPrimitiveType, Type},
|
||||
token::NumericSuffix,
|
||||
},
|
||||
std::args::{FromKclValue, TyF64},
|
||||
CompilationError, SourceRange,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -210,7 +210,7 @@ impl RuntimeType {
|
||||
let ty_val = exec_state
|
||||
.stack()
|
||||
.get(&format!("{}{}", memory::TYPE_PREFIX, alias), source_range)
|
||||
.map_err(|_| CompilationError::err(source_range, format!("Unknown type: {}", alias)))?;
|
||||
.map_err(|_| CompilationError::err(source_range, format!("Unknown type: {alias}")))?;
|
||||
|
||||
Ok(match ty_val {
|
||||
KclValue::Type { value, .. } => match value {
|
||||
@ -241,7 +241,7 @@ impl RuntimeType {
|
||||
"a tuple with values of types ({})",
|
||||
tys.iter().map(Self::human_friendly_type).collect::<Vec<_>>().join(", ")
|
||||
),
|
||||
RuntimeType::Object(_) => format!("an object with fields {}", self),
|
||||
RuntimeType::Object(_) => format!("an object with fields {self}"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1529,7 +1529,7 @@ impl KclValue {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::execution::{parse_execute, ExecTestResults};
|
||||
use crate::execution::{ExecTestResults, parse_execute};
|
||||
|
||||
fn values(exec_state: &mut ExecState) -> Vec<KclValue> {
|
||||
vec![
|
||||
@ -1975,14 +1975,16 @@ mod test {
|
||||
])
|
||||
)
|
||||
);
|
||||
assert!(RuntimeType::Union(vec![
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any)),
|
||||
RuntimeType::Primitive(PrimitiveType::Boolean)
|
||||
])
|
||||
.subtype(&RuntimeType::Union(vec![
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any)),
|
||||
RuntimeType::Primitive(PrimitiveType::Boolean)
|
||||
])));
|
||||
assert!(
|
||||
RuntimeType::Union(vec![
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any)),
|
||||
RuntimeType::Primitive(PrimitiveType::Boolean)
|
||||
])
|
||||
.subtype(&RuntimeType::Union(vec![
|
||||
RuntimeType::Primitive(PrimitiveType::Number(NumericType::Any)),
|
||||
RuntimeType::Primitive(PrimitiveType::Boolean)
|
||||
]))
|
||||
);
|
||||
|
||||
// Covariance
|
||||
let count = KclValue::Number {
|
||||
|
@ -3,10 +3,10 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::typed_path::TypedPath,
|
||||
fs::FileSystem,
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{execution::typed_path::TypedPath, SourceRange};
|
||||
use crate::{SourceRange, execution::typed_path::TypedPath};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod local;
|
||||
|
@ -4,11 +4,11 @@ use anyhow::Result;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::typed_path::TypedPath,
|
||||
fs::FileSystem,
|
||||
wasm::JsFuture,
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
#[wasm_bindgen(module = "/../../src/lang/std/fileSystemManager.ts")]
|
||||
|
@ -90,10 +90,9 @@ pub use errors::{
|
||||
ReportWithOutputs,
|
||||
};
|
||||
pub use execution::{
|
||||
bust_cache, clear_mem_cache,
|
||||
ExecOutcome, ExecState, ExecutorContext, ExecutorSettings, MetaSettings, Point2d, bust_cache, clear_mem_cache,
|
||||
typed_path::TypedPath,
|
||||
types::{UnitAngle, UnitLen},
|
||||
ExecOutcome, ExecState, ExecutorContext, ExecutorSettings, MetaSettings, Point2d,
|
||||
};
|
||||
pub use lsp::{
|
||||
copilot::Backend as CopilotLspBackend,
|
||||
@ -101,7 +100,7 @@ pub use lsp::{
|
||||
};
|
||||
pub use modules::ModuleId;
|
||||
pub use parsing::ast::types::{FormatOptions, NodePath, Step as NodePathStep};
|
||||
pub use settings::types::{project::ProjectConfiguration, Configuration, UnitLength};
|
||||
pub use settings::types::{Configuration, UnitLength, project::ProjectConfiguration};
|
||||
pub use source_range::SourceRange;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use unparser::{recast_dir, walk_dir};
|
||||
@ -109,12 +108,12 @@ pub use unparser::{recast_dir, walk_dir};
|
||||
// Rather than make executor public and make lots of it pub(crate), just re-export into a new module.
|
||||
// Ideally we wouldn't export these things at all, they should only be used for testing.
|
||||
pub mod exec {
|
||||
pub use crate::execution::{
|
||||
types::{NumericType, UnitAngle, UnitLen, UnitType},
|
||||
DefaultPlanes, IdGenerator, KclValue, PlaneType, Sketch,
|
||||
};
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
pub use crate::execution::{ArtifactCommand, Operation};
|
||||
pub use crate::execution::{
|
||||
DefaultPlanes, IdGenerator, KclValue, PlaneType, Sketch,
|
||||
types::{NumericType, UnitAngle, UnitLen, UnitType},
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
@ -136,7 +135,7 @@ pub mod native_engine {
|
||||
}
|
||||
|
||||
pub mod std_utils {
|
||||
pub use crate::std::utils::{get_tangential_arc_to_info, is_points_ccw_wasm, TangentialArcInfoInput};
|
||||
pub use crate::std::utils::{TangentialArcInfoInput, get_tangential_arc_to_info, is_points_ccw_wasm};
|
||||
}
|
||||
|
||||
pub mod pretty {
|
||||
@ -160,7 +159,7 @@ lazy_static::lazy_static! {
|
||||
#[cfg(feature = "cli")]
|
||||
let named_extensions = kittycad::types::FileImportFormat::value_variants()
|
||||
.iter()
|
||||
.map(|x| format!("{}", x))
|
||||
.map(|x| format!("{x}"))
|
||||
.collect::<Vec<String>>();
|
||||
#[cfg(not(feature = "cli"))]
|
||||
let named_extensions = vec![]; // We don't really need this outside of the CLI.
|
||||
@ -276,41 +275,25 @@ impl Program {
|
||||
#[inline]
|
||||
fn try_f64_to_usize(f: f64) -> Option<usize> {
|
||||
let i = f as usize;
|
||||
if i as f64 == f {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if i as f64 == f { Some(i) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_f64_to_u32(f: f64) -> Option<u32> {
|
||||
let i = f as u32;
|
||||
if i as f64 == f {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if i as f64 == f { Some(i) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_f64_to_u64(f: f64) -> Option<u64> {
|
||||
let i = f as u64;
|
||||
if i as f64 == f {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if i as f64 == f { Some(i) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_f64_to_i64(f: f64) -> Option<i64> {
|
||||
let i = f as i64;
|
||||
if i as f64 == f {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if i as f64 == f { Some(i) } else { None }
|
||||
}
|
||||
|
||||
/// Get the version of the KCL library.
|
||||
|
@ -2,11 +2,11 @@ use anyhow::Result;
|
||||
use convert_case::Casing;
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::Suggestion,
|
||||
lint::rule::{def_finding, Discovered, Finding},
|
||||
lint::rule::{Discovered, Finding, def_finding},
|
||||
parsing::ast::types::{Node as AstNode, ObjectProperty, Program, VariableDeclarator},
|
||||
walk::Node,
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
def_finding!(
|
||||
@ -38,12 +38,12 @@ fn lint_lower_camel_case_var(decl: &VariableDeclarator, prog: &AstNode<Program>)
|
||||
let recast = prog.recast(&Default::default(), 0);
|
||||
|
||||
let suggestion = Suggestion {
|
||||
title: format!("rename '{}' to '{}'", name, new_name),
|
||||
title: format!("rename '{name}' to '{new_name}'"),
|
||||
insert: recast,
|
||||
source_range: prog.as_source_range(),
|
||||
};
|
||||
findings.push(Z0001.at(
|
||||
format!("found '{}'", name),
|
||||
format!("found '{name}'"),
|
||||
SourceRange::new(ident.start, ident.end, ident.module_id),
|
||||
Some(suggestion.clone()),
|
||||
));
|
||||
@ -61,7 +61,7 @@ fn lint_lower_camel_case_property(decl: &ObjectProperty, _prog: &AstNode<Program
|
||||
if !name.is_case(convert_case::Case::Camel) {
|
||||
// We can't rename the properties yet.
|
||||
findings.push(Z0001.at(
|
||||
format!("found '{}'", name),
|
||||
format!("found '{name}'"),
|
||||
SourceRange::new(ident.start, ident.end, ident.module_id),
|
||||
None,
|
||||
));
|
||||
@ -93,7 +93,7 @@ pub fn lint_object_properties(decl: Node, prog: &AstNode<Program>) -> Result<Vec
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{lint_object_properties, lint_variables, Z0001};
|
||||
use super::{Z0001, lint_object_properties, lint_variables};
|
||||
use crate::lint::rule::{assert_finding, test_finding, test_no_finding};
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
errors::Suggestion,
|
||||
lint::{
|
||||
checks::offset_plane::start_sketch_on_check_specific_plane,
|
||||
rule::{def_finding, Discovered, Finding},
|
||||
rule::{Discovered, Finding, def_finding},
|
||||
},
|
||||
parsing::ast::types::{Node as AstNode, Program},
|
||||
walk::Node,
|
||||
@ -33,14 +33,11 @@ pub fn lint_should_be_default_plane(node: Node, _prog: &AstNode<Program>) -> Res
|
||||
}
|
||||
let suggestion = Suggestion {
|
||||
title: "use defaultPlane instead".to_owned(),
|
||||
insert: format!("{}", plane_name),
|
||||
insert: format!("{plane_name}"),
|
||||
source_range: call_source_range,
|
||||
};
|
||||
Ok(vec![Z0002.at(
|
||||
format!(
|
||||
"custom plane in startSketchOn; defaultPlane {} would work here",
|
||||
plane_name
|
||||
),
|
||||
format!("custom plane in startSketchOn; defaultPlane {plane_name} would work here"),
|
||||
call_source_range,
|
||||
Some(suggestion),
|
||||
)])
|
||||
@ -48,7 +45,7 @@ pub fn lint_should_be_default_plane(node: Node, _prog: &AstNode<Program>) -> Res
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{lint_should_be_default_plane, Z0002};
|
||||
use super::{Z0002, lint_should_be_default_plane};
|
||||
use crate::lint::rule::{test_finding, test_no_finding};
|
||||
|
||||
test_finding!(
|
||||
|
@ -2,6 +2,6 @@ mod camel_case;
|
||||
mod default_plane;
|
||||
mod offset_plane;
|
||||
|
||||
pub use camel_case::{lint_object_properties, lint_variables, Z0001};
|
||||
pub use default_plane::{lint_should_be_default_plane, Z0002};
|
||||
pub use offset_plane::{lint_should_be_offset_plane, Z0003};
|
||||
pub use camel_case::{Z0001, lint_object_properties, lint_variables};
|
||||
pub use default_plane::{Z0002, lint_should_be_default_plane};
|
||||
pub use offset_plane::{Z0003, lint_should_be_offset_plane};
|
||||
|
@ -1,15 +1,15 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{
|
||||
engine::{PlaneName, DEFAULT_PLANE_INFO},
|
||||
SourceRange,
|
||||
engine::{DEFAULT_PLANE_INFO, PlaneName},
|
||||
errors::Suggestion,
|
||||
execution::{types::UnitLen, PlaneInfo, Point3d},
|
||||
lint::rule::{def_finding, Discovered, Finding},
|
||||
execution::{PlaneInfo, Point3d, types::UnitLen},
|
||||
lint::rule::{Discovered, Finding, def_finding},
|
||||
parsing::ast::types::{
|
||||
BinaryPart, CallExpressionKw, Expr, LiteralValue, Node as AstNode, ObjectExpression, Program, UnaryOperator,
|
||||
},
|
||||
walk::Node,
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
def_finding!(
|
||||
@ -39,14 +39,11 @@ pub fn lint_should_be_offset_plane(node: Node, _prog: &AstNode<Program>) -> Resu
|
||||
}
|
||||
let suggestion = Suggestion {
|
||||
title: "use offsetPlane instead".to_owned(),
|
||||
insert: format!("offsetPlane({}, offset = {})", plane_name, offset),
|
||||
insert: format!("offsetPlane({plane_name}, offset = {offset})"),
|
||||
source_range: call_source_range,
|
||||
};
|
||||
Ok(vec![Z0003.at(
|
||||
format!(
|
||||
"custom plane in startSketchOn; offsetPlane from {} would work here",
|
||||
plane_name
|
||||
),
|
||||
format!("custom plane in startSketchOn; offsetPlane from {plane_name} would work here"),
|
||||
call_source_range,
|
||||
Some(suggestion),
|
||||
)])
|
||||
@ -68,16 +65,16 @@ fn get_xyz(point: &ObjectExpression) -> Option<(f64, f64, f64)> {
|
||||
|
||||
for property in &point.properties {
|
||||
let Some(value) = (match &property.value {
|
||||
Expr::UnaryExpression(ref value) => {
|
||||
Expr::UnaryExpression(value) => {
|
||||
if value.operator != UnaryOperator::Neg {
|
||||
continue;
|
||||
}
|
||||
let BinaryPart::Literal(ref value) = &value.inner.argument else {
|
||||
let BinaryPart::Literal(value) = &value.inner.argument else {
|
||||
continue;
|
||||
};
|
||||
unlitafy(&value.inner.value).map(|v| -v)
|
||||
}
|
||||
Expr::Literal(ref value) => unlitafy(&value.value),
|
||||
Expr::Literal(value) => unlitafy(&value.value),
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
@ -271,7 +268,7 @@ fn normalize_plane_info(plane_info: &PlaneInfo) -> PlaneInfo {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{lint_should_be_offset_plane, Z0003};
|
||||
use super::{Z0003, lint_should_be_offset_plane};
|
||||
use crate::lint::rule::{test_finding, test_no_finding};
|
||||
|
||||
test_finding!(
|
||||
|
@ -4,11 +4,11 @@ use serde::Serialize;
|
||||
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::Suggestion,
|
||||
lsp::IntoDiagnostic,
|
||||
parsing::ast::types::{Node as AstNode, Program},
|
||||
walk::Node,
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
/// Check the provided AST for any found rule violations.
|
||||
@ -180,7 +180,7 @@ impl Finding {
|
||||
}
|
||||
|
||||
macro_rules! def_finding {
|
||||
( $code:ident, $title:expr, $description:expr ) => {
|
||||
( $code:ident, $title:expr_2021, $description:expr_2021 ) => {
|
||||
/// Generated Finding
|
||||
pub const $code: Finding = $crate::lint::rule::finding!($code, $title, $description);
|
||||
};
|
||||
@ -188,7 +188,7 @@ macro_rules! def_finding {
|
||||
pub(crate) use def_finding;
|
||||
|
||||
macro_rules! finding {
|
||||
( $code:ident, $title:expr, $description:expr ) => {
|
||||
( $code:ident, $title:expr_2021, $description:expr_2021 ) => {
|
||||
$crate::lint::rule::Finding {
|
||||
code: stringify!($code),
|
||||
title: $title,
|
||||
@ -205,7 +205,7 @@ pub(crate) use test::{assert_finding, assert_no_finding, test_finding, test_no_f
|
||||
mod test {
|
||||
|
||||
macro_rules! assert_no_finding {
|
||||
( $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
( $check:expr_2021, $finding:expr_2021, $kcl:expr_2021 ) => {
|
||||
let prog = $crate::Program::parse_no_errs($kcl).unwrap();
|
||||
|
||||
// Ensure the code still works.
|
||||
@ -220,7 +220,7 @@ mod test {
|
||||
}
|
||||
|
||||
macro_rules! assert_finding {
|
||||
( $check:expr, $finding:expr, $kcl:expr, $output:expr, $suggestion:expr ) => {
|
||||
( $check:expr_2021, $finding:expr_2021, $kcl:expr_2021, $output:expr_2021, $suggestion:expr_2021 ) => {
|
||||
let prog = $crate::Program::parse_no_errs($kcl).unwrap();
|
||||
|
||||
// Ensure the code still works.
|
||||
@ -250,7 +250,7 @@ mod test {
|
||||
}
|
||||
|
||||
macro_rules! test_finding {
|
||||
( $name:ident, $check:expr, $finding:expr, $kcl:expr, $output:expr, $suggestion:expr ) => {
|
||||
( $name:ident, $check:expr_2021, $finding:expr_2021, $kcl:expr_2021, $output:expr_2021, $suggestion:expr_2021 ) => {
|
||||
#[tokio::test]
|
||||
async fn $name() {
|
||||
$crate::lint::rule::assert_finding!($check, $finding, $kcl, $output, $suggestion);
|
||||
@ -259,7 +259,7 @@ mod test {
|
||||
}
|
||||
|
||||
macro_rules! test_no_finding {
|
||||
( $name:ident, $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
( $name:ident, $check:expr_2021, $finding:expr_2021, $kcl:expr_2021 ) => {
|
||||
#[tokio::test]
|
||||
async fn $name() {
|
||||
$crate::lint::rule::assert_no_finding!($check, $finding, $kcl);
|
||||
|
@ -90,7 +90,7 @@ where
|
||||
|
||||
async fn do_initialized(&self, params: InitializedParams) {
|
||||
self.client()
|
||||
.log_message(MessageType::INFO, format!("initialized: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("initialized: {params:?}"))
|
||||
.await;
|
||||
|
||||
self.set_is_initialized(true).await;
|
||||
@ -139,7 +139,7 @@ where
|
||||
self.client()
|
||||
.log_message(
|
||||
MessageType::WARNING,
|
||||
format!("updating from disk `{}` failed: {:?}", project_dir, err),
|
||||
format!("updating from disk `{project_dir}` failed: {err:?}"),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
@ -148,19 +148,19 @@ where
|
||||
|
||||
async fn do_did_change_configuration(&self, params: DidChangeConfigurationParams) {
|
||||
self.client()
|
||||
.log_message(MessageType::INFO, format!("configuration changed: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("configuration changed: {params:?}"))
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn do_did_change_watched_files(&self, params: DidChangeWatchedFilesParams) {
|
||||
self.client()
|
||||
.log_message(MessageType::INFO, format!("watched files changed: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("watched files changed: {params:?}"))
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn do_did_create_files(&self, params: CreateFilesParams) {
|
||||
self.client()
|
||||
.log_message(MessageType::INFO, format!("files created: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("files created: {params:?}"))
|
||||
.await;
|
||||
// Create each file in the code map.
|
||||
for file in params.files {
|
||||
@ -170,7 +170,7 @@ where
|
||||
|
||||
async fn do_did_rename_files(&self, params: RenameFilesParams) {
|
||||
self.client()
|
||||
.log_message(MessageType::INFO, format!("files renamed: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("files renamed: {params:?}"))
|
||||
.await;
|
||||
// Rename each file in the code map.
|
||||
for file in params.files {
|
||||
@ -186,7 +186,7 @@ where
|
||||
|
||||
async fn do_did_delete_files(&self, params: DeleteFilesParams) {
|
||||
self.client()
|
||||
.log_message(MessageType::INFO, format!("files deleted: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("files deleted: {params:?}"))
|
||||
.await;
|
||||
// Delete each file in the map.
|
||||
for file in params.files {
|
||||
@ -228,7 +228,7 @@ where
|
||||
|
||||
async fn do_did_close(&self, params: DidCloseTextDocumentParams) {
|
||||
self.client()
|
||||
.log_message(MessageType::INFO, format!("document closed: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("document closed: {params:?}"))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use std::{
|
||||
use dashmap::DashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tower_lsp::{
|
||||
LanguageServer,
|
||||
jsonrpc::{Error, Result},
|
||||
lsp_types::{
|
||||
CreateFilesParams, DeleteFilesParams, Diagnostic, DidChangeConfigurationParams, DidChangeTextDocumentParams,
|
||||
@ -22,7 +23,6 @@ use tower_lsp::{
|
||||
TextDocumentSyncKind, TextDocumentSyncOptions, WorkspaceFolder, WorkspaceFoldersServerCapabilities,
|
||||
WorkspaceServerCapabilities,
|
||||
},
|
||||
LanguageServer,
|
||||
};
|
||||
|
||||
use crate::lsp::{
|
||||
@ -198,7 +198,7 @@ impl Backend {
|
||||
.map_err(|err| Error {
|
||||
code: tower_lsp::jsonrpc::ErrorCode::from(69),
|
||||
data: None,
|
||||
message: Cow::from(format!("Failed to get completions from zoo api: {}", err)),
|
||||
message: Cow::from(format!("Failed to get completions from zoo api: {err}")),
|
||||
})?;
|
||||
Ok(resp.completions)
|
||||
}
|
||||
@ -209,7 +209,7 @@ impl Backend {
|
||||
let mut lock = copy.write().map_err(|err| Error {
|
||||
code: tower_lsp::jsonrpc::ErrorCode::from(69),
|
||||
data: None,
|
||||
message: Cow::from(format!("Failed lock: {}", err)),
|
||||
message: Cow::from(format!("Failed lock: {err}")),
|
||||
})?;
|
||||
*lock = params;
|
||||
Ok(Success::new(true))
|
||||
@ -254,7 +254,7 @@ impl Backend {
|
||||
.map_err(|err| Error {
|
||||
code: tower_lsp::jsonrpc::ErrorCode::from(69),
|
||||
data: None,
|
||||
message: Cow::from(format!("Failed to get completions: {}", err)),
|
||||
message: Cow::from(format!("Failed to get completions: {err}")),
|
||||
})?;
|
||||
#[cfg(not(test))]
|
||||
let mut completion_list = vec![];
|
||||
@ -294,7 +294,7 @@ part001 = cube(pos = [0,0], scale = 20)
|
||||
|
||||
pub async fn accept_completion(&self, params: CopilotAcceptCompletionParams) {
|
||||
self.client
|
||||
.log_message(MessageType::INFO, format!("Accepted completions: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("Accepted completions: {params:?}"))
|
||||
.await;
|
||||
|
||||
// Get the original telemetry data.
|
||||
@ -303,7 +303,7 @@ part001 = cube(pos = [0,0], scale = 20)
|
||||
};
|
||||
|
||||
self.client
|
||||
.log_message(MessageType::INFO, format!("Original telemetry: {:?}", original))
|
||||
.log_message(MessageType::INFO, format!("Original telemetry: {original:?}"))
|
||||
.await;
|
||||
|
||||
// TODO: Send the telemetry data to the zoo api.
|
||||
@ -311,7 +311,7 @@ part001 = cube(pos = [0,0], scale = 20)
|
||||
|
||||
pub async fn reject_completions(&self, params: CopilotRejectCompletionParams) {
|
||||
self.client
|
||||
.log_message(MessageType::INFO, format!("Rejected completions: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("Rejected completions: {params:?}"))
|
||||
.await;
|
||||
|
||||
// Get the original telemetry data.
|
||||
@ -323,7 +323,7 @@ part001 = cube(pos = [0,0], scale = 20)
|
||||
}
|
||||
|
||||
self.client
|
||||
.log_message(MessageType::INFO, format!("Original telemetry: {:?}", originals))
|
||||
.log_message(MessageType::INFO, format!("Original telemetry: {originals:?}"))
|
||||
.await;
|
||||
|
||||
// TODO: Send the telemetry data to the zoo api.
|
||||
|
@ -85,7 +85,7 @@ impl CopilotCompletionResponse {
|
||||
impl CopilotCyclingCompletion {
|
||||
pub fn new(text: String, line_before: String, position: CopilotPosition) -> Self {
|
||||
let display_text = text.clone();
|
||||
let text = format!("{}{}", line_before, text);
|
||||
let text = format!("{line_before}{text}");
|
||||
let end_char = text.find('\n').unwrap_or(text.len()) as u32;
|
||||
Self {
|
||||
uuid: uuid::Uuid::new_v4(),
|
||||
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tower_lsp::lsp_types::Range as LspRange;
|
||||
|
||||
use crate::{parsing::ast::types::*, SourceRange};
|
||||
use crate::{SourceRange, parsing::ast::types::*};
|
||||
|
||||
/// Describes information about a hover.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||
|
@ -15,6 +15,7 @@ use dashmap::DashMap;
|
||||
use sha2::Digest;
|
||||
use tokio::sync::RwLock;
|
||||
use tower_lsp::{
|
||||
Client, LanguageServer,
|
||||
jsonrpc::Result as RpcResult,
|
||||
lsp_types::{
|
||||
CodeAction, CodeActionKind, CodeActionOptions, CodeActionOrCommand, CodeActionParams,
|
||||
@ -37,10 +38,10 @@ use tower_lsp::{
|
||||
TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, TextEdit, WorkDoneProgressOptions,
|
||||
WorkspaceEdit, WorkspaceFolder, WorkspaceFoldersServerCapabilities, WorkspaceServerCapabilities,
|
||||
},
|
||||
Client, LanguageServer,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ModuleId, Program, SourceRange,
|
||||
docs::kcl_doc::ModData,
|
||||
errors::LspSuggestion,
|
||||
exec::KclValue,
|
||||
@ -51,11 +52,10 @@ use crate::{
|
||||
util::IntoDiagnostic,
|
||||
},
|
||||
parsing::{
|
||||
PIPE_OPERATOR,
|
||||
ast::types::{Expr, VariableKind},
|
||||
token::TokenStream,
|
||||
PIPE_OPERATOR,
|
||||
},
|
||||
ModuleId, Program, SourceRange,
|
||||
};
|
||||
|
||||
pub mod custom_notifications;
|
||||
@ -290,10 +290,9 @@ impl crate::lsp::backend::Backend for Backend {
|
||||
};
|
||||
|
||||
// Get the previous tokens.
|
||||
let tokens_changed = if let Some(previous_tokens) = self.token_map.get(&filename) {
|
||||
*previous_tokens != tokens
|
||||
} else {
|
||||
true
|
||||
let tokens_changed = match self.token_map.get(&filename) {
|
||||
Some(previous_tokens) => *previous_tokens != tokens,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
let had_diagnostics = self.has_diagnostics(params.uri.as_ref()).await;
|
||||
@ -424,7 +423,7 @@ impl Backend {
|
||||
self.client
|
||||
.log_message(
|
||||
MessageType::ERROR,
|
||||
format!("token type `{:?}` not accounted for", token_type),
|
||||
format!("token type `{token_type:?}` not accounted for"),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
@ -436,119 +435,121 @@ impl Backend {
|
||||
|
||||
// Calculate the token modifiers.
|
||||
// Get the value at the current position.
|
||||
let token_modifiers_bitset = if let Some(ast) = self.ast_map.get(params.uri.as_str()) {
|
||||
let token_index = Arc::new(Mutex::new(token_type_index));
|
||||
let modifier_index: Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
|
||||
crate::walk::walk(&ast.ast, |node: crate::walk::Node| {
|
||||
let Ok(node_range): Result<SourceRange, _> = (&node).try_into() else {
|
||||
return Ok(true);
|
||||
};
|
||||
|
||||
if !node_range.contains(source_range.start()) {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let get_modifier = |modifier: Vec<SemanticTokenModifier>| -> Result<bool> {
|
||||
let mut mods = modifier_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
let Some(token_modifier_index) = self.get_semantic_token_modifier_index(modifier) else {
|
||||
let token_modifiers_bitset = match self.ast_map.get(params.uri.as_str()) {
|
||||
Some(ast) => {
|
||||
let token_index = Arc::new(Mutex::new(token_type_index));
|
||||
let modifier_index: Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
|
||||
crate::walk::walk(&ast.ast, |node: crate::walk::Node| {
|
||||
let Ok(node_range): Result<SourceRange, _> = (&node).try_into() else {
|
||||
return Ok(true);
|
||||
};
|
||||
if *mods == 0 {
|
||||
*mods = token_modifier_index;
|
||||
} else {
|
||||
*mods |= token_modifier_index;
|
||||
}
|
||||
Ok(false)
|
||||
};
|
||||
|
||||
match node {
|
||||
crate::walk::Node::TagDeclarator(_) => {
|
||||
return get_modifier(vec![
|
||||
SemanticTokenModifier::DEFINITION,
|
||||
SemanticTokenModifier::STATIC,
|
||||
]);
|
||||
if !node_range.contains(source_range.start()) {
|
||||
return Ok(true);
|
||||
}
|
||||
crate::walk::Node::VariableDeclarator(variable) => {
|
||||
let sr: SourceRange = (&variable.id).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
if let Expr::FunctionExpression(_) = &variable.init {
|
||||
|
||||
let get_modifier = |modifier: Vec<SemanticTokenModifier>| -> Result<bool> {
|
||||
let mut mods = modifier_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
let Some(token_modifier_index) = self.get_semantic_token_modifier_index(modifier) else {
|
||||
return Ok(true);
|
||||
};
|
||||
if *mods == 0 {
|
||||
*mods = token_modifier_index;
|
||||
} else {
|
||||
*mods |= token_modifier_index;
|
||||
}
|
||||
Ok(false)
|
||||
};
|
||||
|
||||
match node {
|
||||
crate::walk::Node::TagDeclarator(_) => {
|
||||
return get_modifier(vec![
|
||||
SemanticTokenModifier::DEFINITION,
|
||||
SemanticTokenModifier::STATIC,
|
||||
]);
|
||||
}
|
||||
crate::walk::Node::VariableDeclarator(variable) => {
|
||||
let sr: SourceRange = (&variable.id).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
if let Expr::FunctionExpression(_) = &variable.init {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::FUNCTION) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
}
|
||||
|
||||
return get_modifier(vec![
|
||||
SemanticTokenModifier::DECLARATION,
|
||||
SemanticTokenModifier::READONLY,
|
||||
]);
|
||||
}
|
||||
}
|
||||
crate::walk::Node::Parameter(_) => {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::PARAMETER) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
return Ok(false);
|
||||
}
|
||||
crate::walk::Node::MemberExpression(member_expression) => {
|
||||
let sr: SourceRange = (&member_expression.property).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::PROPERTY) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
crate::walk::Node::ObjectProperty(object_property) => {
|
||||
let sr: SourceRange = (&object_property.key).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::PROPERTY) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
}
|
||||
return get_modifier(vec![SemanticTokenModifier::DECLARATION]);
|
||||
}
|
||||
crate::walk::Node::CallExpressionKw(call_expr) => {
|
||||
let sr: SourceRange = (&call_expr.callee).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::FUNCTION) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
|
||||
if self.stdlib_completions.contains_key(&call_expr.callee.name.name) {
|
||||
// This is a stdlib function.
|
||||
return get_modifier(vec![SemanticTokenModifier::DEFAULT_LIBRARY]);
|
||||
}
|
||||
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(true)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
return get_modifier(vec![
|
||||
SemanticTokenModifier::DECLARATION,
|
||||
SemanticTokenModifier::READONLY,
|
||||
]);
|
||||
}
|
||||
}
|
||||
crate::walk::Node::Parameter(_) => {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::PARAMETER) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
return Ok(false);
|
||||
}
|
||||
crate::walk::Node::MemberExpression(member_expression) => {
|
||||
let sr: SourceRange = (&member_expression.property).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::PROPERTY) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
crate::walk::Node::ObjectProperty(object_property) => {
|
||||
let sr: SourceRange = (&object_property.key).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::PROPERTY) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
}
|
||||
return get_modifier(vec![SemanticTokenModifier::DECLARATION]);
|
||||
}
|
||||
crate::walk::Node::CallExpressionKw(call_expr) => {
|
||||
let sr: SourceRange = (&call_expr.callee).into();
|
||||
if sr.contains(source_range.start()) {
|
||||
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
|
||||
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::FUNCTION) {
|
||||
Some(index) => index,
|
||||
None => token_type_index,
|
||||
};
|
||||
let t = match token_index.lock() {
|
||||
Ok(guard) => *guard,
|
||||
_ => 0,
|
||||
};
|
||||
token_type_index = t;
|
||||
|
||||
if self.stdlib_completions.contains_key(&call_expr.callee.name.name) {
|
||||
// This is a stdlib function.
|
||||
return get_modifier(vec![SemanticTokenModifier::DEFAULT_LIBRARY]);
|
||||
}
|
||||
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
match modifier_index.lock() {
|
||||
Ok(guard) => *guard,
|
||||
_ => 0,
|
||||
}
|
||||
Ok(true)
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let t = if let Ok(guard) = token_index.lock() { *guard } else { 0 };
|
||||
token_type_index = t;
|
||||
|
||||
let m = if let Ok(guard) = modifier_index.lock() {
|
||||
*guard
|
||||
} else {
|
||||
0
|
||||
};
|
||||
m
|
||||
} else {
|
||||
0
|
||||
}
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
// We need to check if we are on the last token of the line.
|
||||
@ -652,11 +653,14 @@ impl Backend {
|
||||
.await;
|
||||
}
|
||||
|
||||
let mut items = if let Some(items) = self.diagnostics_map.get(params.uri.as_str()) {
|
||||
// TODO: Would be awesome to fix the clone here.
|
||||
items.clone()
|
||||
} else {
|
||||
vec![]
|
||||
let mut items = match self.diagnostics_map.get(params.uri.as_str()) {
|
||||
Some(items) => {
|
||||
// TODO: Would be awesome to fix the clone here.
|
||||
items.clone()
|
||||
}
|
||||
_ => {
|
||||
vec![]
|
||||
}
|
||||
};
|
||||
|
||||
for diagnostic in diagnostics {
|
||||
@ -768,7 +772,7 @@ impl Backend {
|
||||
// Read hash digest and consume hasher
|
||||
let result = hasher.finalize();
|
||||
// Get the hash as a string.
|
||||
let user_id_hash = format!("{:x}", result);
|
||||
let user_id_hash = format!("{result:x}");
|
||||
|
||||
// Get the workspace folders.
|
||||
// The key of the workspace folder is the project name.
|
||||
@ -866,7 +870,7 @@ impl Backend {
|
||||
impl LanguageServer for Backend {
|
||||
async fn initialize(&self, params: InitializeParams) -> RpcResult<InitializeResult> {
|
||||
self.client
|
||||
.log_message(MessageType::INFO, format!("initialize: {:?}", params))
|
||||
.log_message(MessageType::INFO, format!("initialize: {params:?}"))
|
||||
.await;
|
||||
|
||||
Ok(InitializeResult {
|
||||
@ -1006,7 +1010,7 @@ impl LanguageServer for Backend {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
if let Err(err) = self.send_telemetry().await {
|
||||
self.client
|
||||
.log_message(MessageType::WARNING, format!("failed to send telemetry: {}", err))
|
||||
.log_message(MessageType::WARNING, format!("failed to send telemetry: {err}"))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
@ -1090,7 +1094,7 @@ impl LanguageServer for Backend {
|
||||
Ok(Some(LspHover {
|
||||
contents: HoverContents::Markup(MarkupContent {
|
||||
kind: MarkupKind::Markdown,
|
||||
value: format!("```\n{}{}\n```\n\n{}", name, sig, docs),
|
||||
value: format!("```\n{name}{sig}\n```\n\n{docs}"),
|
||||
}),
|
||||
range: Some(range),
|
||||
}))
|
||||
@ -1118,7 +1122,7 @@ impl LanguageServer for Backend {
|
||||
Ok(Some(LspHover {
|
||||
contents: HoverContents::Markup(MarkupContent {
|
||||
kind: MarkupKind::Markdown,
|
||||
value: format!("```\n{}\n```\n\n{}", name, docs),
|
||||
value: format!("```\n{name}\n```\n\n{docs}"),
|
||||
}),
|
||||
range: Some(range),
|
||||
}))
|
||||
@ -1153,17 +1157,17 @@ impl LanguageServer for Backend {
|
||||
} => Ok(Some(LspHover {
|
||||
contents: HoverContents::Markup(MarkupContent {
|
||||
kind: MarkupKind::Markdown,
|
||||
value: format!("```\n{}: {}\n```", name, ty),
|
||||
value: format!("```\n{name}: {ty}\n```"),
|
||||
}),
|
||||
range: Some(range),
|
||||
})),
|
||||
Hover::Variable { name, ty: None, range } => Ok(with_cached_var(&name, |value| {
|
||||
let mut text: String = format!("```\n{}", name);
|
||||
let mut text: String = format!("```\n{name}");
|
||||
if let Some(ty) = value.principal_type() {
|
||||
text.push_str(&format!(": {}", ty.human_friendly_type()));
|
||||
}
|
||||
if let Some(v) = value.value_str() {
|
||||
text.push_str(&format!(" = {}", v));
|
||||
text.push_str(&format!(" = {v}"));
|
||||
}
|
||||
text.push_str("\n```");
|
||||
|
||||
|
@ -13,8 +13,8 @@ use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity, DiagnosticTag};
|
||||
pub use util::IntoDiagnostic;
|
||||
|
||||
use crate::{
|
||||
errors::{Severity, Tag},
|
||||
CompilationError,
|
||||
errors::{Severity, Tag},
|
||||
};
|
||||
|
||||
impl IntoDiagnostic for CompilationError {
|
||||
|
@ -2,18 +2,18 @@ use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
use tower_lsp::{
|
||||
LanguageServer,
|
||||
lsp_types::{
|
||||
CodeActionKind, CodeActionOrCommand, Diagnostic, PrepareRenameResponse, SemanticTokenModifier,
|
||||
SemanticTokenType, TextEdit, WorkspaceEdit,
|
||||
},
|
||||
LanguageServer,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::{LspSuggestion, Suggestion},
|
||||
lsp::test_util::{copilot_lsp_server, kcl_lsp_server},
|
||||
parsing::ast::types::{Node, Program},
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
#[track_caller]
|
||||
@ -276,11 +276,7 @@ async fn test_updating_kcl_lsp_files() {
|
||||
assert_eq!(server.code_map.len(), 11);
|
||||
// Just make sure that one of the current files read from disk is accurate.
|
||||
assert_eq!(
|
||||
server
|
||||
.code_map
|
||||
.get(&format!("{}/util.rs", string_path))
|
||||
.unwrap()
|
||||
.clone(),
|
||||
server.code_map.get(&format!("{string_path}/util.rs")).unwrap().clone(),
|
||||
include_str!("util.rs").as_bytes()
|
||||
);
|
||||
}
|
||||
@ -633,7 +629,7 @@ async fn test_kcl_lsp_create_zip() {
|
||||
}
|
||||
|
||||
assert_eq!(files.len(), 12);
|
||||
let util_path = format!("{}/util.rs", string_path).replace("file://", "");
|
||||
let util_path = format!("{string_path}/util.rs").replace("file://", "");
|
||||
assert!(files.contains_key(&util_path));
|
||||
assert_eq!(files.get("/test.kcl"), Some(&4));
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
exec::KclValue,
|
||||
execution::{typed_path::TypedPath, EnvironmentRef, ModuleArtifactState, PreImportedGeometry},
|
||||
execution::{EnvironmentRef, ModuleArtifactState, PreImportedGeometry, typed_path::TypedPath},
|
||||
fs::{FileManager, FileSystem},
|
||||
parsing::ast::types::{ImportPath, Node, Program},
|
||||
source_range::SourceRange,
|
||||
@ -73,13 +73,13 @@ impl ModuleLoader {
|
||||
}
|
||||
|
||||
pub(crate) fn enter_module(&mut self, path: &ModulePath) {
|
||||
if let ModulePath::Local { value: ref path } = path {
|
||||
if let ModulePath::Local { value: path } = path {
|
||||
self.import_stack.push(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn leave_module(&mut self, path: &ModulePath) {
|
||||
if let ModulePath::Local { value: ref path } = path {
|
||||
if let ModulePath::Local { value: path } = path {
|
||||
let popped = self.import_stack.pop().unwrap();
|
||||
assert_eq!(path, &popped);
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ pub(crate) mod digest;
|
||||
pub mod types;
|
||||
|
||||
use crate::{
|
||||
parsing::ast::types::{BinaryPart, BodyItem, Expr, LiteralIdentifier},
|
||||
ModuleId,
|
||||
parsing::ast::types::{BinaryPart, BodyItem, Expr, LiteralIdentifier},
|
||||
};
|
||||
|
||||
impl BodyItem {
|
||||
|
@ -25,15 +25,14 @@ pub use crate::parsing::ast::types::{
|
||||
none::KclNone,
|
||||
};
|
||||
use crate::{
|
||||
ModuleId, TypedPath,
|
||||
errors::KclError,
|
||||
execution::{
|
||||
annotations,
|
||||
KclValue, Metadata, TagIdentifier, annotations,
|
||||
types::{ArrayLen, UnitAngle, UnitLen},
|
||||
KclValue, Metadata, TagIdentifier,
|
||||
},
|
||||
parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR},
|
||||
parsing::{PIPE_OPERATOR, ast::digest::Digest, token::NumericSuffix},
|
||||
source_range::SourceRange,
|
||||
ModuleId, TypedPath,
|
||||
};
|
||||
|
||||
mod condition;
|
||||
@ -72,18 +71,18 @@ impl<T: JsonSchema> schemars::JsonSchema for Node<T> {
|
||||
T::schema_name()
|
||||
}
|
||||
|
||||
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
let mut child = T::json_schema(gen).into_object();
|
||||
fn json_schema(r#gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
let mut child = T::json_schema(r#gen).into_object();
|
||||
// We want to add the start and end fields to the schema.
|
||||
// Ideally we would add _any_ extra fields from the Node type automatically
|
||||
// but this is a bit hard since this isn't a macro.
|
||||
let Some(ref mut object) = &mut child.object else {
|
||||
let Some(object) = &mut child.object else {
|
||||
// This should never happen. But it will panic at compile time of docs if it does.
|
||||
// Which is better than runtime.
|
||||
panic!("Expected object schema for {}", T::schema_name());
|
||||
};
|
||||
object.properties.insert("start".to_string(), usize::json_schema(gen));
|
||||
object.properties.insert("end".to_string(), usize::json_schema(gen));
|
||||
object.properties.insert("start".to_string(), usize::json_schema(r#gen));
|
||||
object.properties.insert("end".to_string(), usize::json_schema(r#gen));
|
||||
|
||||
schemars::schema::Schema::Object(child.clone())
|
||||
}
|
||||
@ -681,7 +680,7 @@ impl Program {
|
||||
break;
|
||||
}
|
||||
}
|
||||
BodyItem::VariableDeclaration(ref mut variable_declaration) => {
|
||||
BodyItem::VariableDeclaration(variable_declaration) => {
|
||||
if let Some(var_old_name) = variable_declaration.rename_symbol(new_name, pos) {
|
||||
old_name = Some(var_old_name);
|
||||
break;
|
||||
@ -705,18 +704,16 @@ impl Program {
|
||||
// Recurse over the item.
|
||||
let mut value = match item {
|
||||
BodyItem::ImportStatement(_) => None, // TODO
|
||||
BodyItem::ExpressionStatement(ref mut expression_statement) => {
|
||||
Some(&mut expression_statement.expression)
|
||||
}
|
||||
BodyItem::VariableDeclaration(ref mut variable_declaration) => {
|
||||
BodyItem::ExpressionStatement(expression_statement) => Some(&mut expression_statement.expression),
|
||||
BodyItem::VariableDeclaration(variable_declaration) => {
|
||||
variable_declaration.get_mut_expr_for_position(pos)
|
||||
}
|
||||
BodyItem::TypeDeclaration(_) => None,
|
||||
BodyItem::ReturnStatement(ref mut return_statement) => Some(&mut return_statement.argument),
|
||||
BodyItem::ReturnStatement(return_statement) => Some(&mut return_statement.argument),
|
||||
};
|
||||
|
||||
// Check if we have a function expression.
|
||||
if let Some(Expr::FunctionExpression(ref mut function_expression)) = &mut value {
|
||||
if let Some(Expr::FunctionExpression(function_expression)) = &mut value {
|
||||
// Check if the params to the function expression contain the position.
|
||||
for param in &mut function_expression.params {
|
||||
let param_source_range: SourceRange = (¶m.identifier).into();
|
||||
@ -764,7 +761,7 @@ impl Program {
|
||||
BodyItem::ExpressionStatement(_) => {
|
||||
continue;
|
||||
}
|
||||
BodyItem::VariableDeclaration(ref mut variable_declaration) => {
|
||||
BodyItem::VariableDeclaration(variable_declaration) => {
|
||||
if variable_declaration.declaration.id.name == name {
|
||||
variable_declaration.declaration = declarator;
|
||||
return;
|
||||
@ -783,14 +780,14 @@ impl Program {
|
||||
for item in &mut self.body {
|
||||
match item {
|
||||
BodyItem::ImportStatement(_) => {} // TODO
|
||||
BodyItem::ExpressionStatement(ref mut expression_statement) => expression_statement
|
||||
BodyItem::ExpressionStatement(expression_statement) => expression_statement
|
||||
.expression
|
||||
.replace_value(source_range, new_value.clone()),
|
||||
BodyItem::VariableDeclaration(ref mut variable_declaration) => {
|
||||
BodyItem::VariableDeclaration(variable_declaration) => {
|
||||
variable_declaration.replace_value(source_range, new_value.clone())
|
||||
}
|
||||
BodyItem::TypeDeclaration(_) => {}
|
||||
BodyItem::ReturnStatement(ref mut return_statement) => {
|
||||
BodyItem::ReturnStatement(return_statement) => {
|
||||
return_statement.argument.replace_value(source_range, new_value.clone())
|
||||
}
|
||||
}
|
||||
@ -1040,18 +1037,18 @@ impl Expr {
|
||||
}
|
||||
|
||||
match self {
|
||||
Expr::BinaryExpression(ref mut bin_exp) => bin_exp.replace_value(source_range, new_value),
|
||||
Expr::ArrayExpression(ref mut array_exp) => array_exp.replace_value(source_range, new_value),
|
||||
Expr::ArrayRangeExpression(ref mut array_range) => array_range.replace_value(source_range, new_value),
|
||||
Expr::ObjectExpression(ref mut obj_exp) => obj_exp.replace_value(source_range, new_value),
|
||||
Expr::BinaryExpression(bin_exp) => bin_exp.replace_value(source_range, new_value),
|
||||
Expr::ArrayExpression(array_exp) => array_exp.replace_value(source_range, new_value),
|
||||
Expr::ArrayRangeExpression(array_range) => array_range.replace_value(source_range, new_value),
|
||||
Expr::ObjectExpression(obj_exp) => obj_exp.replace_value(source_range, new_value),
|
||||
Expr::MemberExpression(_) => {}
|
||||
Expr::Literal(_) => {}
|
||||
Expr::FunctionExpression(ref mut func_exp) => func_exp.replace_value(source_range, new_value),
|
||||
Expr::CallExpressionKw(ref mut call_exp) => call_exp.replace_value(source_range, new_value),
|
||||
Expr::FunctionExpression(func_exp) => func_exp.replace_value(source_range, new_value),
|
||||
Expr::CallExpressionKw(call_exp) => call_exp.replace_value(source_range, new_value),
|
||||
Expr::Name(_) => {}
|
||||
Expr::TagDeclarator(_) => {}
|
||||
Expr::PipeExpression(ref mut pipe_exp) => pipe_exp.replace_value(source_range, new_value),
|
||||
Expr::UnaryExpression(ref mut unary_exp) => unary_exp.replace_value(source_range, new_value),
|
||||
Expr::PipeExpression(pipe_exp) => pipe_exp.replace_value(source_range, new_value),
|
||||
Expr::UnaryExpression(unary_exp) => unary_exp.replace_value(source_range, new_value),
|
||||
Expr::IfExpression(_) => {}
|
||||
Expr::PipeSubstitution(_) => {}
|
||||
Expr::LabelledExpression(expr) => expr.expr.replace_value(source_range, new_value),
|
||||
@ -1113,25 +1110,19 @@ impl Expr {
|
||||
fn rename_identifiers(&mut self, old_name: &str, new_name: &str) {
|
||||
match self {
|
||||
Expr::Literal(_literal) => {}
|
||||
Expr::Name(ref mut identifier) => identifier.rename(old_name, new_name),
|
||||
Expr::TagDeclarator(ref mut tag) => tag.rename(old_name, new_name),
|
||||
Expr::BinaryExpression(ref mut binary_expression) => {
|
||||
binary_expression.rename_identifiers(old_name, new_name)
|
||||
}
|
||||
Expr::Name(identifier) => identifier.rename(old_name, new_name),
|
||||
Expr::TagDeclarator(tag) => tag.rename(old_name, new_name),
|
||||
Expr::BinaryExpression(binary_expression) => binary_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::FunctionExpression(_function_identifier) => {}
|
||||
Expr::CallExpressionKw(ref mut call_expression) => call_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::PipeExpression(ref mut pipe_expression) => pipe_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::CallExpressionKw(call_expression) => call_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::PipeExpression(pipe_expression) => pipe_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::PipeSubstitution(_) => {}
|
||||
Expr::ArrayExpression(ref mut array_expression) => array_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::ArrayRangeExpression(ref mut array_range) => array_range.rename_identifiers(old_name, new_name),
|
||||
Expr::ObjectExpression(ref mut object_expression) => {
|
||||
object_expression.rename_identifiers(old_name, new_name)
|
||||
}
|
||||
Expr::MemberExpression(ref mut member_expression) => {
|
||||
member_expression.rename_identifiers(old_name, new_name)
|
||||
}
|
||||
Expr::UnaryExpression(ref mut unary_expression) => unary_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::IfExpression(ref mut expr) => expr.rename_identifiers(old_name, new_name),
|
||||
Expr::ArrayExpression(array_expression) => array_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::ArrayRangeExpression(array_range) => array_range.rename_identifiers(old_name, new_name),
|
||||
Expr::ObjectExpression(object_expression) => object_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::MemberExpression(member_expression) => member_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::UnaryExpression(unary_expression) => unary_expression.rename_identifiers(old_name, new_name),
|
||||
Expr::IfExpression(expr) => expr.rename_identifiers(old_name, new_name),
|
||||
Expr::LabelledExpression(expr) => expr.expr.rename_identifiers(old_name, new_name),
|
||||
Expr::AscribedExpression(expr) => expr.expr.rename_identifiers(old_name, new_name),
|
||||
Expr::None(_) => {}
|
||||
@ -1325,15 +1316,9 @@ impl BinaryPart {
|
||||
match self {
|
||||
BinaryPart::Literal(_) => {}
|
||||
BinaryPart::Name(_) => {}
|
||||
BinaryPart::BinaryExpression(ref mut binary_expression) => {
|
||||
binary_expression.replace_value(source_range, new_value)
|
||||
}
|
||||
BinaryPart::CallExpressionKw(ref mut call_expression) => {
|
||||
call_expression.replace_value(source_range, new_value)
|
||||
}
|
||||
BinaryPart::UnaryExpression(ref mut unary_expression) => {
|
||||
unary_expression.replace_value(source_range, new_value)
|
||||
}
|
||||
BinaryPart::BinaryExpression(binary_expression) => binary_expression.replace_value(source_range, new_value),
|
||||
BinaryPart::CallExpressionKw(call_expression) => call_expression.replace_value(source_range, new_value),
|
||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.replace_value(source_range, new_value),
|
||||
BinaryPart::MemberExpression(_) => {}
|
||||
BinaryPart::IfExpression(e) => e.replace_value(source_range, new_value),
|
||||
BinaryPart::AscribedExpression(e) => e.expr.replace_value(source_range, new_value),
|
||||
@ -1370,21 +1355,13 @@ impl BinaryPart {
|
||||
fn rename_identifiers(&mut self, old_name: &str, new_name: &str) {
|
||||
match self {
|
||||
BinaryPart::Literal(_literal) => {}
|
||||
BinaryPart::Name(ref mut identifier) => identifier.rename(old_name, new_name),
|
||||
BinaryPart::BinaryExpression(ref mut binary_expression) => {
|
||||
binary_expression.rename_identifiers(old_name, new_name)
|
||||
}
|
||||
BinaryPart::CallExpressionKw(ref mut call_expression) => {
|
||||
call_expression.rename_identifiers(old_name, new_name)
|
||||
}
|
||||
BinaryPart::UnaryExpression(ref mut unary_expression) => {
|
||||
unary_expression.rename_identifiers(old_name, new_name)
|
||||
}
|
||||
BinaryPart::MemberExpression(ref mut member_expression) => {
|
||||
member_expression.rename_identifiers(old_name, new_name)
|
||||
}
|
||||
BinaryPart::IfExpression(ref mut if_expression) => if_expression.rename_identifiers(old_name, new_name),
|
||||
BinaryPart::AscribedExpression(ref mut e) => e.expr.rename_identifiers(old_name, new_name),
|
||||
BinaryPart::Name(identifier) => identifier.rename(old_name, new_name),
|
||||
BinaryPart::BinaryExpression(binary_expression) => binary_expression.rename_identifiers(old_name, new_name),
|
||||
BinaryPart::CallExpressionKw(call_expression) => call_expression.rename_identifiers(old_name, new_name),
|
||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.rename_identifiers(old_name, new_name),
|
||||
BinaryPart::MemberExpression(member_expression) => member_expression.rename_identifiers(old_name, new_name),
|
||||
BinaryPart::IfExpression(if_expression) => if_expression.rename_identifiers(old_name, new_name),
|
||||
BinaryPart::AscribedExpression(e) => e.expr.rename_identifiers(old_name, new_name),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2824,7 +2801,7 @@ impl MemberExpression {
|
||||
self.object.rename_identifiers(old_name, new_name);
|
||||
|
||||
match &mut self.property {
|
||||
LiteralIdentifier::Identifier(ref mut identifier) => identifier.rename(old_name, new_name),
|
||||
LiteralIdentifier::Identifier(identifier) => identifier.rename(old_name, new_name),
|
||||
LiteralIdentifier::Literal(_) => {}
|
||||
}
|
||||
}
|
||||
@ -3312,7 +3289,7 @@ impl Type {
|
||||
.map(|t| t.human_friendly_type())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" or "),
|
||||
Type::Object { .. } => format!("an object with fields `{}`", self),
|
||||
Type::Object { .. } => format!("an object with fields `{self}`"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -3469,7 +3446,11 @@ pub struct RequiredParamAfterOptionalParam(pub Box<Parameter>);
|
||||
|
||||
impl std::fmt::Display for RequiredParamAfterOptionalParam {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "KCL functions must declare any optional parameters after all the required parameters. But your required parameter {} is _after_ an optional parameter. You must move it to before the optional parameters instead.", self.0.identifier.name)
|
||||
write!(
|
||||
f,
|
||||
"KCL functions must declare any optional parameters after all the required parameters. But your required parameter {} is _after_ an optional parameter. You must move it to before the optional parameters instead.",
|
||||
self.0.identifier.name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
use super::CompilationError;
|
||||
use crate::{
|
||||
parsing::ast::types::{BinaryExpression, BinaryOperator, BinaryPart, Node},
|
||||
SourceRange,
|
||||
parsing::ast::types::{BinaryExpression, BinaryOperator, BinaryPart, Node},
|
||||
};
|
||||
|
||||
/// Parses a list of tokens (in infix order, i.e. as the user typed them)
|
||||
@ -127,11 +127,11 @@ impl From<BinaryOperator> for BinaryExpressionToken {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
ModuleId,
|
||||
parsing::{
|
||||
ast::types::{Literal, LiteralValue},
|
||||
token::NumericSuffix,
|
||||
},
|
||||
ModuleId,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
@ -1,11 +1,11 @@
|
||||
use crate::{
|
||||
ModuleId,
|
||||
errors::{CompilationError, KclError, KclErrorDetails},
|
||||
parsing::{
|
||||
ast::types::{Node, Program},
|
||||
token::TokenStream,
|
||||
},
|
||||
source_range::SourceRange,
|
||||
ModuleId,
|
||||
};
|
||||
|
||||
pub(crate) mod ast;
|
||||
@ -18,7 +18,7 @@ pub const PIPE_OPERATOR: &str = "|>";
|
||||
|
||||
// `?` like behavior for `Result`s to return a ParseResult if there is an error.
|
||||
macro_rules! pr_try {
|
||||
($e: expr) => {
|
||||
($e: expr_2021) => {
|
||||
match $e {
|
||||
Ok(a) => a,
|
||||
Err(e) => return e.into(),
|
||||
@ -187,7 +187,7 @@ pub fn deprecation(s: &str, kind: DeprecationKind) -> Option<&'static str> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
macro_rules! parse_and_lex {
|
||||
($func_name:ident, $test_kcl_program:expr) => {
|
||||
($func_name:ident, $test_kcl_program:expr_2021) => {
|
||||
#[test]
|
||||
fn $func_name() {
|
||||
let _ = crate::parsing::top_level_parse($test_kcl_program);
|
||||
|
@ -14,14 +14,16 @@ use winnow::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
DeprecationKind,
|
||||
ast::types::{AscribedExpression, ImportPath, LabelledExpression},
|
||||
token::{NumericSuffix, RESERVED_WORDS},
|
||||
DeprecationKind,
|
||||
};
|
||||
use crate::{
|
||||
IMPORT_FILE_EXTENSIONS, SourceRange, TypedPath,
|
||||
errors::{CompilationError, Severity, Tag},
|
||||
execution::types::ArrayLen,
|
||||
parsing::{
|
||||
PIPE_OPERATOR, PIPE_SUBSTITUTION_OPERATOR,
|
||||
ast::types::{
|
||||
Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem,
|
||||
BoxNode, CallExpressionKw, CommentStyle, DefaultParamVal, ElseIf, Expr, ExpressionStatement,
|
||||
@ -33,9 +35,7 @@ use crate::{
|
||||
},
|
||||
math::BinaryExpressionToken,
|
||||
token::{Token, TokenSlice, TokenType},
|
||||
PIPE_OPERATOR, PIPE_SUBSTITUTION_OPERATOR,
|
||||
},
|
||||
SourceRange, TypedPath, IMPORT_FILE_EXTENSIONS,
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
@ -602,7 +602,7 @@ fn binary_operator(i: &mut TokenSlice) -> ModalResult<BinaryOperator> {
|
||||
return Err(CompilationError::fatal(
|
||||
token.as_source_range(),
|
||||
format!("{} is not a binary operator", token.value.as_str()),
|
||||
))
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok(op)
|
||||
@ -726,7 +726,7 @@ fn shebang(i: &mut TokenSlice) -> ModalResult<Node<Shebang>> {
|
||||
opt(whitespace).parse_next(i)?;
|
||||
|
||||
Ok(Node::new(
|
||||
Shebang::new(format!("#!{}", value)),
|
||||
Shebang::new(format!("#!{value}")),
|
||||
0,
|
||||
tokens.last().unwrap().end,
|
||||
tokens.first().unwrap().module_id,
|
||||
@ -1926,7 +1926,7 @@ fn validate_path_string(path_string: String, var_name: bool, path_range: SourceR
|
||||
return Err(ErrMode::Cut(
|
||||
CompilationError::fatal(
|
||||
path_range,
|
||||
format!("Invalid import path for import from std: {}.", path_string),
|
||||
format!("Invalid import path for import from std: {path_string}."),
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
@ -1938,7 +1938,10 @@ fn validate_path_string(path_string: String, var_name: bool, path_range: SourceR
|
||||
if !IMPORT_FILE_EXTENSIONS.contains(&extn.to_string_lossy().to_string()) {
|
||||
ParseContext::warn(CompilationError::err(
|
||||
path_range,
|
||||
format!("unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}", IMPORT_FILE_EXTENSIONS.join(", ")),
|
||||
format!(
|
||||
"unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}",
|
||||
IMPORT_FILE_EXTENSIONS.join(", ")
|
||||
),
|
||||
))
|
||||
}
|
||||
ImportPath::Foreign {
|
||||
@ -2210,7 +2213,7 @@ fn declaration(i: &mut TokenSlice) -> ModalResult<BoxNode<VariableDeclaration>>
|
||||
if matches!(val, Expr::FunctionExpression(_)) {
|
||||
return Err(CompilationError::fatal(
|
||||
SourceRange::new(start, dec_end, id.module_id),
|
||||
format!("Expected a `fn` variable kind, found: `{}`", kind),
|
||||
format!("Expected a `fn` variable kind, found: `{kind}`"),
|
||||
));
|
||||
}
|
||||
Ok(val)
|
||||
@ -3312,10 +3315,10 @@ fn fn_call_kw(i: &mut TokenSlice) -> ModalResult<Node<CallExpressionKw>> {
|
||||
ParseContext::warn(
|
||||
CompilationError::err(
|
||||
result.as_source_range(),
|
||||
format!("Calling `{}` is deprecated, prefer using `{}`.", callee_str, suggestion),
|
||||
format!("Calling `{callee_str}` is deprecated, prefer using `{suggestion}`."),
|
||||
)
|
||||
.with_suggestion(
|
||||
format!("Replace `{}` with `{}`", callee_str, suggestion),
|
||||
format!("Replace `{callee_str}` with `{suggestion}`"),
|
||||
suggestion,
|
||||
None,
|
||||
Tag::Deprecated,
|
||||
@ -3333,13 +3336,13 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
parsing::ast::types::{BodyItem, Expr, VariableKind},
|
||||
ModuleId,
|
||||
parsing::ast::types::{BodyItem, Expr, VariableKind},
|
||||
};
|
||||
|
||||
fn assert_reserved(word: &str) {
|
||||
// Try to use it as a variable name.
|
||||
let code = format!(r#"{} = 0"#, word);
|
||||
let code = format!(r#"{word} = 0"#);
|
||||
let result = crate::parsing::top_level_parse(code.as_str());
|
||||
let err = &result.unwrap_errs().next().unwrap();
|
||||
// Which token causes the error may change. In "return = 0", for
|
||||
@ -5263,7 +5266,7 @@ mod snapshot_math_tests {
|
||||
// The macro takes a KCL program, ensures it tokenizes and parses, then compares
|
||||
// its parsed AST to a snapshot (kept in this repo in a file under snapshots/ dir)
|
||||
macro_rules! snapshot_test {
|
||||
($func_name:ident, $test_kcl_program:expr) => {
|
||||
($func_name:ident, $test_kcl_program:expr_2021) => {
|
||||
#[test]
|
||||
fn $func_name() {
|
||||
let module_id = crate::ModuleId::default();
|
||||
@ -5301,7 +5304,7 @@ mod snapshot_tests {
|
||||
// The macro takes a KCL program, ensures it tokenizes and parses, then compares
|
||||
// its parsed AST to a snapshot (kept in this repo in a file under snapshots/ dir)
|
||||
macro_rules! snapshot_test {
|
||||
($func_name:ident, $test_kcl_program:expr) => {
|
||||
($func_name:ident, $test_kcl_program:expr_2021) => {
|
||||
#[test]
|
||||
fn $func_name() {
|
||||
let module_id = crate::ModuleId::default();
|
||||
|
@ -16,10 +16,10 @@ use winnow::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
CompilationError, ModuleId,
|
||||
errors::KclError,
|
||||
parsing::ast::types::{ItemVisibility, VariableKind},
|
||||
source_range::SourceRange,
|
||||
CompilationError, ModuleId,
|
||||
};
|
||||
|
||||
mod tokeniser;
|
||||
@ -609,7 +609,7 @@ impl From<ParseError<Input<'_>, winnow::error::ContextError>> for KclError {
|
||||
// TODO: Add the Winnow parser context to the error.
|
||||
// See https://github.com/KittyCAD/modeling-app/issues/784
|
||||
KclError::new_lexical(crate::errors::KclErrorDetails::new(
|
||||
format!("found unknown token '{}'", bad_token),
|
||||
format!("found unknown token '{bad_token}'"),
|
||||
vec![SourceRange::new(offset, offset + 1, module_id)],
|
||||
))
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
use fnv::FnvHashMap;
|
||||
use lazy_static::lazy_static;
|
||||
use winnow::{
|
||||
LocatingSlice, Stateful,
|
||||
ascii::{digit1, multispace1},
|
||||
combinator::{alt, opt, peek, preceded, repeat},
|
||||
error::{ContextError, ParseError},
|
||||
prelude::*,
|
||||
stream::{Location, Stream},
|
||||
token::{any, none_of, take_till, take_until, take_while},
|
||||
LocatingSlice, Stateful,
|
||||
};
|
||||
|
||||
use super::TokenStream;
|
||||
use crate::{
|
||||
parsing::token::{Token, TokenType},
|
||||
ModuleId,
|
||||
parsing::token::{Token, TokenType},
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use schemars::{gen::SchemaGenerator, JsonSchema};
|
||||
use serde_json::{json, Value};
|
||||
use schemars::{JsonSchema, r#gen::SchemaGenerator};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::settings::types::{project::ProjectConfiguration, Configuration};
|
||||
use crate::settings::types::{Configuration, project::ProjectConfiguration};
|
||||
|
||||
// Project settings example in TOML format
|
||||
const PROJECT_SETTINGS_EXAMPLE: &str = r#"[settings.app]
|
||||
@ -60,7 +60,7 @@ fn init_handlebars() -> handlebars::Handlebars<'static> {
|
||||
let pretty_options = array
|
||||
.iter()
|
||||
.filter_map(|v| v.as_str())
|
||||
.map(|s| format!("`{}`", s))
|
||||
.map(|s| format!("`{s}`"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
out.write(&pretty_options)?;
|
||||
@ -89,17 +89,17 @@ fn init_handlebars() -> handlebars::Handlebars<'static> {
|
||||
Value::Null => out.write("None")?,
|
||||
Value::Bool(b) => out.write(&b.to_string())?,
|
||||
Value::Number(n) => out.write(&n.to_string())?,
|
||||
Value::String(s) => out.write(&format!("`{}`", s))?,
|
||||
Value::String(s) => out.write(&format!("`{s}`"))?,
|
||||
Value::Array(arr) => {
|
||||
let formatted = arr
|
||||
.iter()
|
||||
.map(|v| match v {
|
||||
Value::String(s) => format!("`{}`", s),
|
||||
_ => format!("{}", v),
|
||||
Value::String(s) => format!("`{s}`"),
|
||||
_ => format!("{v}"),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
out.write(&format!("[{}]", formatted))?;
|
||||
out.write(&format!("[{formatted}]"))?;
|
||||
}
|
||||
Value::Object(_) => out.write("(complex default)")?,
|
||||
}
|
||||
@ -122,7 +122,7 @@ pub fn generate_settings_docs() {
|
||||
let hbs = init_handlebars();
|
||||
|
||||
// Generate project settings documentation
|
||||
let mut settings = schemars::gen::SchemaSettings::default();
|
||||
let mut settings = schemars::r#gen::SchemaSettings::default();
|
||||
settings.inline_subschemas = true;
|
||||
settings.meta_schema = None; // We don't need the meta schema for docs
|
||||
settings.option_nullable = false; // Important - makes Option fields show properly
|
||||
|
@ -716,13 +716,15 @@ enable_ssao = false
|
||||
|
||||
let result = color.validate();
|
||||
if let Ok(r) = result {
|
||||
panic!("Expected an error, but got success: {:?}", r);
|
||||
panic!("Expected an error, but got success: {r:?}");
|
||||
}
|
||||
assert!(result.is_err());
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color"));
|
||||
assert!(
|
||||
result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color")
|
||||
);
|
||||
|
||||
let appearance = AppearanceSettings {
|
||||
theme: AppTheme::System,
|
||||
@ -730,13 +732,15 @@ enable_ssao = false
|
||||
};
|
||||
let result = appearance.validate();
|
||||
if let Ok(r) = result {
|
||||
panic!("Expected an error, but got success: {:?}", r);
|
||||
panic!("Expected an error, but got success: {r:?}");
|
||||
}
|
||||
assert!(result.is_err());
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color"));
|
||||
assert!(
|
||||
result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -746,13 +750,15 @@ color = 1567.4"#;
|
||||
|
||||
let result = Configuration::parse_and_validate(settings_file);
|
||||
if let Ok(r) = result {
|
||||
panic!("Expected an error, but got success: {:?}", r);
|
||||
panic!("Expected an error, but got success: {r:?}");
|
||||
}
|
||||
assert!(result.is_err());
|
||||
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color"));
|
||||
assert!(
|
||||
result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
use crate::settings::types::{
|
||||
is_default, AppColor, CommandBarSettings, DefaultTrue, OnboardingStatus, TextEditorSettings, UnitLength,
|
||||
AppColor, CommandBarSettings, DefaultTrue, OnboardingStatus, TextEditorSettings, UnitLength, is_default,
|
||||
};
|
||||
|
||||
/// Project specific settings for the app.
|
||||
@ -203,14 +203,16 @@ color = 1567.4"#;
|
||||
|
||||
let result = ProjectConfiguration::parse_and_validate(settings_file);
|
||||
if let Ok(r) = result {
|
||||
panic!("Expected an error, but got success: {:?}", r);
|
||||
panic!("Expected an error, but got success: {r:?}");
|
||||
}
|
||||
assert!(result.is_err());
|
||||
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color"));
|
||||
assert!(
|
||||
result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("color: Validation error: color")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,14 +1,14 @@
|
||||
use std::{
|
||||
panic::{catch_unwind, AssertUnwindSafe},
|
||||
panic::{AssertUnwindSafe, catch_unwind},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use crate::{
|
||||
ExecOutcome, ExecState, ExecutorContext, ModuleId,
|
||||
errors::KclError,
|
||||
execution::{EnvironmentRef, ModuleArtifactState},
|
||||
ExecOutcome, ExecState, ExecutorContext, ModuleId,
|
||||
};
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
use crate::{
|
||||
@ -241,7 +241,10 @@ async fn execute_test(test: &Test, render_to_png: bool, export_step: bool) {
|
||||
Ok((exec_state, ctx, env_ref, png, step)) => {
|
||||
let fail_path = test.output_dir.join("execution_error.snap");
|
||||
if std::fs::exists(&fail_path).unwrap() {
|
||||
panic!("This test case is expected to fail, but it passed. If this is intended, and the test should actually be passing now, please delete kcl-lib/{}", fail_path.to_string_lossy())
|
||||
panic!(
|
||||
"This test case is expected to fail, but it passed. If this is intended, and the test should actually be passing now, please delete kcl-lib/{}",
|
||||
fail_path.to_string_lossy()
|
||||
)
|
||||
}
|
||||
if render_to_png {
|
||||
twenty_twenty::assert_image(test.output_dir.join(RENDERED_MODEL_NAME), &png, 0.99);
|
||||
@ -287,10 +290,13 @@ async fn execute_test(test: &Test, render_to_png: bool, export_step: bool) {
|
||||
let report = error.clone().into_miette_report_with_outputs(&input).unwrap();
|
||||
let report = miette::Report::new(report);
|
||||
if previously_passed {
|
||||
eprintln!("This test case failed, but it previously passed. If this is intended, and the test should actually be failing now, please delete kcl-lib/{} and other associated passing artifacts", ok_path.to_string_lossy());
|
||||
eprintln!(
|
||||
"This test case failed, but it previously passed. If this is intended, and the test should actually be failing now, please delete kcl-lib/{} and other associated passing artifacts",
|
||||
ok_path.to_string_lossy()
|
||||
);
|
||||
panic!("{report:?}");
|
||||
}
|
||||
let report = format!("{:?}", report);
|
||||
let report = format!("{report:?}");
|
||||
|
||||
let err_result = catch_unwind(AssertUnwindSafe(|| {
|
||||
assert_snapshot(test, "Error from executing", || {
|
||||
@ -2882,7 +2888,7 @@ mod clone_w_fillets {
|
||||
/// Test that KCL is executed correctly.
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#[ignore] // turn on when https://github.com/KittyCAD/engine/pull/3380 is merged
|
||||
// There's also a test in clone.rs you need to turn too
|
||||
// There's also a test in clone.rs you need to turn too
|
||||
async fn kcl_test_execute() {
|
||||
super::execute(TEST_NAME, true).await
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Run all the KCL samples in the `kcl_samples` directory.
|
||||
use std::{
|
||||
fs,
|
||||
panic::{catch_unwind, AssertUnwindSafe},
|
||||
panic::{AssertUnwindSafe, catch_unwind},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
@ -86,7 +86,11 @@ fn test_after_engine_ensure_kcl_samples_manifest_etc() {
|
||||
.into_iter()
|
||||
.filter(|name| !input_names.contains(name))
|
||||
.collect::<Vec<_>>();
|
||||
assert!(missing.is_empty(), "Expected input kcl-samples for the following. If these are no longer tests, delete the expected output directories for them in {}: {missing:?}", OUTPUTS_DIR.to_string_lossy());
|
||||
assert!(
|
||||
missing.is_empty(),
|
||||
"Expected input kcl-samples for the following. If these are no longer tests, delete the expected output directories for them in {}: {missing:?}",
|
||||
OUTPUTS_DIR.to_string_lossy()
|
||||
);
|
||||
|
||||
// We want to move the screenshot for the inputs to the public/kcl-samples
|
||||
// directory so that they can be used as inputs for the next run.
|
||||
@ -189,7 +193,7 @@ fn kcl_samples_inputs() -> Vec<Test> {
|
||||
let entry_point = if main_kcl_path.exists() {
|
||||
main_kcl_path
|
||||
} else {
|
||||
panic!("No main.kcl found in {:?}", sub_dir);
|
||||
panic!("No main.kcl found in {sub_dir:?}");
|
||||
};
|
||||
tests.push(test(&dir_name_str, entry_point));
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Standard library appearance.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd};
|
||||
use kittycad_modeling_cmds::{self as kcmc, shared::Color};
|
||||
use regex::Regex;
|
||||
use rgba_simple::Hex;
|
||||
@ -10,8 +10,8 @@ use super::args::TyF64;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{ArrayLen, RuntimeType},
|
||||
ExecState, KclValue, SolidOrImportedGeometry,
|
||||
types::{ArrayLen, RuntimeType},
|
||||
},
|
||||
std::Args,
|
||||
};
|
||||
@ -63,7 +63,7 @@ pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclVal
|
||||
// Make sure the color if set is valid.
|
||||
if !HEX_REGEX.is_match(&color) {
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!("Invalid hex color (`{}`), try something like `#fff000`", color),
|
||||
format!("Invalid hex color (`{color}`), try something like `#fff000`"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
}
|
||||
|
@ -7,12 +7,13 @@ use serde::Serialize;
|
||||
use super::fillet::EdgeReference;
|
||||
pub use crate::execution::fn_call::Args;
|
||||
use crate::{
|
||||
ModuleId,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
kcl_value::FunctionSource,
|
||||
types::{NumericType, PrimitiveType, RuntimeType, UnitAngle, UnitLen, UnitType},
|
||||
ExecState, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, PlaneInfo, Sketch, SketchSurface, Solid,
|
||||
TagIdentifier,
|
||||
kcl_value::FunctionSource,
|
||||
types::{NumericType, PrimitiveType, RuntimeType, UnitAngle, UnitLen, UnitType},
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
source_range::SourceRange,
|
||||
@ -21,7 +22,6 @@ use crate::{
|
||||
sketch::FaceTag,
|
||||
sweep::SweepPath,
|
||||
},
|
||||
ModuleId,
|
||||
};
|
||||
|
||||
const ERROR_STRING_SKETCH_TO_SOLID_HELPER: &str =
|
||||
@ -97,8 +97,8 @@ impl JsonSchema for TyF64 {
|
||||
"TyF64".to_string()
|
||||
}
|
||||
|
||||
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
gen.subschema_for::<f64>()
|
||||
fn json_schema(r#gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
r#gen.subschema_for::<f64>()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use crate::{
|
||||
ExecutorContext,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
ExecState,
|
||||
fn_call::{Arg, Args, KwArgs},
|
||||
kcl_value::{FunctionSource, KclValue},
|
||||
types::RuntimeType,
|
||||
ExecState,
|
||||
},
|
||||
source_range::SourceRange,
|
||||
ExecutorContext,
|
||||
};
|
||||
|
||||
/// Apply a function to each element of an array.
|
||||
|
@ -5,14 +5,14 @@ use anyhow::Result;
|
||||
use super::args::TyF64;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{types::RuntimeType, ExecState, KclValue},
|
||||
execution::{ExecState, KclValue, types::RuntimeType},
|
||||
std::Args,
|
||||
};
|
||||
|
||||
async fn _assert(value: bool, message: &str, args: &Args) -> Result<(), KclError> {
|
||||
if !value {
|
||||
return Err(KclError::new_type(KclErrorDetails::new(
|
||||
format!("assert failed: {}", message),
|
||||
format!("assert failed: {message}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
//! Standard library chamfers.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::CutType, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, shared::CutType};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
|
||||
use super::args::TyF64;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::RuntimeType, ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, ModelingCmdMeta,
|
||||
Solid,
|
||||
ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, ModelingCmdMeta, Solid,
|
||||
types::RuntimeType,
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::{fillet::EdgeReference, Args},
|
||||
std::{Args, fillet::EdgeReference},
|
||||
};
|
||||
|
||||
pub(crate) const DEFAULT_TOLERANCE: f64 = 0.0000001;
|
||||
|
@ -4,10 +4,9 @@ use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{
|
||||
each_cmd as mcmd,
|
||||
ok_response::{output::EntityGetAllChildUuids, OkModelingCmdResponse},
|
||||
ModelingCmd, each_cmd as mcmd,
|
||||
ok_response::{OkModelingCmdResponse, output::EntityGetAllChildUuids},
|
||||
websocket::OkWebSocketResponseData,
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds::{self as kcmc};
|
||||
|
||||
@ -15,11 +14,11 @@ use super::extrude::do_post_extrude;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
ExecState, GeometryWithImportedGeometry, KclValue, ModelingCmdMeta, Sketch, Solid,
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::{extrude::NamedCapTags, Args},
|
||||
std::{Args, extrude::NamedCapTags},
|
||||
};
|
||||
|
||||
/// Clone a sketch or solid.
|
||||
@ -91,7 +90,7 @@ async fn inner_clone(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
KclError::new_internal(KclErrorDetails::new(
|
||||
format!("failed to fix tags and references: {:?}", e),
|
||||
format!("failed to fix tags and references: {e:?}"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -320,10 +319,10 @@ clonedCube = clone(cube)
|
||||
assert_ne!(cube, cloned_cube);
|
||||
|
||||
let KclValue::Sketch { value: cube } = cube else {
|
||||
panic!("Expected a sketch, got: {:?}", cube);
|
||||
panic!("Expected a sketch, got: {cube:?}");
|
||||
};
|
||||
let KclValue::Sketch { value: cloned_cube } = cloned_cube else {
|
||||
panic!("Expected a sketch, got: {:?}", cloned_cube);
|
||||
panic!("Expected a sketch, got: {cloned_cube:?}");
|
||||
};
|
||||
|
||||
assert_ne!(cube.id, cloned_cube.id);
|
||||
@ -369,10 +368,10 @@ clonedCube = clone(cube)
|
||||
assert_ne!(cube, cloned_cube);
|
||||
|
||||
let KclValue::Solid { value: cube } = cube else {
|
||||
panic!("Expected a solid, got: {:?}", cube);
|
||||
panic!("Expected a solid, got: {cube:?}");
|
||||
};
|
||||
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
|
||||
panic!("Expected a solid, got: {:?}", cloned_cube);
|
||||
panic!("Expected a solid, got: {cloned_cube:?}");
|
||||
};
|
||||
|
||||
assert_ne!(cube.id, cloned_cube.id);
|
||||
@ -427,10 +426,10 @@ clonedCube = clone(cube)
|
||||
assert_ne!(cube, cloned_cube);
|
||||
|
||||
let KclValue::Sketch { value: cube } = cube else {
|
||||
panic!("Expected a sketch, got: {:?}", cube);
|
||||
panic!("Expected a sketch, got: {cube:?}");
|
||||
};
|
||||
let KclValue::Sketch { value: cloned_cube } = cloned_cube else {
|
||||
panic!("Expected a sketch, got: {:?}", cloned_cube);
|
||||
panic!("Expected a sketch, got: {cloned_cube:?}");
|
||||
};
|
||||
|
||||
assert_ne!(cube.id, cloned_cube.id);
|
||||
@ -483,10 +482,10 @@ clonedCube = clone(cube)
|
||||
assert_ne!(cube, cloned_cube);
|
||||
|
||||
let KclValue::Solid { value: cube } = cube else {
|
||||
panic!("Expected a solid, got: {:?}", cube);
|
||||
panic!("Expected a solid, got: {cube:?}");
|
||||
};
|
||||
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
|
||||
panic!("Expected a solid, got: {:?}", cloned_cube);
|
||||
panic!("Expected a solid, got: {cloned_cube:?}");
|
||||
};
|
||||
|
||||
assert_ne!(cube.id, cloned_cube.id);
|
||||
@ -555,10 +554,10 @@ clonedCube = clone(cube)
|
||||
assert_ne!(cube, cloned_cube);
|
||||
|
||||
let KclValue::Solid { value: cube } = cube else {
|
||||
panic!("Expected a solid, got: {:?}", cube);
|
||||
panic!("Expected a solid, got: {cube:?}");
|
||||
};
|
||||
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
|
||||
panic!("Expected a solid, got: {:?}", cloned_cube);
|
||||
panic!("Expected a solid, got: {cloned_cube:?}");
|
||||
};
|
||||
|
||||
assert_ne!(cube.id, cloned_cube.id);
|
||||
@ -655,10 +654,10 @@ clonedCube = clone(cube)
|
||||
assert_ne!(cube, cloned_cube);
|
||||
|
||||
let KclValue::Solid { value: cube } = cube else {
|
||||
panic!("Expected a solid, got: {:?}", cube);
|
||||
panic!("Expected a solid, got: {cube:?}");
|
||||
};
|
||||
let KclValue::Solid { value: cloned_cube } = cloned_cube else {
|
||||
panic!("Expected a solid, got: {:?}", cloned_cube);
|
||||
panic!("Expected a solid, got: {cloned_cube:?}");
|
||||
};
|
||||
|
||||
assert_ne!(cube.id, cloned_cube.id);
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Constructive Solid Geometry (CSG) operations.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit};
|
||||
use kittycad_modeling_cmds::{
|
||||
self as kcmc,
|
||||
ok_response::OkModelingCmdResponse,
|
||||
@ -9,11 +9,11 @@ use kittycad_modeling_cmds::{
|
||||
websocket::OkWebSocketResponseData,
|
||||
};
|
||||
|
||||
use super::{args::TyF64, DEFAULT_TOLERANCE_MM};
|
||||
use super::{DEFAULT_TOLERANCE_MM, args::TyF64};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{types::RuntimeType, ExecState, KclValue, ModelingCmdMeta, Solid},
|
||||
std::{patterns::GeometryTrait, Args},
|
||||
execution::{ExecState, KclValue, ModelingCmdMeta, Solid, types::RuntimeType},
|
||||
std::{Args, patterns::GeometryTrait},
|
||||
};
|
||||
|
||||
/// Union two or more solids into a single solid.
|
||||
|
@ -1,18 +1,18 @@
|
||||
//! Edge helper functions.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, ok_response::OkModelingCmdResponse, websocket::OkWebSocketResponseData, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, ok_response::OkModelingCmdResponse, websocket::OkWebSocketResponseData};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{ArrayLen, RuntimeType},
|
||||
ExecState, ExtrudeSurface, KclValue, ModelingCmdMeta, TagIdentifier,
|
||||
types::{ArrayLen, RuntimeType},
|
||||
},
|
||||
std::{sketch::FaceTag, Args},
|
||||
SourceRange,
|
||||
std::{Args, sketch::FaceTag},
|
||||
};
|
||||
|
||||
/// Get the opposite edge to the edge given.
|
||||
@ -55,7 +55,7 @@ async fn inner_get_opposite_edge(
|
||||
} = &resp
|
||||
else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("mcmd::Solid3dGetOppositeEdge response was not as expected: {:?}", resp),
|
||||
format!("mcmd::Solid3dGetOppositeEdge response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
@ -104,10 +104,7 @@ async fn inner_get_next_adjacent_edge(
|
||||
} = &resp
|
||||
else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!(
|
||||
"mcmd::Solid3dGetNextAdjacentEdge response was not as expected: {:?}",
|
||||
resp
|
||||
),
|
||||
format!("mcmd::Solid3dGetNextAdjacentEdge response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
@ -160,10 +157,7 @@ async fn inner_get_previous_adjacent_edge(
|
||||
} = &resp
|
||||
else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!(
|
||||
"mcmd::Solid3dGetPrevAdjacentEdge response was not as expected: {:?}",
|
||||
resp
|
||||
),
|
||||
format!("mcmd::Solid3dGetPrevAdjacentEdge response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
@ -259,7 +253,7 @@ async fn inner_get_common_edge(
|
||||
} = &resp
|
||||
else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("mcmd::Solid3dGetCommonEdge response was not as expected: {:?}", resp),
|
||||
format!("mcmd::Solid3dGetCommonEdge response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
|
@ -4,13 +4,12 @@ use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{
|
||||
each_cmd as mcmd,
|
||||
ModelingCmd, each_cmd as mcmd,
|
||||
length_unit::LengthUnit,
|
||||
ok_response::OkModelingCmdResponse,
|
||||
output::ExtrusionFaceInfo,
|
||||
shared::{ExtrusionFaceCapType, Opposite},
|
||||
websocket::{ModelingCmdReq, OkWebSocketResponseData},
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds::{
|
||||
self as kcmc,
|
||||
@ -18,12 +17,12 @@ use kittycad_modeling_cmds::{
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{args::TyF64, utils::point_to_mm, DEFAULT_TOLERANCE_MM};
|
||||
use super::{DEFAULT_TOLERANCE_MM, args::TyF64, utils::point_to_mm};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::RuntimeType, ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, ModelingCmdMeta, Path, Sketch,
|
||||
SketchSurface, Solid,
|
||||
ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, ModelingCmdMeta, Path, Sketch, SketchSurface, Solid,
|
||||
types::RuntimeType,
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::Args,
|
||||
|
@ -2,20 +2,20 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use indexmap::IndexMap;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::CutType, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, shared::CutType};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{args::TyF64, DEFAULT_TOLERANCE_MM};
|
||||
use super::{DEFAULT_TOLERANCE_MM, args::TyF64};
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::RuntimeType, EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, ModelingCmdMeta,
|
||||
Solid, TagIdentifier,
|
||||
EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, ModelingCmdMeta, Solid, TagIdentifier,
|
||||
types::RuntimeType,
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::Args,
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
/// A tag or a uuid of an edge.
|
||||
|
@ -1,17 +1,17 @@
|
||||
//! Standard library helices.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, shared::Angle};
|
||||
use kittycad_modeling_cmds::{self as kcmc, shared::Point3d};
|
||||
|
||||
use super::args::TyF64;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{PrimitiveType, RuntimeType},
|
||||
ExecState, Helix as HelixValue, KclValue, ModelingCmdMeta, Solid,
|
||||
types::{PrimitiveType, RuntimeType},
|
||||
},
|
||||
std::{axis_or_reference::Axis3dOrEdgeReference, Args},
|
||||
std::{Args, axis_or_reference::Axis3dOrEdgeReference},
|
||||
};
|
||||
|
||||
/// Create a helix.
|
||||
|
@ -3,18 +3,18 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
|
||||
use super::{args::TyF64, DEFAULT_TOLERANCE_MM};
|
||||
use super::{DEFAULT_TOLERANCE_MM, args::TyF64};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{NumericType, RuntimeType},
|
||||
ExecState, KclValue, ModelingCmdMeta, Sketch, Solid,
|
||||
types::{NumericType, RuntimeType},
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::{extrude::do_post_extrude, Args},
|
||||
std::{Args, extrude::do_post_extrude},
|
||||
};
|
||||
|
||||
const DEFAULT_V_DEGREE: u32 = 2;
|
||||
|
@ -3,13 +3,13 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{
|
||||
CompilationError,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{ArrayLen, NumericType, RuntimeType},
|
||||
ExecState, KclValue,
|
||||
types::{ArrayLen, NumericType, RuntimeType},
|
||||
},
|
||||
std::args::{Args, TyF64},
|
||||
CompilationError,
|
||||
};
|
||||
|
||||
/// Compute the remainder after dividing `num` by `div`.
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Standard library mirror.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd};
|
||||
use kittycad_modeling_cmds::{
|
||||
self as kcmc, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, shared::Point3d,
|
||||
websocket::OkWebSocketResponseData,
|
||||
@ -10,10 +10,10 @@ use kittycad_modeling_cmds::{
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{PrimitiveType, RuntimeType},
|
||||
ExecState, KclValue, Sketch,
|
||||
types::{PrimitiveType, RuntimeType},
|
||||
},
|
||||
std::{axis_or_reference::Axis2dOrEdgeReference, Args},
|
||||
std::{Args, axis_or_reference::Axis2dOrEdgeReference},
|
||||
};
|
||||
|
||||
/// Mirror a sketch.
|
||||
@ -84,14 +84,14 @@ async fn inner_mirror_2d(
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
"No edges found in mirror info".to_string(),
|
||||
vec![args.source_range],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
} else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("EntityMirror response was not as expected: {:?}", resp),
|
||||
format!("EntityMirror response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
@ -127,14 +127,14 @@ async fn inner_mirror_2d(
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
"No edges found in mirror info".to_string(),
|
||||
vec![args.source_range],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
} else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("EntityMirrorAcrossEdge response was not as expected: {:?}", resp),
|
||||
format!("EntityMirrorAcrossEdge response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
|
@ -31,7 +31,7 @@ pub use args::Args;
|
||||
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
execution::{types::PrimitiveType, ExecState, KclValue},
|
||||
execution::{ExecState, KclValue, types::PrimitiveType},
|
||||
};
|
||||
|
||||
pub type StdFn = fn(
|
||||
|
@ -4,8 +4,8 @@ use std::cmp::Ordering;
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{
|
||||
each_cmd as mcmd, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, shared::Transform,
|
||||
websocket::OkWebSocketResponseData, ModelingCmd,
|
||||
ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, ok_response::OkModelingCmdResponse, shared::Transform,
|
||||
websocket::OkWebSocketResponseData,
|
||||
};
|
||||
use kittycad_modeling_cmds::{
|
||||
self as kcmc,
|
||||
@ -16,19 +16,19 @@ use uuid::Uuid;
|
||||
|
||||
use super::axis_or_reference::Axis3dOrPoint3d;
|
||||
use crate::{
|
||||
ExecutorContext, SourceRange,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
ExecState, Geometries, Geometry, KclObjectFields, KclValue, Sketch, Solid,
|
||||
fn_call::{Arg, Args, KwArgs},
|
||||
kcl_value::FunctionSource,
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
ExecState, Geometries, Geometry, KclObjectFields, KclValue, Sketch, Solid,
|
||||
},
|
||||
std::{
|
||||
args::TyF64,
|
||||
axis_or_reference::Axis2dOrPoint2d,
|
||||
utils::{point_3d_to_mm, point_to_mm},
|
||||
},
|
||||
ExecutorContext, SourceRange,
|
||||
};
|
||||
|
||||
const MUST_HAVE_ONE_INSTANCE: &str = "There must be at least 1 instance of your geometry";
|
||||
@ -176,7 +176,7 @@ async fn send_pattern_transform<T: GeometryTrait>(
|
||||
&mock_ids
|
||||
} else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("EntityLinearPattern response was not as expected: {:?}", resp),
|
||||
format!("EntityLinearPattern response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
@ -244,7 +244,7 @@ async fn make_transform<T: GeometryTrait>(
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
"Transform function must return a transform object".to_string(),
|
||||
source_ranges.clone(),
|
||||
)))
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
@ -970,7 +970,7 @@ async fn pattern_circular(
|
||||
&mock_ids
|
||||
} else {
|
||||
return Err(KclError::new_engine(KclErrorDetails::new(
|
||||
format!("EntityCircularPattern response was not as expected: {:?}", resp),
|
||||
format!("EntityCircularPattern response was not as expected: {resp:?}"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
};
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! Standard library plane helpers.
|
||||
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Color, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, shared::Color};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
|
||||
use super::{args::TyF64, sketch::PlaneData};
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
execution::{types::RuntimeType, ExecState, KclValue, ModelingCmdMeta, Plane, PlaneType},
|
||||
execution::{ExecState, KclValue, ModelingCmdMeta, Plane, PlaneType, types::RuntimeType},
|
||||
std::Args,
|
||||
};
|
||||
|
||||
|
@ -2,22 +2,21 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{
|
||||
each_cmd as mcmd,
|
||||
ModelingCmd, each_cmd as mcmd,
|
||||
length_unit::LengthUnit,
|
||||
shared::{Angle, Opposite},
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds::{self as kcmc, shared::Point3d};
|
||||
|
||||
use super::{args::TyF64, DEFAULT_TOLERANCE_MM};
|
||||
use super::{DEFAULT_TOLERANCE_MM, args::TyF64};
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
ExecState, KclValue, ModelingCmdMeta, Sketch, Solid,
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, Args},
|
||||
std::{Args, axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude},
|
||||
};
|
||||
|
||||
extern crate nalgebra_glm as glm;
|
||||
@ -76,7 +75,7 @@ async fn inner_revolve(
|
||||
// nice and we use the other data in the docs, so we still need use the derive above for the json schema.
|
||||
if !(-360.0..=360.0).contains(&angle) || angle == 0.0 {
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!("Expected angle to be between -360 and 360 and not 0, found `{}`", angle),
|
||||
format!("Expected angle to be between -360 and 360 and not 0, found `{angle}`"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
}
|
||||
@ -89,8 +88,7 @@ async fn inner_revolve(
|
||||
if !(-360.0..=360.0).contains(&bidirectional_angle) || bidirectional_angle == 0.0 {
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!(
|
||||
"Expected bidirectional angle to be between -360 and 360 and not 0, found `{}`",
|
||||
bidirectional_angle
|
||||
"Expected bidirectional angle to be between -360 and 360 and not 0, found `{bidirectional_angle}`"
|
||||
),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
@ -100,10 +98,7 @@ async fn inner_revolve(
|
||||
let ang = angle.signum() * bidirectional_angle + angle;
|
||||
if !(-360.0..=360.0).contains(&ang) {
|
||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||
format!(
|
||||
"Combined angle and bidirectional must be between -360 and 360, found '{}'",
|
||||
ang
|
||||
),
|
||||
format!("Combined angle and bidirectional must be between -360 and 360, found '{ang}'"),
|
||||
vec![args.source_range],
|
||||
)));
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ use super::utils::untype_point;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
ExecState, KclValue, Sketch, TagIdentifier,
|
||||
types::{NumericType, PrimitiveType, RuntimeType},
|
||||
},
|
||||
std::{args::TyF64, utils::between, Args},
|
||||
std::{Args, args::TyF64, utils::between},
|
||||
};
|
||||
|
||||
/// Returns the point at the end of the given segment.
|
||||
@ -25,7 +25,7 @@ fn inner_segment_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -48,7 +48,7 @@ fn inner_segment_end_x(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -68,7 +68,7 @@ fn inner_segment_end_y(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -88,7 +88,7 @@ fn inner_segment_start(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -111,7 +111,7 @@ fn inner_segment_start_x(tag: &TagIdentifier, exec_state: &mut ExecState, args:
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -131,7 +131,7 @@ fn inner_segment_start_y(tag: &TagIdentifier, exec_state: &mut ExecState, args:
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -152,7 +152,7 @@ fn inner_last_segment_x(sketch: Sketch, args: Args) -> Result<TyF64, KclError> {
|
||||
.last()
|
||||
.ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a Sketch with at least one segment, found `{:?}`", sketch),
|
||||
format!("Expected a Sketch with at least one segment, found `{sketch:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?
|
||||
@ -175,7 +175,7 @@ fn inner_last_segment_y(sketch: Sketch, args: Args) -> Result<TyF64, KclError> {
|
||||
.last()
|
||||
.ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a Sketch with at least one segment, found `{:?}`", sketch),
|
||||
format!("Expected a Sketch with at least one segment, found `{sketch:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?
|
||||
@ -195,7 +195,7 @@ fn inner_segment_length(tag: &TagIdentifier, exec_state: &mut ExecState, args: A
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -215,7 +215,7 @@ fn inner_segment_angle(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
@ -237,7 +237,7 @@ async fn inner_tangent_to_end(tag: &TagIdentifier, exec_state: &mut ExecState, a
|
||||
let line = args.get_tag_engine_info(exec_state, tag)?;
|
||||
let path = line.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected a line segment with a path, found `{:?}`", line),
|
||||
format!("Expected a line segment with a path, found `{line:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
|
@ -2,10 +2,9 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{
|
||||
each_cmd as mcmd,
|
||||
ModelingCmd, each_cmd as mcmd,
|
||||
length_unit::LengthUnit,
|
||||
shared::{Angle, Point2d as KPoint2d},
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use kittycad_modeling_cmds::shared::PathSegment;
|
||||
@ -17,17 +16,17 @@ use super::{
|
||||
utils::{point_to_len_unit, point_to_mm, point_to_typed, untype_point, untyped_point_to_mm},
|
||||
};
|
||||
use crate::{
|
||||
SourceRange,
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{RuntimeType, UnitLen},
|
||||
BasePath, ExecState, GeoMeta, KclValue, ModelingCmdMeta, Path, Sketch, SketchSurface,
|
||||
types::{RuntimeType, UnitLen},
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::{
|
||||
utils::{calculate_circle_center, distance},
|
||||
Args,
|
||||
utils::{calculate_circle_center, distance},
|
||||
},
|
||||
SourceRange,
|
||||
};
|
||||
|
||||
/// A sketch surface or a sketch.
|
||||
|
@ -1,17 +1,17 @@
|
||||
//! Standard library shells.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
|
||||
use super::args::TyF64;
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{ArrayLen, RuntimeType},
|
||||
ExecState, KclValue, Solid,
|
||||
types::{ArrayLen, RuntimeType},
|
||||
},
|
||||
std::{sketch::FaceTag, Args},
|
||||
std::{Args, sketch::FaceTag},
|
||||
};
|
||||
|
||||
/// Create a shell.
|
||||
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||
use indexmap::IndexMap;
|
||||
use kcmc::shared::Point2d as KPoint2d; // Point2d is already defined in this pkg, to impl ts_rs traits.
|
||||
use kcmc::shared::Point3d as KPoint3d; // Point3d is already defined in this pkg, to impl ts_rs traits.
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, websocket::ModelingCmdReq, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, websocket::ModelingCmdReq};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
use kittycad_modeling_cmds::shared::PathSegment;
|
||||
use parse_display::{Display, FromStr};
|
||||
@ -17,17 +17,16 @@ use crate::execution::{Artifact, ArtifactId, CodeRef, StartSketchOnFace, StartSk
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{ArrayLen, NumericType, PrimitiveType, RuntimeType, UnitLen},
|
||||
BasePath, ExecState, Face, GeoMeta, KclValue, ModelingCmdMeta, Path, Plane, PlaneInfo, Point2d, Sketch,
|
||||
SketchSurface, Solid, TagEngineInfo, TagIdentifier,
|
||||
types::{ArrayLen, NumericType, PrimitiveType, RuntimeType, UnitLen},
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::{
|
||||
args::{Args, TyF64},
|
||||
utils::{
|
||||
arc_center_and_end, get_tangential_arc_to_info, get_x_component, get_y_component,
|
||||
TangentialArcInfoInput, arc_center_and_end, get_tangential_arc_to_info, get_x_component, get_y_component,
|
||||
intersection_with_parallel_line, point_to_len_unit, point_to_mm, untyped_point_to_mm,
|
||||
TangentialArcInfoInput,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -45,7 +44,7 @@ pub enum FaceTag {
|
||||
impl std::fmt::Display for FaceTag {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
FaceTag::Tag(t) => write!(f, "{}", t),
|
||||
FaceTag::Tag(t) => write!(f, "{t}"),
|
||||
FaceTag::StartOrEnd(StartOrEnd::Start) => write!(f, "start"),
|
||||
FaceTag::StartOrEnd(StartOrEnd::End) => write!(f, "end"),
|
||||
}
|
||||
@ -62,7 +61,7 @@ impl FaceTag {
|
||||
must_be_planar: bool,
|
||||
) -> Result<uuid::Uuid, KclError> {
|
||||
match self {
|
||||
FaceTag::Tag(ref t) => args.get_adjacent_face_to_tag(exec_state, t, must_be_planar).await,
|
||||
FaceTag::Tag(t) => args.get_adjacent_face_to_tag(exec_state, t, must_be_planar).await,
|
||||
FaceTag::StartOrEnd(StartOrEnd::Start) => solid.start_cap_id.ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
"Expected a start face".to_string(),
|
||||
@ -737,7 +736,7 @@ pub async fn inner_angled_line_that_intersects(
|
||||
let intersect_path = args.get_tag_engine_info(exec_state, &intersect_tag)?;
|
||||
let path = intersect_path.path.clone().ok_or_else(|| {
|
||||
KclError::new_type(KclErrorDetails::new(
|
||||
format!("Expected an intersect path with a path, found `{:?}`", intersect_path),
|
||||
format!("Expected an intersect path with a path, found `{intersect_path:?}`"),
|
||||
vec![args.source_range],
|
||||
))
|
||||
})?;
|
||||
|
@ -1,20 +1,20 @@
|
||||
//! Standard library sweep.
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit};
|
||||
use kittycad_modeling_cmds::{self as kcmc, shared::RelativeTo};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{args::TyF64, DEFAULT_TOLERANCE_MM};
|
||||
use super::{DEFAULT_TOLERANCE_MM, args::TyF64};
|
||||
use crate::{
|
||||
errors::KclError,
|
||||
execution::{
|
||||
types::{NumericType, RuntimeType},
|
||||
ExecState, Helix, KclValue, ModelingCmdMeta, Sketch, Solid,
|
||||
types::{NumericType, RuntimeType},
|
||||
},
|
||||
parsing::ast::types::TagNode,
|
||||
std::{extrude::do_post_extrude, Args},
|
||||
std::{Args, extrude::do_post_extrude},
|
||||
};
|
||||
|
||||
/// A path to sweep along.
|
||||
@ -79,7 +79,7 @@ async fn inner_sweep(
|
||||
return Err(KclError::new_syntax(crate::errors::KclErrorDetails::new(
|
||||
"If you provide relativeTo, it must either be 'sketchPlane' or 'trajectoryCurve'".to_owned(),
|
||||
vec![args.source_range],
|
||||
)))
|
||||
)));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,21 +2,20 @@
|
||||
|
||||
use anyhow::Result;
|
||||
use kcmc::{
|
||||
each_cmd as mcmd,
|
||||
ModelingCmd, each_cmd as mcmd,
|
||||
length_unit::LengthUnit,
|
||||
shared,
|
||||
shared::{Point3d, Point4d},
|
||||
ModelingCmd,
|
||||
};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
|
||||
use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
execution::{
|
||||
types::{PrimitiveType, RuntimeType},
|
||||
ExecState, KclValue, SolidOrSketchOrImportedGeometry,
|
||||
types::{PrimitiveType, RuntimeType},
|
||||
},
|
||||
std::{args::TyF64, axis_or_reference::Axis3dOrPoint3d, Args},
|
||||
std::{Args, args::TyF64, axis_or_reference::Axis3dOrPoint3d},
|
||||
};
|
||||
|
||||
/// Scale a solid or a sketch.
|
||||
|
@ -88,11 +88,7 @@ pub(crate) fn delta(from_angle: Angle, to_angle: Angle) -> Angle {
|
||||
|
||||
pub(crate) fn normalize_rad(angle: f64) -> f64 {
|
||||
let draft = angle % (2.0 * PI);
|
||||
if draft < 0.0 {
|
||||
draft + 2.0 * PI
|
||||
} else {
|
||||
draft
|
||||
}
|
||||
if draft < 0.0 { draft + 2.0 * PI } else { draft }
|
||||
}
|
||||
|
||||
fn calculate_intersection_of_two_lines(line1: &[Coords2d; 2], line2_angle: f64, line2_point: Coords2d) -> Coords2d {
|
||||
@ -174,8 +170,8 @@ pub(crate) fn arc_center_and_end(
|
||||
let end_angle = end_angle.to_radians();
|
||||
|
||||
let center = [
|
||||
-1.0 * (radius * libm::cos(start_angle) - from[0]),
|
||||
-1.0 * (radius * libm::sin(start_angle) - from[1]),
|
||||
-(radius * libm::cos(start_angle) - from[0]),
|
||||
-(radius * libm::sin(start_angle) - from[1]),
|
||||
];
|
||||
|
||||
let end = [
|
||||
@ -240,7 +236,7 @@ mod tests {
|
||||
use approx::assert_relative_eq;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::{calculate_circle_center, get_x_component, get_y_component, Angle};
|
||||
use super::{Angle, calculate_circle_center, get_x_component, get_y_component};
|
||||
|
||||
static EACH_QUAD: [(i32, [i32; 2]); 12] = [
|
||||
(-315, [1, 1]),
|
||||
|
@ -3,10 +3,10 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{
|
||||
ConnectionError, ExecError, KclError, KclErrorWithOutputs, Program,
|
||||
engine::new_zoo_client,
|
||||
errors::ExecErrorWithState,
|
||||
execution::{EnvironmentRef, ExecState, ExecutorContext, ExecutorSettings},
|
||||
ConnectionError, ExecError, KclError, KclErrorWithOutputs, Program,
|
||||
};
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
@ -64,7 +64,7 @@ pub async fn execute_and_snapshot_ast(
|
||||
// Close the context to avoid any resource leaks.
|
||||
ctx.close().await;
|
||||
return Err(ExecErrorWithState::new(
|
||||
ExecError::BadExport(format!("Export failed: {:?}", err)),
|
||||
ExecError::BadExport(format!("Export failed: {err:?}")),
|
||||
exec_state.clone(),
|
||||
));
|
||||
}
|
||||
@ -184,7 +184,7 @@ pub async fn execute_and_export_step(
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
return Err(ExecErrorWithState::new(
|
||||
ExecError::BadExport(format!("Export failed: {:?}", err)),
|
||||
ExecError::BadExport(format!("Export failed: {err:?}")),
|
||||
exec_state.clone(),
|
||||
));
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
use std::fmt::Write;
|
||||
|
||||
use crate::{
|
||||
KclError, ModuleId,
|
||||
parsing::{
|
||||
DeprecationKind, PIPE_OPERATOR,
|
||||
ast::types::{
|
||||
Annotation, ArrayExpression, ArrayRangeExpression, AscribedExpression, Associativity, BinaryExpression,
|
||||
BinaryOperator, BinaryPart, BodyItem, CallExpressionKw, CommentStyle, DefaultParamVal, Expr, FormatOptions,
|
||||
@ -10,9 +12,8 @@ use crate::{
|
||||
Parameter, PipeExpression, Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration,
|
||||
VariableKind,
|
||||
},
|
||||
deprecation, DeprecationKind, PIPE_OPERATOR,
|
||||
deprecation,
|
||||
},
|
||||
KclError, ModuleId,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -110,7 +111,7 @@ impl Program {
|
||||
let formatted = custom_white_space_or_comment.recast(options, indentation_level);
|
||||
if i == 0 && !formatted.trim().is_empty() {
|
||||
if let NonCodeValue::BlockComment { .. } = custom_white_space_or_comment.value {
|
||||
format!("\n{}", formatted)
|
||||
format!("\n{formatted}")
|
||||
} else {
|
||||
formatted
|
||||
}
|
||||
@ -127,7 +128,7 @@ impl Program {
|
||||
custom_white_space_or_comment
|
||||
};
|
||||
|
||||
let _ = write!(output, "{}{}{}", start_string, recast_str, end_string);
|
||||
let _ = write!(output, "{start_string}{recast_str}{end_string}");
|
||||
output
|
||||
})
|
||||
.trim()
|
||||
@ -135,7 +136,7 @@ impl Program {
|
||||
|
||||
// Insert a final new line if the user wants it.
|
||||
if options.insert_final_newline && !result.is_empty() {
|
||||
format!("{}\n", result)
|
||||
format!("{result}\n")
|
||||
} else {
|
||||
result
|
||||
}
|
||||
@ -158,16 +159,16 @@ impl Node<NonCodeNode> {
|
||||
NonCodeValue::InlineComment {
|
||||
value,
|
||||
style: CommentStyle::Line,
|
||||
} => format!(" // {}\n", value),
|
||||
} => format!(" // {value}\n"),
|
||||
NonCodeValue::InlineComment {
|
||||
value,
|
||||
style: CommentStyle::Block,
|
||||
} => format!(" /* {} */", value),
|
||||
} => format!(" /* {value} */"),
|
||||
NonCodeValue::BlockComment { value, style } => match style {
|
||||
CommentStyle::Block => format!("{}/* {} */", indentation, value),
|
||||
CommentStyle::Block => format!("{indentation}/* {value} */"),
|
||||
CommentStyle::Line => {
|
||||
if value.trim().is_empty() {
|
||||
format!("{}//\n", indentation)
|
||||
format!("{indentation}//\n")
|
||||
} else {
|
||||
format!("{}// {}\n", indentation, value.trim())
|
||||
}
|
||||
@ -176,10 +177,10 @@ impl Node<NonCodeNode> {
|
||||
NonCodeValue::NewLineBlockComment { value, style } => {
|
||||
let add_start_new_line = if self.start == 0 { "" } else { "\n\n" };
|
||||
match style {
|
||||
CommentStyle::Block => format!("{}{}/* {} */\n", add_start_new_line, indentation, value),
|
||||
CommentStyle::Block => format!("{add_start_new_line}{indentation}/* {value} */\n"),
|
||||
CommentStyle::Line => {
|
||||
if value.trim().is_empty() {
|
||||
format!("{}{}//\n", add_start_new_line, indentation)
|
||||
format!("{add_start_new_line}{indentation}//\n")
|
||||
} else {
|
||||
format!("{}{}// {}\n", add_start_new_line, indentation, value.trim())
|
||||
}
|
||||
@ -241,7 +242,7 @@ impl ImportStatement {
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let mut string = format!("{}{}import ", vis, indentation);
|
||||
let mut string = format!("{vis}{indentation}import ");
|
||||
match &self.selector {
|
||||
ImportSelector::List { items } => {
|
||||
for (i, item) in items.iter().enumerate() {
|
||||
@ -291,7 +292,7 @@ impl Expr {
|
||||
Expr::BinaryExpression(bin_exp) => bin_exp.recast(options, indentation_level, ctxt),
|
||||
Expr::ArrayExpression(array_exp) => array_exp.recast(options, indentation_level, ctxt),
|
||||
Expr::ArrayRangeExpression(range_exp) => range_exp.recast(options, indentation_level, ctxt),
|
||||
Expr::ObjectExpression(ref obj_exp) => obj_exp.recast(options, indentation_level, ctxt),
|
||||
Expr::ObjectExpression(obj_exp) => obj_exp.recast(options, indentation_level, ctxt),
|
||||
Expr::MemberExpression(mem_exp) => mem_exp.recast(options, indentation_level, ctxt),
|
||||
Expr::Literal(literal) => literal.recast(),
|
||||
Expr::FunctionExpression(func_exp) => {
|
||||
@ -702,13 +703,7 @@ impl MemberExpression {
|
||||
|
||||
impl BinaryExpression {
|
||||
fn recast(&self, options: &FormatOptions, _indentation_level: usize, ctxt: ExprContext) -> String {
|
||||
let maybe_wrap_it = |a: String, doit: bool| -> String {
|
||||
if doit {
|
||||
format!("({})", a)
|
||||
} else {
|
||||
a
|
||||
}
|
||||
};
|
||||
let maybe_wrap_it = |a: String, doit: bool| -> String { if doit { format!("({a})") } else { a } };
|
||||
|
||||
// It would be better to always preserve the user's parentheses but since we've dropped that
|
||||
// info from the AST, we bracket expressions as necessary.
|
||||
@ -977,7 +972,7 @@ mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
use crate::{parsing::ast::types::FormatOptions, ModuleId};
|
||||
use crate::{ModuleId, parsing::ast::types::FormatOptions};
|
||||
|
||||
#[test]
|
||||
fn test_recast_annotations_without_body_items() {
|
||||
|
@ -289,9 +289,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
macro_rules! kcl {
|
||||
( $kcl:expr ) => {{
|
||||
$crate::parsing::top_level_parse($kcl).unwrap()
|
||||
}};
|
||||
( $kcl:expr_2021 ) => {{ $crate::parsing::top_level_parse($kcl).unwrap() }};
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -153,9 +153,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
macro_rules! kcl {
|
||||
( $kcl:expr ) => {{
|
||||
$crate::parsing::top_level_parse($kcl).unwrap()
|
||||
}};
|
||||
( $kcl:expr_2021 ) => {{ $crate::parsing::top_level_parse($kcl).unwrap() }};
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -57,9 +57,7 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
macro_rules! kcl {
|
||||
( $kcl:expr ) => {{
|
||||
$crate::parsing::top_level_parse($kcl).unwrap()
|
||||
}};
|
||||
( $kcl:expr_2021 ) => {{ $crate::parsing::top_level_parse($kcl).unwrap() }};
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -19,7 +19,7 @@ fn tokio() -> &'static tokio::runtime::Runtime {
|
||||
fn into_miette(error: kcl_lib::KclErrorWithOutputs, code: &str) -> PyErr {
|
||||
let report = error.clone().into_miette_report_with_outputs(code).unwrap();
|
||||
let report = miette::Report::new(report);
|
||||
pyo3::exceptions::PyException::new_err(format!("{:?}", report))
|
||||
pyo3::exceptions::PyException::new_err(format!("{report:?}"))
|
||||
}
|
||||
|
||||
fn into_miette_for_parse(filename: &str, input: &str, error: kcl_lib::KclError) -> PyErr {
|
||||
@ -29,7 +29,7 @@ fn into_miette_for_parse(filename: &str, input: &str, error: kcl_lib::KclError)
|
||||
filename: filename.to_string(),
|
||||
};
|
||||
let report = miette::Report::new(report);
|
||||
pyo3::exceptions::PyException::new_err(format!("{:?}", report))
|
||||
pyo3::exceptions::PyException::new_err(format!("{report:?}"))
|
||||
}
|
||||
|
||||
/// The variety of image formats snapshots may be exported to.
|
||||
@ -402,8 +402,7 @@ async fn execute_and_snapshot(path: String, image_format: ImageFormat) -> PyResu
|
||||
} = resp
|
||||
else {
|
||||
return Err(pyo3::exceptions::PyException::new_err(format!(
|
||||
"Unexpected response from engine: {:?}",
|
||||
resp
|
||||
"Unexpected response from engine: {resp:?}"
|
||||
)));
|
||||
};
|
||||
|
||||
@ -459,8 +458,7 @@ async fn execute_code_and_snapshot(code: String, image_format: ImageFormat) -> P
|
||||
} = resp
|
||||
else {
|
||||
return Err(pyo3::exceptions::PyException::new_err(format!(
|
||||
"Unexpected response from engine: {:?}",
|
||||
resp
|
||||
"Unexpected response from engine: {resp:?}"
|
||||
)));
|
||||
};
|
||||
|
||||
@ -510,8 +508,7 @@ async fn execute_and_export(path: String, export_format: FileExportFormat) -> Py
|
||||
|
||||
let kittycad_modeling_cmds::websocket::OkWebSocketResponseData::Export { files } = resp else {
|
||||
return Err(pyo3::exceptions::PyException::new_err(format!(
|
||||
"Unexpected response from engine: {:?}",
|
||||
resp
|
||||
"Unexpected response from engine: {resp:?}"
|
||||
)));
|
||||
};
|
||||
|
||||
@ -558,8 +555,7 @@ async fn execute_code_and_export(code: String, export_format: FileExportFormat)
|
||||
|
||||
let kittycad_modeling_cmds::websocket::OkWebSocketResponseData::Export { files } = resp else {
|
||||
return Err(pyo3::exceptions::PyException::new_err(format!(
|
||||
"Unexpected response from engine: {:?}",
|
||||
resp
|
||||
"Unexpected response from engine: {resp:?}"
|
||||
)));
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ impl EngineConnection {
|
||||
|
||||
fn handle_command(&self, cmd_id: &ModelingCmdId, cmd: &kcmc::ModelingCmd) -> (String, OkModelingCmdResponse) {
|
||||
let cpp_id = id_to_cpp(cmd_id);
|
||||
let cmd_id = format!("{}", cmd_id);
|
||||
let cmd_id = format!("{cmd_id}");
|
||||
let mut this_response = OkModelingCmdResponse::Empty {};
|
||||
|
||||
let new_code = match cmd {
|
||||
@ -86,7 +86,7 @@ impl EngineConnection {
|
||||
size,
|
||||
..
|
||||
}) => {
|
||||
let plane_id = format!("plane_{}", cpp_id);
|
||||
let plane_id = format!("plane_{cpp_id}");
|
||||
format!(
|
||||
r#"
|
||||
auto {plane_id} = make_shared<Object>("plane", glm::dvec3 {{ 0, 0, 0 }});
|
||||
@ -108,8 +108,8 @@ impl EngineConnection {
|
||||
)
|
||||
}
|
||||
kcmc::ModelingCmd::StartPath(kcmc::StartPath { .. }) => {
|
||||
let sketch_id = format!("sketch_{}", cpp_id);
|
||||
let path_id = format!("path_{}", cpp_id);
|
||||
let sketch_id = format!("sketch_{cpp_id}");
|
||||
let path_id = format!("path_{cpp_id}");
|
||||
format!(
|
||||
r#"
|
||||
auto {sketch_id} = make_shared<Object>("sketch", glm::dvec3 {{ 0, 0, 0 }});
|
||||
@ -178,7 +178,7 @@ impl EngineConnection {
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
format!("//{:?}", cmd)
|
||||
format!("//{cmd:?}")
|
||||
}
|
||||
},
|
||||
kcmc::ModelingCmd::ClosePath(kcmc::ClosePath { path_id }) => {
|
||||
@ -240,9 +240,8 @@ impl EngineConnection {
|
||||
}) => {
|
||||
format!(
|
||||
r#"
|
||||
//face info get {} {}
|
||||
"#,
|
||||
object_id, edge_id
|
||||
//face info get {object_id} {edge_id}
|
||||
"#
|
||||
)
|
||||
}
|
||||
kcmc::ModelingCmd::EntityCircularPattern(kcmc::EntityCircularPattern {
|
||||
@ -313,11 +312,11 @@ impl EngineConnection {
|
||||
// base_code.push_str(&repl_uuid_fix_code);
|
||||
|
||||
// base_code
|
||||
format!("//{:?}", cmd)
|
||||
format!("//{cmd:?}")
|
||||
}
|
||||
_ => {
|
||||
//helps us follow along with the currently unhandled engine commands
|
||||
format!("//{:?}", cmd)
|
||||
format!("//{cmd:?}")
|
||||
}
|
||||
};
|
||||
|
||||
@ -330,7 +329,7 @@ fn id_to_cpp(id: &ModelingCmdId) -> String {
|
||||
}
|
||||
|
||||
fn uuid_to_cpp(id: &uuid::Uuid) -> String {
|
||||
let str = format!("{}", id);
|
||||
let str = format!("{id}");
|
||||
str::replace(&str, "-", "_")
|
||||
}
|
||||
|
||||
|
@ -16,5 +16,5 @@ async fn main() {
|
||||
|
||||
let result = kcl_to_engine_core(&kcl).await.expect("kcl conversion");
|
||||
|
||||
println!("{}", result);
|
||||
println!("{result}");
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "1.87"
|
||||
channel = "1.88"
|
||||
components = ["clippy", "rustfmt"]
|
||||
|
Reference in New Issue
Block a user