Merge branch 'main' into pierremtb/issue5504-Add-edit-flow-for-Revolve

This commit is contained in:
Pierre Jacquier
2025-03-24 11:04:57 -04:00
committed by GitHub
306 changed files with 87917 additions and 26728 deletions

File diff suppressed because one or more lines are too long

View File

@ -10,10 +10,10 @@ Construct a circle derived from 3 points.
```js
circleThreePoint(
sketchSurfaceOrGroup: SketchOrSurface,
p1: [number],
p2: [number],
p3: [number],
sketchSurfaceOrGroup: SketchOrSurface,
tag?: TagDeclarator,
): Sketch
```
@ -23,10 +23,10 @@ circleThreePoint(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on. | Yes |
| `p1` | [`[number]`](/docs/kcl/types/number) | 1st point to derive the circle. | Yes |
| `p2` | [`[number]`](/docs/kcl/types/number) | 2nd point to derive the circle. | Yes |
| `p3` | [`[number]`](/docs/kcl/types/number) | 3rd point to derive the circle. | Yes |
| `sketchSurfaceOrGroup` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | Plane or surface to sketch on. | Yes |
| [`tag`](/docs/kcl/types/tag) | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | Identifier for the circle to reference elsewhere. | No |
### Returns

View File

@ -15,7 +15,7 @@ std::math::E: number = 2.71828182845904523536028747135266250_
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 30,

View File

@ -17,7 +17,7 @@ std::math::PI: number = 3.14159265358979323846264338327950288_
```js
circumference = 70
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = circumference/ (2 * PI))
example = extrude(exampleSketch, length = 5)

View File

@ -15,7 +15,7 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,

View File

@ -61,7 +61,6 @@ layout: manual
* [`bezierCurve`](kcl/bezierCurve)
* [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer)
* [`circle`](kcl/circle)
* [`circleThreePoint`](kcl/circleThreePoint)
* [`close`](kcl/close)
* [`cm`](kcl/cm)
@ -145,3 +144,5 @@ layout: manual
* [`cos`](kcl/std-math-cos)
* [`sin`](kcl/std-math-sin)
* [`tan`](kcl/std-math-tan)
* **std::sketch**
* [`circle`](kcl/std-sketch-circle)

View File

@ -9,7 +9,7 @@ Compute the cosine of a number (in radians).
```js
cos(num: number(rad)): number(_)
cos(@num: number(rad)): number(_)
```
@ -27,7 +27,7 @@ cos(num: number(rad)): number(_)
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 30,

View File

@ -9,7 +9,7 @@ Compute the sine of a number (in radians).
```js
sin(num: number(rad)): number(_)
sin(@num: number(rad)): number(_)
```
@ -27,7 +27,7 @@ sin(num: number(rad)): number(_)
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,

View File

@ -9,7 +9,7 @@ Compute the tangent of a number (in radians).
```js
tan(num: number(rad)): number(_)
tan(@num: number(rad)): number(_)
```
@ -27,7 +27,7 @@ tan(num: number(rad)): number(_)
### Examples
```js
exampleSketch = startSketchOn("XZ")
exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,8 @@ A point in two dimensional space.
type Point2d = [number; 2]
```
`Point2d` is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value
with type `Point2d`, use an array, e.g., `[0, 0]` or `[5.0, 3.14]`.
[`Point2d`](/docs/kcl/types/Point2d) is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value
with type [`Point2d`](/docs/kcl/types/Point2d), use an array, e.g., `[0, 0]` or `[5.0, 3.14]`.

View File

@ -10,8 +10,8 @@ A point in three dimensional space.
type Point3d = [number; 3]
```
`Point3d` is an alias for a three-element array of [number](/docs/kcl/types/number)s. To write a value
with type `Point3d`, use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`.
[`Point3d`](/docs/kcl/types/Point3d) is an alias for a three-element array of [number](/docs/kcl/types/number)s. To write a value
with type [`Point3d`](/docs/kcl/types/Point3d), use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`.

View File

@ -17,7 +17,7 @@ mySketch = startSketchOn('XY')
|> close()
```
The `mySketch` variable will be an executed `Sketch` object. Executed being past
The `mySketch` variable will be an executed [`Sketch`](/docs/kcl/types/Sketch) object. Executed being past
tense, because the engine has already executed the commands to create the sketch.
The previous sketch commands will never be executed again, in this case.

View File

@ -18,7 +18,7 @@ myPart = startSketchOn('XY')
|> extrude(length = 6)
```
The `myPart` variable will be an executed `Solid` object. Executed being past
The `myPart` variable will be an executed [`Solid`](/docs/kcl/types/Solid) object. Executed being past
tense, because the engine has already executed the commands to create the solid.
The previous solid commands will never be executed again, in this case.

View File

@ -1082,7 +1082,7 @@ openSketch = startSketchOn(XY)
}) => {
// One dumb hardcoded screen pixel value
const testPoint = { x: 620, y: 257 }
const expectedOutput = `helix001 = helix( revolutions = 1, angleStart = 360, counterClockWise = false, radius = 5, axis = 'X', length = 5,)`
const expectedOutput = `helix001 = helix( revolutions = 1, angleStart = 360, ccw = false, radius = 5, axis = 'X', length = 5,)`
const expectedLine = `revolutions=1,`
await homePage.goToModelingScene()
@ -1099,7 +1099,7 @@ openSketch = startSketchOn(XY)
headerArguments: {
AngleStart: '',
Axis: '',
CounterClockWise: '',
Ccw: '',
Length: '',
Radius: '',
Revolutions: '',
@ -1141,7 +1141,7 @@ openSketch = startSketchOn(XY)
headerArguments: {
AngleStart: '360',
Axis: 'X',
CounterClockWise: '',
Ccw: '',
Length: initialInput,
Radius: '5',
Revolutions: '1',
@ -1156,7 +1156,7 @@ openSketch = startSketchOn(XY)
headerArguments: {
AngleStart: '360',
Axis: 'X',
CounterClockWise: '',
Ccw: '',
Length: newInput,
Radius: '5',
Revolutions: '1',

View File

@ -191,7 +191,7 @@ test(
// error text on hover
await page.hover('.cm-lint-marker-error')
const crypticErrorText = `Expected a tag declarator`
const crypticErrorText = `The arg tag was given, but it was the wrong type`
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
// black pixel means the scene has been cleared.
@ -409,7 +409,7 @@ test(
// error text on hover
await page.hover('.cm-lint-marker-error')
const crypticErrorText = `Expected a tag declarator`
const crypticErrorText = `The arg tag was given, but it was the wrong type`
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
// black pixel means the scene has been cleared.
@ -453,7 +453,7 @@ test(
// error text on hover
await page.hover('.cm-lint-marker-error')
const crypticErrorText = `Expected a tag declarator`
const crypticErrorText = `The arg tag was given, but it was the wrong type`
await expect(page.getByText(crypticErrorText).first()).toBeVisible()
}
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -75,17 +75,14 @@ LabeledArgument { ArgumentLabel Equals expression }
ArgumentList { "(" commaSep<LabeledArgument | expression> ")" }
type[@isGroup=Type] {
@specialize[@name=PrimitiveType]<
identifier,
"bool" | "number" | "string" | "tag" | "Sketch" | "SketchSurface" | "Solid" | "Plane"
> |
PrimitiveType { identifier } |
ArrayType { "[" type !member (";" Number "+"?)? "]" } |
ObjectType { "{" commaSep<ObjectProperty { PropertyName ":" type }> "}" }
}
VariableDefinition { identifier }
VariableName { identifier }
VariableName { identifier ("::" identifier)*}
ArgumentLabel { identifier }
@ -137,7 +134,7 @@ commaSep1NoTrailingComma<term> { term ("," term)* }
"(" ")"
"{" "}"
"[" "]"
"," "?" ":" "." ".." ";"
"," "?" ":" "." ".." ";" "::"
}
@external propSource kclHighlight from "./highlight"

View File

@ -29,7 +29,7 @@
"vscode-uri": "^3.1.0"
},
"devDependencies": {
"@types/node": "^22.13.10",
"@types/node": "^22.13.13",
"ts-node": "^10.9.2"
}
}

View File

@ -116,10 +116,10 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
"@types/node@^22.13.10":
version "22.13.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.10.tgz#df9ea358c5ed991266becc3109dc2dc9125d77e4"
integrity sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==
"@types/node@^22.13.13":
version "22.13.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.13.tgz#5e7d110fb509b0d4a43fbf48fa9d6e0f83e1b1e7"
integrity sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ==
dependencies:
undici-types "~6.20.0"

View File

@ -837,10 +837,10 @@ holeIndex = 6
// Create the mounting plate extrusion, holes, and fillets
part = rectShape([0, 0], 20, 20)
|> hole(circle(XY, [-holeIndex, holeIndex], holeRadius), %)
|> hole(circle(XY, [holeIndex, holeIndex], holeRadius), %)
|> hole(circle(XY, [-holeIndex, -holeIndex], holeRadius), %)
|> hole(circle(XY, [holeIndex, -holeIndex], holeRadius), %)
|> hole(circle('XY', center = [-holeIndex, holeIndex], radius = holeRadius), %)
|> hole(circle('XY', center = [holeIndex, holeIndex], radius = holeRadius), %)
|> hole(circle('XY', center = [-holeIndex, -holeIndex], radius = holeRadius), %)
|> hole(circle('XY', center = [holeIndex, -holeIndex], radius = holeRadius), %)
|> extrude(length = 2)
|> fillet(
radius = 4,
@ -860,7 +860,7 @@ part = rectShape([0, 0], 20, 20)
};
assert_eq!(
err.error.message(),
"This function requires a keyword argument 'center'"
"The input argument of std::sketch::circle requires a value with type `Sketch | Plane | Face`, but found string (text)"
);
}
@ -1347,7 +1347,7 @@ secondSketch = startSketchOn(part001, '')
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([297, 299, 0])], message: "Argument at index 1 was supposed to be type Option<kcl_lib::std::sketch::FaceTag> but found string (text)" }"#
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([297, 299, 0])], message: "Argument at index 1 was supposed to be type Option<FaceTag> but found string (text)" }"#
);
}
@ -1983,7 +1983,7 @@ someFunction('INVALID')
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([51, 60, 0]), SourceRange([65, 88, 0])], message: "Argument at index 0 was supposed to be type kcl_lib::std::sketch::SketchData but found string (text)" }"#
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([51, 60, 0]), SourceRange([65, 88, 0])], message: "Argument at index 0 was supposed to be type SketchData but found string (text)" }"#
);
}
@ -2004,7 +2004,7 @@ someFunction('INVALID')
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([103, 113, 0]), SourceRange([126, 155, 0]), SourceRange([159, 182, 0])], message: "Argument at index 0 was supposed to be type kcl_lib::std::sketch::SketchData but found string (text)" }"#
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([103, 113, 0]), SourceRange([126, 155, 0]), SourceRange([159, 182, 0])], message: "Argument at index 0 was supposed to be type SketchData but found string (text)" }"#
);
}

View File

@ -467,6 +467,10 @@ fn generate_type_from_kcl(ty: &TyData, file_name: String, example_name: String)
});
let output = hbs.render("kclType", &data)?;
let output = cleanup_type_links(
&output,
ty.referenced_types.iter().filter(|t| !DECLARED_TYPES.contains(&&***t)),
);
expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output);
Ok(())
@ -514,6 +518,13 @@ fn generate_function_from_kcl(function: &FnData, file_name: String) -> Result<()
});
let output = hbs.render("function", &data)?;
let output = cleanup_type_links(
&output,
function
.referenced_types
.iter()
.filter(|t| !DECLARED_TYPES.contains(&&***t)),
);
expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output);
Ok(())
@ -677,6 +688,12 @@ fn cleanup_type_links<'a>(output: &str, types: impl Iterator<Item = &'a String>)
}
}
// TODO handle union types generically rather than special casing them.
cleaned_output = cleaned_output.replace(
"`Sketch | Plane | Face`",
"[`Sketch`](/docs/kcl/types/Sketch) `|` [`Plane`](/docs/kcl/types/Face) `|` [`Plane`](/docs/kcl/types/Face)",
);
cleanup_static_links(&cleaned_output)
}

View File

@ -1,4 +1,4 @@
use std::str::FromStr;
use std::{collections::HashSet, str::FromStr};
use regex::Regex;
use tower_lsp::lsp_types::{
@ -9,7 +9,7 @@ use tower_lsp::lsp_types::{
use crate::{
execution::annotations,
parsing::{
ast::types::{Annotation, Node, NonCodeNode, VariableKind},
ast::types::{Annotation, Node, PrimitiveType, Type, VariableKind},
token::NumericSuffix,
},
ModuleId,
@ -59,7 +59,6 @@ impl CollectionVisitor {
format!("std::{}::", self.name)
};
let mut dd = match var.kind {
// TODO metadata for args
VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name)),
VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name)),
};
@ -322,6 +321,8 @@ pub struct FnData {
/// Code examples.
/// These are tested and we know they compile and execute.
pub examples: Vec<(String, ExampleProperties)>,
#[allow(dead_code)]
pub referenced_types: Vec<String>,
}
impl FnData {
@ -332,6 +333,17 @@ impl FnData {
};
let name = var.declaration.id.name.clone();
qual_name.push_str(&name);
let mut referenced_types = HashSet::new();
if let Some(t) = &expr.return_type {
collect_type_names(&mut referenced_types, t);
}
for p in &expr.params {
if let Some(t) = &p.type_ {
collect_type_names(&mut referenced_types, t);
}
}
FnData {
name,
qual_name,
@ -346,6 +358,7 @@ impl FnData {
summary: None,
description: None,
examples: Vec::new(),
referenced_types: referenced_types.into_iter().collect(),
}
}
@ -414,7 +427,7 @@ impl FnData {
}
#[allow(clippy::literal_string_with_formatting_args)]
fn to_autocomplete_snippet(&self) -> String {
pub(super) fn to_autocomplete_snippet(&self) -> String {
if self.name == "loft" {
return "loft([${0:sketch000}, ${1:sketch001}])${}".to_owned();
} else if self.name == "hole" {
@ -480,12 +493,12 @@ pub struct ArgData {
/// If the argument is required.
pub kind: ArgKind,
/// 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
/// This is helpful if the type is really basic, like "number" -- that won't tell the user much about
/// how this argument is meant to be used.
pub docs: Option<String>,
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ArgKind {
Special,
// Parameter is whether the arg is optional.
@ -495,38 +508,47 @@ pub enum ArgKind {
impl ArgData {
fn from_ast(arg: &crate::parsing::ast::types::Parameter) -> Self {
ArgData {
let mut result = ArgData {
name: arg.identifier.name.clone(),
ty: arg.type_.as_ref().map(|t| t.to_string()),
// Doc comments are not yet supported on parameters.
docs: None,
kind: if arg.labeled {
ArgKind::Labelled(arg.optional())
} else {
ArgKind::Special
},
}
}
};
fn _with_meta(&mut self, _meta: &[Node<NonCodeNode>]) {
// TODO use comments for docs (we can't currently get the comments for an argument)
result.with_comments(&arg.identifier.pre_comments);
result
}
pub fn get_autocomplete_snippet(&self, index: usize) -> Option<(usize, String)> {
match &self.ty {
Some(s)
if [
"Sketch",
"SketchSet",
"Solid",
"SolidSet",
"SketchSurface",
"SketchOrSurface",
]
.contains(&&**s) =>
{
Some((index, format!("${{{}:{}}}", index, "%")))
let label = if self.kind == ArgKind::Special {
String::new()
} else {
format!("{} = ", self.name)
};
match self.ty.as_deref() {
Some(s) if ["Sketch", "Solid", "Plane | Face", "Sketch | Plane | Face"].contains(&s) => {
Some((index, format!("{label}${{{}:{}}}", index, "%")))
}
Some("number") if self.kind.required() => Some((index, format!(r#"{label}${{{}:3.14}}"#, index))),
Some("Point2d") if self.kind.required() => Some((
index + 1,
format!(r#"{label}[${{{}:3.14}}, ${{{}:3.14}}]"#, index, index + 1),
)),
Some("Point3d") if self.kind.required() => Some((
index + 2,
format!(
r#"{label}[${{{}:3.14}}, ${{{}:3.14}}, ${{{}:3.14}}]"#,
index,
index + 1,
index + 2
),
)),
Some("string") if self.kind.required() => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))),
Some("bool") if self.kind.required() => Some((index, format!(r#"{label}${{{}:false}}"#, index))),
_ => None,
}
}
@ -570,12 +592,19 @@ pub struct TyData {
/// Code examples.
/// These are tested and we know they compile and execute.
pub examples: Vec<(String, ExampleProperties)>,
#[allow(dead_code)]
pub referenced_types: Vec<String>,
}
impl TyData {
fn from_ast(ty: &crate::parsing::ast::types::TypeDeclaration, mut qual_name: String) -> Self {
let name = ty.name.name.clone();
qual_name.push_str(&name);
let mut referenced_types = HashSet::new();
if let Some(t) = &ty.alias {
collect_type_names(&mut referenced_types, t);
}
TyData {
name,
qual_name,
@ -589,6 +618,7 @@ impl TyData {
summary: None,
description: None,
examples: Vec::new(),
referenced_types: referenced_types.into_iter().collect(),
}
}
@ -852,6 +882,66 @@ impl ApplyMeta for TyData {
}
}
impl ApplyMeta for ArgData {
fn apply_docs(
&mut self,
summary: Option<String>,
description: Option<String>,
_examples: Vec<(String, ExampleProperties)>,
) {
let Some(mut docs) = summary else {
return;
};
if let Some(desc) = description {
docs.push_str("\n\n");
docs.push_str(&desc);
}
self.docs = Some(docs);
}
fn deprecated(&mut self, _deprecated: bool) {
unreachable!();
}
fn doc_hidden(&mut self, _doc_hidden: bool) {
unreachable!();
}
fn impl_kind(&mut self, _impl_kind: annotations::Impl) {
unreachable!();
}
}
fn collect_type_names(acc: &mut HashSet<String>, ty: &Type) {
match ty {
Type::Primitive(primitive_type) => {
acc.insert(collect_type_names_from_primitive(primitive_type));
}
Type::Array { ty, .. } => {
acc.insert(collect_type_names_from_primitive(ty));
}
Type::Union { tys } => tys.iter().for_each(|t| {
acc.insert(collect_type_names_from_primitive(t));
}),
Type::Object { properties } => properties.iter().for_each(|p| {
if let Some(t) = &p.type_ {
collect_type_names(acc, t)
}
}),
}
}
fn collect_type_names_from_primitive(ty: &PrimitiveType) -> String {
match ty {
PrimitiveType::String => "string".to_owned(),
PrimitiveType::Number(_) => "number".to_owned(),
PrimitiveType::Boolean => "bool".to_owned(),
PrimitiveType::Tag => "tag".to_owned(),
PrimitiveType::Named(id) => id.name.clone(),
}
}
#[cfg(test)]
mod test {
use super::*;

View File

@ -927,6 +927,8 @@ fn get_autocomplete_string_from_schema(schema: &schemars::schema::Schema) -> Res
mod tests {
use pretty_assertions::assert_eq;
use crate::docs::kcl_doc::{self, DocData};
use super::StdLibFn;
#[test]
@ -1007,8 +1009,11 @@ mod tests {
#[test]
#[allow(clippy::literal_string_with_formatting_args)]
fn get_autocomplete_snippet_circle() {
let circle_fn: Box<dyn StdLibFn> = Box::new(crate::std::shapes::Circle);
let snippet = circle_fn.to_autocomplete_snippet().unwrap();
let data = kcl_doc::walk_prelude();
let DocData::Fn(circle_fn) = data.into_iter().find(|d| d.name() == "circle").unwrap() else {
panic!();
};
let snippet = circle_fn.to_autocomplete_snippet();
assert_eq!(
snippet,
r#"circle(${0:%}, center = [${1:3.14}, ${2:3.14}], radius = ${3:3.14})${}"#

View File

@ -78,13 +78,16 @@ pub(super) fn expect_properties<'a>(
}
pub(super) fn expect_ident(expr: &Expr) -> Result<&str, KclError> {
match expr {
Expr::Identifier(id) => Ok(&id.name),
e => Err(KclError::Semantic(KclErrorDetails {
message: "Unexpected settings value, expected a simple name, e.g., `mm`".to_owned(),
source_ranges: vec![e.into()],
})),
if let Expr::Name(name) = expr {
if let Some(name) = name.local_ident() {
return Ok(*name);
}
}
Err(KclError::Semantic(KclErrorDetails {
message: "Unexpected settings value, expected a simple name, e.g., `mm`".to_owned(),
source_ranges: vec![expr.into()],
}))
}
pub(super) fn get_impl(annotations: &[Node<Annotation>], source_range: SourceRange) -> Result<Option<Impl>, KclError> {

View File

@ -1,6 +1,7 @@
use std::collections::HashMap;
use async_recursion::async_recursion;
use indexmap::IndexMap;
use crate::{
engine::ExecutionKind,
@ -19,7 +20,7 @@ use crate::{
parsing::ast::types::{
Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem,
CallExpression, CallExpressionKw, Expr, FunctionExpression, IfExpression, ImportPath, ImportSelector,
ItemVisibility, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node, NodeRef,
ItemVisibility, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, Node, NodeRef,
ObjectExpression, PipeExpression, Program, TagDeclarator, Type, UnaryExpression, UnaryOperator,
},
source_range::SourceRange,
@ -514,15 +515,23 @@ impl ExecutorContext {
source_range: SourceRange,
) -> Result<Option<KclValue>, KclError> {
let path = exec_state.global.module_infos[&module_id].path.clone();
let repr = exec_state.global.module_infos[&module_id].take_repr();
let mut repr = exec_state.global.module_infos[&module_id].take_repr();
// DON'T EARLY RETURN! We need to restore the module repr
let result = match &repr {
let result = match &mut repr {
ModuleRepr::Root => Err(exec_state.circular_import_error(&path, source_range)),
ModuleRepr::Kcl(program, _) => self
.exec_module_from_ast(program, module_id, &path, exec_state, exec_kind, source_range)
.await
.map(|(val, _, _)| val),
ModuleRepr::Kcl(program, cached_items) => {
let result = self
.exec_module_from_ast(program, module_id, &path, exec_state, exec_kind, source_range)
.await;
match result {
Ok((val, env, items)) => {
*cached_items = Some((env, items));
Ok(val)
}
Err(e) => Err(e),
}
}
ModuleRepr::Foreign(geom) => super::import::send_to_engine(geom.clone(), self)
.await
.map(|geom| Some(KclValue::ImportedGeometry(geom))),
@ -578,8 +587,8 @@ impl ExecutorContext {
Expr::None(none) => KclValue::from(none),
Expr::Literal(literal) => KclValue::from_literal((**literal).clone(), &exec_state.mod_local.settings),
Expr::TagDeclarator(tag) => tag.execute(exec_state).await?,
Expr::Identifier(identifier) => {
let value = exec_state.stack().get(&identifier.name, identifier.into())?.clone();
Expr::Name(name) => {
let value = name.get_result(exec_state, self).await?.clone();
if let KclValue::Module { value: module_id, meta } = value {
self.exec_module_for_result(module_id, exec_state, ExecutionKind::Normal, metadata.source_range)
.await?
@ -610,7 +619,11 @@ impl ExecutorContext {
if let Some(std_path) = &exec_state.mod_local.settings.std_path {
let (func, props) = crate::std::std_fn(std_path, statement_kind.expect_name());
KclValue::Function {
value: FunctionSource::Std { func, props },
value: FunctionSource::Std {
func,
props,
ast: function_expression.clone(),
},
meta: vec![metadata.to_owned()],
}
} else {
@ -622,7 +635,7 @@ impl ExecutorContext {
}
} else {
// Snapshotting memory here is crucial for semantics so that we close
// over variables. Variables defined lexically later shouldn't
// over variables. Variables defined lexically later shouldn't
// be available to the function body.
KclValue::Function {
value: FunctionSource::User {
@ -710,10 +723,7 @@ impl BinaryPart {
(**literal).clone(),
&exec_state.mod_local.settings,
)),
BinaryPart::Identifier(identifier) => {
let value = exec_state.stack().get(&identifier.name, identifier.into())?;
Ok(value.clone())
}
BinaryPart::Name(name) => name.get_result(exec_state, ctx).await.cloned(),
BinaryPart::BinaryExpression(binary_expression) => binary_expression.get_result(exec_state, ctx).await,
BinaryPart::CallExpression(call_expression) => call_expression.execute(exec_state, ctx).await,
BinaryPart::CallExpressionKw(call_expression) => call_expression.execute(exec_state, ctx).await,
@ -724,6 +734,73 @@ impl BinaryPart {
}
}
impl Node<Name> {
async fn get_result<'a>(
&self,
exec_state: &'a mut ExecState,
ctx: &ExecutorContext,
) -> Result<&'a KclValue, KclError> {
if self.abs_path {
return Err(KclError::Semantic(KclErrorDetails {
message: "Absolute paths (names beginning with `::` are not yet supported)".to_owned(),
source_ranges: self.as_source_ranges(),
}));
}
if self.path.is_empty() {
return exec_state.stack().get(&self.name.name, self.into());
}
let mut mem_spec: Option<(EnvironmentRef, Vec<String>)> = None;
for p in &self.path {
let value = match mem_spec {
Some((env, exports)) => {
if !exports.contains(&p.name) {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("Item {} not found in module's exported items", p.name),
source_ranges: p.as_source_ranges(),
}));
}
exec_state
.stack()
.memory
.get_from(&p.name, env, p.as_source_range(), 0)?
}
None => exec_state.stack().get(&p.name, self.into())?,
};
let KclValue::Module { value: module_id, .. } = value else {
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Identifier in path must refer to a module, found {}",
value.human_friendly_type()
),
source_ranges: p.as_source_ranges(),
}));
};
mem_spec = Some(
ctx.exec_module_for_items(*module_id, exec_state, ExecutionKind::Normal, p.as_source_range())
.await?,
);
}
let (env, exports) = mem_spec.unwrap();
if !exports.contains(&self.name.name) {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("Item {} not found in module's exported items", self.name.name),
source_ranges: self.name.as_source_ranges(),
}));
}
exec_state
.stack()
.memory
.get_from(&self.name.name, env, self.name.as_source_range(), 0)
}
}
impl Node<MemberExpression> {
fn get_result(&self, exec_state: &mut ExecState) -> Result<KclValue, KclError> {
let property = Property::try_from(self.computed, self.property.clone(), exec_state, self.into())?;
@ -1054,11 +1131,11 @@ async fn inner_execute_pipe_body(
impl Node<CallExpressionKw> {
#[async_recursion]
pub async fn execute(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
let fn_name = &self.callee.name;
let fn_name = &self.callee;
let callsite: SourceRange = self.into();
// Build a hashmap from argument labels to the final evaluated values.
let mut fn_args = HashMap::with_capacity(self.arguments.len());
let mut fn_args = IndexMap::with_capacity(self.arguments.len());
for arg_expr in &self.arguments {
let source_range = SourceRange::from(arg_expr.arg.clone());
let metadata = Metadata { source_range };
@ -1098,6 +1175,7 @@ impl Node<CallExpressionKw> {
format!("`{fn_name}` is deprecated, see the docs for a recommended replacement"),
));
}
let op = if func.feature_tree_operation() {
let op_labeled_args = args
.kw_args
@ -1118,10 +1196,34 @@ impl Node<CallExpressionKw> {
None
};
let formals = func.args(false);
for (label, arg) in &args.kw_args.labeled {
match formals.iter().find(|p| &p.name == label) {
Some(p) => {
if !p.label_required {
exec_state.err(CompilationError::err(
arg.source_range,
format!(
"The function `{fn_name}` expects an unlabeled first parameter (`{label}`), but it is labelled in the call"
),
));
}
}
None => {
exec_state.err(CompilationError::err(
arg.source_range,
format!("`{label}` is not an argument of `{fn_name}`"),
));
}
}
}
// Attempt to call the function.
let mut return_value = {
// Don't early-return in this block.
exec_state.mut_stack().push_new_env_for_rust_call();
let result = func.std_lib_fn()(exec_state, args).await;
exec_state.mut_stack().pop_env();
if let Some(mut op) = op {
op.set_std_lib_call_is_error(result.is_err());
@ -1140,10 +1242,9 @@ impl Node<CallExpressionKw> {
Ok(return_value)
}
FunctionKind::UserDefined => {
let source_range = SourceRange::from(self);
// Clone the function so that we can use a mutable reference to
// exec_state.
let func = exec_state.stack().get(fn_name, source_range)?.clone();
let func = fn_name.get_result(exec_state, ctx).await?.clone();
// Track call operation.
let op_labeled_args = args
@ -1153,7 +1254,7 @@ impl Node<CallExpressionKw> {
.map(|(k, arg)| (k.clone(), OpArg::new(OpKclValue::from(&arg.value), arg.source_range)))
.collect();
exec_state.global.operations.push(Operation::UserDefinedFunctionCall {
name: Some(fn_name.clone()),
name: Some(fn_name.to_string()),
function_source_range: func.function_def_source_range().unwrap_or_default(),
unlabeled_arg: args
.kw_args
@ -1164,17 +1265,21 @@ impl Node<CallExpressionKw> {
source_range: callsite,
});
let return_value = func
.call_fn_kw(args, exec_state, ctx.clone(), callsite)
.await
.map_err(|e| {
// Add the call expression to the source ranges.
// TODO currently ignored by the frontend
e.add_source_ranges(vec![source_range])
})?;
let Some(fn_src) = func.as_fn() else {
return Err(KclError::Semantic(KclErrorDetails {
message: "cannot call this because it isn't a function".to_string(),
source_ranges: vec![callsite],
}));
};
let return_value = fn_src.call_kw(exec_state, ctx, args, callsite).await.map_err(|e| {
// Add the call expression to the source ranges.
// TODO currently ignored by the frontend
e.add_source_ranges(vec![callsite])
})?;
let result = return_value.ok_or_else(move || {
let mut source_ranges: Vec<SourceRange> = vec![source_range];
let mut source_ranges: Vec<SourceRange> = vec![callsite];
// We want to send the source range of the original function.
if let KclValue::Function { meta, .. } = func {
source_ranges = meta.iter().map(|m| m.source_range).collect();
@ -1197,7 +1302,7 @@ impl Node<CallExpressionKw> {
impl Node<CallExpression> {
#[async_recursion]
pub async fn execute(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
let fn_name = &self.callee.name;
let fn_name = &self.callee;
let callsite = SourceRange::from(self);
let mut fn_args: Vec<Arg> = Vec::with_capacity(self.arguments.len());
@ -1279,11 +1384,11 @@ impl Node<CallExpression> {
let source_range = SourceRange::from(self);
// Clone the function so that we can use a mutable reference to
// exec_state.
let func = exec_state.stack().get(fn_name, source_range)?.clone();
let func = fn_name.get_result(exec_state, ctx).await?.clone();
// Track call operation.
exec_state.global.operations.push(Operation::UserDefinedFunctionCall {
name: Some(fn_name.clone()),
name: Some(fn_name.to_string()),
function_source_range: func.function_def_source_range().unwrap_or_default(),
unlabeled_arg: None,
// TODO: Add the arguments for legacy positional parameters.
@ -1291,14 +1396,17 @@ impl Node<CallExpression> {
source_range: callsite,
});
let return_value = func
.call_fn(fn_args, exec_state, ctx.clone(), source_range)
.await
.map_err(|e| {
// Add the call expression to the source ranges.
// TODO currently ignored by the frontend
e.add_source_ranges(vec![source_range])
})?;
let Some(fn_src) = func.as_fn() else {
return Err(KclError::Semantic(KclErrorDetails {
message: "cannot call this because it isn't a function".to_string(),
source_ranges: vec![source_range],
}));
};
let return_value = fn_src.call(exec_state, ctx, fn_args, source_range).await.map_err(|e| {
// Add the call expression to the source ranges.
// TODO currently ignored by the frontend
e.add_source_ranges(vec![source_range])
})?;
let result = return_value.ok_or_else(move || {
let mut source_ranges: Vec<SourceRange> = vec![source_range];
@ -1784,6 +1892,27 @@ fn assign_args_to_params_kw(
mut args: crate::std::args::KwArgs,
exec_state: &mut ExecState,
) -> Result<(), KclError> {
for (label, arg) in &args.labeled {
match function_expression.params.iter().find(|p| &p.identifier.name == label) {
Some(p) => {
if !p.labeled {
exec_state.err(CompilationError::err(
arg.source_range,
format!(
"This function expects an unlabeled first parameter (`{label}`), but it is labelled in the call"
),
));
}
}
None => {
exec_state.err(CompilationError::err(
arg.source_range,
format!("`{label}` is not an argument of this function"),
));
}
}
}
// Add the arguments to the memory. A new call frame should have already
// been created.
let source_ranges = vec![function_expression.into()];
@ -1832,10 +1961,11 @@ fn assign_args_to_params_kw(
)?;
}
}
Ok(())
}
pub(crate) async fn call_user_defined_function(
async fn call_user_defined_function(
args: Vec<Arg>,
memory: EnvironmentRef,
function_expression: NodeRef<'_, FunctionExpression>,
@ -1868,7 +1998,7 @@ pub(crate) async fn call_user_defined_function(
result
}
pub(crate) async fn call_user_defined_function_kw(
async fn call_user_defined_function_kw(
args: crate::std::args::KwArgs,
memory: EnvironmentRef,
function_expression: NodeRef<'_, FunctionExpression>,
@ -1906,35 +2036,138 @@ impl FunctionSource {
&self,
exec_state: &mut ExecState,
ctx: &ExecutorContext,
args: Vec<Arg>,
source_range: SourceRange,
mut args: Vec<Arg>,
callsite: SourceRange,
) -> Result<Option<KclValue>, KclError> {
match self {
FunctionSource::Std { func, props } => {
FunctionSource::Std { props, .. } => {
if args.len() <= 1 {
let args = crate::std::Args::new_kw(
KwArgs {
unlabeled: args.pop(),
labeled: IndexMap::new(),
},
callsite,
ctx.clone(),
exec_state.mod_local.pipe_value.clone().map(|v| Arg::new(v, callsite)),
);
self.call_kw(exec_state, ctx, args, callsite).await
} else {
Err(KclError::Semantic(KclErrorDetails {
message: format!("{} requires its arguments to be labelled", props.name),
source_ranges: vec![callsite],
}))
}
}
FunctionSource::User { ast, memory, .. } => {
call_user_defined_function(args, *memory, ast, exec_state, ctx).await
}
FunctionSource::None => unreachable!(),
}
}
pub async fn call_kw(
&self,
exec_state: &mut ExecState,
ctx: &ExecutorContext,
mut args: crate::std::Args,
callsite: SourceRange,
) -> Result<Option<KclValue>, KclError> {
match self {
FunctionSource::Std { func, ast, props } => {
if props.deprecated {
exec_state.warn(CompilationError::err(
source_range,
callsite,
format!(
"`{}` is deprecated, see the docs for a recommended replacement",
props.name
),
));
}
let args = crate::std::Args::new(
args,
source_range,
ctx.clone(),
exec_state
.mod_local
.pipe_value
.clone()
.map(|v| Arg::new(v, source_range)),
);
func(exec_state, args).await.map(Some)
for (label, arg) in &mut args.kw_args.labeled {
match ast.params.iter().find(|p| &p.identifier.name == label) {
Some(p) => {
if !p.labeled {
exec_state.err(CompilationError::err(
arg.source_range,
format!(
"The function `{}` expects an unlabeled first parameter (`{label}`), but it is labelled in the call",
props.name
),
));
}
if let Some(ty) = &p.type_ {
arg.value = arg
.value
.coerce(
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
.unwrap(),
exec_state,
)
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!(
"{label} requires a value with type `{}`, but found {}",
ty.inner,
arg.value.human_friendly_type()
),
source_ranges: vec![callsite],
})
})?;
}
}
None => {
exec_state.err(CompilationError::err(
arg.source_range,
format!("`{label}` is not an argument of `{}`", props.name),
));
}
}
}
if let Some(arg) = &mut args.kw_args.unlabeled {
if let Some(p) = ast.params.iter().find(|p| !p.labeled) {
if let Some(ty) = &p.type_ {
arg.value = arg
.value
.coerce(
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
exec_state,
)
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!(
"The input argument of {} requires a value with type `{}`, but found {}",
props.name,
ty.inner,
arg.value.human_friendly_type()
),
source_ranges: vec![callsite],
})
})?;
}
}
}
// Attempt to call the function.
exec_state.mut_stack().push_new_env_for_rust_call();
let mut result = {
// Don't early-return in this block.
let result = func(exec_state, args).await;
exec_state.mut_stack().pop_env();
// TODO support recording op into the feature tree
result
}?;
update_memory_for_tags_of_geometry(&mut result, exec_state)?;
Ok(Some(result))
}
FunctionSource::User { ast, memory, .. } => {
call_user_defined_function(args, *memory, ast, exec_state, ctx).await
call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, ctx).await
}
FunctionSource::None => unreachable!(),
}

View File

@ -9,13 +9,13 @@ use crate::{
errors::KclErrorDetails,
execution::{
types::{NumericType, PrimitiveType, RuntimeType},
ExecState, ExecutorContext, Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier,
Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier,
},
parsing::ast::types::{
DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, TagDeclarator, TagNode,
},
std::{args::Arg, StdFnProps},
CompilationError, KclError, ModuleId, SourceRange,
std::StdFnProps,
KclError, ModuleId, SourceRange,
};
pub type KclObjectFields = HashMap<String, KclValue>;
@ -113,6 +113,7 @@ pub enum FunctionSource {
None,
Std {
func: crate::std::StdFn,
ast: crate::parsing::ast::types::BoxNode<FunctionExpression>,
props: StdFnProps,
},
User {
@ -550,91 +551,10 @@ impl KclValue {
Ok(*b)
}
/// If this memory item is a function, call it with the given arguments, return its val as Ok.
/// If it's not a function, return Err.
pub async fn call_fn(
&self,
args: Vec<Arg>,
exec_state: &mut ExecState,
ctx: ExecutorContext,
source_range: SourceRange,
) -> Result<Option<KclValue>, KclError> {
pub fn as_fn(&self) -> Option<&FunctionSource> {
match self {
KclValue::Function {
value: FunctionSource::Std { func, props },
..
} => {
if props.deprecated {
exec_state.warn(CompilationError::err(
source_range,
format!(
"`{}` is deprecated, see the docs for a recommended replacement",
props.name
),
));
}
exec_state.mut_stack().push_new_env_for_rust_call();
let args = crate::std::Args::new(
args,
source_range,
ctx.clone(),
exec_state
.mod_local
.pipe_value
.clone()
.map(|v| Arg::new(v, source_range)),
);
let result = func(exec_state, args).await.map(Some);
exec_state.mut_stack().pop_env();
result
}
KclValue::Function {
value: FunctionSource::User { ast, memory, .. },
..
} => crate::execution::exec_ast::call_user_defined_function(args, *memory, ast, exec_state, &ctx).await,
_ => Err(KclError::Semantic(KclErrorDetails {
message: "cannot call this because it isn't a function".to_string(),
source_ranges: vec![source_range],
})),
}
}
/// If this is a function, call it by applying keyword arguments.
/// If it's not a function, returns an error.
pub async fn call_fn_kw(
&self,
args: crate::std::Args,
exec_state: &mut ExecState,
ctx: ExecutorContext,
callsite: SourceRange,
) -> Result<Option<KclValue>, KclError> {
match self {
KclValue::Function {
value: FunctionSource::Std { func: _, props },
..
} => {
if props.deprecated {
exec_state.warn(CompilationError::err(
callsite,
format!(
"`{}` is deprecated, see the docs for a recommended replacement",
props.name
),
));
}
todo!("Implement KCL stdlib fns with keyword args");
}
KclValue::Function {
value: FunctionSource::User { ast, memory, .. },
..
} => {
crate::execution::exec_ast::call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, &ctx)
.await
}
_ => Err(KclError::Semantic(KclErrorDetails {
message: "cannot call this because it isn't a function".to_string(),
source_ranges: vec![callsite],
})),
KclValue::Function { value, .. } => Some(value),
_ => None,
}
}

View File

@ -31,7 +31,7 @@ pub fn lint_should_be_offset_plane(node: Node) -> Result<Vec<Discovered>> {
return Ok(vec![]);
};
if call.inner.callee.inner.name != "startSketchOn" {
if call.inner.callee.inner.name.name != "startSketchOn" {
return Ok(vec![]);
}

View File

@ -62,7 +62,7 @@ pub fn lint_call_expressions(exp: Node) -> Result<Vec<Discovered>> {
return Ok(vec![]);
};
match stdlib.get_either(&exp.callee.name) {
match stdlib.get_either(&exp.callee) {
FunctionKind::Core(func) => lint_too_many_args_std_lib_function(func, exp),
_ => Ok(vec![]),
}

View File

@ -105,16 +105,19 @@ impl Expr {
// TODO: LSP hover information for values/types. https://github.com/KittyCAD/modeling-app/issues/1126
Expr::None(_) => None,
Expr::Literal(_) => None,
Expr::Identifier(id) => {
if id.contains(pos) {
let name = id.name.clone();
Some(Hover::Variable {
ty: opts
.vars
Expr::Name(name) => {
if name.contains(pos) {
let ty = if let Some(name) = name.local_ident() {
opts.vars
.as_ref()
.and_then(|vars| vars.get(&name).and_then(Clone::clone)),
name,
range: id.as_source_range().to_lsp_range(code),
.and_then(|vars| vars.get(&**name).and_then(Clone::clone))
} else {
None
};
Some(Hover::Variable {
ty,
name: name.to_string(),
range: name.as_source_range().to_lsp_range(code),
})
} else {
None
@ -137,7 +140,7 @@ impl BinaryPart {
fn get_hover_value_for_position(&self, pos: usize, code: &str, opts: &HoverOpts) -> Option<Hover> {
match self {
BinaryPart::Literal(_literal) => None,
BinaryPart::Identifier(_identifier) => None,
BinaryPart::Name(_identifier) => None,
BinaryPart::BinaryExpression(binary_expression) => {
binary_expression.get_hover_value_for_position(pos, code, opts)
}
@ -163,7 +166,7 @@ impl CallExpression {
let callee_source_range: SourceRange = self.callee.clone().into();
if callee_source_range.contains(pos) {
return Some(Hover::Function {
name: self.callee.name.clone(),
name: self.callee.to_string(),
range: callee_source_range.to_lsp_range(code),
});
}
@ -173,7 +176,7 @@ impl CallExpression {
if source_range.contains(pos) {
return if opts.prefer_sig {
Some(Hover::Signature {
name: self.callee.name.clone(),
name: self.callee.to_string(),
parameter_index: index as u32,
range: source_range.to_lsp_range(code),
})
@ -192,7 +195,7 @@ impl CallExpressionKw {
let callee_source_range: SourceRange = self.callee.clone().into();
if callee_source_range.contains(pos) {
return Some(Hover::Function {
name: self.callee.name.clone(),
name: self.callee.to_string(),
range: callee_source_range.to_lsp_range(code),
});
}
@ -202,7 +205,7 @@ impl CallExpressionKw {
if source_range.contains(pos) {
return if opts.prefer_sig {
Some(Hover::Signature {
name: self.callee.name.clone(),
name: self.callee.to_string(),
parameter_index: index as u32,
range: source_range.to_lsp_range(code),
})
@ -215,7 +218,7 @@ impl CallExpressionKw {
if id.as_source_range().contains(pos) {
return Some(Hover::KwArg {
name: id.name.clone(),
callee_name: self.callee.name.clone(),
callee_name: self.callee.to_string(),
range: id.as_source_range().to_lsp_range(code),
});
}

View File

@ -523,7 +523,7 @@ impl Backend {
None => token_type_index,
};
if self.stdlib_completions.contains_key(&call_expr.callee.name) {
if self.stdlib_completions.contains_key(&call_expr.callee.name.name) {
// This is a stdlib function.
return get_modifier(vec![SemanticTokenModifier::DEFAULT_LIBRARY]);
}

View File

@ -87,6 +87,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> {
match mod_name {
"prelude" => Some(include_str!("../std/prelude.kcl")),
"math" => Some(include_str!("../std/math.kcl")),
"sketch" => Some(include_str!("../std/sketch.kcl")),
_ => None,
}
}

View File

@ -4,7 +4,7 @@ use crate::parsing::ast::types::{
Annotation, ArrayExpression, ArrayRangeExpression, Ascription, BinaryExpression, BinaryPart, BodyItem,
CallExpression, CallExpressionKw, DefaultParamVal, ElseIf, Expr, ExpressionStatement, FunctionExpression,
Identifier, IfExpression, ImportItem, ImportSelector, ImportStatement, ItemVisibility, KclNone, LabelledExpression,
Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, ObjectExpression, ObjectProperty,
Literal, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, ObjectExpression, ObjectProperty,
Parameter, PipeExpression, PipeSubstitution, PrimitiveType, Program, ReturnStatement, TagDeclarator, Type,
TypeDeclaration, UnaryExpression, VariableDeclaration, VariableDeclarator, VariableKind,
};
@ -128,7 +128,7 @@ impl Expr {
pub fn compute_digest(&mut self) -> Digest {
match self {
Expr::Literal(lit) => lit.compute_digest(),
Expr::Identifier(id) => id.compute_digest(),
Expr::Name(id) => id.compute_digest(),
Expr::TagDeclarator(tag) => tag.compute_digest(),
Expr::BinaryExpression(be) => be.compute_digest(),
Expr::FunctionExpression(fe) => fe.compute_digest(),
@ -157,7 +157,7 @@ impl BinaryPart {
pub fn compute_digest(&mut self) -> Digest {
match self {
BinaryPart::Literal(lit) => lit.compute_digest(),
BinaryPart::Identifier(id) => id.compute_digest(),
BinaryPart::Name(id) => id.compute_digest(),
BinaryPart::BinaryExpression(be) => be.compute_digest(),
BinaryPart::CallExpression(ce) => ce.compute_digest(),
BinaryPart::CallExpressionKw(ce) => ce.compute_digest(),
@ -377,6 +377,17 @@ impl Identifier {
});
}
impl Name {
compute_digest!(|slf, hasher| {
hasher.update(slf.name.compute_digest());
for p in &mut slf.path {
hasher.update(p.compute_digest());
}
if slf.abs_path {
hasher.update([1]);
}
});
}
impl TagDeclarator {
compute_digest!(|slf, hasher| {
let name = slf.name.as_bytes();

View File

@ -23,7 +23,7 @@ impl Expr {
pub fn module_id(&self) -> ModuleId {
match self {
Expr::Literal(literal) => literal.module_id,
Expr::Identifier(identifier) => identifier.module_id,
Expr::Name(identifier) => identifier.module_id,
Expr::TagDeclarator(tag) => tag.module_id,
Expr::BinaryExpression(binary_expression) => binary_expression.module_id,
Expr::FunctionExpression(function_expression) => function_expression.module_id,
@ -48,7 +48,7 @@ impl BinaryPart {
pub fn module_id(&self) -> ModuleId {
match self {
BinaryPart::Literal(literal) => literal.module_id,
BinaryPart::Identifier(identifier) => identifier.module_id,
BinaryPart::Name(identifier) => identifier.module_id,
BinaryPart::BinaryExpression(binary_expression) => binary_expression.module_id,
BinaryPart::CallExpression(call_expression) => call_expression.module_id,
BinaryPart::CallExpressionKw(call_expression) => call_expression.module_id,

View File

@ -35,6 +35,7 @@ mod condition;
mod literal_value;
mod none;
#[derive(Debug)]
pub enum Definition<'a> {
Variable(&'a VariableDeclarator),
Import(NodeRef<'a, ImportStatement>),
@ -166,6 +167,18 @@ impl<T> Node<T> {
self.pre_comments = comments;
self.comment_start = start;
}
pub fn map_ref<'a, U: 'a>(&'a self, f: fn(&'a T) -> U) -> Node<U> {
Node {
inner: f(&self.inner),
start: self.start,
end: self.end,
module_id: self.module_id,
outer_attrs: self.outer_attrs.clone(),
pre_comments: self.pre_comments.clone(),
comment_start: self.start,
}
}
}
impl<T> Deref for Node<T> {
@ -762,7 +775,7 @@ impl From<&BodyItem> for SourceRange {
#[allow(clippy::large_enum_variant)]
pub enum Expr {
Literal(BoxNode<Literal>),
Identifier(BoxNode<Identifier>),
Name(BoxNode<Name>),
TagDeclarator(BoxNode<TagDeclarator>),
BinaryExpression(BoxNode<BinaryExpression>),
FunctionExpression(BoxNode<FunctionExpression>),
@ -814,7 +827,7 @@ impl Expr {
Expr::FunctionExpression(_func_exp) => None,
Expr::CallExpression(_call_exp) => None,
Expr::CallExpressionKw(_call_exp) => None,
Expr::Identifier(_ident) => None,
Expr::Name(_ident) => None,
Expr::TagDeclarator(_tag) => None,
Expr::PipeExpression(pipe_exp) => Some(&pipe_exp.non_code_meta),
Expr::UnaryExpression(_unary_exp) => None,
@ -842,7 +855,7 @@ impl Expr {
Expr::FunctionExpression(ref mut func_exp) => func_exp.replace_value(source_range, new_value),
Expr::CallExpression(ref mut call_exp) => call_exp.replace_value(source_range, new_value),
Expr::CallExpressionKw(ref mut call_exp) => call_exp.replace_value(source_range, new_value),
Expr::Identifier(_) => {}
Expr::Name(_) => {}
Expr::TagDeclarator(_) => {}
Expr::PipeExpression(ref mut pipe_exp) => pipe_exp.replace_value(source_range, new_value),
Expr::UnaryExpression(ref mut unary_exp) => unary_exp.replace_value(source_range, new_value),
@ -857,7 +870,7 @@ impl Expr {
pub fn start(&self) -> usize {
match self {
Expr::Literal(literal) => literal.start,
Expr::Identifier(identifier) => identifier.start,
Expr::Name(identifier) => identifier.start,
Expr::TagDeclarator(tag) => tag.start,
Expr::BinaryExpression(binary_expression) => binary_expression.start,
Expr::FunctionExpression(function_expression) => function_expression.start,
@ -880,7 +893,7 @@ impl Expr {
pub fn end(&self) -> usize {
match self {
Expr::Literal(literal) => literal.end,
Expr::Identifier(identifier) => identifier.end,
Expr::Name(identifier) => identifier.end,
Expr::TagDeclarator(tag) => tag.end,
Expr::BinaryExpression(binary_expression) => binary_expression.end,
Expr::FunctionExpression(function_expression) => function_expression.end,
@ -904,7 +917,7 @@ impl Expr {
fn rename_identifiers(&mut self, old_name: &str, new_name: &str) {
match self {
Expr::Literal(_literal) => {}
Expr::Identifier(ref mut identifier) => identifier.rename(old_name, new_name),
Expr::Name(ref mut identifier) => identifier.rename(old_name, new_name),
Expr::TagDeclarator(ref mut tag) => tag.rename(old_name, new_name),
Expr::BinaryExpression(ref mut binary_expression) => {
binary_expression.rename_identifiers(old_name, new_name)
@ -934,7 +947,7 @@ impl Expr {
pub fn get_constraint_level(&self) -> ConstraintLevel {
match self {
Expr::Literal(literal) => literal.get_constraint_level(),
Expr::Identifier(identifier) => identifier.get_constraint_level(),
Expr::Name(identifier) => identifier.get_constraint_level(),
Expr::TagDeclarator(tag) => tag.get_constraint_level(),
Expr::BinaryExpression(binary_expression) => binary_expression.get_constraint_level(),
@ -967,35 +980,6 @@ impl Expr {
}
}
/// Describe this expression's type for a human, for typechecking.
/// This is a best-effort function, it's OK to give a shitty string here (but we should work on improving it)
pub fn human_friendly_type(&self) -> &'static str {
match self {
Expr::Literal(node) => match node.inner.value {
LiteralValue::Number { .. } => "number",
LiteralValue::String(_) => "string (text)",
LiteralValue::Bool(_) => "boolean (true/false value)",
},
Expr::Identifier(_) => "named constant",
Expr::TagDeclarator(_) => "tag declarator",
Expr::BinaryExpression(_) => "expression",
Expr::FunctionExpression(_) => "function definition",
Expr::CallExpression(_) => "function call",
Expr::CallExpressionKw(_) => "function call",
Expr::PipeExpression(_) => "pipeline of function calls",
Expr::PipeSubstitution(_) => "left-hand side of a |> pipeline",
Expr::ArrayExpression(_) => "array",
Expr::ArrayRangeExpression(_) => "array",
Expr::ObjectExpression(_) => "object",
Expr::MemberExpression(_) => "property of an object/array",
Expr::UnaryExpression(_) => "expression",
Expr::IfExpression(_) => "if expression",
Expr::LabelledExpression(_) => "labelled expression",
Expr::AscribedExpression(_) => "type-ascribed expression",
Expr::None(_) => "none",
}
}
pub fn literal_bool(&self) -> Option<bool> {
match self {
Expr::Literal(lit) => match lit.value {
@ -1028,7 +1012,7 @@ impl Expr {
pub fn ident_name(&self) -> Option<&str> {
match self {
Expr::Identifier(ident) => Some(&ident.name),
Expr::Name(ident) => Some(&ident.name.name),
_ => None,
}
}
@ -1102,7 +1086,7 @@ impl Ascription {
#[serde(tag = "type")]
pub enum BinaryPart {
Literal(BoxNode<Literal>),
Identifier(BoxNode<Identifier>),
Name(BoxNode<Name>),
BinaryExpression(BoxNode<BinaryExpression>),
CallExpression(BoxNode<CallExpression>),
CallExpressionKw(BoxNode<CallExpressionKw>),
@ -1128,7 +1112,7 @@ impl BinaryPart {
pub fn get_constraint_level(&self) -> ConstraintLevel {
match self {
BinaryPart::Literal(literal) => literal.get_constraint_level(),
BinaryPart::Identifier(identifier) => identifier.get_constraint_level(),
BinaryPart::Name(identifier) => identifier.get_constraint_level(),
BinaryPart::BinaryExpression(binary_expression) => binary_expression.get_constraint_level(),
BinaryPart::CallExpression(call_expression) => call_expression.get_constraint_level(),
BinaryPart::CallExpressionKw(call_expression) => call_expression.get_constraint_level(),
@ -1141,7 +1125,7 @@ impl BinaryPart {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
match self {
BinaryPart::Literal(_) => {}
BinaryPart::Identifier(_) => {}
BinaryPart::Name(_) => {}
BinaryPart::BinaryExpression(ref mut binary_expression) => {
binary_expression.replace_value(source_range, new_value)
}
@ -1162,7 +1146,7 @@ impl BinaryPart {
pub fn start(&self) -> usize {
match self {
BinaryPart::Literal(literal) => literal.start,
BinaryPart::Identifier(identifier) => identifier.start,
BinaryPart::Name(identifier) => identifier.start,
BinaryPart::BinaryExpression(binary_expression) => binary_expression.start,
BinaryPart::CallExpression(call_expression) => call_expression.start,
BinaryPart::CallExpressionKw(call_expression) => call_expression.start,
@ -1175,7 +1159,7 @@ impl BinaryPart {
pub fn end(&self) -> usize {
match self {
BinaryPart::Literal(literal) => literal.end,
BinaryPart::Identifier(identifier) => identifier.end,
BinaryPart::Name(identifier) => identifier.end,
BinaryPart::BinaryExpression(binary_expression) => binary_expression.end,
BinaryPart::CallExpression(call_expression) => call_expression.end,
BinaryPart::CallExpressionKw(call_expression) => call_expression.end,
@ -1189,7 +1173,7 @@ impl BinaryPart {
fn rename_identifiers(&mut self, old_name: &str, new_name: &str) {
match self {
BinaryPart::Literal(_literal) => {}
BinaryPart::Identifier(ref mut identifier) => identifier.rename(old_name, new_name),
BinaryPart::Name(ref mut identifier) => identifier.rename(old_name, new_name),
BinaryPart::BinaryExpression(ref mut binary_expression) => {
binary_expression.rename_identifiers(old_name, new_name)
}
@ -1418,13 +1402,13 @@ impl Annotation {
pub fn new_from_meta_settings(settings: &crate::execution::MetaSettings) -> Annotation {
let mut properties: Vec<Node<ObjectProperty>> = vec![ObjectProperty::new(
Identifier::new(annotations::SETTINGS_UNIT_LENGTH),
Expr::Identifier(Box::new(Identifier::new(&settings.default_length_units.to_string()))),
Expr::Name(Box::new(Name::new(&settings.default_length_units.to_string()))),
)];
if settings.default_angle_units != Default::default() {
properties.push(ObjectProperty::new(
Identifier::new(annotations::SETTINGS_UNIT_ANGLE),
Expr::Identifier(Box::new(Identifier::new(&settings.default_angle_units.to_string()))),
Expr::Name(Box::new(Name::new(&settings.default_angle_units.to_string()))),
));
}
Annotation {
@ -1689,7 +1673,7 @@ pub struct ExpressionStatement {
#[ts(export)]
#[serde(tag = "type")]
pub struct CallExpression {
pub callee: Node<Identifier>,
pub callee: Node<Name>,
pub arguments: Vec<Expr>,
#[serde(default, skip_serializing_if = "Option::is_none")]
@ -1701,7 +1685,7 @@ pub struct CallExpression {
#[ts(export)]
#[serde(rename_all = "camelCase", tag = "type")]
pub struct CallExpressionKw {
pub callee: Node<Identifier>,
pub callee: Node<Name>,
pub unlabeled: Option<Expr>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub arguments: Vec<LabeledArg>,
@ -1775,7 +1759,7 @@ impl Node<CallExpressionKw> {
impl CallExpression {
pub fn new(name: &str, arguments: Vec<Expr>) -> Result<Node<Self>, KclError> {
Ok(Node::no_src(Self {
callee: Identifier::new(name),
callee: Name::new(name),
arguments,
digest: None,
}))
@ -1807,7 +1791,7 @@ impl CallExpression {
impl CallExpressionKw {
pub fn new(name: &str, unlabeled: Option<Expr>, arguments: Vec<LabeledArg>) -> Result<Node<Self>, KclError> {
Ok(Node::no_src(Self {
callee: Identifier::new(name),
callee: Name::new(name),
unlabeled,
arguments,
digest: None,
@ -2192,13 +2176,8 @@ impl Node<Identifier> {
/// Get the constraint level for this identifier.
/// Identifier are always fully constrained.
pub fn get_constraint_level(&self) -> ConstraintLevel {
match &*self.name {
"XY" | "XZ" | "YZ" => ConstraintLevel::None {
source_ranges: vec![self.into()],
},
_ => ConstraintLevel::Full {
source_ranges: vec![self.into()],
},
ConstraintLevel::Full {
source_ranges: vec![self.into()],
}
}
}
@ -2223,6 +2202,99 @@ impl Identifier {
}
}
/// A qualified name, e.g., `foo`, `bar::foo`, or `::bar::foo`.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub struct Name {
pub name: Node<Identifier>,
// The qualifying parts of the name.
pub path: NodeList<Identifier>,
// The path starts with `::`.
pub abs_path: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)]
pub digest: Option<Digest>,
}
impl Node<Name> {
pub fn get_constraint_level(&self) -> ConstraintLevel {
match &*self.name.name {
"XY" | "XZ" | "YZ" => ConstraintLevel::None {
source_ranges: vec![self.into()],
},
_ => ConstraintLevel::Full {
source_ranges: vec![self.into()],
},
}
}
}
impl Name {
pub fn new(name: &str) -> Node<Self> {
Node::no_src(Name {
name: Node::no_src(Identifier {
name: name.to_string(),
digest: None,
}),
path: Vec::new(),
abs_path: false,
digest: None,
})
}
pub fn local_ident(&self) -> Option<Node<&str>> {
if self.path.is_empty() && !self.abs_path {
Some(self.name.map_ref(|n| &n.name))
} else {
None
}
}
/// Rename all identifiers that have the old name to the new given name.
fn rename(&mut self, old_name: &str, new_name: &str) {
if let Some(n) = self.local_ident() {
if n.inner == old_name {
self.name.name = new_name.to_owned();
}
}
}
}
impl From<Node<Identifier>> for Node<Name> {
fn from(value: Node<Identifier>) -> Self {
let start = value.start;
let end = value.end;
let mod_id = value.module_id;
Node::new(
Name {
name: value,
path: Vec::new(),
abs_path: false,
digest: None,
},
start,
end,
mod_id,
)
}
}
impl fmt::Display for Name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.abs_path {
f.write_str("::")?;
}
for p in &self.path {
f.write_str(&p.name)?;
f.write_str("::")?;
}
f.write_str(&self.name.name)
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
#[ts(export)]
#[serde(tag = "type")]

View File

@ -18,7 +18,6 @@ use super::{
DeprecationKind,
};
use crate::{
docs::StdLibFn,
errors::{CompilationError, Severity, Tag},
execution::types::ArrayLen,
parsing::{
@ -27,9 +26,9 @@ use crate::{
BoxNode, CallExpression, CallExpressionKw, CommentStyle, DefaultParamVal, ElseIf, Expr,
ExpressionStatement, FunctionExpression, Identifier, IfExpression, ImportItem, ImportSelector,
ImportStatement, ItemVisibility, LabeledArg, Literal, LiteralIdentifier, LiteralValue, MemberExpression,
MemberObject, Node, NodeList, NonCodeMeta, NonCodeNode, NonCodeValue, ObjectExpression, ObjectProperty,
Parameter, PipeExpression, PipeSubstitution, PrimitiveType, Program, ReturnStatement, Shebang,
TagDeclarator, Type, TypeDeclaration, UnaryExpression, UnaryOperator, VariableDeclaration,
MemberObject, Name, Node, NodeList, NonCodeMeta, NonCodeNode, NonCodeValue, ObjectExpression,
ObjectProperty, Parameter, PipeExpression, PipeSubstitution, PrimitiveType, Program, ReturnStatement,
Shebang, TagDeclarator, Type, TypeDeclaration, UnaryExpression, UnaryOperator, VariableDeclaration,
VariableDeclarator, VariableKind,
},
math::BinaryExpressionToken,
@ -631,7 +630,7 @@ fn operand(i: &mut TokenSlice) -> PResult<BinaryPart> {
}
Expr::UnaryExpression(x) => BinaryPart::UnaryExpression(x),
Expr::Literal(x) => BinaryPart::Literal(x),
Expr::Identifier(x) => BinaryPart::Identifier(x),
Expr::Name(x) => BinaryPart::Name(x),
Expr::BinaryExpression(x) => BinaryPart::BinaryExpression(x),
Expr::CallExpression(x) => BinaryPart::CallExpression(x),
Expr::CallExpressionKw(x) => BinaryPart::CallExpressionKw(x),
@ -891,7 +890,7 @@ fn object_property_same_key_and_val(i: &mut TokenSlice) -> PResult<Node<ObjectPr
key.end,
key.module_id,
ObjectProperty {
value: Expr::Identifier(Box::new(key.clone())),
value: Expr::Name(Box::new(key.clone().into())),
key,
digest: None,
},
@ -2069,7 +2068,7 @@ fn expr_allowed_in_pipe_expr(i: &mut TokenSlice) -> PResult<Expr> {
literal.map(Expr::Literal),
fn_call.map(Box::new).map(Expr::CallExpression),
fn_call_kw.map(Box::new).map(Expr::CallExpressionKw),
nameable_identifier.map(Box::new).map(Expr::Identifier),
name.map(Box::new).map(Expr::Name),
array,
object.map(Box::new).map(Expr::ObjectExpression),
pipe_sub.map(Box::new).map(Expr::PipeSubstitution),
@ -2088,7 +2087,7 @@ fn possible_operands(i: &mut TokenSlice) -> PResult<Expr> {
member_expression.map(Box::new).map(Expr::MemberExpression),
literal.map(Expr::Literal),
fn_call.map(Box::new).map(Expr::CallExpression),
nameable_identifier.map(Box::new).map(Expr::Identifier),
name.map(Box::new).map(Expr::Name),
binary_expr_in_parens.map(Box::new).map(Expr::BinaryExpression),
unnecessarily_bracketed,
))
@ -2360,6 +2359,35 @@ fn nameable_identifier(i: &mut TokenSlice) -> PResult<Node<Identifier>> {
Ok(result)
}
fn name(i: &mut TokenSlice) -> PResult<Node<Name>> {
let abs_path = opt(double_colon).parse_next(i)?;
let mut idents: NodeList<Identifier> = separated(1.., nameable_identifier, double_colon)
.parse_next(i)
.map_err(|e| e.backtrack())?;
let mut start = idents[0].start;
if let Some(abs_path) = &abs_path {
start = abs_path.start;
}
let abs_path = abs_path.is_some();
let name = idents.pop().unwrap();
let end = name.end;
let module_id = name.module_id;
Ok(Node::new(
Name {
name,
path: idents,
abs_path,
digest: None,
},
start,
end,
module_id,
))
}
impl TryFrom<Token> for Node<TagDeclarator> {
type Error = CompilationError;
@ -2671,6 +2699,10 @@ fn plus(i: &mut TokenSlice) -> PResult<Token> {
one_of((TokenType::Operator, "+")).parse_next(i)
}
fn double_colon(i: &mut TokenSlice) -> PResult<Token> {
TokenType::DoubleColon.parse_from(i)
}
fn equals(i: &mut TokenSlice) -> PResult<Token> {
one_of((TokenType::Operator, "="))
.context(expected("the equals operator, ="))
@ -2851,15 +2883,40 @@ fn uom_for_type(i: &mut TokenSlice) -> PResult<NumericSuffix> {
any.try_map(|t: Token| t.value.parse()).parse_next(i)
}
fn comment(i: &mut TokenSlice) -> PResult<Node<String>> {
any.verify_map(|token: Token| {
let value = match token.token_type {
TokenType::LineComment => token.value,
TokenType::BlockComment => token.value,
_ => return None,
};
Some(Node::new(value, token.start, token.end, token.module_id))
})
.context(expected("Comment"))
.parse_next(i)
}
fn comments(i: &mut TokenSlice) -> PResult<Node<Vec<String>>> {
let comments: Vec<Node<String>> = repeat(1.., (comment, opt(whitespace)).map(|(c, _)| c)).parse_next(i)?;
let start = comments[0].start;
let module_id = comments[0].module_id;
let end = comments.last().unwrap().end;
let inner = comments.into_iter().map(|n| n.inner).collect();
Ok(Node::new(inner, start, end, module_id))
}
struct ParamDescription {
labeled: bool,
arg_name: Token,
type_: std::option::Option<Node<Type>>,
default_value: Option<DefaultParamVal>,
comments: Option<Node<Vec<String>>>,
}
fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
let (found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = (
let (_, comments, found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = (
opt(whitespace),
opt(comments),
opt(at_sign),
any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"),
opt(question_mark),
@ -2869,6 +2926,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
opt((equals, opt(whitespace), literal).map(|(_, _, literal)| literal)),
)
.parse_next(i)?;
Ok(ParamDescription {
labeled: found_at_sign.is_none(),
arg_name,
@ -2883,6 +2941,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
return Err(ErrMode::Backtrack(ContextError::from(e)));
}
},
comments,
})
}
@ -2892,6 +2951,7 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> {
let candidates: Vec<_> = separated(0.., parameter, comma_sep)
.context(expected("function parameters"))
.parse_next(i)?;
opt(comma_sep).parse_next(i)?;
// Make sure all those tokens are valid parameters.
let params: Vec<Parameter> = candidates
@ -2902,8 +2962,13 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> {
arg_name,
type_,
default_value,
comments,
}| {
let identifier = Node::<Identifier>::try_from(arg_name)?;
let mut identifier = Node::<Identifier>::try_from(arg_name)?;
if let Some(comments) = comments {
identifier.comment_start = comments.start;
identifier.pre_comments = comments.inner;
}
Ok(Parameter {
identifier,
@ -2957,76 +3022,6 @@ fn binding_name(i: &mut TokenSlice) -> PResult<Node<Identifier>> {
.parse_next(i)
}
/// Typecheck the arguments in a keyword fn call.
fn typecheck_all_kw(std_fn: Box<dyn StdLibFn>, args: &[&LabeledArg]) -> PResult<()> {
for arg in args {
let label = &arg.label;
let expr = &arg.arg;
if let Some(spec_arg) = std_fn.args(false).iter().find(|spec_arg| spec_arg.name == label.name) {
typecheck(spec_arg, &expr)?;
}
}
Ok(())
}
/// Type check the arguments in a positional fn call.
fn typecheck_all_positional(std_fn: Box<dyn StdLibFn>, args: &[&Expr]) -> PResult<()> {
for (i, spec_arg) in std_fn.args(false).iter().enumerate() {
let Some(arg) = &args.get(i) else {
// The executor checks the number of arguments, so we don't need to check it here.
continue;
};
typecheck(spec_arg, arg)?;
}
Ok(())
}
fn typecheck(spec_arg: &crate::docs::StdLibFnArg, arg: &&Expr) -> PResult<()> {
match spec_arg.type_.as_ref() {
"TagNode" => match &arg {
Expr::Identifier(_) => {
// These are fine since we want someone to be able to map a variable to a tag declarator.
}
Expr::TagDeclarator(tag) => {
// TODO: Remove this check. It should be redundant.
tag.clone()
.into_valid_binding_name()
.map_err(|e| ErrMode::Cut(ContextError::from(e)))?;
}
e => {
return Err(ErrMode::Cut(
CompilationError::fatal(
SourceRange::from(*arg),
format!(
"Expected a tag declarator like `$name`, found {}",
e.human_friendly_type()
),
)
.into(),
));
}
},
"TagIdentifier" => match &arg {
Expr::Identifier(_) => {}
Expr::MemberExpression(_) => {}
e => {
return Err(ErrMode::Cut(
CompilationError::fatal(
SourceRange::from(*arg),
format!(
"Expected a tag identifier like `tagName`, found {}",
e.human_friendly_type()
),
)
.into(),
));
}
},
_ => {}
}
Ok(())
}
/// Either a positional or keyword function call.
fn fn_call_pos_or_kw(i: &mut TokenSlice) -> PResult<Expr> {
alt((
@ -3047,15 +3042,10 @@ fn labelled_fn_call(i: &mut TokenSlice) -> PResult<Expr> {
}
fn fn_call(i: &mut TokenSlice) -> PResult<Node<CallExpression>> {
let fn_name = nameable_identifier(i)?;
let fn_name = name(i)?;
opt(whitespace).parse_next(i)?;
let _ = terminated(open_paren, opt(whitespace)).parse_next(i)?;
let args = arguments(i)?;
if let Some(std_fn) = crate::std::get_stdlib_fn(&fn_name.name) {
let just_args: Vec<_> = args.iter().collect();
typecheck_all_positional(std_fn, &just_args)?;
}
let end = preceded(opt(whitespace), close_paren).parse_next(i)?.end;
let result = Node::new_node(
@ -3069,17 +3059,15 @@ fn fn_call(i: &mut TokenSlice) -> PResult<Node<CallExpression>> {
},
);
if let Some(suggestion) = super::deprecation(&result.callee.name, DeprecationKind::Function) {
let callee_str = result.callee.name.name.to_string();
if let Some(suggestion) = super::deprecation(&callee_str, DeprecationKind::Function) {
ParseContext::warn(
CompilationError::err(
result.as_source_range(),
format!(
"Calling `{}` is deprecated, prefer using `{}`.",
result.callee.name, suggestion
),
format!("Calling `{}` is deprecated, prefer using `{}`.", callee_str, suggestion),
)
.with_suggestion(
format!("Replace `{}` with `{}`", result.callee.name, suggestion),
format!("Replace `{}` with `{}`", callee_str, suggestion),
suggestion,
None,
Tag::Deprecated,
@ -3091,7 +3079,7 @@ fn fn_call(i: &mut TokenSlice) -> PResult<Node<CallExpression>> {
}
fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
let fn_name = nameable_identifier(i)?;
let fn_name = name(i)?;
opt(whitespace).parse_next(i)?;
let _ = open_paren.parse_next(i)?;
ignore_whitespace(i);
@ -3147,10 +3135,6 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
Ok((args, non_code_nodes))
},
)?;
if let Some(std_fn) = crate::std::get_stdlib_fn(&fn_name.name) {
let just_args: Vec<_> = args.iter().collect();
typecheck_all_kw(std_fn, &just_args)?;
}
ignore_whitespace(i);
opt(comma_sep).parse_next(i)?;
let end = close_paren.parse_next(i)?.end;
@ -3172,17 +3156,15 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
},
);
if let Some(suggestion) = super::deprecation(&result.callee.name, DeprecationKind::Function) {
let callee_str = result.callee.name.name.to_string();
if let Some(suggestion) = super::deprecation(&callee_str, DeprecationKind::Function) {
ParseContext::warn(
CompilationError::err(
result.as_source_range(),
format!(
"Calling `{}` is deprecated, prefer using `{}`.",
result.callee.name, suggestion
),
format!("Calling `{}` is deprecated, prefer using `{}`.", callee_str, suggestion),
)
.with_suggestion(
format!("Replace `{}` with `{}`", result.callee.name, suggestion),
format!("Replace `{}` with `{}`", callee_str, suggestion),
suggestion,
None,
Tag::Deprecated,
@ -3244,6 +3226,17 @@ mod tests {
}
}
#[test]
fn parse_names() {
for (test, expected_len) in [("someVar", 0), ("::foo", 0), ("foo::bar::baz", 2)] {
let tokens = crate::parsing::token::lex(test, ModuleId::default()).unwrap();
match name.parse(tokens.as_slice()) {
Ok(n) => assert_eq!(n.path.len(), expected_len, "Could not parse name from `{test}`: {n:?}"),
Err(e) => panic!("Could not parse name from `{test}`: {e:?}"),
}
}
}
#[test]
fn weird_program_unclosed_paren() {
let tokens = crate::parsing::token::lex("fn firstPrime(", ModuleId::default()).unwrap();

View File

@ -18,17 +18,33 @@ expression: actual
"type": "BinaryExpression",
"operator": "*",
"left": {
"type": "Identifier",
"type": "Identifier",
"name": "distance",
"type": "Name",
"type": "Name",
"name": {
"type": "Identifier",
"name": "distance",
"start": 0,
"end": 8,
"commentStart": 0
},
"path": [],
"abs_path": false,
"start": 0,
"end": 8,
"commentStart": 0
},
"right": {
"type": "Identifier",
"type": "Identifier",
"name": "p",
"type": "Name",
"type": "Name",
"name": {
"type": "Identifier",
"name": "p",
"start": 11,
"end": 12,
"commentStart": 11
},
"path": [],
"abs_path": false,
"start": 11,
"end": 12,
"commentStart": 11
@ -38,9 +54,17 @@ expression: actual
"commentStart": 0
},
"right": {
"type": "Identifier",
"type": "Identifier",
"name": "FOS",
"type": "Name",
"type": "Name",
"name": {
"type": "Identifier",
"name": "FOS",
"start": 15,
"end": 18,
"commentStart": 15
},
"path": [],
"abs_path": false,
"start": 15,
"end": 18,
"commentStart": 15
@ -70,17 +94,33 @@ expression: actual
"type": "BinaryExpression",
"operator": "*",
"left": {
"type": "Identifier",
"type": "Identifier",
"name": "sigmaAllow",
"type": "Name",
"type": "Name",
"name": {
"type": "Identifier",
"name": "sigmaAllow",
"start": 26,
"end": 36,
"commentStart": 26
},
"path": [],
"abs_path": false,
"start": 26,
"end": 36,
"commentStart": 26
},
"right": {
"type": "Identifier",
"type": "Identifier",
"name": "width",
"type": "Name",
"type": "Name",
"name": {
"type": "Identifier",
"name": "width",
"start": 39,
"end": 44,
"commentStart": 39
},
"path": [],
"abs_path": false,
"start": 39,
"end": 44,
"commentStart": 39

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 26,
"end": 28,
"name": "XY",
"name": {
"commentStart": 26,
"end": 28,
"name": "XY",
"start": 26,
"type": "Identifier"
},
"path": [],
"start": 26,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 12,
"end": 25,
"name": "startSketchOn",
"name": {
"commentStart": 12,
"end": 25,
"name": "startSketchOn",
"start": 12,
"type": "Identifier"
},
"path": [],
"start": 12,
"type": "Identifier"
"type": "Name"
},
"commentStart": 12,
"end": 29,
@ -86,11 +102,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 37,
"end": 51,
"name": "startProfileAt",
"name": {
"commentStart": 37,
"end": 51,
"name": "startProfileAt",
"start": 37,
"type": "Identifier"
},
"path": [],
"start": 37,
"type": "Identifier"
"type": "Name"
},
"commentStart": 37,
"end": 62,
@ -142,11 +166,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 70,
"end": 74,
"name": "line",
"name": {
"commentStart": 70,
"end": 74,
"name": "line",
"start": 70,
"type": "Identifier"
},
"path": [],
"start": 70,
"type": "Identifier"
"type": "Name"
},
"commentStart": 70,
"end": 86,
@ -206,11 +238,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 94,
"end": 107,
"name": "tangentialArc",
"name": {
"commentStart": 94,
"end": 107,
"name": "tangentialArc",
"start": 94,
"type": "Identifier"
},
"path": [],
"start": 94,
"type": "Identifier"
"type": "Name"
},
"commentStart": 94,
"end": 119,
@ -270,11 +310,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 127,
"end": 131,
"name": "line",
"name": {
"commentStart": 127,
"end": 131,
"name": "line",
"start": 127,
"type": "Identifier"
},
"path": [],
"start": 127,
"type": "Identifier"
"type": "Name"
},
"commentStart": 127,
"end": 144,
@ -308,11 +356,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 152,
"end": 159,
"name": "extrude",
"name": {
"commentStart": 152,
"end": 159,
"name": "extrude",
"start": 152,
"type": "Identifier"
},
"path": [],
"start": 152,
"type": "Identifier"
"type": "Name"
},
"commentStart": 152,
"end": 170,

View File

@ -18,12 +18,20 @@ expression: actual
},
"init": {
"argument": {
"abs_path": false,
"commentStart": 6,
"end": 11,
"name": "scale",
"name": {
"commentStart": 6,
"end": 11,
"name": "scale",
"start": 6,
"type": "Identifier"
},
"path": [],
"start": 6,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"commentStart": 5,
"end": 11,

View File

@ -62,11 +62,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 4,
"name": "line",
"name": {
"commentStart": 0,
"end": 4,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 0,
"end": 27,

View File

@ -65,11 +65,19 @@ expression: actual
"expression": {
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 62,
"end": 78,
"name": "firstPrimeNumber",
"name": {
"commentStart": 62,
"end": 78,
"name": "firstPrimeNumber",
"start": 62,
"type": "Identifier"
},
"path": [],
"start": 62,
"type": "Identifier"
"type": "Name"
},
"commentStart": 62,
"end": 80,

View File

@ -83,11 +83,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 54,
"end": 59,
"name": "thing",
"name": {
"commentStart": 54,
"end": 59,
"name": "thing",
"start": 54,
"type": "Identifier"
},
"path": [],
"start": 54,
"type": "Identifier"
"type": "Name"
},
"commentStart": 54,
"end": 66,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 25,
"end": 27,
"name": "XY",
"name": {
"commentStart": 25,
"end": 27,
"name": "XY",
"start": 25,
"type": "Identifier"
},
"path": [],
"start": 25,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 11,
"end": 24,
"name": "startSketchOn",
"name": {
"commentStart": 11,
"end": 24,
"name": "startSketchOn",
"start": 11,
"type": "Identifier"
},
"path": [],
"start": 11,
"type": "Identifier"
"type": "Name"
},
"commentStart": 11,
"end": 28,
@ -86,11 +102,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 40,
"end": 54,
"name": "startProfileAt",
"name": {
"commentStart": 40,
"end": 54,
"name": "startProfileAt",
"start": 40,
"type": "Identifier"
},
"path": [],
"start": 40,
"type": "Identifier"
"type": "Name"
},
"commentStart": 40,
"end": 64,
@ -163,11 +187,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 76,
"end": 80,
"name": "line",
"name": {
"commentStart": 76,
"end": 80,
"name": "line",
"start": 76,
"type": "Identifier"
},
"path": [],
"start": 76,
"type": "Identifier"
"type": "Name"
},
"commentStart": 76,
"end": 117,
@ -223,11 +255,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 129,
"end": 133,
"name": "line",
"name": {
"commentStart": 129,
"end": 133,
"name": "line",
"start": 129,
"type": "Identifier"
},
"path": [],
"start": 129,
"type": "Identifier"
"type": "Name"
},
"commentStart": 129,
"end": 155,
@ -301,11 +341,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 167,
"end": 171,
"name": "line",
"name": {
"commentStart": 167,
"end": 171,
"name": "line",
"start": 167,
"type": "Identifier"
},
"path": [],
"start": 167,
"type": "Identifier"
"type": "Name"
},
"commentStart": 167,
"end": 211,
@ -317,11 +365,19 @@ expression: actual
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 223,
"end": 228,
"name": "close",
"name": {
"commentStart": 223,
"end": 228,
"name": "close",
"start": 223,
"type": "Identifier"
},
"path": [],
"start": 223,
"type": "Identifier"
"type": "Name"
},
"commentStart": 223,
"end": 230,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 25,
"end": 27,
"name": "XY",
"name": {
"commentStart": 25,
"end": 27,
"name": "XY",
"start": 25,
"type": "Identifier"
},
"path": [],
"start": 25,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 11,
"end": 24,
"name": "startSketchOn",
"name": {
"commentStart": 11,
"end": 24,
"name": "startSketchOn",
"start": 11,
"type": "Identifier"
},
"path": [],
"start": 11,
"type": "Identifier"
"type": "Name"
},
"commentStart": 11,
"end": 28,
@ -86,11 +102,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 32,
"end": 46,
"name": "startProfileAt",
"name": {
"commentStart": 32,
"end": 46,
"name": "startProfileAt",
"start": 32,
"type": "Identifier"
},
"path": [],
"start": 32,
"type": "Identifier"
"type": "Name"
},
"commentStart": 32,
"end": 56,
@ -145,11 +169,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 60,
"end": 64,
"name": "line",
"name": {
"commentStart": 60,
"end": 64,
"name": "line",
"start": 60,
"type": "Identifier"
},
"path": [],
"start": 60,
"type": "Identifier"
"type": "Name"
},
"commentStart": 60,
"end": 86,
@ -161,11 +193,19 @@ expression: actual
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 90,
"end": 95,
"name": "close",
"name": {
"commentStart": 90,
"end": 95,
"name": "close",
"start": 90,
"type": "Identifier"
},
"path": [],
"start": 90,
"type": "Identifier"
"type": "Name"
},
"commentStart": 90,
"end": 97,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 22,
"end": 24,
"name": "XY",
"name": {
"commentStart": 22,
"end": 24,
"name": "XY",
"start": 22,
"type": "Identifier"
},
"path": [],
"start": 22,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 8,
"end": 21,
"name": "startSketchOn",
"name": {
"commentStart": 8,
"end": 21,
"name": "startSketchOn",
"start": 8,
"type": "Identifier"
},
"path": [],
"start": 8,
"type": "Identifier"
"type": "Name"
},
"commentStart": 8,
"end": 25,
@ -45,12 +61,20 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 44,
"end": 45,
"name": "p",
"name": {
"commentStart": 44,
"end": 45,
"name": "p",
"start": 44,
"type": "Identifier"
},
"path": [],
"start": 44,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 47,
@ -61,11 +85,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 29,
"end": 43,
"name": "startProfileAt",
"name": {
"commentStart": 29,
"end": 43,
"name": "startProfileAt",
"start": 29,
"type": "Identifier"
},
"path": [],
"start": 29,
"type": "Identifier"
"type": "Name"
},
"commentStart": 29,
"end": 49,

View File

@ -34,11 +34,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 8,
"end": 9,
"name": "f",
"name": {
"commentStart": 8,
"end": 9,
"name": "f",
"start": 8,
"type": "Identifier"
},
"path": [],
"start": 8,
"type": "Identifier"
"type": "Name"
},
"commentStart": 8,
"end": 12,
@ -69,11 +77,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 16,
"end": 17,
"name": "g",
"name": {
"commentStart": 16,
"end": 17,
"name": "g",
"start": 16,
"type": "Identifier"
},
"path": [],
"start": 16,
"type": "Identifier"
"type": "Name"
},
"commentStart": 16,
"end": 23,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 22,
"end": 24,
"name": "XY",
"name": {
"commentStart": 22,
"end": 24,
"name": "XY",
"start": 22,
"type": "Identifier"
},
"path": [],
"start": 22,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 8,
"end": 21,
"name": "startSketchOn",
"name": {
"commentStart": 8,
"end": 21,
"name": "startSketchOn",
"start": 8,
"type": "Identifier"
},
"path": [],
"start": 8,
"type": "Identifier"
"type": "Name"
},
"commentStart": 8,
"end": 25,
@ -45,12 +61,20 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 44,
"end": 45,
"name": "p",
"name": {
"commentStart": 44,
"end": 45,
"name": "p",
"start": 44,
"type": "Identifier"
},
"path": [],
"start": 44,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 47,
@ -61,11 +85,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 29,
"end": 43,
"name": "startProfileAt",
"name": {
"commentStart": 29,
"end": 43,
"name": "startProfileAt",
"start": 29,
"type": "Identifier"
},
"path": [],
"start": 29,
"type": "Identifier"
"type": "Name"
},
"commentStart": 29,
"end": 49,
@ -100,12 +132,20 @@ expression: actual
}
},
{
"abs_path": false,
"commentStart": 68,
"end": 69,
"name": "l",
"name": {
"commentStart": 68,
"end": 69,
"name": "l",
"start": 68,
"type": "Identifier"
},
"path": [],
"start": 68,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"end": 70,
@ -116,11 +156,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 53,
"end": 57,
"name": "line",
"name": {
"commentStart": 53,
"end": 57,
"name": "line",
"start": 53,
"type": "Identifier"
},
"path": [],
"start": 53,
"type": "Identifier"
"type": "Name"
},
"commentStart": 53,
"end": 71,

View File

@ -54,11 +54,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 4,
"name": "line",
"name": {
"commentStart": 0,
"end": 4,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 0,
"end": 26,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 25,
"end": 27,
"name": "XY",
"name": {
"commentStart": 25,
"end": 27,
"name": "XY",
"start": 25,
"type": "Identifier"
},
"path": [],
"start": 25,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 11,
"end": 24,
"name": "startSketchOn",
"name": {
"commentStart": 11,
"end": 24,
"name": "startSketchOn",
"start": 11,
"type": "Identifier"
},
"path": [],
"start": 11,
"type": "Identifier"
"type": "Name"
},
"commentStart": 11,
"end": 28,
@ -86,11 +102,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 32,
"end": 46,
"name": "startProfileAt",
"name": {
"commentStart": 32,
"end": 46,
"name": "startProfileAt",
"start": 32,
"type": "Identifier"
},
"path": [],
"start": 32,
"type": "Identifier"
"type": "Name"
},
"commentStart": 32,
"end": 56,

View File

@ -31,20 +31,36 @@ expression: actual
"value": "hello"
},
{
"abs_path": false,
"commentStart": 16,
"end": 27,
"name": "aIdentifier",
"name": {
"commentStart": 16,
"end": 27,
"name": "aIdentifier",
"start": 16,
"type": "Identifier"
},
"path": [],
"start": 16,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 3,
"name": "log",
"name": {
"commentStart": 0,
"end": 3,
"name": "log",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 0,
"end": 28,

View File

@ -25,12 +25,20 @@ expression: actual
}
},
{
"abs_path": false,
"commentStart": 9,
"end": 10,
"name": "l",
"name": {
"commentStart": 9,
"end": 10,
"name": "l",
"start": 9,
"type": "Identifier"
},
"path": [],
"start": 9,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"end": 11,
@ -47,11 +55,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 0,
"end": 4,
"name": "line",
"name": {
"commentStart": 0,
"end": 4,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 0,
"end": 15,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 31,
"end": 33,
"name": "XY",
"name": {
"commentStart": 31,
"end": 33,
"name": "XY",
"start": 31,
"type": "Identifier"
},
"path": [],
"start": 31,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 17,
"end": 30,
"name": "startSketchOn",
"name": {
"commentStart": 17,
"end": 30,
"name": "startSketchOn",
"start": 17,
"type": "Identifier"
},
"path": [],
"start": 17,
"type": "Identifier"
"type": "Name"
},
"commentStart": 17,
"end": 34,
@ -111,11 +127,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 42,
"end": 48,
"name": "circle",
"name": {
"commentStart": 42,
"end": 48,
"name": "circle",
"start": 42,
"type": "Identifier"
},
"path": [],
"start": 42,
"type": "Identifier"
"type": "Name"
},
"commentStart": 42,
"end": 76,
@ -150,11 +174,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 84,
"end": 91,
"name": "extrude",
"name": {
"commentStart": 84,
"end": 91,
"name": "extrude",
"start": 84,
"type": "Identifier"
},
"path": [],
"start": 84,
"type": "Identifier"
"type": "Name"
},
"commentStart": 84,
"end": 104,

View File

@ -23,12 +23,20 @@ expression: actual
"argument": {
"arguments": [
{
"abs_path": false,
"commentStart": 36,
"end": 41,
"name": "angle",
"name": {
"commentStart": 36,
"end": 41,
"name": "angle",
"start": 36,
"type": "Identifier"
},
"path": [],
"start": 36,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 43,
@ -44,11 +52,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 28,
"end": 35,
"name": "default",
"name": {
"commentStart": 28,
"end": 35,
"name": "default",
"start": 28,
"type": "Identifier"
},
"path": [],
"start": 28,
"type": "Identifier"
"type": "Name"
},
"commentStart": 28,
"end": 47,

View File

@ -59,11 +59,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 17,
"end": 23,
"name": "legLen",
"name": {
"commentStart": 17,
"end": 23,
"name": "legLen",
"start": 17,
"type": "Identifier"
},
"path": [],
"start": 17,
"type": "Identifier"
"type": "Name"
},
"commentStart": 17,
"end": 29,
@ -80,11 +88,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 8,
"end": 11,
"name": "min",
"name": {
"commentStart": 8,
"end": 11,
"name": "min",
"start": 8,
"type": "Identifier"
},
"path": [],
"start": 8,
"type": "Identifier"
"type": "Name"
},
"commentStart": 8,
"end": 30,

View File

@ -31,11 +31,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 13,
"end": 26,
"name": "startSketchOn",
"name": {
"commentStart": 13,
"end": 26,
"name": "startSketchOn",
"start": 13,
"type": "Identifier"
},
"path": [],
"start": 13,
"type": "Identifier"
"type": "Name"
},
"commentStart": 13,
"end": 32,
@ -54,11 +62,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 109,
"end": 123,
"name": "startProfileAt",
"name": {
"commentStart": 109,
"end": 123,
"name": "startProfileAt",
"start": 109,
"type": "Identifier"
},
"path": [],
"start": 109,
"type": "Identifier"
"type": "Name"
},
"commentStart": 109,
"end": 126,

View File

@ -34,20 +34,36 @@ expression: actual
"cond": {
"arguments": [
{
"abs_path": false,
"commentStart": 51,
"end": 57,
"name": "radius",
"name": {
"commentStart": 51,
"end": 57,
"name": "radius",
"start": 51,
"type": "Identifier"
},
"path": [],
"start": 51,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 46,
"end": 50,
"name": "func",
"name": {
"commentStart": 46,
"end": 50,
"name": "func",
"start": 46,
"type": "Identifier"
},
"path": [],
"start": 46,
"type": "Identifier"
"type": "Name"
},
"commentStart": 46,
"end": 58,

View File

@ -66,12 +66,20 @@ expression: actual
"start": 22,
"type": "ObjectProperty",
"value": {
"abs_path": false,
"commentStart": 22,
"end": 23,
"name": "x",
"name": {
"commentStart": 22,
"end": 23,
"name": "x",
"start": 22,
"type": "Identifier"
},
"path": [],
"start": 22,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
{

View File

@ -8,12 +8,20 @@ expression: actual
"commentStart": 0,
"end": 5,
"expression": {
"abs_path": false,
"commentStart": 0,
"end": 5,
"name": "truee",
"name": {
"commentStart": 0,
"end": 5,
"name": "truee",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"start": 0,
"type": "ExpressionStatement",

View File

@ -47,11 +47,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 13,
"end": 19,
"name": "legLen",
"name": {
"commentStart": 13,
"end": 19,
"name": "legLen",
"start": 13,
"type": "Identifier"
},
"path": [],
"start": 13,
"type": "Identifier"
"type": "Name"
},
"commentStart": 13,
"end": 25,
@ -80,11 +88,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 8,
"end": 11,
"name": "min",
"name": {
"commentStart": 8,
"end": 11,
"name": "min",
"start": 8,
"type": "Identifier"
},
"path": [],
"start": 8,
"type": "Identifier"
"type": "Name"
},
"commentStart": 8,
"end": 29,

View File

@ -73,11 +73,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 17,
"end": 23,
"name": "myFunc",
"name": {
"commentStart": 17,
"end": 23,
"name": "myFunc",
"start": 17,
"type": "Identifier"
},
"path": [],
"start": 17,
"type": "Identifier"
"type": "Name"
},
"commentStart": 17,
"end": 30,

View File

@ -21,12 +21,20 @@ expression: actual
"end": 21,
"left": {
"argument": {
"abs_path": false,
"commentStart": 5,
"end": 9,
"name": "leg2",
"name": {
"commentStart": 5,
"end": 9,
"name": "leg2",
"start": 5,
"type": "Identifier"
},
"path": [],
"start": 5,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"commentStart": 4,
"end": 9,
@ -37,12 +45,20 @@ expression: actual
},
"operator": "+",
"right": {
"abs_path": false,
"commentStart": 12,
"end": 21,
"name": "thickness",
"name": {
"commentStart": 12,
"end": 21,
"name": "thickness",
"start": 12,
"type": "Identifier"
},
"path": [],
"start": 12,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"start": 4,
"type": "BinaryExpression",

View File

@ -21,12 +21,20 @@ expression: actual
"body": [
{
"argument": {
"abs_path": false,
"commentStart": 30,
"end": 32,
"name": "sg",
"name": {
"commentStart": 30,
"end": 32,
"name": "sg",
"start": 30,
"type": "Identifier"
},
"path": [],
"start": 30,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"commentStart": 23,
"end": 32,
@ -36,12 +44,20 @@ expression: actual
},
{
"argument": {
"abs_path": false,
"commentStart": 48,
"end": 50,
"name": "sg",
"name": {
"commentStart": 48,
"end": 50,
"name": "sg",
"start": 48,
"type": "Identifier"
},
"path": [],
"start": 48,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"commentStart": 41,
"end": 50,

View File

@ -28,12 +28,20 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 14,
"end": 15,
"name": "a",
"name": {
"commentStart": 14,
"end": 15,
"name": "a",
"start": 14,
"type": "Identifier"
},
"path": [],
"start": 14,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
{
@ -46,21 +54,37 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 21,
"end": 22,
"name": "b",
"name": {
"commentStart": 21,
"end": 22,
"name": "b",
"start": 21,
"type": "Identifier"
},
"path": [],
"start": 21,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
}
],
"callee": {
"abs_path": false,
"commentStart": 6,
"end": 9,
"name": "foo",
"name": {
"commentStart": 6,
"end": 9,
"name": "foo",
"start": 6,
"type": "Identifier"
},
"path": [],
"start": 6,
"type": "Identifier"
"type": "Name"
},
"commentStart": 6,
"end": 23,

View File

@ -42,21 +42,37 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 19,
"end": 20,
"name": "x",
"name": {
"commentStart": 19,
"end": 20,
"name": "x",
"start": 19,
"type": "Identifier"
},
"path": [],
"start": 19,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
}
],
"callee": {
"abs_path": false,
"commentStart": 11,
"end": 12,
"name": "f",
"name": {
"commentStart": 11,
"end": 12,
"name": "f",
"start": 11,
"type": "Identifier"
},
"path": [],
"start": 11,
"type": "Identifier"
"type": "Name"
},
"commentStart": 11,
"end": 21,

View File

@ -28,12 +28,20 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 28,
"end": 29,
"name": "x",
"name": {
"commentStart": 28,
"end": 29,
"name": "x",
"start": 28,
"type": "Identifier"
},
"path": [],
"start": 28,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
{
@ -46,12 +54,20 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 50,
"end": 51,
"name": "x",
"name": {
"commentStart": 50,
"end": 51,
"name": "x",
"start": 50,
"type": "Identifier"
},
"path": [],
"start": 50,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
{
@ -64,21 +80,37 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 72,
"end": 73,
"name": "x",
"name": {
"commentStart": 72,
"end": 73,
"name": "x",
"start": 72,
"type": "Identifier"
},
"path": [],
"start": 72,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
}
],
"callee": {
"abs_path": false,
"commentStart": 6,
"end": 7,
"name": "f",
"name": {
"commentStart": 6,
"end": 7,
"name": "f",
"start": 6,
"type": "Identifier"
},
"path": [],
"start": 6,
"type": "Identifier"
"type": "Name"
},
"commentStart": 6,
"end": 87,

View File

@ -28,12 +28,20 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 28,
"end": 29,
"name": "x",
"name": {
"commentStart": 28,
"end": 29,
"name": "x",
"start": 28,
"type": "Identifier"
},
"path": [],
"start": 28,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
{
@ -46,21 +54,37 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 75,
"end": 76,
"name": "x",
"name": {
"commentStart": 75,
"end": 76,
"name": "x",
"start": 75,
"type": "Identifier"
},
"path": [],
"start": 75,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
}
],
"callee": {
"abs_path": false,
"commentStart": 6,
"end": 7,
"name": "f",
"name": {
"commentStart": 6,
"end": 7,
"name": "f",
"start": 6,
"type": "Identifier"
},
"path": [],
"start": 6,
"type": "Identifier"
"type": "Name"
},
"commentStart": 6,
"end": 90,

View File

@ -28,21 +28,37 @@ expression: actual
"type": "Identifier"
},
"arg": {
"abs_path": false,
"commentStart": 17,
"end": 18,
"name": "z",
"name": {
"commentStart": 17,
"end": 18,
"name": "z",
"start": 17,
"type": "Identifier"
},
"path": [],
"start": 17,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
}
],
"callee": {
"abs_path": false,
"commentStart": 6,
"end": 9,
"name": "foo",
"name": {
"commentStart": 6,
"end": 9,
"name": "foo",
"start": 6,
"type": "Identifier"
},
"path": [],
"start": 6,
"type": "Identifier"
"type": "Name"
},
"commentStart": 6,
"end": 19,
@ -50,12 +66,20 @@ expression: actual
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"abs_path": false,
"commentStart": 10,
"end": 11,
"name": "x",
"name": {
"commentStart": 10,
"end": 11,
"name": "x",
"start": 10,
"type": "Identifier"
},
"path": [],
"start": 10,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
"start": 0,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 19,
"end": 21,
"name": "XY",
"name": {
"commentStart": 19,
"end": 21,
"name": "XY",
"start": 19,
"type": "Identifier"
},
"path": [],
"start": 19,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 5,
"end": 18,
"name": "startSketchOn",
"name": {
"commentStart": 5,
"end": 18,
"name": "startSketchOn",
"start": 5,
"type": "Identifier"
},
"path": [],
"start": 5,
"type": "Identifier"
"type": "Name"
},
"commentStart": 5,
"end": 22,
@ -45,12 +61,20 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 41,
"end": 44,
"name": "pos",
"name": {
"commentStart": 41,
"end": 44,
"name": "pos",
"start": 41,
"type": "Identifier"
},
"path": [],
"start": 41,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 46,
@ -61,11 +85,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 26,
"end": 40,
"name": "startProfileAt",
"name": {
"commentStart": 26,
"end": 40,
"name": "startProfileAt",
"start": 26,
"type": "Identifier"
},
"path": [],
"start": 26,
"type": "Identifier"
"type": "Name"
},
"commentStart": 26,
"end": 48,

View File

@ -21,20 +21,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 19,
"end": 21,
"name": "XY",
"name": {
"commentStart": 19,
"end": 21,
"name": "XY",
"start": 19,
"type": "Identifier"
},
"path": [],
"start": 19,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 5,
"end": 18,
"name": "startSketchOn",
"name": {
"commentStart": 5,
"end": 18,
"name": "startSketchOn",
"start": 5,
"type": "Identifier"
},
"path": [],
"start": 5,
"type": "Identifier"
"type": "Name"
},
"commentStart": 5,
"end": 22,
@ -45,20 +61,36 @@ expression: actual
{
"arguments": [
{
"abs_path": false,
"commentStart": 45,
"end": 48,
"name": "pos",
"name": {
"commentStart": 45,
"end": 48,
"name": "pos",
"start": 45,
"type": "Identifier"
},
"path": [],
"start": 45,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 30,
"end": 44,
"name": "startProfileAt",
"name": {
"commentStart": 30,
"end": 44,
"name": "startProfileAt",
"start": 30,
"type": "Identifier"
},
"path": [],
"start": 30,
"type": "Identifier"
"type": "Name"
},
"commentStart": 30,
"end": 49,
@ -85,12 +117,20 @@ expression: actual
},
{
"argument": {
"abs_path": false,
"commentStart": 63,
"end": 68,
"name": "scale",
"name": {
"commentStart": 63,
"end": 68,
"name": "scale",
"start": 63,
"type": "Identifier"
},
"path": [],
"start": 63,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"commentStart": 62,
"end": 68,
@ -114,11 +154,19 @@ expression: actual
}
],
"callee": {
"abs_path": false,
"commentStart": 53,
"end": 57,
"name": "line",
"name": {
"commentStart": 53,
"end": 57,
"name": "line",
"start": 53,
"type": "Identifier"
},
"path": [],
"start": 53,
"type": "Identifier"
"type": "Name"
},
"commentStart": 53,
"end": 73,

View File

@ -351,6 +351,8 @@ pub enum TokenType {
Comma,
/// A colon.
Colon,
/// A double colon: `::`
DoubleColon,
/// A period.
Period,
/// A double period: `..`.
@ -393,6 +395,7 @@ impl TryFrom<TokenType> for SemanticTokenType {
| TokenType::Brace
| TokenType::Comma
| TokenType::Colon
| TokenType::DoubleColon
| TokenType::Period
| TokenType::DoublePeriod
| TokenType::Hash

View File

@ -87,8 +87,8 @@ pub(super) fn token(i: &mut Input<'_>) -> PResult<Token> {
'?' => question_mark,
'@' => at,
'0'..='9' => number,
':' => colon,
';' => semi_colon,
':' => alt((double_colon, colon)),
'.' => alt((number, double_period, period)),
'#' => hash,
'$' => dollar,
@ -293,6 +293,15 @@ fn semi_colon(i: &mut Input<'_>) -> PResult<Token> {
))
}
fn double_colon(i: &mut Input<'_>) -> PResult<Token> {
let (value, range) = "::".with_span().parse_next(i)?;
Ok(Token::from_range(
range,
i.state.module_id,
TokenType::DoubleColon,
value.to_string(),
))
}
fn period(i: &mut Input<'_>) -> PResult<Token> {
let (value, range) = '.'.with_span().parse_next(i)?;
Ok(Token::from_range(

View File

@ -1,6 +1,7 @@
use std::{any::type_name, collections::HashMap, num::NonZeroU32};
use std::num::NonZeroU32;
use anyhow::Result;
use indexmap::IndexMap;
use kcmc::{
websocket::{ModelingCmdReq, OkWebSocketResponseData},
ModelingCmd,
@ -57,7 +58,7 @@ pub struct KwArgs {
/// Unlabeled keyword args. Currently only the first arg can be unlabeled.
pub unlabeled: Option<Arg>,
/// Labeled args.
pub labeled: HashMap<String, Arg>,
pub labeled: IndexMap<String, Arg>,
}
impl KwArgs {
@ -146,7 +147,7 @@ impl Args {
source_ranges: vec![self.source_range],
message: format!(
"The arg {label} was given, but it was the wrong type. It should be type {} but it was {}",
type_name::<T>(),
tynm::type_name::<T>(),
arg.value.human_friendly_type(),
),
})
@ -229,7 +230,7 @@ impl Args {
source_ranges: vec![arg.source_range],
message: format!(
"Expected an array of {} but found {}",
type_name::<T>(),
tynm::type_name::<T>(),
arg.value.human_friendly_type()
),
});
@ -244,7 +245,7 @@ impl Args {
source_ranges: arg.source_ranges(),
message: format!(
"Expected a {} but found {}",
type_name::<T>(),
tynm::type_name::<T>(),
arg.value.human_friendly_type()
),
})
@ -924,7 +925,7 @@ where
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Argument at index {i} was supposed to be type {} but found {}",
type_name::<T>(),
tynm::type_name::<T>(),
arg.value.human_friendly_type(),
),
source_ranges: arg.source_ranges(),
@ -947,7 +948,7 @@ where
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Argument at index {i} was supposed to be type Option<{}> but found {}",
type_name::<T>(),
tynm::type_name::<T>(),
arg.value.human_friendly_type()
),
source_ranges: arg.source_ranges(),
@ -1000,48 +1001,54 @@ where
impl<'a> FromKclValue<'a> for [f64; 2] {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::MixedArray { value, meta: _ } = arg else {
return None;
};
if value.len() != 2 {
return None;
match arg {
KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
if value.len() != 2 {
return None;
}
let v0 = value.first()?;
let v1 = value.get(1)?;
let array = [v0.as_f64()?, v1.as_f64()?];
Some(array)
}
_ => None,
}
let v0 = value.first()?;
let v1 = value.get(1)?;
let array = [v0.as_f64()?, v1.as_f64()?];
Some(array)
}
}
impl<'a> FromKclValue<'a> for [usize; 3] {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::MixedArray { value, meta: _ } = arg else {
return None;
};
if value.len() != 3 {
return None;
match arg {
KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
if value.len() != 3 {
return None;
}
let v0 = value.first()?;
let v1 = value.get(1)?;
let v2 = value.get(2)?;
let array = [v0.as_usize()?, v1.as_usize()?, v2.as_usize()?];
Some(array)
}
_ => None,
}
let v0 = value.first()?;
let v1 = value.get(1)?;
let v2 = value.get(2)?;
let array = [v0.as_usize()?, v1.as_usize()?, v2.as_usize()?];
Some(array)
}
}
impl<'a> FromKclValue<'a> for [f64; 3] {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::MixedArray { value, meta: _ } = arg else {
return None;
};
if value.len() != 3 {
return None;
match arg {
KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
if value.len() != 3 {
return None;
}
let v0 = value.first()?;
let v1 = value.get(1)?;
let v2 = value.get(2)?;
let array = [v0.as_f64()?, v1.as_f64()?, v2.as_f64()?];
Some(array)
}
_ => None,
}
let v0 = value.first()?;
let v1 = value.get(1)?;
let v2 = value.get(2)?;
let array = [v0.as_f64()?, v1.as_f64()?, v2.as_f64()?];
Some(array)
}
}

View File

@ -47,19 +47,19 @@ fn inner_rem(num: f64, divisor: f64) -> f64 {
/// Compute the cosine of a number (in radians).
pub async fn cos(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num = args.get_number()?;
let num: f64 = args.get_unlabeled_kw_arg("input")?;
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.cos())))
}
/// Compute the sine of a number (in radians).
pub async fn sin(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num = args.get_number()?;
let num: f64 = args.get_unlabeled_kw_arg("input")?;
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.sin())))
}
/// Compute the tangent of a number (in radians).
pub async fn tan(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num = args.get_number()?;
let num: f64 = args.get_unlabeled_kw_arg("input")?;
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.tan())))
}

View File

@ -43,6 +43,7 @@ use crate::{
docs::StdLibFn,
errors::KclError,
execution::{types::PrimitiveType, ExecState, KclValue},
parsing::ast::types::Name,
};
pub type StdFn = fn(
@ -71,7 +72,6 @@ lazy_static! {
Box::new(crate::std::segment::TangentToEnd),
Box::new(crate::std::segment::AngleToMatchLengthX),
Box::new(crate::std::segment::AngleToMatchLengthY),
Box::new(crate::std::shapes::Circle),
Box::new(crate::std::shapes::CircleThreePoint),
Box::new(crate::std::shapes::Polygon),
Box::new(crate::std::sketch::Line),
@ -202,6 +202,10 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
|e, a| Box::pin(crate::std::math::tan(e, a)),
StdFnProps::default("std::math::tan"),
),
("sketch", "circle") => (
|e, a| Box::pin(crate::std::shapes::circle(e, a)),
StdFnProps::default("std::sketch::circle"),
),
_ => unreachable!(),
}
}
@ -247,12 +251,14 @@ impl StdLib {
self.fns.get(name).cloned()
}
pub fn get_either(&self, name: &str) -> FunctionKind {
if let Some(f) = self.get(name) {
FunctionKind::Core(f)
} else {
FunctionKind::UserDefined
pub fn get_either(&self, name: &Name) -> FunctionKind {
if let Some(name) = name.local_ident() {
if let Some(f) = self.get(name.inner) {
return FunctionKind::Core(f);
}
}
FunctionKind::UserDefined
}
pub fn contains_key(&self, key: &str) -> bool {

View File

@ -46,38 +46,6 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
})
}
/// Construct a 2-dimensional circle, of the specified radius, centered at
/// the provided (x, y) origin point.
///
/// ```no_run
/// exampleSketch = startSketchOn("-XZ")
/// |> circle( center = [0, 0], radius = 10 )
///
/// example = extrude(exampleSketch, length = 5)
/// ```
///
/// ```no_run
/// exampleSketch = startSketchOn("XZ")
/// |> startProfileAt([-15, 0], %)
/// |> line(end = [30, 0])
/// |> line(end = [0, 30])
/// |> line(end = [-30, 0])
/// |> close()
/// |> hole(circle( center = [0, 15], radius = 5), %)
///
/// example = extrude(exampleSketch, length = 5)
/// ```
#[stdlib {
name = "circle",
keywords = true,
unlabeled_first = true,
args = {
sketch_or_surface = {docs = "Plane or surface to sketch on."},
center = {docs = "The center of the circle."},
radius = {docs = "The radius of the circle."},
tag = { docs = "Create a new tag which refers to this circle"},
}
}]
async fn inner_circle(
sketch_or_surface: SketchOrSurface,
center: [f64; 2],
@ -152,13 +120,13 @@ async fn inner_circle(
/// Sketch a 3-point circle.
pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch_surface_or_group = args.get_unlabeled_kw_arg("sketch_surface_or_group")?;
let p1 = args.get_kw_arg("p1")?;
let p2 = args.get_kw_arg("p2")?;
let p3 = args.get_kw_arg("p3")?;
let sketch_surface_or_group = args.get_unlabeled_kw_arg("sketch_surface_or_group")?;
let tag = args.get_kw_arg_opt("tag")?;
let sketch = inner_circle_three_point(p1, p2, p3, sketch_surface_or_group, tag, exec_state, args).await?;
let sketch = inner_circle_three_point(sketch_surface_or_group, p1, p2, p3, tag, exec_state, args).await?;
Ok(KclValue::Sketch {
value: Box::new(sketch),
})
@ -176,10 +144,10 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul
keywords = true,
unlabeled_first = true,
args = {
sketch_surface_or_group = {docs = "Plane or surface to sketch on."},
p1 = {docs = "1st point to derive the circle."},
p2 = {docs = "2nd point to derive the circle."},
p3 = {docs = "3rd point to derive the circle."},
sketch_surface_or_group = {docs = "Plane or surface to sketch on."},
tag = {docs = "Identifier for the circle to reference elsewhere."},
}
}]
@ -187,10 +155,10 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul
// Similar to inner_circle, but needs to retain 3-point information in the
// path so it can be used for other features, otherwise it's lost.
async fn inner_circle_three_point(
sketch_surface_or_group: SketchOrSurface,
p1: [f64; 2],
p2: [f64; 2],
p3: [f64; 2],
sketch_surface_or_group: SketchOrSurface,
tag: Option<TagNode>,
exec_state: &mut ExecState,
args: Args,

View File

@ -293,10 +293,13 @@ impl Expr {
}
Expr::CallExpression(call_exp) => call_exp.recast(options, indentation_level, ctxt),
Expr::CallExpressionKw(call_exp) => call_exp.recast(options, indentation_level, ctxt),
Expr::Identifier(ident) => match deprecation(&ident.name, DeprecationKind::Const) {
Some(suggestion) => suggestion.to_owned(),
None => ident.name.to_owned(),
},
Expr::Name(name) => {
let result = name.to_string();
match deprecation(&result, DeprecationKind::Const) {
Some(suggestion) => suggestion.to_owned(),
None => result,
}
}
Expr::TagDeclarator(tag) => tag.recast(),
Expr::PipeExpression(pipe_exp) => pipe_exp.recast(options, indentation_level),
Expr::UnaryExpression(unary_exp) => unary_exp.recast(options),
@ -325,10 +328,13 @@ impl BinaryPart {
fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
match &self {
BinaryPart::Literal(literal) => literal.recast(),
BinaryPart::Identifier(ident) => match deprecation(&ident.name, DeprecationKind::Const) {
Some(suggestion) => suggestion.to_owned(),
None => ident.name.to_owned(),
},
BinaryPart::Name(name) => {
let result = name.to_string();
match deprecation(&result, DeprecationKind::Const) {
Some(suggestion) => suggestion.to_owned(),
None => result,
}
}
BinaryPart::BinaryExpression(binary_expression) => binary_expression.recast(options),
BinaryPart::CallExpression(call_expression) => {
call_expression.recast(options, indentation_level, ExprContext::Other)
@ -352,7 +358,7 @@ impl CallExpression {
} else {
options.get_indentation(indentation_level)
},
self.callee.name,
self.callee,
self.arguments
.iter()
.map(|arg| arg.recast(options, indentation_level, ctxt))
@ -382,9 +388,9 @@ impl CallExpressionKw {
} else {
options.get_indentation(indentation_level)
};
let name = &self.callee.name;
let name = self.callee.to_string();
if let Some(suggestion) = deprecation(name, DeprecationKind::Function) {
if let Some(suggestion) = deprecation(&name, DeprecationKind::Function) {
return format!("{indent}{suggestion}");
}
@ -583,7 +589,7 @@ impl ArrayExpression {
fn expr_is_trivial(expr: &Expr) -> bool {
matches!(
expr,
Expr::Literal(_) | Expr::Identifier(_) | Expr::TagDeclarator(_) | Expr::PipeSubstitution(_) | Expr::None(_)
Expr::Literal(_) | Expr::Name(_) | Expr::TagDeclarator(_) | Expr::PipeSubstitution(_) | Expr::None(_)
)
}
@ -733,7 +739,7 @@ impl UnaryExpression {
fn recast(&self, options: &FormatOptions) -> String {
match self.argument {
BinaryPart::Literal(_)
| BinaryPart::Identifier(_)
| BinaryPart::Name(_)
| BinaryPart::MemberExpression(_)
| BinaryPart::IfExpression(_)
| BinaryPart::CallExpressionKw(_)

View File

@ -20,6 +20,7 @@ pub enum Node<'a> {
Literal(NodeRef<'a, types::Literal>),
TagDeclarator(NodeRef<'a, types::TagDeclarator>),
Identifier(NodeRef<'a, types::Identifier>),
Name(NodeRef<'a, types::Name>),
BinaryExpression(NodeRef<'a, types::BinaryExpression>),
FunctionExpression(NodeRef<'a, types::FunctionExpression>),
CallExpression(NodeRef<'a, types::CallExpression>),
@ -60,6 +61,7 @@ impl Node<'_> {
Node::Literal(n) => n.digest,
Node::TagDeclarator(n) => n.digest,
Node::Identifier(n) => n.digest,
Node::Name(n) => n.digest,
Node::BinaryExpression(n) => n.digest,
Node::FunctionExpression(n) => n.digest,
Node::CallExpression(n) => n.digest,
@ -104,6 +106,7 @@ impl Node<'_> {
Node::Literal(n) => *n as *const _ as *const (),
Node::TagDeclarator(n) => *n as *const _ as *const (),
Node::Identifier(n) => *n as *const _ as *const (),
Node::Name(n) => *n as *const _ as *const (),
Node::BinaryExpression(n) => *n as *const _ as *const (),
Node::FunctionExpression(n) => *n as *const _ as *const (),
Node::CallExpression(n) => *n as *const _ as *const (),
@ -148,6 +151,7 @@ impl TryFrom<&Node<'_>> for SourceRange {
Node::Literal(n) => SourceRange::from(*n),
Node::TagDeclarator(n) => SourceRange::from(*n),
Node::Identifier(n) => SourceRange::from(*n),
Node::Name(n) => SourceRange::from(*n),
Node::BinaryExpression(n) => SourceRange::from(*n),
Node::FunctionExpression(n) => SourceRange::from(*n),
Node::CallExpression(n) => SourceRange::from(*n),
@ -192,7 +196,7 @@ impl<'tree> From<&'tree types::Expr> for Node<'tree> {
match node {
types::Expr::Literal(lit) => lit.as_ref().into(),
types::Expr::TagDeclarator(tag) => tag.as_ref().into(),
types::Expr::Identifier(id) => id.as_ref().into(),
types::Expr::Name(id) => id.as_ref().into(),
types::Expr::BinaryExpression(be) => be.as_ref().into(),
types::Expr::FunctionExpression(fe) => fe.as_ref().into(),
types::Expr::CallExpression(ce) => ce.as_ref().into(),
@ -216,7 +220,7 @@ impl<'tree> From<&'tree types::BinaryPart> for Node<'tree> {
fn from(node: &'tree types::BinaryPart) -> Self {
match node {
types::BinaryPart::Literal(lit) => lit.as_ref().into(),
types::BinaryPart::Identifier(id) => id.as_ref().into(),
types::BinaryPart::Name(id) => id.as_ref().into(),
types::BinaryPart::BinaryExpression(be) => be.as_ref().into(),
types::BinaryPart::CallExpression(ce) => ce.as_ref().into(),
types::BinaryPart::CallExpressionKw(ce) => ce.as_ref().into(),
@ -275,6 +279,7 @@ impl_from!(Node, VariableDeclarator);
impl_from!(Node, Literal);
impl_from!(Node, TagDeclarator);
impl_from!(Node, Identifier);
impl_from!(Node, Name);
impl_from!(Node, BinaryExpression);
impl_from!(Node, FunctionExpression);
impl_from!(Node, CallExpression);

View File

@ -134,6 +134,10 @@ impl<'tree> Visitable<'tree> for Node<'tree> {
Node::Ascription(e) => {
vec![(&e.expr).into()]
}
Node::Name(n) => Some((&n.name).into())
.into_iter()
.chain(n.path.iter().map(|n| n.into()))
.collect(),
Node::PipeSubstitution(_)
| Node::TagDeclarator(_)
| Node::Identifier(_)

View File

@ -5,7 +5,7 @@
/// ```
/// circumference = 70
///
/// exampleSketch = startSketchOn("XZ")
/// exampleSketch = startSketchOn(XZ)
/// |> circle(center = [0, 0], radius = circumference/ (2 * PI))
///
/// example = extrude(exampleSketch, length = 5)
@ -15,7 +15,7 @@ export PI = 3.14159265358979323846264338327950288_
/// The value of Eulers number `e`.
///
/// ```
/// exampleSketch = startSketchOn("XZ")
/// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %)
/// |> angledLine({
/// angle = 30,
@ -31,7 +31,7 @@ export E = 2.71828182845904523536028747135266250_
/// The value of `tau`, the full circle constant (τ). Equal to 2π.
///
/// ```
/// exampleSketch = startSketchOn("XZ")
/// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %)
/// |> angledLine({
/// angle = 50,
@ -47,7 +47,7 @@ export TAU = 6.28318530717958647692528676655900577_
/// Compute the cosine of a number (in radians).
///
/// ```
/// exampleSketch = startSketchOn("XZ")
/// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %)
/// |> angledLine({
/// angle = 30,
@ -59,12 +59,12 @@ export TAU = 6.28318530717958647692528676655900577_
/// example = extrude(exampleSketch, length = 5)
/// ```
@(impl = std_rust)
export fn cos(num: number(rad)): number(_) {}
export fn cos(@num: number(rad)): number(_) {}
/// Compute the sine of a number (in radians).
///
/// ```
/// exampleSketch = startSketchOn("XZ")
/// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %)
/// |> angledLine({
/// angle = 50,
@ -76,12 +76,12 @@ export fn cos(num: number(rad)): number(_) {}
/// example = extrude(exampleSketch, length = 5)
/// ```
@(impl = std_rust)
export fn sin(num: number(rad)): number(_) {}
export fn sin(@num: number(rad)): number(_) {}
/// Compute the tangent of a number (in radians).
///
/// ```
/// exampleSketch = startSketchOn("XZ")
/// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %)
/// |> angledLine({
/// angle = 50,
@ -93,4 +93,4 @@ export fn sin(num: number(rad)): number(_) {}
/// example = extrude(exampleSketch, length = 5)
/// ```
@(impl = std_rust)
export fn tan(num: number(rad)): number(_) {}
export fn tan(@num: number(rad)): number(_) {}

View File

@ -3,6 +3,7 @@
// Note that everything in the prelude is treated as exported.
export import * from "std::math"
export import * from "std::sketch"
/// A number
///

View File

@ -0,0 +1,34 @@
@no_std
/// Construct a 2-dimensional circle, of the specified radius, centered at
/// the provided (x, y) origin point.
///
/// ```
/// exampleSketch = startSketchOn(-XZ)
/// |> circle(center = [0, 0], radius = 10)
///
/// example = extrude(exampleSketch, length = 5)
/// ```
///
/// ```
/// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([-15, 0], %)
/// |> line(end = [30, 0])
/// |> line(end = [0, 30])
/// |> line(end = [-30, 0])
/// |> close()
/// |> hole(circle(center = [0, 15], radius = 5), %)
///
/// example = extrude(exampleSketch, length = 5)
/// ```
@(impl = std_rust)
export fn circle(
/// Sketch to extend, or plane or surface to sketch on.
@sketch_or_surface: Sketch | Plane | Face,
/// The center of the circle.
center: Point2d,
/// The radius of the circle.
radius: number,
/// Create a new tag which refers to this circle.
tag?: tag,
): Sketch {}

File diff suppressed because it is too large Load Diff

View File

@ -32,11 +32,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 10,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 10,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 10,
"end": 0,
@ -88,11 +96,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 35,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 35,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 35,
"end": 0,
@ -147,11 +163,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 73,
"end": 0,
"name": "line",
"name": {
"commentStart": 73,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 73,
"end": 0,
@ -233,11 +257,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 103,
"end": 0,
"name": "line",
"name": {
"commentStart": 103,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 103,
"end": 0,
@ -309,11 +341,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 148,
"end": 0,
"name": "line",
"name": {
"commentStart": 148,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 148,
"end": 0,
@ -330,20 +370,36 @@ description: Result of parsing angled_line.kcl
{
"arguments": [
{
"abs_path": false,
"commentStart": 199,
"end": 0,
"name": "seg01",
"name": {
"commentStart": 199,
"end": 0,
"name": "seg01",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 192,
"end": 0,
"name": "segAng",
"name": {
"commentStart": 192,
"end": 0,
"name": "segAng",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 192,
"end": 0,
@ -378,11 +434,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 180,
"end": 0,
"name": "angledLine",
"name": {
"commentStart": 180,
"end": 0,
"name": "angledLine",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 180,
"end": 0,
@ -445,11 +509,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 223,
"end": 0,
"name": "line",
"name": {
"commentStart": 223,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 223,
"end": 0,
@ -469,11 +541,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 256,
"end": 0,
"name": "close",
"name": {
"commentStart": 256,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 256,
"end": 0,
@ -507,11 +587,19 @@ description: Result of parsing angled_line.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 270,
"end": 0,
"name": "extrude",
"name": {
"commentStart": 270,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 270,
"end": 0,

View File

@ -77,12 +77,20 @@ description: Result of parsing argument_error.kcl
"expression": {
"arguments": [
{
"abs_path": false,
"commentStart": 28,
"end": 0,
"name": "f",
"name": {
"commentStart": 28,
"end": 0,
"name": "f",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 31,
@ -119,11 +127,19 @@ description: Result of parsing argument_error.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 24,
"end": 0,
"name": "map",
"name": {
"commentStart": 24,
"end": 0,
"name": "map",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 24,
"end": 0,

View File

@ -86,20 +86,36 @@ description: Result of parsing array_elem_pop.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 31,
"end": 0,
"name": "arr",
"name": {
"commentStart": 31,
"end": 0,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 27,
"end": 0,
"name": "pop",
"name": {
"commentStart": 27,
"end": 0,
"name": "pop",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 27,
"end": 0,
@ -131,20 +147,36 @@ description: Result of parsing array_elem_pop.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 51,
"end": 0,
"name": "new_arr1",
"name": {
"commentStart": 51,
"end": 0,
"name": "new_arr1",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 47,
"end": 0,
"name": "pop",
"name": {
"commentStart": 47,
"end": 0,
"name": "pop",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 47,
"end": 0,
@ -176,20 +208,36 @@ description: Result of parsing array_elem_pop.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 76,
"end": 0,
"name": "new_arr2",
"name": {
"commentStart": 76,
"end": 0,
"name": "new_arr2",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 72,
"end": 0,
"name": "pop",
"name": {
"commentStart": 72,
"end": 0,
"name": "pop",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 72,
"end": 0,
@ -274,11 +322,19 @@ description: Result of parsing array_elem_pop.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 86,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 86,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 86,
"end": 0,
@ -358,11 +414,19 @@ description: Result of parsing array_elem_pop.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 160,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 160,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 160,
"end": 0,
@ -442,11 +506,19 @@ description: Result of parsing array_elem_pop.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 234,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 234,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 234,
"end": 0,

View File

@ -49,20 +49,36 @@ description: Result of parsing array_elem_pop_empty_fail.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 20,
"end": 0,
"name": "arr",
"name": {
"commentStart": 20,
"end": 0,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 16,
"end": 0,
"name": "pop",
"name": {
"commentStart": 16,
"end": 0,
"name": "pop",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 16,
"end": 0,

View File

@ -86,20 +86,36 @@ description: Result of parsing array_elem_pop_fail.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 32,
"end": 0,
"name": "arr",
"name": {
"commentStart": 32,
"end": 0,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 28,
"end": 0,
"name": "pop",
"name": {
"commentStart": 28,
"end": 0,
"name": "pop",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 28,
"end": 0,

View File

@ -86,12 +86,20 @@ description: Result of parsing array_elem_push.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 32,
"end": 0,
"name": "arr",
"name": {
"commentStart": 32,
"end": 0,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 37,
@ -107,11 +115,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 27,
"end": 0,
"name": "push",
"name": {
"commentStart": 27,
"end": 0,
"name": "push",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 27,
"end": 0,
@ -143,12 +159,20 @@ description: Result of parsing array_elem_push.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 56,
"end": 0,
"name": "new_arr1",
"name": {
"commentStart": 56,
"end": 0,
"name": "new_arr1",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 66,
@ -164,11 +188,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 51,
"end": 0,
"name": "push",
"name": {
"commentStart": 51,
"end": 0,
"name": "push",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 51,
"end": 0,
@ -253,11 +285,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 69,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 69,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 69,
"end": 0,
@ -337,11 +377,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 143,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 143,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 143,
"end": 0,
@ -421,11 +469,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 217,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 217,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 217,
"end": 0,
@ -505,11 +561,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 291,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 291,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 291,
"end": 0,
@ -589,11 +653,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 367,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 367,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 367,
"end": 0,
@ -673,11 +745,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 441,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 441,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 441,
"end": 0,
@ -757,11 +837,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 515,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 515,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 515,
"end": 0,
@ -841,11 +929,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 589,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 589,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 589,
"end": 0,
@ -925,11 +1021,19 @@ description: Result of parsing array_elem_push.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 665,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 665,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 665,
"end": 0,

View File

@ -86,12 +86,20 @@ description: Result of parsing array_elem_push_fail.kcl
"init": {
"arguments": [
{
"abs_path": false,
"commentStart": 33,
"end": 0,
"name": "arr",
"name": {
"commentStart": 33,
"end": 0,
"name": "arr",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 38,
@ -107,11 +115,19 @@ description: Result of parsing array_elem_push_fail.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 28,
"end": 0,
"name": "push",
"name": {
"commentStart": 28,
"end": 0,
"name": "push",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 28,
"end": 0,

View File

@ -126,11 +126,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 12,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 12,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 12,
"end": 0,
@ -224,22 +232,38 @@ description: Result of parsing array_range_expr.kcl
"commentStart": 95,
"end": 0,
"endElement": {
"abs_path": false,
"commentStart": 102,
"end": 0,
"name": "four",
"name": {
"commentStart": 102,
"end": 0,
"name": "four",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"endInclusive": true,
"start": 0,
"startElement": {
"abs_path": false,
"commentStart": 96,
"end": 0,
"name": "zero",
"name": {
"commentStart": 96,
"end": 0,
"name": "zero",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"type": "ArrayRangeExpression",
"type": "ArrayRangeExpression"
@ -321,11 +345,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 108,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 108,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 108,
"end": 0,
@ -355,12 +387,20 @@ description: Result of parsing array_range_expr.kcl
"commentStart": 179,
"end": 0,
"left": {
"abs_path": false,
"commentStart": 179,
"end": 0,
"name": "four",
"name": {
"commentStart": 179,
"end": 0,
"name": "four",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"operator": "+",
"right": {
@ -381,11 +421,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 175,
"end": 0,
"name": "int",
"name": {
"commentStart": 175,
"end": 0,
"name": "int",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 175,
"end": 0,
@ -418,22 +466,38 @@ description: Result of parsing array_range_expr.kcl
"commentStart": 194,
"end": 0,
"endElement": {
"abs_path": false,
"commentStart": 201,
"end": 0,
"name": "five",
"name": {
"commentStart": 201,
"end": 0,
"name": "five",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"endInclusive": true,
"start": 0,
"startElement": {
"abs_path": false,
"commentStart": 195,
"end": 0,
"name": "zero",
"name": {
"commentStart": 195,
"end": 0,
"name": "zero",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"type": "ArrayRangeExpression",
"type": "ArrayRangeExpression"
@ -515,11 +579,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 207,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 207,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 207,
"end": 0,
@ -599,11 +671,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 276,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 276,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 276,
"end": 0,
@ -636,12 +716,20 @@ description: Result of parsing array_range_expr.kcl
"commentStart": 363,
"end": 0,
"left": {
"abs_path": false,
"commentStart": 363,
"end": 0,
"name": "five",
"name": {
"commentStart": 363,
"end": 0,
"name": "five",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"operator": "-",
"right": {
@ -662,11 +750,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 359,
"end": 0,
"name": "int",
"name": {
"commentStart": 359,
"end": 0,
"name": "int",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 359,
"end": 0,
@ -682,12 +778,20 @@ description: Result of parsing array_range_expr.kcl
"commentStart": 346,
"end": 0,
"left": {
"abs_path": false,
"commentStart": 346,
"end": 0,
"name": "zero",
"name": {
"commentStart": 346,
"end": 0,
"name": "zero",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"operator": "+",
"right": {
@ -708,11 +812,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 342,
"end": 0,
"name": "int",
"name": {
"commentStart": 342,
"end": 0,
"name": "int",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 342,
"end": 0,
@ -800,11 +912,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 374,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 374,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 374,
"end": 0,
@ -884,11 +1004,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 427,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 427,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 427,
"end": 0,
@ -968,11 +1096,19 @@ description: Result of parsing array_range_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 489,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 489,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 489,
"end": 0,

View File

@ -58,11 +58,19 @@ description: Result of parsing array_range_negative_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 6,
"end": 0,
"name": "int",
"name": {
"commentStart": 6,
"end": 0,
"name": "int",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 6,
"end": 0,
@ -158,11 +166,19 @@ description: Result of parsing array_range_negative_expr.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 20,
"end": 0,
"name": "assertEqual",
"name": {
"commentStart": 20,
"end": 0,
"name": "assertEqual",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 20,
"end": 0,

View File

@ -32,11 +32,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 12,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 12,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 12,
"end": 0,
@ -104,11 +112,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 37,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 37,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 37,
"end": 0,
@ -163,11 +179,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 70,
"end": 0,
"name": "line",
"name": {
"commentStart": 70,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 70,
"end": 0,
@ -241,11 +265,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 95,
"end": 0,
"name": "line",
"name": {
"commentStart": 95,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 95,
"end": 0,
@ -327,11 +359,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 137,
"end": 0,
"name": "line",
"name": {
"commentStart": 137,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 137,
"end": 0,
@ -365,11 +405,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 197,
"end": 0,
"name": "profileStartX",
"name": {
"commentStart": 197,
"end": 0,
"name": "profileStartX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 197,
"end": 0,
@ -388,11 +436,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 215,
"end": 0,
"name": "profileStartY",
"name": {
"commentStart": 215,
"end": 0,
"name": "profileStartY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 215,
"end": 0,
@ -409,11 +465,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 177,
"end": 0,
"name": "line",
"name": {
"commentStart": 177,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 177,
"end": 0,
@ -425,11 +489,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 239,
"end": 0,
"name": "close",
"name": {
"commentStart": 239,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 239,
"end": 0,
@ -501,11 +573,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 260,
"end": 0,
"name": "extrude",
"name": {
"commentStart": 260,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 260,
"end": 0,
@ -513,12 +593,20 @@ description: Result of parsing artifact_graph_example_code1.kcl
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"abs_path": false,
"commentStart": 268,
"end": 0,
"name": "sketch001",
"name": {
"commentStart": 268,
"end": 0,
"name": "sketch001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
{
@ -558,12 +646,20 @@ description: Result of parsing artifact_graph_example_code1.kcl
"commentStart": 324,
"elements": [
{
"abs_path": false,
"commentStart": 325,
"end": 0,
"name": "seg01",
"name": {
"commentStart": 325,
"end": 0,
"name": "seg01",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"end": 0,
@ -574,11 +670,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 298,
"end": 0,
"name": "fillet",
"name": {
"commentStart": 298,
"end": 0,
"name": "fillet",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 298,
"end": 0,
@ -620,28 +724,52 @@ description: Result of parsing artifact_graph_example_code1.kcl
{
"arguments": [
{
"abs_path": false,
"commentStart": 359,
"end": 0,
"name": "extrude001",
"name": {
"commentStart": 359,
"end": 0,
"name": "extrude001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"abs_path": false,
"commentStart": 371,
"end": 0,
"name": "seg02",
"name": {
"commentStart": 371,
"end": 0,
"name": "seg02",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 345,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 345,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 345,
"end": 0,
@ -709,11 +837,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 383,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 383,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 383,
"end": 0,
@ -768,11 +904,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 416,
"end": 0,
"name": "line",
"name": {
"commentStart": 416,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 416,
"end": 0,
@ -836,11 +980,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 440,
"end": 0,
"name": "line",
"name": {
"commentStart": 440,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 440,
"end": 0,
@ -874,11 +1026,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 485,
"end": 0,
"name": "profileStartX",
"name": {
"commentStart": 485,
"end": 0,
"name": "profileStartX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 485,
"end": 0,
@ -897,11 +1057,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 503,
"end": 0,
"name": "profileStartY",
"name": {
"commentStart": 503,
"end": 0,
"name": "profileStartY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 503,
"end": 0,
@ -918,11 +1086,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 465,
"end": 0,
"name": "line",
"name": {
"commentStart": 465,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 465,
"end": 0,
@ -934,11 +1110,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 527,
"end": 0,
"name": "close",
"name": {
"commentStart": 527,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 527,
"end": 0,
@ -1000,11 +1184,19 @@ description: Result of parsing artifact_graph_example_code1.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 548,
"end": 0,
"name": "extrude",
"name": {
"commentStart": 548,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 548,
"end": 0,
@ -1012,12 +1204,20 @@ description: Result of parsing artifact_graph_example_code1.kcl
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"abs_path": false,
"commentStart": 556,
"end": 0,
"name": "sketch002",
"name": {
"commentStart": 556,
"end": 0,
"name": "sketch002",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
"start": 0,

View File

@ -32,11 +32,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 12,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 12,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 12,
"end": 0,
@ -88,11 +96,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 37,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 37,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 37,
"end": 0,
@ -152,11 +168,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 71,
"end": 0,
"name": "angledLine",
"name": {
"commentStart": 71,
"end": 0,
"name": "angledLine",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 71,
"end": 0,
@ -175,20 +199,36 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
"left": {
"arguments": [
{
"abs_path": false,
"commentStart": 154,
"end": 0,
"name": "rectangleSegmentA001",
"name": {
"commentStart": 154,
"end": 0,
"name": "rectangleSegmentA001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 147,
"end": 0,
"name": "segAng",
"name": {
"commentStart": 147,
"end": 0,
"name": "segAng",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 147,
"end": 0,
@ -248,11 +288,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 127,
"end": 0,
"name": "angledLine",
"name": {
"commentStart": 127,
"end": 0,
"name": "angledLine",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 127,
"end": 0,
@ -268,20 +316,36 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
{
"arguments": [
{
"abs_path": false,
"commentStart": 260,
"end": 0,
"name": "rectangleSegmentA001",
"name": {
"commentStart": 260,
"end": 0,
"name": "rectangleSegmentA001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 253,
"end": 0,
"name": "segAng",
"name": {
"commentStart": 253,
"end": 0,
"name": "segAng",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 253,
"end": 0,
@ -293,20 +357,36 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
"argument": {
"arguments": [
{
"abs_path": false,
"commentStart": 298,
"end": 0,
"name": "rectangleSegmentA001",
"name": {
"commentStart": 298,
"end": 0,
"name": "rectangleSegmentA001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 291,
"end": 0,
"name": "segLen",
"name": {
"commentStart": 291,
"end": 0,
"name": "segLen",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 291,
"end": 0,
@ -344,11 +424,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 233,
"end": 0,
"name": "angledLine",
"name": {
"commentStart": 233,
"end": 0,
"name": "angledLine",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 233,
"end": 0,
@ -381,11 +469,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 379,
"end": 0,
"name": "profileStartX",
"name": {
"commentStart": 379,
"end": 0,
"name": "profileStartX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 379,
"end": 0,
@ -404,11 +500,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 397,
"end": 0,
"name": "profileStartY",
"name": {
"commentStart": 397,
"end": 0,
"name": "profileStartY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 397,
"end": 0,
@ -425,11 +529,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 359,
"end": 0,
"name": "line",
"name": {
"commentStart": 359,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 359,
"end": 0,
@ -441,11 +553,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 421,
"end": 0,
"name": "close",
"name": {
"commentStart": 421,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 421,
"end": 0,
@ -496,11 +616,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 441,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 441,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 441,
"end": 0,
@ -552,11 +680,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 467,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 467,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 467,
"end": 0,
@ -611,11 +747,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 502,
"end": 0,
"name": "line",
"name": {
"commentStart": 502,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 502,
"end": 0,
@ -668,11 +812,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 533,
"end": 0,
"name": "tangentialArcTo",
"name": {
"commentStart": 533,
"end": 0,
"name": "tangentialArcTo",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 533,
"end": 0,
@ -732,11 +884,19 @@ description: Result of parsing artifact_graph_example_code_no_3d.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 565,
"end": 0,
"name": "tangentialArcTo",
"name": {
"commentStart": 565,
"end": 0,
"name": "tangentialArcTo",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 565,
"end": 0,

View File

@ -43,11 +43,19 @@ description: Result of parsing artifact_graph_example_code_offset_planes.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 17,
"end": 0,
"name": "offsetPlane",
"name": {
"commentStart": 17,
"end": 0,
"name": "offsetPlane",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 17,
"end": 0,
@ -119,11 +127,19 @@ description: Result of parsing artifact_graph_example_code_offset_planes.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 65,
"end": 0,
"name": "offsetPlane",
"name": {
"commentStart": 65,
"end": 0,
"name": "offsetPlane",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 65,
"end": 0,
@ -187,11 +203,19 @@ description: Result of parsing artifact_graph_example_code_offset_planes.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 114,
"end": 0,
"name": "offsetPlane",
"name": {
"commentStart": 114,
"end": 0,
"name": "offsetPlane",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 114,
"end": 0,
@ -234,20 +258,36 @@ description: Result of parsing artifact_graph_example_code_offset_planes.kcl
{
"arguments": [
{
"abs_path": false,
"commentStart": 172,
"end": 0,
"name": "offsetPlane001",
"name": {
"commentStart": 172,
"end": 0,
"name": "offsetPlane001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 158,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 158,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 158,
"end": 0,
@ -299,11 +339,19 @@ description: Result of parsing artifact_graph_example_code_offset_planes.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 193,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 193,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 193,
"end": 0,
@ -358,11 +406,19 @@ description: Result of parsing artifact_graph_example_code_offset_planes.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 224,
"end": 0,
"name": "line",
"name": {
"commentStart": 224,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 224,
"end": 0,

View File

@ -32,11 +32,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 12,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 12,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 12,
"end": 0,
@ -88,11 +96,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 37,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 37,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 37,
"end": 0,
@ -147,11 +163,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 68,
"end": 0,
"name": "line",
"name": {
"commentStart": 68,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 68,
"end": 0,
@ -233,11 +257,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 92,
"end": 0,
"name": "line",
"name": {
"commentStart": 92,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 92,
"end": 0,
@ -271,11 +303,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 151,
"end": 0,
"name": "profileStartX",
"name": {
"commentStart": 151,
"end": 0,
"name": "profileStartX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 151,
"end": 0,
@ -294,11 +334,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 169,
"end": 0,
"name": "profileStartY",
"name": {
"commentStart": 169,
"end": 0,
"name": "profileStartY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 169,
"end": 0,
@ -315,11 +363,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 131,
"end": 0,
"name": "line",
"name": {
"commentStart": 131,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 131,
"end": 0,
@ -331,11 +387,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 193,
"end": 0,
"name": "close",
"name": {
"commentStart": 193,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 193,
"end": 0,
@ -397,11 +461,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 214,
"end": 0,
"name": "extrude",
"name": {
"commentStart": 214,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 214,
"end": 0,
@ -409,12 +481,20 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"abs_path": false,
"commentStart": 222,
"end": 0,
"name": "sketch001",
"name": {
"commentStart": 222,
"end": 0,
"name": "sketch001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
"start": 0,
@ -443,28 +523,52 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
{
"arguments": [
{
"abs_path": false,
"commentStart": 271,
"end": 0,
"name": "extrude001",
"name": {
"commentStart": 271,
"end": 0,
"name": "extrude001",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"abs_path": false,
"commentStart": 283,
"end": 0,
"name": "seg01",
"name": {
"commentStart": 283,
"end": 0,
"name": "seg01",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 257,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 257,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 257,
"end": 0,
@ -524,11 +628,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 295,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 295,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 295,
"end": 0,
@ -583,11 +695,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 331,
"end": 0,
"name": "line",
"name": {
"commentStart": 331,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 331,
"end": 0,
@ -651,11 +771,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 355,
"end": 0,
"name": "line",
"name": {
"commentStart": 355,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 355,
"end": 0,
@ -689,11 +817,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 400,
"end": 0,
"name": "profileStartX",
"name": {
"commentStart": 400,
"end": 0,
"name": "profileStartX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 400,
"end": 0,
@ -712,11 +848,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 418,
"end": 0,
"name": "profileStartY",
"name": {
"commentStart": 418,
"end": 0,
"name": "profileStartY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 418,
"end": 0,
@ -733,11 +877,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 380,
"end": 0,
"name": "line",
"name": {
"commentStart": 380,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 380,
"end": 0,
@ -749,11 +901,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 442,
"end": 0,
"name": "close",
"name": {
"commentStart": 442,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 442,
"end": 0,
@ -815,11 +975,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 463,
"end": 0,
"name": "extrude",
"name": {
"commentStart": 463,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 463,
"end": 0,
@ -827,12 +995,20 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"abs_path": false,
"commentStart": 471,
"end": 0,
"name": "sketch002",
"name": {
"commentStart": 471,
"end": 0,
"name": "sketch002",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
"start": 0,
@ -861,12 +1037,20 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
{
"arguments": [
{
"abs_path": false,
"commentStart": 520,
"end": 0,
"name": "extrude002",
"name": {
"commentStart": 520,
"end": 0,
"name": "extrude002",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"commentStart": 532,
@ -879,11 +1063,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 506,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 506,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 506,
"end": 0,
@ -935,11 +1127,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 544,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 544,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 544,
"end": 0,
@ -1012,11 +1212,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 577,
"end": 0,
"name": "line",
"name": {
"commentStart": 577,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 577,
"end": 0,
@ -1080,11 +1288,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 617,
"end": 0,
"name": "line",
"name": {
"commentStart": 617,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 617,
"end": 0,
@ -1118,11 +1334,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 662,
"end": 0,
"name": "profileStartX",
"name": {
"commentStart": 662,
"end": 0,
"name": "profileStartX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 662,
"end": 0,
@ -1141,11 +1365,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 680,
"end": 0,
"name": "profileStartY",
"name": {
"commentStart": 680,
"end": 0,
"name": "profileStartY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 680,
"end": 0,
@ -1162,11 +1394,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 642,
"end": 0,
"name": "line",
"name": {
"commentStart": 642,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 642,
"end": 0,
@ -1178,11 +1418,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 704,
"end": 0,
"name": "close",
"name": {
"commentStart": 704,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 704,
"end": 0,
@ -1244,11 +1492,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 725,
"end": 0,
"name": "extrude",
"name": {
"commentStart": 725,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 725,
"end": 0,
@ -1256,12 +1512,20 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"abs_path": false,
"commentStart": 733,
"end": 0,
"name": "sketch003",
"name": {
"commentStart": 733,
"end": 0,
"name": "sketch003",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
"start": 0,
@ -1290,28 +1554,52 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
{
"arguments": [
{
"abs_path": false,
"commentStart": 782,
"end": 0,
"name": "extrude003",
"name": {
"commentStart": 782,
"end": 0,
"name": "extrude003",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
{
"abs_path": false,
"commentStart": 794,
"end": 0,
"name": "seg02",
"name": {
"commentStart": 794,
"end": 0,
"name": "seg02",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
],
"callee": {
"abs_path": false,
"commentStart": 768,
"end": 0,
"name": "startSketchOn",
"name": {
"commentStart": 768,
"end": 0,
"name": "startSketchOn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 768,
"end": 0,
@ -1371,11 +1659,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 806,
"end": 0,
"name": "startProfileAt",
"name": {
"commentStart": 806,
"end": 0,
"name": "startProfileAt",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 806,
"end": 0,
@ -1430,11 +1726,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 839,
"end": 0,
"name": "line",
"name": {
"commentStart": 839,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 839,
"end": 0,
@ -1498,11 +1802,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 865,
"end": 0,
"name": "line",
"name": {
"commentStart": 865,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 865,
"end": 0,
@ -1536,11 +1848,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 912,
"end": 0,
"name": "profileStartX",
"name": {
"commentStart": 912,
"end": 0,
"name": "profileStartX",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 912,
"end": 0,
@ -1559,11 +1879,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 930,
"end": 0,
"name": "profileStartY",
"name": {
"commentStart": 930,
"end": 0,
"name": "profileStartY",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 930,
"end": 0,
@ -1580,11 +1908,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 892,
"end": 0,
"name": "line",
"name": {
"commentStart": 892,
"end": 0,
"name": "line",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 892,
"end": 0,
@ -1596,11 +1932,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
{
"arguments": [],
"callee": {
"abs_path": false,
"commentStart": 954,
"end": 0,
"name": "close",
"name": {
"commentStart": 954,
"end": 0,
"name": "close",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 954,
"end": 0,
@ -1662,11 +2006,19 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
}
],
"callee": {
"abs_path": false,
"commentStart": 975,
"end": 0,
"name": "extrude",
"name": {
"commentStart": 975,
"end": 0,
"name": "extrude",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier"
"type": "Name"
},
"commentStart": 975,
"end": 0,
@ -1674,12 +2026,20 @@ description: Result of parsing artifact_graph_sketch_on_face_etc.kcl
"type": "CallExpressionKw",
"type": "CallExpressionKw",
"unlabeled": {
"abs_path": false,
"commentStart": 983,
"end": 0,
"name": "sketch004",
"name": {
"commentStart": 983,
"end": 0,
"name": "sketch004",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
},
"start": 0,

View File

@ -1,25 +1,25 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[76, 113, 3]"]
3["Segment<br>[119, 136, 3]"]
4["Segment<br>[142, 160, 3]"]
5["Segment<br>[166, 184, 3]"]
6["Segment<br>[190, 246, 3]"]
7["Segment<br>[252, 259, 3]"]
2["Path<br>[76, 113, 4]"]
3["Segment<br>[119, 136, 4]"]
4["Segment<br>[142, 160, 4]"]
5["Segment<br>[166, 184, 4]"]
6["Segment<br>[190, 246, 4]"]
7["Segment<br>[252, 259, 4]"]
8[Solid2d]
end
subgraph path25 [Path]
25["Path<br>[76, 111, 4]"]
26["Segment<br>[117, 134, 4]"]
27["Segment<br>[140, 158, 4]"]
28["Segment<br>[164, 182, 4]"]
29["Segment<br>[188, 244, 4]"]
30["Segment<br>[250, 257, 4]"]
25["Path<br>[76, 111, 5]"]
26["Segment<br>[117, 134, 5]"]
27["Segment<br>[140, 158, 5]"]
28["Segment<br>[164, 182, 5]"]
29["Segment<br>[188, 244, 5]"]
30["Segment<br>[250, 257, 5]"]
31[Solid2d]
end
1["Plane<br>[47, 66, 3]"]
9["Sweep Extrusion<br>[265, 287, 3]"]
1["Plane<br>[47, 66, 4]"]
9["Sweep Extrusion<br>[265, 287, 4]"]
10[Wall]
11[Wall]
12[Wall]
@ -34,8 +34,8 @@ flowchart LR
21["SweepEdge Adjacent"]
22["SweepEdge Opposite"]
23["SweepEdge Adjacent"]
24["Plane<br>[47, 66, 4]"]
32["Sweep Extrusion<br>[263, 285, 4]"]
24["Plane<br>[47, 66, 5]"]
32["Sweep Extrusion<br>[263, 285, 5]"]
33[Wall]
34[Wall]
35[Wall]

View File

@ -51,12 +51,20 @@ description: Result of parsing assembly_mixed_units_cubes.kcl
"commentStart": 100,
"end": 0,
"expression": {
"abs_path": false,
"commentStart": 102,
"end": 0,
"name": "cubeIn",
"name": {
"commentStart": 102,
"end": 0,
"name": "cubeIn",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"start": 0,
"type": "ExpressionStatement",
@ -66,12 +74,20 @@ description: Result of parsing assembly_mixed_units_cubes.kcl
"commentStart": 109,
"end": 0,
"expression": {
"abs_path": false,
"commentStart": 109,
"end": 0,
"name": "cubeMm",
"name": {
"commentStart": 109,
"end": 0,
"name": "cubeMm",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
},
"start": 0,
"type": "ExpressionStatement",
@ -105,12 +121,20 @@ description: Result of parsing assembly_mixed_units_cubes.kcl
"start": 0,
"type": "ObjectProperty",
"value": {
"abs_path": false,
"commentStart": 30,
"end": 0,
"name": "in",
"name": {
"commentStart": 30,
"end": 0,
"name": "in",
"start": 0,
"type": "Identifier"
},
"path": [],
"start": 0,
"type": "Identifier",
"type": "Identifier"
"type": "Name",
"type": "Name"
}
}
],

View File

@ -5,10 +5,10 @@ description: Variables in memory after executing assembly_mixed_units_cubes.kcl
{
"cubeIn": {
"type": "Module",
"value": 3
"value": 4
},
"cubeMm": {
"type": "Module",
"value": 4
"value": 5
}
}

Some files were not shown because too many files have changed in this diff Show More