2023-02-21 10:50:45 +11:00
|
|
|
import {
|
|
|
|
ProgramMemory,
|
|
|
|
Path,
|
2024-09-27 15:44:44 -07:00
|
|
|
Sketch,
|
2023-02-21 10:50:45 +11:00
|
|
|
SourceRange,
|
|
|
|
PathToNode,
|
2023-02-12 10:56:45 +11:00
|
|
|
Program,
|
|
|
|
PipeExpression,
|
|
|
|
CallExpression,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
CallExpressionKw,
|
2023-02-12 10:56:45 +11:00
|
|
|
VariableDeclarator,
|
2024-08-12 15:38:42 -05:00
|
|
|
Expr,
|
2023-03-19 18:46:39 +11:00
|
|
|
VariableDeclaration,
|
2024-06-24 22:39:04 -07:00
|
|
|
Identifier,
|
2024-09-27 15:44:44 -07:00
|
|
|
sketchFromKclValue,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange,
|
2024-05-24 20:54:42 +10:00
|
|
|
} from 'lang/wasm'
|
2023-03-03 20:35:48 +11:00
|
|
|
import {
|
|
|
|
getNodeFromPath,
|
|
|
|
getNodeFromPathCurry,
|
2024-09-23 22:42:51 +10:00
|
|
|
getObjExprProperty,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
LABELED_ARG_FIELD,
|
2024-05-24 20:54:42 +10:00
|
|
|
} from 'lang/queryAst'
|
2025-01-27 14:24:28 +01:00
|
|
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
2024-05-24 20:54:42 +10:00
|
|
|
import {
|
|
|
|
isLiteralArrayOrStatic,
|
|
|
|
isNotLiteralArrayOrStatic,
|
|
|
|
} from 'lang/std/sketchcombos'
|
2024-07-02 17:16:27 +10:00
|
|
|
import { toolTips, ToolTip } from 'lang/langHelpers'
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
import {
|
|
|
|
createPipeExpression,
|
|
|
|
mutateKwArg,
|
|
|
|
splitPathAtPipeExpression,
|
|
|
|
} from '../modifyAst'
|
2023-02-12 10:56:45 +11:00
|
|
|
|
2024-05-24 20:54:42 +10:00
|
|
|
import {
|
|
|
|
SketchLineHelper,
|
|
|
|
ConstrainInfo,
|
|
|
|
ArrayItemInput,
|
|
|
|
ObjectPropertyInput,
|
|
|
|
SingleValueInput,
|
2024-07-15 19:20:32 +10:00
|
|
|
AddTagInfo,
|
2024-09-13 21:14:14 +10:00
|
|
|
SegmentInputs,
|
|
|
|
SimplifiedArgDetails,
|
|
|
|
RawArgs,
|
|
|
|
CreatedSketchExprResult,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
SketchLineHelperKw,
|
2024-05-24 20:54:42 +10:00
|
|
|
} from 'lang/std/stdTypes'
|
2023-02-12 10:56:45 +11:00
|
|
|
|
|
|
|
import {
|
|
|
|
createLiteral,
|
2024-06-24 22:39:04 -07:00
|
|
|
createTagDeclarator,
|
2023-02-12 10:56:45 +11:00
|
|
|
createCallExpression,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
createCallExpressionStdLibKw,
|
2023-02-12 10:56:45 +11:00
|
|
|
createArrayExpression,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
createLabeledArg,
|
2023-02-12 10:56:45 +11:00
|
|
|
createPipeSubstitution,
|
|
|
|
createObjectExpression,
|
|
|
|
mutateArrExp,
|
|
|
|
mutateObjExpProp,
|
|
|
|
findUniqueName,
|
2024-05-24 20:54:42 +10:00
|
|
|
} from 'lang/modifyAst'
|
2025-02-05 09:01:45 -05:00
|
|
|
import { roundOff, getLength, getAngle, isArray } from 'lib/utils'
|
2024-06-24 11:45:40 -04:00
|
|
|
import { err } from 'lib/trap'
|
2023-08-24 17:28:59 -07:00
|
|
|
import { perpendicularDistance } from 'sketch-helpers'
|
2024-06-24 22:39:04 -07:00
|
|
|
import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
|
2024-09-26 18:25:05 +10:00
|
|
|
import { EdgeCutInfo } from 'machines/modelingMachine'
|
2024-10-30 16:52:17 -04:00
|
|
|
import { Node } from 'wasm-lib/kcl/bindings/Node'
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
import { findKwArg, findKwArgAny, findKwArgAnyIndex } from 'lang/util'
|
|
|
|
|
|
|
|
export const ARG_TAG = 'tag'
|
|
|
|
export const ARG_END = 'end'
|
|
|
|
export const ARG_END_ABSOLUTE = 'endAbsolute'
|
2023-02-12 10:56:45 +11:00
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
const STRAIGHT_SEGMENT_ERR = new Error(
|
|
|
|
'Invalid input, expected "straight-segment"'
|
|
|
|
)
|
2024-09-23 22:42:51 +10:00
|
|
|
const ARC_SEGMENT_ERR = new Error('Invalid input, expected "arc-segment"')
|
2024-09-13 21:14:14 +10:00
|
|
|
|
2023-02-12 10:56:45 +11:00
|
|
|
export type Coords2d = [number, number]
|
|
|
|
|
2024-09-27 15:44:44 -07:00
|
|
|
export function getCoordsFromPaths(skGroup: Sketch, index = 0): Coords2d {
|
2024-10-23 12:42:54 -05:00
|
|
|
const currentPath = skGroup?.paths?.[index]
|
2023-02-12 10:56:45 +11:00
|
|
|
if (!currentPath && skGroup?.start) {
|
2023-03-17 08:27:40 +11:00
|
|
|
return skGroup.start.to
|
2023-02-12 10:56:45 +11:00
|
|
|
} else if (!currentPath) {
|
|
|
|
return [0, 0]
|
|
|
|
}
|
2024-02-11 12:59:00 +11:00
|
|
|
if (currentPath.type === 'ToPoint') {
|
2023-02-12 10:56:45 +11:00
|
|
|
return [currentPath.to[0], currentPath.to[1]]
|
|
|
|
}
|
|
|
|
return [0, 0]
|
|
|
|
}
|
|
|
|
|
2023-03-02 21:19:11 +11:00
|
|
|
export function createFirstArg(
|
2023-09-15 11:48:23 -04:00
|
|
|
sketchFn: ToolTip,
|
2024-08-12 15:38:42 -05:00
|
|
|
val: Expr | [Expr, Expr] | [Expr, Expr, Expr]
|
|
|
|
): Expr | Error {
|
2025-02-05 09:01:45 -05:00
|
|
|
if (isArray(val)) {
|
2023-02-21 10:50:45 +11:00
|
|
|
if (
|
2024-03-15 17:03:42 -04:00
|
|
|
[
|
|
|
|
'angledLine',
|
|
|
|
'angledLineOfXLength',
|
|
|
|
'angledLineOfYLength',
|
|
|
|
'angledLineToX',
|
|
|
|
'angledLineToY',
|
|
|
|
].includes(sketchFn)
|
2023-02-21 10:50:45 +11:00
|
|
|
)
|
2024-03-15 17:03:42 -04:00
|
|
|
return createArrayExpression(val)
|
2023-04-03 16:05:25 +10:00
|
|
|
if (['angledLineThatIntersects'].includes(sketchFn) && val[2])
|
|
|
|
return createObjectExpression({
|
|
|
|
angle: val[0],
|
|
|
|
offset: val[1],
|
|
|
|
intersectTag: val[2],
|
|
|
|
})
|
2023-02-21 10:50:45 +11:00
|
|
|
} else {
|
2024-03-15 17:03:42 -04:00
|
|
|
if (
|
|
|
|
['startSketchAt', 'xLine', 'xLineTo', 'yLine', 'yLineTo'].includes(
|
|
|
|
sketchFn
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return val
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('Missing sketch line type')
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
|
|
|
|
2024-05-24 20:54:42 +10:00
|
|
|
type AbbreviatedInput =
|
|
|
|
| ArrayItemInput<any>['index']
|
|
|
|
| ObjectPropertyInput<any>['key']
|
|
|
|
| SingleValueInput<any>['type']
|
2024-09-13 21:14:14 +10:00
|
|
|
| SimplifiedArgDetails
|
2024-05-24 20:54:42 +10:00
|
|
|
| undefined
|
|
|
|
|
|
|
|
const constrainInfo = (
|
|
|
|
a: ConstrainInfo['type'],
|
|
|
|
b: ConstrainInfo['isConstrained'],
|
|
|
|
c: ConstrainInfo['value'],
|
|
|
|
f: ConstrainInfo['stdLibFnName'],
|
|
|
|
g: AbbreviatedInput,
|
|
|
|
d: ConstrainInfo['sourceRange'],
|
|
|
|
e: ConstrainInfo['pathToNode']
|
|
|
|
): ConstrainInfo => ({
|
|
|
|
type: a,
|
|
|
|
isConstrained: b,
|
|
|
|
value: c,
|
|
|
|
sourceRange: d,
|
|
|
|
argPosition:
|
|
|
|
g === 'singleValue'
|
|
|
|
? { type: 'singleValue' }
|
|
|
|
: typeof g === 'number'
|
|
|
|
? { type: 'arrayItem', index: g }
|
|
|
|
: typeof g === 'string'
|
|
|
|
? { type: 'objectProperty', key: g }
|
|
|
|
: undefined,
|
|
|
|
pathToNode: e,
|
|
|
|
stdLibFnName: f,
|
|
|
|
})
|
|
|
|
|
|
|
|
const commonConstraintInfoHelper = (
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
callExp: CallExpression | CallExpressionKw,
|
2024-05-24 20:54:42 +10:00
|
|
|
inputConstrainTypes: [ConstrainInfo['type'], ConstrainInfo['type']],
|
|
|
|
stdLibFnName: ConstrainInfo['stdLibFnName'],
|
|
|
|
abbreviatedInputs: [
|
|
|
|
{
|
|
|
|
arrayInput?: 0 | 1
|
|
|
|
objInput?: ObjectPropertyInput<any>['key']
|
|
|
|
},
|
|
|
|
{
|
|
|
|
arrayInput?: 0 | 1
|
|
|
|
objInput?: ObjectPropertyInput<any>['key']
|
|
|
|
}
|
|
|
|
],
|
|
|
|
code: string,
|
|
|
|
pathToNode: PathToNode
|
|
|
|
) => {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (callExp.type !== 'CallExpression' && callExp.type !== 'CallExpressionKw')
|
|
|
|
return []
|
|
|
|
const firstArg = (() => {
|
|
|
|
switch (callExp.type) {
|
|
|
|
case 'CallExpression':
|
|
|
|
return callExp.arguments[0]
|
|
|
|
case 'CallExpressionKw':
|
|
|
|
return findKwArgAny([ARG_END, ARG_END_ABSOLUTE], callExp)
|
|
|
|
}
|
|
|
|
})()
|
|
|
|
if (firstArg === undefined) {
|
|
|
|
return []
|
|
|
|
}
|
2024-05-24 20:54:42 +10:00
|
|
|
const isArr = firstArg.type === 'ArrayExpression'
|
|
|
|
if (!isArr && firstArg.type !== 'ObjectExpression') return []
|
2024-09-13 21:14:14 +10:00
|
|
|
const pipeExpressionIndex = pathToNode.findIndex(
|
|
|
|
([_, nodeName]) => nodeName === 'PipeExpression'
|
|
|
|
)
|
|
|
|
const pathToBase = pathToNode.slice(0, pipeExpressionIndex + 2)
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const argIndex = (() => {
|
|
|
|
switch (callExp.type) {
|
|
|
|
case 'CallExpression':
|
|
|
|
return 0
|
|
|
|
case 'CallExpressionKw':
|
|
|
|
return findKwArgAnyIndex([ARG_END, ARG_END_ABSOLUTE], callExp)
|
|
|
|
}
|
|
|
|
})()
|
|
|
|
if (argIndex === undefined) {
|
|
|
|
return []
|
|
|
|
}
|
|
|
|
|
|
|
|
// Construct the pathToNode.
|
|
|
|
const pathToArrayExpression: PathToNode = (() => {
|
|
|
|
const isKw = callExp.type === 'CallExpressionKw'
|
|
|
|
let path: PathToNode = [
|
|
|
|
...pathToBase,
|
|
|
|
['arguments', callExp.type],
|
|
|
|
[argIndex, 'index'],
|
|
|
|
]
|
|
|
|
if (isKw) {
|
|
|
|
path.push(['arg', LABELED_ARG_FIELD])
|
|
|
|
}
|
|
|
|
path.push(
|
|
|
|
isArr
|
|
|
|
? ['elements', 'ArrayExpression']
|
|
|
|
: ['properties', 'ObjectExpression']
|
|
|
|
)
|
|
|
|
return path
|
|
|
|
})()
|
|
|
|
|
2024-05-24 20:54:42 +10:00
|
|
|
const pathToFirstArg: PathToNode = isArr
|
|
|
|
? [...pathToArrayExpression, [0, 'index']]
|
|
|
|
: [
|
|
|
|
...pathToArrayExpression,
|
|
|
|
[
|
|
|
|
firstArg.properties.findIndex(
|
|
|
|
(a) => a.key.name === abbreviatedInputs[0].objInput
|
|
|
|
),
|
|
|
|
'index',
|
|
|
|
],
|
|
|
|
['value', 'Property'],
|
|
|
|
]
|
|
|
|
|
|
|
|
const pathToSecondArg: PathToNode = isArr
|
|
|
|
? [...pathToArrayExpression, [1, 'index']]
|
|
|
|
: [
|
|
|
|
...pathToArrayExpression,
|
|
|
|
[
|
|
|
|
firstArg.properties.findIndex(
|
|
|
|
(a) => a.key.name === abbreviatedInputs[1].objInput
|
|
|
|
),
|
|
|
|
'index',
|
|
|
|
],
|
|
|
|
['value', 'Property'],
|
|
|
|
]
|
|
|
|
|
|
|
|
const input1 = isArr
|
|
|
|
? firstArg.elements[0]
|
|
|
|
: firstArg.properties.find(
|
|
|
|
(a) => a.key.name === abbreviatedInputs[0].objInput
|
|
|
|
)?.value
|
|
|
|
const input2 = isArr
|
|
|
|
? firstArg.elements[1]
|
|
|
|
: firstArg.properties.find(
|
|
|
|
(a) => a.key.name === abbreviatedInputs[1].objInput
|
|
|
|
)?.value
|
|
|
|
|
|
|
|
const constraints: ConstrainInfo[] = []
|
|
|
|
if (input1)
|
|
|
|
constraints.push(
|
|
|
|
constrainInfo(
|
|
|
|
inputConstrainTypes[0],
|
|
|
|
isNotLiteralArrayOrStatic(input1),
|
|
|
|
code.slice(input1.start, input1.end),
|
|
|
|
stdLibFnName,
|
|
|
|
isArr ? abbreviatedInputs[0].arrayInput : abbreviatedInputs[0].objInput,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(input1.start, input1.end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToFirstArg
|
|
|
|
)
|
|
|
|
)
|
|
|
|
if (input2)
|
|
|
|
constraints.push(
|
|
|
|
constrainInfo(
|
|
|
|
inputConstrainTypes[1],
|
|
|
|
isNotLiteralArrayOrStatic(input2),
|
|
|
|
code.slice(input2.start, input2.end),
|
|
|
|
stdLibFnName,
|
|
|
|
isArr ? abbreviatedInputs[1].arrayInput : abbreviatedInputs[1].objInput,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(input2.start, input2.end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToSecondArg
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
return constraints
|
|
|
|
}
|
|
|
|
|
|
|
|
const horzVertConstraintInfoHelper = (
|
|
|
|
callExp: CallExpression,
|
|
|
|
inputConstrainTypes: [ConstrainInfo['type'], ConstrainInfo['type']],
|
|
|
|
stdLibFnName: ConstrainInfo['stdLibFnName'],
|
|
|
|
abbreviatedInput: AbbreviatedInput,
|
|
|
|
code: string,
|
|
|
|
pathToNode: PathToNode
|
|
|
|
) => {
|
|
|
|
if (callExp.type !== 'CallExpression') return []
|
|
|
|
const firstArg = callExp.arguments?.[0]
|
|
|
|
const callee = callExp.callee
|
|
|
|
const pathToFirstArg: PathToNode = [
|
|
|
|
...pathToNode,
|
|
|
|
['arguments', 'CallExpression'],
|
|
|
|
[0, 'index'],
|
|
|
|
]
|
|
|
|
const pathToCallee: PathToNode = [...pathToNode, ['callee', 'CallExpression']]
|
|
|
|
return [
|
|
|
|
constrainInfo(
|
|
|
|
inputConstrainTypes[0],
|
|
|
|
true,
|
|
|
|
callee.name,
|
|
|
|
stdLibFnName,
|
|
|
|
undefined,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(callee.start, callee.end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToCallee
|
|
|
|
),
|
|
|
|
constrainInfo(
|
|
|
|
inputConstrainTypes[1],
|
|
|
|
isNotLiteralArrayOrStatic(callExp.arguments?.[0]),
|
|
|
|
code.slice(firstArg.start, firstArg.end),
|
|
|
|
stdLibFnName,
|
|
|
|
abbreviatedInput,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(firstArg.start, firstArg.end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToFirstArg
|
|
|
|
),
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2024-07-15 19:20:32 +10:00
|
|
|
function getTag(index = 2): SketchLineHelper['getTag'] {
|
|
|
|
return (callExp: CallExpression) => {
|
|
|
|
if (callExp.type !== 'CallExpression')
|
|
|
|
return new Error('Not a CallExpression')
|
|
|
|
const arg = callExp.arguments?.[index]
|
|
|
|
if (!arg) return new Error('No argument')
|
|
|
|
if (arg.type !== 'TagDeclarator')
|
|
|
|
return new Error('Tag not a TagDeclarator')
|
|
|
|
return arg.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
function getTagKwArg(): SketchLineHelperKw['getTag'] {
|
|
|
|
return (callExp: CallExpressionKw) => {
|
|
|
|
if (callExp.type !== 'CallExpressionKw')
|
|
|
|
return new Error('Not a CallExpressionKw')
|
|
|
|
const arg = findKwArg(ARG_TAG, callExp)
|
|
|
|
if (!arg) return new Error('No argument')
|
|
|
|
if (arg.type !== 'TagDeclarator')
|
|
|
|
return new Error('Tag not a TagDeclarator')
|
|
|
|
return arg.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const line: SketchLineHelperKw = {
|
|
|
|
add: ({
|
|
|
|
node,
|
|
|
|
previousProgramMemory,
|
|
|
|
pathToNode,
|
|
|
|
segmentInput,
|
|
|
|
replaceExistingCallback,
|
|
|
|
spliceBetween,
|
|
|
|
}) => {
|
2024-09-13 21:14:14 +10:00
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const { from, to } = segmentInput
|
2024-12-16 10:34:11 -05:00
|
|
|
const _node = { ...node }
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression | CallExpressionKw>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
2024-12-16 10:34:11 -05:00
|
|
|
const { node: pipe } = nodeMeta
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const nodeMeta2 = getNodeFromPath<VariableDeclarator>(
|
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
|
|
|
if (err(nodeMeta2)) return nodeMeta2
|
|
|
|
const { node: varDec } = nodeMeta2
|
2023-03-05 07:34:56 +11:00
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const newXVal = createLiteral(roundOff(to[0] - from[0], 2))
|
|
|
|
const newYVal = createLiteral(roundOff(to[1] - from[1], 2))
|
2023-03-05 07:34:56 +11:00
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (
|
|
|
|
spliceBetween &&
|
|
|
|
!replaceExistingCallback &&
|
|
|
|
pipe.type === 'PipeExpression'
|
|
|
|
) {
|
|
|
|
const callExp = createCallExpressionStdLibKw(
|
|
|
|
'line',
|
|
|
|
null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution.
|
|
|
|
// TODO: ADAM: This should have a tag sometimes.
|
|
|
|
[createLabeledArg(ARG_END, createArrayExpression([newXVal, newYVal]))]
|
|
|
|
)
|
|
|
|
const pathToNodeIndex = pathToNode.findIndex(
|
|
|
|
(x) => x[1] === 'PipeExpression'
|
|
|
|
)
|
|
|
|
const pipeIndex = pathToNode[pathToNodeIndex + 1][0]
|
|
|
|
if (typeof pipeIndex === 'undefined' || typeof pipeIndex === 'string') {
|
|
|
|
return new Error('pipeIndex is undefined')
|
|
|
|
}
|
|
|
|
pipe.body = [
|
|
|
|
...pipe.body.slice(0, pipeIndex),
|
|
|
|
callExp,
|
|
|
|
...pipe.body.slice(pipeIndex),
|
|
|
|
]
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (replaceExistingCallback && pipe.type !== 'CallExpressionKw') {
|
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayItem',
|
|
|
|
index: 0,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
argType: 'xRelative',
|
|
|
|
expr: createLiteral(roundOff(to[0] - from[0], 2)),
|
2024-09-13 21:14:14 +10:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayItem',
|
|
|
|
index: 1,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
argType: 'yRelative',
|
|
|
|
expr: createLiteral(roundOff(to[1] - from[1], 2)),
|
2024-09-13 21:14:14 +10:00
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2024-12-16 10:34:11 -05:00
|
|
|
pipe.body[callIndex] = callExp
|
2023-03-07 15:45:59 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
pathToNode: [...pathToNode],
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const callExp = createCallExpressionStdLibKw(
|
|
|
|
'line',
|
|
|
|
null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution.
|
|
|
|
[createLabeledArg(ARG_END, createArrayExpression([newXVal, newYVal]))]
|
|
|
|
)
|
|
|
|
if (pipe.type === 'PipeExpression') {
|
|
|
|
pipe.body = [...pipe.body, callExp]
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode: [
|
|
|
|
...pathToNode,
|
|
|
|
['body', 'PipeExpression'],
|
|
|
|
[pipe.body.length - 1, 'CallExpressionKw'],
|
|
|
|
],
|
2023-03-07 15:45:59 +11:00
|
|
|
}
|
2023-03-05 07:34:56 +11:00
|
|
|
} else {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
varDec.init = createPipeExpression([varDec.init, callExp])
|
2023-03-05 07:34:56 +11:00
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpressionKw>(_node, pathToNode)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
|
|
|
|
const toArrExp = createArrayExpression([
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
createLiteral(roundOff(to[0] - from[0], 2)),
|
|
|
|
createLiteral(roundOff(to[1] - from[1], 2)),
|
2023-02-12 10:56:45 +11:00
|
|
|
])
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
mutateKwArg(ARG_END, callExpression, toArrExp)
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
getTag: getTagKwArg(),
|
|
|
|
addTag: addTagKw(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
commonConstraintInfoHelper(
|
|
|
|
callExp,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
['xRelative', 'yRelative'],
|
|
|
|
'line',
|
2024-05-24 20:54:42 +10:00
|
|
|
[{ arrayInput: 0 }, { arrayInput: 1 }],
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
export const lineTo: SketchLineHelperKw = {
|
2023-02-12 10:56:45 +11:00
|
|
|
add: ({
|
|
|
|
node,
|
|
|
|
previousProgramMemory,
|
|
|
|
pathToNode,
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput,
|
|
|
|
replaceExistingCallback,
|
2024-04-03 13:22:56 +11:00
|
|
|
spliceBetween,
|
2023-02-12 10:56:45 +11:00
|
|
|
}) => {
|
2024-09-13 21:14:14 +10:00
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const to = segmentInput.to
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression | CallExpressionKw>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: pipe } = nodeMeta
|
|
|
|
const nodeMeta2 = getNodeFromPath<VariableDeclarator>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta2)) return nodeMeta2
|
|
|
|
const { node: varDec } = nodeMeta2
|
2023-03-02 21:19:11 +11:00
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const newXVal = createLiteral(roundOff(to[0], 2))
|
|
|
|
const newYVal = createLiteral(roundOff(to[1], 2))
|
2023-03-02 21:19:11 +11:00
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (
|
|
|
|
spliceBetween &&
|
|
|
|
!replaceExistingCallback &&
|
|
|
|
pipe.type === 'PipeExpression'
|
|
|
|
) {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const callExp = createCallExpressionStdLibKw(
|
|
|
|
'line',
|
|
|
|
null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution.
|
|
|
|
[
|
|
|
|
createLabeledArg(
|
|
|
|
ARG_END_ABSOLUTE,
|
|
|
|
createArrayExpression([newXVal, newYVal])
|
|
|
|
),
|
|
|
|
]
|
|
|
|
)
|
2024-04-03 13:22:56 +11:00
|
|
|
const pathToNodeIndex = pathToNode.findIndex(
|
|
|
|
(x) => x[1] === 'PipeExpression'
|
|
|
|
)
|
|
|
|
const pipeIndex = pathToNode[pathToNodeIndex + 1][0]
|
|
|
|
if (typeof pipeIndex === 'undefined' || typeof pipeIndex === 'string') {
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('pipeIndex is undefined')
|
2024-04-03 13:22:56 +11:00
|
|
|
}
|
|
|
|
pipe.body = [
|
|
|
|
...pipe.body.slice(0, pipeIndex),
|
|
|
|
callExp,
|
|
|
|
...pipe.body.slice(pipeIndex),
|
|
|
|
]
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (replaceExistingCallback && pipe.type !== 'CallExpressionKw') {
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayItem',
|
|
|
|
index: 0,
|
|
|
|
argType: 'xRelative',
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
expr: newXVal,
|
2024-09-13 21:14:14 +10:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayItem',
|
|
|
|
index: 1,
|
|
|
|
argType: 'yRelative',
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
expr: newYVal,
|
2024-09-13 21:14:14 +10:00
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2023-03-17 21:15:46 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
2024-06-24 11:45:40 -04:00
|
|
|
pathToNode: [...pathToNode],
|
2023-03-17 21:15:46 +11:00
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-03-02 21:19:11 +11:00
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const callExp = createCallExpressionStdLibKw(
|
|
|
|
'line',
|
|
|
|
null, // Assumes this is being called in a pipeline, so the first arg is optional and if not given, will become pipeline substitution.
|
|
|
|
[
|
|
|
|
createLabeledArg(
|
|
|
|
ARG_END_ABSOLUTE,
|
|
|
|
createArrayExpression([newXVal, newYVal])
|
|
|
|
),
|
|
|
|
]
|
|
|
|
)
|
2023-09-13 08:36:47 +10:00
|
|
|
if (pipe.type === 'PipeExpression') {
|
|
|
|
pipe.body = [...pipe.body, callExp]
|
2023-10-14 03:47:46 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode: [
|
|
|
|
...pathToNode,
|
|
|
|
['body', 'PipeExpression'],
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
[pipe.body.length - 1, 'CallExpressionKw'],
|
2023-10-14 03:47:46 +11:00
|
|
|
],
|
|
|
|
}
|
2023-09-13 08:36:47 +10:00
|
|
|
} else {
|
|
|
|
varDec.init = createPipeExpression([varDec.init, callExp])
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpressionKw>(_node, pathToNode)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
|
|
|
|
const toArrExp = createArrayExpression([
|
|
|
|
createLiteral(roundOff(to[0] - from[0], 2)),
|
|
|
|
createLiteral(roundOff(to[1] - from[1], 2)),
|
|
|
|
])
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
mutateKwArg(ARG_END_ABSOLUTE, callExpression, toArrExp)
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
getTag: getTagKwArg(),
|
|
|
|
addTag: addTagKw(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
commonConstraintInfoHelper(
|
|
|
|
callExp,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
['xAbsolute', 'yAbsolute'],
|
2024-05-24 20:54:42 +10:00
|
|
|
'line',
|
|
|
|
[{ arrayInput: 0 }, { arrayInput: 1 }],
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const xLineTo: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to } = segmentInput
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2023-02-21 10:50:45 +11:00
|
|
|
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
2024-06-24 11:45:40 -04:00
|
|
|
const _node1 = getNode<PipeExpression>('PipeExpression')
|
|
|
|
if (err(_node1)) return _node1
|
|
|
|
const { node: pipe } = _node1
|
2023-02-21 10:50:45 +11:00
|
|
|
|
|
|
|
const newVal = createLiteral(roundOff(to[0], 2))
|
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'singleValue',
|
|
|
|
argType: 'xAbsolute',
|
|
|
|
expr: createLiteral(roundOff(to[0], 2)),
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2023-03-17 21:15:46 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
2023-03-17 21:15:46 +11:00
|
|
|
const callExp = createCallExpression('xLineTo', [
|
|
|
|
newVal,
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
pipe.body = [...pipe.body, callExp]
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const newX = createLiteral(roundOff(to[0], 2))
|
2023-09-13 07:23:14 -07:00
|
|
|
if (isLiteralArrayOrStatic(callExpression.arguments?.[0])) {
|
2023-02-12 10:56:45 +11:00
|
|
|
callExpression.arguments[0] = newX
|
|
|
|
} else {
|
|
|
|
mutateObjExpProp(callExpression.arguments?.[0], newX, 'to')
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
horzVertConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['horizontal', 'xAbsolute'],
|
|
|
|
'xLineTo',
|
|
|
|
'singleValue',
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const yLineTo: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to } = segmentInput
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2023-02-21 10:50:45 +11:00
|
|
|
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
2024-06-24 11:45:40 -04:00
|
|
|
const _node1 = getNode<PipeExpression>('PipeExpression')
|
|
|
|
if (err(_node1)) return _node1
|
|
|
|
const { node: pipe } = _node1
|
2023-02-21 10:50:45 +11:00
|
|
|
|
|
|
|
const newVal = createLiteral(roundOff(to[1], 2))
|
2023-03-17 21:15:46 +11:00
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'singleValue',
|
|
|
|
argType: 'yAbsolute',
|
|
|
|
expr: newVal,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2023-03-17 21:15:46 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
2023-03-17 21:15:46 +11:00
|
|
|
const callExp = createCallExpression('yLineTo', [
|
|
|
|
newVal,
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
pipe.body = [...pipe.body, callExp]
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const newY = createLiteral(roundOff(to[1], 2))
|
2023-09-13 07:23:14 -07:00
|
|
|
if (isLiteralArrayOrStatic(callExpression.arguments?.[0])) {
|
2023-02-12 10:56:45 +11:00
|
|
|
callExpression.arguments[0] = newY
|
|
|
|
} else {
|
|
|
|
mutateObjExpProp(callExpression.arguments?.[0], newY, 'to')
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
horzVertConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['vertical', 'yAbsolute'],
|
|
|
|
'yLineTo',
|
|
|
|
'singleValue',
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const xLine: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2024-12-16 10:34:11 -05:00
|
|
|
const _node = { ...node }
|
2023-02-21 10:50:45 +11:00
|
|
|
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
2024-12-16 10:34:11 -05:00
|
|
|
const _node1 = getNode<PipeExpression>('PipeExpression')
|
|
|
|
if (err(_node1)) return _node1
|
|
|
|
const { node: pipe } = _node1
|
2023-02-21 10:50:45 +11:00
|
|
|
|
|
|
|
const newVal = createLiteral(roundOff(to[0] - from[0], 2))
|
2023-03-10 14:55:16 +11:00
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'singleValue',
|
|
|
|
argType: 'xRelative',
|
|
|
|
expr: newVal,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2024-12-16 10:34:11 -05:00
|
|
|
pipe.body[callIndex] = callExp
|
2023-03-10 14:55:16 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
2023-03-10 14:55:16 +11:00
|
|
|
|
|
|
|
const newLine = createCallExpression('xLine', [
|
2024-09-13 21:14:14 +10:00
|
|
|
newVal,
|
2023-03-10 14:55:16 +11:00
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
2024-12-16 10:34:11 -05:00
|
|
|
pipe.body = [...pipe.body, newLine]
|
2023-02-21 10:50:45 +11:00
|
|
|
return { modifiedAst: _node, pathToNode }
|
2023-02-12 10:56:45 +11:00
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const newX = createLiteral(roundOff(to[0] - from[0], 2))
|
2023-09-13 07:23:14 -07:00
|
|
|
if (isLiteralArrayOrStatic(callExpression.arguments?.[0])) {
|
2023-02-12 10:56:45 +11:00
|
|
|
callExpression.arguments[0] = newX
|
|
|
|
} else {
|
|
|
|
mutateObjExpProp(callExpression.arguments?.[0], newX, 'length')
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
horzVertConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['horizontal', 'xRelative'],
|
|
|
|
'xLine',
|
|
|
|
'singleValue',
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const yLine: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2024-12-16 10:34:11 -05:00
|
|
|
const _node = { ...node }
|
2023-02-21 10:50:45 +11:00
|
|
|
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
2024-12-16 10:34:11 -05:00
|
|
|
const _node1 = getNode<PipeExpression>('PipeExpression')
|
|
|
|
if (err(_node1)) return _node1
|
|
|
|
const { node: pipe } = _node1
|
2023-02-21 10:50:45 +11:00
|
|
|
const newVal = createLiteral(roundOff(to[1] - from[1], 2))
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'singleValue',
|
|
|
|
argType: 'yRelative',
|
|
|
|
expr: newVal,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2024-12-16 10:34:11 -05:00
|
|
|
pipe.body[callIndex] = callExp
|
2023-03-10 14:55:16 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
2023-03-10 14:55:16 +11:00
|
|
|
|
|
|
|
const newLine = createCallExpression('yLine', [
|
|
|
|
newVal,
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
2024-12-16 10:34:11 -05:00
|
|
|
pipe.body = [...pipe.body, newLine]
|
2023-02-21 10:50:45 +11:00
|
|
|
return { modifiedAst: _node, pathToNode }
|
2023-02-12 10:56:45 +11:00
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const newY = createLiteral(roundOff(to[1] - from[1], 2))
|
2023-09-13 07:23:14 -07:00
|
|
|
if (isLiteralArrayOrStatic(callExpression.arguments?.[0])) {
|
2023-02-12 10:56:45 +11:00
|
|
|
callExpression.arguments[0] = newY
|
|
|
|
} else {
|
|
|
|
mutateObjExpProp(callExpression.arguments?.[0], newY, 'length')
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
horzVertConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['vertical', 'yRelative'],
|
|
|
|
'yLine',
|
|
|
|
'singleValue',
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
2024-02-11 12:59:00 +11:00
|
|
|
export const tangentialArcTo: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to } = segmentInput
|
2024-02-11 12:59:00 +11:00
|
|
|
const _node = { ...node }
|
|
|
|
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
2024-06-24 11:45:40 -04:00
|
|
|
const _node1 = getNode<PipeExpression | CallExpression>('PipeExpression')
|
|
|
|
if (err(_node1)) return _node1
|
|
|
|
const { node: pipe } = _node1
|
|
|
|
const _node2 = getNodeFromPath<VariableDeclarator>(
|
2024-02-11 12:59:00 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(_node2)) return _node2
|
|
|
|
const { node: varDec } = _node2
|
2024-02-11 12:59:00 +11:00
|
|
|
|
|
|
|
const toX = createLiteral(roundOff(to[0], 2))
|
|
|
|
const toY = createLiteral(roundOff(to[1], 2))
|
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback && pipe.type !== 'CallExpression') {
|
2024-02-11 12:59:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayItem',
|
|
|
|
index: 0,
|
|
|
|
argType: 'xRelative',
|
|
|
|
expr: toX,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayItem',
|
|
|
|
index: 1,
|
|
|
|
argType: 'yAbsolute',
|
|
|
|
expr: toY,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2024-02-11 12:59:00 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const newLine = createCallExpression('tangentialArcTo', [
|
|
|
|
createArrayExpression([toX, toY]),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
if (pipe.type === 'PipeExpression') {
|
|
|
|
pipe.body = [...pipe.body, newLine]
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode: [
|
|
|
|
...pathToNode,
|
|
|
|
['body', 'PipeExpression'],
|
|
|
|
[pipe.body.length - 1, 'CallExpression'],
|
|
|
|
],
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
varDec.init = createPipeExpression([varDec.init, newLine])
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to } = input
|
2024-02-11 12:59:00 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2024-02-11 12:59:00 +11:00
|
|
|
const x = createLiteral(roundOff(to[0], 2))
|
|
|
|
const y = createLiteral(roundOff(to[1], 2))
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
if (!mutateArrExp(firstArg, createArrayExpression([x, y]))) {
|
|
|
|
mutateObjExpProp(firstArg, createArrayExpression([x, y]), 'to')
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp: CallExpression, code, pathToNode) => {
|
|
|
|
if (callExp.type !== 'CallExpression') return []
|
|
|
|
const firstArg = callExp.arguments?.[0]
|
|
|
|
if (firstArg.type !== 'ArrayExpression') return []
|
|
|
|
const callee = callExp.callee
|
|
|
|
const pathToCallee: PathToNode = [
|
|
|
|
...pathToNode,
|
|
|
|
['callee', 'CallExpression'],
|
|
|
|
]
|
|
|
|
const pathToArrayExpression: PathToNode = [
|
|
|
|
...pathToNode,
|
|
|
|
['arguments', 'CallExpression'],
|
|
|
|
[0, 'index'],
|
|
|
|
['elements', 'ArrayExpression'],
|
|
|
|
]
|
|
|
|
const pathToFirstArg: PathToNode = [...pathToArrayExpression, [0, 'index']]
|
|
|
|
const pathToSecondArg: PathToNode = [...pathToArrayExpression, [1, 'index']]
|
|
|
|
return [
|
|
|
|
constrainInfo(
|
|
|
|
'tangentialWithPrevious',
|
|
|
|
true,
|
|
|
|
callee.name,
|
|
|
|
'tangentialArcTo',
|
|
|
|
undefined,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(callee.start, callee.end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToCallee
|
|
|
|
),
|
|
|
|
constrainInfo(
|
|
|
|
'xAbsolute',
|
|
|
|
isNotLiteralArrayOrStatic(firstArg.elements[0]),
|
|
|
|
code.slice(firstArg.elements[0].start, firstArg.elements[0].end),
|
|
|
|
'tangentialArcTo',
|
|
|
|
0,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(firstArg.elements[0].start, firstArg.elements[0].end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToFirstArg
|
|
|
|
),
|
|
|
|
constrainInfo(
|
|
|
|
'yAbsolute',
|
|
|
|
isNotLiteralArrayOrStatic(firstArg.elements[1]),
|
|
|
|
code.slice(firstArg.elements[1].start, firstArg.elements[1].end),
|
|
|
|
'tangentialArcTo',
|
|
|
|
1,
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(firstArg.elements[1].start, firstArg.elements[1].end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToSecondArg
|
|
|
|
),
|
|
|
|
]
|
|
|
|
},
|
2024-02-11 12:59:00 +11:00
|
|
|
}
|
2024-09-23 22:42:51 +10:00
|
|
|
export const circle: SketchLineHelper = {
|
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'arc-segment') return ARC_SEGMENT_ERR
|
|
|
|
|
|
|
|
const { center, radius } = segmentInput
|
|
|
|
const _node = { ...node }
|
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression>(
|
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: pipe } = nodeMeta
|
|
|
|
|
|
|
|
const x = createLiteral(roundOff(center[0], 2))
|
|
|
|
const y = createLiteral(roundOff(center[1], 2))
|
|
|
|
|
|
|
|
const radiusExp = createLiteral(roundOff(radius, 2))
|
|
|
|
|
|
|
|
if (replaceExistingCallback) {
|
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayInObject',
|
|
|
|
index: 0,
|
|
|
|
key: 'center',
|
|
|
|
argType: 'xAbsolute',
|
|
|
|
expr: x,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayInObject',
|
|
|
|
index: 1,
|
|
|
|
key: 'center',
|
|
|
|
argType: 'yAbsolute',
|
|
|
|
expr: y,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'objectProperty',
|
|
|
|
key: 'radius',
|
|
|
|
argType: 'radius',
|
|
|
|
expr: radiusExp,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
|
|
|
|
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new Error('not implemented')
|
|
|
|
},
|
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'arc-segment') return ARC_SEGMENT_ERR
|
|
|
|
const { center, radius } = input
|
|
|
|
const _node = { ...node }
|
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: callExpression, shallowPath } = nodeMeta
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
const newCenter = createArrayExpression([
|
|
|
|
createLiteral(roundOff(center[0])),
|
|
|
|
createLiteral(roundOff(center[1])),
|
|
|
|
])
|
|
|
|
mutateObjExpProp(firstArg, newCenter, 'center')
|
|
|
|
const newRadius = createLiteral(roundOff(radius))
|
|
|
|
mutateObjExpProp(firstArg, newRadius, 'radius')
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode: shallowPath,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getTag: getTag(),
|
|
|
|
addTag: addTag(),
|
|
|
|
getConstraintInfo: (callExp: CallExpression, code, pathToNode) => {
|
|
|
|
if (callExp.type !== 'CallExpression') return []
|
|
|
|
const firstArg = callExp.arguments?.[0]
|
|
|
|
if (firstArg.type !== 'ObjectExpression') return []
|
|
|
|
const centerDetails = getObjExprProperty(firstArg, 'center')
|
|
|
|
const radiusDetails = getObjExprProperty(firstArg, 'radius')
|
|
|
|
if (!centerDetails || !radiusDetails) return []
|
|
|
|
if (centerDetails.expr.type !== 'ArrayExpression') return []
|
|
|
|
|
|
|
|
const pathToCenterArrayExpression: PathToNode = [
|
|
|
|
...pathToNode,
|
|
|
|
['arguments', 'CallExpression'],
|
|
|
|
[0, 'index'],
|
|
|
|
['properties', 'ObjectExpression'],
|
|
|
|
[centerDetails.index, 'index'],
|
|
|
|
['value', 'Property'],
|
|
|
|
['elements', 'ArrayExpression'],
|
|
|
|
]
|
|
|
|
const pathToRadiusLiteral: PathToNode = [
|
|
|
|
...pathToNode,
|
|
|
|
['arguments', 'CallExpression'],
|
|
|
|
[0, 'index'],
|
|
|
|
['properties', 'ObjectExpression'],
|
|
|
|
[radiusDetails.index, 'index'],
|
|
|
|
['value', 'Property'],
|
|
|
|
]
|
|
|
|
const pathToXArg: PathToNode = [
|
|
|
|
...pathToCenterArrayExpression,
|
|
|
|
[0, 'index'],
|
|
|
|
]
|
|
|
|
const pathToYArg: PathToNode = [
|
|
|
|
...pathToCenterArrayExpression,
|
|
|
|
[1, 'index'],
|
|
|
|
]
|
|
|
|
|
|
|
|
return [
|
|
|
|
constrainInfo(
|
|
|
|
'radius',
|
|
|
|
isNotLiteralArrayOrStatic(radiusDetails.expr),
|
|
|
|
code.slice(radiusDetails.expr.start, radiusDetails.expr.end),
|
|
|
|
'circle',
|
|
|
|
'radius',
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(radiusDetails.expr.start, radiusDetails.expr.end),
|
2024-09-23 22:42:51 +10:00
|
|
|
pathToRadiusLiteral
|
|
|
|
),
|
|
|
|
{
|
|
|
|
stdLibFnName: 'circle',
|
|
|
|
type: 'xAbsolute',
|
|
|
|
isConstrained: isNotLiteralArrayOrStatic(
|
|
|
|
centerDetails.expr.elements[0]
|
|
|
|
),
|
2025-01-17 14:34:36 -05:00
|
|
|
sourceRange: topLevelRange(
|
2024-09-23 22:42:51 +10:00
|
|
|
centerDetails.expr.elements[0].start,
|
2025-01-17 14:34:36 -05:00
|
|
|
centerDetails.expr.elements[0].end
|
|
|
|
),
|
2024-09-23 22:42:51 +10:00
|
|
|
pathToNode: pathToXArg,
|
|
|
|
value: code.slice(
|
|
|
|
centerDetails.expr.elements[0].start,
|
|
|
|
centerDetails.expr.elements[0].end
|
|
|
|
),
|
|
|
|
argPosition: {
|
|
|
|
type: 'arrayInObject',
|
|
|
|
index: 0,
|
|
|
|
key: 'center',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
stdLibFnName: 'circle',
|
|
|
|
type: 'yAbsolute',
|
|
|
|
isConstrained: isNotLiteralArrayOrStatic(
|
|
|
|
centerDetails.expr.elements[1]
|
|
|
|
),
|
2025-01-17 14:34:36 -05:00
|
|
|
sourceRange: topLevelRange(
|
2024-09-23 22:42:51 +10:00
|
|
|
centerDetails.expr.elements[1].start,
|
2025-01-17 14:34:36 -05:00
|
|
|
centerDetails.expr.elements[1].end
|
|
|
|
),
|
2024-09-23 22:42:51 +10:00
|
|
|
pathToNode: pathToYArg,
|
|
|
|
value: code.slice(
|
|
|
|
centerDetails.expr.elements[1].start,
|
|
|
|
centerDetails.expr.elements[1].end
|
|
|
|
),
|
|
|
|
argPosition: {
|
|
|
|
type: 'arrayInObject',
|
|
|
|
index: 1,
|
|
|
|
key: 'center',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]
|
|
|
|
},
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
export const angledLine: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2023-03-02 21:19:11 +11:00
|
|
|
const getNode = getNodeFromPathCurry(_node, pathToNode)
|
2024-06-24 11:45:40 -04:00
|
|
|
const _node1 = getNode<PipeExpression>('PipeExpression')
|
|
|
|
if (err(_node1)) return _node1
|
|
|
|
const { node: pipe } = _node1
|
2023-03-02 21:19:11 +11:00
|
|
|
|
|
|
|
const newAngleVal = createLiteral(roundOff(getAngle(from, to), 0))
|
|
|
|
const newLengthVal = createLiteral(roundOff(getLength(from, to), 2))
|
2023-03-10 08:48:50 +11:00
|
|
|
const newLine = createCallExpression('angledLine', [
|
|
|
|
createArrayExpression([newAngleVal, newLengthVal]),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
2023-03-02 21:19:11 +11:00
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 0,
|
|
|
|
key: 'angle',
|
|
|
|
argType: 'angle',
|
|
|
|
expr: newAngleVal,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 1,
|
|
|
|
key: 'length',
|
|
|
|
argType: 'length',
|
|
|
|
expr: newLengthVal,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2023-03-10 08:48:50 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-03-02 21:19:11 +11:00
|
|
|
} else {
|
|
|
|
pipe.body = [...pipe.body, newLine]
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const angle = roundOff(getAngle(from, to), 0)
|
|
|
|
const lineLength = roundOff(getLength(from, to), 2)
|
|
|
|
|
|
|
|
const angleLit = createLiteral(angle)
|
|
|
|
const lengthLit = createLiteral(lineLength)
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) {
|
|
|
|
mutateObjExpProp(firstArg, angleLit, 'angle')
|
|
|
|
mutateObjExpProp(firstArg, lengthLit, 'length')
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
commonConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['angle', 'length'],
|
|
|
|
'angledLine',
|
|
|
|
[
|
|
|
|
{ arrayInput: 0, objInput: 'angle' },
|
|
|
|
{ arrayInput: 1, objInput: 'length' },
|
|
|
|
],
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const angledLineOfXLength: SketchLineHelper = {
|
|
|
|
add: ({
|
|
|
|
node,
|
|
|
|
previousProgramMemory,
|
|
|
|
pathToNode,
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput,
|
|
|
|
replaceExistingCallback,
|
2023-02-12 10:56:45 +11:00
|
|
|
}) => {
|
2024-09-13 21:14:14 +10:00
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: pipe } = nodeMeta
|
|
|
|
const nodeMeta2 = getNodeFromPath<VariableDeclarator>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta2)) return nodeMeta2
|
|
|
|
const { node: varDec } = nodeMeta2
|
|
|
|
|
2023-02-12 10:56:45 +11:00
|
|
|
const variableName = varDec.id.name
|
2024-09-27 15:44:44 -07:00
|
|
|
const sketch = sketchFromKclValue(
|
Remove KclValue::SketchGroup variant (#3446)
We can store Rust types like `SketchGroup` as their own variant of `KclValue`, or as `KclValue::UserVal`. Sometimes we store in one and try to read from the other, which fails. This causes bugs, like #3338.
Instead, we should use either ::SketchGroup or ::UserVal, and stop using the other. If we stopped using ::UserVal, we'd need a new variant for every Rust type we wanted to build, including user-defined types. So I don't think that's practical.
Instead, we should store every KCL value by de/serializing it into UserVal. This is a first step along that path, removing just the SketchGroup variants. If it goes well, we can remove the other specialized variants too.
My only concern is there might be performance implications from how frequently we convert between serde_json::Value and Rust types via Serde. But I'm not too worried -- there's no parsing JSON strings, just traversing serde_json::Value trees. This isn't great for performance but I think it'll probably be miniscule in comparison to doing all the API calls.
2024-08-21 11:06:48 -05:00
|
|
|
previousProgramMemory?.get(variableName),
|
|
|
|
variableName
|
|
|
|
)
|
|
|
|
if (err(sketch)) {
|
|
|
|
return sketch
|
2024-06-24 11:45:40 -04:00
|
|
|
}
|
2023-03-02 21:19:11 +11:00
|
|
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
|
|
|
const xLength = createLiteral(roundOff(Math.abs(from[0] - to[0]), 2) || 0.1)
|
2024-09-13 21:14:14 +10:00
|
|
|
let newLine: Expr
|
|
|
|
if (replaceExistingCallback) {
|
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 0,
|
|
|
|
key: 'angle',
|
|
|
|
argType: 'angle',
|
|
|
|
expr: angle,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 1,
|
|
|
|
key: 'length',
|
|
|
|
argType: 'xRelative',
|
|
|
|
expr: xLength,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
newLine = result.callExp
|
|
|
|
} else {
|
|
|
|
newLine = createCallExpression('angledLineOfXLength', [
|
|
|
|
createArrayExpression([angle, xLength]),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
}
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
2023-03-02 21:19:11 +11:00
|
|
|
pipe.body[callIndex] = newLine
|
|
|
|
} else {
|
|
|
|
pipe.body = [...pipe.body, newLine]
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const angle = roundOff(getAngle(from, to), 0)
|
|
|
|
const xLength = roundOff(Math.abs(to[0] - from[0]), 2)
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
const adjustedXLength = isAngleLiteral(firstArg)
|
|
|
|
? Math.abs(xLength)
|
|
|
|
: xLength // todo make work for variable angle > 180
|
|
|
|
|
|
|
|
const angleLit = createLiteral(angle)
|
|
|
|
const lengthLit = createLiteral(adjustedXLength)
|
|
|
|
|
|
|
|
if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) {
|
|
|
|
mutateObjExpProp(firstArg, angleLit, 'angle')
|
|
|
|
mutateObjExpProp(firstArg, lengthLit, 'length')
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
commonConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['angle', 'xRelative'],
|
|
|
|
'angledLineOfXLength',
|
|
|
|
[
|
|
|
|
{ arrayInput: 0, objInput: 'angle' },
|
|
|
|
{ arrayInput: 1, objInput: 'length' },
|
|
|
|
],
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const angledLineOfYLength: SketchLineHelper = {
|
|
|
|
add: ({
|
|
|
|
node,
|
|
|
|
previousProgramMemory,
|
|
|
|
pathToNode,
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput,
|
|
|
|
replaceExistingCallback,
|
2023-02-12 10:56:45 +11:00
|
|
|
}) => {
|
2024-09-13 21:14:14 +10:00
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: pipe } = nodeMeta
|
|
|
|
const nodeMeta2 = getNodeFromPath<VariableDeclarator>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta2)) return nodeMeta2
|
|
|
|
const { node: varDec } = nodeMeta2
|
2023-02-12 10:56:45 +11:00
|
|
|
const variableName = varDec.id.name
|
2024-09-27 15:44:44 -07:00
|
|
|
const sketch = sketchFromKclValue(
|
Remove KclValue::SketchGroup variant (#3446)
We can store Rust types like `SketchGroup` as their own variant of `KclValue`, or as `KclValue::UserVal`. Sometimes we store in one and try to read from the other, which fails. This causes bugs, like #3338.
Instead, we should use either ::SketchGroup or ::UserVal, and stop using the other. If we stopped using ::UserVal, we'd need a new variant for every Rust type we wanted to build, including user-defined types. So I don't think that's practical.
Instead, we should store every KCL value by de/serializing it into UserVal. This is a first step along that path, removing just the SketchGroup variants. If it goes well, we can remove the other specialized variants too.
My only concern is there might be performance implications from how frequently we convert between serde_json::Value and Rust types via Serde. But I'm not too worried -- there's no parsing JSON strings, just traversing serde_json::Value trees. This isn't great for performance but I think it'll probably be miniscule in comparison to doing all the API calls.
2024-08-21 11:06:48 -05:00
|
|
|
previousProgramMemory?.get(variableName),
|
|
|
|
variableName
|
|
|
|
)
|
|
|
|
if (err(sketch)) return sketch
|
2023-03-02 21:19:11 +11:00
|
|
|
|
|
|
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
|
|
|
const yLength = createLiteral(roundOff(Math.abs(from[1] - to[1]), 2) || 0.1)
|
2024-09-13 21:14:14 +10:00
|
|
|
let newLine: Expr
|
|
|
|
if (replaceExistingCallback) {
|
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 0,
|
|
|
|
key: 'angle',
|
|
|
|
argType: 'angle',
|
|
|
|
expr: angle,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 1,
|
|
|
|
key: 'length',
|
|
|
|
argType: 'yRelative',
|
|
|
|
expr: yLength,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
newLine = result.callExp
|
|
|
|
} else {
|
|
|
|
newLine = createCallExpression('angledLineOfYLength', [
|
|
|
|
createArrayExpression([angle, yLength]),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
}
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
2023-03-02 21:19:11 +11:00
|
|
|
pipe.body[callIndex] = newLine
|
|
|
|
} else {
|
|
|
|
pipe.body = [...pipe.body, newLine]
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const angle = roundOff(getAngle(from, to), 0)
|
|
|
|
const yLength = roundOff(to[1] - from[1], 2)
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
const adjustedYLength = isAngleLiteral(firstArg)
|
|
|
|
? Math.abs(yLength)
|
|
|
|
: yLength // todo make work for variable angle > 180
|
|
|
|
|
|
|
|
const angleLit = createLiteral(angle)
|
|
|
|
const lengthLit = createLiteral(adjustedYLength)
|
|
|
|
|
|
|
|
if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) {
|
|
|
|
mutateObjExpProp(firstArg, angleLit, 'angle')
|
|
|
|
mutateObjExpProp(firstArg, lengthLit, 'length')
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
commonConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['angle', 'yRelative'],
|
|
|
|
'angledLineOfYLength',
|
|
|
|
[
|
|
|
|
{ arrayInput: 0, objInput: 'angle' },
|
|
|
|
{ arrayInput: 1, objInput: 'length' },
|
|
|
|
],
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const angledLineToX: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: pipe } = nodeMeta
|
2023-03-02 21:19:11 +11:00
|
|
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
|
|
|
const xArg = createLiteral(roundOff(to[0], 2))
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 0,
|
|
|
|
key: 'angle',
|
|
|
|
argType: 'angle',
|
|
|
|
expr: angle,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 1,
|
|
|
|
key: 'to',
|
|
|
|
argType: 'xAbsolute',
|
|
|
|
expr: xArg,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2023-03-17 08:27:40 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-03-02 21:19:11 +11:00
|
|
|
}
|
2023-03-17 08:27:40 +11:00
|
|
|
|
|
|
|
const callExp = createCallExpression('angledLineToX', [
|
|
|
|
createArrayExpression([angle, xArg]),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
pipe.body = [...pipe.body, callExp]
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const angle = roundOff(getAngle(from, to), 0)
|
|
|
|
const xLength = roundOff(to[0], 2)
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
const adjustedXLength = xLength
|
|
|
|
|
|
|
|
const angleLit = createLiteral(angle)
|
|
|
|
const lengthLit = createLiteral(adjustedXLength)
|
|
|
|
|
|
|
|
if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) {
|
|
|
|
mutateObjExpProp(firstArg, angleLit, 'angle')
|
|
|
|
mutateObjExpProp(firstArg, lengthLit, 'to')
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
commonConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['angle', 'xAbsolute'],
|
|
|
|
'angledLineToX',
|
|
|
|
[
|
|
|
|
{ arrayInput: 0, objInput: 'angle' },
|
|
|
|
{ arrayInput: 1, objInput: 'to' },
|
|
|
|
],
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
export const angledLineToY: SketchLineHelper = {
|
2024-09-13 21:14:14 +10:00
|
|
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: pipe } = nodeMeta
|
|
|
|
|
2023-03-02 21:19:11 +11:00
|
|
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
|
|
|
const yArg = createLiteral(roundOff(to[1], 2))
|
2023-03-10 14:55:16 +11:00
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 0,
|
|
|
|
key: 'angle',
|
|
|
|
argType: 'angle',
|
|
|
|
expr: angle,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'arrayOrObjItem',
|
|
|
|
index: 1,
|
|
|
|
key: 'to',
|
|
|
|
argType: 'yAbsolute',
|
|
|
|
expr: yArg,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2023-03-10 14:55:16 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
2023-03-02 21:19:11 +11:00
|
|
|
}
|
2023-03-10 14:55:16 +11:00
|
|
|
|
|
|
|
const newLine = createCallExpression('angledLineToY', [
|
|
|
|
createArrayExpression([angle, yArg]),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
pipe.body = [...pipe.body, newLine]
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
const angle = roundOff(getAngle(from, to), 0)
|
|
|
|
const xLength = roundOff(to[1], 2)
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
const adjustedXLength = xLength
|
|
|
|
|
|
|
|
const angleLit = createLiteral(angle)
|
|
|
|
const lengthLit = createLiteral(adjustedXLength)
|
|
|
|
|
|
|
|
if (!mutateArrExp(firstArg, createArrayExpression([angleLit, lengthLit]))) {
|
|
|
|
mutateObjExpProp(firstArg, angleLit, 'angle')
|
|
|
|
mutateObjExpProp(firstArg, lengthLit, 'to')
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-03-17 18:24:03 +11:00
|
|
|
addTag: addTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
getConstraintInfo: (callExp, ...args) =>
|
|
|
|
commonConstraintInfoHelper(
|
|
|
|
callExp,
|
|
|
|
['angle', 'yAbsolute'],
|
|
|
|
'angledLineToY',
|
|
|
|
[
|
|
|
|
{ arrayInput: 0, objInput: 'angle' },
|
|
|
|
{ arrayInput: 1, objInput: 'to' },
|
|
|
|
],
|
|
|
|
...args
|
|
|
|
),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
2023-03-19 18:46:39 +11:00
|
|
|
export const angledLineThatIntersects: SketchLineHelper = {
|
|
|
|
add: ({
|
|
|
|
node,
|
|
|
|
pathToNode,
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput,
|
|
|
|
replaceExistingCallback,
|
2023-03-19 18:46:39 +11:00
|
|
|
referencedSegment,
|
|
|
|
}) => {
|
2024-09-13 21:14:14 +10:00
|
|
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { from, to } = segmentInput
|
2023-03-19 18:46:39 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<PipeExpression>(
|
2023-03-19 18:46:39 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: pipe } = nodeMeta
|
|
|
|
|
2023-03-19 18:46:39 +11:00
|
|
|
const angle = createLiteral(roundOff(getAngle(from, to), 0))
|
2024-06-24 11:45:40 -04:00
|
|
|
if (!referencedSegment) {
|
|
|
|
return new Error('referencedSegment must be provided')
|
|
|
|
}
|
|
|
|
|
2023-03-19 18:46:39 +11:00
|
|
|
const offset = createLiteral(
|
|
|
|
roundOff(
|
|
|
|
perpendicularDistance(
|
|
|
|
referencedSegment?.from,
|
|
|
|
referencedSegment?.to,
|
|
|
|
to
|
|
|
|
),
|
|
|
|
2
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
if (replaceExistingCallback) {
|
|
|
|
const result = replaceExistingCallback([
|
|
|
|
{
|
|
|
|
type: 'objectProperty',
|
|
|
|
key: 'angle',
|
|
|
|
argType: 'angle',
|
|
|
|
expr: angle,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'objectProperty',
|
|
|
|
key: 'offset',
|
|
|
|
argType: 'intersectionOffset',
|
|
|
|
expr: offset,
|
|
|
|
},
|
|
|
|
])
|
|
|
|
if (err(result)) return result
|
|
|
|
const { callExp, valueUsedInTransform } = result
|
2023-04-01 16:47:00 +11:00
|
|
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
2023-03-19 18:46:39 +11:00
|
|
|
pipe.body[callIndex] = callExp
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
valueUsedInTransform,
|
|
|
|
}
|
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('not implemented')
|
2023-03-19 18:46:39 +11:00
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
updateArgs: ({ node, pathToNode, input, previousProgramMemory }) => {
|
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to, from } = input
|
2023-03-19 18:46:39 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: callExpression } = nodeMeta
|
2023-03-19 18:46:39 +11:00
|
|
|
const angle = roundOff(getAngle(from, to), 0)
|
|
|
|
|
|
|
|
const firstArg = callExpression.arguments?.[0]
|
|
|
|
const intersectTag =
|
|
|
|
firstArg.type === 'ObjectExpression'
|
|
|
|
? firstArg.properties.find((p) => p.key.name === 'intersectTag')
|
|
|
|
?.value || createLiteral('')
|
|
|
|
: createLiteral('')
|
|
|
|
const intersectTagName =
|
2024-06-24 22:39:04 -07:00
|
|
|
intersectTag.type === 'Identifier' ? intersectTag.name : ''
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta2 = getNodeFromPath<VariableDeclaration>(
|
2023-03-19 18:46:39 +11:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'VariableDeclaration'
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta2)) return nodeMeta2
|
2023-03-19 18:46:39 +11:00
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
const { node: varDec } = nodeMeta2
|
2024-12-07 07:16:04 +13:00
|
|
|
const varName = varDec.declaration.id.name
|
2024-09-27 15:44:44 -07:00
|
|
|
const sketch = sketchFromKclValue(
|
Remove KclValue::SketchGroup variant (#3446)
We can store Rust types like `SketchGroup` as their own variant of `KclValue`, or as `KclValue::UserVal`. Sometimes we store in one and try to read from the other, which fails. This causes bugs, like #3338.
Instead, we should use either ::SketchGroup or ::UserVal, and stop using the other. If we stopped using ::UserVal, we'd need a new variant for every Rust type we wanted to build, including user-defined types. So I don't think that's practical.
Instead, we should store every KCL value by de/serializing it into UserVal. This is a first step along that path, removing just the SketchGroup variants. If it goes well, we can remove the other specialized variants too.
My only concern is there might be performance implications from how frequently we convert between serde_json::Value and Rust types via Serde. But I'm not too worried -- there's no parsing JSON strings, just traversing serde_json::Value trees. This isn't great for performance but I think it'll probably be miniscule in comparison to doing all the API calls.
2024-08-21 11:06:48 -05:00
|
|
|
previousProgramMemory.get(varName),
|
|
|
|
varName
|
|
|
|
)
|
2024-09-27 15:44:44 -07:00
|
|
|
if (err(sketch)) return sketch
|
2024-10-23 12:42:54 -05:00
|
|
|
const intersectPath = sketch.paths.find(
|
2024-06-24 14:45:07 -07:00
|
|
|
({ tag }: Path) => tag && tag.value === intersectTagName
|
2023-03-19 18:46:39 +11:00
|
|
|
)
|
|
|
|
let offset = 0
|
|
|
|
if (intersectPath) {
|
|
|
|
offset = roundOff(
|
|
|
|
perpendicularDistance(intersectPath?.from, intersectPath?.to, to),
|
|
|
|
2
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const angleLit = createLiteral(angle)
|
|
|
|
|
|
|
|
mutateObjExpProp(firstArg, angleLit, 'angle')
|
|
|
|
mutateObjExpProp(firstArg, createLiteral(offset), 'offset')
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
},
|
2024-07-15 19:20:32 +10:00
|
|
|
getTag: getTag(),
|
2024-05-24 20:54:42 +10:00
|
|
|
addTag: addTag(),
|
|
|
|
getConstraintInfo: (callExp: CallExpression, code, pathToNode) => {
|
|
|
|
if (callExp.type !== 'CallExpression') return []
|
|
|
|
const firstArg = callExp.arguments?.[0]
|
|
|
|
if (firstArg.type !== 'ObjectExpression') return []
|
|
|
|
const angleIndex = firstArg.properties.findIndex(
|
|
|
|
(p) => p.key.name === 'angle'
|
|
|
|
)
|
|
|
|
const offsetIndex = firstArg.properties.findIndex(
|
|
|
|
(p) => p.key.name === 'offset'
|
|
|
|
)
|
|
|
|
const intersectTag = firstArg.properties.findIndex(
|
|
|
|
(p) => p.key.name === 'intersectTag'
|
|
|
|
)
|
|
|
|
const returnVal = []
|
|
|
|
const pathToObjectExp: PathToNode = [
|
|
|
|
...pathToNode,
|
|
|
|
['arguments', 'CallExpression'],
|
|
|
|
[0, 'index'],
|
|
|
|
['properties', 'ObjectExpression'],
|
|
|
|
]
|
|
|
|
if (angleIndex !== -1) {
|
|
|
|
const angle = firstArg.properties[angleIndex]?.value
|
|
|
|
const pathToAngleProp: PathToNode = [
|
|
|
|
...pathToObjectExp,
|
|
|
|
[angleIndex, 'index'],
|
|
|
|
['value', 'Property'],
|
|
|
|
]
|
|
|
|
returnVal.push(
|
|
|
|
constrainInfo(
|
|
|
|
'angle',
|
|
|
|
isNotLiteralArrayOrStatic(angle),
|
|
|
|
code.slice(angle.start, angle.end),
|
|
|
|
'angledLineThatIntersects',
|
|
|
|
'angle',
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(angle.start, angle.end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToAngleProp
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
if (offsetIndex !== -1) {
|
|
|
|
const offset = firstArg.properties[offsetIndex]?.value
|
|
|
|
const pathToOffsetProp: PathToNode = [
|
|
|
|
...pathToObjectExp,
|
|
|
|
[offsetIndex, 'index'],
|
|
|
|
['value', 'Property'],
|
|
|
|
]
|
|
|
|
returnVal.push(
|
|
|
|
constrainInfo(
|
|
|
|
'intersectionOffset',
|
|
|
|
isNotLiteralArrayOrStatic(offset),
|
|
|
|
code.slice(offset.start, offset.end),
|
|
|
|
'angledLineThatIntersects',
|
|
|
|
'offset',
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(offset.start, offset.end),
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToOffsetProp
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
if (intersectTag !== -1) {
|
2024-10-30 16:52:17 -04:00
|
|
|
const tag = firstArg.properties[intersectTag]?.value as Node<Identifier>
|
2024-05-24 20:54:42 +10:00
|
|
|
const pathToTagProp: PathToNode = [
|
|
|
|
...pathToObjectExp,
|
|
|
|
[intersectTag, 'index'],
|
|
|
|
['value', 'Property'],
|
|
|
|
]
|
2024-06-24 22:39:04 -07:00
|
|
|
const info = constrainInfo(
|
|
|
|
'intersectionTag',
|
|
|
|
// This will always be a tag identifier.
|
|
|
|
false,
|
|
|
|
code.slice(tag.start, tag.end),
|
|
|
|
'angledLineThatIntersects',
|
|
|
|
'intersectTag',
|
2025-01-17 14:34:36 -05:00
|
|
|
topLevelRange(tag.start, tag.end),
|
2024-06-24 22:39:04 -07:00
|
|
|
pathToTagProp
|
2024-05-24 20:54:42 +10:00
|
|
|
)
|
2024-06-24 22:39:04 -07:00
|
|
|
returnVal.push(info)
|
2024-05-24 20:54:42 +10:00
|
|
|
}
|
|
|
|
return returnVal
|
|
|
|
},
|
2023-03-19 18:46:39 +11:00
|
|
|
}
|
|
|
|
|
2024-03-02 08:48:30 +11:00
|
|
|
export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({
|
|
|
|
node,
|
|
|
|
pathToNode,
|
2024-09-13 21:14:14 +10:00
|
|
|
input,
|
2024-03-02 08:48:30 +11:00
|
|
|
}) => {
|
2024-09-13 21:14:14 +10:00
|
|
|
if (input.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
|
|
|
const { to } = input
|
2024-03-02 08:48:30 +11:00
|
|
|
const _node = { ...node }
|
2024-06-24 11:45:40 -04:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
|
|
|
if (err(nodeMeta)) {
|
|
|
|
console.error(nodeMeta)
|
|
|
|
return {
|
|
|
|
modifiedAst: {
|
|
|
|
start: 0,
|
|
|
|
end: 0,
|
2024-11-26 16:39:57 +13:00
|
|
|
shebang: null,
|
2024-11-07 11:23:41 -05:00
|
|
|
moduleId: 0,
|
2024-06-24 11:45:40 -04:00
|
|
|
body: [],
|
2024-10-17 16:22:40 -07:00
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
nonCodeMeta: {
|
2024-10-30 16:52:17 -04:00
|
|
|
start: 0,
|
|
|
|
end: 0,
|
2024-11-07 11:23:41 -05:00
|
|
|
moduleId: 0,
|
2024-10-30 16:52:17 -04:00
|
|
|
startNodes: [],
|
2024-06-24 11:45:40 -04:00
|
|
|
nonCodeNodes: [],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
}
|
2024-03-02 08:48:30 +11:00
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
const { node: callExpression } = nodeMeta
|
2024-03-02 08:48:30 +11:00
|
|
|
const toArrExp = createArrayExpression([
|
|
|
|
createLiteral(roundOff(to[0])),
|
|
|
|
createLiteral(roundOff(to[1])),
|
|
|
|
])
|
|
|
|
|
|
|
|
mutateArrExp(callExpression.arguments?.[0], toArrExp) ||
|
|
|
|
mutateObjExpProp(callExpression.arguments?.[0], toArrExp, 'to')
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
pathToNode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-12 10:56:45 +11:00
|
|
|
export const sketchLineHelperMap: { [key: string]: SketchLineHelper } = {
|
|
|
|
xLine,
|
|
|
|
yLine,
|
|
|
|
xLineTo,
|
|
|
|
yLineTo,
|
|
|
|
angledLine,
|
|
|
|
angledLineOfXLength,
|
|
|
|
angledLineOfYLength,
|
|
|
|
angledLineToX,
|
|
|
|
angledLineToY,
|
2023-03-19 18:46:39 +11:00
|
|
|
angledLineThatIntersects,
|
2024-02-11 12:59:00 +11:00
|
|
|
tangentialArcTo,
|
2024-09-23 22:42:51 +10:00
|
|
|
circle,
|
2023-02-12 10:56:45 +11:00
|
|
|
} as const
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
export const sketchLineHelperMapKw: { [key: string]: SketchLineHelperKw } = {
|
|
|
|
line,
|
|
|
|
lineTo,
|
|
|
|
} as const
|
|
|
|
|
2023-02-12 10:56:45 +11:00
|
|
|
export function changeSketchArguments(
|
2024-10-30 16:52:17 -04:00
|
|
|
node: Node<Program>,
|
2023-02-12 10:56:45 +11:00
|
|
|
programMemory: ProgramMemory,
|
2024-09-23 22:42:51 +10:00
|
|
|
sourceRangeOrPath:
|
|
|
|
| {
|
|
|
|
type: 'sourceRange'
|
|
|
|
sourceRange: SourceRange
|
|
|
|
}
|
|
|
|
| {
|
|
|
|
type: 'path'
|
|
|
|
pathToNode: PathToNode
|
|
|
|
},
|
2024-09-13 21:14:14 +10:00
|
|
|
input: SegmentInputs
|
2024-10-30 16:52:17 -04:00
|
|
|
): { modifiedAst: Node<Program>; pathToNode: PathToNode } | Error {
|
2023-02-12 10:56:45 +11:00
|
|
|
const _node = { ...node }
|
2024-09-23 22:42:51 +10:00
|
|
|
const thePath =
|
|
|
|
sourceRangeOrPath.type === 'sourceRange'
|
|
|
|
? getNodePathFromSourceRange(_node, sourceRangeOrPath.sourceRange)
|
|
|
|
: sourceRangeOrPath.pathToNode
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const nodeMeta = getNodeFromPath<CallExpression | CallExpressionKw>(
|
|
|
|
_node,
|
|
|
|
thePath
|
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(nodeMeta)) return nodeMeta
|
|
|
|
|
|
|
|
const { node: callExpression, shallowPath } = nodeMeta
|
2023-02-12 10:56:45 +11:00
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const fnName = callExpression?.callee?.name
|
|
|
|
if (fnName in sketchLineHelperMap) {
|
2023-02-12 10:56:45 +11:00
|
|
|
const { updateArgs } = sketchLineHelperMap[callExpression.callee.name]
|
2024-06-24 11:45:40 -04:00
|
|
|
if (!updateArgs) {
|
|
|
|
return new Error('not a sketch line helper')
|
|
|
|
}
|
|
|
|
|
2023-02-12 10:56:45 +11:00
|
|
|
return updateArgs({
|
|
|
|
node: _node,
|
|
|
|
previousProgramMemory: programMemory,
|
2023-04-01 16:47:00 +11:00
|
|
|
pathToNode: shallowPath,
|
2024-09-13 21:14:14 +10:00
|
|
|
input,
|
2023-02-12 10:56:45 +11:00
|
|
|
})
|
|
|
|
}
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (fnName in sketchLineHelperMapKw) {
|
|
|
|
const isAbsolute =
|
|
|
|
callExpression.type === 'CallExpressionKw' &&
|
|
|
|
findKwArg('endAbsolute', callExpression) !== undefined
|
|
|
|
const correctFnName = fnName === 'line' && isAbsolute ? 'lineTo' : fnName
|
|
|
|
const { updateArgs } = sketchLineHelperMapKw[correctFnName]
|
|
|
|
if (!updateArgs) {
|
|
|
|
return new Error('not a sketch line keyword helper')
|
|
|
|
}
|
|
|
|
|
|
|
|
return updateArgs({
|
|
|
|
node: _node,
|
|
|
|
previousProgramMemory: programMemory,
|
|
|
|
pathToNode: shallowPath,
|
|
|
|
input,
|
|
|
|
})
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return new Error(`not a sketch line helper: ${fnName}`)
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
2024-05-24 20:54:42 +10:00
|
|
|
export function getConstraintInfo(
|
2024-10-30 16:52:17 -04:00
|
|
|
callExpression: Node<CallExpression>,
|
2024-05-24 20:54:42 +10:00
|
|
|
code: string,
|
|
|
|
pathToNode: PathToNode
|
|
|
|
): ConstrainInfo[] {
|
|
|
|
const fnName = callExpression?.callee?.name || ''
|
|
|
|
if (!(fnName in sketchLineHelperMap)) return []
|
|
|
|
return sketchLineHelperMap[fnName].getConstraintInfo(
|
|
|
|
callExpression,
|
|
|
|
code,
|
|
|
|
pathToNode
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
export function getConstraintInfoKw(
|
|
|
|
callExpression: Node<CallExpressionKw>,
|
|
|
|
code: string,
|
|
|
|
pathToNode: PathToNode
|
|
|
|
): ConstrainInfo[] {
|
|
|
|
const fnName = callExpression?.callee?.name || ''
|
|
|
|
const isAbsolute = findKwArg('endAbsolute', callExpression) !== undefined
|
|
|
|
if (!(fnName in sketchLineHelperMapKw)) return []
|
|
|
|
const correctFnName = fnName === 'line' && isAbsolute ? 'lineTo' : fnName
|
|
|
|
return sketchLineHelperMapKw[correctFnName].getConstraintInfo(
|
|
|
|
callExpression,
|
|
|
|
code,
|
|
|
|
pathToNode
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-09-14 09:34:37 -04:00
|
|
|
export function compareVec2Epsilon(
|
|
|
|
vec1: [number, number],
|
2024-02-11 12:59:00 +11:00
|
|
|
vec2: [number, number],
|
|
|
|
compareEpsilon = 0.015625 // or 2^-6
|
2023-09-14 09:34:37 -04:00
|
|
|
) {
|
|
|
|
const xDifference = Math.abs(vec1[0] - vec2[0])
|
2023-11-08 20:27:53 +11:00
|
|
|
const yDifference = Math.abs(vec1[1] - vec2[1])
|
2023-09-14 09:34:37 -04:00
|
|
|
return xDifference < compareEpsilon && yDifference < compareEpsilon
|
|
|
|
}
|
|
|
|
|
2024-02-11 12:59:00 +11:00
|
|
|
// this version uses this distance of the two points instead of comparing x and y separately
|
|
|
|
export function compareVec2Epsilon2(
|
|
|
|
vec1: [number, number],
|
|
|
|
vec2: [number, number],
|
|
|
|
compareEpsilon = 0.015625 // or 2^-6
|
|
|
|
) {
|
|
|
|
const xDifference = Math.abs(vec1[0] - vec2[0])
|
|
|
|
const yDifference = Math.abs(vec1[1] - vec2[1])
|
|
|
|
const distance = Math.sqrt(
|
|
|
|
xDifference * xDifference + yDifference * yDifference
|
|
|
|
)
|
|
|
|
return distance < compareEpsilon
|
|
|
|
}
|
|
|
|
|
2024-04-03 13:22:56 +11:00
|
|
|
interface CreateLineFnCallArgs {
|
2024-10-30 16:52:17 -04:00
|
|
|
node: Node<Program>
|
2024-04-03 13:22:56 +11:00
|
|
|
programMemory: ProgramMemory
|
2024-09-13 21:14:14 +10:00
|
|
|
input: SegmentInputs
|
2024-04-03 13:22:56 +11:00
|
|
|
fnName: ToolTip
|
|
|
|
pathToNode: PathToNode
|
|
|
|
spliceBetween?: boolean
|
|
|
|
}
|
|
|
|
|
2023-02-21 10:50:45 +11:00
|
|
|
export function addNewSketchLn({
|
2023-03-17 15:53:20 +11:00
|
|
|
node: _node,
|
2023-02-21 10:50:45 +11:00
|
|
|
programMemory: previousProgramMemory,
|
|
|
|
fnName,
|
|
|
|
pathToNode,
|
2024-09-13 21:14:14 +10:00
|
|
|
input: segmentInput,
|
2024-04-03 13:22:56 +11:00
|
|
|
spliceBetween = false,
|
2024-06-24 11:45:40 -04:00
|
|
|
}: CreateLineFnCallArgs):
|
|
|
|
| {
|
2024-10-30 16:52:17 -04:00
|
|
|
modifiedAst: Node<Program>
|
2024-06-24 11:45:40 -04:00
|
|
|
pathToNode: PathToNode
|
|
|
|
}
|
|
|
|
| Error {
|
2024-07-25 20:11:46 -04:00
|
|
|
const node = structuredClone(_node)
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const { add, updateArgs } =
|
|
|
|
sketchLineHelperMap?.[fnName] || sketchLineHelperMapKw?.[fnName] || {}
|
2024-06-24 11:45:40 -04:00
|
|
|
if (!add || !updateArgs) {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return new Error(`${fnName} is not a sketch line helper`)
|
2024-06-24 11:45:40 -04:00
|
|
|
}
|
|
|
|
|
2024-10-30 16:52:17 -04:00
|
|
|
getNodeFromPath<Node<VariableDeclarator>>(
|
|
|
|
node,
|
|
|
|
pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
getNodeFromPath<Node<PipeExpression | CallExpression | CallExpressionKw>>(
|
2023-02-21 10:50:45 +11:00
|
|
|
node,
|
|
|
|
pathToNode,
|
2023-11-01 07:39:31 -04:00
|
|
|
'PipeExpression'
|
2023-02-21 10:50:45 +11:00
|
|
|
)
|
|
|
|
return add({
|
|
|
|
node,
|
|
|
|
previousProgramMemory,
|
|
|
|
pathToNode,
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput,
|
2024-04-03 13:22:56 +11:00
|
|
|
spliceBetween,
|
2023-02-21 10:50:45 +11:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-05-23 00:53:15 -04:00
|
|
|
export function addCallExpressionsToPipe({
|
|
|
|
node,
|
|
|
|
pathToNode,
|
|
|
|
expressions,
|
|
|
|
}: {
|
2024-10-30 16:52:17 -04:00
|
|
|
node: Node<Program>
|
2024-05-23 00:53:15 -04:00
|
|
|
programMemory: ProgramMemory
|
|
|
|
pathToNode: PathToNode
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
expressions: Node<CallExpression | CallExpressionKw>[]
|
2024-05-23 00:53:15 -04:00
|
|
|
}) {
|
|
|
|
const _node = { ...node }
|
2024-10-30 16:52:17 -04:00
|
|
|
const pipeExpression = getNodeFromPath<Node<PipeExpression>>(
|
2024-05-23 00:53:15 -04:00
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
2024-06-24 11:45:40 -04:00
|
|
|
)
|
|
|
|
if (err(pipeExpression)) return pipeExpression
|
|
|
|
|
|
|
|
if (pipeExpression.node.type !== 'PipeExpression') {
|
|
|
|
return new Error('not a pipe expression')
|
|
|
|
}
|
|
|
|
pipeExpression.node.body = [...pipeExpression.node.body, ...expressions]
|
2024-05-23 00:53:15 -04:00
|
|
|
return _node
|
|
|
|
}
|
|
|
|
|
2023-09-14 09:34:37 -04:00
|
|
|
export function addCloseToPipe({
|
|
|
|
node,
|
|
|
|
pathToNode,
|
|
|
|
}: {
|
|
|
|
node: Program
|
|
|
|
programMemory: ProgramMemory
|
|
|
|
pathToNode: PathToNode
|
|
|
|
}) {
|
|
|
|
const _node = { ...node }
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const closeExpression = createCallExpressionStdLibKw('close', null, [])
|
2023-09-14 09:34:37 -04:00
|
|
|
const pipeExpression = getNodeFromPath<PipeExpression>(
|
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
'PipeExpression'
|
2024-06-24 11:45:40 -04:00
|
|
|
)
|
|
|
|
if (err(pipeExpression)) return pipeExpression
|
|
|
|
|
|
|
|
if (pipeExpression.node.type !== 'PipeExpression') {
|
|
|
|
return new Error('not a pipe expression')
|
|
|
|
}
|
|
|
|
pipeExpression.node.body = [...pipeExpression.node.body, closeExpression]
|
2023-09-14 09:34:37 -04:00
|
|
|
return _node
|
|
|
|
}
|
|
|
|
|
2023-02-21 10:50:45 +11:00
|
|
|
export function replaceSketchLine({
|
|
|
|
node,
|
|
|
|
programMemory,
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToNode: _pathToNode,
|
2023-02-21 10:50:45 +11:00
|
|
|
fnName,
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput,
|
|
|
|
replaceExistingCallback,
|
2023-03-05 07:34:56 +11:00
|
|
|
referencedSegment,
|
2023-02-21 10:50:45 +11:00
|
|
|
}: {
|
2024-10-30 16:52:17 -04:00
|
|
|
node: Node<Program>
|
2023-02-21 10:50:45 +11:00
|
|
|
programMemory: ProgramMemory
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToNode: PathToNode
|
2023-09-15 11:48:23 -04:00
|
|
|
fnName: ToolTip
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput: SegmentInputs
|
|
|
|
replaceExistingCallback: (rawArgs: RawArgs) => CreatedSketchExprResult | Error
|
2023-03-05 07:34:56 +11:00
|
|
|
referencedSegment?: Path
|
2024-06-24 11:45:40 -04:00
|
|
|
}):
|
|
|
|
| {
|
2024-10-30 16:52:17 -04:00
|
|
|
modifiedAst: Node<Program>
|
2024-06-24 11:45:40 -04:00
|
|
|
valueUsedInTransform?: number
|
|
|
|
pathToNode: PathToNode
|
|
|
|
}
|
|
|
|
| Error {
|
2024-09-23 22:42:51 +10:00
|
|
|
if (![...toolTips, 'intersect', 'circle'].includes(fnName)) {
|
2024-09-13 21:14:14 +10:00
|
|
|
return new Error(`The following function name is not tooltip: ${fnName}`)
|
2024-06-24 11:45:40 -04:00
|
|
|
}
|
2023-02-21 10:50:45 +11:00
|
|
|
const _node = { ...node }
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
const { add } =
|
|
|
|
sketchLineHelperMap[fnName] === undefined
|
|
|
|
? sketchLineHelperMapKw[fnName]
|
|
|
|
: sketchLineHelperMap[fnName]
|
2024-06-24 11:45:40 -04:00
|
|
|
const addRetVal = add({
|
2023-02-21 10:50:45 +11:00
|
|
|
node: _node,
|
|
|
|
previousProgramMemory: programMemory,
|
2024-05-24 20:54:42 +10:00
|
|
|
pathToNode: _pathToNode,
|
2023-03-05 07:34:56 +11:00
|
|
|
referencedSegment,
|
2024-09-13 21:14:14 +10:00
|
|
|
segmentInput,
|
|
|
|
replaceExistingCallback,
|
2023-02-21 10:50:45 +11:00
|
|
|
})
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(addRetVal)) return addRetVal
|
|
|
|
|
|
|
|
const { modifiedAst, valueUsedInTransform, pathToNode } = addRetVal
|
2023-04-14 07:49:36 +10:00
|
|
|
return { modifiedAst, valueUsedInTransform, pathToNode }
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
2024-09-26 18:25:05 +10:00
|
|
|
/** Ostensibly should be used to add a chamfer tag to a chamfer call expression
|
|
|
|
*
|
|
|
|
* However things get complicated in situations like:
|
|
|
|
* ```ts
|
|
|
|
* |> chamfer({
|
|
|
|
* length: 1,
|
|
|
|
* tags: [tag1, tagOfInterest]
|
|
|
|
* }, %)
|
|
|
|
* ```
|
|
|
|
* Because tag declarator is not allowed on a chamfer with more than one tag,
|
|
|
|
* They must be pulled apart into separate chamfer calls:
|
|
|
|
* ```ts
|
|
|
|
* |> chamfer({
|
|
|
|
* length: 1,
|
|
|
|
* tags: [tag1]
|
|
|
|
* }, %)
|
|
|
|
* |> chamfer({
|
|
|
|
* length: 1,
|
|
|
|
* tags: [tagOfInterest]
|
|
|
|
* }, %, $newTagDeclarator)
|
|
|
|
* ```
|
|
|
|
*/
|
|
|
|
function addTagToChamfer(
|
|
|
|
tagInfo: AddTagInfo,
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
edgeCutMeta: EdgeCutInfo
|
2024-09-26 18:25:05 +10:00
|
|
|
):
|
|
|
|
| {
|
2024-10-30 16:52:17 -04:00
|
|
|
modifiedAst: Node<Program>
|
2024-09-26 18:25:05 +10:00
|
|
|
tag: string
|
|
|
|
}
|
|
|
|
| Error {
|
|
|
|
const _node = structuredClone(tagInfo.node)
|
|
|
|
let pipeIndex = 0
|
|
|
|
for (let i = 0; i < tagInfo.pathToNode.length; i++) {
|
|
|
|
if (tagInfo.pathToNode[i][1] === 'PipeExpression') {
|
|
|
|
pipeIndex = Number(tagInfo.pathToNode[i + 1][0])
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const pipeExpr = getNodeFromPath<PipeExpression>(
|
|
|
|
_node,
|
|
|
|
tagInfo.pathToNode,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
|
|
|
const variableDec = getNodeFromPath<VariableDeclarator>(
|
|
|
|
_node,
|
|
|
|
tagInfo.pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
|
|
|
if (err(pipeExpr)) return pipeExpr
|
|
|
|
if (err(variableDec)) return variableDec
|
|
|
|
const isPipeExpression = pipeExpr.node.type === 'PipeExpression'
|
|
|
|
|
2024-12-16 10:34:11 -05:00
|
|
|
console.log('pipeExpr', pipeExpr, variableDec)
|
|
|
|
// const callExpr = isPipeExpression ? pipeExpr.node.body[pipeIndex] : variableDec.node.init
|
2024-09-26 18:25:05 +10:00
|
|
|
const callExpr = isPipeExpression
|
|
|
|
? pipeExpr.node.body[pipeIndex]
|
|
|
|
: variableDec.node.init
|
|
|
|
if (callExpr.type !== 'CallExpression')
|
|
|
|
return new Error('no chamfer call Expr')
|
|
|
|
const chamferObjArg = callExpr.arguments[0]
|
|
|
|
if (chamferObjArg.type !== 'ObjectExpression')
|
|
|
|
return new Error('first argument should be an object expression')
|
|
|
|
const inputTags = getObjExprProperty(chamferObjArg, 'tags')
|
|
|
|
if (!inputTags) return new Error('no tags property')
|
|
|
|
if (inputTags.expr.type !== 'ArrayExpression')
|
|
|
|
return new Error('tags should be an array expression')
|
|
|
|
|
|
|
|
const isChamferBreakUpNeeded = inputTags.expr.elements.length > 1
|
|
|
|
if (!isChamferBreakUpNeeded) {
|
|
|
|
return addTag(2)(tagInfo)
|
|
|
|
}
|
|
|
|
|
|
|
|
// There's more than one input tag, we need to break that chamfer call into a separate chamfer call
|
|
|
|
// so that it can have a tag declarator added.
|
|
|
|
const tagIndexToPullOut = inputTags.expr.elements.findIndex((tag) => {
|
|
|
|
// e.g. chamfer({ tags: [tagOfInterest, tag2] }, %)
|
|
|
|
// ^^^^^^^^^^^^^
|
|
|
|
const elementMatchesBaseTagType =
|
|
|
|
edgeCutMeta?.subType === 'base' &&
|
|
|
|
tag.type === 'Identifier' &&
|
|
|
|
tag.name === edgeCutMeta.tagName
|
|
|
|
if (elementMatchesBaseTagType) return true
|
|
|
|
|
|
|
|
// e.g. chamfer({ tags: [getOppositeEdge(tagOfInterest), tag2] }, %)
|
|
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
const tagMatchesOppositeTagType =
|
|
|
|
edgeCutMeta?.subType === 'opposite' &&
|
|
|
|
tag.type === 'CallExpression' &&
|
|
|
|
tag.callee.name === 'getOppositeEdge' &&
|
|
|
|
tag.arguments[0].type === 'Identifier' &&
|
|
|
|
tag.arguments[0].name === edgeCutMeta.tagName
|
|
|
|
if (tagMatchesOppositeTagType) return true
|
|
|
|
|
|
|
|
// e.g. chamfer({ tags: [getNextAdjacentEdge(tagOfInterest), tag2] }, %)
|
|
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
const tagMatchesAdjacentTagType =
|
|
|
|
edgeCutMeta?.subType === 'adjacent' &&
|
|
|
|
tag.type === 'CallExpression' &&
|
|
|
|
(tag.callee.name === 'getNextAdjacentEdge' ||
|
|
|
|
tag.callee.name === 'getPrevAdjacentEdge') &&
|
|
|
|
tag.arguments[0].type === 'Identifier' &&
|
|
|
|
tag.arguments[0].name === edgeCutMeta.tagName
|
|
|
|
if (tagMatchesAdjacentTagType) return true
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
if (tagIndexToPullOut === -1) return new Error('tag not found')
|
|
|
|
// get the tag we're pulling out
|
|
|
|
const tagToPullOut = inputTags.expr.elements[tagIndexToPullOut]
|
|
|
|
// and remove it from the original chamfer call
|
|
|
|
// [pullOutTag, tag2] to [tag2]
|
|
|
|
inputTags.expr.elements.splice(tagIndexToPullOut, 1)
|
|
|
|
|
|
|
|
// get the length of the chamfer we're breaking up, as the new chamfer will have the same length
|
|
|
|
const chamferLength = getObjExprProperty(chamferObjArg, 'length')
|
|
|
|
if (!chamferLength) return new Error('no chamfer length')
|
|
|
|
const tagDec = createTagDeclarator(findUniqueName(_node, 'seg', 2))
|
|
|
|
const solid3dIdentifierUsedInOriginalChamfer = callExpr.arguments[1]
|
|
|
|
const newExpressionToInsert = createCallExpression('chamfer', [
|
|
|
|
createObjectExpression({
|
|
|
|
length: chamferLength.expr,
|
|
|
|
// single tag to add to the new chamfer call
|
|
|
|
tags: createArrayExpression([tagToPullOut]),
|
|
|
|
}),
|
|
|
|
isPipeExpression
|
|
|
|
? createPipeSubstitution()
|
|
|
|
: solid3dIdentifierUsedInOriginalChamfer,
|
|
|
|
tagDec,
|
|
|
|
])
|
|
|
|
|
|
|
|
// insert the new chamfer call with the tag declarator, add its above the original
|
|
|
|
// alternatively we could use `pipeIndex + 1` to insert it below the original
|
|
|
|
if (isPipeExpression) {
|
|
|
|
pipeExpr.node.body.splice(pipeIndex, 0, newExpressionToInsert)
|
|
|
|
} else {
|
2024-12-16 10:34:11 -05:00
|
|
|
console.log('yo', createPipeExpression([newExpressionToInsert, callExpr]))
|
2024-09-26 18:25:05 +10:00
|
|
|
callExpr.arguments[1] = createPipeSubstitution()
|
|
|
|
variableDec.node.init = createPipeExpression([
|
|
|
|
newExpressionToInsert,
|
|
|
|
callExpr,
|
|
|
|
])
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
tag: tagDec.value,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-13 21:14:14 +10:00
|
|
|
export function addTagForSketchOnFace(
|
|
|
|
tagInfo: AddTagInfo,
|
2024-09-26 18:25:05 +10:00
|
|
|
expressionName: string,
|
|
|
|
edgeCutMeta: EdgeCutInfo | null
|
|
|
|
):
|
|
|
|
| {
|
2024-10-30 16:52:17 -04:00
|
|
|
modifiedAst: Node<Program>
|
2024-09-26 18:25:05 +10:00
|
|
|
tag: string
|
|
|
|
}
|
|
|
|
| Error {
|
2024-03-22 10:23:04 +11:00
|
|
|
if (expressionName === 'close') {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return addTagKw()(tagInfo)
|
2024-03-22 10:23:04 +11:00
|
|
|
}
|
2024-09-26 18:25:05 +10:00
|
|
|
if (expressionName === 'chamfer') {
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (edgeCutMeta === null) {
|
|
|
|
return new Error(
|
|
|
|
'Cannot add tag to chamfer because no edge cut was provided'
|
|
|
|
)
|
|
|
|
}
|
2024-09-26 18:25:05 +10:00
|
|
|
return addTagToChamfer(tagInfo, edgeCutMeta)
|
|
|
|
}
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (expressionName in sketchLineHelperMapKw) {
|
|
|
|
const { addTag } = sketchLineHelperMapKw[expressionName]
|
|
|
|
return addTag(tagInfo)
|
|
|
|
}
|
2023-02-12 10:56:45 +11:00
|
|
|
if (expressionName in sketchLineHelperMap) {
|
|
|
|
const { addTag } = sketchLineHelperMap[expressionName]
|
2024-09-13 21:14:14 +10:00
|
|
|
return addTag(tagInfo)
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error(`"${expressionName}" is not a sketch line helper`)
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
|
2024-07-15 19:20:32 +10:00
|
|
|
export function getTagFromCallExpression(
|
|
|
|
callExp: CallExpression
|
|
|
|
): string | Error {
|
|
|
|
if (callExp.callee.name === 'close') return getTag(1)(callExp)
|
|
|
|
if (callExp.callee.name in sketchLineHelperMap) {
|
|
|
|
const { getTag } = sketchLineHelperMap[callExp.callee.name]
|
|
|
|
return getTag(callExp)
|
|
|
|
}
|
|
|
|
return new Error(`"${callExp.callee.name}" is not a sketch line helper`)
|
|
|
|
}
|
|
|
|
|
2024-08-12 15:38:42 -05:00
|
|
|
function isAngleLiteral(lineArugement: Expr): boolean {
|
2023-02-12 10:56:45 +11:00
|
|
|
return lineArugement?.type === 'ArrayExpression'
|
2023-09-13 07:23:14 -07:00
|
|
|
? isLiteralArrayOrStatic(lineArugement.elements[0])
|
2023-02-12 10:56:45 +11:00
|
|
|
: lineArugement?.type === 'ObjectExpression'
|
2023-09-13 07:23:14 -07:00
|
|
|
? isLiteralArrayOrStatic(
|
|
|
|
lineArugement.properties.find(({ key }) => key.name === 'angle')?.value
|
|
|
|
)
|
2023-02-12 10:56:45 +11:00
|
|
|
: false
|
|
|
|
}
|
|
|
|
|
2024-10-30 16:52:17 -04:00
|
|
|
type addTagFn = (
|
|
|
|
a: AddTagInfo
|
|
|
|
) => { modifiedAst: Node<Program>; tag: string } | Error
|
2023-02-12 10:56:45 +11:00
|
|
|
|
2024-03-22 10:23:04 +11:00
|
|
|
function addTag(tagIndex = 2): addTagFn {
|
2023-02-12 10:56:45 +11:00
|
|
|
return ({ node, pathToNode }) => {
|
|
|
|
const _node = { ...node }
|
2024-10-30 16:52:17 -04:00
|
|
|
const callExpr = getNodeFromPath<Node<CallExpression>>(
|
2023-02-12 10:56:45 +11:00
|
|
|
_node,
|
2024-03-17 18:24:03 +11:00
|
|
|
pathToNode,
|
|
|
|
'CallExpression'
|
2023-02-12 10:56:45 +11:00
|
|
|
)
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(callExpr)) return callExpr
|
|
|
|
|
|
|
|
const { node: primaryCallExp } = callExpr
|
|
|
|
|
2024-03-17 18:24:03 +11:00
|
|
|
// Tag is always 3rd expression now, using arg index feels brittle
|
|
|
|
// but we can come up with a better way to identify tag later.
|
2024-03-22 10:23:04 +11:00
|
|
|
const thirdArg = primaryCallExp.arguments?.[tagIndex]
|
2024-06-24 22:39:04 -07:00
|
|
|
const tagDeclarator =
|
|
|
|
thirdArg ||
|
|
|
|
(createTagDeclarator(findUniqueName(_node, 'seg', 2)) as TagDeclarator)
|
2024-03-17 18:24:03 +11:00
|
|
|
const isTagExisting = !!thirdArg
|
|
|
|
if (!isTagExisting) {
|
2024-06-24 22:39:04 -07:00
|
|
|
primaryCallExp.arguments[tagIndex] = tagDeclarator
|
2024-03-17 18:24:03 +11:00
|
|
|
}
|
2024-06-24 22:39:04 -07:00
|
|
|
if ('value' in tagDeclarator) {
|
|
|
|
// Now TypeScript knows tagDeclarator has a value property
|
2023-02-12 10:56:45 +11:00
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
2024-06-24 22:39:04 -07:00
|
|
|
tag: String(tagDeclarator.value),
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
2024-03-15 17:03:42 -04:00
|
|
|
} else {
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('Unable to assign tag without value')
|
2023-02-12 10:56:45 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
function addTagKw(): addTagFn {
|
|
|
|
return ({ node, pathToNode }) => {
|
|
|
|
const _node = { ...node }
|
|
|
|
// We have to allow for the possibility that the path is actually to a call expression.
|
|
|
|
// That's because if the parser reads something like `close()`, it doesn't know if this
|
|
|
|
// is a keyword or positional call.
|
|
|
|
// In fact, even something like `close(%)` could be either (because we allow 1 unlabeled
|
|
|
|
// starting param).
|
|
|
|
const callExpr = getNodeFromPath<Node<CallExpressionKw | CallExpression>>(
|
|
|
|
_node,
|
|
|
|
pathToNode,
|
|
|
|
['CallExpressionKw', 'CallExpression']
|
|
|
|
)
|
|
|
|
if (err(callExpr)) return callExpr
|
|
|
|
|
|
|
|
// If the original node is a call expression, we'll need to change it to a call with keyword args.
|
|
|
|
const primaryCallExp: CallExpressionKw =
|
|
|
|
callExpr.node.type === 'CallExpressionKw'
|
|
|
|
? callExpr.node
|
|
|
|
: {
|
|
|
|
type: 'CallExpressionKw',
|
|
|
|
callee: callExpr.node.callee,
|
|
|
|
unlabeled: callExpr.node.arguments.length
|
|
|
|
? callExpr.node.arguments[0]
|
|
|
|
: null,
|
|
|
|
arguments: [],
|
|
|
|
}
|
|
|
|
const tagArg = findKwArg(ARG_TAG, primaryCallExp)
|
|
|
|
const tagDeclarator =
|
|
|
|
tagArg || createTagDeclarator(findUniqueName(_node, 'seg', 2))
|
|
|
|
const isTagExisting = !!tagArg
|
|
|
|
if (!isTagExisting) {
|
|
|
|
const labeledArg = createLabeledArg(ARG_TAG, tagDeclarator)
|
|
|
|
primaryCallExp.arguments.push(labeledArg)
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we changed the node, we must replace the old node with the new node in the AST.
|
|
|
|
const mustReplaceNode = primaryCallExp.type !== callExpr.node.type
|
|
|
|
if (mustReplaceNode) {
|
|
|
|
getNodeFromPath(_node, pathToNode, ['CallExpression'], false, {
|
|
|
|
...primaryCallExp,
|
|
|
|
start: callExpr.node.start,
|
|
|
|
end: callExpr.node.end,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('value' in tagDeclarator) {
|
|
|
|
// Now TypeScript knows tagDeclarator has a value property
|
|
|
|
return {
|
|
|
|
modifiedAst: _node,
|
|
|
|
tag: String(tagDeclarator.value),
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return new Error('Unable to assign tag without value')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-12 10:56:45 +11:00
|
|
|
export function getYComponent(
|
|
|
|
angleDegree: number,
|
|
|
|
xComponent: number
|
|
|
|
): [number, number] {
|
|
|
|
const normalisedAngle = ((angleDegree % 360) + 360) % 360 // between 0 and 360
|
|
|
|
let yComponent = xComponent * Math.tan((normalisedAngle * Math.PI) / 180)
|
|
|
|
const sign = normalisedAngle > 90 && normalisedAngle <= 270 ? -1 : 1
|
|
|
|
return [sign * xComponent, sign * yComponent]
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getXComponent(
|
|
|
|
angleDegree: number,
|
|
|
|
yComponent: number
|
|
|
|
): [number, number] {
|
|
|
|
const normalisedAngle = ((angleDegree % 360) + 360) % 360 // between 0 and 360
|
|
|
|
let xComponent = yComponent / Math.tan((normalisedAngle * Math.PI) / 180)
|
|
|
|
const sign = normalisedAngle > 180 && normalisedAngle <= 360 ? -1 : 1
|
|
|
|
return [sign * xComponent, sign * yComponent]
|
|
|
|
}
|
2023-02-21 10:50:45 +11:00
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
function getFirstArgValuesForXYFns(callExpression: CallExpression):
|
|
|
|
| {
|
2024-08-12 15:38:42 -05:00
|
|
|
val: [Expr, Expr]
|
|
|
|
tag?: Expr
|
2024-06-24 11:45:40 -04:00
|
|
|
}
|
|
|
|
| Error {
|
2023-02-21 10:50:45 +11:00
|
|
|
// used for lineTo, line
|
|
|
|
const firstArg = callExpression.arguments[0]
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
return getValuesForXYFns(firstArg)
|
|
|
|
}
|
|
|
|
|
|
|
|
function getValuesForXYFns(arg: Expr):
|
|
|
|
| {
|
|
|
|
val: [Expr, Expr]
|
|
|
|
tag?: Expr
|
|
|
|
}
|
|
|
|
| Error {
|
|
|
|
if (arg.type === 'ArrayExpression') {
|
|
|
|
return { val: [arg.elements[0], arg.elements[1]] }
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (arg.type === 'ObjectExpression') {
|
|
|
|
const to = arg.properties.find((p) => p.key.name === 'to')?.value
|
|
|
|
const tag = arg.properties.find((p) => p.key.name === 'tag')?.value
|
2023-02-21 10:50:45 +11:00
|
|
|
if (to?.type === 'ArrayExpression') {
|
|
|
|
const [x, y] = to.elements
|
|
|
|
return { val: [x, y], tag }
|
|
|
|
}
|
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('expected ArrayExpression or ObjectExpression')
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
function getFirstArgValuesForAngleFns(callExpression: CallExpression):
|
|
|
|
| {
|
2024-08-12 15:38:42 -05:00
|
|
|
val: [Expr, Expr]
|
|
|
|
tag?: Expr
|
2024-06-24 11:45:40 -04:00
|
|
|
}
|
|
|
|
| Error {
|
2023-02-21 10:50:45 +11:00
|
|
|
// used for angledLine, angledLineOfXLength, angledLineToX, angledLineOfYLength, angledLineToY
|
|
|
|
const firstArg = callExpression.arguments[0]
|
|
|
|
if (firstArg.type === 'ArrayExpression') {
|
|
|
|
return { val: [firstArg.elements[0], firstArg.elements[1]] }
|
|
|
|
}
|
|
|
|
if (firstArg.type === 'ObjectExpression') {
|
|
|
|
const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value
|
|
|
|
const angle = firstArg.properties.find((p) => p.key.name === 'angle')?.value
|
|
|
|
const secondArgName = ['angledLineToX', 'angledLineToY'].includes(
|
2023-09-15 11:48:23 -04:00
|
|
|
callExpression?.callee?.name as ToolTip
|
2023-02-21 10:50:45 +11:00
|
|
|
)
|
|
|
|
? 'to'
|
|
|
|
: 'length'
|
|
|
|
const length = firstArg.properties.find(
|
|
|
|
(p) => p.key.name === secondArgName
|
|
|
|
)?.value
|
|
|
|
if (angle && length) {
|
|
|
|
return { val: [angle, length], tag }
|
|
|
|
}
|
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('expected ArrayExpression or ObjectExpression')
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
|
2024-08-12 15:38:42 -05:00
|
|
|
val: Expr
|
|
|
|
tag?: Expr
|
2023-02-21 10:50:45 +11:00
|
|
|
} {
|
|
|
|
// used for xLine, yLine, xLineTo, yLineTo
|
|
|
|
const firstArg = callExpression.arguments[0]
|
|
|
|
if (firstArg.type !== 'ObjectExpression') {
|
|
|
|
return { val: firstArg }
|
|
|
|
}
|
|
|
|
const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value
|
2023-03-17 08:27:40 +11:00
|
|
|
const secondArgName = ['xLineTo', 'yLineTo', 'startSketchAt'].includes(
|
2023-02-21 10:50:45 +11:00
|
|
|
// const secondArgName = ['xLineTo', 'yLineTo', 'angledLineToX', 'angledLineToY'].includes(
|
|
|
|
callExpression?.callee?.name
|
|
|
|
)
|
|
|
|
? 'to'
|
|
|
|
: 'length'
|
|
|
|
const length = firstArg.properties.find(
|
|
|
|
(p) => p.key.name === secondArgName
|
|
|
|
)?.value
|
|
|
|
if (length) {
|
|
|
|
return { val: length, tag }
|
|
|
|
}
|
2023-03-22 03:02:37 +11:00
|
|
|
console.warn('expected ArrayExpression or ObjectExpression')
|
|
|
|
return {
|
|
|
|
val: createLiteral(1),
|
|
|
|
}
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|
|
|
|
|
2024-09-23 22:42:51 +10:00
|
|
|
const getCircle = (
|
|
|
|
callExp: CallExpression
|
|
|
|
):
|
|
|
|
| {
|
|
|
|
val: [Expr, Expr, Expr]
|
|
|
|
tag?: Expr
|
|
|
|
}
|
|
|
|
| Error => {
|
|
|
|
const firstArg = callExp.arguments[0]
|
|
|
|
if (firstArg.type === 'ObjectExpression') {
|
|
|
|
const centerDetails = getObjExprProperty(firstArg, 'center')
|
|
|
|
const radiusDetails = getObjExprProperty(firstArg, 'radius')
|
|
|
|
const tag = callExp.arguments[2]
|
|
|
|
if (centerDetails?.expr?.type === 'ArrayExpression' && radiusDetails) {
|
|
|
|
return {
|
|
|
|
val: [
|
|
|
|
centerDetails?.expr.elements[0],
|
|
|
|
centerDetails?.expr.elements[1],
|
|
|
|
radiusDetails.expr,
|
|
|
|
],
|
|
|
|
tag,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new Error('expected ArrayExpression or ObjectExpression')
|
|
|
|
}
|
2023-03-19 18:46:39 +11:00
|
|
|
const getAngledLineThatIntersects = (
|
|
|
|
callExp: CallExpression
|
2024-06-24 11:45:40 -04:00
|
|
|
):
|
|
|
|
| {
|
2024-08-12 15:38:42 -05:00
|
|
|
val: [Expr, Expr, Expr]
|
|
|
|
tag?: Expr
|
2024-06-24 11:45:40 -04:00
|
|
|
}
|
|
|
|
| Error => {
|
2023-03-19 18:46:39 +11:00
|
|
|
const firstArg = callExp.arguments[0]
|
|
|
|
if (firstArg.type === 'ObjectExpression') {
|
|
|
|
const tag = firstArg.properties.find((p) => p.key.name === 'tag')?.value
|
|
|
|
const angle = firstArg.properties.find((p) => p.key.name === 'angle')?.value
|
|
|
|
const offset = firstArg.properties.find(
|
|
|
|
(p) => p.key.name === 'offset'
|
|
|
|
)?.value
|
2023-04-03 16:05:25 +10:00
|
|
|
const intersectTag = firstArg.properties.find(
|
|
|
|
(p) => p.key.name === 'intersectTag'
|
|
|
|
)?.value
|
|
|
|
if (angle && offset && intersectTag) {
|
|
|
|
return { val: [angle, offset, intersectTag], tag }
|
2023-03-19 18:46:39 +11:00
|
|
|
}
|
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('expected ArrayExpression or ObjectExpression')
|
2023-03-19 18:46:39 +11:00
|
|
|
}
|
|
|
|
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
/**
|
|
|
|
Given a line call, return whether it's using absolute or relative end.
|
|
|
|
*/
|
|
|
|
export function isAbsoluteLine(lineCall: CallExpressionKw): boolean | Error {
|
|
|
|
const name = lineCall?.callee?.name
|
|
|
|
switch (name) {
|
|
|
|
case 'line':
|
|
|
|
if (findKwArg(ARG_END, lineCall) !== undefined) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if (findKwArg(ARG_END_ABSOLUTE, lineCall) !== undefined) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return new Error(
|
|
|
|
`line call has neither ${ARG_END} nor ${ARG_END_ABSOLUTE} params`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return new Error(`Unknown sketch function ${name}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Get the argument corresponding to 'end' or 'endAbsolute' or wherever the line actually ends.
|
|
|
|
*/
|
|
|
|
export function getArgForEnd(lineCall: CallExpressionKw):
|
|
|
|
| {
|
|
|
|
val: Expr | [Expr, Expr] | [Expr, Expr, Expr]
|
|
|
|
tag?: Expr
|
|
|
|
}
|
|
|
|
| Error {
|
|
|
|
const name = lineCall?.callee?.name
|
|
|
|
let arg
|
|
|
|
if (name === 'line') {
|
|
|
|
arg = findKwArgAny([ARG_END, ARG_END_ABSOLUTE], lineCall)
|
|
|
|
} else {
|
|
|
|
return new Error('cannot find end of line function: ' + name)
|
|
|
|
}
|
|
|
|
if (arg === undefined) {
|
|
|
|
return new Error("no end of the line was found in fn '" + name + "'")
|
|
|
|
}
|
|
|
|
return getValuesForXYFns(arg)
|
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function getFirstArg(callExp: CallExpression):
|
|
|
|
| {
|
2024-08-12 15:38:42 -05:00
|
|
|
val: Expr | [Expr, Expr] | [Expr, Expr, Expr]
|
|
|
|
tag?: Expr
|
2024-06-24 11:45:40 -04:00
|
|
|
}
|
|
|
|
| Error {
|
2023-03-02 21:19:11 +11:00
|
|
|
const name = callExp?.callee?.name
|
|
|
|
if (
|
|
|
|
[
|
|
|
|
'angledLine',
|
|
|
|
'angledLineOfXLength',
|
|
|
|
'angledLineToX',
|
|
|
|
'angledLineOfYLength',
|
|
|
|
'angledLineToY',
|
|
|
|
].includes(name)
|
|
|
|
) {
|
|
|
|
return getFirstArgValuesForAngleFns(callExp)
|
|
|
|
}
|
|
|
|
if (['xLine', 'yLine', 'xLineTo', 'yLineTo'].includes(name)) {
|
|
|
|
return getFirstArgValuesForXYLineFns(callExp)
|
|
|
|
}
|
2023-03-17 08:27:40 +11:00
|
|
|
if (['startSketchAt'].includes(name)) {
|
|
|
|
return getFirstArgValuesForXYLineFns(callExp)
|
|
|
|
}
|
2023-03-19 18:46:39 +11:00
|
|
|
if (['angledLineThatIntersects'].includes(name)) {
|
|
|
|
return getAngledLineThatIntersects(callExp)
|
|
|
|
}
|
2024-02-11 12:59:00 +11:00
|
|
|
if (['tangentialArcTo'].includes(name)) {
|
|
|
|
// TODO probably needs it's own implementation
|
|
|
|
return getFirstArgValuesForXYFns(callExp)
|
|
|
|
}
|
2024-09-23 22:42:51 +10:00
|
|
|
if (name === 'circle') {
|
|
|
|
return getCircle(callExp)
|
|
|
|
}
|
2024-06-24 11:45:40 -04:00
|
|
|
return new Error('unexpected call expression: ' + name)
|
2023-02-21 10:50:45 +11:00
|
|
|
}
|