Compare commits

...

92 Commits

Author SHA1 Message Date
8210663923 replicate bad error 2023-11-10 05:55:57 +11:00
7272cc9fbd Describe Rust version for devs (#1044)
Fixes #1042
2023-11-09 17:01:52 +00:00
b925ed9b65 KCL stdlib and circle function (#1029)
Allows stdlib functions to be written as KCL, not as Rust. 

Rust stdlib functions will hereafter be referred to as "core" not "std".

Right now the only stdlib function I implemented is a circle function (it's a wrapper around the core arc function which sets the arc's start/end to 0 and 360 respectively). I know I want to change this function as soon as KCL has enums, which is my next task. So, I don't want users to start using this right away. To that end, I've named this function "unstable_stdlib_circle" not "circle". Once the function is ready to be stabilized, I can rename it to just "circle".

Note that this PR modifies the existing "sketch and extrude a cylinder" KCL test so that instead of using a user-defined circle function, it uses the unstable_stdlib_circle function now. And the twenty-twenty tests pass, so we know my stdlib is working.

https://github.com/KittyCAD/modeling-app/issues/922
2023-11-09 09:58:20 -06:00
0db5db2181 Bump js-sys from 0.3.64 to 0.3.65 in /src/wasm-lib (#980)
Bumps [js-sys](https://github.com/rustwasm/wasm-bindgen) from 0.3.64 to 0.3.65.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/commits)

---
updated-dependencies:
- dependency-name: js-sys
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-08 23:41:53 -06:00
898e3db9d1 AST function nodes no longer have stdlib function members (#1031)
* AST function nodes no longer have stdlib function members

IMO the AST should not need an actual pointer to a stdlib function -- that is a completely separate concern from the AST.

Instead, the AST nodes can just store function names, and the executor will have a stdlib which it can look up those names in.

* Fix tests

* Update snapshot tests
2023-11-08 20:23:59 -06:00
d337ac2546 Test with a circle function (#1030) 2023-11-08 15:06:41 -06:00
371d8e08f7 Refactor the call_fn fn to be more readable (#1028) 2023-11-08 13:44:31 -06:00
338c43a29d Fix auto-version in nightly builds (#1026)
* WIP Fix auto-version in nightly builds
Fixes #1015

* WIP

* Revert "WIP"

This reverts commit 7838bf1298.

* Need to update src-tauri/tauri.release.conf.json after CI changes

* Fixes just to test

* Clean up after tests
2023-11-08 13:58:37 +00:00
52bb5a2657 Bump @sentry/react from 7.65.0 to 7.77.0 (#977)
Bumps [@sentry/react](https://github.com/getsentry/sentry-javascript) from 7.65.0 to 7.77.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.65.0...7.77.0)

---
updated-dependencies:
- dependency-name: "@sentry/react"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-08 10:39:40 +00:00
1b6a06d266 Bump vscode-languageserver-protocol from 3.17.3 to 3.17.5 (#978)
Bumps [vscode-languageserver-protocol](https://github.com/Microsoft/vscode-languageserver-node/tree/HEAD/protocol) from 3.17.3 to 3.17.5.
- [Commits](https://github.com/Microsoft/vscode-languageserver-node/commits/release/types/3.17.5/protocol)

---
updated-dependencies:
- dependency-name: vscode-languageserver-protocol
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-08 05:28:24 -05:00
c68d4778a5 Bump @tauri-apps/api from 1.5.0 to 1.5.1 (#979)
Bumps [@tauri-apps/api](https://github.com/tauri-apps/tauri) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/api-v1.5...@tauri-apps/api-v1.5.1)

---
updated-dependencies:
- dependency-name: "@tauri-apps/api"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-08 05:28:01 -05:00
a8abea4fb5 Bump eslint from 8.46.0 to 8.53.0 (#1001)
Bumps [eslint](https://github.com/eslint/eslint) from 8.46.0 to 8.53.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.46.0...v8.53.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-08 05:27:13 -05:00
a0678d22a8 fix epsilon bug (#1025) 2023-11-08 09:27:53 +00:00
acbfae2e65 Bump wasm-bindgen from 0.2.87 to 0.2.88 in /src/wasm-lib (#981)
Bumps [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) from 0.2.87 to 0.2.88.
- [Release notes](https://github.com/rustwasm/wasm-bindgen/releases)
- [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustwasm/wasm-bindgen/compare/0.2.87...0.2.88)

---
updated-dependencies:
- dependency-name: wasm-bindgen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-07 23:56:23 -06:00
1e1bec6a8a Bump winnow (#1024) 2023-11-07 23:55:45 -06:00
06462b5a65 Bump syn from 2.0.38 to 2.0.39 in /src/wasm-lib (#1000)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.38 to 2.0.39.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.38...2.0.39)

---
updated-dependencies:
- dependency-name: syn
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-07 22:45:58 -06:00
2f292fb1be Bump tauri-plugin-fs-extra from 11048fd to 6865299 in /src-tauri (#1023)
Bumps [tauri-plugin-fs-extra](https://github.com/tauri-apps/plugins-workspace) from `11048fd` to `6865299`.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](11048fd997...6865299149)

---
updated-dependencies:
- dependency-name: tauri-plugin-fs-extra
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-07 22:45:20 -06:00
8184e7b376 Bump serde from 1.0.190 to 1.0.192 in /src-tauri (#1009)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.190 to 1.0.192.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.190...v1.0.192)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-07 22:45:03 -06:00
b1084cbf80 Bump serde from 1.0.190 to 1.0.192 in /src/wasm-lib (#1012)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.190 to 1.0.192.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.190...v1.0.192)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-07 22:44:55 -06:00
548b45905e Cut release v0.11.3 (#1020)
cut release v0.11.3
2023-11-08 12:57:00 +11:00
141fd2f3f1 fix variables panel and others (#1021) 2023-11-08 01:27:43 +00:00
604d931962 selections fix follow up (#1019) 2023-11-07 23:10:30 +00:00
b1668410f8 Neaten up stdlib code (#1017) 2023-11-07 12:12:18 -06:00
13176cec38 Cut release v0.11.2 (#1005)
* Cut release v0.11.2

* Replace 'release' with '*' for artifact upload

* New logic to prevent top-level artifact.zip changes

* Fix upload

---------

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
2023-11-07 05:20:26 -05:00
3a59ae13b6 fix selections (#1013) 2023-11-07 07:21:32 +00:00
57c2481943 unused imports (#1011) 2023-11-07 03:29:50 +00:00
a1c555c51e clear errors on good parse (#1008) 2023-11-07 02:02:44 +00:00
4d520541be Build release & sign only on merge / release / release PR (#991)
* Add env variable for release || schedule || Cut out v PR

* Skip Windows, Apple, and Tauri Updater signing

* Add tauri args to bypass updater on debug

* Trying to address includeRelease and includeDebug issues

* WIP

* Clean up, fix bool eval

* -c to --config

* Remove src-tauri

* inline config

* Cleanup

* Remove concurrency block

* Test release

* Escape backslash

* Clean up

* Add back concurrency and BUILD_RELEASE eval

* Back to build:wasm (no speed impr noticed)

* Adam's suggestions

Co-authored-by: Adam Chalmers <adam.chalmers@kittycad.io>

* New logic to prevent top-level artifact.zip changes

---------

Co-authored-by: Adam Chalmers <adam.chalmers@kittycad.io>
2023-11-06 19:51:32 -05:00
82586f002b Test Jess's KCL error (#1004) 2023-11-06 14:01:51 -06:00
4bd08f7444 safe parse (#996)
* safe parse

* use safe parse on mouse up, stream
2023-11-06 06:47:45 +00:00
6b2603b1c4 don't overwrite current file on onboarding-replay (#1003)
don't over write file on onboarding
2023-11-06 04:03:21 +00:00
af49bebde3 compare formated asts before execute (#1002) 2023-11-06 03:43:01 +00:00
ca056996fd stop double execute on project open (#997) 2023-11-06 14:33:19 +11:00
34163da361 start of fixing changing files and cleaning up after execute (#897)
* start of fixing changing files and cleaning up after execute

* stop constraints from leaving artifacts

* don't write file on initial load
2023-11-06 11:49:13 +11:00
7c22bac638 Remove unwraps from binary expression algorithm (#992) 2023-11-03 13:30:19 -05:00
37a65b166b Fix silly mistakes in previous CI.yml PRs (#988)
* Fix silly mistakes in previous CI.yml PRs

This is what happens when I code before my morning matcha

Part of #987
2023-11-02 12:34:38 -05:00
1189f272ba Use debug builds for wasm-pack on PRs (#986) 2023-11-02 09:55:58 -05:00
ca5bc880dc Build tauri app in debug mode on PRs, release mode on releases (#985)
Build tauri app in debug mode on PRs, release mode on merges.

Release builds are very slow and should only be used for actual releases. Fast debug builds should be used for CI on PRs.
2023-11-02 09:55:36 -05:00
828daba304 Tweak Codespell CI (#975)
Ensure codespell CI job actually catches typos
2023-11-01 23:35:41 +00:00
0b9ba55bb4 Nicer error messages for unknown tokens (#974) 2023-11-01 23:08:22 +00:00
2d2a85ae7d remove view change from debug panel (#866)
remove view change from debug
2023-11-01 23:03:58 +00:00
cc57a302cc Update twenty-twenty (#973)
Due to engine PR #1566
2023-11-01 22:35:17 +00:00
fdbfd0c4b6 Fix typos (#972)
* Update twenty-twenty

Due to engine PR #1566

* Fix typos
2023-11-01 22:34:54 +00:00
2e419907e6 Tokenizing fallibility (#883)
Tokenization tracks invalid tokens and produces a nice error about them

---------

Co-authored-by: Adam Chalmers <adam.chalmers@kittycad.io>
2023-11-01 17:20:49 -05:00
3d0c5c10b0 KCL literals are typed, not JSON values (#971)
We now control the KCL type system instead of reusing JSON's type system.
2023-11-01 13:52:50 -05:00
4d47c067b7 Snapshot testing for parser (#969)
See https://docs.rs/insta for more.
2023-11-01 12:40:40 -05:00
3b3b5371eb Bump wasm-streams from 0.3.0 to 0.4.0 in /src/wasm-lib (#961)
Bumps [wasm-streams](https://github.com/MattiasBuelens/wasm-streams) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/MattiasBuelens/wasm-streams/releases)
- [Changelog](https://github.com/MattiasBuelens/wasm-streams/blob/main/CHANGELOG.md)
- [Commits](https://github.com/MattiasBuelens/wasm-streams/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: wasm-streams
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-01 08:43:18 -05:00
3ea77f8e1e Bump zustand from 4.4.0 to 4.4.5 (#963)
Bumps [zustand](https://github.com/pmndrs/zustand) from 4.4.0 to 4.4.5.
- [Release notes](https://github.com/pmndrs/zustand/releases)
- [Commits](https://github.com/pmndrs/zustand/compare/v4.4.0...v4.4.5)

---
updated-dependencies:
- dependency-name: zustand
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2023-11-01 09:14:57 -04:00
4fa7c07e54 Bump @uiw/react-codemirror from 4.21.13 to 4.21.20 (#967)
Bumps [@uiw/react-codemirror](https://github.com/uiwjs/react-codemirror) from 4.21.13 to 4.21.20.
- [Release notes](https://github.com/uiwjs/react-codemirror/releases)
- [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.21.13...v4.21.20)

---
updated-dependencies:
- dependency-name: "@uiw/react-codemirror"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2023-11-01 09:14:04 -04:00
c66a96a333 Bump @testing-library/react from 13.4.0 to 14.0.0 (#965)
Bumps [@testing-library/react](https://github.com/testing-library/react-testing-library) from 13.4.0 to 14.0.0.
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v13.4.0...v14.0.0)

---
updated-dependencies:
- dependency-name: "@testing-library/react"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-01 07:42:24 -04:00
4196ff91ac Bump vite from 4.4.9 to 4.5.0 (#966)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.9 to 4.5.0.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.0/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-01 07:41:58 -04:00
cf66b93963 Fix most Github Actions 'annotations' in PRs (#417)
* Fix Github Actions 'annotations' in PRs
Fixes #383

* Fix the React Hooks complains, and _app for rust

* Revert "Fix the React Hooks complains, and _app for rust"

This reverts commit 4a2ff925e5.

* Add back prettier fix and rust _app

* Fmt

* More annotation fixes

* More non-hooks fixes

* Rollback with eslint rule

* Add APPLE_TEAM_ID secret

* Revert "Add APPLE_TEAM_ID secret"

This reverts commit 346aaff5f4.

* More fixes
2023-11-01 07:39:31 -04:00
0b0219b810 Add repository field to Cargo.toml (#960) 2023-10-31 18:24:19 -05:00
36c7fcf6d7 Add a basic tauri e2e test on Linux (#923)
* WIP e2e test

* Working test on Linux

* Clean up

* Add to CI

* Fix

* Install tauri-driver

* Migrate to ubuntu-latest

* Add button check and click

* Update name

* Separate job for e2e test

* Fix path

* Fix perms

* Fix perms

* Single build-test-apps job

* Lint wdio file
2023-10-31 18:30:24 -04:00
023c3cbb90 New math parser (#956)
* New math parser

* Remove old parser

* Comments

* Move tests into parser_impl, remove dead code

* Backport some math tests
2023-10-31 14:16:18 -05:00
387f7e0912 New benchmark for parsing binary expressions (#957) 2023-10-31 18:04:24 +00:00
9b55b1fd12 Bump serde_json from 1.0.107 to 1.0.108 in /src-tauri (#954)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.107 to 1.0.108.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.107...v1.0.108)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2023-10-31 09:58:27 -05:00
4b6662169c Bump tauri-plugin-fs-extra from 68d77f9 to 11048fd in /src-tauri (#955)
Bumps [tauri-plugin-fs-extra](https://github.com/tauri-apps/plugins-workspace) from `68d77f9` to `11048fd`.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](68d77f999c...11048fd997)

---
updated-dependencies:
- dependency-name: tauri-plugin-fs-extra
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:50:50 -04:00
d36abfcb3d Bump serde_json from 1.0.107 to 1.0.108 in /src/wasm-lib (#953)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.107 to 1.0.108.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.107...v1.0.108)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:50:07 -04:00
9002ae9efb Bump winnow from 0.5.17 to 0.5.18 in /src/wasm-lib (#952)
Bumps [winnow](https://github.com/winnow-rs/winnow) from 0.5.17 to 0.5.18.
- [Changelog](https://github.com/winnow-rs/winnow/blob/main/CHANGELOG.md)
- [Commits](https://github.com/winnow-rs/winnow/compare/v0.5.17...v0.5.18)

---
updated-dependencies:
- dependency-name: winnow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:49:51 -04:00
4deea25394 Bump @codemirror/autocomplete from 6.9.0 to 6.10.2 (#951)
Bumps [@codemirror/autocomplete](https://github.com/codemirror/autocomplete) from 6.9.0 to 6.10.2.
- [Changelog](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/autocomplete/compare/6.9.0...6.10.2)

---
updated-dependencies:
- dependency-name: "@codemirror/autocomplete"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:49:15 -04:00
b5940d2cb7 Bump @tauri-apps/cli from 1.5.2 to 1.5.6 (#950)
Bumps [@tauri-apps/cli](https://github.com/tauri-apps/tauri) from 1.5.2 to 1.5.6.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/cli-v1.5.2...@tauri-apps/cli-v1.5.6)

---
updated-dependencies:
- dependency-name: "@tauri-apps/cli"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:48:51 -04:00
932b467c1e Bump @testing-library/user-event from 13.5.0 to 14.5.1 (#949)
Bumps [@testing-library/user-event](https://github.com/testing-library/user-event) from 13.5.0 to 14.5.1.
- [Release notes](https://github.com/testing-library/user-event/releases)
- [Changelog](https://github.com/testing-library/user-event/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/user-event/compare/v13.5.0...v14.5.1)

---
updated-dependencies:
- dependency-name: "@testing-library/user-event"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:48:34 -04:00
7c7f5c81c4 Bump web-vitals from 2.1.4 to 3.5.0 (#948)
Bumps [web-vitals](https://github.com/GoogleChrome/web-vitals) from 2.1.4 to 3.5.0.
- [Changelog](https://github.com/GoogleChrome/web-vitals/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GoogleChrome/web-vitals/compare/v2.1.4...v3.5.0)

---
updated-dependencies:
- dependency-name: web-vitals
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:48:05 -04:00
066b4f3e06 Bump typescript from 4.9.5 to 5.2.2 (#778)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.9.5 to 5.2.2.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.9.5...v5.2.2)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-31 06:47:34 -04:00
c6067bfc7a Bump kittycad from 0.2.38 to 0.2.41 in /src-tauri (#935)
Bumps [kittycad](https://github.com/KittyCAD/kittycad.rs) from 0.2.38 to 0.2.41.
- [Release notes](https://github.com/KittyCAD/kittycad.rs/releases)
- [Commits](https://github.com/KittyCAD/kittycad.rs/compare/v0.2.38...v0.2.41)

---
updated-dependencies:
- dependency-name: kittycad
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 22:22:05 -05:00
2018f0d517 Bump actions/setup-node from 3 to 4 (#924)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 22:21:57 -05:00
74aae3d15f Bump openapitor from 57b4d8b to 1b2562f in /src/wasm-lib (#938)
Bumps [openapitor](https://github.com/KittyCAD/kittycad.rs) from `57b4d8b` to `1b2562f`.
- [Release notes](https://github.com/KittyCAD/kittycad.rs/releases)
- [Commits](57b4d8b168...1b2562f4b3)

---
updated-dependencies:
- dependency-name: openapitor
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 22:21:35 -05:00
812f419e75 Bump serde from 1.0.189 to 1.0.190 in /src/wasm-lib (#941)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.190.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.190)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 22:21:23 -05:00
5ec8cc69db Bump tauri-plugin-fs-extra from 9b20f28 to 68d77f9 in /src-tauri (#942)
Bumps [tauri-plugin-fs-extra](https://github.com/tauri-apps/plugins-workspace) from `9b20f28` to `68d77f9`.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](9b20f28d74...68d77f999c)

---
updated-dependencies:
- dependency-name: tauri-plugin-fs-extra
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 22:21:14 -05:00
a5302b6e0e Nitpick my Winnow code (#946) 2023-10-30 22:20:37 -05:00
2114cc0d94 Bump @babel/traverse from 7.22.8 to 7.23.2 (#879)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.8 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:45:36 -04:00
2471ce1aba Bump swr from 2.2.0 to 2.2.2 (#332)
Bumps [swr](https://github.com/vercel/swr) from 2.2.0 to 2.2.2.
- [Release notes](https://github.com/vercel/swr/releases)
- [Commits](https://github.com/vercel/swr/compare/v2.2.0...v2.2.2)

---
updated-dependencies:
- dependency-name: swr
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
2023-10-30 20:45:18 -04:00
35772475b9 Bump uuid and @types/uuid (#617)
Bumps [uuid](https://github.com/uuidjs/uuid) and [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid). These dependencies needed to be updated together.

Updates `uuid` from 9.0.0 to 9.0.1
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1)

Updates `@types/uuid` from 9.0.2 to 9.0.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: "@types/uuid"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:44:51 -04:00
86c592c0f6 Bump vite-tsconfig-paths from 4.2.0 to 4.2.1 (#750)
Bumps [vite-tsconfig-paths](https://github.com/aleclarson/vite-tsconfig-paths) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/aleclarson/vite-tsconfig-paths/releases)
- [Commits](https://github.com/aleclarson/vite-tsconfig-paths/compare/v4.2.0...v4.2.1)

---
updated-dependencies:
- dependency-name: vite-tsconfig-paths
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:44:33 -04:00
0e98973cfa Bump @types/debounce-promise from 3.1.6 to 3.1.8 (#899)
Bumps [@types/debounce-promise](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/debounce-promise) from 3.1.6 to 3.1.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/debounce-promise)

---
updated-dependencies:
- dependency-name: "@types/debounce-promise"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:43:46 -04:00
7dd16fe6de Bump clap from 4.4.6 to 4.4.7 in /src/wasm-lib (#939)
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.6 to 4.4.7.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.6...v4.4.7)

---
updated-dependencies:
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:42:58 -04:00
478b636049 Bump crypto-js from 4.1.1 to 4.2.0 (#940)
Bumps [crypto-js](https://github.com/brix/crypto-js) from 4.1.1 to 4.2.0.
- [Commits](https://github.com/brix/crypto-js/compare/4.1.1...4.2.0)

---
updated-dependencies:
- dependency-name: crypto-js
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:42:43 -04:00
c779311a56 Bump serde from 1.0.189 to 1.0.190 in /src-tauri (#943)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.189 to 1.0.190.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.189...v1.0.190)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:42:01 -04:00
ca02ec1151 Bump futures from 0.3.28 to 0.3.29 in /src/wasm-lib (#944)
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.28...0.3.29)

---
updated-dependencies:
- dependency-name: futures
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 20:41:37 -04:00
b271d5060e Fix typos and unnecessary import paths (#945) 2023-10-27 18:42:35 +00:00
19f11fe55a Cut release v0.11.1 (#936) 2023-10-26 07:27:29 -04:00
f6f1574982 Use kittycad::Angle instead of our own (#934) 2023-10-24 16:32:41 -07:00
6dc4fbc808 Use KittyCAD rust library from workspace (#932)
* Use KittyCAD rust library from workspace

* Clippy
2023-10-24 20:49:06 +00:00
8843d02380 Cargo update (#929) 2023-10-24 11:24:59 -07:00
3578ec07e6 Bump uuid from 1.4.1 to 1.5.0 in /src/wasm-lib (#926)
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.4.1...1.5.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 10:42:07 -07:00
db35f73e41 Bump thiserror from 1.0.49 to 1.0.50 in /src/wasm-lib (#927)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.49 to 1.0.50.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.49...1.0.50)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 10:41:47 -07:00
5cfc2b7941 DRY the code (#921) 2023-10-24 17:30:14 +00:00
318e4a0cc7 Update kittycad.rs (#919) 2023-10-23 14:03:38 -07:00
1e23be8f08 Update rustix (#920) 2023-10-23 14:03:28 -07:00
ef547e7db8 bump kc lib 45 (#913) 2023-10-20 05:05:42 +00:00
71b48bbd89 Fix nightly last_update link (#901) 2023-10-18 21:01:44 -04:00
157 changed files with 10505 additions and 6080 deletions

3
.codespellrc Normal file
View File

@ -0,0 +1,3 @@
[codespell]
ignore-words-list: crate,everytime
skip: **/target,node_modules,build

View File

@ -12,27 +12,32 @@ on:
# Daily at 04:00 AM UTC
# Will checkout the last commit from the default branch (main as of 2023-10-04)
env:
BUILD_RELEASE: ${{ github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'pull_request' && contains(github.event.pull_request.title, 'Cut release v') }}
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
check-format:
runs-on: 'ubuntu-20.04'
runs-on: 'ubuntu-latest'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- run: yarn install
- run: yarn fmt-check
check-types:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
@ -44,12 +49,27 @@ jobs:
- run: yarn build:wasm
- run: yarn tsc
check-typos:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
- name: Install codespell
run: |
python -m pip install codespell
- name: Run codespell
run: codespell --config .codespellrc # Edit this file to tweak the typo list and other configuration.
build-test-web:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
@ -68,14 +88,15 @@ jobs:
- run: yarn test:cov
prepare-json-files:
runs-on: ubuntu-20.04 # seperate job on Ubuntu for easy string manipulations (compared to Windows)
runs-on: ubuntu-latest # seperate job on Ubuntu for easy string manipulations (compared to Windows)
outputs:
version: ${{ steps.export_version.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
@ -84,8 +105,8 @@ jobs:
if: github.event_name == 'schedule'
run: |
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
echo "$(jq --arg url 'https://dl.kittycad.io/releases/modeling-app/test/nightly/last_update.json' \
'.tauri.updater.endpoints[]=$url' src-tauri/tauri.conf.json --indent 2)" > src-tauri/tauri.conf.json
echo "$(jq --arg url 'https://dl.kittycad.io/releases/modeling-app/nightly/last_update.json' \
'.tauri.updater.endpoints[]=$url' src-tauri/tauri.release.conf.json --indent 2)" > src-tauri/tauri.release.conf.json
- uses: actions/upload-artifact@v3
if: github.event_name == 'schedule'
@ -93,16 +114,18 @@ jobs:
path: |
package.json
src-tauri/tauri.conf.json
src-tauri/tauri.release.conf.json
- id: export_version
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
build-apps:
needs: [check-format, build-test-web, prepare-json-files, check-types]
build-test-apps:
needs: [prepare-json-files]
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-20.04, windows-latest]
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
@ -114,25 +137,32 @@ jobs:
ls -l artifact
cp artifact/package.json package.json
cp artifact/src-tauri/tauri.conf.json src-tauri/tauri.conf.json
cp artifact/src-tauri/tauri.release.conf.json src-tauri/tauri.release.conf.json
- name: install ubuntu system dependencies
if: matrix.os == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libayatana-appindicator3-dev librsvg2-dev
- name: Install ubuntu system dependencies
if: matrix.os == 'ubuntu-latest'
run: >
sudo apt-get update &&
sudo apt-get install -y
libgtk-3-dev
libgtksourceview-3.0-dev
webkit2gtk-4.0
libappindicator3-dev
webkit2gtk-driver
xvfb
- name: Sync node version and setup cache
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn' # Set this to npm, yarn or pnpm.
- run: yarn install
- name: Rust setup
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Rust cache
- name: Setup Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: './src-tauri -> target'
@ -141,24 +171,27 @@ jobs:
with:
workspaces: './src/wasm-lib'
- name: wasm prep
- name: Run build:wasm manually
shell: bash
env:
MODE: ${{ env.BUILD_RELEASE == 'true' && '--release' || '--debug' }}
run: |
mkdir src/wasm-lib/pkg; cd src/wasm-lib
npx wasm-pack build --target web --out-dir pkg
echo "building with ${{ env.MODE }}"
npx wasm-pack build --target web --out-dir pkg ${{ env.MODE }}
cd ../../
cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
- name: Fix format
run: yarn fmt
- name: install apple silicon target mac
- name: Install Universal target (MacOS only)
if: matrix.os == 'macos-latest'
run: |
rustup target add aarch64-apple-darwin
- name: Prepare Windows certificate and variables
if: matrix.os == 'windows-latest'
- name: Prepare certificate and variables (Windows only)
if: ${{ matrix.os == 'windows-latest' && env.BUILD_RELEASE == 'true' }}
run: |
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
cat /d/Certificate_pkcs12.p12
@ -172,8 +205,8 @@ jobs:
echo "C:\Program Files\DigiCert\DigiCert One Signing Manager Tools" >> $GITHUB_PATH
shell: bash
- name: Setup Windows certicate with SSM KSP
if: matrix.os == 'windows-latest'
- name: Setup certicate with SSM KSP (Windows only)
if: ${{ matrix.os == 'windows-latest' && env.BUILD_RELEASE == 'true' }}
run: |
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
msiexec /i smtools-windows-x64.msi /quiet /qn
@ -183,8 +216,17 @@ jobs:
smksp_cert_sync.exe
shell: cmd
- name: Build and sign the app for the current platform
- name: Build the app (debug)
uses: tauri-apps/tauri-action@v0
if: ${{ env.BUILD_RELEASE == 'false' }}
with:
includeRelease: false
includeDebug: true
args: ${{ matrix.os == 'macos-latest' && '--target universal-apple-darwin' || '' }}
- name: Build the app (release) and sign
uses: tauri-apps/tauri-action@v0
if: ${{ env.BUILD_RELEASE == 'true' }}
env:
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
@ -194,17 +236,35 @@ jobs:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
TAURI_CONF_ARGS: "--config ${{ matrix.os == 'windows-latest' && 'src-tauri\\tauri.release.conf.json' || 'src-tauri/tauri.release.conf.json' }}"
with:
args: ${{ matrix.os == 'macos-latest' && '--target universal-apple-darwin' || '' }}
args: "${{ matrix.os == 'macos-latest' && '--target universal-apple-darwin' || '' }} ${{ env.TAURI_CONF_ARGS }}"
- uses: actions/upload-artifact@v3
env:
PREFIX: ${{ matrix.os == 'macos-latest' && 'src-tauri/target/universal-apple-darwin' || 'src-tauri/target' }}
MODE: ${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}
with:
path: ${{ matrix.os == 'macos-latest' && 'src-tauri/target/universal-apple-darwin/release/bundle/*/*' || 'src-tauri/target/release/bundle/*/*' }}
path: "${{ env.PREFIX }}/${{ env.MODE }}/bundle/*/*"
- name: Install tauri-driver for e2e tests (linux only)
if: matrix.os == 'ubuntu-latest'
uses: actions-rs/cargo@v1
with:
command: install
args: tauri-driver
- name: Run e2e tests (linux only)
if: matrix.os == 'ubuntu-latest'
run: xvfb-run yarn test:e2e
env:
MODE: ${{ env.BUILD_RELEASE == 'true' && 'release' || 'debug' }}
publish-apps-release:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
if: ${{ github.event_name == 'release' || github.event_name == 'schedule' }}
needs: [build-test-web, prepare-json-files, build-apps]
needs: [check-format, check-types, check-typos, build-test-web, prepare-json-files, build-test-apps]
env:
VERSION_NO_V: ${{ needs.prepare-json-files.outputs.version }}
VERSION: ${{ github.event_name == 'release' && format('v{0}', needs.prepare-json-files.outputs.version) || needs.prepare-json-files.outputs.version }}

View File

@ -48,7 +48,7 @@ We recommend downloading the latest application binary from [our Releases page](
## Running a development build
First, [install Rust via `rustup`](https://www.rust-lang.org/tools/install). This project uses a lot of Rust compiled to [WASM](https://webassembly.org/) within it. Then, run:
First, [install Rust via `rustup`](https://www.rust-lang.org/tools/install). This project uses a lot of Rust compiled to [WASM](https://webassembly.org/) within it. We always use the latest stable version of Rust, so you may need to run `rustup update stable`. Then, run:
```
yarn install
@ -104,7 +104,7 @@ To spin up up tauri dev, `yarn install` and `yarn build:wasm-dev` need to have b
yarn tauri dev
```
Will spin up the web app before opening up the tauri dev desktop app. Note that it's probably a good idea to close the browser tab that gets opened since at the time of writting they can conflict.
Will spin up the web app before opening up the tauri dev desktop app. Note that it's probably a good idea to close the browser tab that gets opened since at the time of writing they can conflict.
The dev instance automatically opens up the browser devtools which can be disabled by [commenting it out](https://github.com/KittyCAD/modeling-app/blob/main/src-tauri/src/main.rs#L92.)

View File

@ -3812,7 +3812,7 @@
"args": [
{
"name": "data",
"type": "AngeledLineThatIntersectsData",
"type": "AngledLineThatIntersectsData",
"schema": {
"description": "Data for drawing an angled line that intersects with a given line.",
"type": "object",

View File

@ -763,12 +763,12 @@ Draw an angled line that intersects with a given line.
```
angledLineThatIntersects(data: AngeledLineThatIntersectsData, sketch_group: SketchGroup) -> SketchGroup
angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch_group: SketchGroup) -> SketchGroup
```
#### Arguments
* `data`: `AngeledLineThatIntersectsData` - Data for drawing an angled line that intersects with a given line.
* `data`: `AngledLineThatIntersectsData` - Data for drawing an angled line that intersects with a given line.
```
{
// The angle of the line.

View File

@ -0,0 +1,11 @@
describe('Modeling App', () => {
it('open the sign in page', async () => {
const button = await $('#signin')
expect(button).toHaveText('Sign in')
// Workaround for .click(), see https://github.com/tauri-apps/tauri/issues/6541
await button.waitForClickable()
await browser.execute('arguments[0].click();', button)
// TODO: handle auth
})
})

View File

@ -1,33 +1,33 @@
{
"name": "untitled-app",
"version": "0.11.0",
"version": "0.11.3",
"private": true,
"dependencies": {
"@codemirror/autocomplete": "^6.9.0",
"@codemirror/autocomplete": "^6.10.2",
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.13",
"@headlessui/tailwindcss": "^0.2.0",
"@kittycad/lib": "^0.0.43",
"@kittycad/lib": "^0.0.45",
"@lezer/javascript": "^1.4.7",
"@open-rpc/client-js": "^1.8.1",
"@react-hook/resize-observer": "^1.2.6",
"@replit/codemirror-interact": "^6.3.0",
"@sentry/react": "^7.65.0",
"@tauri-apps/api": "^1.5.0",
"@sentry/react": "^7.77.0",
"@tauri-apps/api": "^1.5.1",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.1",
"@ts-stack/markdown": "^1.5.0",
"@types/node": "^16.7.13",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@uiw/react-codemirror": "^4.21.13",
"@uiw/react-codemirror": "^4.21.20",
"@xstate/inspect": "^0.8.0",
"@xstate/react": "^3.2.2",
"crypto-js": "^4.1.1",
"crypto-js": "^4.2.0",
"debounce-promise": "^3.1.2",
"formik": "^2.4.3",
"fuse.js": "^6.6.2",
@ -43,20 +43,20 @@
"react-modal-promise": "^1.0.2",
"react-router-dom": "^6.14.2",
"sketch-helpers": "^0.0.4",
"swr": "^2.0.4",
"swr": "^2.2.2",
"tauri-plugin-fs-extra-api": "https://github.com/tauri-apps/tauri-plugin-fs-extra#v1",
"toml": "^3.0.0",
"ts-node": "^10.9.1",
"typescript": "^4.4.2",
"uuid": "^9.0.0",
"typescript": "^5.2.2",
"uuid": "^9.0.1",
"vitest": "^0.34.6",
"vscode-jsonrpc": "^8.1.0",
"vscode-languageserver-protocol": "^3.17.3",
"vscode-languageserver-protocol": "^3.17.5",
"wasm-pack": "^0.12.1",
"web-vitals": "^2.1.0",
"web-vitals": "^3.5.0",
"ws": "^8.13.0",
"xstate": "^4.38.2",
"zustand": "^4.1.4"
"zustand": "^4.4.5"
},
"scripts": {
"start": "vite",
@ -69,6 +69,7 @@
"test:nowatch": "vitest run --mode development",
"test:rust": "(cd src/wasm-lib && cargo test --all && cargo clippy --all --tests --benches)",
"test:cov": "vitest run --coverage --mode development",
"test:e2e": "wdio run wdio.conf.js",
"simpleserver:ci": "yarn pretest && http-server ./public --cors -p 3000 &",
"simpleserver": "yarn pretest && http-server ./public --cors -p 3000",
"fmt": "prettier --write ./src",
@ -102,18 +103,18 @@
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@babel/preset-env": "^7.22.9",
"@tauri-apps/cli": "^1.5.0",
"@tauri-apps/cli": "^1.5.6",
"@types/crypto-js": "^4.1.1",
"@types/debounce-promise": "^3.1.6",
"@types/debounce-promise": "^3.1.8",
"@types/isomorphic-fetch": "^0.0.36",
"@types/react-modal": "^3.16.0",
"@types/uuid": "^9.0.1",
"@types/uuid": "^9.0.4",
"@types/wicg-file-system-access": "^2020.9.6",
"@types/ws": "^8.5.5",
"@vitejs/plugin-react": "^4.0.3",
"@vitest/coverage-istanbul": "^0.34.1",
"autoprefixer": "^10.4.13",
"eslint": "^8.44.0",
"eslint": "^8.53.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-css-modules": "^2.11.0",
"happy-dom": "^10.8.0",
@ -122,9 +123,13 @@
"prettier": "^2.8.0",
"setimmediate": "^1.0.5",
"tailwindcss": "^3.2.4",
"vite": "^4.4.3",
"vite": "^4.5.0",
"vite-plugin-eslint": "^1.8.1",
"vite-tsconfig-paths": "^4.2.0",
"yarn": "^1.22.19"
"vite-tsconfig-paths": "^4.2.1",
"yarn": "^1.22.19",
"@wdio/cli": "^7.7.3",
"@wdio/local-runner": "^7.7.3",
"@wdio/mocha-framework": "^7.7.3",
"@wdio/spec-reporter": "^7.7.3"
}
}

69
src-tauri/Cargo.lock generated
View File

@ -122,6 +122,12 @@ dependencies = [
"system-deps 6.1.0",
]
[[package]]
name = "atomic"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
[[package]]
name = "autocfg"
version = "1.1.0"
@ -1567,7 +1573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi 0.3.1",
"rustix 0.38.13",
"rustix 0.38.21",
"windows-sys 0.48.0",
]
@ -1658,9 +1664,9 @@ dependencies = [
[[package]]
name = "kittycad"
version = "0.2.33"
version = "0.2.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d341a81a4dfef43460d395c87d86c17e24affb96db0e7f4a35e8688f0e092344"
checksum = "874914cd40bfd43674406683bb3f0924d41780698a4ade96f2e180a73678bdd1"
dependencies = [
"anyhow",
"async-trait",
@ -1759,9 +1765,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "linux-raw-sys"
version = "0.4.7"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
[[package]]
name = "lock_api"
@ -2833,9 +2839,9 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "reqwest"
version = "0.11.20"
version = "0.11.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
dependencies = [
"base64 0.21.2",
"bytes",
@ -2862,6 +2868,7 @@ dependencies = [
"serde",
"serde_json",
"serde_urlencoded",
"system-configuration",
"tokio",
"tokio-native-tls",
"tokio-rustls",
@ -3011,9 +3018,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.37.19"
version = "0.37.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
dependencies = [
"bitflags 1.3.2",
"errno",
@ -3025,14 +3032,14 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.13"
version = "0.38.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys 0.4.7",
"linux-raw-sys 0.4.10",
"windows-sys 0.48.0",
]
@ -3208,9 +3215,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.189"
version = "1.0.192"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537"
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
dependencies = [
"serde_derive",
]
@ -3226,9 +3233,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.189"
version = "1.0.192"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5"
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
dependencies = [
"proc-macro2",
"quote",
@ -3248,9 +3255,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.107"
version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [
"itoa 1.0.6",
"ryu",
@ -3600,6 +3607,27 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "system-configuration"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "system-deps"
version = "5.0.0"
@ -3828,7 +3856,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-fs-extra"
version = "0.0.0"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#9b20f28d747f6ec3ba5a80bfcd5edc1d573b4c90"
source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#6865299149ffd183365e3ff291acf3edac78ca61"
dependencies = [
"log",
"serde",
@ -3927,7 +3955,7 @@ dependencies = [
"cfg-if",
"fastrand",
"redox_syscall 0.3.5",
"rustix 0.37.19",
"rustix 0.37.27",
"windows-sys 0.45.0",
]
@ -4292,6 +4320,7 @@ version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
dependencies = [
"atomic",
"getrandom 0.2.9",
"serde",
]

View File

@ -4,7 +4,7 @@ version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
repository = "https://github.com/KittyCAD/modeling-app"
default-run = "app"
edition = "2021"
rust-version = "1.60"
@ -16,7 +16,7 @@ tauri-build = { version = "1.5.0", features = [] }
[dependencies]
anyhow = "1"
kittycad = "0.2.33"
kittycad = "0.2.41"
oauth2 = "4.4.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

View File

@ -68,7 +68,7 @@ async fn login(app: tauri::AppHandle, host: &str) -> Result<String, InvokeError>
};
// Open the system browser with the auth_uri.
// We do this in the browser and not a seperate window because we want 1password and
// We do this in the browser and not a separate window because we want 1password and
// other crap to work well.
tauri::api::shell::open(&app.shell_scope(), auth_uri.secret(), None)
.map_err(|e| InvokeError::from_anyhow(e.into()))?;
@ -129,10 +129,10 @@ async fn get_user(
fn main() {
tauri::Builder::default()
.setup(|app| {
.setup(|_app| {
#[cfg(debug_assertions)] // only include this code on debug builds
{
let window = app.get_window("main").unwrap();
let window = _app.get_window("main").unwrap();
// comment out the below if you don't devtools to open everytime.
// it's useful because otherwise devtools shuts everytime rust code changes.
window.open_devtools();

View File

@ -8,7 +8,7 @@
},
"package": {
"productName": "kittycad-modeling",
"version": "0.11.0"
"version": "0.11.3"
},
"tauri": {
"allowlist": {
@ -72,23 +72,13 @@
},
"resources": [],
"shortDescription": "",
"targets": "all",
"windows": {
"certificateThumbprint": "F4C9A52FF7BC26EE5E054946F6B11DEEA94C748D",
"digestAlgorithm": "sha256",
"timestampUrl": "http://timestamp.digicert.com"
}
"targets": "all"
},
"security": {
"csp": null
},
"updater": {
"active": true,
"endpoints": [
"https://dl.kittycad.io/releases/modeling-app/last_update.json"
],
"dialog": true,
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEUzNzA4MjBEQjFBRTY4NzYKUldSMmFLNnhEWUp3NCtsT21Jd05wQktOaGVkOVp6MUFma0hNTDRDSnI2RkJJTEZOWG1ncFhqcU8K"
"active": false
},
"windows": [
{

View File

@ -1,7 +1,6 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"package": {
"productName": "KittyCAD Modeling"
}
}
}

View File

@ -0,0 +1,21 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"tauri": {
"updater": {
"active": true,
"endpoints": [
"https://dl.kittycad.io/releases/modeling-app/last_update.json"
],
"dialog": true,
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEUzNzA4MjBEQjFBRTY4NzYKUldSMmFLNnhEWUp3NCtsT21Jd05wQktOaGVkOVp6MUFma0hNTDRDSnI2RkJJTEZOWG1ncFhqcU8K"
},
"bundle": {
"identifier": "io.kittycad.modeling-app",
"windows": {
"certificateThumbprint": "F4C9A52FF7BC26EE5E054946F6B11DEEA94C748D",
"digestAlgorithm": "sha256",
"timestampUrl": "http://timestamp.digicert.com"
}
}
}
}

View File

@ -1,7 +1,6 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"package": {
"productName": "KittyCAD Modeling"
}
}
}

View File

@ -1,4 +1,4 @@
import { useEffect, useCallback, MouseEventHandler } from 'react'
import { useCallback, MouseEventHandler } from 'react'
import { DebugPanel } from './components/DebugPanel'
import { v4 as uuidv4 } from 'uuid'
import { PaneType, useStore } from './useStore'
@ -19,7 +19,6 @@ import {
} from '@fortawesome/free-solid-svg-icons'
import { useHotkeys } from 'react-hotkeys-hook'
import { getNormalisedCoordinates } from './lib/utils'
import { isTauri } from './lib/isTauri'
import { useLoaderData } from 'react-router-dom'
import { IndexLoaderData } from './Router'
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
@ -31,11 +30,10 @@ import { TextEditor } from 'components/TextEditor'
import { Themes, getSystemTheme } from 'lib/theme'
import { useEngineConnectionSubscriptions } from 'hooks/useEngineConnectionSubscriptions'
import { engineCommandManager } from './lang/std/engineConnection'
import { kclManager } from 'lang/KclSinglton'
import { useModelingContext } from 'hooks/useModelingContext'
export function App() {
const { code: loadedCode, project, file } = useLoaderData() as IndexLoaderData
const { project, file } = useLoaderData() as IndexLoaderData
useHotKeyListener()
const {
@ -82,26 +80,6 @@ export function App() {
? 'opacity-40'
: ''
// Use file code loaded from disk
// on mount, and overwrite any locally-stored code
useEffect(() => {
if (isTauri() && loadedCode !== null) {
if (kclManager.engineCommandManager.engineConnection?.isReady()) {
// If the engine is ready, promptly execute the loaded code
kclManager.setCodeAndExecute(loadedCode)
} else {
// Otherwise, just set the code and wait for the connection to complete
kclManager.setCode(loadedCode)
}
}
return () => {
// Clear code on unmount if in desktop app
if (isTauri()) {
kclManager.setCode('')
}
}
}, [loadedCode])
useEngineConnectionSubscriptions()
const debounceSocketSend = throttle<EngineCommand>((message) => {
@ -248,7 +226,7 @@ export function App() {
<Stream className="absolute inset-0 z-0" />
{showDebugPanel && (
<DebugPanel
title="Debug"
title="Debug (AST Explorer)"
className={
'transition-opacity transition-duration-75 ' +
paneOpacity +

View File

@ -42,7 +42,7 @@ import CommandBarProvider from 'components/CommandBar'
import { TEST, VITE_KC_SENTRY_DSN } from './env'
import * as Sentry from '@sentry/react'
import ModelingMachineProvider from 'components/ModelingMachineProvider'
import { KclContextProvider } from 'lang/KclSinglton'
import { KclContextProvider, kclManager } from 'lang/KclSinglton'
import FileMachineProvider from 'components/FileMachineProvider'
import { sep } from '@tauri-apps/api/path'
@ -207,6 +207,7 @@ const router = createBrowserRouter(
projectPath + sep + PROJECT_ENTRYPOINT
)
const children = await readDir(projectPath, { recursive: true })
kclManager.setCodeAndExecute(code, false)
return {
code,

View File

@ -1,4 +1,3 @@
import { ToolTip } from './useStore'
import { Fragment, WheelEvent, useRef, useMemo } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faSearch, faX } from '@fortawesome/free-solid-svg-icons'
@ -15,23 +14,6 @@ export const sketchButtonClassnames = {
icon: 'text-fern-20 h-auto group-hover:text-fern-10 hover:text-fern-10 dark:text-chalkboard-100 dark:group-hover:text-chalkboard-100 dark:hover:text-chalkboard-100 group-disabled:bg-chalkboard-60 hover:group-disabled:text-inherit',
}
const sketchFnLabels: Record<ToolTip | 'sketch_line' | 'move', string> = {
sketch_line: 'Line',
line: 'Line',
move: 'Move',
angledLine: 'Angled Line',
angledLineThatIntersects: 'Angled Line That Intersects',
angledLineOfXLength: 'Angled Line Of X Length',
angledLineOfYLength: 'Angled Line Of Y Length',
angledLineToX: 'Angled Line To X',
angledLineToY: 'Angled Line To Y',
lineTo: 'Line to Point',
xLine: 'Horizontal Line',
yLine: 'Vertical Line',
xLineTo: 'Horizontal Line to Point',
yLineTo: 'Vertical Line to Point',
}
export const Toolbar = () => {
const { state, send, context } = useModelingContext()
const toolbarButtonsRef = useRef<HTMLSpanElement>(null)

View File

@ -184,6 +184,7 @@ function DisplayObj({
</li>
)
}
return null
})}
</ul>
</span>

View File

@ -1,5 +1,5 @@
import { useEffect, useState, useRef } from 'react'
import { parse, BinaryPart, Value, executor } from '../lang/wasm'
import { parse, BinaryPart, Value } from '../lang/wasm'
import {
createIdentifier,
createLiteral,
@ -10,6 +10,7 @@ import { findAllPreviousVariables, PrevVariable } from '../lang/queryAst'
import { engineCommandManager } from '../lang/std/engineConnection'
import { kclManager, useKclContext } from 'lang/KclSinglton'
import { useModelingContext } from 'hooks/useModelingContext'
import { executeAst } from 'useStore'
export const AvailableVars = ({
onVarClick,
@ -130,27 +131,29 @@ export function useCalc({
if (!programMemory || !selectionRange) return
const varInfo = findAllPreviousVariables(
kclManager.ast,
programMemory,
kclManager.programMemory,
selectionRange
)
setAvailableVarInfo(varInfo)
}, [kclManager.ast, programMemory, selectionRange])
}, [kclManager.ast, kclManager.programMemory, selectionRange])
useEffect(() => {
try {
const code = `const __result__ = ${value}\nshow(__result__)`
const code = `const __result__ = ${value}`
const ast = parse(code)
const _programMem: any = { root: {}, return: null }
availableVarInfo.variables.forEach(({ key, value }) => {
_programMem.root[key] = { type: 'userVal', value, __meta: [] }
})
executor(
executeAst({
ast,
_programMem,
engineCommandManager,
kclManager.defaultPlanes
).then((programMemory) => {
defaultPlanes: kclManager.defaultPlanes,
useFakeExecutor: true,
programMemoryOverride: JSON.parse(
JSON.stringify(kclManager.programMemory)
),
}).then(({ programMemory }) => {
const resultDeclaration = ast.body.find(
(a) =>
a.type === 'VariableDeclaration' &&
@ -167,7 +170,7 @@ export function useCalc({
setCalcResult('NAN')
setValueNode(null)
}
}, [value])
}, [value, availableVarInfo])
return {
valueNode,
@ -212,7 +215,10 @@ export const CreateNewVariable = ({
}) => {
return (
<>
<label htmlFor="create-new-variable" className="block mt-3 font-mono">
<label
htmlFor="create-new-variable"
className="block mt-3 font-mono text-gray-900"
>
Create new variable
</label>
<div className="mt-1 flex gap-2 items-center">
@ -223,6 +229,7 @@ export const CreateNewVariable = ({
onChange={(e) => {
setShouldCreateVariable(e.target.checked)
}}
className="bg-white text-gray-900"
/>
)}
<input

View File

@ -1,29 +1,7 @@
import { CollapsiblePanel, CollapsiblePanelProps } from './CollapsiblePanel'
import { v4 as uuidv4 } from 'uuid'
import { EngineCommand } from '../lang/std/engineConnection'
import { useState } from 'react'
import { ActionButton } from '../components/ActionButton'
import { faCheck } from '@fortawesome/free-solid-svg-icons'
import { isReducedMotion } from 'lang/util'
import { AstExplorer } from './AstExplorer'
import { engineCommandManager } from '../lang/std/engineConnection'
type SketchModeCmd = Extract<
Extract<EngineCommand, { type: 'modeling_cmd_req' }>['cmd'],
{ type: 'default_camera_enable_sketch_mode' }
>
export const DebugPanel = ({ className, ...props }: CollapsiblePanelProps) => {
const [sketchModeCmd, setSketchModeCmd] = useState<SketchModeCmd>({
type: 'default_camera_enable_sketch_mode',
origin: { x: 0, y: 0, z: 0 },
x_axis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 1, z: 0 },
distance_to_plane: 100,
ortho: true,
animated: !isReducedMotion(),
})
if (!sketchModeCmd) return null
return (
<CollapsiblePanel
{...props}
@ -34,67 +12,6 @@ export const DebugPanel = ({ className, ...props }: CollapsiblePanelProps) => {
style={{ maxHeight: 'calc(100% - 3rem - 1.25rem - 1.25rem)' }}
>
<section className="p-4 flex flex-col gap-4">
<Xyz
onChange={setSketchModeCmd}
pointKey="origin"
data={sketchModeCmd}
/>
<Xyz
onChange={setSketchModeCmd}
pointKey="x_axis"
data={sketchModeCmd}
/>
<Xyz
onChange={setSketchModeCmd}
pointKey="y_axis"
data={sketchModeCmd}
/>
<div className="flex">
<div className="pr-4">distance_to_plane</div>
<input
className="w-16 dark:bg-chalkboard-90"
type="number"
value={sketchModeCmd.distance_to_plane}
onChange={({ target }) => {
setSketchModeCmd({
...sketchModeCmd,
distance_to_plane: Number(target.value),
})
}}
/>
<div className="pr-4">ortho</div>
<input
className="w-16"
type="checkbox"
checked={sketchModeCmd.ortho}
onChange={(a) =>
setSketchModeCmd({
...sketchModeCmd,
ortho: a.target.checked,
})
}
/>
</div>
<ActionButton
Element="button"
onClick={() => {
engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd: sketchModeCmd,
cmd_id: uuidv4(),
})
}}
className="hover:border-succeed-50"
icon={{
icon: faCheck,
bgClassName:
'bg-succeed-80 group-hover:bg-succeed-70 hover:bg-succeed-70',
iconClassName:
'text-succeed-20 group-hover:text-succeed-10 hover:text-succeed-10',
}}
>
Send sketch mode command
</ActionButton>
<div style={{ height: '400px' }} className="overflow-y-auto">
<AstExplorer />
</div>
@ -102,41 +19,3 @@ export const DebugPanel = ({ className, ...props }: CollapsiblePanelProps) => {
</CollapsiblePanel>
)
}
const Xyz = ({
pointKey,
data,
onChange,
}: {
pointKey: 'origin' | 'y_axis' | 'x_axis'
data: SketchModeCmd
onChange: (a: SketchModeCmd) => void
}) => {
if (!data) return null
return (
<div className="flex">
<div className="pr-4">{pointKey}</div>
{Object.entries(data[pointKey]).map(([axis, val]) => {
return (
<div key={axis} className="flex">
<div className="w-4">{axis}</div>
<input
className="w-16 dark:bg-chalkboard-90"
type="number"
value={val}
onChange={({ target }) => {
onChange({
...data,
[pointKey]: {
...data[pointKey],
[axis]: Number(target.value),
},
})
}}
/>
</div>
)
})}
</div>
)
}

View File

@ -2,7 +2,7 @@ import { IndexLoaderData, paths } from 'Router'
import { ActionButton } from './ActionButton'
import Tooltip from './Tooltip'
import { FileEntry } from '@tauri-apps/api/fs'
import { Dispatch, useEffect, useRef, useState } from 'react'
import { Dispatch, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Dialog, Disclosure } from '@headlessui/react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
@ -163,7 +163,6 @@ const FileTreeItem = ({
function openFile() {
if (fileOrDir.children !== undefined) return // Don't open directories
kclManager.setCode('')
navigate(`${paths.FILE}/${encodeURIComponent(fileOrDir.path)}`)
closePanel()
}

View File

@ -20,7 +20,6 @@ import {
recast,
parse,
Program,
VariableDeclarator,
PipeExpression,
CallExpression,
} from 'lang/wasm'
@ -148,7 +147,7 @@ export const ModelingMachineProvider = ({
engineCommandManager.artifactMap[sketchEnginePathId] = {
type: 'result',
range: [startProfileAtCallExp.start, startProfileAtCallExp.end],
commandType: 'extend_path',
commandType: 'start_path',
data: null,
raw: {} as any,
}

View File

@ -108,7 +108,7 @@ export const SetAngleLengthModal = ({
</label>
<div className="mt-1 flex">
<button
className="border border-gray-300 px-2"
className="border border-gray-300 px-2 text-gray-900"
onClick={() => setSign(-sign)}
>
{sign > 0 ? '+' : '-'}
@ -118,7 +118,7 @@ export const SetAngleLengthModal = ({
type="text"
name="val"
id="val"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono pl-1"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono pl-1 text-gray-900"
value={value}
onChange={(e) => {
setValue(e.target.value)

View File

@ -87,7 +87,7 @@ export const GetInfoModal = ({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-2xl bg-white/90 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900"
@ -109,7 +109,7 @@ export const GetInfoModal = ({
</label>
<div className="mt-1 flex">
<button
className="border border-gray-300 px-2 mr-1"
className="border border-gray-400 px-2 mr-1 text-gray-900"
onClick={() => setSign(-sign)}
>
{sign > 0 ? '+' : '-'}
@ -119,7 +119,7 @@ export const GetInfoModal = ({
name="val"
id="val"
ref={inputRef}
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm text-gray-900 border-gray-300 rounded-md font-mono"
value={value}
onChange={(e) => {
setValue(e.target.value)
@ -139,7 +139,7 @@ export const GetInfoModal = ({
name="segName"
id="segName"
disabled={!isSegNameEditable}
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md font-mono"
className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm text-gray-900 border-gray-300 rounded-md font-mono"
value={segName}
onChange={(e) => {
setSegName(e.target.value)

View File

@ -14,7 +14,7 @@ import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
import { CameraDragInteractionType_type } from '@kittycad/lib/dist/types/src/models'
import { Models } from '@kittycad/lib'
import { getNodeFromPath } from 'lang/queryAst'
import { VariableDeclarator, recast, parse, CallExpression } from 'lang/wasm'
import { VariableDeclarator, recast, CallExpression } from 'lang/wasm'
import { engineCommandManager } from '../lang/std/engineConnection'
import { useModelingContext } from 'hooks/useModelingContext'
import { kclManager, useKclContext } from 'lang/KclSinglton'
@ -267,11 +267,11 @@ export const Stream = ({ className = '' }) => {
}
engineCommandManager.sendSceneCommand(command).then(async () => {
if (!context.sketchPathToNode) return
const varDec = getNodeFromPath<VariableDeclarator>(
getNodeFromPath<VariableDeclarator>(
kclManager.ast,
context.sketchPathToNode,
'VariableDeclarator'
).node
)
// Get the current plane string for plane we are on.
let currentPlaneString = ''
if (context.sketchPlaneId === kclManager.getPlaneId('xy')) {
@ -342,7 +342,8 @@ export const Stream = ({ className = '' }) => {
// update artifact map ranges now that we have updated the ast.
code = recast(modded.modifiedAst)
const astWithCurrentRanges = parse(code)
const astWithCurrentRanges = kclManager.safeParse(code)
if (!astWithCurrentRanges) return
const updateNode = getNodeFromPath<CallExpression>(
astWithCurrentRanges,
modded.pathToNode

View File

@ -17,15 +17,7 @@ import { useStore } from 'useStore'
import { processCodeMirrorRanges } from 'lib/selections'
import { LanguageServerClient } from 'editor/lsp'
import kclLanguage from 'editor/lsp/language'
import { isTauri } from 'lib/isTauri'
import { useParams } from 'react-router-dom'
import { writeTextFile } from '@tauri-apps/api/fs'
import { toast } from 'react-hot-toast'
import {
EditorView,
addLineHighlight,
lineHighlightField,
} from 'editor/highlightextension'
import { EditorView, lineHighlightField } from 'editor/highlightextension'
import { roundOff } from 'lib/utils'
import { kclErrToDiagnostic } from 'lang/errors'
import { CSSRuleObject } from 'tailwindcss/types/config'
@ -50,7 +42,6 @@ export const TextEditor = ({
}: {
theme: Themes.Light | Themes.Dark
}) => {
const pathParams = useParams()
const { editorView, isLSPServerReady, setEditorView, setIsLSPServerReady } =
useStore((s) => ({
editorView: s.editorView,
@ -92,7 +83,7 @@ export const TextEditor = ({
// Here we initialize the plugin which will start the client.
// When we have multi-file support the name of the file will be a dep of
// this use memo, as well as the directory structure, which I think is
// a good setup becuase it will restart the client but not the server :)
// a good setup because it will restart the client but not the server :)
// We do not want to restart the server, its just wasteful.
const kclLSP = useMemo(() => {
let plugin = null
@ -113,18 +104,6 @@ export const TextEditor = ({
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
const onChange = (newCode: string) => {
kclManager.setCodeAndExecute(newCode)
if (isTauri() && pathParams.id) {
// Save the file to disk
// Note that PROJECT_ENTRYPOINT is hardcoded until we support multiple files
writeTextFile(pathParams.id, newCode).catch((err) => {
// TODO: add Sentry per GH issue #254 (https://github.com/KittyCAD/modeling-app/issues/254)
console.error('error saving file', err)
toast.error('Error saving file, please check file permissions')
})
}
if (editorView) {
editorView?.dispatch({ effects: addLineHighlight.of([0, 0]) })
}
} //, []);
const onUpdate = (viewUpdate: ViewUpdate) => {
if (!editorView) {

View File

@ -69,7 +69,7 @@ export function applyConstraintEqualLength({
modifiedAst: Program
pathToNodeMap: PathToNodeMap
} {
const { enabled, transforms } = setEqualLengthInfo({ selectionRanges })
const { transforms } = setEqualLengthInfo({ selectionRanges })
const { modifiedAst, pathToNodeMap } = transformSecondarySketchLinesTagFirst({
ast: kclManager.ast,
selectionRanges,

View File

@ -108,6 +108,7 @@ export default class Client extends jsrpc.JSONRPCServerAndClient {
break
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
messageString += message
return
})

View File

@ -26,7 +26,7 @@ export class Codec {
}
}
// FIXME: tracing effiency
// FIXME: tracing efficiency
export class IntoServer
extends Queue<Uint8Array>
implements AsyncGenerator<Uint8Array, never, void>

View File

@ -2,8 +2,6 @@ import { useEffect } from 'react'
import { useStore } from 'useStore'
import { engineCommandManager } from '../lang/std/engineConnection'
import { useModelingContext } from './useModelingContext'
import { v4 as uuidv4 } from 'uuid'
import { SourceRange } from 'lang/wasm'
import { getEventForSelectWithPoint } from 'lib/selections'
export function useEngineConnectionSubscriptions() {
@ -13,11 +11,6 @@ export function useEngineConnectionSubscriptions() {
}))
const { send, context } = useModelingContext()
interface RangeAndId {
id: string
range: SourceRange
}
useEffect(() => {
if (!engineCommandManager) return
@ -42,7 +35,7 @@ export function useEngineConnectionSubscriptions() {
const event = await getEventForSelectWithPoint(engineEvent, {
sketchEnginePathId: context.sketchEnginePathId,
})
send(event)
event && send(event)
},
})
return () => {

View File

@ -1,5 +1,5 @@
import { useLayoutEffect, useEffect, useRef } from 'react'
import { _executor, parse } from '../lang/wasm'
import { parse } from '../lang/wasm'
import { useStore } from '../useStore'
import { engineCommandManager } from '../lang/std/engineConnection'
import { deferExecution } from 'lib/utils'
@ -26,10 +26,6 @@ export function useSetupEngineManager(
const hasSetNonZeroDimensions = useRef<boolean>(false)
useEffect(() => {
kclManager.executeCode()
}, [])
useLayoutEffect(() => {
// Load the engine command manager once with the initial width and height,
// then we do not want to reload it.

View File

@ -18,7 +18,11 @@ import { bracket } from 'lib/exampleKcl'
import { createContext, useContext, useEffect, useState } from 'react'
import { getNodeFromPath } from './queryAst'
import { IndexLoaderData } from 'Router'
import { useLoaderData } from 'react-router-dom'
import { Params, useLoaderData } from 'react-router-dom'
import { isTauri } from 'lib/isTauri'
import { writeTextFile } from '@tauri-apps/api/fs'
import { toast } from 'react-hot-toast'
import { useParams } from 'react-router-dom'
const PERSIST_CODE_TOKEN = 'persistCode'
@ -41,10 +45,20 @@ class KclManager {
private _kclErrors: KCLError[] = []
private _isExecuting = false
private _wasmInitFailed = true
private _params: Params<string> = {}
engineCommandManager: EngineCommandManager
private _defferer = deferExecution((code: string) => {
const ast = parse(code)
const ast = this.safeParse(code)
if (!ast) return
try {
const fmtAndStringify = (ast: Program) =>
JSON.stringify(parse(recast(ast)))
const isAstTheSame = fmtAndStringify(ast) === fmtAndStringify(this._ast)
if (isAstTheSame) return
} catch (e) {
console.error(e)
}
this.executeAst(ast)
}, 600)
@ -71,6 +85,21 @@ class KclManager {
set code(code) {
this._code = code
this._codeCallBack(code)
if (isTauri()) {
setTimeout(() => {
// Wait one event loop to give a chance for params to be set
// Save the file to disk
// Note that PROJECT_ENTRYPOINT is hardcoded until we support multiple files
this._params.id &&
writeTextFile(this._params.id, code).catch((err) => {
// TODO: add Sentry per GH issue #254 (https://github.com/KittyCAD/modeling-app/issues/254)
console.error('error saving file', err)
toast.error('Error saving file, please check file permissions')
})
})
} else {
localStorage.setItem(PERSIST_CODE_TOKEN, code)
}
}
get programMemory() {
@ -117,10 +146,19 @@ class KclManager {
this._wasmInitFailedCallback(wasmInitFailed)
}
setParams(params: Params<string>) {
this._params = params
}
constructor(engineCommandManager: EngineCommandManager) {
this.engineCommandManager = engineCommandManager
if (isTauri()) {
this.code = ''
return
}
const storedCode = localStorage.getItem(PERSIST_CODE_TOKEN)
// TODO #819 remove zustand persistance logic in a few months
// TODO #819 remove zustand persistence logic in a few months
// short term migration, shouldn't make a difference for tauri app users
// anyway since that's filesystem based.
const zustandStore = JSON.parse(localStorage.getItem('store') || '{}')
@ -130,6 +168,7 @@ class KclManager {
zustandStore.state.code = ''
localStorage.setItem('store', JSON.stringify(zustandStore))
} else if (storedCode === null) {
console.log('stored brack thing')
this.code = bracket
} else {
this.code = storedCode
@ -164,6 +203,21 @@ class KclManager {
this._executeCallback = callback
}
safeParse(code: string): Program | null {
try {
const ast = parse(code)
this.kclErrors = []
return ast
} catch (e) {
console.error('error parsing code', e)
if (e instanceof KCLError) {
this.kclErrors = [e]
if (e.msg === 'file is empty') engineCommandManager.endSession()
}
return null
}
}
async ensureWasmInit() {
try {
await initPromise
@ -184,20 +238,20 @@ class KclManager {
defaultPlanes: this.defaultPlanes,
})
this.isExecuting = false
this._logs = logs
this._kclErrors = errors
this._programMemory = programMemory
this._ast = { ...ast }
this.logs = logs
this.kclErrors = errors
this.programMemory = programMemory
this.ast = { ...ast }
if (updateCode) {
this._code = recast(ast)
this._codeCallBack(this._code)
this.code = recast(ast)
}
this._executeCallback()
}
async executeAstMock(ast: Program = this._ast, updateCode = false) {
await this.ensureWasmInit()
const newCode = recast(ast)
const newAst = parse(newCode)
const newAst = this.safeParse(newCode)
if (!newAst) return
await this?.engineCommandManager?.waitForReady
if (updateCode) {
this.setCode(recast(ast))
@ -233,13 +287,17 @@ class KclManager {
this.ast = ast
if (code) this.code = code
}
setCode(code: string) {
setCode(code: string, shouldWriteFile = true) {
if (shouldWriteFile) {
// use the normal code setter
this.code = code
return
}
this._code = code
this._codeCallBack(code)
localStorage.setItem(PERSIST_CODE_TOKEN, code)
}
setCodeAndExecute(code: string) {
this.setCode(code)
setCodeAndExecute(code: string, shouldWriteFile = true) {
this.setCode(code, shouldWriteFile)
if (code.trim()) {
this._defferer(code)
return
@ -260,9 +318,11 @@ class KclManager {
this.engineCommandManager.endSession()
}
format() {
this.code = recast(parse(kclManager.code))
const ast = this.safeParse(this.code)
if (!ast) return
this.code = recast(ast)
}
// There's overlapping resposibility between updateAst and executeAst.
// There's overlapping responsibility between updateAst and executeAst.
// updateAst was added as it was used a lot before xState migration so makes the port easier.
// but should probably have think about which of the function to keep
async updateAst(
@ -270,15 +330,13 @@ class KclManager {
execute: boolean,
optionalParams?: {
focusPath?: PathToNode
callBack?: (ast: Program) => void
}
): Promise<Selections | null> {
const newCode = recast(ast)
const astWithUpdatedSource = parse(newCode)
optionalParams?.callBack?.(astWithUpdatedSource)
const astWithUpdatedSource = this.safeParse(newCode)
if (!astWithUpdatedSource) return null
let returnVal: Selections | null = null
this.code = newCode
if (optionalParams?.focusPath) {
const { node } = getNodeFromPath<any>(
astWithUpdatedSource,
@ -299,12 +357,12 @@ class KclManager {
if (execute) {
// Call execute on the set ast.
await this.executeAst(astWithUpdatedSource)
await this.executeAst(astWithUpdatedSource, true)
} else {
// When we don't re-execute, we still want to update the program
// memory with the new ast. So we will hit the mock executor
// instead.
await this.executeAstMock(astWithUpdatedSource)
await this.executeAstMock(astWithUpdatedSource, true)
}
return returnVal
}
@ -369,6 +427,11 @@ export function KclContextProvider({
setWasmInitFailed,
})
}, [])
const params = useParams()
useEffect(() => {
kclManager.setParams(params)
}, [params])
return (
<KclContext.Provider
value={{

View File

@ -331,9 +331,6 @@ const myVar = funcN(1, 2)`
raw: '2',
},
],
function: {
type: 'InMemory',
},
optional: false,
},
},
@ -403,7 +400,6 @@ describe('testing pipe operator special', () => {
],
},
],
function: expect.any(Object),
optional: false,
},
{
@ -440,7 +436,6 @@ describe('testing pipe operator special', () => {
},
{ type: 'PipeSubstitution', start: 59, end: 60 },
],
function: expect.any(Object),
optional: false,
},
{
@ -513,7 +508,6 @@ describe('testing pipe operator special', () => {
},
{ type: 'PipeSubstitution', start: 105, end: 106 },
],
function: expect.any(Object),
optional: false,
},
{
@ -550,7 +544,6 @@ describe('testing pipe operator special', () => {
},
{ type: 'PipeSubstitution', start: 128, end: 129 },
],
function: expect.any(Object),
optional: false,
},
{
@ -573,9 +566,6 @@ describe('testing pipe operator special', () => {
},
{ type: 'PipeSubstitution', start: 143, end: 144 },
],
function: {
type: 'InMemory',
},
optional: false,
},
],
@ -655,9 +645,6 @@ describe('testing pipe operator special', () => {
end: 35,
},
],
function: {
type: 'InMemory',
},
optional: false,
},
],
@ -1345,7 +1332,7 @@ describe('nests binary expressions correctly', () => {
],
})
})
it('should nest properly with two opperators of equal precedence', () => {
it('should nest properly with two operators of equal precedence', () => {
const code = `const yo = 1 + 2 - 3`
const { body } = parse(code)
expect((body[0] as any).declarations[0].init).toEqual({
@ -1382,7 +1369,7 @@ describe('nests binary expressions correctly', () => {
},
})
})
it('should nest properly with two opperators of equal (but higher) precedence', () => {
it('should nest properly with two operators of equal (but higher) precedence', () => {
const code = `const yo = 1 * 2 / 3`
const { body } = parse(code)
expect((body[0] as any).declarations[0].init).toEqual({
@ -1443,7 +1430,7 @@ describe('nests binary expressions correctly', () => {
type: 'BinaryExpression',
operator: '*',
start: 15,
end: 26,
end: 25,
left: { type: 'Literal', value: 2, raw: '2', start: 15, end: 16 },
right: {
type: 'BinaryExpression',
@ -1567,7 +1554,6 @@ describe('test UnaryExpression', () => {
{ type: 'Literal', start: 19, end: 20, value: 4, raw: '4' },
{ type: 'Literal', start: 22, end: 25, value: 100, raw: '100' },
],
function: expect.any(Object),
optional: false,
},
})
@ -1601,12 +1587,10 @@ describe('testing nested call expressions', () => {
{ type: 'Literal', start: 34, end: 35, value: 5, raw: '5' },
{ type: 'Literal', start: 37, end: 38, value: 3, raw: '3' },
],
function: expect.any(Object),
optional: false,
},
},
],
function: expect.any(Object),
optional: false,
})
})
@ -1638,7 +1622,6 @@ describe('should recognise callExpresions in binaryExpressions', () => {
},
{ type: 'PipeSubstitution', start: 25, end: 26 },
],
function: expect.any(Object),
optional: false,
},
right: { type: 'Literal', value: 1, raw: '1', start: 30, end: 31 },

View File

@ -18,6 +18,20 @@ export class KCLError {
}
}
export class KCLLexicalError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('lexical', msg, sourceRanges)
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
}
}
export class KCLInternalError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('internal', msg, sourceRanges)
Object.setPrototypeOf(this, KCLSyntaxError.prototype)
}
}
export class KCLSyntaxError extends KCLError {
constructor(msg: string, sourceRanges: [number, number][]) {
super('syntax', msg, sourceRanges)

View File

@ -310,7 +310,7 @@ export function extrudeSketch(
const name = findUniqueName(node, 'part')
const VariableDeclaration = createVariableDeclaration(name, extrudeCall)
let showCallIndex = getShowIndex(_node)
if (showCallIndex == -1) {
if (showCallIndex === -1) {
// We didn't find a show, so let's just append everything
showCallIndex = _node.body.length
}
@ -480,21 +480,6 @@ export function createCallExpressionStdLib(
end: 0,
name,
},
function: {
type: 'StdLib',
func: {
// We only need the name here to map it back when it serializes
// to rust, don't worry about the rest.
name,
summary: '',
description: '',
tags: [],
returnValue: { type: '', required: false, name: '', schema: {} },
args: [],
unpublished: false,
deprecated: false,
},
},
optional: false,
arguments: args,
}
@ -514,9 +499,6 @@ export function createCallExpression(
end: 0,
name,
},
function: {
type: 'InMemory',
},
optional: false,
arguments: args,
}

View File

@ -2,5 +2,5 @@ The std is as expected, tools that are provided with the language.
For this language that means functions.
However because programatically changing the source code is a first class citizen in this lang, there needs to be helpes for adding and modifying these function calls,
However because programmatically changing the source code is a first class citizen in this lang, there needs to be helpers for adding and modifying these function calls,
So it makes sense to group some of these together.

View File

@ -289,6 +289,7 @@ export class EngineConnection {
)
} else {
console.error(`Error from server:\n${errorsString}`)
console.log(message)
}
return
}
@ -664,7 +665,7 @@ export class EngineCommandManager {
},
})
// Inisialize the planes.
// Initialize the planes.
this.initPlanes().then(() => {
// We execute the code here to make sure if the stream was to
// restart in a session, we want to make sure to execute the code.
@ -887,8 +888,9 @@ export class EngineCommandManager {
}
endSession() {
// TODO: instead of sending a single command with `object_ids: Object.keys(this.artifactMap)`
// we need to loop over them each individualy because if the engine doesn't recognise a single
// we need to loop over them each individually because if the engine doesn't recognise a single
// id the whole command fails.
const artifactsToDelete: any = {}
Object.entries(this.artifactMap).forEach(([id, artifact]) => {
const artifactTypesToDelete: ArtifactMap[string]['commandType'][] = [
// 'start_path' creates a new scene object for the path, which is why it needs to be deleted,
@ -898,7 +900,9 @@ export class EngineCommandManager {
'start_path',
]
if (!artifactTypesToDelete.includes(artifact.commandType)) return
artifactsToDelete[id] = artifact
})
Object.keys(artifactsToDelete).forEach((id) => {
const deletCmd: EngineCommand = {
type: 'modeling_cmd_req',
cmd_id: uuidv4(),
@ -982,7 +986,7 @@ export class EngineCommandManager {
if (parseCommand.type === 'modeling_cmd_req')
return this.handlePendingCommand(id, parseCommand?.cmd, range)
}
throw 'shouldnt reach here'
throw Error('shouldnt reach here')
}
handlePendingCommand(
id: string,

View File

@ -20,7 +20,6 @@ import {
import { isLiteralArrayOrStatic } from './sketchcombos'
import { toolTips, ToolTip } from '../../useStore'
import { createPipeExpression, splitPathAtPipeExpression } from '../modifyAst'
import { generateUuidFromHashSeed } from '../../lib/uuid'
import { SketchLineHelper, ModifyAstBase, TransformCallback } from './stdTypes'
@ -92,18 +91,12 @@ export function createFirstArg(
throw new Error('all sketch line types should have been covered')
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type LineData = {
from: [number, number, number]
to: [number, number, number]
}
function makeId(seed: string | any) {
if (typeof seed === 'string') {
return generateUuidFromHashSeed(seed)
}
return generateUuidFromHashSeed(JSON.stringify(seed))
}
export const lineTo: SketchLineHelper = {
add: ({
node,
@ -250,9 +243,6 @@ export const line: SketchLineHelper = {
])
if (callExpression.arguments?.[0].type === 'ObjectExpression') {
const toProp = callExpression.arguments?.[0].properties?.find(
({ key }) => key.name === 'to'
)
mutateObjExpProp(callExpression.arguments?.[0], toArrExp, 'to')
} else {
mutateArrExp(callExpression.arguments?.[0], toArrExp)
@ -956,7 +946,7 @@ export function compareVec2Epsilon(
) {
const compareEpsilon = 0.015625 // or 2^-6
const xDifference = Math.abs(vec1[0] - vec2[0])
const yDifference = Math.abs(vec1[0] - vec2[0])
const yDifference = Math.abs(vec1[1] - vec2[1])
return xDifference < compareEpsilon && yDifference < compareEpsilon
}
@ -974,14 +964,12 @@ export function addNewSketchLn({
const node = JSON.parse(JSON.stringify(_node))
const { add, updateArgs } = sketchLineHelperMap?.[fnName] || {}
if (!add || !updateArgs) throw new Error('not a sketch line helper')
const { node: varDec } = getNodeFromPath<VariableDeclarator>(
getNodeFromPath<VariableDeclarator>(node, pathToNode, 'VariableDeclarator')
getNodeFromPath<PipeExpression | CallExpression>(
node,
pathToNode,
'VariableDeclarator'
'PipeExpression'
)
const { node: pipeExp, shallowPath: pipePath } = getNodeFromPath<
PipeExpression | CallExpression
>(node, pathToNode, 'PipeExpression')
return add({
node,
previousProgramMemory,

View File

@ -50,7 +50,7 @@ async function testingSwapSketchFnCall({
}
}
describe('testing swaping out sketch calls with xLine/xLineTo', () => {
describe('testing swapping out sketch calls with xLine/xLineTo', () => {
const bigExampleArr = [
`const part001 = startSketchOn('XY')`,
` |> startProfileAt([0, 0], %)`,
@ -178,7 +178,7 @@ describe('testing swaping out sketch calls with xLine/xLineTo', () => {
constraintType: 'horizontal',
})
const expectedLine = "xLine({ length: -0.86, tag: 'abc4' }, %)"
// hmm "-0.86" is correct since the angle is 104, but need to make sure this is compatiable `-myVar`
// hmm "-0.86" is correct since the angle is 104, but need to make sure this is compatible `-myVar`
expect(newCode).toContain(expectedLine)
// new line should start at the same place as the old line
expect(originalRange[0]).toBe(newCode.indexOf(expectedLine))
@ -268,7 +268,7 @@ describe('testing swaping out sketch calls with xLine/xLineTo', () => {
})
})
describe('testing swaping out sketch calls with xLine/xLineTo while keeping variable/identifiers intact', () => {
describe('testing swapping out sketch calls with xLine/xLineTo while keeping variable/identifiers intact', () => {
// Enable rotations #152
const variablesExampleArr = [
`const lineX = -1`,

View File

@ -108,7 +108,7 @@ const part001 = startSketchOn('XY')
|> line([myVar, 1], %) // ln-should use legLen for y
|> line([myVar, -1], %) // ln-legLen but negative
|> line([-0.62, -1.54], %) // ln-should become angledLine
|> angledLine([myVar, 1.04], %) // ln-use segLen for secound arg
|> angledLine([myVar, 1.04], %) // ln-use segLen for second arg
|> angledLine([45, 1.04], %) // ln-segLen again
|> angledLineOfXLength([54, 2.35], %) // ln-should be transformed to angledLine
|> angledLineOfXLength([50, myVar], %) // ln-should use legAngX to calculate angle
@ -163,7 +163,7 @@ const part001 = startSketchOn('XY')
-legLen(segLen('seg01', %), myVar)
], %) // ln-legLen but negative
|> angledLine([-112, segLen('seg01', %)], %) // ln-should become angledLine
|> angledLine([myVar, segLen('seg01', %)], %) // ln-use segLen for secound arg
|> angledLine([myVar, segLen('seg01', %)], %) // ln-use segLen for second arg
|> angledLine([45, segLen('seg01', %)], %) // ln-segLen again
|> angledLine([54, segLen('seg01', %)], %) // ln-should be transformed to angledLine
|> angledLineOfXLength([
@ -471,7 +471,7 @@ async function helperThing(
}
describe('testing getConstraintLevelFromSourceRange', () => {
it('should devide up lines into free, partial and fully contrained', () => {
it('should divide up lines into free, partial and fully contrained', () => {
const code = `const baseLength = 3
const baseThick = 1
const armThick = 0.5

View File

@ -26,5 +26,4 @@ const bracket = startSketchOn('XY')
|> close(%)
|> extrude(width, %)
show(bracket)
`

View File

@ -15,7 +15,7 @@ app needs these selections to be based on cursors, therefore the app must
be in control of selections. On top of that because we need to set cursor
positions in code-mirror for selections, both from app logic, and still
allow the user to add multiple cursors like a normal editor, it's best to
let code mirror control cursor positions and assosiate those source ranges
let code mirror control cursor positions and associate those source ranges
with entity ids from code-mirror events later.
So it's a lot of back and forth. conceptually the back and forth is:
@ -43,7 +43,7 @@ In detail:
1) Click commands are mostly sent in stream.tsx search for
"select_with_point"
2) The handler for when the engine sends back entitiy ids calls
2) The handler for when the engine sends back entity ids calls
getEventForSelectWithPoint, it fires an XState event to update our
selections is xstate context
3 and 4) The XState handler for the above uses handleSelectionBatch and
@ -102,8 +102,8 @@ export async function getEventForSelectWithPoint(
Models['OkModelingCmdResponse_type'],
{ type: 'select_with_point' }
>,
{ sketchEnginePathId }: { sketchEnginePathId: string }
): Promise<ModelingMachineEvent> {
{ sketchEnginePathId }: { sketchEnginePathId?: string }
): Promise<ModelingMachineEvent | null> {
if (!data?.entity_id) {
return {
type: 'Set selection',
@ -120,6 +120,7 @@ export async function getEventForSelectWithPoint(
},
}
}
// if (!sketchEnginePathId) return null
// selected a vertex
const res = await engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
@ -127,7 +128,7 @@ export async function getEventForSelectWithPoint(
cmd: {
type: 'path_get_curve_uuids_for_vertices',
vertex_ids: [data.entity_id],
path_id: sketchEnginePathId,
path_id: sketchEnginePathId || '',
},
})
const curveIds = res?.data?.data?.curve_ids
@ -303,7 +304,7 @@ export function resetAndSetEngineEntitySelectionCmds(
selections: SelectionToEngine[]
): Models['WebSocketRequest_type'][] {
if (!engineCommandManager.engineConnection?.isReady()) {
console.log('engine connection isnt ready')
console.log('engine connection is not ready')
return []
}
return [

View File

@ -9,7 +9,6 @@ import { documentDir, homeDir, sep } from '@tauri-apps/api/path'
import { isTauri } from './isTauri'
import { ProjectWithEntryPointMetadata } from '../Router'
import { metadata } from 'tauri-plugin-fs-extra-api'
import { bracket } from './exampleKcl'
const PROJECT_FOLDER = 'kittycad-modeling-projects'
export const FILE_EXT = '.kcl'
@ -211,7 +210,8 @@ export function sortProject(project: FileEntry[]): FileEntry[] {
// Creates a new file in the default directory with the default project name
// Returns the path to the new file
export async function createNewProject(
path: string
path: string,
initCode = ''
): Promise<ProjectWithEntryPointMetadata> {
if (!isTauri) {
throw new Error('createNewProject() can only be called from a Tauri app')
@ -225,10 +225,12 @@ export async function createNewProject(
})
}
await writeTextFile(path + sep + PROJECT_ENTRYPOINT, bracket).catch((err) => {
console.error('Error creating new file:', err)
throw err
})
await writeTextFile(path + sep + PROJECT_ENTRYPOINT, initCode).catch(
(err) => {
console.error('Error creating new file:', err)
throw err
}
)
const m = await metadata(path)

View File

@ -9,6 +9,7 @@ import { v4 as uuidv4 } from 'uuid'
type WebSocketResponse = Models['OkWebSocketResponseData_type']
class MockEngineCommandManager {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(mockParams: {
setIsStreamReady: (isReady: boolean) => void
setMediaStream: (stream: MediaStream) => void

View File

@ -664,8 +664,8 @@ export const modelingMachine = createMachine(
on: {
Cancel: {
target: 'idle',
// TODO what if we're existing extrude equiped, should these actions still be fired?
// mabye cancel needs to have a guard for if else logic?
// TODO what if we're existing extrude equipped, should these actions still be fired?
// maybe cancel needs to have a guard for if else logic?
actions: [
'edit_mode_exit',
'default_camera_disable_sketch_mode',
@ -882,7 +882,7 @@ export const modelingMachine = createMachine(
// TODO implement source ranges for all of these constraints
// need to make the async like the modal constraints
'Make selection horizontal': ({ selectionRanges }) => {
const { modifiedAst, pathToNodeMap } = applyConstraintHorzVert(
const { modifiedAst } = applyConstraintHorzVert(
selectionRanges,
'horizontal',
kclManager.ast,
@ -891,7 +891,7 @@ export const modelingMachine = createMachine(
kclManager.updateAst(modifiedAst, true)
},
'Make selection vertical': ({ selectionRanges }) => {
const { modifiedAst, pathToNodeMap } = applyConstraintHorzVert(
const { modifiedAst } = applyConstraintHorzVert(
selectionRanges,
'vertical',
kclManager.ast,
@ -900,33 +900,33 @@ export const modelingMachine = createMachine(
kclManager.updateAst(modifiedAst, true)
},
'Constrain horizontally align': ({ selectionRanges }) => {
const { modifiedAst, pathToNodeMap } = applyConstraintHorzVertAlign({
const { modifiedAst } = applyConstraintHorzVertAlign({
selectionRanges,
constraint: 'setVertDistance',
})
kclManager.updateAst(modifiedAst, true)
},
'Constrain vertically align': ({ selectionRanges }) => {
const { modifiedAst, pathToNodeMap } = applyConstraintHorzVertAlign({
const { modifiedAst } = applyConstraintHorzVertAlign({
selectionRanges,
constraint: 'setHorzDistance',
})
kclManager.updateAst(modifiedAst, true)
},
'Constrain equal length': ({ selectionRanges }) => {
const { modifiedAst, pathToNodeMap } = applyConstraintEqualLength({
const { modifiedAst } = applyConstraintEqualLength({
selectionRanges,
})
kclManager.updateAst(modifiedAst, true)
},
'Constrain parallel': ({ selectionRanges }) => {
const { modifiedAst, pathToNodeMap } = applyConstraintEqualAngle({
const { modifiedAst } = applyConstraintEqualAngle({
selectionRanges,
})
kclManager.updateAst(modifiedAst, true)
},
'Constrain remove constraints': ({ selectionRanges }) => {
const { modifiedAst, pathToNodeMap } = applyRemoveConstrainingValues({
const { modifiedAst } = applyRemoveConstrainingValues({
selectionRanges,
})
kclManager.updateAst(modifiedAst, true)

View File

@ -43,7 +43,10 @@ function OnboardingWithNewFile() {
ONBOARDING_PROJECT_NAME,
nextIndex
)
const newFile = await createNewProject(defaultDirectory + sep + name)
const newFile = await createNewProject(
defaultDirectory + sep + name,
bracket
)
navigate(
`${paths.FILE}/${encodeURIComponent(
newFile.path + sep + PROJECT_ENTRYPOINT
@ -79,7 +82,7 @@ function OnboardingWithNewFile() {
<ActionButton
Element="button"
onClick={() => {
kclManager.setCode(bracket)
kclManager.setCodeAndExecute(bracket)
next()
}}
icon={{ icon: faArrowRight }}
@ -118,7 +121,7 @@ function OnboardingWithNewFile() {
Element="button"
onClick={() => {
createAndOpenNewProject()
kclManager.setCode(bracket)
kclManager.setCode(bracket, false)
dismiss()
}}
icon={{ icon: faArrowRight }}

View File

@ -32,6 +32,7 @@ import {
} from 'lib/tauriFS'
import { ONBOARDING_PROJECT_NAME } from './Onboarding'
import { sep } from '@tauri-apps/api/path'
import { bracket } from 'lib/exampleKcl'
export const Settings = () => {
const loaderData =
@ -96,7 +97,10 @@ export const Settings = () => {
ONBOARDING_PROJECT_NAME,
nextIndex
)
const newFile = await createNewProject(defaultDirectory + sep + name)
const newFile = await createNewProject(
defaultDirectory + sep + name,
bracket
)
navigate(`${paths.FILE}/${encodeURIComponent(newFile.path)}`)
}

View File

@ -67,6 +67,7 @@ const SignIn = () => {
onClick={signInTauri}
icon={{ icon: faSignInAlt }}
className="w-fit mt-4"
id="signin"
>
Sign in
</ActionButton>

View File

@ -253,11 +253,13 @@ export async function executeAst({
engineCommandManager,
defaultPlanes,
useFakeExecutor = false,
programMemoryOverride,
}: {
ast: Program
engineCommandManager: EngineCommandManager
defaultPlanes: DefaultPlanes
useFakeExecutor?: boolean
programMemoryOverride?: ProgramMemory
}): Promise<{
logs: string[]
errors: KCLError[]
@ -269,10 +271,13 @@ export async function executeAst({
engineCommandManager.startNewSession()
}
const programMemory = await (useFakeExecutor
? enginelessExecutor(ast, {
root: defaultProgramMemory,
return: null,
})
? enginelessExecutor(
ast,
programMemoryOverride || {
root: defaultProgramMemory,
return: null,
}
)
: _executor(
ast,
{

View File

@ -6,10 +6,10 @@
serial-integration = { max-threads = 4 }
[profile.default]
slow-timeout = { period = "60s", terminate-after = 1 }
slow-timeout = { period = "10s", terminate-after = 1 }
[profile.ci]
slow-timeout = { period = "120s", terminate-after = 10 }
slow-timeout = { period = "30s", terminate-after = 5 }
[[profile.default.overrides]]
filter = "test(serial_test_)"
@ -20,3 +20,7 @@ threads-required = 4
filter = "test(serial_test_)"
test-group = "serial-integration"
threads-required = 4
[[profile.default.overrides]]
filter = "test(parser::parser_impl::snapshot_tests)"
slow-timeout = { period = "1s", terminate-after = 5 }

628
src/wasm-lib/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,8 @@
name = "wasm-lib"
version = "0.1.0"
edition = "2021"
repository = "https://github.com/KittyCAD/modeling-app"
rust-version = "1.73"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
@ -11,28 +13,28 @@ crate-type = ["cdylib"]
bson = { version = "2.7.0", features = ["uuid-1", "chrono"] }
gloo-utils = "0.2.0"
kcl-lib = { path = "kcl" }
kittycad = { version = "0.2.33", default-features = false, features = ["js"] }
serde_json = "1.0.107"
uuid = { version = "1.4.1", features = ["v4", "js", "serde"] }
wasm-bindgen = "0.2.87"
kittycad = { workspace = true }
serde_json = "1.0.108"
uuid = { version = "1.5.0", features = ["v4", "js", "serde"] }
wasm-bindgen = "0.2.88"
wasm-bindgen-futures = "0.4.37"
[dev-dependencies]
anyhow = "1"
image = "0.24.7"
kittycad = "0.2.33"
kittycad = { workspace = true, default-features = true }
pretty_assertions = "1.4.0"
reqwest = { version = "0.11.22", default-features = false }
tokio = { version = "1.33.0", features = ["rt-multi-thread", "macros", "time"] }
twenty-twenty = "0.6.1"
uuid = { version = "1.4.1", features = ["v4", "js", "serde"] }
uuid = { version = "1.5.0", features = ["v4", "js", "serde"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
futures = "0.3.28"
js-sys = "0.3.64"
futures = "0.3.29"
js-sys = "0.3.65"
tower-lsp = { version = "0.20.0", default-features = false, features = ["runtime-agnostic"] }
wasm-bindgen-futures = { version = "0.4.37", features = ["futures-core-03-stream"] }
wasm-streams = "0.3.0"
wasm-streams = "0.4.0"
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.57"
@ -53,6 +55,9 @@ members = [
"kcl",
]
[workspace.dependencies]
kittycad = { version = "0.2.41", default-features = false, features = ["js"] }
[[test]]
name = "executor"
path = "tests/executor/main.rs"

View File

@ -4,6 +4,8 @@ description = "A tool for generating documentation from Rust derive macros"
version = "0.1.4"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"
rust-version = "1.73"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -14,9 +16,9 @@ proc-macro = true
convert_case = "0.6.0"
proc-macro2 = "1"
quote = "1"
serde = { version = "1.0.189", features = ["derive"] }
serde = { version = "1.0.192", features = ["derive"] }
serde_tokenstream = "0.2"
syn = { version = "2.0.38", features = ["full"] }
syn = { version = "2.0.39", features = ["full"] }
[dev-dependencies]
expectorate = "1.1.0"

View File

@ -4,6 +4,8 @@ description = "KittyCAD Language"
version = "0.1.35"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"
rust-version = "1.73"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -11,31 +13,31 @@ license = "MIT"
anyhow = { version = "1.0.75", features = ["backtrace"] }
async-recursion = "1.0.5"
async-trait = "0.1.73"
clap = { version = "4.4.6", features = ["cargo", "derive", "env", "unicode"], optional = true }
clap = { version = "4.4.7", features = ["cargo", "derive", "env", "unicode"], optional = true }
dashmap = "5.5.3"
derive-docs = { version = "0.1.4" }
#derive-docs = { path = "../derive-docs" }
kittycad = { version = "0.2.33", default-features = false, features = ["js"] }
kittycad = { workspace = true }
lazy_static = "1.4.0"
parse-display = "0.8.2"
schemars = { version = "0.8", features = ["impl_json_schema", "url", "uuid1"] }
serde = { version = "1.0.189", features = ["derive"] }
serde_json = "1.0.107"
thiserror = "1.0.49"
serde = { version = "1.0.192", features = ["derive"] }
serde_json = "1.0.108"
thiserror = "1.0.50"
ts-rs = { version = "7", package = "ts-rs-json-value", features = ["serde-json-impl", "schemars-impl", "uuid-impl"] }
uuid = { version = "1.4.1", features = ["v4", "js", "serde"] }
winnow = "0.5.16"
uuid = { version = "1.5.0", features = ["v4", "js", "serde"] }
winnow = "0.5.18"
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = { version = "0.3.64" }
js-sys = { version = "0.3.65" }
tower-lsp = { version = "0.20.0", default-features = false, features = ["runtime-agnostic"] }
wasm-bindgen = "0.2.87"
wasm-bindgen = "0.2.88"
wasm-bindgen-futures = "0.4.37"
web-sys = { version = "0.3.64", features = ["console"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
bson = { version = "2.7.0", features = ["uuid-1", "chrono"] }
futures = { version = "0.3.28" }
futures = { version = "0.3.29" }
reqwest = { version = "0.11.22", default-features = false }
tokio = { version = "1.33.0", features = ["full"] }
tokio-tungstenite = { version = "0.20.0", features = ["rustls-tls-native-roots"] }
@ -50,9 +52,13 @@ engine = []
panic = "abort"
debug = true
[profile.bench]
debug = true # Flamegraphs of benchmarks require accurate debug symbols
[dev-dependencies]
criterion = "0.5.1"
expectorate = "1.1.0"
insta = { version = "1.34.0", features = ["json"] }
itertools = "0.11.0"
pretty_assertions = "1.4.0"
tokio = { version = "1.33.0", features = ["rt-multi-thread", "macros", "time"] }

View File

@ -11,6 +11,7 @@ pub fn bench_parse(c: &mut Criterion) {
("pipes_on_pipes", PIPES_PROGRAM),
("big_kitt", KITT_PROGRAM),
("cube", CUBE_PROGRAM),
("math", MATH_PROGRAM),
] {
let tokens = kcl_lib::token::lexer(file);
c.bench_function(&format!("parse_{name}"), move |b| {
@ -33,3 +34,4 @@ criterion_main!(benches);
const KITT_PROGRAM: &str = include_str!("../../tests/executor/inputs/kittycad_svg.kcl");
const PIPES_PROGRAM: &str = include_str!("../../tests/executor/inputs/pipes_on_pipes.kcl");
const CUBE_PROGRAM: &str = include_str!("../../tests/executor/inputs/cube.kcl");
const MATH_PROGRAM: &str = include_str!("../../tests/executor/inputs/math.kcl");

View File

@ -3,6 +3,8 @@ name = "kcl-lib-fuzz"
version = "0.0.0"
publish = false
edition = "2021"
repository = "https://github.com/KittyCAD/modeling-app"
rust-version = "1.73"
[package.metadata]
cargo-fuzz = true

View File

@ -136,7 +136,7 @@ pub async fn modify_ast_for_sketch(
})?;
let mut additional_lines = Vec::new();
let mut last_point = first_control_points.points[1].clone();
let mut last_point = first_control_points.points[1];
for control_point in control_points[1..].iter() {
additional_lines.push([
(control_point.points[1].x - last_point.x),

View File

@ -6,15 +6,20 @@ use anyhow::Result;
use parse_display::{Display, FromStr};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Map;
use serde_json::{Map, Value as JValue};
use tower_lsp::lsp_types::{CompletionItem, CompletionItemKind, DocumentSymbol, Range as LspRange, SymbolKind};
pub use self::literal_value::LiteralValue;
use crate::{
docs::StdLibFn,
errors::{KclError, KclErrorDetails},
executor::{ExecutorContext, MemoryItem, Metadata, PipeInfo, ProgramMemory, SourceRange, UserVal},
executor::{BodyType, ExecutorContext, MemoryItem, Metadata, PipeInfo, ProgramMemory, SourceRange, UserVal},
parser::PIPE_OPERATOR,
std::{kcl_stdlib::KclStdLibFn, FunctionKind},
};
mod literal_value;
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
@ -371,13 +376,13 @@ impl BodyItem {
}
}
impl From<BodyItem> for crate::executor::SourceRange {
impl From<BodyItem> for SourceRange {
fn from(item: BodyItem) -> Self {
Self([item.start(), item.end()])
}
}
impl From<&BodyItem> for crate::executor::SourceRange {
impl From<&BodyItem> for SourceRange {
fn from(item: &BodyItem) -> Self {
Self([item.start(), item.end()])
}
@ -534,13 +539,13 @@ impl Value {
}
}
impl From<Value> for crate::executor::SourceRange {
impl From<Value> for SourceRange {
fn from(value: Value) -> Self {
Self([value.start(), value.end()])
}
}
impl From<&Value> for crate::executor::SourceRange {
impl From<&Value> for SourceRange {
fn from(value: &Value) -> Self {
Self([value.start(), value.end()])
}
@ -558,13 +563,13 @@ pub enum BinaryPart {
MemberExpression(Box<MemberExpression>),
}
impl From<BinaryPart> for crate::executor::SourceRange {
impl From<BinaryPart> for SourceRange {
fn from(value: BinaryPart) -> Self {
Self([value.start(), value.end()])
}
}
impl From<&BinaryPart> for crate::executor::SourceRange {
impl From<&BinaryPart> for SourceRange {
fn from(value: &BinaryPart) -> Self {
Self([value.start(), value.end()])
}
@ -640,7 +645,7 @@ impl BinaryPart {
pipe_info: &mut PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
@ -780,7 +785,7 @@ pub enum NonCodeValue {
/// 1 + 1
/// ```
/// Now this is important. The block comment is attached to the next line.
/// This is always the case. Also the block comment doesnt have a new line above it.
/// This is always the case. Also the block comment doesn't have a new line above it.
/// If it did it would be a `NewLineBlockComment`.
BlockComment {
value: String,
@ -858,7 +863,6 @@ pub struct CallExpression {
pub callee: Identifier,
pub arguments: Vec<Value>,
pub optional: bool,
pub function: Function,
}
impl_value_meta!(CallExpression);
@ -871,22 +875,12 @@ impl From<CallExpression> for Value {
impl CallExpression {
pub fn new(name: &str, arguments: Vec<Value>) -> Result<Self, KclError> {
// Create our stdlib.
let stdlib = crate::std::StdLib::new();
let func = stdlib.get(name).ok_or_else(|| {
KclError::UndefinedValue(KclErrorDetails {
message: format!("Function {} is not defined", name),
source_ranges: vec![],
})
})?;
Ok(Self {
start: 0,
end: 0,
callee: Identifier::new(name),
arguments,
optional: false,
function: Function::StdLib { func },
})
}
@ -930,7 +924,7 @@ impl CallExpression {
binary_expression.get_result(memory, pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => {
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
@ -968,8 +962,8 @@ impl CallExpression {
fn_args.push(result);
}
match &self.function {
Function::StdLib { func } => {
match ctx.stdlib.get_either(&self.callee.name) {
FunctionKind::Core(func) => {
// Attempt to call the function.
let args = crate::std::Args::new(fn_args, self.into(), ctx.clone());
let result = func.std_lib_fn()(args).await?;
@ -981,14 +975,54 @@ impl CallExpression {
Ok(result)
}
}
Function::InMemory => {
FunctionKind::Std(func) => {
let function_expression = func.function();
if fn_args.len() != function_expression.params.len() {
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Expected {} arguments, got {}",
function_expression.params.len(),
fn_args.len(),
),
source_ranges: vec![(function_expression).into()],
}));
}
// Add the arguments to the memory.
let mut fn_memory = memory.clone();
for (index, param) in function_expression.params.iter().enumerate() {
fn_memory.add(&param.name, fn_args.get(index).unwrap().clone(), param.into())?;
}
// Call the stdlib function
let p = func.function().clone().body;
let results = crate::executor::execute(p, &mut fn_memory, BodyType::Block, ctx).await?;
let out = results.return_;
let result = out.ok_or_else(|| {
KclError::UndefinedValue(KclErrorDetails {
message: format!("Result of stdlib function {} is undefined", fn_name),
source_ranges: vec![self.into()],
})
})?;
let result = result.get_value()?;
if pipe_info.is_in_pipe {
pipe_info.index += 1;
pipe_info.previous_results.push(result);
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), ctx).await
} else {
Ok(result)
}
}
FunctionKind::UserDefined => {
let func = memory.get(&fn_name, self.into())?;
let result = func
.call_fn(fn_args, memory.clone(), ctx.clone())
.await?
.ok_or_else(|| {
KclError::UndefinedValue(KclErrorDetails {
message: format!("Result of function {} is undefined", fn_name),
message: format!("Result of user-defined function {} is undefined", fn_name),
source_ranges: vec![self.into()],
})
})?;
@ -1063,10 +1097,15 @@ impl CallExpression {
#[ts(export)]
#[serde(tag = "type")]
pub enum Function {
/// A stdlib function.
/// A stdlib function written in Rust (aka core lib).
StdLib {
/// The function.
func: Box<dyn crate::docs::StdLibFn>,
func: Box<dyn StdLibFn>,
},
/// A stdlib function written in KCL.
StdLibKcl {
/// The function.
func: Box<dyn KclStdLibFn>,
},
/// A function that is defined in memory.
#[default]
@ -1312,24 +1351,18 @@ impl VariableDeclarator {
pub struct Literal {
pub start: usize,
pub end: usize,
pub value: serde_json::Value,
pub value: LiteralValue,
pub raw: String,
}
impl_value_meta!(Literal);
impl From<Literal> for Value {
fn from(literal: Literal) -> Self {
Value::Literal(Box::new(literal))
}
}
impl Literal {
pub fn new(value: serde_json::Value) -> Self {
pub fn new(value: LiteralValue) -> Self {
Self {
start: 0,
end: 0,
raw: value.to_string(),
raw: JValue::from(value.clone()).to_string(),
value,
}
}
@ -1343,11 +1376,19 @@ impl Literal {
}
fn recast(&self) -> String {
if let serde_json::Value::String(value) = &self.value {
let quote = if self.raw.trim().starts_with('"') { '"' } else { '\'' };
format!("{}{}{}", quote, value, quote)
} else {
self.value.to_string()
match self.value {
LiteralValue::Fractional(x) => {
if x.fract() == 0.0 {
format!("{x:?}")
} else {
self.raw.clone()
}
}
LiteralValue::IInteger(_) => self.raw.clone(),
LiteralValue::String(ref s) => {
let quote = if self.raw.trim().starts_with('"') { '"' } else { '\'' };
format!("{quote}{s}{quote}")
}
}
}
}
@ -1355,7 +1396,7 @@ impl Literal {
impl From<Literal> for MemoryItem {
fn from(literal: Literal) -> Self {
MemoryItem::UserVal(UserVal {
value: literal.value.clone(),
value: JValue::from(literal.value.clone()),
meta: vec![Metadata {
source_range: literal.into(),
}],
@ -1366,7 +1407,7 @@ impl From<Literal> for MemoryItem {
impl From<&Box<Literal>> for MemoryItem {
fn from(literal: &Box<Literal>) -> Self {
MemoryItem::UserVal(UserVal {
value: literal.value.clone(),
value: JValue::from(literal.value.clone()),
meta: vec![Metadata {
source_range: literal.into(),
}],
@ -1552,7 +1593,7 @@ impl ArrayExpression {
binary_expression.get_result(memory, pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => {
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
@ -1703,7 +1744,7 @@ impl ObjectExpression {
binary_expression.get_result(memory, pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => {
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
@ -1831,13 +1872,13 @@ impl MemberObject {
}
}
impl From<MemberObject> for crate::executor::SourceRange {
impl From<MemberObject> for SourceRange {
fn from(obj: MemberObject) -> Self {
Self([obj.start(), obj.end()])
}
}
impl From<&MemberObject> for crate::executor::SourceRange {
impl From<&MemberObject> for SourceRange {
fn from(obj: &MemberObject) -> Self {
Self([obj.start(), obj.end()])
}
@ -1867,13 +1908,13 @@ impl LiteralIdentifier {
}
}
impl From<LiteralIdentifier> for crate::executor::SourceRange {
impl From<LiteralIdentifier> for SourceRange {
fn from(id: LiteralIdentifier) -> Self {
Self([id.start(), id.end()])
}
}
impl From<&LiteralIdentifier> for crate::executor::SourceRange {
impl From<&LiteralIdentifier> for SourceRange {
fn from(id: &LiteralIdentifier) -> Self {
Self([id.start(), id.end()])
}
@ -1967,17 +2008,21 @@ impl MemberExpression {
LiteralIdentifier::Identifier(identifier) => identifier.name.to_string(),
LiteralIdentifier::Literal(literal) => {
let value = literal.value.clone();
// Parse this as a string.
if let serde_json::Value::String(string) = value {
string
} else if let serde_json::Value::Number(_) = &value {
// It can also be a number if we are getting a member of an array.
return self.get_result_array(memory, parse_json_number_as_usize(&value, self.into())?);
} else {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("Expected string literal or number for property name, found {:?}", value),
source_ranges: vec![literal.into()],
}));
match value {
LiteralValue::IInteger(x) if x >= 0 => return self.get_result_array(memory, x as usize),
LiteralValue::IInteger(x) => {
return Err(KclError::Syntax(KclErrorDetails {
source_ranges: vec![self.into()],
message: format!("invalid index: {x}"),
}))
}
LiteralValue::Fractional(x) => {
return Err(KclError::Syntax(KclErrorDetails {
source_ranges: vec![self.into()],
message: format!("invalid index: {x}"),
}))
}
LiteralValue::String(s) => s,
}
}
};
@ -2133,7 +2178,7 @@ impl BinaryExpression {
pipe_info: &mut PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
@ -2175,6 +2220,7 @@ impl BinaryExpression {
BinaryOperator::Mul => (left * right).into(),
BinaryOperator::Div => (left / right).into(),
BinaryOperator::Mod => (left % right).into(),
BinaryOperator::Pow => (left.powf(right)).into(),
};
Ok(MemoryItem::UserVal(UserVal {
@ -2208,22 +2254,6 @@ pub fn parse_json_number_as_f64(j: &serde_json::Value, source_range: SourceRange
}
}
pub fn parse_json_number_as_usize(j: &serde_json::Value, source_range: SourceRange) -> Result<usize, KclError> {
if let serde_json::Value::Number(n) = &j {
Ok(n.as_i64().ok_or_else(|| {
KclError::Syntax(KclErrorDetails {
source_ranges: vec![source_range],
message: format!("Invalid index: {}", j),
})
})? as usize)
} else {
Err(KclError::Syntax(KclErrorDetails {
source_ranges: vec![source_range],
message: format!("Invalid index: {}", j),
}))
}
}
pub fn parse_json_value_as_string(j: &serde_json::Value) -> Option<String> {
if let serde_json::Value::String(n) = &j {
Some(n.clone())
@ -2257,13 +2287,46 @@ pub enum BinaryOperator {
#[serde(rename = "%")]
#[display("%")]
Mod,
/// Raise a number to a power.
#[serde(rename = "^")]
#[display("^")]
Pow,
}
/// Mathematical associativity.
/// Should a . b . c be read as (a . b) . c, or a . (b . c)
/// See <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#precedence_and_associativity> for more.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum Associativity {
/// Read a . b . c as (a . b) . c
Left,
/// Read a . b . c as a . (b . c)
Right,
}
impl Associativity {
pub fn is_left(&self) -> bool {
matches!(self, Self::Left)
}
}
impl BinaryOperator {
/// Follow JS definitions of each operator.
/// Taken from <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table>
pub fn precedence(&self) -> u8 {
match &self {
BinaryOperator::Add | BinaryOperator::Sub => 11,
BinaryOperator::Mul | BinaryOperator::Div | BinaryOperator::Mod => 12,
BinaryOperator::Pow => 6,
}
}
/// Follow JS definitions of each operator.
/// Taken from <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table>
pub fn associativity(&self) -> Associativity {
match self {
Self::Add | Self::Sub | Self::Mul | Self::Div | Self::Mod => Associativity::Left,
Self::Pow => Associativity::Right,
}
}
}
@ -2307,7 +2370,7 @@ impl UnaryExpression {
pipe_info: &mut PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
// We DO NOT set this gloablly because if we did and this was called inside a pipe it would
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
@ -3255,4 +3318,40 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted.trim(), some_program_string);
}
#[test]
fn recast_literal() {
use winnow::Parser;
for (i, (raw, expected, reason)) in [
(
"5.0",
"5.0",
"fractional numbers should stay fractional, i.e. don't reformat this to '5'",
),
(
"5",
"5",
"integers should stay integral, i.e. don't reformat this to '5.0'",
),
(
"5.0000000",
"5.0",
"if the number is f64 but not fractional, use its canonical format",
),
("5.1", "5.1", "straightforward case works"),
]
.into_iter()
.enumerate()
{
let tokens = crate::token::lexer(raw);
let literal = crate::parser::parser_impl::unsigned_number_literal
.parse(&tokens)
.unwrap();
assert_eq!(
literal.recast(),
expected,
"failed test {i}, which is testing that {reason}"
);
}
}
}

View File

@ -0,0 +1,70 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value as JValue;
use super::{Literal, Value};
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(untagged, rename_all = "snake_case")]
pub enum LiteralValue {
IInteger(i64),
Fractional(f64),
String(String),
}
impl From<Literal> for Value {
fn from(literal: Literal) -> Self {
Value::Literal(Box::new(literal))
}
}
impl From<LiteralValue> for JValue {
fn from(value: LiteralValue) -> Self {
match value {
LiteralValue::IInteger(x) => x.into(),
LiteralValue::Fractional(x) => x.into(),
LiteralValue::String(x) => x.into(),
}
}
}
impl From<f64> for LiteralValue {
fn from(value: f64) -> Self {
Self::Fractional(value)
}
}
impl From<i64> for LiteralValue {
fn from(value: i64) -> Self {
Self::IInteger(value)
}
}
impl From<String> for LiteralValue {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<u32> for LiteralValue {
fn from(value: u32) -> Self {
Self::IInteger(value as i64)
}
}
impl From<u16> for LiteralValue {
fn from(value: u16) -> Self {
Self::IInteger(value as i64)
}
}
impl From<u8> for LiteralValue {
fn from(value: u8) -> Self {
Self::IInteger(value as i64)
}
}
impl From<&'static str> for LiteralValue {
fn from(value: &'static str) -> Self {
// TODO: Make this Cow<str>
Self::String(value.to_owned())
}
}

View File

@ -193,7 +193,7 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
}
fn to_signature_help(&self) -> SignatureHelp {
// Fill this in based on the current positon of the cursor.
// Fill this in based on the current position of the cursor.
let active_parameter = None;
SignatureHelp {

View File

@ -8,6 +8,8 @@ use crate::executor::SourceRange;
#[ts(export)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum KclError {
#[error("lexical: {0:?}")]
Lexical(KclErrorDetails),
#[error("syntax: {0:?}")]
Syntax(KclErrorDetails),
#[error("semantic: {0:?}")]
@ -26,6 +28,8 @@ pub enum KclError {
InvalidExpression(KclErrorDetails),
#[error("engine: {0:?}")]
Engine(KclErrorDetails),
#[error("internal error, please report to KittyCAD team: {0:?}")]
Internal(KclErrorDetails),
}
#[derive(Debug, Serialize, Deserialize, ts_rs::TS, Clone)]
@ -40,20 +44,8 @@ pub struct KclErrorDetails {
impl KclError {
/// Get the error message, line and column from the error and input code.
pub fn get_message_line_column(&self, input: &str) -> (String, Option<usize>, Option<usize>) {
let (type_, source_range, message) = match &self {
KclError::Syntax(e) => ("syntax", e.source_ranges.clone(), e.message.clone()),
KclError::Semantic(e) => ("semantic", e.source_ranges.clone(), e.message.clone()),
KclError::Type(e) => ("type", e.source_ranges.clone(), e.message.clone()),
KclError::Unimplemented(e) => ("unimplemented", e.source_ranges.clone(), e.message.clone()),
KclError::Unexpected(e) => ("unexpected", e.source_ranges.clone(), e.message.clone()),
KclError::ValueAlreadyDefined(e) => ("value already defined", e.source_ranges.clone(), e.message.clone()),
KclError::UndefinedValue(e) => ("undefined value", e.source_ranges.clone(), e.message.clone()),
KclError::InvalidExpression(e) => ("invalid expression", e.source_ranges.clone(), e.message.clone()),
KclError::Engine(e) => ("engine", e.source_ranges.clone(), e.message.clone()),
};
// Calculate the line and column of the error from the source range.
let (line, column) = if let Some(range) = source_range.first() {
let (line, column) = if let Some(range) = self.source_ranges().first() {
let line = input[..range.0[0]].lines().count();
let column = input[..range.0[0]].lines().last().map(|l| l.len()).unwrap_or_default();
@ -62,11 +54,28 @@ impl KclError {
(None, None)
};
(format!("{}: {}", type_, message), line, column)
(format!("{}: {}", self.error_type(), self.message()), line, column)
}
pub fn error_type(&self) -> &'static str {
match self {
KclError::Lexical(_) => "lexical",
KclError::Syntax(_) => "syntax",
KclError::Semantic(_) => "semantic",
KclError::Type(_) => "type",
KclError::Unimplemented(_) => "unimplemented",
KclError::Unexpected(_) => "unexpected",
KclError::ValueAlreadyDefined(_) => "value already defined",
KclError::UndefinedValue(_) => "undefined value",
KclError::InvalidExpression(_) => "invalid expression",
KclError::Engine(_) => "engine",
KclError::Internal(_) => "internal",
}
}
pub fn source_ranges(&self) -> Vec<SourceRange> {
match &self {
KclError::Lexical(e) => e.source_ranges.clone(),
KclError::Syntax(e) => e.source_ranges.clone(),
KclError::Semantic(e) => e.source_ranges.clone(),
KclError::Type(e) => e.source_ranges.clone(),
@ -76,12 +85,14 @@ impl KclError {
KclError::UndefinedValue(e) => e.source_ranges.clone(),
KclError::InvalidExpression(e) => e.source_ranges.clone(),
KclError::Engine(e) => e.source_ranges.clone(),
KclError::Internal(e) => e.source_ranges.clone(),
}
}
/// Get the inner error message.
pub fn message(&self) -> &str {
match &self {
KclError::Lexical(e) => &e.message,
KclError::Syntax(e) => &e.message,
KclError::Semantic(e) => &e.message,
KclError::Type(e) => &e.message,
@ -91,6 +102,7 @@ impl KclError {
KclError::UndefinedValue(e) => &e.message,
KclError::InvalidExpression(e) => &e.message,
KclError::Engine(e) => &e.message,
KclError::Internal(e) => &e.message,
}
}

View File

@ -1,8 +1,9 @@
//! The executor for the AST.
use std::collections::HashMap;
use std::{collections::HashMap, sync::Arc};
use anyhow::Result;
use async_recursion::async_recursion;
use kittycad::types::{Color, ModelingCmd, Point3D};
use parse_display::{Display, FromStr};
use schemars::JsonSchema;
@ -10,9 +11,10 @@ use serde::{Deserialize, Serialize};
use tower_lsp::lsp_types::{Position as LspPosition, Range as LspRange};
use crate::{
ast::types::{BodyItem, Function, FunctionExpression, Value},
ast::types::{BodyItem, FunctionExpression, Value},
engine::{EngineConnection, EngineManager},
errors::{KclError, KclErrorDetails},
std::{FunctionKind, StdLib},
};
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
@ -183,7 +185,7 @@ impl DefaultPlanes {
SourceRange::default(),
ModelingCmd::MakePlane {
clobber: false,
origin: default_origin.clone(),
origin: default_origin,
size: default_size,
x_axis: Point3D { x: 1.0, y: 0.0, z: 0.0 },
y_axis: Point3D { x: 0.0, y: 1.0, z: 0.0 },
@ -216,7 +218,7 @@ impl DefaultPlanes {
SourceRange::default(),
ModelingCmd::MakePlane {
clobber: false,
origin: default_origin.clone(),
origin: default_origin,
size: default_size,
x_axis: Point3D { x: 0.0, y: 1.0, z: 0.0 },
y_axis: Point3D { x: 0.0, y: 0.0, z: 1.0 },
@ -347,27 +349,27 @@ impl MemoryItem {
}
}
/// If this memory item is a function, call it with the given arguments, return its val as Ok.
/// If it's not a function, return Err.
pub async fn call_fn(
&self,
args: Vec<MemoryItem>,
memory: ProgramMemory,
ctx: ExecutorContext,
) -> Result<Option<ProgramReturn>, KclError> {
if let MemoryItem::Function { func, expression, meta } = &self {
if let Some(func) = func {
func(args, memory, expression.clone(), meta.clone(), ctx).await
} else {
Err(KclError::Semantic(KclErrorDetails {
message: format!("Not a function: {:?}", expression),
source_ranges: vec![],
}))
}
} else {
Err(KclError::Semantic(KclErrorDetails {
let MemoryItem::Function { func, expression, meta } = &self else {
return Err(KclError::Semantic(KclErrorDetails {
message: "not a in memory function".to_string(),
source_ranges: vec![],
}))
}
}));
};
let Some(func) = func else {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("Not a function: {:?}", expression),
source_ranges: vec![],
}));
};
func(args, memory, expression.clone(), meta.clone(), ctx).await
}
}
@ -776,9 +778,11 @@ impl Default for PipeInfo {
pub struct ExecutorContext {
pub engine: EngineConnection,
pub planes: DefaultPlanes,
pub stdlib: Arc<StdLib>,
}
/// Execute a AST's program.
#[async_recursion(?Send)]
pub async fn execute(
program: crate::ast::types::Program,
memory: &mut ProgramMemory,
@ -826,24 +830,37 @@ pub async fn execute(
}
}
let _show_fn = Box::new(crate::std::Show);
if let Function::StdLib { func: _show_fn } = &call_expr.function {
if options != BodyType::Root {
return Err(KclError::Semantic(KclErrorDetails {
message: "Cannot call show outside of a root".to_string(),
source_ranges: vec![call_expr.into()],
}));
match ctx.stdlib.get_either(&call_expr.callee.name) {
FunctionKind::Core(func) => {
use crate::docs::StdLibFn;
if func.name() == _show_fn.name() {
if options != BodyType::Root {
return Err(KclError::Semantic(KclErrorDetails {
message: "Cannot call show outside of a root".to_string(),
source_ranges: vec![call_expr.into()],
}));
}
memory.return_ = Some(ProgramReturn::Arguments(call_expr.arguments.clone()));
}
}
FunctionKind::Std(func) => {
let mut newmem = memory.clone();
let result = execute(func.program().to_owned(), &mut newmem, BodyType::Block, ctx).await?;
memory.return_ = result.return_;
}
FunctionKind::UserDefined => {
if let Some(func) = memory.clone().root.get(&fn_name) {
let result = func.call_fn(args.clone(), memory.clone(), ctx.clone()).await?;
memory.return_ = Some(ProgramReturn::Arguments(call_expr.arguments.clone()));
} else if let Some(func) = memory.clone().root.get(&fn_name) {
let result = func.call_fn(args.clone(), memory.clone(), ctx.clone()).await?;
memory.return_ = result;
} else {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("No such name {} defined", fn_name),
source_ranges: vec![call_expr.into()],
}));
memory.return_ = result;
} else {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("No such name {} defined", fn_name),
source_ranges: vec![call_expr.into()],
}));
}
}
}
}
}
@ -1011,7 +1028,11 @@ mod tests {
let mut mem: ProgramMemory = Default::default();
let engine = EngineConnection::new().await?;
let planes = DefaultPlanes::new(&engine).await?;
let ctx = ExecutorContext { engine, planes };
let ctx = ExecutorContext {
engine,
planes,
stdlib: Arc::new(StdLib::default()),
};
let memory = execute(program, &mut mem, BodyType::Root, &ctx).await?;
Ok(memory)

View File

@ -5,7 +5,6 @@ pub mod docs;
pub mod engine;
pub mod errors;
pub mod executor;
pub mod math_parser;
pub mod parser;
pub mod server;
pub mod std;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
use crate::{
ast::types::{BinaryExpression, BinaryOperator, BinaryPart},
errors::{KclError, KclErrorDetails},
executor::SourceRange,
};
/// Parses a list of tokens (in infix order, i.e. as the user typed them)
/// into a binary expression tree.
pub fn parse(infix_tokens: Vec<BinaryExpressionToken>) -> Result<BinaryExpression, KclError> {
let rpn = postfix(infix_tokens);
evaluate(rpn)
}
/// Parses a list of tokens (in postfix order) into a binary expression tree.
fn evaluate(rpn: Vec<BinaryExpressionToken>) -> Result<BinaryExpression, KclError> {
let source_ranges = source_range(&rpn);
let mut operand_stack: Vec<BinaryPart> = Vec::new();
let e = KclError::Internal(KclErrorDetails {
source_ranges,
message: "error parsing binary math expressions".to_owned(),
});
for item in rpn {
let expr = match item {
BinaryExpressionToken::Operator(operator) => {
let Some(right) = operand_stack.pop() else {
return Err(e);
};
let Some(left) = operand_stack.pop() else {
return Err(e);
};
BinaryPart::BinaryExpression(Box::new(BinaryExpression {
start: left.start(),
end: right.end(),
operator,
left,
right,
}))
}
BinaryExpressionToken::Operand(o) => o,
};
operand_stack.push(expr)
}
if let Some(BinaryPart::BinaryExpression(expr)) = operand_stack.pop() {
Ok(*expr)
} else {
// If this branch is used, the evaluation algorithm has a bug and must be fixed.
// This is a programmer error, not a user error.
Err(e)
}
}
fn source_range(tokens: &[BinaryExpressionToken]) -> Vec<SourceRange> {
let sources: Vec<_> = tokens
.iter()
.filter_map(|op| match op {
BinaryExpressionToken::Operator(_) => None,
BinaryExpressionToken::Operand(o) => Some((o.start(), o.end())),
})
.collect();
match (sources.first(), sources.last()) {
(Some((start, _)), Some((_, end))) => vec![SourceRange([*start, *end])],
_ => Vec::new(),
}
}
/// Reorders tokens from infix order to postfix order.
fn postfix(infix: Vec<BinaryExpressionToken>) -> Vec<BinaryExpressionToken> {
let mut operator_stack: Vec<BinaryOperator> = Vec::with_capacity(infix.len());
let mut output = Vec::with_capacity(infix.len());
for token in infix {
match token {
BinaryExpressionToken::Operator(o1) => {
// From https://en.wikipedia.org/wiki/Shunting_yard_algorithm:
// while (
// there is an operator o2 at the top of the operator stack which is not a left parenthesis,
// and (o2 has greater precedence than o1 or (o1 and o2 have the same precedence and o1 is left-associative))
// )
// pop o2 from the operator stack into the output queue
while let Some(o2) = operator_stack.pop() {
if (o2.precedence() > o1.precedence())
|| o1.precedence() == o2.precedence() && o1.associativity().is_left()
{
output.push(BinaryExpressionToken::Operator(o2));
} else {
operator_stack.push(o2);
break;
}
}
operator_stack.push(o1);
}
o @ BinaryExpressionToken::Operand(_) => output.push(o),
}
}
// After the while loop, pop the remaining items from the operator stack into the output queue.
output.extend(operator_stack.into_iter().rev().map(BinaryExpressionToken::Operator));
output
}
/// Expressions are made up of operators and operands.
#[derive(PartialEq, Debug)]
pub enum BinaryExpressionToken {
Operator(BinaryOperator),
Operand(BinaryPart),
}
impl From<BinaryPart> for BinaryExpressionToken {
fn from(value: BinaryPart) -> Self {
Self::Operand(value)
}
}
impl From<BinaryOperator> for BinaryExpressionToken {
fn from(value: BinaryOperator) -> Self {
Self::Operator(value)
}
}
#[cfg(test)]
mod tests {
use crate::ast::types::Literal;
use super::*;
#[test]
fn parse_and_evaluate() {
/// Make a literal
fn lit(n: u8) -> BinaryPart {
BinaryPart::Literal(Box::new(Literal {
start: 0,
end: 0,
value: n.into(),
raw: n.to_string(),
}))
}
let tests: Vec<Vec<BinaryExpressionToken>> = vec![
// 3 + 4 × 2 ÷ ( 1 5 ) ^ 2 ^ 3
vec![
lit(3).into(),
BinaryOperator::Add.into(),
lit(4).into(),
BinaryOperator::Mul.into(),
lit(2).into(),
BinaryOperator::Div.into(),
BinaryPart::BinaryExpression(Box::new(BinaryExpression {
start: 0,
end: 0,
operator: BinaryOperator::Sub,
left: lit(1),
right: lit(5),
}))
.into(),
BinaryOperator::Pow.into(),
lit(2).into(),
BinaryOperator::Pow.into(),
lit(3).into(),
],
];
for infix_input in tests {
let rpn = postfix(infix_input);
let _tree = evaluate(rpn).unwrap();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 5,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 4,
"end": 5,
"value": 2,
"raw": "2"
}
}

View File

@ -0,0 +1,26 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 3,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 2,
"end": 3,
"value": 2,
"raw": "2"
}
}

View File

@ -0,0 +1,26 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 4,
"operator": "-",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 3,
"end": 4,
"value": 2,
"raw": "2"
}
}

View File

@ -0,0 +1,41 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 9,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 4,
"end": 9,
"operator": "*",
"left": {
"type": "Literal",
"type": "Literal",
"start": 4,
"end": 5,
"value": 2,
"raw": "2"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 8,
"end": 9,
"value": 3,
"raw": "3"
}
}
}

View File

@ -0,0 +1,41 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 11,
"operator": "*",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 6,
"end": 11,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 6,
"end": 7,
"value": 2,
"raw": "2"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 10,
"end": 11,
"value": 3,
"raw": "3"
}
}
}

View File

@ -0,0 +1,56 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 17,
"operator": "/",
"left": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 0,
"end": 11,
"operator": "*",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 6,
"end": 11,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 6,
"end": 7,
"value": 2,
"raw": "2"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 10,
"end": 11,
"value": 3,
"raw": "3"
}
}
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 16,
"end": 17,
"value": 4,
"raw": "4"
}
}

View File

@ -0,0 +1,56 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 17,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 6,
"end": 17,
"operator": "/",
"left": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 6,
"end": 11,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 6,
"end": 7,
"value": 2,
"raw": "2"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 10,
"end": 11,
"value": 3,
"raw": "3"
}
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 16,
"end": 17,
"value": 4,
"raw": "4"
}
}
}

View File

@ -0,0 +1,71 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 22,
"operator": "*",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 7,
"end": 22,
"operator": "+",
"left": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 7,
"end": 18,
"operator": "/",
"left": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 7,
"end": 12,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 7,
"end": 8,
"value": 2,
"raw": "2"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 11,
"end": 12,
"value": 3,
"raw": "3"
}
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 4,
"raw": "4"
}
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 21,
"end": 22,
"value": 5,
"raw": "5"
}
}
}

View File

@ -0,0 +1,41 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 13,
"operator": "*",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 1,
"raw": "1"
},
"right": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 8,
"end": 13,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 8,
"end": 9,
"value": 2,
"raw": "2"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 12,
"end": 13,
"value": 3,
"raw": "3"
}
}
}

View File

@ -0,0 +1,81 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 44,
"operator": "/",
"left": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 0,
"end": 22,
"operator": "*",
"left": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 0,
"end": 18,
"operator": "*",
"left": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 0,
"end": 12,
"operator": "*",
"left": {
"type": "Identifier",
"type": "Identifier",
"start": 0,
"end": 8,
"name": "distance"
},
"right": {
"type": "Identifier",
"type": "Identifier",
"start": 11,
"end": 12,
"name": "p"
}
},
"right": {
"type": "Identifier",
"type": "Identifier",
"start": 15,
"end": 18,
"name": "FOS"
}
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 21,
"end": 22,
"value": 6,
"raw": "6"
}
},
"right": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 26,
"end": 44,
"operator": "*",
"left": {
"type": "Identifier",
"type": "Identifier",
"start": 26,
"end": 36,
"name": "sigmaAllow"
},
"right": {
"type": "Identifier",
"type": "Identifier",
"start": 39,
"end": 44,
"name": "width"
}
}
}

View File

@ -0,0 +1,26 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"type": "BinaryExpression",
"start": 0,
"end": 8,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 2,
"raw": "2"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 7,
"end": 8,
"value": 3,
"raw": "3"
}
}

View File

@ -0,0 +1,263 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 144,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 143,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 143,
"id": {
"type": "Identifier",
"start": 6,
"end": 15,
"name": "boxSketch"
},
"init": {
"type": "PipeExpression",
"type": "PipeExpression",
"start": 18,
"end": 143,
"body": [
{
"type": "CallExpression",
"type": "CallExpression",
"start": 18,
"end": 39,
"callee": {
"type": "Identifier",
"start": 18,
"end": 31,
"name": "startSketchAt"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 32,
"end": 38,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 33,
"end": 34,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 36,
"end": 37,
"value": 0,
"raw": "0"
}
]
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 47,
"end": 63,
"callee": {
"type": "Identifier",
"start": 47,
"end": 51,
"name": "line"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 52,
"end": 59,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 53,
"end": 54,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 56,
"end": 58,
"value": 10,
"raw": "10"
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 61,
"end": 62
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 71,
"end": 96,
"callee": {
"type": "Identifier",
"start": 71,
"end": 84,
"name": "tangentialArc"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 85,
"end": 92,
"elements": [
{
"type": "UnaryExpression",
"type": "UnaryExpression",
"start": 86,
"end": 88,
"operator": "-",
"argument": {
"type": "Literal",
"type": "Literal",
"start": 87,
"end": 88,
"value": 5,
"raw": "5"
}
},
{
"type": "Literal",
"type": "Literal",
"start": 90,
"end": 91,
"value": 5,
"raw": "5"
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 94,
"end": 95
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 104,
"end": 121,
"callee": {
"type": "Identifier",
"start": 104,
"end": 108,
"name": "line"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 109,
"end": 117,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 110,
"end": 111,
"value": 5,
"raw": "5"
},
{
"type": "UnaryExpression",
"type": "UnaryExpression",
"start": 113,
"end": 116,
"operator": "-",
"argument": {
"type": "Literal",
"type": "Literal",
"start": 114,
"end": 116,
"value": 15,
"raw": "15"
}
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 119,
"end": 120
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 129,
"end": 143,
"callee": {
"type": "Identifier",
"start": 129,
"end": 136,
"name": "extrude"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 137,
"end": 139,
"value": 10,
"raw": "10"
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 141,
"end": 142
}
],
"optional": false
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,48 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 17,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 17,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 17,
"id": {
"type": "Identifier",
"start": 6,
"end": 8,
"name": "sg"
},
"init": {
"type": "UnaryExpression",
"type": "UnaryExpression",
"start": 11,
"end": 17,
"operator": "-",
"argument": {
"type": "Identifier",
"type": "Identifier",
"start": 12,
"end": 17,
"name": "scale"
}
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,85 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 23,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 23,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 23,
"callee": {
"type": "Identifier",
"start": 0,
"end": 6,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 7,
"end": 22,
"properties": [
{
"type": "ObjectProperty",
"start": 9,
"end": 20,
"key": {
"type": "Identifier",
"start": 9,
"end": 11,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 13,
"end": 20,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 14,
"end": 15,
"value": 0,
"raw": "0"
},
{
"type": "UnaryExpression",
"type": "UnaryExpression",
"start": 17,
"end": 19,
"operator": "-",
"argument": {
"type": "Literal",
"type": "Literal",
"start": 18,
"end": 19,
"value": 1,
"raw": "1"
}
}
]
}
}
]
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,130 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 23,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 23,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 23,
"id": {
"type": "Identifier",
"start": 6,
"end": 13,
"name": "myArray"
},
"init": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 16,
"end": 23,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 1,
"raw": "1"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 2,
"raw": "2"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 3,
"raw": "3"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 4,
"raw": "4"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 5,
"raw": "5"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 6,
"raw": "6"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 7,
"raw": "7"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 8,
"raw": "8"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 9,
"raw": "9"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 10,
"raw": "10"
}
]
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,85 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 80,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 5,
"end": 57,
"declarations": [
{
"type": "VariableDeclarator",
"start": 8,
"end": 57,
"id": {
"type": "Identifier",
"start": 8,
"end": 24,
"name": "firstPrimeNumber"
},
"init": {
"type": "FunctionExpression",
"type": "FunctionExpression",
"start": 27,
"end": 57,
"params": [],
"body": {
"start": 33,
"end": 57,
"body": [
{
"type": "ReturnStatement",
"type": "ReturnStatement",
"start": 43,
"end": 51,
"argument": {
"type": "Literal",
"type": "Literal",
"start": 50,
"end": 51,
"value": 2,
"raw": "2"
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
}
],
"kind": "fn"
},
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 62,
"end": 80,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 62,
"end": 80,
"callee": {
"type": "Identifier",
"start": 62,
"end": 78,
"name": "firstPrimeNumber"
},
"arguments": [],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,99 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 66,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 49,
"declarations": [
{
"type": "VariableDeclarator",
"start": 3,
"end": 49,
"id": {
"type": "Identifier",
"start": 3,
"end": 8,
"name": "thing"
},
"init": {
"type": "FunctionExpression",
"type": "FunctionExpression",
"start": 11,
"end": 49,
"params": [
{
"type": "Identifier",
"start": 12,
"end": 17,
"name": "param"
}
],
"body": {
"start": 22,
"end": 49,
"body": [
{
"type": "ReturnStatement",
"type": "ReturnStatement",
"start": 32,
"end": 43,
"argument": {
"type": "Identifier",
"type": "Identifier",
"start": 39,
"end": 43,
"name": "true"
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
}
],
"kind": "fn"
},
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 54,
"end": 66,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 54,
"end": 66,
"callee": {
"type": "Identifier",
"start": 54,
"end": 59,
"name": "thing"
},
"arguments": [
{
"type": "Identifier",
"type": "Identifier",
"start": 60,
"end": 65,
"name": "false"
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,317 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 192,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 192,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 192,
"id": {
"type": "Identifier",
"start": 6,
"end": 14,
"name": "mySketch"
},
"init": {
"type": "PipeExpression",
"type": "PipeExpression",
"start": 17,
"end": 192,
"body": [
{
"type": "CallExpression",
"type": "CallExpression",
"start": 17,
"end": 37,
"callee": {
"type": "Identifier",
"start": 17,
"end": 30,
"name": "startSketchAt"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 31,
"end": 36,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 32,
"end": 33,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 34,
"end": 35,
"value": 0,
"raw": "0"
}
]
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 49,
"end": 89,
"callee": {
"type": "Identifier",
"start": 49,
"end": 55,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 56,
"end": 85,
"properties": [
{
"type": "ObjectProperty",
"start": 58,
"end": 68,
"key": {
"type": "Identifier",
"start": 58,
"end": 60,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 62,
"end": 68,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 63,
"end": 64,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 66,
"end": 67,
"value": 1,
"raw": "1"
}
]
}
},
{
"type": "ObjectProperty",
"start": 70,
"end": 83,
"key": {
"type": "Identifier",
"start": 70,
"end": 73,
"name": "tag"
},
"value": {
"type": "Literal",
"type": "Literal",
"start": 75,
"end": 83,
"value": "myPath",
"raw": "'myPath'"
}
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 87,
"end": 88
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 101,
"end": 118,
"callee": {
"type": "Identifier",
"start": 101,
"end": 107,
"name": "lineTo"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 108,
"end": 114,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 109,
"end": 110,
"value": 1,
"raw": "1"
},
{
"type": "Literal",
"type": "Literal",
"start": 112,
"end": 113,
"value": 1,
"raw": "1"
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 116,
"end": 117
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 130,
"end": 172,
"callee": {
"type": "Identifier",
"start": 130,
"end": 136,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 137,
"end": 168,
"properties": [
{
"type": "ObjectProperty",
"start": 139,
"end": 148,
"key": {
"type": "Identifier",
"start": 139,
"end": 141,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 143,
"end": 148,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 144,
"end": 145,
"value": 1,
"raw": "1"
},
{
"type": "Literal",
"type": "Literal",
"start": 146,
"end": 147,
"value": 0,
"raw": "0"
}
]
}
},
{
"type": "ObjectProperty",
"start": 150,
"end": 166,
"key": {
"type": "Identifier",
"start": 150,
"end": 153,
"name": "tag"
},
"value": {
"type": "Literal",
"type": "Literal",
"start": 155,
"end": 166,
"value": "rightPath",
"raw": "\"rightPath\""
}
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 170,
"end": 171
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 184,
"end": 192,
"callee": {
"type": "Identifier",
"start": 184,
"end": 189,
"name": "close"
},
"arguments": [
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 190,
"end": 191
}
],
"optional": false
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,151 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 70,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 70,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 70,
"id": {
"type": "Identifier",
"start": 6,
"end": 14,
"name": "mySketch"
},
"init": {
"type": "PipeExpression",
"type": "PipeExpression",
"start": 17,
"end": 70,
"body": [
{
"type": "CallExpression",
"type": "CallExpression",
"start": 17,
"end": 37,
"callee": {
"type": "Identifier",
"start": 17,
"end": 30,
"name": "startSketchAt"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 31,
"end": 36,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 32,
"end": 33,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 34,
"end": 35,
"value": 0,
"raw": "0"
}
]
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 41,
"end": 58,
"callee": {
"type": "Identifier",
"start": 41,
"end": 47,
"name": "lineTo"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 48,
"end": 54,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 49,
"end": 50,
"value": 1,
"raw": "1"
},
{
"type": "Literal",
"type": "Literal",
"start": 52,
"end": 53,
"value": 1,
"raw": "1"
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 56,
"end": 57
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 62,
"end": 70,
"callee": {
"type": "Identifier",
"start": 62,
"end": 67,
"name": "close"
},
"arguments": [
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 68,
"end": 69
}
],
"optional": false
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,56 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 30,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 30,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 30,
"id": {
"type": "Identifier",
"start": 6,
"end": 11,
"name": "myBox"
},
"init": {
"type": "CallExpression",
"type": "CallExpression",
"start": 14,
"end": 30,
"callee": {
"type": "Identifier",
"start": 14,
"end": 27,
"name": "startSketchAt"
},
"arguments": [
{
"type": "Identifier",
"type": "Identifier",
"start": 28,
"end": 29,
"name": "p"
}
],
"optional": false
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,92 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 26,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 26,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 26,
"id": {
"type": "Identifier",
"start": 6,
"end": 11,
"name": "myBox"
},
"init": {
"type": "PipeExpression",
"type": "PipeExpression",
"start": 14,
"end": 26,
"body": [
{
"type": "CallExpression",
"type": "CallExpression",
"start": 14,
"end": 18,
"callee": {
"type": "Identifier",
"start": 14,
"end": 15,
"name": "f"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 16,
"end": 17,
"value": 1,
"raw": "1"
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 22,
"end": 26,
"callee": {
"type": "Identifier",
"start": 22,
"end": 23,
"name": "g"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 24,
"end": 25,
"value": 2,
"raw": "2"
}
],
"optional": false
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,112 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 49,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 49,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 49,
"id": {
"type": "Identifier",
"start": 6,
"end": 11,
"name": "myBox"
},
"init": {
"type": "PipeExpression",
"type": "PipeExpression",
"start": 14,
"end": 49,
"body": [
{
"type": "CallExpression",
"type": "CallExpression",
"start": 14,
"end": 30,
"callee": {
"type": "Identifier",
"start": 14,
"end": 27,
"name": "startSketchAt"
},
"arguments": [
{
"type": "Identifier",
"type": "Identifier",
"start": 28,
"end": 29,
"name": "p"
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 34,
"end": 49,
"callee": {
"type": "Identifier",
"start": 34,
"end": 38,
"name": "line"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 39,
"end": 45,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 40,
"end": 41,
"value": 0,
"raw": "0"
},
{
"type": "Identifier",
"type": "Identifier",
"start": 43,
"end": 44,
"name": "l"
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 47,
"end": 48
}
],
"optional": false
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,78 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 22,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 22,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 22,
"callee": {
"type": "Identifier",
"start": 0,
"end": 6,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 7,
"end": 21,
"properties": [
{
"type": "ObjectProperty",
"start": 9,
"end": 19,
"key": {
"type": "Identifier",
"start": 9,
"end": 11,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 13,
"end": 19,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 14,
"end": 15,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 1,
"raw": "1"
}
]
}
}
]
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,113 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 36,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 36,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 36,
"callee": {
"type": "Identifier",
"start": 0,
"end": 6,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 7,
"end": 35,
"properties": [
{
"type": "ObjectProperty",
"start": 9,
"end": 19,
"key": {
"type": "Identifier",
"start": 9,
"end": 11,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 13,
"end": 19,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 14,
"end": 15,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 1,
"raw": "1"
}
]
}
},
{
"type": "ObjectProperty",
"start": 21,
"end": 33,
"key": {
"type": "Identifier",
"start": 21,
"end": 25,
"name": "from"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 27,
"end": 33,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 28,
"end": 29,
"value": 3,
"raw": "3"
},
{
"type": "Literal",
"type": "Literal",
"start": 31,
"end": 32,
"value": 3,
"raw": "3"
}
]
}
}
]
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,78 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 19,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 19,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 19,
"callee": {
"type": "Identifier",
"start": 0,
"end": 6,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 7,
"end": 18,
"properties": [
{
"type": "ObjectProperty",
"start": 8,
"end": 17,
"key": {
"type": "Identifier",
"start": 8,
"end": 10,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 11,
"end": 17,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 12,
"end": 13,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 15,
"end": 16,
"value": 1,
"raw": "1"
}
]
}
}
]
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,113 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 35,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 35,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 35,
"callee": {
"type": "Identifier",
"start": 0,
"end": 6,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 7,
"end": 34,
"properties": [
{
"type": "ObjectProperty",
"start": 9,
"end": 19,
"key": {
"type": "Identifier",
"start": 9,
"end": 11,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 13,
"end": 19,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 14,
"end": 15,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 1,
"raw": "1"
}
]
}
},
{
"type": "ObjectProperty",
"start": 21,
"end": 33,
"key": {
"type": "Identifier",
"start": 21,
"end": 25,
"name": "from"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 27,
"end": 33,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 28,
"end": 29,
"value": 3,
"raw": "3"
},
{
"type": "Literal",
"type": "Literal",
"start": 31,
"end": 32,
"value": 3,
"raw": "3"
}
]
}
}
]
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,113 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 35,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 35,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 35,
"callee": {
"type": "Identifier",
"start": 0,
"end": 6,
"name": "lineTo"
},
"arguments": [
{
"type": "ObjectExpression",
"type": "ObjectExpression",
"start": 7,
"end": 34,
"properties": [
{
"type": "ObjectProperty",
"start": 9,
"end": 19,
"key": {
"type": "Identifier",
"start": 9,
"end": 11,
"name": "to"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 13,
"end": 19,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 14,
"end": 15,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 17,
"end": 18,
"value": 1,
"raw": "1"
}
]
}
},
{
"type": "ObjectProperty",
"start": 20,
"end": 32,
"key": {
"type": "Identifier",
"start": 20,
"end": 24,
"name": "from"
},
"value": {
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 26,
"end": 32,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 27,
"end": 28,
"value": 3,
"raw": "3"
},
{
"type": "Literal",
"type": "Literal",
"start": 30,
"end": 31,
"value": 3,
"raw": "3"
}
]
}
}
]
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,73 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 37,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 37,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 37,
"id": {
"type": "Identifier",
"start": 6,
"end": 14,
"name": "mySketch"
},
"init": {
"type": "CallExpression",
"type": "CallExpression",
"start": 17,
"end": 37,
"callee": {
"type": "Identifier",
"start": 17,
"end": 30,
"name": "startSketchAt"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 31,
"end": 36,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 32,
"end": 33,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 34,
"end": 35,
"value": 0,
"raw": "0"
}
]
}
],
"optional": false
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,58 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 28,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 28,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 28,
"callee": {
"type": "Identifier",
"start": 0,
"end": 3,
"name": "log"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 4,
"end": 5,
"value": 5,
"raw": "5"
},
{
"type": "Literal",
"type": "Literal",
"start": 7,
"end": 14,
"value": "hello",
"raw": "\"hello\""
},
{
"type": "Identifier",
"type": "Identifier",
"start": 16,
"end": 27,
"name": "aIdentifier"
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,43 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 7,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 7,
"expression": {
"type": "BinaryExpression",
"type": "BinaryExpression",
"start": 0,
"end": 7,
"operator": "+",
"left": {
"type": "Literal",
"type": "Literal",
"start": 0,
"end": 1,
"value": 5,
"raw": "5"
},
"right": {
"type": "Literal",
"type": "Literal",
"start": 4,
"end": 7,
"value": "a",
"raw": "\"a\""
}
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,64 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 15,
"body": [
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 0,
"end": 15,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 0,
"end": 15,
"callee": {
"type": "Identifier",
"start": 0,
"end": 4,
"name": "line"
},
"arguments": [
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 5,
"end": 11,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 6,
"end": 7,
"value": 0,
"raw": "0"
},
{
"type": "Identifier",
"type": "Identifier",
"start": 9,
"end": 10,
"name": "l"
}
]
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 13,
"end": 14
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,158 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 90,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 74,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 74,
"id": {
"type": "Identifier",
"start": 6,
"end": 14,
"name": "cylinder"
},
"init": {
"type": "PipeExpression",
"type": "PipeExpression",
"start": 17,
"end": 74,
"body": [
{
"type": "CallExpression",
"type": "CallExpression",
"start": 17,
"end": 56,
"callee": {
"type": "Identifier",
"start": 17,
"end": 39,
"name": "unstable_stdlib_circle"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 40,
"end": 44,
"value": "XY",
"raw": "'XY'"
},
{
"type": "ArrayExpression",
"type": "ArrayExpression",
"start": 46,
"end": 51,
"elements": [
{
"type": "Literal",
"type": "Literal",
"start": 47,
"end": 48,
"value": 0,
"raw": "0"
},
{
"type": "Literal",
"type": "Literal",
"start": 49,
"end": 50,
"value": 0,
"raw": "0"
}
]
},
{
"type": "Literal",
"type": "Literal",
"start": 53,
"end": 55,
"value": 22,
"raw": "22"
}
],
"optional": false
},
{
"type": "CallExpression",
"type": "CallExpression",
"start": 60,
"end": 74,
"callee": {
"type": "Identifier",
"start": 60,
"end": 67,
"name": "extrude"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 68,
"end": 70,
"value": 14,
"raw": "14"
},
{
"type": "PipeSubstitution",
"type": "PipeSubstitution",
"start": 72,
"end": 73
}
],
"optional": false
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}
}
],
"kind": "const"
},
{
"type": "ExpressionStatement",
"type": "ExpressionStatement",
"start": 75,
"end": 89,
"expression": {
"type": "CallExpression",
"type": "CallExpression",
"start": 75,
"end": 89,
"callee": {
"type": "Identifier",
"start": 75,
"end": 79,
"name": "show"
},
"arguments": [
{
"type": "Identifier",
"type": "Identifier",
"start": 80,
"end": 88,
"name": "cylinder"
}
],
"optional": false
}
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

View File

@ -0,0 +1,95 @@
---
source: kcl/src/parser/parser_impl.rs
expression: actual
---
{
"start": 0,
"end": 36,
"body": [
{
"type": "VariableDeclaration",
"type": "VariableDeclaration",
"start": 0,
"end": 36,
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 36,
"id": {
"type": "Identifier",
"start": 6,
"end": 11,
"name": "myVar"
},
"init": {
"type": "CallExpression",
"type": "CallExpression",
"start": 14,
"end": 36,
"callee": {
"type": "Identifier",
"start": 14,
"end": 17,
"name": "min"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 18,
"end": 19,
"value": 5,
"raw": "5"
},
{
"type": "UnaryExpression",
"type": "UnaryExpression",
"start": 22,
"end": 35,
"operator": "-",
"argument": {
"type": "CallExpression",
"type": "CallExpression",
"start": 23,
"end": 35,
"callee": {
"type": "Identifier",
"start": 23,
"end": 29,
"name": "legLen"
},
"arguments": [
{
"type": "Literal",
"type": "Literal",
"start": 30,
"end": 31,
"value": 5,
"raw": "5"
},
{
"type": "Literal",
"type": "Literal",
"start": 33,
"end": 34,
"value": 4,
"raw": "4"
}
],
"optional": false
}
}
],
"optional": false
}
}
],
"kind": "const"
}
],
"nonCodeMeta": {
"nonCodeNodes": {},
"start": []
}
}

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