2023-08-25 13:41:04 -07:00
|
|
|
//! Functions for generating docs for our stdlib functions.
|
|
|
|
|
2024-09-27 07:37:46 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
mod gen_std_tests;
|
2025-02-20 19:33:21 +13:00
|
|
|
pub mod kcl_doc;
|
2024-09-27 07:37:46 -07:00
|
|
|
|
2025-02-27 22:03:37 +13:00
|
|
|
use std::{
|
|
|
|
fmt::{self, Write},
|
|
|
|
path::Path,
|
|
|
|
};
|
2024-06-19 13:57:50 -07:00
|
|
|
|
2023-08-25 13:41:04 -07:00
|
|
|
use anyhow::Result;
|
2025-05-06 16:09:59 +12:00
|
|
|
use kcl_doc::ModData;
|
2025-05-13 08:29:38 +12:00
|
|
|
use parse_display::Display;
|
2023-09-05 16:02:27 -07:00
|
|
|
use schemars::JsonSchema;
|
2023-08-25 13:41:04 -07:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-09-05 16:02:27 -07:00
|
|
|
use tower_lsp::lsp_types::{
|
|
|
|
CompletionItem, CompletionItemKind, CompletionItemLabelDetails, Documentation, InsertTextFormat, MarkupContent,
|
|
|
|
MarkupKind, ParameterInformation, ParameterLabel, SignatureHelp, SignatureInformation,
|
|
|
|
};
|
2023-08-25 13:41:04 -07:00
|
|
|
|
2025-05-13 08:29:38 +12:00
|
|
|
use crate::execution::{types::NumericType, Sketch};
|
2025-02-20 10:12:37 +13:00
|
|
|
|
2025-05-06 16:09:59 +12:00
|
|
|
// These types are declared in (KCL) std.
|
2025-05-13 08:29:38 +12:00
|
|
|
const DECLARED_TYPES: [&str; 17] = [
|
|
|
|
"any",
|
|
|
|
"number",
|
|
|
|
"string",
|
|
|
|
"tag",
|
|
|
|
"bool",
|
|
|
|
"Sketch",
|
|
|
|
"Solid",
|
|
|
|
"Plane",
|
|
|
|
"Helix",
|
|
|
|
"Face",
|
|
|
|
"Edge",
|
|
|
|
"Point2d",
|
|
|
|
"Point3d",
|
|
|
|
"Axis2d",
|
|
|
|
"Axis3d",
|
|
|
|
"ImportedGeometry",
|
2025-05-13 14:59:23 +12:00
|
|
|
"fn",
|
2025-05-06 16:09:59 +12:00
|
|
|
];
|
|
|
|
|
2025-02-20 10:12:37 +13:00
|
|
|
lazy_static::lazy_static! {
|
|
|
|
static ref NUMERIC_TYPE_SCHEMA: schemars::schema::SchemaObject = {
|
|
|
|
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
|
|
|
settings.inline_subschemas = true;
|
|
|
|
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
|
|
|
generator.root_schema_for::<NumericType>().schema
|
|
|
|
};
|
|
|
|
}
|
2024-06-19 13:57:50 -07:00
|
|
|
|
2025-05-13 08:29:38 +12:00
|
|
|
/// The primitive types that can be used in a KCL file.
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, JsonSchema, Display)]
|
|
|
|
#[serde(rename_all = "lowercase")]
|
|
|
|
#[display(style = "lowercase")]
|
|
|
|
enum Primitive {
|
|
|
|
/// A boolean value.
|
|
|
|
Bool,
|
|
|
|
/// A number value.
|
|
|
|
Number,
|
|
|
|
/// A string value.
|
|
|
|
String,
|
|
|
|
/// A uuid value.
|
|
|
|
Uuid,
|
|
|
|
}
|
|
|
|
|
2023-09-05 16:02:27 -07:00
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, ts_rs::TS)]
|
|
|
|
#[ts(export)]
|
|
|
|
#[serde(rename_all = "camelCase")]
|
2023-08-25 13:41:04 -07:00
|
|
|
pub struct StdLibFnData {
|
|
|
|
/// The name of the function.
|
|
|
|
pub name: String,
|
|
|
|
/// The summary of the function.
|
|
|
|
pub summary: String,
|
|
|
|
/// The description of the function.
|
|
|
|
pub description: String,
|
|
|
|
/// The tags of the function.
|
|
|
|
pub tags: Vec<String>,
|
2024-12-05 14:27:51 -06:00
|
|
|
/// If this function uses keyword arguments, or positional arguments.
|
|
|
|
pub keyword_arguments: bool,
|
2023-08-25 13:41:04 -07:00
|
|
|
/// The args of the function.
|
|
|
|
pub args: Vec<StdLibFnArg>,
|
|
|
|
/// The return value of the function.
|
2023-09-05 16:02:27 -07:00
|
|
|
pub return_value: Option<StdLibFnArg>,
|
2023-08-25 13:41:04 -07:00
|
|
|
/// If the function is unpublished.
|
|
|
|
pub unpublished: bool,
|
|
|
|
/// If the function is deprecated.
|
|
|
|
pub deprecated: bool,
|
2025-05-06 14:14:11 +12:00
|
|
|
/// Code examples. The bool is whether the example is `norun``
|
2024-03-13 12:56:46 -07:00
|
|
|
/// These are tested and we know they compile and execute.
|
2025-05-06 14:14:11 +12:00
|
|
|
pub examples: Vec<(String, bool)>,
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// This struct defines a single argument to a stdlib function.
|
2023-09-05 16:02:27 -07:00
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, ts_rs::TS)]
|
2024-09-20 16:28:52 -05:00
|
|
|
// There's a bug in ts_rs where this isn't correctly imported by StdLibFnData.
|
|
|
|
#[ts(export_to = "StdLibFnData.ts")]
|
2023-09-05 16:02:27 -07:00
|
|
|
#[serde(rename_all = "camelCase")]
|
2023-08-25 13:41:04 -07:00
|
|
|
pub struct StdLibFnArg {
|
|
|
|
/// The name of the argument.
|
|
|
|
pub name: String,
|
|
|
|
/// The type of the argument.
|
|
|
|
pub type_: String,
|
|
|
|
/// The schema of the argument.
|
2024-01-11 15:31:35 -08:00
|
|
|
#[ts(type = "any")]
|
2024-09-30 12:30:22 -07:00
|
|
|
pub schema: schemars::schema::RootSchema,
|
2023-08-25 13:41:04 -07:00
|
|
|
/// If the argument is required.
|
|
|
|
pub required: bool,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
/// Include this in completion snippets?
|
|
|
|
#[serde(default, skip_serializing_if = "is_false")]
|
|
|
|
pub include_in_snippet: bool,
|
2024-12-13 13:07:52 -06:00
|
|
|
/// Additional information that could be used instead of the type's description.
|
|
|
|
/// This is helpful if the type is really basic, like "u32" -- that won't tell the user much about
|
|
|
|
/// how this argument is meant to be used.
|
|
|
|
/// Empty string means this has no docs.
|
|
|
|
#[serde(default, skip_serializing_if = "String::is_empty")]
|
|
|
|
pub description: String,
|
2024-12-05 14:27:51 -06:00
|
|
|
/// Even in functions that use keyword arguments, not every parameter requires a label (most do though).
|
|
|
|
/// Some functions allow one unlabeled parameter, which has to be first in the
|
|
|
|
/// argument list.
|
|
|
|
///
|
|
|
|
/// This field is ignored for functions that still use positional arguments.
|
|
|
|
/// Defaults to true.
|
|
|
|
#[serde(default = "its_true")]
|
|
|
|
pub label_required: bool,
|
|
|
|
}
|
|
|
|
|
2025-02-27 22:03:37 +13:00
|
|
|
impl fmt::Display for StdLibFnArg {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2025-05-06 16:09:59 +12:00
|
|
|
if !self.label_required {
|
|
|
|
f.write_char('@')?;
|
|
|
|
}
|
2025-02-27 22:03:37 +13:00
|
|
|
f.write_str(&self.name)?;
|
|
|
|
if !self.required {
|
|
|
|
f.write_char('?')?;
|
|
|
|
}
|
|
|
|
f.write_str(": ")?;
|
|
|
|
f.write_str(&self.type_)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-05 14:27:51 -06:00
|
|
|
fn its_true() -> bool {
|
|
|
|
true
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
fn is_false(b: &bool) -> bool {
|
|
|
|
!b
|
|
|
|
}
|
|
|
|
|
2023-08-25 13:41:04 -07:00
|
|
|
impl StdLibFnArg {
|
2024-09-27 07:37:46 -07:00
|
|
|
/// If the argument is a primitive.
|
|
|
|
pub fn is_primitive(&self) -> Result<bool> {
|
2024-09-30 12:30:22 -07:00
|
|
|
is_primitive(&self.schema.schema.clone().into()).map(|r| r.is_some())
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
2023-08-31 22:19:23 -07:00
|
|
|
pub fn get_autocomplete_string(&self) -> Result<String> {
|
2024-09-30 12:30:22 -07:00
|
|
|
get_autocomplete_string_from_schema(&self.schema.schema.clone().into())
|
2023-08-31 22:19:23 -07:00
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
pub fn get_autocomplete_snippet(&self, index: usize, in_keyword_fn: bool) -> Result<Option<(usize, String)>> {
|
|
|
|
let label = if in_keyword_fn && self.label_required {
|
|
|
|
&format!("{} = ", self.name)
|
|
|
|
} else {
|
|
|
|
""
|
|
|
|
};
|
2025-03-21 15:38:08 -07:00
|
|
|
if (self.type_ == "Sketch"
|
2025-03-17 17:57:26 +13:00
|
|
|
|| self.type_ == "[Sketch]"
|
2025-04-23 21:26:09 -07:00
|
|
|
|| self.type_ == "Geometry"
|
|
|
|
|| self.type_ == "GeometryWithImportedGeometry"
|
2024-09-27 15:44:44 -07:00
|
|
|
|| self.type_ == "Solid"
|
2025-03-17 17:57:26 +13:00
|
|
|
|| self.type_ == "[Solid]"
|
2024-04-23 10:31:20 -07:00
|
|
|
|| self.type_ == "SketchSurface"
|
2024-09-27 15:44:44 -07:00
|
|
|
|| self.type_ == "SketchOrSurface"
|
2025-04-17 17:22:19 -07:00
|
|
|
|| self.type_ == "SolidOrImportedGeometry"
|
2025-03-21 15:38:08 -07:00
|
|
|
|| self.type_ == "SolidOrSketchOrImportedGeometry")
|
|
|
|
&& (self.required || self.include_in_snippet)
|
2024-04-23 10:31:20 -07:00
|
|
|
{
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return Ok(Some((index, format!("{label}${{{}:{}}}", index, "%"))));
|
2024-10-30 16:52:17 -04:00
|
|
|
} else if (self.type_ == "TagDeclarator" || self.type_ == "TagNode") && self.required {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return Ok(Some((index, format!("{label}${{{}:{}}}", index, "$myTag"))));
|
2024-06-24 14:45:07 -07:00
|
|
|
} else if self.type_ == "TagIdentifier" && self.required {
|
|
|
|
// TODO: actually use the ast to populate this.
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return Ok(Some((index, format!("{label}${{{}:{}}}", index, "myTag"))));
|
2024-10-01 08:50:23 -05:00
|
|
|
} else if self.type_ == "[KclValue]" && self.required {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return Ok(Some((index, format!("{label}${{{}:{}}}", index, "[0..9]"))));
|
2024-10-04 13:26:16 -05:00
|
|
|
} else if self.type_ == "KclValue" && self.required {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return Ok(Some((index, format!("{label}${{{}:{}}}", index, "3"))));
|
2024-04-12 13:28:58 -07:00
|
|
|
}
|
2025-02-07 16:36:51 -06:00
|
|
|
self.get_autocomplete_snippet_from_schema(&self.schema.schema.clone().into(), index, in_keyword_fn, &self.name)
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
.map(|maybe| maybe.map(|(index, snippet)| (index, format!("{label}{snippet}"))))
|
2024-04-12 13:28:58 -07:00
|
|
|
}
|
|
|
|
|
2025-05-06 16:09:59 +12:00
|
|
|
pub fn description(&self, kcl_std: Option<&ModData>) -> Option<String> {
|
2024-12-13 13:07:52 -06:00
|
|
|
// Check if we explicitly gave this stdlib arg a description.
|
|
|
|
if !self.description.is_empty() {
|
2025-05-12 16:48:30 +12:00
|
|
|
assert!(!self.description.contains('\n'), "Arg docs will get truncated");
|
2024-12-13 13:07:52 -06:00
|
|
|
return Some(self.description.clone());
|
|
|
|
}
|
2025-05-06 16:09:59 +12:00
|
|
|
|
|
|
|
if let Some(kcl_std) = kcl_std {
|
|
|
|
if let Some(t) = docs_for_type(&self.type_, kcl_std) {
|
|
|
|
return Some(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-13 13:07:52 -06:00
|
|
|
// If not, then try to get something meaningful from the schema.
|
2024-09-30 12:30:22 -07:00
|
|
|
get_description_string_from_schema(&self.schema.clone())
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
|
|
|
|
fn get_autocomplete_snippet_from_schema(
|
|
|
|
&self,
|
|
|
|
schema: &schemars::schema::Schema,
|
|
|
|
index: usize,
|
|
|
|
in_keyword_fn: bool,
|
2025-02-07 16:36:51 -06:00
|
|
|
name: &str,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
) -> Result<Option<(usize, String)>> {
|
|
|
|
match schema {
|
|
|
|
schemars::schema::Schema::Object(o) => {
|
|
|
|
// Check if the schema is the same as a Sketch.
|
|
|
|
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
|
|
|
// We set this so we can recurse them later.
|
|
|
|
settings.inline_subschemas = true;
|
|
|
|
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
|
|
|
let sketch_schema = generator.root_schema_for::<Sketch>().schema;
|
|
|
|
if sketch_schema.object == o.object {
|
|
|
|
return Ok(Some((index, format!("${{{}:sketch{}}}", index, "000"))));
|
|
|
|
}
|
|
|
|
|
2025-02-07 16:36:51 -06:00
|
|
|
if name == "color" {
|
|
|
|
let snippet = format!("${{{}:\"#ff0000\"}}", index);
|
|
|
|
return Ok(Some((index, snippet)));
|
|
|
|
}
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if let Some(serde_json::Value::Bool(nullable)) = o.extensions.get("nullable") {
|
|
|
|
if (!in_keyword_fn && *nullable) || (in_keyword_fn && !self.include_in_snippet) {
|
|
|
|
return Ok(None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if o.enum_values.is_some() {
|
|
|
|
let auto_str = get_autocomplete_string_from_schema(schema)?;
|
|
|
|
return Ok(Some((index, format!("${{{}:{}}}", index, auto_str))));
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(format) = &o.format {
|
|
|
|
if format == "uuid" {
|
|
|
|
return Ok(Some((index, format!(r#"${{{}:"tag_or_edge_fn"}}"#, index))));
|
|
|
|
} else if format == "double" {
|
|
|
|
return Ok(Some((index, format!(r#"${{{}:3.14}}"#, index))));
|
|
|
|
} else if format == "uint"
|
|
|
|
|| format == "int64"
|
|
|
|
|| format == "uint32"
|
|
|
|
|| format == "uint64"
|
|
|
|
|| format == "uint8"
|
|
|
|
{
|
|
|
|
return Ok(Some((index, format!(r#"${{{}:10}}"#, index))));
|
|
|
|
} else {
|
|
|
|
anyhow::bail!("unknown format: {}", format);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(obj_val) = &o.object {
|
|
|
|
let mut fn_docs = String::new();
|
|
|
|
fn_docs.push_str("{\n");
|
|
|
|
// Let's print out the object's properties.
|
|
|
|
let mut i = index;
|
|
|
|
for (prop_name, prop) in obj_val.properties.iter() {
|
|
|
|
if prop_name.starts_with('_') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tolerance is a an optional property that we don't want to show in the
|
|
|
|
// autocomplete, since it is mostly for advanced users.
|
|
|
|
if prop_name == "tolerance" {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2025-02-07 16:36:51 -06:00
|
|
|
if let Some((new_index, snippet)) =
|
|
|
|
self.get_autocomplete_snippet_from_schema(prop, i, false, name)?
|
|
|
|
{
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
fn_docs.push_str(&format!("\t{} = {},\n", prop_name, snippet));
|
|
|
|
i = new_index + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_docs.push('}');
|
|
|
|
|
|
|
|
return Ok(Some((i - 1, fn_docs)));
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(array_val) = &o.array {
|
|
|
|
if let Some(schemars::schema::SingleOrVec::Single(items)) = &array_val.items {
|
|
|
|
// Let's print out the object's properties.
|
|
|
|
match array_val.max_items {
|
|
|
|
Some(val) => {
|
|
|
|
return Ok(Some((
|
|
|
|
index + (val as usize) - 1,
|
|
|
|
format!(
|
|
|
|
"[{}]",
|
|
|
|
(0..val)
|
|
|
|
.map(|v| self
|
|
|
|
.get_autocomplete_snippet_from_schema(
|
|
|
|
items,
|
|
|
|
index + (v as usize),
|
2025-02-07 16:36:51 -06:00
|
|
|
in_keyword_fn,
|
|
|
|
name
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
.unwrap()
|
|
|
|
.1)
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join(", ")
|
|
|
|
),
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
return Ok(Some((
|
|
|
|
index,
|
|
|
|
format!(
|
|
|
|
"[{}]",
|
2025-02-07 16:36:51 -06:00
|
|
|
self.get_autocomplete_snippet_from_schema(items, index, in_keyword_fn, name)?
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
.ok_or_else(|| anyhow::anyhow!("expected snippet"))?
|
|
|
|
.1
|
|
|
|
),
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} else if let Some(items) = &array_val.contains {
|
|
|
|
return Ok(Some((
|
|
|
|
index,
|
|
|
|
format!(
|
|
|
|
"[{}]",
|
2025-02-07 16:36:51 -06:00
|
|
|
self.get_autocomplete_snippet_from_schema(items, index, in_keyword_fn, name)?
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
.ok_or_else(|| anyhow::anyhow!("expected snippet"))?
|
|
|
|
.1
|
|
|
|
),
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(subschemas) = &o.subschemas {
|
|
|
|
let mut fn_docs = String::new();
|
|
|
|
let mut i = index;
|
|
|
|
if let Some(items) = &subschemas.one_of {
|
|
|
|
let mut had_enum_string = false;
|
|
|
|
let mut parsed_enum_values: Vec<String> = Vec::new();
|
|
|
|
for item in items {
|
|
|
|
if let schemars::schema::Schema::Object(o) = item {
|
|
|
|
if let Some(enum_values) = &o.enum_values {
|
|
|
|
for enum_value in enum_values {
|
|
|
|
if let serde_json::value::Value::String(enum_value) = enum_value {
|
|
|
|
had_enum_string = true;
|
|
|
|
parsed_enum_values.push(format!("\"{}\"", enum_value));
|
|
|
|
} else {
|
|
|
|
had_enum_string = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !had_enum_string {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
had_enum_string = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
had_enum_string = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if had_enum_string && !parsed_enum_values.is_empty() {
|
|
|
|
return Ok(Some((index, parsed_enum_values[0].to_string())));
|
|
|
|
} else if let Some(item) = items.iter().next() {
|
|
|
|
if let Some((new_index, snippet)) =
|
2025-02-07 16:36:51 -06:00
|
|
|
self.get_autocomplete_snippet_from_schema(item, index, in_keyword_fn, name)?
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
{
|
|
|
|
i = new_index + 1;
|
|
|
|
fn_docs.push_str(&snippet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if let Some(items) = &subschemas.any_of {
|
|
|
|
if let Some(item) = items.iter().next() {
|
|
|
|
if let Some((new_index, snippet)) =
|
2025-02-07 16:36:51 -06:00
|
|
|
self.get_autocomplete_snippet_from_schema(item, index, in_keyword_fn, name)?
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
{
|
|
|
|
i = new_index + 1;
|
|
|
|
fn_docs.push_str(&snippet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
anyhow::bail!("unknown subschemas: {:#?}", subschemas);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok(Some((i - 1, fn_docs)));
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(schemars::schema::SingleOrVec::Single(single)) = &o.instance_type {
|
|
|
|
if schemars::schema::InstanceType::Boolean == **single {
|
|
|
|
return Ok(Some((index, format!(r#"${{{}:false}}"#, index))));
|
|
|
|
} else if schemars::schema::InstanceType::String == **single {
|
|
|
|
return Ok(Some((index, format!(r#"${{{}:"string"}}"#, index))));
|
|
|
|
} else if schemars::schema::InstanceType::Null == **single {
|
|
|
|
return Ok(None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
anyhow::bail!("unknown type: {:#?}", o)
|
|
|
|
}
|
|
|
|
schemars::schema::Schema::Bool(_) => Ok(Some((index, format!(r#"${{{}:false}}"#, index)))),
|
|
|
|
}
|
|
|
|
}
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<StdLibFnArg> for ParameterInformation {
|
|
|
|
fn from(arg: StdLibFnArg) -> Self {
|
|
|
|
ParameterInformation {
|
|
|
|
label: ParameterLabel::Simple(arg.name.to_string()),
|
2025-05-06 16:09:59 +12:00
|
|
|
documentation: arg.description(None).map(|description| {
|
2023-09-05 16:02:27 -07:00
|
|
|
Documentation::MarkupContent(MarkupContent {
|
|
|
|
kind: MarkupKind::Markdown,
|
|
|
|
value: description,
|
|
|
|
})
|
|
|
|
}),
|
|
|
|
}
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-05-06 16:09:59 +12:00
|
|
|
fn docs_for_type(ty: &str, kcl_std: &ModData) -> Option<String> {
|
2025-05-08 11:05:57 +12:00
|
|
|
let key = if ty.starts_with("number") { "number" } else { ty };
|
|
|
|
|
|
|
|
if DECLARED_TYPES.contains(&key) {
|
|
|
|
if let Some(data) = kcl_std.find_by_name(key) {
|
2025-05-06 16:09:59 +12:00
|
|
|
return data.summary().cloned();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2023-08-25 13:41:04 -07:00
|
|
|
/// This trait defines functions called upon stdlib functions to generate
|
|
|
|
/// documentation for them.
|
2023-09-05 16:02:27 -07:00
|
|
|
pub trait StdLibFn: std::fmt::Debug + Send + Sync {
|
2023-08-25 13:41:04 -07:00
|
|
|
/// The name of the function.
|
|
|
|
fn name(&self) -> String;
|
|
|
|
|
|
|
|
/// The summary of the function.
|
|
|
|
fn summary(&self) -> String;
|
|
|
|
|
|
|
|
/// The description of the function.
|
|
|
|
fn description(&self) -> String;
|
|
|
|
|
2024-12-05 14:27:51 -06:00
|
|
|
/// Does this use keyword arguments, or positional?
|
|
|
|
fn keyword_arguments(&self) -> bool;
|
|
|
|
|
2023-08-25 13:41:04 -07:00
|
|
|
/// The tags of the function.
|
|
|
|
fn tags(&self) -> Vec<String>;
|
|
|
|
|
|
|
|
/// The args of the function.
|
2024-09-28 11:51:08 -07:00
|
|
|
fn args(&self, inline_subschemas: bool) -> Vec<StdLibFnArg>;
|
2023-08-25 13:41:04 -07:00
|
|
|
|
|
|
|
/// The return value of the function.
|
2024-09-28 11:51:08 -07:00
|
|
|
fn return_value(&self, inline_subschemas: bool) -> Option<StdLibFnArg>;
|
2023-08-25 13:41:04 -07:00
|
|
|
|
|
|
|
/// If the function is unpublished.
|
|
|
|
fn unpublished(&self) -> bool;
|
|
|
|
|
|
|
|
/// If the function is deprecated.
|
|
|
|
fn deprecated(&self) -> bool;
|
|
|
|
|
2024-12-16 13:10:31 -05:00
|
|
|
/// If the function should appear in the feature tree.
|
|
|
|
fn feature_tree_operation(&self) -> bool;
|
|
|
|
|
2024-03-13 12:56:46 -07:00
|
|
|
/// Any example code blocks.
|
2025-05-06 14:14:11 +12:00
|
|
|
fn examples(&self) -> Vec<(String, bool)>;
|
2024-03-13 12:56:46 -07:00
|
|
|
|
2023-08-25 13:41:04 -07:00
|
|
|
/// The function itself.
|
|
|
|
fn std_lib_fn(&self) -> crate::std::StdFn;
|
|
|
|
|
2023-09-05 16:02:27 -07:00
|
|
|
/// Helper function to clone the boxed trait object.
|
|
|
|
fn clone_box(&self) -> Box<dyn StdLibFn>;
|
|
|
|
|
2023-08-25 13:41:04 -07:00
|
|
|
/// Return a JSON struct representing the function.
|
|
|
|
fn to_json(&self) -> Result<StdLibFnData> {
|
|
|
|
Ok(StdLibFnData {
|
|
|
|
name: self.name(),
|
|
|
|
summary: self.summary(),
|
|
|
|
description: self.description(),
|
|
|
|
tags: self.tags(),
|
2024-12-05 14:27:51 -06:00
|
|
|
keyword_arguments: self.keyword_arguments(),
|
2024-09-28 11:51:08 -07:00
|
|
|
args: self.args(false),
|
|
|
|
return_value: self.return_value(false),
|
2023-08-25 13:41:04 -07:00
|
|
|
unpublished: self.unpublished(),
|
|
|
|
deprecated: self.deprecated(),
|
2024-03-13 12:56:46 -07:00
|
|
|
examples: self.examples(),
|
2023-08-25 13:41:04 -07:00
|
|
|
})
|
|
|
|
}
|
2023-08-31 22:19:23 -07:00
|
|
|
|
2025-02-27 22:03:37 +13:00
|
|
|
fn fn_signature(&self, include_name: bool) -> String {
|
2023-08-31 22:19:23 -07:00
|
|
|
let mut signature = String::new();
|
2025-02-27 22:03:37 +13:00
|
|
|
if include_name {
|
|
|
|
signature.push_str(&self.name());
|
|
|
|
}
|
|
|
|
|
|
|
|
let args = self.args(false);
|
|
|
|
if args.is_empty() {
|
|
|
|
signature.push_str("()");
|
|
|
|
} else if args.len() == 1 {
|
|
|
|
signature.push('(');
|
|
|
|
signature.push_str(&args[0].to_string());
|
|
|
|
signature.push(')');
|
|
|
|
} else {
|
|
|
|
signature.push('(');
|
|
|
|
for a in args {
|
|
|
|
signature.push_str("\n ");
|
|
|
|
signature.push_str(&a.to_string());
|
|
|
|
signature.push(',');
|
2024-03-07 12:35:56 -08:00
|
|
|
}
|
2025-02-27 22:03:37 +13:00
|
|
|
signature.push('\n');
|
|
|
|
signature.push(')');
|
2023-08-31 22:19:23 -07:00
|
|
|
}
|
2024-09-28 11:51:08 -07:00
|
|
|
if let Some(return_value) = self.return_value(false) {
|
2025-03-04 22:53:31 +13:00
|
|
|
signature.push_str(&format!(": {}", return_value.type_));
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
2023-08-31 22:19:23 -07:00
|
|
|
|
|
|
|
signature
|
|
|
|
}
|
2023-09-05 16:02:27 -07:00
|
|
|
|
2024-04-12 13:28:58 -07:00
|
|
|
fn to_completion_item(&self) -> Result<CompletionItem> {
|
|
|
|
Ok(CompletionItem {
|
2023-09-05 16:02:27 -07:00
|
|
|
label: self.name(),
|
|
|
|
label_details: Some(CompletionItemLabelDetails {
|
2025-02-27 22:03:37 +13:00
|
|
|
detail: Some(self.fn_signature(false)),
|
2023-09-05 16:02:27 -07:00
|
|
|
description: None,
|
|
|
|
}),
|
|
|
|
kind: Some(CompletionItemKind::FUNCTION),
|
|
|
|
detail: None,
|
|
|
|
documentation: Some(Documentation::MarkupContent(MarkupContent {
|
|
|
|
kind: MarkupKind::Markdown,
|
|
|
|
value: if !self.description().is_empty() {
|
|
|
|
format!("{}\n\n{}", self.summary(), self.description())
|
|
|
|
} else {
|
|
|
|
self.summary()
|
|
|
|
},
|
|
|
|
})),
|
|
|
|
deprecated: Some(self.deprecated()),
|
|
|
|
preselect: None,
|
|
|
|
sort_text: None,
|
|
|
|
filter_text: None,
|
2024-04-12 13:28:58 -07:00
|
|
|
insert_text: Some(self.to_autocomplete_snippet()?),
|
2023-09-05 16:02:27 -07:00
|
|
|
insert_text_format: Some(InsertTextFormat::SNIPPET),
|
|
|
|
insert_text_mode: None,
|
|
|
|
text_edit: None,
|
|
|
|
additional_text_edits: None,
|
|
|
|
command: None,
|
|
|
|
commit_characters: None,
|
|
|
|
data: None,
|
|
|
|
tags: None,
|
2024-04-12 13:28:58 -07:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_autocomplete_snippet(&self) -> Result<String> {
|
2024-12-11 12:59:02 -08:00
|
|
|
if self.name() == "loft" {
|
2025-04-10 19:53:05 -07:00
|
|
|
return Ok("loft([${0:sketch000}, ${1:sketch001}])".to_string());
|
2025-04-10 23:27:42 -07:00
|
|
|
} else if self.name() == "union" {
|
|
|
|
return Ok("union([${0:extrude001}, ${1:extrude002}])".to_string());
|
|
|
|
} else if self.name() == "subtract" {
|
|
|
|
return Ok("subtract([${0:extrude001}], tools = [${1:extrude002}])".to_string());
|
|
|
|
} else if self.name() == "intersect" {
|
|
|
|
return Ok("intersect([${0:extrude001}, ${1:extrude002}])".to_string());
|
2025-04-26 15:31:51 -05:00
|
|
|
} else if self.name() == "subtract2D" {
|
|
|
|
return Ok("subtract2d(${0:%}, tool = ${1:%})".to_string());
|
2024-12-11 12:59:02 -08:00
|
|
|
}
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
let in_keyword_fn = self.keyword_arguments();
|
2024-04-12 13:28:58 -07:00
|
|
|
let mut args = Vec::new();
|
|
|
|
let mut index = 0;
|
2024-09-28 11:51:08 -07:00
|
|
|
for arg in self.args(true).iter() {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if let Some((i, arg_str)) = arg.get_autocomplete_snippet(index, in_keyword_fn)? {
|
2024-04-12 13:28:58 -07:00
|
|
|
index = i + 1;
|
|
|
|
args.push(arg_str);
|
|
|
|
}
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
2025-04-10 19:53:05 -07:00
|
|
|
Ok(format!("{}({})", self.name(), args.join(", ")))
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn to_signature_help(&self) -> SignatureHelp {
|
2023-11-01 17:34:54 -05:00
|
|
|
// Fill this in based on the current position of the cursor.
|
2023-09-05 16:02:27 -07:00
|
|
|
let active_parameter = None;
|
|
|
|
|
|
|
|
SignatureHelp {
|
|
|
|
signatures: vec![SignatureInformation {
|
2025-04-30 13:58:46 -07:00
|
|
|
label: self.fn_signature(true),
|
2023-09-05 16:02:27 -07:00
|
|
|
documentation: Some(Documentation::MarkupContent(MarkupContent {
|
|
|
|
kind: MarkupKind::Markdown,
|
2025-04-30 13:58:46 -07:00
|
|
|
value: format!(
|
|
|
|
r#"{}
|
|
|
|
|
|
|
|
{}"#,
|
|
|
|
self.summary(),
|
|
|
|
self.description()
|
|
|
|
)
|
|
|
|
.trim()
|
|
|
|
.to_string(),
|
2023-09-05 16:02:27 -07:00
|
|
|
})),
|
2024-09-28 11:51:08 -07:00
|
|
|
parameters: Some(self.args(true).into_iter().map(|arg| arg.into()).collect()),
|
2023-09-05 16:02:27 -07:00
|
|
|
active_parameter,
|
|
|
|
}],
|
|
|
|
active_signature: Some(0),
|
|
|
|
active_parameter,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl JsonSchema for dyn StdLibFn {
|
|
|
|
fn schema_name() -> String {
|
|
|
|
"StdLibFn".to_string()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
|
|
|
gen.subschema_for::<StdLibFnData>()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Serialize for Box<dyn StdLibFn> {
|
|
|
|
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
|
|
self.to_json().unwrap().serialize(serializer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'de> Deserialize<'de> for Box<dyn StdLibFn> {
|
|
|
|
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
|
|
|
let data = StdLibFnData::deserialize(deserializer)?;
|
|
|
|
let stdlib = crate::std::StdLib::new();
|
|
|
|
let stdlib_fn = stdlib
|
|
|
|
.get(&data.name)
|
|
|
|
.ok_or_else(|| serde::de::Error::custom(format!("StdLibFn {} not found", data.name)))?;
|
|
|
|
Ok(stdlib_fn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ts_rs::TS for dyn StdLibFn {
|
2024-05-22 14:22:07 -04:00
|
|
|
type WithoutGenerics = Self;
|
2023-09-05 16:02:27 -07:00
|
|
|
|
|
|
|
fn name() -> String {
|
|
|
|
"StdLibFnData".to_string()
|
|
|
|
}
|
|
|
|
|
2024-05-22 14:22:07 -04:00
|
|
|
fn decl() -> String {
|
|
|
|
StdLibFnData::decl()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn decl_concrete() -> String {
|
|
|
|
StdLibFnData::decl_concrete()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn inline() -> String {
|
|
|
|
StdLibFnData::inline()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn inline_flattened() -> String {
|
|
|
|
StdLibFnData::inline_flattened()
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
|
|
|
|
2024-05-22 14:22:07 -04:00
|
|
|
fn output_path() -> Option<&'static Path> {
|
|
|
|
StdLibFnData::output_path()
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for Box<dyn StdLibFn> {
|
|
|
|
fn clone(&self) -> Box<dyn StdLibFn> {
|
|
|
|
self.clone_box()
|
|
|
|
}
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
2024-09-30 12:30:22 -07:00
|
|
|
pub fn get_description_string_from_schema(schema: &schemars::schema::RootSchema) -> Option<String> {
|
|
|
|
if let Some(metadata) = &schema.schema.metadata {
|
|
|
|
if let Some(description) = &metadata.description {
|
|
|
|
return Some(description.to_string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(reference) = &schema.schema.reference {
|
2025-04-03 15:59:26 -04:00
|
|
|
if let Some(definition) = schema.definitions.get(reference.split('/').next_back().unwrap_or("")) {
|
2024-09-30 12:30:22 -07:00
|
|
|
let schemars::schema::Schema::Object(definition) = definition else {
|
|
|
|
return None;
|
|
|
|
};
|
|
|
|
if let Some(metadata) = &definition.metadata {
|
|
|
|
if let Some(description) = &metadata.description {
|
|
|
|
return Some(description.to_string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have subschemas iterate over them and recursively create references.
|
|
|
|
if let Some(subschema) = &schema.schema.subschemas {
|
|
|
|
if let Some(one_of) = &subschema.one_of {
|
|
|
|
if one_of.len() == 1 {
|
|
|
|
return get_description_string_from_schema(&schemars::schema::RootSchema {
|
|
|
|
meta_schema: schema.meta_schema.clone(),
|
|
|
|
schema: one_of[0].clone().into(),
|
|
|
|
definitions: schema.definitions.clone(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(all_of) = &subschema.all_of {
|
|
|
|
if all_of.len() == 1 {
|
|
|
|
return get_description_string_from_schema(&schemars::schema::RootSchema {
|
|
|
|
meta_schema: schema.meta_schema.clone(),
|
|
|
|
schema: all_of[0].clone().into(),
|
|
|
|
definitions: schema.definitions.clone(),
|
|
|
|
});
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
}
|
2024-09-28 11:51:08 -07:00
|
|
|
|
2024-09-30 12:30:22 -07:00
|
|
|
if let Some(any_of) = &subschema.any_of {
|
|
|
|
if any_of.len() == 1 {
|
|
|
|
return get_description_string_from_schema(&schemars::schema::RootSchema {
|
|
|
|
meta_schema: schema.meta_schema.clone(),
|
|
|
|
schema: any_of[0].clone().into(),
|
|
|
|
definitions: schema.definitions.clone(),
|
|
|
|
});
|
2024-09-28 11:51:08 -07:00
|
|
|
}
|
|
|
|
}
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2025-05-13 08:29:38 +12:00
|
|
|
fn is_primitive(schema: &schemars::schema::Schema) -> Result<Option<Primitive>> {
|
2023-08-25 13:41:04 -07:00
|
|
|
match schema {
|
|
|
|
schemars::schema::Schema::Object(o) => {
|
2024-09-27 07:37:46 -07:00
|
|
|
if o.enum_values.is_some() {
|
|
|
|
// It's an enum so it's not a primitive.
|
|
|
|
return Ok(None);
|
2024-02-12 12:18:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check if there
|
2023-08-25 13:41:04 -07:00
|
|
|
if let Some(format) = &o.format {
|
|
|
|
if format == "uuid" {
|
2024-09-27 07:37:46 -07:00
|
|
|
return Ok(Some(Primitive::Uuid));
|
2024-04-23 15:59:12 -07:00
|
|
|
} else if format == "double"
|
|
|
|
|| format == "uint"
|
2024-07-25 21:18:52 -04:00
|
|
|
|| format == "int32"
|
2024-04-23 15:59:12 -07:00
|
|
|
|| format == "int64"
|
2024-07-09 12:24:42 -04:00
|
|
|
|| format == "uint8"
|
2024-04-23 15:59:12 -07:00
|
|
|
|| format == "uint32"
|
|
|
|
|| format == "uint64"
|
|
|
|
{
|
2024-09-27 07:37:46 -07:00
|
|
|
return Ok(Some(Primitive::Number));
|
2023-08-25 13:41:04 -07:00
|
|
|
} else {
|
|
|
|
anyhow::bail!("unknown format: {}", format);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-27 07:37:46 -07:00
|
|
|
if o.object.is_some() {
|
|
|
|
// It's an object so it's not a primitive.
|
|
|
|
return Ok(None);
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
2024-09-27 07:37:46 -07:00
|
|
|
if o.array.is_some() {
|
|
|
|
return Ok(None);
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
2024-09-27 07:37:46 -07:00
|
|
|
if o.subschemas.is_some() {
|
|
|
|
return Ok(None);
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
2024-08-16 19:48:09 -07:00
|
|
|
if let Some(schemars::schema::SingleOrVec::Single(single)) = &o.instance_type {
|
|
|
|
if schemars::schema::InstanceType::Boolean == **single {
|
2024-09-27 07:37:46 -07:00
|
|
|
return Ok(Some(Primitive::Bool));
|
2024-08-16 19:48:09 -07:00
|
|
|
} else if schemars::schema::InstanceType::String == **single
|
|
|
|
|| schemars::schema::InstanceType::Null == **single
|
|
|
|
{
|
2024-09-27 07:37:46 -07:00
|
|
|
return Ok(Some(Primitive::String));
|
2024-08-16 19:48:09 -07:00
|
|
|
}
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
|
2024-09-27 07:37:46 -07:00
|
|
|
if o.reference.is_some() {
|
|
|
|
return Ok(None);
|
2024-06-23 19:19:24 -07:00
|
|
|
}
|
|
|
|
|
2023-08-25 13:41:04 -07:00
|
|
|
anyhow::bail!("unknown type: {:#?}", o)
|
|
|
|
}
|
2024-09-27 07:37:46 -07:00
|
|
|
schemars::schema::Schema::Bool(_) => Ok(Some(Primitive::Bool)),
|
2023-08-25 13:41:04 -07:00
|
|
|
}
|
|
|
|
}
|
2023-08-31 22:19:23 -07:00
|
|
|
|
2024-09-27 07:37:46 -07:00
|
|
|
fn get_autocomplete_string_from_schema(schema: &schemars::schema::Schema) -> Result<String> {
|
2023-08-31 22:19:23 -07:00
|
|
|
match schema {
|
|
|
|
schemars::schema::Schema::Object(o) => {
|
2024-04-12 13:28:58 -07:00
|
|
|
if let Some(enum_values) = &o.enum_values {
|
|
|
|
let mut parsed_enum_values: Vec<String> = Default::default();
|
|
|
|
let mut had_enum_string = false;
|
|
|
|
for enum_value in enum_values {
|
|
|
|
if let serde_json::value::Value::String(enum_value) = enum_value {
|
|
|
|
had_enum_string = true;
|
2025-04-30 17:13:11 +12:00
|
|
|
parsed_enum_values.push(enum_value.to_owned());
|
2024-04-12 13:28:58 -07:00
|
|
|
} else {
|
|
|
|
had_enum_string = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if had_enum_string && !parsed_enum_values.is_empty() {
|
|
|
|
return Ok(parsed_enum_values[0].to_string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-31 22:19:23 -07:00
|
|
|
if let Some(format) = &o.format {
|
|
|
|
if format == "uuid" {
|
|
|
|
return Ok(Primitive::Uuid.to_string());
|
2024-04-23 15:59:12 -07:00
|
|
|
} else if format == "double"
|
|
|
|
|| format == "uint"
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
|| format == "uint8"
|
2024-04-23 15:59:12 -07:00
|
|
|
|| format == "int64"
|
|
|
|
|| format == "uint32"
|
|
|
|
|| format == "uint64"
|
|
|
|
{
|
2023-08-31 22:19:23 -07:00
|
|
|
return Ok(Primitive::Number.to_string());
|
|
|
|
} else {
|
|
|
|
anyhow::bail!("unknown format: {}", format);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(obj_val) = &o.object {
|
|
|
|
let mut fn_docs = String::new();
|
|
|
|
fn_docs.push_str("{\n");
|
|
|
|
// Let's print out the object's properties.
|
|
|
|
for (prop_name, prop) in obj_val.properties.iter() {
|
|
|
|
if prop_name.starts_with('_') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_docs.push_str(&format!(
|
2023-09-05 16:02:27 -07:00
|
|
|
"\t{}: {},\n",
|
2023-08-31 22:19:23 -07:00
|
|
|
prop_name,
|
|
|
|
get_autocomplete_string_from_schema(prop)?,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_docs.push('}');
|
|
|
|
|
|
|
|
return Ok(fn_docs);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(array_val) = &o.array {
|
|
|
|
if let Some(schemars::schema::SingleOrVec::Single(items)) = &array_val.items {
|
|
|
|
// Let's print out the object's properties.
|
2024-04-12 13:28:58 -07:00
|
|
|
match array_val.max_items {
|
|
|
|
Some(val) => {
|
|
|
|
return Ok(format!(
|
|
|
|
"[{}]",
|
|
|
|
(0..val).map(|_| "number").collect::<Vec<_>>().join(", ")
|
|
|
|
));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
return Ok(format!("[{}]", get_autocomplete_string_from_schema(items)?));
|
|
|
|
}
|
|
|
|
};
|
2023-08-31 22:19:23 -07:00
|
|
|
} else if let Some(items) = &array_val.contains {
|
|
|
|
return Ok(format!("[{}]", get_autocomplete_string_from_schema(items)?));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(subschemas) = &o.subschemas {
|
|
|
|
let mut fn_docs = String::new();
|
|
|
|
if let Some(items) = &subschemas.one_of {
|
2024-04-12 13:28:58 -07:00
|
|
|
let mut had_enum_string = false;
|
|
|
|
let mut parsed_enum_values: Vec<String> = Vec::new();
|
|
|
|
for item in items {
|
|
|
|
if let schemars::schema::Schema::Object(o) = item {
|
|
|
|
if let Some(enum_values) = &o.enum_values {
|
|
|
|
for enum_value in enum_values {
|
|
|
|
if let serde_json::value::Value::String(enum_value) = enum_value {
|
|
|
|
had_enum_string = true;
|
|
|
|
parsed_enum_values.push(format!("\"{}\"", enum_value));
|
|
|
|
} else {
|
|
|
|
had_enum_string = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !had_enum_string {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
had_enum_string = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
had_enum_string = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if had_enum_string && !parsed_enum_values.is_empty() {
|
|
|
|
return Ok(parsed_enum_values[0].to_string());
|
|
|
|
} else if let Some(item) = items.iter().next() {
|
2023-08-31 22:19:23 -07:00
|
|
|
// Let's print out the object's properties.
|
|
|
|
fn_docs.push_str(&get_autocomplete_string_from_schema(item)?);
|
|
|
|
}
|
|
|
|
} else if let Some(items) = &subschemas.any_of {
|
|
|
|
if let Some(item) = items.iter().next() {
|
|
|
|
// Let's print out the object's properties.
|
|
|
|
fn_docs.push_str(&get_autocomplete_string_from_schema(item)?);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
anyhow::bail!("unknown subschemas: {:#?}", subschemas);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ok(fn_docs);
|
|
|
|
}
|
|
|
|
|
2024-08-16 19:48:09 -07:00
|
|
|
if let Some(schemars::schema::SingleOrVec::Single(single)) = &o.instance_type {
|
|
|
|
if schemars::schema::InstanceType::Boolean == **single {
|
|
|
|
return Ok(Primitive::Bool.to_string());
|
|
|
|
} else if schemars::schema::InstanceType::String == **single
|
|
|
|
|| schemars::schema::InstanceType::Null == **single
|
|
|
|
{
|
|
|
|
return Ok(Primitive::String.to_string());
|
|
|
|
}
|
2023-08-31 22:19:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
anyhow::bail!("unknown type: {:#?}", o)
|
|
|
|
}
|
|
|
|
schemars::schema::Schema::Bool(_) => Ok(Primitive::Bool.to_string()),
|
|
|
|
}
|
|
|
|
}
|
2023-09-05 16:02:27 -07:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use pretty_assertions::assert_eq;
|
|
|
|
|
2024-04-12 13:28:58 -07:00
|
|
|
use super::StdLibFn;
|
2025-03-26 01:59:43 -04:00
|
|
|
use crate::docs::kcl_doc::{self, DocData};
|
2024-04-12 13:28:58 -07:00
|
|
|
|
2023-09-05 16:02:27 -07:00
|
|
|
#[test]
|
|
|
|
fn test_serialize_function() {
|
2024-12-05 17:56:49 +13:00
|
|
|
let some_function = crate::parsing::ast::types::Function::StdLib {
|
2023-09-05 16:02:27 -07:00
|
|
|
func: Box::new(crate::std::sketch::Line),
|
|
|
|
};
|
|
|
|
let serialized = serde_json::to_string(&some_function).unwrap();
|
|
|
|
assert!(serialized.contains(r#"{"type":"StdLib""#));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_deserialize_function() {
|
2024-12-05 14:27:51 -06:00
|
|
|
let some_function_string = r#"{"type":"StdLib","func":{"name":"line","keywordArguments":false,"summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{},"schemaDefinitions":{}},"args":[],"unpublished":false,"deprecated":false, "examples": []}}"#;
|
2024-12-05 17:56:49 +13:00
|
|
|
let some_function: crate::parsing::ast::types::Function = serde_json::from_str(some_function_string).unwrap();
|
2023-09-05 16:02:27 -07:00
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
some_function,
|
2024-12-05 17:56:49 +13:00
|
|
|
crate::parsing::ast::types::Function::StdLib {
|
2024-06-27 15:43:49 -07:00
|
|
|
func: Box::new(crate::std::sketch::Line)
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2024-04-12 13:28:58 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_line() {
|
|
|
|
let line_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Line);
|
|
|
|
let snippet = line_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 19:53:05 -07:00
|
|
|
assert_eq!(snippet, r#"line(${0:%}, end = [${1:3.14}, ${2:3.14}])"#);
|
2024-04-12 13:28:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_extrude() {
|
|
|
|
let extrude_fn: Box<dyn StdLibFn> = Box::new(crate::std::extrude::Extrude);
|
|
|
|
let snippet = extrude_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 19:53:05 -07:00
|
|
|
assert_eq!(snippet, r#"extrude(${0:%}, length = ${1:3.14})"#);
|
2024-04-12 13:28:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_fillet() {
|
2025-04-28 14:20:38 +12:00
|
|
|
let data = kcl_doc::walk_prelude();
|
2025-05-06 11:02:55 +12:00
|
|
|
let DocData::Fn(fillet_fn) = data.find_by_name("fillet").unwrap() else {
|
2025-04-28 14:20:38 +12:00
|
|
|
panic!();
|
|
|
|
};
|
|
|
|
let snippet = fillet_fn.to_autocomplete_snippet();
|
|
|
|
assert_eq!(snippet, r#"fillet(radius = ${0:3.14}, tags = [${1:tag_or_edge_fn}])"#);
|
2024-04-12 13:28:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_start_sketch_on() {
|
|
|
|
let start_sketch_on_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::StartSketchOn);
|
|
|
|
let snippet = start_sketch_on_fn.to_autocomplete_snippet().unwrap();
|
2025-04-30 17:13:11 +12:00
|
|
|
assert_eq!(snippet, r#"startSketchOn(${0:XY})"#);
|
2024-04-12 13:28:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_pattern_circular_3d() {
|
2024-07-29 01:16:18 -07:00
|
|
|
// We test this one specifically because it has ints and floats and strings.
|
2024-04-12 13:28:58 -07:00
|
|
|
let pattern_fn: Box<dyn StdLibFn> = Box::new(crate::std::patterns::PatternCircular3D);
|
|
|
|
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-05-18 21:46:00 -05:00
|
|
|
r#"patternCircular3d(${0:%}, instances = ${1:10}, axis = [${2:3.14}, ${3:3.14}, ${4:3.14}], center = [${5:3.14}, ${6:3.14}, ${7:3.14}])"#
|
2024-04-12 13:28:58 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_revolve() {
|
2025-04-03 22:44:52 +13:00
|
|
|
let data = kcl_doc::walk_prelude();
|
2025-05-06 11:02:55 +12:00
|
|
|
let DocData::Fn(revolve_fn) = data.find_by_name("revolve").unwrap() else {
|
2025-04-03 22:44:52 +13:00
|
|
|
panic!();
|
|
|
|
};
|
|
|
|
let snippet = revolve_fn.to_autocomplete_snippet();
|
2025-04-10 19:53:05 -07:00
|
|
|
assert_eq!(snippet, r#"revolve(axis = ${0:X})"#);
|
2024-04-12 13:28:58 -07:00
|
|
|
}
|
2024-07-03 18:05:24 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_circle() {
|
2025-03-24 21:55:24 +13:00
|
|
|
let data = kcl_doc::walk_prelude();
|
2025-05-06 11:02:55 +12:00
|
|
|
let DocData::Fn(circle_fn) = data.find_by_name("circle").unwrap() else {
|
2025-03-24 21:55:24 +13:00
|
|
|
panic!();
|
|
|
|
};
|
|
|
|
let snippet = circle_fn.to_autocomplete_snippet();
|
2024-09-23 22:42:51 +10:00
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-04-10 19:53:05 -07:00
|
|
|
r#"circle(center = [${0:3.14}, ${1:3.14}], radius = ${2:3.14})"#
|
2024-09-24 19:35:23 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_arc() {
|
|
|
|
let arc_fn: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Arc);
|
|
|
|
let snippet = arc_fn.to_autocomplete_snippet().unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-04-18 17:40:44 -05:00
|
|
|
r#"arc(${0:%}, angleStart = ${1:3.14}, angleEnd = ${2:3.14}, radius = ${3:3.14})"#
|
2024-09-24 19:35:23 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-10-01 08:50:23 -05:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_map() {
|
2025-05-13 08:29:38 +12:00
|
|
|
let data = kcl_doc::walk_prelude();
|
|
|
|
let DocData::Fn(map_fn) = data.find_by_name("map").unwrap() else {
|
|
|
|
panic!();
|
|
|
|
};
|
|
|
|
let snippet = map_fn.to_autocomplete_snippet();
|
|
|
|
assert_eq!(snippet, r#"map()"#);
|
2024-10-01 08:50:23 -05:00
|
|
|
}
|
|
|
|
|
2024-09-24 19:35:23 -07:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_pattern_linear_2d() {
|
|
|
|
let pattern_fn: Box<dyn StdLibFn> = Box::new(crate::std::patterns::PatternLinear2D);
|
|
|
|
let snippet = pattern_fn.to_autocomplete_snippet().unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-04-10 19:53:05 -07:00
|
|
|
r#"patternLinear2d(${0:%}, instances = ${1:10}, distance = ${2:3.14}, axis = [${3:3.14}, ${4:3.14}])"#
|
2024-09-23 22:42:51 +10:00
|
|
|
);
|
2024-07-03 18:05:24 -07:00
|
|
|
}
|
2024-10-01 13:11:09 -07:00
|
|
|
|
2024-12-10 17:51:51 -08:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_appearance() {
|
|
|
|
let appearance_fn: Box<dyn StdLibFn> = Box::new(crate::std::appearance::Appearance);
|
|
|
|
let snippet = appearance_fn.to_autocomplete_snippet().unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-04-10 19:53:05 -07:00
|
|
|
r#"appearance(${0:%}, color = ${1:"#.to_owned() + "\"#" + r#"ff0000"})"#
|
2024-12-10 17:51:51 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-12-11 12:59:02 -08:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_loft() {
|
|
|
|
let loft_fn: Box<dyn StdLibFn> = Box::new(crate::std::loft::Loft);
|
|
|
|
let snippet = loft_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 19:53:05 -07:00
|
|
|
assert_eq!(snippet, r#"loft([${0:sketch000}, ${1:sketch001}])"#);
|
2024-12-11 12:59:02 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_sweep() {
|
|
|
|
let sweep_fn: Box<dyn StdLibFn> = Box::new(crate::std::sweep::Sweep);
|
|
|
|
let snippet = sweep_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 19:53:05 -07:00
|
|
|
assert_eq!(snippet, r#"sweep(${0:%}, path = ${1:sketch000})"#);
|
2024-12-11 12:59:02 -08:00
|
|
|
}
|
|
|
|
|
2024-12-11 17:07:14 -08:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_hole() {
|
2025-04-26 15:31:51 -05:00
|
|
|
let f: Box<dyn StdLibFn> = Box::new(crate::std::sketch::Subtract2D);
|
|
|
|
let snippet = f.to_autocomplete_snippet().unwrap();
|
|
|
|
assert_eq!(snippet, r#"subtract2d(${0:%}, tool = ${1:%})"#);
|
2024-12-11 17:07:14 -08:00
|
|
|
}
|
|
|
|
|
2025-01-13 15:34:43 -08:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_helix() {
|
2025-04-03 22:44:52 +13:00
|
|
|
let data = kcl_doc::walk_prelude();
|
2025-05-06 11:02:55 +12:00
|
|
|
let DocData::Fn(helix_fn) = data.find_by_name("helix").unwrap() else {
|
2025-04-03 22:44:52 +13:00
|
|
|
panic!();
|
|
|
|
};
|
|
|
|
let snippet = helix_fn.to_autocomplete_snippet();
|
2025-01-13 15:34:43 -08:00
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-04-10 19:53:05 -07:00
|
|
|
r#"helix(revolutions = ${0:3.14}, angleStart = ${1:3.14}, radius = ${2:3.14}, axis = ${3:X}, length = ${4:3.14})"#
|
2025-01-13 15:34:43 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2025-03-21 15:38:08 -07:00
|
|
|
fn get_autocomplete_snippet_union() {
|
|
|
|
let union_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Union);
|
|
|
|
let snippet = union_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 23:27:42 -07:00
|
|
|
assert_eq!(snippet, r#"union([${0:extrude001}, ${1:extrude002}])"#);
|
2025-03-21 15:38:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_subtract() {
|
|
|
|
let subtract_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Subtract);
|
|
|
|
let snippet = subtract_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 23:27:42 -07:00
|
|
|
assert_eq!(snippet, r#"subtract([${0:extrude001}], tools = [${1:extrude002}])"#);
|
2025-03-21 15:38:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_intersect() {
|
|
|
|
let intersect_fn: Box<dyn StdLibFn> = Box::new(crate::std::csg::Intersect);
|
|
|
|
let snippet = intersect_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 23:27:42 -07:00
|
|
|
assert_eq!(snippet, r#"intersect([${0:extrude001}, ${1:extrude002}])"#);
|
2025-03-21 15:38:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_get_common_edge() {
|
|
|
|
let get_common_edge_fn: Box<dyn StdLibFn> = Box::new(crate::std::edge::GetCommonEdge);
|
|
|
|
let snippet = get_common_edge_fn.to_autocomplete_snippet().unwrap();
|
2025-01-13 15:34:43 -08:00
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-03-21 15:38:08 -07:00
|
|
|
r#"getCommonEdge(faces = [{
|
|
|
|
value = ${0:"string"},
|
2025-04-10 19:53:05 -07:00
|
|
|
}])"#
|
2025-01-13 15:34:43 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2025-02-26 16:45:19 -08:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_scale() {
|
|
|
|
let scale_fn: Box<dyn StdLibFn> = Box::new(crate::std::transform::Scale);
|
|
|
|
let snippet = scale_fn.to_autocomplete_snippet().unwrap();
|
2025-04-10 19:53:05 -07:00
|
|
|
assert_eq!(snippet, r#"scale(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})"#);
|
2025-02-26 16:45:19 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_translate() {
|
|
|
|
let translate_fn: Box<dyn StdLibFn> = Box::new(crate::std::transform::Translate);
|
|
|
|
let snippet = translate_fn.to_autocomplete_snippet().unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-04-10 19:53:05 -07:00
|
|
|
r#"translate(${0:%}, x = ${1:3.14}, y = ${2:3.14}, z = ${3:3.14})"#
|
2025-02-26 16:45:19 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_rotate() {
|
|
|
|
let rotate_fn: Box<dyn StdLibFn> = Box::new(crate::std::transform::Rotate);
|
|
|
|
let snippet = rotate_fn.to_autocomplete_snippet().unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
snippet,
|
2025-04-10 19:53:05 -07:00
|
|
|
r#"rotate(${0:%}, roll = ${1:3.14}, pitch = ${2:3.14}, yaw = ${3:3.14})"#
|
2025-02-26 16:45:19 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2025-04-23 21:26:09 -07:00
|
|
|
#[test]
|
|
|
|
#[allow(clippy::literal_string_with_formatting_args)]
|
|
|
|
fn get_autocomplete_snippet_clone() {
|
2025-05-13 08:29:38 +12:00
|
|
|
let data = kcl_doc::walk_prelude();
|
|
|
|
let DocData::Fn(clone_fn) = data.find_by_name("clone").unwrap() else {
|
|
|
|
panic!();
|
|
|
|
};
|
|
|
|
let snippet = clone_fn.to_autocomplete_snippet();
|
2025-04-23 21:26:09 -07:00
|
|
|
assert_eq!(snippet, r#"clone(${0:part001})"#);
|
|
|
|
}
|
|
|
|
|
2025-05-15 19:53:35 +02:00
|
|
|
#[test]
|
|
|
|
fn get_autocomplete_snippet_offset_plane() {
|
|
|
|
let data = kcl_doc::walk_prelude();
|
|
|
|
let DocData::Fn(offset_plane_fn) = data.find_by_name("offsetPlane").unwrap() else {
|
|
|
|
panic!();
|
|
|
|
};
|
|
|
|
let snippet = offset_plane_fn.to_autocomplete_snippet();
|
|
|
|
assert_eq!(snippet, r#"offsetPlane(${0:XY}, offset = ${1:3.14})"#);
|
|
|
|
}
|
|
|
|
|
2024-10-01 13:11:09 -07:00
|
|
|
// We want to test the snippets we compile at lsp start.
|
|
|
|
#[test]
|
|
|
|
fn get_all_stdlib_autocomplete_snippets() {
|
|
|
|
let stdlib = crate::std::StdLib::new();
|
2025-02-20 19:33:21 +13:00
|
|
|
let kcl_std = crate::docs::kcl_doc::walk_prelude();
|
|
|
|
crate::lsp::kcl::get_completions_from_stdlib(&stdlib, &kcl_std).unwrap();
|
2024-10-01 13:11:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// We want to test the signatures we compile at lsp start.
|
|
|
|
#[test]
|
|
|
|
fn get_all_stdlib_signatures() {
|
|
|
|
let stdlib = crate::std::StdLib::new();
|
2025-02-20 19:33:21 +13:00
|
|
|
let kcl_std = crate::docs::kcl_doc::walk_prelude();
|
|
|
|
crate::lsp::kcl::get_signatures_from_stdlib(&stdlib, &kcl_std);
|
2024-10-01 13:11:09 -07:00
|
|
|
}
|
2025-04-30 13:58:46 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get_extrude_signature_help() {
|
|
|
|
let extrude_fn: Box<dyn StdLibFn> = Box::new(crate::std::extrude::Extrude);
|
|
|
|
let sh = extrude_fn.to_signature_help();
|
|
|
|
assert_eq!(
|
|
|
|
sh.signatures[0].label,
|
|
|
|
r#"extrude(
|
2025-05-06 16:09:59 +12:00
|
|
|
@sketches: [Sketch],
|
2025-04-30 13:58:46 -07:00
|
|
|
length: number,
|
|
|
|
symmetric?: bool,
|
|
|
|
bidirectionalLength?: number,
|
|
|
|
tagStart?: TagNode,
|
|
|
|
tagEnd?: TagNode,
|
|
|
|
): [Solid]"#
|
|
|
|
);
|
|
|
|
}
|
2023-09-05 16:02:27 -07:00
|
|
|
}
|