allow nested files imported (#7090)
* allow nested files Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix test Signed-off-by: Jess Frazelle <github@jessfraz.com> * disallow bad things Signed-off-by: Jess Frazelle <github@jessfraz.com> * add playwright test on windows Signed-off-by: Jess Frazelle <github@jessfraz.com> * add playwright test on windows Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix test Signed-off-by: Jess Frazelle <github@jessfraz.com> * Update rust/kcl-lib/tests/nested_windows_main_kcl/unparsed@main.kcl.snap Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
This commit is contained in:
@ -2064,3 +2064,59 @@ test(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
test(
|
||||||
|
'nested dir import works on windows',
|
||||||
|
{ tag: ['@electron', '@windows'] },
|
||||||
|
async ({ scene, cmdBar, context, page }, testInfo) => {
|
||||||
|
// Skip if on non-windows
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
test.skip()
|
||||||
|
}
|
||||||
|
await context.folderSetupFn(async (dir) => {
|
||||||
|
const bracketDir = path.join(dir, 'bracket')
|
||||||
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
|
const nestedDir = path.join(bracketDir, 'nested')
|
||||||
|
await fsp.mkdir(nestedDir, { recursive: true })
|
||||||
|
|
||||||
|
await fsp.copyFile(
|
||||||
|
executorInputPath('cylinder-inches.kcl'),
|
||||||
|
path.join(nestedDir, 'main.kcl')
|
||||||
|
)
|
||||||
|
await fsp.writeFile(
|
||||||
|
path.join(bracketDir, 'main.kcl'),
|
||||||
|
`import 'nested\\main.kcl' as thing
|
||||||
|
|
||||||
|
thing`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setBodyDimensions({ width: 1200, height: 500 })
|
||||||
|
const u = await getUtils(page)
|
||||||
|
|
||||||
|
const pointOnModel = { x: 630, y: 280 }
|
||||||
|
|
||||||
|
await test.step('Opening the bracket project should load the stream', async () => {
|
||||||
|
// expect to see the text bracket
|
||||||
|
await expect(page.getByText('bracket')).toBeVisible()
|
||||||
|
|
||||||
|
await page.getByText('bracket').click()
|
||||||
|
|
||||||
|
await scene.settled(cmdBar)
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).toBeEnabled({
|
||||||
|
timeout: 20_000,
|
||||||
|
})
|
||||||
|
|
||||||
|
// gray at this pixel means the stream has loaded in the most
|
||||||
|
// user way we can verify it (pixel color)
|
||||||
|
await expect
|
||||||
|
.poll(() => u.getGreatestPixDiff(pointOnModel, [125, 125, 125]), {
|
||||||
|
timeout: 10_000,
|
||||||
|
})
|
||||||
|
.toBeLessThan(15)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ -35,31 +35,28 @@ impl Default for TypedPath {
|
|||||||
|
|
||||||
impl From<&String> for TypedPath {
|
impl From<&String> for TypedPath {
|
||||||
fn from(path: &String) -> Self {
|
fn from(path: &String) -> Self {
|
||||||
#[cfg(target_arch = "wasm32")]
|
TypedPath::new(path)
|
||||||
{
|
|
||||||
TypedPath(typed_path::TypedPath::derive(path).to_path_buf())
|
|
||||||
}
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
{
|
|
||||||
TypedPath(std::path::PathBuf::from(path))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for TypedPath {
|
impl From<&str> for TypedPath {
|
||||||
fn from(path: &str) -> Self {
|
fn from(path: &str) -> Self {
|
||||||
|
TypedPath::new(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypedPath {
|
||||||
|
pub fn new(path: &str) -> Self {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
TypedPath(typed_path::TypedPath::derive(path).to_path_buf())
|
TypedPath(typed_path::TypedPath::derive(path).to_path_buf())
|
||||||
}
|
}
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
{
|
{
|
||||||
TypedPath(std::path::PathBuf::from(path))
|
TypedPath(normalise_import(path))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedPath {
|
|
||||||
pub fn extension(&self) -> Option<&str> {
|
pub fn extension(&self) -> Option<&str> {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
@ -85,6 +82,17 @@ impl TypedPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn join_typed(&self, path: &TypedPath) -> Self {
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
{
|
||||||
|
TypedPath(self.0.join(path.0.to_path()))
|
||||||
|
}
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
{
|
||||||
|
TypedPath(self.0.join(&path.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parent(&self) -> Option<Self> {
|
pub fn parent(&self) -> Option<Self> {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
@ -206,3 +214,19 @@ impl schemars::JsonSchema for TypedPath {
|
|||||||
gen.subschema_for::<std::path::PathBuf>()
|
gen.subschema_for::<std::path::PathBuf>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Turn `nested\foo\bar\main.kcl` or `nested/foo/bar/main.kcl`
|
||||||
|
/// into a PathBuf that works on the host OS.
|
||||||
|
///
|
||||||
|
/// * Does **not** touch `..` or symlinks – call `canonicalize()` if you need that.
|
||||||
|
/// * Returns an owned `PathBuf` only when normalisation was required.
|
||||||
|
fn normalise_import<S: AsRef<str>>(raw: S) -> std::path::PathBuf {
|
||||||
|
let s = raw.as_ref();
|
||||||
|
// On Unix we need to swap `\` → `/`. On Windows we leave it alone.
|
||||||
|
// (Windows happily consumes `/`)
|
||||||
|
if cfg!(unix) && s.contains('\\') {
|
||||||
|
std::path::PathBuf::from(s.replace('\\', "/"))
|
||||||
|
} else {
|
||||||
|
std::path::Path::new(s).to_path_buf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -185,9 +185,9 @@ impl ModulePath {
|
|||||||
match path {
|
match path {
|
||||||
ImportPath::Kcl { filename: path } | ImportPath::Foreign { path } => {
|
ImportPath::Kcl { filename: path } | ImportPath::Foreign { path } => {
|
||||||
let resolved_path = if let Some(project_dir) = project_directory {
|
let resolved_path = if let Some(project_dir) = project_directory {
|
||||||
project_dir.join(path)
|
project_dir.join_typed(path)
|
||||||
} else {
|
} else {
|
||||||
TypedPath::from(path)
|
path.clone()
|
||||||
};
|
};
|
||||||
ModulePath::Local { value: resolved_path }
|
ModulePath::Local { value: resolved_path }
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR},
|
parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR},
|
||||||
source_range::SourceRange,
|
source_range::SourceRange,
|
||||||
ModuleId,
|
ModuleId, TypedPath,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod condition;
|
mod condition;
|
||||||
@ -1741,8 +1741,8 @@ impl ImportSelector {
|
|||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ImportPath {
|
pub enum ImportPath {
|
||||||
Kcl { filename: String },
|
Kcl { filename: TypedPath },
|
||||||
Foreign { path: String },
|
Foreign { path: TypedPath },
|
||||||
Std { path: Vec<String> },
|
Std { path: Vec<String> },
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1811,16 +1811,14 @@ impl ImportStatement {
|
|||||||
|
|
||||||
match &self.path {
|
match &self.path {
|
||||||
ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => {
|
ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => {
|
||||||
let mut parts = s.split('.');
|
let name = s.file_name().map(|f| f.to_string());
|
||||||
let path = parts.next()?;
|
// Remove the extension if it exists.
|
||||||
let _ext = parts.next()?;
|
let extension = s.extension();
|
||||||
let rest = parts.next();
|
if let Some(extension) = extension {
|
||||||
|
name.map(|n| n.trim_end_matches(extension).trim_end_matches('.').to_string())
|
||||||
if rest.is_some() {
|
} else {
|
||||||
return None;
|
name
|
||||||
}
|
}
|
||||||
|
|
||||||
path.rsplit(&['/', '\\']).next().map(str::to_owned)
|
|
||||||
}
|
}
|
||||||
ImportPath::Std { path } => path.last().cloned(),
|
ImportPath::Std { path } => path.last().cloned(),
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ use crate::{
|
|||||||
token::{Token, TokenSlice, TokenType},
|
token::{Token, TokenSlice, TokenType},
|
||||||
PIPE_OPERATOR, PIPE_SUBSTITUTION_OPERATOR,
|
PIPE_OPERATOR, PIPE_SUBSTITUTION_OPERATOR,
|
||||||
},
|
},
|
||||||
SourceRange, IMPORT_FILE_EXTENSIONS,
|
SourceRange, TypedPath, IMPORT_FILE_EXTENSIONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
@ -1862,7 +1862,7 @@ fn validate_path_string(path_string: String, var_name: bool, path_range: SourceR
|
|||||||
let path = if path_string.ends_with(".kcl") {
|
let path = if path_string.ends_with(".kcl") {
|
||||||
if path_string
|
if path_string
|
||||||
.chars()
|
.chars()
|
||||||
.any(|c| !c.is_ascii_alphanumeric() && c != '_' && c != '-' && c != '.')
|
.any(|c| !c.is_ascii_alphanumeric() && c != '_' && c != '-' && c != '.' && c != '/' && c != '\\')
|
||||||
{
|
{
|
||||||
return Err(ErrMode::Cut(
|
return Err(ErrMode::Cut(
|
||||||
CompilationError::fatal(
|
CompilationError::fatal(
|
||||||
@ -1873,7 +1873,30 @@ fn validate_path_string(path_string: String, var_name: bool, path_range: SourceR
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportPath::Kcl { filename: path_string }
|
if path_string.starts_with("..") {
|
||||||
|
return Err(ErrMode::Cut(
|
||||||
|
CompilationError::fatal(
|
||||||
|
path_range,
|
||||||
|
"import path may not start with '..'. Cannot traverse to something outside the bounds of your project. If this path is inside your project please find a better way to reference it.",
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure they are not using an absolute path.
|
||||||
|
if path_string.starts_with('/') || path_string.starts_with('\\') {
|
||||||
|
return Err(ErrMode::Cut(
|
||||||
|
CompilationError::fatal(
|
||||||
|
path_range,
|
||||||
|
"import path may not start with '/' or '\\'. Cannot traverse to something outside the bounds of your project. If this path is inside your project please find a better way to reference it.",
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportPath::Kcl {
|
||||||
|
filename: TypedPath::new(&path_string),
|
||||||
|
}
|
||||||
} else if path_string.starts_with("std::") {
|
} else if path_string.starts_with("std::") {
|
||||||
ParseContext::warn(CompilationError::err(
|
ParseContext::warn(CompilationError::err(
|
||||||
path_range,
|
path_range,
|
||||||
@ -1910,7 +1933,9 @@ fn validate_path_string(path_string: String, var_name: bool, path_range: SourceR
|
|||||||
format!("unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}", IMPORT_FILE_EXTENSIONS.join(", ")),
|
format!("unsupported import path format. KCL files can be imported from the current project, CAD files with the following formats are supported: {}", IMPORT_FILE_EXTENSIONS.join(", ")),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
ImportPath::Foreign { path: path_string }
|
ImportPath::Foreign {
|
||||||
|
path: TypedPath::new(&path_string),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(ErrMode::Cut(
|
return Err(ErrMode::Cut(
|
||||||
CompilationError::fatal(
|
CompilationError::fatal(
|
||||||
@ -4534,6 +4559,16 @@ e
|
|||||||
fn bad_imports() {
|
fn bad_imports() {
|
||||||
assert_err(
|
assert_err(
|
||||||
r#"import cube from "../cube.kcl""#,
|
r#"import cube from "../cube.kcl""#,
|
||||||
|
"import path may not start with '..'. Cannot traverse to something outside the bounds of your project. If this path is inside your project please find a better way to reference it.",
|
||||||
|
[17, 30],
|
||||||
|
);
|
||||||
|
assert_err(
|
||||||
|
r#"import cube from "/cube.kcl""#,
|
||||||
|
"import path may not start with '/' or '\\'. Cannot traverse to something outside the bounds of your project. If this path is inside your project please find a better way to reference it.",
|
||||||
|
[17, 28],
|
||||||
|
);
|
||||||
|
assert_err(
|
||||||
|
r#"import cube from "C:\cube.kcl""#,
|
||||||
"import path may only contain alphanumeric characters, underscore, hyphen, and period. KCL files in other directories are not yet supported.",
|
"import path may only contain alphanumeric characters, underscore, hyphen, and period. KCL files in other directories are not yet supported.",
|
||||||
[17, 30],
|
[17, 30],
|
||||||
);
|
);
|
||||||
|
@ -3276,3 +3276,45 @@ mod subtract_regression10 {
|
|||||||
super::execute(TEST_NAME, true).await
|
super::execute(TEST_NAME, true).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mod nested_main_kcl {
|
||||||
|
const TEST_NAME: &str = "nested_main_kcl";
|
||||||
|
|
||||||
|
/// Test parsing KCL.
|
||||||
|
#[test]
|
||||||
|
fn parse() {
|
||||||
|
super::parse(TEST_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn unparse() {
|
||||||
|
super::unparse(TEST_NAME).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that KCL is executed correctly.
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn kcl_test_execute() {
|
||||||
|
super::execute(TEST_NAME, true).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod nested_windows_main_kcl {
|
||||||
|
const TEST_NAME: &str = "nested_windows_main_kcl";
|
||||||
|
|
||||||
|
/// Test parsing KCL.
|
||||||
|
#[test]
|
||||||
|
fn parse() {
|
||||||
|
super::parse(TEST_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that parsing and unparsing KCL produces the original KCL input.
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn unparse() {
|
||||||
|
super::unparse(TEST_NAME).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that KCL is executed correctly.
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn kcl_test_execute() {
|
||||||
|
super::execute(TEST_NAME, true).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
184
rust/kcl-lib/tests/nested_main_kcl/artifact_commands.snap
Normal file
184
rust/kcl-lib/tests/nested_main_kcl/artifact_commands.snap
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Artifact commands nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "edge_lines_visible",
|
||||||
|
"hidden": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_visible",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_visible",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "make_plane",
|
||||||
|
"origin": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"x_axis": {
|
||||||
|
"x": 1.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"y_axis": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 1.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"size": 60.0,
|
||||||
|
"clobber": false,
|
||||||
|
"hide": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "close_path",
|
||||||
|
"path_id": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "enable_sketch_mode",
|
||||||
|
"entity_id": "[uuid]",
|
||||||
|
"ortho": false,
|
||||||
|
"animated": false,
|
||||||
|
"adjust_camera": false,
|
||||||
|
"planar_normal": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "extend_path",
|
||||||
|
"path": "[uuid]",
|
||||||
|
"segment": {
|
||||||
|
"type": "arc",
|
||||||
|
"center": {
|
||||||
|
"x": 15.0,
|
||||||
|
"y": 0.0
|
||||||
|
},
|
||||||
|
"radius": 5.0,
|
||||||
|
"start": {
|
||||||
|
"unit": "degrees",
|
||||||
|
"value": 0.0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"unit": "degrees",
|
||||||
|
"value": 360.0
|
||||||
|
},
|
||||||
|
"relative": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "move_path_pen",
|
||||||
|
"path": "[uuid]",
|
||||||
|
"to": {
|
||||||
|
"x": 20.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "sketch_mode_disable"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "start_path"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_bring_to_front",
|
||||||
|
"object_id": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "revolve",
|
||||||
|
"target": "[uuid]",
|
||||||
|
"origin": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"axis": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 1.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"axis_is_2d": true,
|
||||||
|
"angle": {
|
||||||
|
"unit": "degrees",
|
||||||
|
"value": 360.0
|
||||||
|
},
|
||||||
|
"tolerance": 0.0000001,
|
||||||
|
"opposite": "None"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "solid3d_get_adjacency_info",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"edge_id": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "solid3d_get_extrusion_face_info",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"edge_id": "[uuid]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Artifact graph flowchart nested_main_kcl.kcl
|
||||||
|
extension: md
|
||||||
|
snapshot_kind: binary
|
||||||
|
---
|
@ -0,0 +1,23 @@
|
|||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
subgraph path2 [Path]
|
||||||
|
2["Path<br>[43, 81, 1]"]
|
||||||
|
3["Segment<br>[43, 81, 1]"]
|
||||||
|
4[Solid2d]
|
||||||
|
end
|
||||||
|
1["Plane<br>[18, 35, 1]"]
|
||||||
|
5["Sweep Revolve<br>[89, 142, 1]"]
|
||||||
|
6[Wall]
|
||||||
|
%% face_code_ref=Missing NodePath
|
||||||
|
7["SweepEdge Adjacent"]
|
||||||
|
1 --- 2
|
||||||
|
2 --- 3
|
||||||
|
2 --- 4
|
||||||
|
2 ---- 5
|
||||||
|
5 <--x 3
|
||||||
|
3 --- 6
|
||||||
|
3 --- 7
|
||||||
|
5 --- 6
|
||||||
|
5 --- 7
|
||||||
|
6 --- 7
|
||||||
|
```
|
73
rust/kcl-lib/tests/nested_main_kcl/ast.snap
Normal file
73
rust/kcl-lib/tests/nested_main_kcl/ast.snap
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of parsing nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"Ok": {
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"path": {
|
||||||
|
"type": "Kcl",
|
||||||
|
"filename": "nested/foo/bar/main.kcl"
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"type": "None",
|
||||||
|
"alias": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "bar",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "ImportStatement",
|
||||||
|
"type": "ImportStatement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"expression": {
|
||||||
|
"abs_path": false,
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "bar",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"path": [],
|
||||||
|
"start": 0,
|
||||||
|
"type": "Name",
|
||||||
|
"type": "Name"
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "ExpressionStatement",
|
||||||
|
"type": "ExpressionStatement"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"nonCodeMeta": {
|
||||||
|
"nonCodeNodes": {
|
||||||
|
"0": [
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"start": 0,
|
||||||
|
"type": "NonCodeNode",
|
||||||
|
"value": {
|
||||||
|
"type": "newLine"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"startNodes": []
|
||||||
|
},
|
||||||
|
"start": 0
|
||||||
|
}
|
||||||
|
}
|
3
rust/kcl-lib/tests/nested_main_kcl/input.kcl
Normal file
3
rust/kcl-lib/tests/nested_main_kcl/input.kcl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import "nested/foo/bar/main.kcl" as bar
|
||||||
|
|
||||||
|
bar
|
@ -0,0 +1,7 @@
|
|||||||
|
// A donut shape.
|
||||||
|
startSketchOn(XY)
|
||||||
|
|> circle( center = [15, 0], radius = 5 )
|
||||||
|
|> revolve(
|
||||||
|
angle = 360,
|
||||||
|
axis = Y,
|
||||||
|
)
|
18
rust/kcl-lib/tests/nested_main_kcl/ops.snap
Normal file
18
rust/kcl-lib/tests/nested_main_kcl/ops.snap
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Operations executed nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "GroupBegin",
|
||||||
|
"group": {
|
||||||
|
"type": "ModuleInstance",
|
||||||
|
"name": "main.kcl",
|
||||||
|
"moduleId": 0
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GroupEnd"
|
||||||
|
}
|
||||||
|
]
|
10
rust/kcl-lib/tests/nested_main_kcl/program_memory.snap
Normal file
10
rust/kcl-lib/tests/nested_main_kcl/program_memory.snap
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Variables in memory after executing nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"bar": {
|
||||||
|
"type": "Module",
|
||||||
|
"value": 1
|
||||||
|
}
|
||||||
|
}
|
BIN
rust/kcl-lib/tests/nested_main_kcl/rendered_model.png
Normal file
BIN
rust/kcl-lib/tests/nested_main_kcl/rendered_model.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 150 KiB |
7
rust/kcl-lib/tests/nested_main_kcl/unparsed.snap
Normal file
7
rust/kcl-lib/tests/nested_main_kcl/unparsed.snap
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of unparsing nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
import "nested/foo/bar/main.kcl" as bar
|
||||||
|
|
||||||
|
bar
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of unparsing tests/nested_main_kcl/nested/foo/bar/main.kcl
|
||||||
|
---
|
||||||
|
// A donut shape.
|
||||||
|
startSketchOn(XY)
|
||||||
|
|> circle(center = [15, 0], radius = 5)
|
||||||
|
|> revolve(angle = 360, axis = Y)
|
@ -0,0 +1,184 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Artifact commands nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "edge_lines_visible",
|
||||||
|
"hidden": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_visible",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_visible",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "make_plane",
|
||||||
|
"origin": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"x_axis": {
|
||||||
|
"x": 1.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"y_axis": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 1.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"size": 60.0,
|
||||||
|
"clobber": false,
|
||||||
|
"hide": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "close_path",
|
||||||
|
"path_id": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "enable_sketch_mode",
|
||||||
|
"entity_id": "[uuid]",
|
||||||
|
"ortho": false,
|
||||||
|
"animated": false,
|
||||||
|
"adjust_camera": false,
|
||||||
|
"planar_normal": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "extend_path",
|
||||||
|
"path": "[uuid]",
|
||||||
|
"segment": {
|
||||||
|
"type": "arc",
|
||||||
|
"center": {
|
||||||
|
"x": 15.0,
|
||||||
|
"y": 0.0
|
||||||
|
},
|
||||||
|
"radius": 5.0,
|
||||||
|
"start": {
|
||||||
|
"unit": "degrees",
|
||||||
|
"value": 0.0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"unit": "degrees",
|
||||||
|
"value": 360.0
|
||||||
|
},
|
||||||
|
"relative": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "move_path_pen",
|
||||||
|
"path": "[uuid]",
|
||||||
|
"to": {
|
||||||
|
"x": 20.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "sketch_mode_disable"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "start_path"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_bring_to_front",
|
||||||
|
"object_id": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "revolve",
|
||||||
|
"target": "[uuid]",
|
||||||
|
"origin": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"axis": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 1.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"axis_is_2d": true,
|
||||||
|
"angle": {
|
||||||
|
"unit": "degrees",
|
||||||
|
"value": 360.0
|
||||||
|
},
|
||||||
|
"tolerance": 0.0000001,
|
||||||
|
"opposite": "None"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "solid3d_get_adjacency_info",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"edge_id": "[uuid]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "solid3d_get_extrusion_face_info",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"edge_id": "[uuid]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Artifact graph flowchart nested_main_kcl.kcl
|
||||||
|
extension: md
|
||||||
|
snapshot_kind: binary
|
||||||
|
---
|
@ -0,0 +1,23 @@
|
|||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
subgraph path2 [Path]
|
||||||
|
2["Path<br>[43, 81, 1]"]
|
||||||
|
3["Segment<br>[43, 81, 1]"]
|
||||||
|
4[Solid2d]
|
||||||
|
end
|
||||||
|
1["Plane<br>[18, 35, 1]"]
|
||||||
|
5["Sweep Revolve<br>[89, 142, 1]"]
|
||||||
|
6[Wall]
|
||||||
|
%% face_code_ref=Missing NodePath
|
||||||
|
7["SweepEdge Adjacent"]
|
||||||
|
1 --- 2
|
||||||
|
2 --- 3
|
||||||
|
2 --- 4
|
||||||
|
2 ---- 5
|
||||||
|
5 <--x 3
|
||||||
|
3 --- 6
|
||||||
|
3 --- 7
|
||||||
|
5 --- 6
|
||||||
|
5 --- 7
|
||||||
|
6 --- 7
|
||||||
|
```
|
73
rust/kcl-lib/tests/nested_windows_main_kcl/ast.snap
Normal file
73
rust/kcl-lib/tests/nested_windows_main_kcl/ast.snap
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of parsing nested_windows_main_kcl.kcl
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"Ok": {
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"path": {
|
||||||
|
"type": "Kcl",
|
||||||
|
"filename": "nested/foo/bar/main.kcl"
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"type": "None",
|
||||||
|
"alias": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "bar",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "ImportStatement",
|
||||||
|
"type": "ImportStatement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"expression": {
|
||||||
|
"abs_path": false,
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "bar",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"path": [],
|
||||||
|
"start": 0,
|
||||||
|
"type": "Name",
|
||||||
|
"type": "Name"
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "ExpressionStatement",
|
||||||
|
"type": "ExpressionStatement"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"nonCodeMeta": {
|
||||||
|
"nonCodeNodes": {
|
||||||
|
"0": [
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"start": 0,
|
||||||
|
"type": "NonCodeNode",
|
||||||
|
"value": {
|
||||||
|
"type": "newLine"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"startNodes": []
|
||||||
|
},
|
||||||
|
"start": 0
|
||||||
|
}
|
||||||
|
}
|
3
rust/kcl-lib/tests/nested_windows_main_kcl/input.kcl
Normal file
3
rust/kcl-lib/tests/nested_windows_main_kcl/input.kcl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import "nested\foo\bar\main.kcl" as bar
|
||||||
|
|
||||||
|
bar
|
@ -0,0 +1,7 @@
|
|||||||
|
// A donut shape.
|
||||||
|
startSketchOn(XY)
|
||||||
|
|> circle( center = [15, 0], radius = 5 )
|
||||||
|
|> revolve(
|
||||||
|
angle = 360,
|
||||||
|
axis = Y,
|
||||||
|
)
|
18
rust/kcl-lib/tests/nested_windows_main_kcl/ops.snap
Normal file
18
rust/kcl-lib/tests/nested_windows_main_kcl/ops.snap
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Operations executed nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "GroupBegin",
|
||||||
|
"group": {
|
||||||
|
"type": "ModuleInstance",
|
||||||
|
"name": "main.kcl",
|
||||||
|
"moduleId": 0
|
||||||
|
},
|
||||||
|
"sourceRange": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GroupEnd"
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Variables in memory after executing nested_main_kcl.kcl
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"bar": {
|
||||||
|
"type": "Module",
|
||||||
|
"value": 1
|
||||||
|
}
|
||||||
|
}
|
BIN
rust/kcl-lib/tests/nested_windows_main_kcl/rendered_model.png
Normal file
BIN
rust/kcl-lib/tests/nested_windows_main_kcl/rendered_model.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 150 KiB |
7
rust/kcl-lib/tests/nested_windows_main_kcl/unparsed.snap
Normal file
7
rust/kcl-lib/tests/nested_windows_main_kcl/unparsed.snap
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of unparsing nested_windows_main_kcl.kcl
|
||||||
|
---
|
||||||
|
import "nested/foo/bar/main.kcl" as bar
|
||||||
|
|
||||||
|
bar
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of unparsing tests/nested_windows_main_kcl/nested/foo/bar/main.kcl
|
||||||
|
---
|
||||||
|
// A donut shape.
|
||||||
|
startSketchOn(XY)
|
||||||
|
|> circle(center = [15, 0], radius = 5)
|
||||||
|
|> revolve(angle = 360, axis = Y)
|
@ -86,11 +86,11 @@ flowchart LR
|
|||||||
8 --- 18
|
8 --- 18
|
||||||
8 ---- 20
|
8 ---- 20
|
||||||
8 --- 21
|
8 --- 21
|
||||||
12 --- 22
|
12 <--x 22
|
||||||
12 <--x 23
|
12 --- 23
|
||||||
12 <--x 24
|
12 <--x 24
|
||||||
16 --- 25
|
16 <--x 25
|
||||||
16 <--x 26
|
16 --- 26
|
||||||
16 <--x 27
|
16 <--x 27
|
||||||
19 --- 22
|
19 --- 22
|
||||||
19 --- 23
|
19 --- 23
|
||||||
|
Reference in New Issue
Block a user