2024-07-15 19:20:32 +10:00
|
|
|
import {
|
2025-01-17 14:34:36 -05:00
|
|
|
ArtifactGraph,
|
2024-07-15 19:20:32 +10:00
|
|
|
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,
|
2024-10-11 23:25:51 +02:00
|
|
|
Expr,
|
|
|
|
Identifier,
|
2024-07-15 19:20:32 +10:00
|
|
|
ObjectExpression,
|
|
|
|
PathToNode,
|
2025-02-03 18:11:26 +01:00
|
|
|
PipeExpression,
|
2024-07-15 19:20:32 +10:00
|
|
|
Program,
|
|
|
|
VariableDeclaration,
|
|
|
|
VariableDeclarator,
|
2024-09-27 15:44:44 -07:00
|
|
|
sketchFromKclValue,
|
2024-07-15 19:20:32 +10:00
|
|
|
} from '../wasm'
|
|
|
|
import {
|
|
|
|
createCallExpressionStdLib,
|
|
|
|
createPipeSubstitution,
|
|
|
|
createObjectExpression,
|
|
|
|
createArrayExpression,
|
|
|
|
createIdentifier,
|
|
|
|
createPipeExpression,
|
|
|
|
} from '../modifyAst'
|
|
|
|
import {
|
|
|
|
getNodeFromPath,
|
|
|
|
hasSketchPipeBeenExtruded,
|
|
|
|
traverse,
|
|
|
|
} from '../queryAst'
|
2025-01-27 14:24:28 +01:00
|
|
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
2024-07-15 19:20:32 +10:00
|
|
|
import {
|
|
|
|
addTagForSketchOnFace,
|
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
|
|
|
ARG_TAG,
|
2024-07-15 19:20:32 +10:00
|
|
|
getTagFromCallExpression,
|
|
|
|
sketchLineHelperMap,
|
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
|
|
|
sketchLineHelperMapKw,
|
2024-07-15 19:20:32 +10:00
|
|
|
} from '../std/sketch'
|
2024-08-26 08:07:20 +02:00
|
|
|
import { err, trap } from 'lib/trap'
|
2024-12-09 15:20:48 -05:00
|
|
|
import { Selection, Selections } from 'lib/selections'
|
2024-08-26 08:07:20 +02:00
|
|
|
import { KclCommandValue } from 'lib/commandTypes'
|
2025-02-05 09:01:45 -05:00
|
|
|
import { isArray } from 'lib/utils'
|
2025-01-17 14:34:36 -05:00
|
|
|
import { Artifact, getSweepFromSuspectedPath } from 'lang/std/artifactGraph'
|
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 } from 'lang/util'
|
2025-02-04 01:14:53 +01:00
|
|
|
import { KclManager } from 'lang/KclSingleton'
|
|
|
|
import { EngineCommandManager } from 'lang/std/engineConnection'
|
|
|
|
import EditorManager from 'editor/manager'
|
|
|
|
import CodeManager from 'lang/codeManager'
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// Edge Treatment Types
|
|
|
|
export enum EdgeTreatmentType {
|
|
|
|
Chamfer = 'chamfer',
|
|
|
|
Fillet = 'fillet',
|
|
|
|
}
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
export interface ChamferParameters {
|
|
|
|
type: EdgeTreatmentType.Chamfer
|
|
|
|
length: KclCommandValue
|
|
|
|
}
|
|
|
|
export interface FilletParameters {
|
|
|
|
type: EdgeTreatmentType.Fillet
|
|
|
|
radius: KclCommandValue
|
|
|
|
}
|
|
|
|
export type EdgeTreatmentParameters = ChamferParameters | FilletParameters
|
|
|
|
|
|
|
|
// Apply Edge Treatment (Fillet or Chamfer) To Selection
|
2025-01-08 16:05:24 +01:00
|
|
|
export async function applyEdgeTreatmentToSelection(
|
2024-10-30 16:52:17 -04:00
|
|
|
ast: Node<Program>,
|
2024-08-26 08:07:20 +02:00
|
|
|
selection: Selections,
|
2025-02-04 01:14:53 +01:00
|
|
|
parameters: EdgeTreatmentParameters,
|
|
|
|
dependencies: {
|
|
|
|
kclManager: KclManager
|
|
|
|
engineCommandManager: EngineCommandManager
|
|
|
|
editorManager: EditorManager
|
|
|
|
codeManager: CodeManager
|
|
|
|
}
|
2025-01-08 16:05:24 +01:00
|
|
|
): Promise<void | Error> {
|
2024-12-02 21:43:59 +01:00
|
|
|
// 1. clone and modify with edge treatment and tag
|
2025-02-04 01:14:53 +01:00
|
|
|
const result = modifyAstWithEdgeTreatmentAndTag(
|
|
|
|
ast,
|
|
|
|
selection,
|
|
|
|
parameters,
|
|
|
|
dependencies
|
|
|
|
)
|
2024-09-09 12:15:16 +02:00
|
|
|
if (err(result)) return result
|
2024-12-02 21:43:59 +01:00
|
|
|
const { modifiedAst, pathToEdgeTreatmentNode } = result
|
2024-09-09 12:15:16 +02:00
|
|
|
|
2024-10-03 11:14:02 +02:00
|
|
|
// 2. update ast
|
2025-02-04 01:14:53 +01:00
|
|
|
await updateAstAndFocus(modifiedAst, pathToEdgeTreatmentNode, dependencies)
|
2024-09-09 12:15:16 +02:00
|
|
|
}
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
export function modifyAstWithEdgeTreatmentAndTag(
|
2024-10-30 16:52:17 -04:00
|
|
|
ast: Node<Program>,
|
2024-11-21 15:04:30 +11:00
|
|
|
selections: Selections,
|
2025-02-04 01:14:53 +01:00
|
|
|
parameters: EdgeTreatmentParameters,
|
|
|
|
dependencies: {
|
|
|
|
kclManager: KclManager
|
|
|
|
engineCommandManager: EngineCommandManager
|
|
|
|
editorManager: EditorManager
|
|
|
|
codeManager: CodeManager
|
|
|
|
}
|
2024-12-02 21:43:59 +01:00
|
|
|
):
|
|
|
|
| { modifiedAst: Node<Program>; pathToEdgeTreatmentNode: Array<PathToNode> }
|
|
|
|
| Error {
|
2024-10-03 11:14:02 +02:00
|
|
|
let clonedAst = structuredClone(ast)
|
|
|
|
const clonedAstForGetExtrude = structuredClone(ast)
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
const astResult = insertParametersIntoAst(clonedAst, parameters)
|
2024-08-26 08:07:20 +02:00
|
|
|
if (err(astResult)) return astResult
|
|
|
|
|
2025-02-04 01:14:53 +01:00
|
|
|
const artifactGraph = dependencies.engineCommandManager.artifactGraph
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-10-03 11:14:02 +02:00
|
|
|
// Step 1: modify ast with tags and group them by extrude nodes (bodies)
|
2024-10-11 23:25:51 +02:00
|
|
|
const extrudeToTagsMap: Map<
|
|
|
|
PathToNode,
|
2024-11-21 15:04:30 +11:00
|
|
|
Array<{ tag: string; artifact: Artifact }>
|
2024-10-11 23:25:51 +02:00
|
|
|
> = new Map()
|
2024-10-03 11:14:02 +02:00
|
|
|
const lookupMap: Map<string, PathToNode> = new Map() // work around for Map key comparison
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-11-21 15:04:30 +11:00
|
|
|
for (const selection of selections.graphSelections) {
|
2024-10-03 11:14:02 +02:00
|
|
|
const result = getPathToExtrudeForSegmentSelection(
|
|
|
|
clonedAstForGetExtrude,
|
2024-12-09 15:20:48 -05:00
|
|
|
selection,
|
2025-02-04 01:14:53 +01:00
|
|
|
artifactGraph,
|
|
|
|
dependencies
|
2024-10-03 11:14:02 +02:00
|
|
|
)
|
|
|
|
if (err(result)) return result
|
|
|
|
const { pathToSegmentNode, pathToExtrudeNode } = result
|
|
|
|
|
|
|
|
const tagResult = mutateAstWithTagForSketchSegment(
|
2024-09-12 21:45:26 +02:00
|
|
|
clonedAst,
|
2024-10-03 11:14:02 +02:00
|
|
|
pathToSegmentNode
|
|
|
|
)
|
|
|
|
if (err(tagResult)) return tagResult
|
|
|
|
const { tag } = tagResult
|
|
|
|
|
|
|
|
// Group tags by their corresponding extrude node
|
|
|
|
const extrudeKey = JSON.stringify(pathToExtrudeNode)
|
|
|
|
|
2024-11-21 15:04:30 +11:00
|
|
|
if (lookupMap.has(extrudeKey) && selection.artifact) {
|
2024-10-03 11:14:02 +02:00
|
|
|
const existingPath = lookupMap.get(extrudeKey)
|
|
|
|
if (!existingPath) return new Error('Path to extrude node not found.')
|
2024-11-21 15:04:30 +11:00
|
|
|
extrudeToTagsMap
|
|
|
|
.get(existingPath)
|
|
|
|
?.push({ tag, artifact: selection.artifact } as const)
|
|
|
|
} else if (selection.artifact) {
|
2024-10-03 11:14:02 +02:00
|
|
|
lookupMap.set(extrudeKey, pathToExtrudeNode)
|
2024-11-21 15:04:30 +11:00
|
|
|
extrudeToTagsMap.set(pathToExtrudeNode, [
|
|
|
|
{ tag, artifact: selection.artifact } as const,
|
|
|
|
])
|
2024-10-03 11:14:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// Step 2: Apply edge treatments for each extrude node (body)
|
|
|
|
let pathToEdgeTreatmentNodes: Array<PathToNode> = []
|
2024-10-11 23:25:51 +02:00
|
|
|
for (const [pathToExtrudeNode, tagInfos] of extrudeToTagsMap.entries()) {
|
2024-12-02 21:43:59 +01:00
|
|
|
// Create an edge treatment expression with multiple tags
|
2024-10-11 23:25:51 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// edge treatment parameter
|
|
|
|
const parameterResult = getParameterNameAndValue(parameters)
|
|
|
|
if (err(parameterResult)) return parameterResult
|
|
|
|
const { parameterName, parameterValue } = parameterResult
|
|
|
|
|
|
|
|
// tag calls
|
2024-11-21 15:04:30 +11:00
|
|
|
const tagCalls = tagInfos.map(({ tag, artifact }) => {
|
|
|
|
return getEdgeTagCall(tag, artifact)
|
2024-10-11 23:25:51 +02:00
|
|
|
})
|
|
|
|
const firstTag = tagCalls[0] // can be Identifier or CallExpression (for opposite and adjacent edges)
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// edge treatment call
|
|
|
|
const edgeTreatmentCall = createCallExpressionStdLib(parameters.type, [
|
2024-10-03 11:14:02 +02:00
|
|
|
createObjectExpression({
|
2024-12-02 21:43:59 +01:00
|
|
|
[parameterName]: parameterValue,
|
2024-10-11 23:25:51 +02:00
|
|
|
tags: createArrayExpression(tagCalls),
|
2024-10-03 11:14:02 +02:00
|
|
|
}),
|
|
|
|
createPipeSubstitution(),
|
|
|
|
])
|
|
|
|
|
|
|
|
// Locate the extrude call
|
|
|
|
const locatedExtrudeDeclarator = locateExtrudeDeclarator(
|
|
|
|
clonedAst,
|
|
|
|
pathToExtrudeNode
|
2024-09-12 21:45:26 +02:00
|
|
|
)
|
2024-10-03 11:14:02 +02:00
|
|
|
if (err(locatedExtrudeDeclarator)) return locatedExtrudeDeclarator
|
|
|
|
const { extrudeDeclarator } = locatedExtrudeDeclarator
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// Modify the extrude expression to include this edge treatment expression
|
|
|
|
// CallExpression - no edge treatment
|
|
|
|
// PipeExpression - edge treatment exists or body in sketch pipe
|
2024-10-03 11:14:02 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
let pathToEdgeTreatmentNode: PathToNode
|
2024-10-03 11:14:02 +02: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 (
|
|
|
|
extrudeDeclarator.init.type === 'CallExpression' ||
|
|
|
|
extrudeDeclarator.init.type === 'CallExpressionKw'
|
|
|
|
) {
|
2024-12-02 21:43:59 +01:00
|
|
|
// 1. case when no edge treatment exists
|
2024-10-03 11:14:02 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// modify ast with new edge treatment call by mutating the extrude node
|
2024-10-03 11:14:02 +02:00
|
|
|
extrudeDeclarator.init = createPipeExpression([
|
|
|
|
extrudeDeclarator.init,
|
2024-12-02 21:43:59 +01:00
|
|
|
edgeTreatmentCall,
|
2024-10-03 11:14:02 +02:00
|
|
|
])
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// get path to the edge treatment node
|
|
|
|
pathToEdgeTreatmentNode = getPathToNodeOfEdgeTreatmentLiteral(
|
2024-10-03 11:14:02 +02:00
|
|
|
pathToExtrudeNode,
|
|
|
|
extrudeDeclarator,
|
2024-12-02 21:43:59 +01:00
|
|
|
firstTag,
|
|
|
|
parameters
|
2024-10-03 11:14:02 +02:00
|
|
|
)
|
2024-12-02 21:43:59 +01:00
|
|
|
pathToEdgeTreatmentNodes.push(pathToEdgeTreatmentNode)
|
2024-10-03 11:14:02 +02:00
|
|
|
} else if (extrudeDeclarator.init.type === 'PipeExpression') {
|
2024-12-02 21:43:59 +01:00
|
|
|
// 2. case when edge treatment exists or extrude in sketch pipe
|
2024-10-03 11:14:02 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// mutate the extrude node with the new edge treatment call
|
|
|
|
extrudeDeclarator.init.body.push(edgeTreatmentCall)
|
2024-10-03 11:14:02 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// get path to the edge treatment node
|
|
|
|
pathToEdgeTreatmentNode = getPathToNodeOfEdgeTreatmentLiteral(
|
2024-10-03 11:14:02 +02:00
|
|
|
pathToExtrudeNode,
|
|
|
|
extrudeDeclarator,
|
2024-12-02 21:43:59 +01:00
|
|
|
firstTag,
|
|
|
|
parameters
|
2024-10-03 11:14:02 +02:00
|
|
|
)
|
2024-12-02 21:43:59 +01:00
|
|
|
pathToEdgeTreatmentNodes.push(pathToEdgeTreatmentNode)
|
2024-10-03 11:14:02 +02:00
|
|
|
} else {
|
|
|
|
return new Error('Unsupported extrude type.')
|
|
|
|
}
|
2024-09-12 21:45:26 +02:00
|
|
|
}
|
2024-12-02 21:43:59 +01:00
|
|
|
return {
|
|
|
|
modifiedAst: clonedAst,
|
|
|
|
pathToEdgeTreatmentNode: pathToEdgeTreatmentNodes,
|
|
|
|
}
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
function insertParametersIntoAst(
|
2024-08-26 08:07:20 +02:00
|
|
|
ast: Program,
|
2024-12-02 21:43:59 +01:00
|
|
|
parameters: EdgeTreatmentParameters
|
2024-08-26 08:07:20 +02:00
|
|
|
): { ast: Program } | Error {
|
|
|
|
try {
|
2024-12-02 21:43:59 +01:00
|
|
|
const newAst = structuredClone(ast)
|
|
|
|
|
|
|
|
// handle radius parameter
|
|
|
|
if (
|
|
|
|
parameters.type === EdgeTreatmentType.Fillet &&
|
|
|
|
'variableName' in parameters.radius &&
|
|
|
|
parameters.radius.variableName &&
|
|
|
|
parameters.radius.insertIndex !== undefined
|
|
|
|
) {
|
|
|
|
newAst.body.splice(
|
|
|
|
parameters.radius.insertIndex,
|
|
|
|
0,
|
|
|
|
parameters.radius.variableDeclarationAst
|
|
|
|
)
|
|
|
|
}
|
|
|
|
// handle length parameter
|
2024-08-26 08:07:20 +02:00
|
|
|
if (
|
2024-12-02 21:43:59 +01:00
|
|
|
parameters.type === EdgeTreatmentType.Chamfer &&
|
|
|
|
'variableName' in parameters.length &&
|
|
|
|
parameters.length.variableName &&
|
|
|
|
parameters.length.insertIndex !== undefined
|
2024-08-26 08:07:20 +02:00
|
|
|
) {
|
2024-12-02 21:43:59 +01:00
|
|
|
newAst.body.splice(
|
|
|
|
parameters.length.insertIndex,
|
|
|
|
0,
|
|
|
|
parameters.length.variableDeclarationAst
|
|
|
|
)
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
2024-12-02 21:43:59 +01:00
|
|
|
|
|
|
|
// handle upcoming parameters here (for blend, bevel, etc.)
|
|
|
|
return { ast: newAst }
|
2024-08-26 08:07:20 +02:00
|
|
|
} catch (error) {
|
|
|
|
return new Error(`Failed to handle AST: ${(error as Error).message}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getPathToExtrudeForSegmentSelection(
|
|
|
|
ast: Program,
|
2024-12-09 15:20:48 -05:00
|
|
|
selection: Selection,
|
2025-02-04 01:14:53 +01:00
|
|
|
artifactGraph: ArtifactGraph,
|
|
|
|
dependencies: {
|
|
|
|
kclManager: KclManager
|
|
|
|
engineCommandManager: EngineCommandManager
|
|
|
|
editorManager: EditorManager
|
|
|
|
codeManager: CodeManager
|
|
|
|
}
|
2024-08-26 08:07:20 +02:00
|
|
|
): { pathToSegmentNode: PathToNode; pathToExtrudeNode: PathToNode } | Error {
|
|
|
|
const pathToSegmentNode = getNodePathFromSourceRange(
|
|
|
|
ast,
|
2024-12-09 15:20:48 -05:00
|
|
|
selection.codeRef?.range
|
2024-08-26 08:07:20 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
const varDecNode = getNodeFromPath<VariableDeclaration>(
|
|
|
|
ast,
|
|
|
|
pathToSegmentNode,
|
|
|
|
'VariableDeclaration'
|
|
|
|
)
|
|
|
|
if (err(varDecNode)) return varDecNode
|
2024-12-07 07:16:04 +13:00
|
|
|
const sketchVar = varDecNode.node.declaration.id.name
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-09-27 15:44:44 -07:00
|
|
|
const sketch = sketchFromKclValue(
|
2025-02-12 10:22:56 +13:00
|
|
|
dependencies.kclManager.variables[sketchVar],
|
2024-08-26 08:07:20 +02:00
|
|
|
sketchVar
|
|
|
|
)
|
2024-09-27 15:44:44 -07:00
|
|
|
if (trap(sketch)) return sketch
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-09-27 15:44:44 -07:00
|
|
|
const extrusion = getSweepFromSuspectedPath(sketch.id, artifactGraph)
|
2024-08-26 08:07:20 +02:00
|
|
|
if (err(extrusion)) return extrusion
|
|
|
|
|
|
|
|
const pathToExtrudeNode = getNodePathFromSourceRange(
|
|
|
|
ast,
|
|
|
|
extrusion.codeRef.range
|
|
|
|
)
|
|
|
|
if (err(pathToExtrudeNode)) return pathToExtrudeNode
|
|
|
|
|
|
|
|
return { pathToSegmentNode, pathToExtrudeNode }
|
|
|
|
}
|
|
|
|
|
|
|
|
async function updateAstAndFocus(
|
2024-10-30 16:52:17 -04:00
|
|
|
modifiedAst: Node<Program>,
|
2025-02-04 01:14:53 +01:00
|
|
|
pathToEdgeTreatmentNode: Array<PathToNode>,
|
|
|
|
dependencies: {
|
|
|
|
kclManager: KclManager
|
|
|
|
engineCommandManager: EngineCommandManager
|
|
|
|
editorManager: EditorManager
|
|
|
|
codeManager: CodeManager
|
|
|
|
}
|
2025-01-08 16:05:24 +01:00
|
|
|
): Promise<void> {
|
2025-02-04 01:14:53 +01:00
|
|
|
const updatedAst = await dependencies.kclManager.updateAst(
|
|
|
|
modifiedAst,
|
|
|
|
true,
|
|
|
|
{
|
|
|
|
focusPath: pathToEdgeTreatmentNode,
|
|
|
|
}
|
|
|
|
)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
2025-02-04 01:14:53 +01:00
|
|
|
await dependencies.codeManager.updateEditorWithAstAndWriteToFile(
|
|
|
|
updatedAst.newAst
|
|
|
|
)
|
2024-11-16 16:49:44 -05:00
|
|
|
|
2024-08-26 08:07:20 +02:00
|
|
|
if (updatedAst?.selections) {
|
2025-02-04 01:14:53 +01:00
|
|
|
dependencies.editorManager.selectRange(updatedAst?.selections)
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-09 15:20:48 -05:00
|
|
|
export function mutateAstWithTagForSketchSegment(
|
2024-10-30 16:52:17 -04:00
|
|
|
astClone: Node<Program>,
|
2024-08-26 08:07:20 +02:00
|
|
|
pathToSegmentNode: PathToNode
|
|
|
|
): { modifiedAst: Program; tag: string } | Error {
|
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 segmentNode = getNodeFromPath<CallExpression | CallExpressionKw>(
|
2024-08-26 08:07:20 +02:00
|
|
|
astClone,
|
2024-07-15 19:20:32 +10:00
|
|
|
pathToSegmentNode,
|
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
|
|
|
['CallExpression', 'CallExpressionKw']
|
2024-07-15 19:20:32 +10:00
|
|
|
)
|
2024-08-26 08:07:20 +02:00
|
|
|
if (err(segmentNode)) return segmentNode
|
2024-07-15 19:20:32 +10:00
|
|
|
|
2024-08-26 08:07:20 +02:00
|
|
|
// Check whether selection is a valid segment
|
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 (
|
|
|
|
!(
|
|
|
|
segmentNode.node.callee.name in sketchLineHelperMap ||
|
|
|
|
segmentNode.node.callee.name in sketchLineHelperMapKw
|
|
|
|
)
|
|
|
|
) {
|
2024-07-15 19:20:32 +10:00
|
|
|
return new Error('Selection is not a sketch segment')
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add tag to the sketch segment or use existing tag
|
2024-08-26 08:07:20 +02:00
|
|
|
// a helper function that creates the updated node and applies the changes to the AST
|
2024-07-15 19:20:32 +10:00
|
|
|
const taggedSegment = addTagForSketchOnFace(
|
|
|
|
{
|
|
|
|
pathToNode: pathToSegmentNode,
|
2024-08-26 08:07:20 +02:00
|
|
|
node: astClone,
|
2024-07-15 19:20:32 +10:00
|
|
|
},
|
2024-09-26 18:25:05 +10:00
|
|
|
segmentNode.node.callee.name,
|
|
|
|
null
|
2024-07-15 19:20:32 +10:00
|
|
|
)
|
|
|
|
if (err(taggedSegment)) return taggedSegment
|
|
|
|
const { tag } = taggedSegment
|
|
|
|
|
2024-08-26 08:07:20 +02:00
|
|
|
return { modifiedAst: astClone, tag }
|
|
|
|
}
|
2024-07-15 19:20:32 +10:00
|
|
|
|
2024-12-10 12:11:01 -05:00
|
|
|
export function getEdgeTagCall(
|
2024-10-11 23:25:51 +02:00
|
|
|
tag: string,
|
2024-11-21 15:04:30 +11:00
|
|
|
artifact: Artifact
|
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
|
|
|
): Node<Identifier | CallExpression | CallExpressionKw> {
|
2024-10-11 23:25:51 +02:00
|
|
|
let tagCall: Expr = createIdentifier(tag)
|
|
|
|
|
|
|
|
// Modify the tag based on selectionType
|
2024-11-21 15:04:30 +11:00
|
|
|
if (artifact.type === 'sweepEdge' && artifact.subType === 'opposite') {
|
2024-10-11 23:25:51 +02:00
|
|
|
tagCall = createCallExpressionStdLib('getOppositeEdge', [tagCall])
|
2024-11-21 15:04:30 +11:00
|
|
|
} else if (artifact.type === 'sweepEdge' && artifact.subType === 'adjacent') {
|
2024-10-11 23:25:51 +02:00
|
|
|
tagCall = createCallExpressionStdLib('getNextAdjacentEdge', [tagCall])
|
|
|
|
}
|
|
|
|
return tagCall
|
|
|
|
}
|
|
|
|
|
2024-08-26 08:07:20 +02:00
|
|
|
function locateExtrudeDeclarator(
|
|
|
|
node: Program,
|
|
|
|
pathToExtrudeNode: PathToNode
|
|
|
|
): { extrudeDeclarator: VariableDeclarator } | Error {
|
2024-11-19 21:30:26 +01:00
|
|
|
const nodeOfExtrudeCall = getNodeFromPath<VariableDeclaration>(
|
2024-08-26 08:07:20 +02:00
|
|
|
node,
|
|
|
|
pathToExtrudeNode,
|
|
|
|
'VariableDeclaration'
|
|
|
|
)
|
2024-11-19 21:30:26 +01:00
|
|
|
if (err(nodeOfExtrudeCall)) return nodeOfExtrudeCall
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-11-19 21:30:26 +01:00
|
|
|
const { node: extrudeVarDecl } = nodeOfExtrudeCall
|
2024-12-07 07:16:04 +13:00
|
|
|
const extrudeDeclarator = extrudeVarDecl.declaration
|
2024-08-26 08:07:20 +02:00
|
|
|
if (!extrudeDeclarator) {
|
|
|
|
return new Error('Extrude Declarator not found.')
|
|
|
|
}
|
|
|
|
|
|
|
|
const extrudeInit = extrudeDeclarator?.init
|
|
|
|
if (!extrudeInit) {
|
|
|
|
return new Error('Extrude Init not found.')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
extrudeInit.type !== '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
|
|
|
extrudeInit.type !== 'CallExpressionKw' &&
|
2024-08-26 08:07:20 +02:00
|
|
|
extrudeInit.type !== 'PipeExpression'
|
|
|
|
) {
|
|
|
|
return new Error('Extrude must be a PipeExpression or CallExpression')
|
|
|
|
}
|
|
|
|
|
|
|
|
return { extrudeDeclarator }
|
|
|
|
}
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
function getPathToNodeOfEdgeTreatmentLiteral(
|
2024-08-26 08:07:20 +02:00
|
|
|
pathToExtrudeNode: PathToNode,
|
|
|
|
extrudeDeclarator: 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
|
|
|
tag: Identifier | CallExpression | CallExpressionKw,
|
2024-12-02 21:43:59 +01:00
|
|
|
parameters: EdgeTreatmentParameters
|
2024-08-26 08:07:20 +02:00
|
|
|
): PathToNode {
|
2024-12-02 21:43:59 +01:00
|
|
|
let pathToEdgeTreatmentObj: PathToNode = []
|
|
|
|
let inEdgeTreatment = false
|
2024-08-26 08:07:20 +02:00
|
|
|
|
|
|
|
traverse(extrudeDeclarator.init, {
|
|
|
|
enter(node, path) {
|
2024-12-02 21:43:59 +01:00
|
|
|
if (
|
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
|
|
|
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
node.callee.name === parameters.type
|
|
|
|
) {
|
|
|
|
inEdgeTreatment = true
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
2024-12-02 21:43:59 +01:00
|
|
|
if (inEdgeTreatment && node.type === 'ObjectExpression') {
|
2024-08-26 08:07:20 +02:00
|
|
|
if (!hasTag(node, tag)) return false
|
2024-12-02 21:43:59 +01:00
|
|
|
pathToEdgeTreatmentObj = getPathToEdgeTreatmentParameterLiteral(
|
|
|
|
node,
|
|
|
|
path,
|
|
|
|
parameters
|
|
|
|
)
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
leave(node) {
|
2024-12-02 21:43:59 +01:00
|
|
|
if (
|
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
|
|
|
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
node.callee.name === parameters.type
|
|
|
|
) {
|
|
|
|
inEdgeTreatment = false
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
})
|
|
|
|
let indexOfPipeExpression = pathToExtrudeNode.findIndex(
|
|
|
|
(path) => path[1] === 'PipeExpression'
|
|
|
|
)
|
|
|
|
|
|
|
|
indexOfPipeExpression =
|
|
|
|
indexOfPipeExpression === -1
|
|
|
|
? pathToExtrudeNode.length
|
|
|
|
: indexOfPipeExpression
|
|
|
|
|
|
|
|
return [
|
|
|
|
...pathToExtrudeNode.slice(0, indexOfPipeExpression),
|
2024-12-02 21:43:59 +01:00
|
|
|
...pathToEdgeTreatmentObj,
|
2024-08-26 08:07:20 +02:00
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2024-10-11 23:25:51 +02:00
|
|
|
function hasTag(
|
|
|
|
node: ObjectExpression,
|
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
|
|
|
tag: Identifier | CallExpression | CallExpressionKw
|
2024-10-11 23:25:51 +02:00
|
|
|
): boolean {
|
2024-08-26 08:07:20 +02:00
|
|
|
return node.properties.some((prop) => {
|
|
|
|
if (prop.key.name === 'tags' && prop.value.type === 'ArrayExpression') {
|
2024-10-11 23:25:51 +02:00
|
|
|
// if selection is a base edge:
|
|
|
|
if (tag.type === 'Identifier') {
|
|
|
|
return prop.value.elements.some(
|
|
|
|
(element) =>
|
|
|
|
element.type === 'Identifier' && element.name === tag.name
|
|
|
|
)
|
|
|
|
}
|
|
|
|
// if selection is an adjacent or opposite edge:
|
|
|
|
if (tag.type === 'CallExpression') {
|
|
|
|
return prop.value.elements.some(
|
|
|
|
(element) =>
|
|
|
|
element.type === 'CallExpression' &&
|
|
|
|
element.callee.name === tag.callee.name && // edge location
|
|
|
|
element.arguments[0].type === 'Identifier' &&
|
|
|
|
tag.arguments[0].type === 'Identifier' &&
|
|
|
|
element.arguments[0].name === tag.arguments[0].name // tag name
|
|
|
|
)
|
|
|
|
}
|
KCL: Use keyword arguments for line, lineTo, extrude and close (#5249)
Part of #4600.
PR: https://github.com/KittyCAD/modeling-app/pull/4826
# Changes to KCL stdlib
- `line(point, sketch, tag)` and `lineTo(point, sketch, tag)` are combined into `line(@sketch, end?, endAbsolute?, tag?)`
- `close(sketch, tag?)` is now `close(@sketch, tag?)`
- `extrude(length, sketch)` is now `extrude(@sketch, length)`
Note that if a parameter starts with `@` like `@sketch`, it doesn't have any label when called, so you call it like this:
```
sketch = startSketchAt([0, 0])
line(sketch, end = [3, 3], tag = $hi)
```
Note also that if you're using a `|>` pipeline, you can omit the `@` argument and it will be assumed to be the LHS of the `|>`. So the above could be written as
```
sketch = startSketchAt([0, 0])
|> line(end = [3, 3], tag = $hi)
```
Also changes frontend tests to use KittyCAD/kcl-samples#139 instead of its main
The regex find-and-replace I use for migrating code (note these don't work with multi-line expressions) are:
```
line\(([^=]*), %\)
line(end = $1)
line\((.*), %, (.*)\)
line(end = $1, tag = $2)
lineTo\((.*), %\)
line(endAbsolute = $1)
lineTo\((.*), %, (.*)\)
line(endAbsolute = $1, tag = $2)
extrude\((.*), %\)
extrude(length = $1)
extrude\(([^=]*), ([a-zA-Z0-9]+)\)
extrude($2, length = $1)
close\(%, (.*)\)
close(tag = $1)
```
# Selected notes from commits before I squash them all
* Fix test 'yRelative to horizontal distance'
Fixes:
- Make a lineTo helper
- Fix pathToNode to go through the labeled arg .arg property
* Fix test by changing lookups into transformMap
Parts of the code assumed that `line` is always a relative call. But
actually now it might be absolute, if it's got an `endAbsolute` parameter.
So, change whether to look up `line` or `lineTo` and the relevant absolute
or relative line types based on that parameter.
* Stop asserting on exact source ranges
When I changed line to kwargs, all the source ranges we assert on became
slightly different. I find these assertions to be very very low value.
So I'm removing them.
* Fix more tests: getConstraintType calls weren't checking if the
'line' fn was absolute or relative.
* Fixed another queryAst test
There were 2 problems:
- Test was looking for the old style of `line` call to choose an offset
for pathToNode
- Test assumed that the `tag` param was always the third one, but in
a kwarg call, you have to look it up by label
* Fix test: traverse was not handling CallExpressionKw
* Fix another test, addTagKw
addTag helper was not aware of kw args.
* Convert close from positional to kwargs
If the close() call has 0 args, or a single unlabeled arg, the parser
interprets it as a CallExpression (positional) not a CallExpressionKw.
But then if a codemod wants to add a tag to it, it tries adding a kwarg
called 'tag', which fails because the CallExpression doesn't need
kwargs inserted into it.
The fix is: change the node from CallExpression to CallExpressionKw, and
update getNodeFromPath to take a 'replacement' arg, so we can replace
the old node with the new node in the AST.
* Fix the last test
Test was looking for `lineTo` as a substring of the input KCL program.
But there's no more lineTo function, so I changed it to look for
line() with an endAbsolute arg, which is the new equivalent.
Also changed the getConstraintInfo code to look up the lineTo if using
line with endAbsolute.
* Fix many bad regex find-replaces
I wrote a regex find-and-replace which converted `line` calls from
positional to keyword calls. But it was accidentally applied to more
places than it should be, for example, angledLine, xLine and yLine calls.
Fixes this.
* Fixes test 'Basic sketch › code pane closed at start'
Problem was, the getNodeFromPath call might not actually find a callExpressionKw,
it might find a callExpression. So the `giveSketchFnCallTag` thought
it was modifying a kwargs call, but it was actually modifying a positional
call.
This meant it tried to push a labeled argument in, rather than a normal
arg, and a lot of other problems. Fixed by doing runtime typechecking.
* Fix: Optional args given with wrong type were silently ignored
Optional args don't have to be given. But if the user gives them, they
should be the right type.
Bug: if the KCL interpreter found an optional arg, which was given, but
was the wrong type, it would ignore it and pretend the arg was never
given at all. This was confusing for users.
Fix: Now if you give an optional arg, but it's the wrong type, KCL will
emit a type error just like it would for a mandatory argument.
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-02-04 08:31:43 -06:00
|
|
|
if (tag.type === 'CallExpressionKw') {
|
|
|
|
return prop.value.elements.some((element) => {
|
|
|
|
if (element.type !== 'CallExpressionKw') {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
const elementTag = findKwArg(ARG_TAG, element)
|
|
|
|
const tagTag = findKwArg(ARG_TAG, tag)
|
|
|
|
|
|
|
|
return (
|
|
|
|
element.callee.name === tag.callee.name && // edge location
|
|
|
|
elementTag !== undefined &&
|
|
|
|
elementTag.type === 'Identifier' &&
|
|
|
|
tagTag !== undefined &&
|
|
|
|
tagTag.type === 'Identifier' &&
|
|
|
|
elementTag.name === tagTag.name
|
|
|
|
)
|
|
|
|
})
|
|
|
|
}
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
function getPathToEdgeTreatmentParameterLiteral(
|
|
|
|
node: ObjectExpression,
|
|
|
|
path: any,
|
|
|
|
parameters: EdgeTreatmentParameters
|
|
|
|
): PathToNode {
|
|
|
|
let pathToEdgeTreatmentObj = path
|
|
|
|
const parameterResult = getParameterNameAndValue(parameters)
|
|
|
|
if (err(parameterResult)) return pathToEdgeTreatmentObj
|
|
|
|
const { parameterName } = parameterResult
|
|
|
|
|
2024-08-26 08:07:20 +02:00
|
|
|
node.properties.forEach((prop, index) => {
|
2024-12-02 21:43:59 +01:00
|
|
|
if (prop.key.name === parameterName) {
|
|
|
|
pathToEdgeTreatmentObj.push(
|
2024-08-26 08:07:20 +02:00
|
|
|
['properties', 'ObjectExpression'],
|
|
|
|
[index, 'index'],
|
|
|
|
['value', 'Property']
|
|
|
|
)
|
|
|
|
}
|
|
|
|
})
|
2024-12-02 21:43:59 +01:00
|
|
|
return pathToEdgeTreatmentObj
|
2024-08-26 08:07:20 +02:00
|
|
|
}
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
function getParameterNameAndValue(
|
|
|
|
parameters: EdgeTreatmentParameters
|
|
|
|
): { parameterName: string; parameterValue: Expr } | Error {
|
|
|
|
if (parameters.type === EdgeTreatmentType.Fillet) {
|
|
|
|
const parameterValue =
|
|
|
|
'variableName' in parameters.radius
|
|
|
|
? parameters.radius.variableIdentifierAst
|
|
|
|
: parameters.radius.valueAst
|
|
|
|
return { parameterName: 'radius', parameterValue }
|
|
|
|
} else if (parameters.type === EdgeTreatmentType.Chamfer) {
|
|
|
|
const parameterValue =
|
|
|
|
'variableName' in parameters.length
|
|
|
|
? parameters.length.variableIdentifierAst
|
|
|
|
: parameters.length.valueAst
|
|
|
|
return { parameterName: 'length', parameterValue }
|
|
|
|
} else {
|
|
|
|
return new Error('Unsupported edge treatment type}')
|
|
|
|
}
|
|
|
|
}
|
2024-08-26 08:07:20 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// Type Guards
|
|
|
|
function isEdgeTreatmentType(name: string): name is EdgeTreatmentType {
|
|
|
|
return name === EdgeTreatmentType.Chamfer || name === EdgeTreatmentType.Fillet
|
|
|
|
}
|
|
|
|
function isEdgeType(name: string): name is EdgeTypes {
|
|
|
|
return (
|
|
|
|
name === 'getNextAdjacentEdge' ||
|
|
|
|
name === 'getPreviousAdjacentEdge' ||
|
|
|
|
name === 'getOppositeEdge'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Button states
|
|
|
|
export const hasValidEdgeTreatmentSelection = ({
|
2024-07-15 19:20:32 +10:00
|
|
|
selectionRanges,
|
|
|
|
ast,
|
|
|
|
code,
|
|
|
|
}: {
|
|
|
|
selectionRanges: Selections
|
2024-10-30 16:52:17 -04:00
|
|
|
ast: Node<Program>
|
2024-07-15 19:20:32 +10:00
|
|
|
code: string
|
|
|
|
}) => {
|
2024-12-02 21:43:59 +01:00
|
|
|
// check if there is anything valid for the edge treatment in the scene
|
2024-07-15 19:20:32 +10:00
|
|
|
let extrudeExists = false
|
|
|
|
traverse(ast, {
|
|
|
|
enter(node) {
|
2024-12-02 21:43:59 +01:00
|
|
|
if (
|
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
|
|
|
(node.type === 'CallExpression' || node.type == 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
(node.callee.name === 'extrude' || node.callee.name === 'revolve')
|
|
|
|
) {
|
2024-07-15 19:20:32 +10:00
|
|
|
extrudeExists = true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if (!extrudeExists) return false
|
|
|
|
|
2024-10-11 23:25:51 +02:00
|
|
|
// check if nothing is selected
|
2024-11-21 15:04:30 +11:00
|
|
|
if (selectionRanges.graphSelections.length === 0) {
|
2024-10-11 23:25:51 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if selection is last string in code
|
2024-11-21 15:04:30 +11:00
|
|
|
if (selectionRanges.graphSelections[0]?.codeRef?.range[0] === code.length) {
|
2024-10-11 23:25:51 +02:00
|
|
|
return true
|
2024-07-15 19:20:32 +10:00
|
|
|
}
|
|
|
|
|
2024-10-11 23:25:51 +02:00
|
|
|
// selection exists:
|
2024-11-21 15:04:30 +11:00
|
|
|
for (const selection of selectionRanges.graphSelections) {
|
2024-10-11 23:25:51 +02:00
|
|
|
// check if all selections are in sketchLineHelperMap
|
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 segmentNode = getNodeFromPath<
|
|
|
|
Node<CallExpression | CallExpressionKw>
|
|
|
|
>(ast, selection.codeRef.pathToNode, ['CallExpression', 'CallExpressionKw'])
|
2024-10-11 23:25:51 +02:00
|
|
|
if (err(segmentNode)) return false
|
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 (
|
|
|
|
!(
|
|
|
|
segmentNode.node.type === 'CallExpression' ||
|
|
|
|
segmentNode.node.type === 'CallExpressionKw'
|
|
|
|
)
|
|
|
|
) {
|
2024-10-11 23:25:51 +02:00
|
|
|
return false
|
|
|
|
}
|
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 (
|
|
|
|
!(
|
|
|
|
segmentNode.node.callee.name in sketchLineHelperMap ||
|
|
|
|
segmentNode.node.callee.name in sketchLineHelperMapKw
|
|
|
|
)
|
|
|
|
) {
|
2024-10-11 23:25:51 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if selection is extruded
|
|
|
|
// TODO: option 1 : extrude is in the sketch pipe
|
|
|
|
|
|
|
|
// option 2: extrude is outside the sketch pipe
|
|
|
|
const extrudeExists = hasSketchPipeBeenExtruded(selection, ast)
|
|
|
|
if (err(extrudeExists)) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if (!extrudeExists) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if tag exists for the selection
|
|
|
|
let tagExists = false
|
|
|
|
let tag = ''
|
|
|
|
traverse(segmentNode.node, {
|
|
|
|
enter(node) {
|
|
|
|
if (node.type === 'TagDeclarator') {
|
|
|
|
tagExists = true
|
|
|
|
tag = node.value
|
2024-07-15 19:20:32 +10:00
|
|
|
}
|
2024-10-11 23:25:51 +02:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// check if tag is used in edge treatment
|
2024-11-21 15:04:30 +11:00
|
|
|
if (tagExists && selection.artifact) {
|
2024-10-11 23:25:51 +02:00
|
|
|
// create tag call
|
2024-11-21 15:04:30 +11:00
|
|
|
let tagCall: Expr = getEdgeTagCall(tag, selection.artifact)
|
2024-10-11 23:25:51 +02:00
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
// check if tag is used in edge treatment
|
|
|
|
let inEdgeTreatment = false
|
|
|
|
let tagUsedInEdgeTreatment = false
|
|
|
|
|
2024-10-11 23:25:51 +02:00
|
|
|
traverse(ast, {
|
|
|
|
enter(node) {
|
2024-12-02 21:43:59 +01:00
|
|
|
if (
|
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
|
|
|
(node.type === 'CallExpression' ||
|
|
|
|
node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
isEdgeTreatmentType(node.callee.name)
|
|
|
|
) {
|
|
|
|
inEdgeTreatment = true
|
2024-10-11 23:25:51 +02:00
|
|
|
}
|
2024-12-02 21:43:59 +01:00
|
|
|
if (inEdgeTreatment && node.type === 'ObjectExpression') {
|
2024-10-11 23:25:51 +02:00
|
|
|
if (hasTag(node, tagCall)) {
|
2024-12-02 21:43:59 +01:00
|
|
|
tagUsedInEdgeTreatment = true
|
2024-10-11 23:25:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
leave(node) {
|
2024-12-02 21:43:59 +01:00
|
|
|
if (
|
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
|
|
|
(node.type === 'CallExpression' ||
|
|
|
|
node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
isEdgeTreatmentType(node.callee.name)
|
|
|
|
) {
|
|
|
|
inEdgeTreatment = false
|
2024-10-11 23:25:51 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
})
|
2024-12-02 21:43:59 +01:00
|
|
|
if (tagUsedInEdgeTreatment) {
|
2024-10-11 23:25:51 +02:00
|
|
|
return false
|
2024-07-15 19:20:32 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-10-11 23:25:51 +02:00
|
|
|
return true
|
2024-07-15 19:20:32 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
type EdgeTypes =
|
|
|
|
| 'baseEdge'
|
|
|
|
| 'getNextAdjacentEdge'
|
|
|
|
| 'getPreviousAdjacentEdge'
|
|
|
|
| 'getOppositeEdge'
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
export const isTagUsedInEdgeTreatment = ({
|
2024-07-15 19:20:32 +10:00
|
|
|
ast,
|
|
|
|
callExp,
|
|
|
|
}: {
|
2024-10-30 16:52:17 -04:00
|
|
|
ast: Node<Program>
|
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-07-15 19:20:32 +10:00
|
|
|
}): Array<EdgeTypes> => {
|
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 tag: string | undefined = (() => {
|
|
|
|
switch (callExp.type) {
|
|
|
|
case 'CallExpression': {
|
|
|
|
const tag = getTagFromCallExpression(callExp)
|
|
|
|
if (err(tag)) return undefined
|
|
|
|
return tag
|
|
|
|
}
|
|
|
|
case 'CallExpressionKw': {
|
|
|
|
const tag = findKwArg(ARG_TAG, callExp)
|
|
|
|
if (tag === undefined) {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
if (tag.type !== 'TagDeclarator') {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
return tag.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})()
|
2024-07-15 19:20:32 +10:00
|
|
|
if (err(tag)) return []
|
|
|
|
|
2024-12-02 21:43:59 +01:00
|
|
|
let inEdgeTreatment = false
|
2024-07-15 19:20:32 +10:00
|
|
|
let inObj = false
|
|
|
|
let inTagHelper: EdgeTypes | '' = ''
|
|
|
|
const edges: Array<EdgeTypes> = []
|
2024-12-02 21:43:59 +01:00
|
|
|
|
2024-07-15 19:20:32 +10:00
|
|
|
traverse(ast, {
|
|
|
|
enter: (node) => {
|
2024-12-02 21:43:59 +01:00
|
|
|
// Check if we are entering an edge treatment call
|
|
|
|
if (
|
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
|
|
|
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
isEdgeTreatmentType(node.callee.name)
|
|
|
|
) {
|
|
|
|
inEdgeTreatment = true
|
2024-07-15 19:20:32 +10:00
|
|
|
}
|
2024-12-02 21:43:59 +01:00
|
|
|
if (inEdgeTreatment && node.type === 'ObjectExpression') {
|
2024-07-15 19:20:32 +10:00
|
|
|
node.properties.forEach((prop) => {
|
|
|
|
if (
|
|
|
|
prop.key.name === 'tags' &&
|
|
|
|
prop.value.type === 'ArrayExpression'
|
|
|
|
) {
|
|
|
|
inObj = true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
inObj &&
|
2024-12-02 21:43:59 +01:00
|
|
|
inEdgeTreatment &&
|
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
|
|
|
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
isEdgeType(node.callee.name)
|
2024-07-15 19:20:32 +10:00
|
|
|
) {
|
|
|
|
inTagHelper = node.callee.name
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
inObj &&
|
2024-12-02 21:43:59 +01:00
|
|
|
inEdgeTreatment &&
|
2024-07-15 19:20:32 +10:00
|
|
|
!inTagHelper &&
|
|
|
|
node.type === 'Identifier' &&
|
|
|
|
node.name === tag
|
|
|
|
) {
|
|
|
|
edges.push('baseEdge')
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
inObj &&
|
2024-12-02 21:43:59 +01:00
|
|
|
inEdgeTreatment &&
|
2024-07-15 19:20:32 +10:00
|
|
|
inTagHelper &&
|
|
|
|
node.type === 'Identifier' &&
|
|
|
|
node.name === tag
|
|
|
|
) {
|
|
|
|
edges.push(inTagHelper)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
leave: (node) => {
|
2024-12-02 21:43:59 +01:00
|
|
|
if (
|
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
|
|
|
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
isEdgeTreatmentType(node.callee.name)
|
|
|
|
) {
|
|
|
|
inEdgeTreatment = false
|
2024-07-15 19:20:32 +10:00
|
|
|
}
|
2024-12-02 21:43:59 +01:00
|
|
|
if (inEdgeTreatment && node.type === 'ObjectExpression') {
|
2024-07-15 19:20:32 +10:00
|
|
|
node.properties.forEach((prop) => {
|
|
|
|
if (
|
|
|
|
prop.key.name === 'tags' &&
|
|
|
|
prop.value.type === 'ArrayExpression'
|
|
|
|
) {
|
|
|
|
inObj = true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if (
|
|
|
|
inObj &&
|
2024-12-02 21:43:59 +01:00
|
|
|
inEdgeTreatment &&
|
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
|
|
|
(node.type === 'CallExpression' || node.type === 'CallExpressionKw') &&
|
2024-12-02 21:43:59 +01:00
|
|
|
isEdgeType(node.callee.name)
|
2024-07-15 19:20:32 +10:00
|
|
|
) {
|
|
|
|
inTagHelper = ''
|
|
|
|
}
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
return edges
|
|
|
|
}
|
2025-02-03 18:11:26 +01:00
|
|
|
|
|
|
|
// Delete Edge Treatment
|
|
|
|
export async function deleteEdgeTreatment(
|
|
|
|
ast: Node<Program>,
|
|
|
|
selection: Selection
|
|
|
|
): Promise<Node<Program> | Error> {
|
|
|
|
/**
|
|
|
|
* Deletes an edge treatment (fillet or chamfer)
|
|
|
|
* from the AST based on the selection.
|
|
|
|
* Handles both standalone treatments
|
|
|
|
* and those within a PipeExpression.
|
|
|
|
*
|
|
|
|
* Supported cases:
|
|
|
|
* [+] fillet and chamfer
|
|
|
|
* [+] piped and non-piped edge treatments
|
|
|
|
* [-] delete single tag from array of tags (currently whole expression is deleted)
|
|
|
|
* [-] multiple selections with different edge treatments (currently single selection is supported)
|
|
|
|
*/
|
|
|
|
|
|
|
|
// 1. Validate Selection Type
|
|
|
|
const { artifact } = selection
|
|
|
|
if (!artifact || artifact.type !== 'edgeCut') {
|
|
|
|
return new Error('Selection is not an edge cut')
|
|
|
|
}
|
|
|
|
|
|
|
|
const { subType: edgeTreatmentType } = artifact
|
|
|
|
if (
|
|
|
|
!edgeTreatmentType ||
|
|
|
|
!['fillet', 'chamfer'].includes(edgeTreatmentType)
|
|
|
|
) {
|
|
|
|
return new Error('Unsupported or missing edge treatment type')
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2. Clone ast and retrieve the VariableDeclarator
|
|
|
|
const astClone = structuredClone(ast)
|
|
|
|
const varDec = getNodeFromPath<VariableDeclarator>(
|
|
|
|
ast,
|
|
|
|
selection?.codeRef?.pathToNode,
|
|
|
|
'VariableDeclarator'
|
|
|
|
)
|
|
|
|
if (err(varDec)) return varDec
|
|
|
|
|
|
|
|
// 3: Check if edge treatment is in a pipe
|
|
|
|
const inPipe = varDec.node.init.type === 'PipeExpression'
|
|
|
|
|
|
|
|
// 4A. Handle standalone edge treatment
|
|
|
|
if (!inPipe) {
|
|
|
|
const varDecPathStep = varDec.shallowPath[1]
|
|
|
|
|
2025-02-05 09:01:45 -05:00
|
|
|
if (!isArray(varDecPathStep) || typeof varDecPathStep[0] !== 'number') {
|
2025-02-03 18:11:26 +01:00
|
|
|
return new Error(
|
|
|
|
'Invalid shallowPath structure: expected a number at shallowPath[1][0]'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const varDecIndex: number = varDecPathStep[0]
|
|
|
|
|
|
|
|
// Remove entire VariableDeclarator from the ast
|
|
|
|
astClone.body.splice(varDecIndex, 1)
|
|
|
|
return astClone
|
|
|
|
}
|
|
|
|
|
|
|
|
// 4B. Handle edge treatment within pipe
|
|
|
|
if (inPipe) {
|
|
|
|
// Retrieve the CallExpression path
|
|
|
|
const callExp =
|
|
|
|
getNodeFromPath<CallExpression>(
|
|
|
|
ast,
|
|
|
|
selection?.codeRef?.pathToNode,
|
|
|
|
'CallExpression'
|
|
|
|
) ?? null
|
|
|
|
if (err(callExp)) return callExp
|
|
|
|
|
|
|
|
const shallowPath = callExp.shallowPath
|
|
|
|
|
|
|
|
// Initialize variables to hold the PipeExpression path and callIndex
|
|
|
|
let pipeExpressionPath: PathToNode | null = null
|
|
|
|
let callIndex: number | null = null
|
|
|
|
|
|
|
|
// Iterate through the shallowPath to find the PipeExpression and callIndex
|
|
|
|
for (let i = 0; i < shallowPath.length - 1; i++) {
|
|
|
|
const [key, value] = shallowPath[i]
|
|
|
|
|
|
|
|
if (key === 'body' && value === 'PipeExpression') {
|
|
|
|
pipeExpressionPath = shallowPath.slice(0, i + 1)
|
|
|
|
|
|
|
|
const nextStep = shallowPath[i + 1]
|
|
|
|
if (
|
|
|
|
nextStep &&
|
|
|
|
nextStep[1] === 'index' &&
|
|
|
|
typeof nextStep[0] === 'number'
|
|
|
|
) {
|
|
|
|
callIndex = nextStep[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pipeExpressionPath) {
|
|
|
|
return new Error('PipeExpression not found in path')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (callIndex === null) {
|
|
|
|
return new Error('Failed to extract CallExpression index')
|
|
|
|
}
|
|
|
|
// Retrieve the PipeExpression node
|
|
|
|
const pipeExpressionNode = getNodeFromPath<PipeExpression>(
|
|
|
|
astClone,
|
|
|
|
pipeExpressionPath,
|
|
|
|
'PipeExpression'
|
|
|
|
)
|
|
|
|
if (err(pipeExpressionNode)) return pipeExpressionNode
|
|
|
|
|
|
|
|
// Ensure that the PipeExpression.body is an array
|
2025-02-05 09:01:45 -05:00
|
|
|
if (!isArray(pipeExpressionNode.node.body)) {
|
2025-02-03 18:11:26 +01:00
|
|
|
return new Error('PipeExpression body is not an array')
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the CallExpression at the specified index
|
|
|
|
pipeExpressionNode.node.body.splice(callIndex, 1)
|
|
|
|
|
|
|
|
// Remove VariableDeclarator if PipeExpression.body is empty
|
|
|
|
if (pipeExpressionNode.node.body.length === 0) {
|
|
|
|
const varDecPathStep = varDec.shallowPath[1]
|
2025-02-05 09:01:45 -05:00
|
|
|
if (!isArray(varDecPathStep) || typeof varDecPathStep[0] !== 'number') {
|
2025-02-03 18:11:26 +01:00
|
|
|
return new Error(
|
|
|
|
'Invalid shallowPath structure: expected a number at shallowPath[1][0]'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
const varDecIndex: number = varDecPathStep[0]
|
|
|
|
astClone.body.splice(varDecIndex, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return astClone
|
|
|
|
}
|
|
|
|
|
|
|
|
return Error('Delete fillets not implemented')
|
|
|
|
}
|