Compare commits
8 Commits
remove-ext
...
jtran/pars
Author | SHA1 | Date | |
---|---|---|---|
a5daa38ea7 | |||
744da59a4b | |||
1506de92f5 | |||
8a03413643 | |||
f59b806a88 | |||
23a0085c78 | |||
a280a8c3f0 | |||
11620dfa6b |
@ -256720,7 +256720,7 @@
|
||||
false
|
||||
],
|
||||
[
|
||||
"// Create a spring by sweeping around a helix path.\n\n// Create a helix around the Z axis.\nhelixPath = helix(\n angleStart = 0,\n ccw = true,\n revolutions = 4,\n length = 10,\n radius = 5,\n axis = Z,\n)\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn(YZ)\n |> circle(center = [0, 0], radius = 1)\n |> sweep(path = helixPath, relativeTo = \"sketchPlane\")",
|
||||
"// Create a spring by sweeping around a helix path.\n\n// Create a helix around the Z axis.\nhelixPath = helix(\n angleStart = 0,\n ccw = true,\n revolutions = 4,\n length = 10,\n radius = 5,\n axis = Z,\n)\n\n// Create a spring by sweeping around the helix path.\nspringSketch = startSketchOn(XZ)\n |> circle(center = [5, 0], radius = 1)\n |> sweep(path = helixPath)",
|
||||
false
|
||||
],
|
||||
[
|
||||
|
@ -6,7 +6,6 @@ test.describe('Onboarding tests', () => {
|
||||
homePage,
|
||||
toolbar,
|
||||
editor,
|
||||
scene,
|
||||
tronApp,
|
||||
}) => {
|
||||
if (!tronApp) {
|
||||
@ -62,7 +61,6 @@ test.describe('Onboarding tests', () => {
|
||||
await editor.expectEditor.toContain('@settings(defaultLengthUnit = in)', {
|
||||
shouldNormalise: true,
|
||||
})
|
||||
await scene.connectionEstablished()
|
||||
})
|
||||
|
||||
await test.step('Go home and verify we still see the tutorial button, then begin it.', async () => {
|
||||
@ -132,9 +130,7 @@ test.describe('Onboarding tests', () => {
|
||||
})
|
||||
|
||||
await test.step('Dismiss the onboarding', async () => {
|
||||
await postDismissToast.waitFor({ state: 'hidden' })
|
||||
await page.keyboard.press('Escape')
|
||||
await expect(postDismissToast).toBeVisible()
|
||||
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
||||
await expect.poll(() => page.url()).not.toContain('/onboarding')
|
||||
})
|
||||
@ -162,13 +158,10 @@ test.describe('Onboarding tests', () => {
|
||||
await test.step('Gets to the onboarding start', async () => {
|
||||
await expect(toolbar.projectName).toContainText('tutorial-project')
|
||||
await expect(tutorialWelcomeHeading).toBeVisible()
|
||||
await scene.connectionEstablished()
|
||||
})
|
||||
|
||||
await test.step('Dismiss the onboarding', async () => {
|
||||
await postDismissToast.waitFor({ state: 'hidden' })
|
||||
await page.keyboard.press('Escape')
|
||||
await expect(postDismissToast).toBeVisible()
|
||||
await expect(page.getByTestId('onboarding-content')).not.toBeVisible()
|
||||
await expect.poll(() => page.url()).not.toContain('/onboarding')
|
||||
})
|
||||
|
@ -1,19 +1,22 @@
|
||||
@precedence {
|
||||
annotation
|
||||
typeCall
|
||||
member
|
||||
call
|
||||
exp @left
|
||||
mult @left
|
||||
add @left
|
||||
ascription @left
|
||||
comp @left
|
||||
logic @left
|
||||
pipe @left
|
||||
range
|
||||
statement
|
||||
}
|
||||
|
||||
@top Program {
|
||||
Shebang?
|
||||
statement*
|
||||
(statement !statement statement*)?
|
||||
}
|
||||
|
||||
statement[@isGroup=Statement] {
|
||||
@ -52,12 +55,15 @@ expression[@isGroup=Expression] {
|
||||
UnaryExpression { UnaryOp expression } |
|
||||
ParenthesizedExpression { "(" expression ")" } |
|
||||
IfExpression { kw<"if"> expression Body kw<"else"> Body } |
|
||||
CallExpression { expression !call ArgumentList } |
|
||||
// We don't currently support arbitrary expressions as the callee part of a
|
||||
// function call.
|
||||
CallExpression { identifier !call ArgumentList } |
|
||||
ArrayExpression { "[" commaSep<expression | IntegerRange { expression !range ".." expression }> "]" } |
|
||||
ObjectExpression { "{" commaSep<ObjectProperty> "}" } |
|
||||
MemberExpression { expression !member "." PropertyName } |
|
||||
SubscriptExpression { expression !member "[" expression "]" } |
|
||||
PipeExpression { expression (!pipe PipeOperator expression)+ }
|
||||
PipeExpression { expression (!pipe PipeOperator expression)+ } |
|
||||
AscribedExpression { expression !ascription ":" type }
|
||||
}
|
||||
|
||||
UnaryOp { AddOp | BangOp }
|
||||
@ -75,7 +81,7 @@ LabeledArgument { ArgumentLabel Equals expression }
|
||||
ArgumentList { "(" commaSep<LabeledArgument | expression> ")" }
|
||||
|
||||
type[@isGroup=Type] {
|
||||
PrimitiveType { identifier } |
|
||||
PrimitiveType { identifier !typeCall ("(" identifier ")")? } |
|
||||
ArrayType { "[" type !member (";" Number "+"?)? "]" } |
|
||||
ObjectType { "{" commaSep<ObjectProperty { PropertyName ":" type }> "}" }
|
||||
}
|
||||
|
13
packages/codemirror-lang-kcl/test/ascription.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# primitive
|
||||
|
||||
true: bool
|
||||
|
||||
==>
|
||||
Program(ExpressionStatement(AscribedExpression(true, ":", PrimitiveType)))
|
||||
|
||||
# numeric units
|
||||
|
||||
3.5: number(mm)
|
||||
|
||||
==>
|
||||
Program(ExpressionStatement(AscribedExpression(3.5, ":", PrimitiveType)))
|
@ -129,6 +129,7 @@ impl From<KclErrorWithOutputs> for KclError {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KclErrorWithOutputs {
|
||||
pub error: KclError,
|
||||
pub non_fatal: Vec<CompilationError>,
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
pub operations: Vec<Operation>,
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
@ -141,8 +142,10 @@ pub struct KclErrorWithOutputs {
|
||||
}
|
||||
|
||||
impl KclErrorWithOutputs {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
error: KclError,
|
||||
non_fatal: Vec<CompilationError>,
|
||||
#[cfg(feature = "artifact-graph")] operations: Vec<Operation>,
|
||||
#[cfg(feature = "artifact-graph")] artifact_commands: Vec<ArtifactCommand>,
|
||||
#[cfg(feature = "artifact-graph")] artifact_graph: ArtifactGraph,
|
||||
@ -152,6 +155,7 @@ impl KclErrorWithOutputs {
|
||||
) -> Self {
|
||||
Self {
|
||||
error,
|
||||
non_fatal,
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
operations,
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
@ -166,6 +170,7 @@ impl KclErrorWithOutputs {
|
||||
pub fn no_outputs(error: KclError) -> Self {
|
||||
Self {
|
||||
error,
|
||||
non_fatal: Default::default(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
operations: Default::default(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
|
@ -1467,7 +1467,6 @@ impl Node<CallExpressionKw> {
|
||||
.await
|
||||
.map_err(|e| {
|
||||
// Add the call expression to the source ranges.
|
||||
// TODO currently ignored by the frontend
|
||||
e.add_source_ranges(vec![callsite])
|
||||
})?;
|
||||
|
||||
|
@ -823,6 +823,7 @@ impl ExecutorContext {
|
||||
|
||||
KclErrorWithOutputs::new(
|
||||
err,
|
||||
exec_state.errors().to_vec(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
exec_state.global.operations.clone(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
@ -999,6 +1000,7 @@ impl ExecutorContext {
|
||||
|
||||
return Err(KclErrorWithOutputs::new(
|
||||
e,
|
||||
exec_state.errors().to_vec(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
exec_state.global.operations.clone(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
@ -1048,6 +1050,7 @@ impl ExecutorContext {
|
||||
|
||||
KclErrorWithOutputs::new(
|
||||
err,
|
||||
exec_state.errors().to_vec(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
exec_state.global.operations.clone(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
@ -1100,6 +1103,7 @@ impl ExecutorContext {
|
||||
|
||||
KclErrorWithOutputs::new(
|
||||
e,
|
||||
exec_state.errors().to_vec(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
exec_state.global.operations.clone(),
|
||||
#[cfg(feature = "artifact-graph")]
|
||||
|
@ -1277,7 +1277,15 @@ impl KclValue {
|
||||
.satisfied(values.len(), allow_shrink)
|
||||
.ok_or(CoercionError::from(self))?;
|
||||
|
||||
assert!(len <= values.len());
|
||||
if len > values.len() {
|
||||
let message = format!(
|
||||
"Internal: Expected coerced array length {len} to be less than or equal to original length {}",
|
||||
values.len()
|
||||
);
|
||||
exec_state.err(CompilationError::err(self.into(), message.clone()));
|
||||
#[cfg(debug_assertions)]
|
||||
panic!("{message}");
|
||||
}
|
||||
values.truncate(len);
|
||||
|
||||
Ok(KclValue::HomArray {
|
||||
|
@ -110,9 +110,9 @@ pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
||||
///
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(YZ)
|
||||
/// |> circle( center = [0, 0], radius = 1)
|
||||
/// |> sweep(path = helixPath, relativeTo = "sketchPlane")
|
||||
/// springSketch = startSketchOn(XZ)
|
||||
/// |> circle( center = [5, 0], radius = 1)
|
||||
/// |> sweep(path = helixPath)
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -82,9 +82,9 @@ export END = 'end'
|
||||
/// )
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(YZ)
|
||||
/// |> circle( center = [0, 0], radius = 0.5)
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// springSketch = startSketchOn(XZ)
|
||||
/// |> circle( center = [5, 0], radius = 0.5)
|
||||
/// |> sweep(path = helixPath)
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
@ -103,9 +103,9 @@ export END = 'end'
|
||||
/// )
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(XY)
|
||||
/// |> circle( center = [0, 0], radius = 0.5 )
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// springSketch = startSketchOn(XZ)
|
||||
/// |> circle( center = [5, 0], radius = 0.5 )
|
||||
/// |> sweep(path = helixPath)
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
@ -123,9 +123,9 @@ export END = 'end'
|
||||
/// )
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// springSketch = startSketchOn(XY)
|
||||
/// |> circle( center = [0, 0], radius = 1 )
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// springSketch = startSketchOn(XZ)
|
||||
/// |> circle( center = [5, 0], radius = 1 )
|
||||
/// |> sweep(path = helixPath)
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
@ -408,13 +408,13 @@ export fn offsetPlane(
|
||||
/// )
|
||||
///
|
||||
///
|
||||
/// springSketch = startSketchOn(YZ)
|
||||
/// springSketch = startSketchOn(XZ)
|
||||
/// |> circle( center = [0, 0], radius = 1)
|
||||
///
|
||||
/// // Create a spring by sweeping around the helix path.
|
||||
/// sweepedSpring = clone(springSketch)
|
||||
/// |> translate(x=100)
|
||||
/// |> sweep(path = helixPath, relativeTo = sweep::SKETCH_PLANE)
|
||||
/// |> translate(x=5)
|
||||
/// |> sweep(path = helixPath)
|
||||
/// ```
|
||||
///
|
||||
/// ```kcl
|
||||
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 185 KiB |
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 187 KiB |
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 185 KiB |
@ -83,7 +83,7 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
<div className="flex flex-1 flex-wrap gap-2">
|
||||
<p
|
||||
data-command-name={selectedCommand?.name}
|
||||
className="pr-4 flex gap-2 items-center"
|
||||
className="pr-2 flex gap-2 items-center"
|
||||
>
|
||||
{selectedCommand &&
|
||||
'icon' in selectedCommand &&
|
||||
@ -93,6 +93,13 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
<span data-testid="command-name">
|
||||
{selectedCommand.displayName || selectedCommand.name}
|
||||
</span>
|
||||
{selectedCommand.status === 'experimental' ? (
|
||||
<span className="text-ml-black text-xs bg-ml-green rounded-full ml-2 px-2 py-1">
|
||||
experimental
|
||||
</span>
|
||||
) : (
|
||||
<span className="pr-2" />
|
||||
)}
|
||||
</p>
|
||||
{Object.entries(nonHiddenArgs || {})
|
||||
.filter(([_, argConfig]) =>
|
||||
@ -124,7 +131,9 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
key={argName}
|
||||
className={`relative w-fit px-2 py-1 rounded-sm flex gap-2 items-center border ${
|
||||
argName === currentArgument?.name
|
||||
? 'disabled:bg-primary/10 dark:disabled:bg-primary/20 disabled:border-primary dark:disabled:border-primary disabled:text-chalkboard-100 dark:disabled:text-chalkboard-10'
|
||||
? selectedCommand.status === 'experimental'
|
||||
? 'disabled:bg-ml-green/10 dark:disabled:bg-ml-green/20 disabled:border-ml-green dark:disabled:border-ml-green disabled:text-chalkboard-100 dark:disabled:text-chalkboard-10'
|
||||
: 'disabled:bg-primary/10 dark:disabled:bg-primary/20 disabled:border-primary dark:disabled:border-primary disabled:text-chalkboard-100 dark:disabled:text-chalkboard-10'
|
||||
: 'bg-chalkboard-20/50 dark:bg-chalkboard-80/50 border-chalkboard-20 dark:border-chalkboard-80'
|
||||
}`}
|
||||
>
|
||||
@ -196,7 +205,29 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{isReviewing ? <ReviewingButton /> : <GatheringArgsButton />}
|
||||
{isReviewing ? (
|
||||
<ReviewingButton
|
||||
bgClassName={
|
||||
selectedCommand.status === 'experimental' ? '!bg-ml-green' : ''
|
||||
}
|
||||
iconClassName={
|
||||
selectedCommand.status === 'experimental'
|
||||
? '!text-ml-black'
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<GatheringArgsButton
|
||||
bgClassName={
|
||||
selectedCommand.status === 'experimental' ? '!bg-ml-green' : ''
|
||||
}
|
||||
iconClassName={
|
||||
selectedCommand.status === 'experimental'
|
||||
? '!text-ml-black'
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="block w-full my-2 h-[1px] bg-chalkboard-20 dark:bg-chalkboard-80" />
|
||||
{children}
|
||||
@ -205,7 +236,8 @@ function CommandBarHeader({ children }: React.PropsWithChildren<object>) {
|
||||
)
|
||||
}
|
||||
|
||||
function ReviewingButton() {
|
||||
type ButtonProps = { bgClassName?: string; iconClassName?: string }
|
||||
function ReviewingButton({ bgClassName, iconClassName }: ButtonProps) {
|
||||
return (
|
||||
<ActionButton
|
||||
Element="button"
|
||||
@ -216,8 +248,8 @@ function ReviewingButton() {
|
||||
data-testid="command-bar-submit"
|
||||
iconStart={{
|
||||
icon: 'checkmark',
|
||||
bgClassName: 'p-1 rounded-sm !bg-primary hover:brightness-110',
|
||||
iconClassName: '!text-chalkboard-10',
|
||||
bgClassName: `p-1 rounded-sm !bg-primary hover:brightness-110 ${bgClassName}`,
|
||||
iconClassName: `!text-chalkboard-10 ${iconClassName}`,
|
||||
}}
|
||||
>
|
||||
<span className="sr-only">Submit command</span>
|
||||
@ -225,7 +257,7 @@ function ReviewingButton() {
|
||||
)
|
||||
}
|
||||
|
||||
function GatheringArgsButton() {
|
||||
function GatheringArgsButton({ bgClassName, iconClassName }: ButtonProps) {
|
||||
return (
|
||||
<ActionButton
|
||||
Element="button"
|
||||
@ -235,8 +267,8 @@ function GatheringArgsButton() {
|
||||
data-testid="command-bar-continue"
|
||||
iconStart={{
|
||||
icon: 'arrowRight',
|
||||
bgClassName: 'p-1 rounded-sm !bg-primary hover:brightness-110',
|
||||
iconClassName: '!text-chalkboard-10',
|
||||
bgClassName: `p-1 rounded-sm !bg-primary hover:brightness-110 ${bgClassName}`,
|
||||
iconClassName: `!text-chalkboard-10 ${iconClassName}`,
|
||||
}}
|
||||
>
|
||||
<span className="sr-only">Continue</span>
|
||||
|
@ -12,6 +12,7 @@ describe('test kclErrToDiagnostic', () => {
|
||||
kind: 'semantic',
|
||||
msg: 'Semantic error',
|
||||
sourceRange: topLevelRange(0, 1),
|
||||
nonFatal: [],
|
||||
operations: [],
|
||||
artifactCommands: [],
|
||||
artifactGraph: defaultArtifactGraph(),
|
||||
@ -24,6 +25,7 @@ describe('test kclErrToDiagnostic', () => {
|
||||
kind: 'type',
|
||||
msg: 'Type error',
|
||||
sourceRange: topLevelRange(4, 5),
|
||||
nonFatal: [],
|
||||
operations: [],
|
||||
artifactCommands: [],
|
||||
artifactGraph: defaultArtifactGraph(),
|
||||
|
@ -24,6 +24,7 @@ export class KCLError extends Error {
|
||||
kind: ExtractKind<RustKclError> | 'name'
|
||||
sourceRange: SourceRange
|
||||
msg: string
|
||||
nonFatal: CompilationError[]
|
||||
operations: Operation[]
|
||||
artifactCommands: ArtifactCommand[]
|
||||
artifactGraph: ArtifactGraph
|
||||
@ -34,6 +35,7 @@ export class KCLError extends Error {
|
||||
kind: ExtractKind<RustKclError> | 'name',
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[] = [],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -44,6 +46,7 @@ export class KCLError extends Error {
|
||||
this.kind = kind
|
||||
this.msg = msg
|
||||
this.sourceRange = sourceRange
|
||||
this.nonFatal = nonFatal
|
||||
this.operations = operations
|
||||
this.artifactCommands = artifactCommands
|
||||
this.artifactGraph = artifactGraph
|
||||
@ -57,6 +60,7 @@ export class KCLLexicalError extends KCLError {
|
||||
constructor(
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -67,6 +71,7 @@ export class KCLLexicalError extends KCLError {
|
||||
'lexical',
|
||||
msg,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -81,6 +86,7 @@ export class KCLInternalError extends KCLError {
|
||||
constructor(
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -91,6 +97,7 @@ export class KCLInternalError extends KCLError {
|
||||
'internal',
|
||||
msg,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -105,6 +112,7 @@ export class KCLSyntaxError extends KCLError {
|
||||
constructor(
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -115,6 +123,7 @@ export class KCLSyntaxError extends KCLError {
|
||||
'syntax',
|
||||
msg,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -129,6 +138,7 @@ export class KCLSemanticError extends KCLError {
|
||||
constructor(
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -139,6 +149,7 @@ export class KCLSemanticError extends KCLError {
|
||||
'semantic',
|
||||
msg,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -153,6 +164,7 @@ export class KCLTypeError extends KCLError {
|
||||
constructor(
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -163,6 +175,7 @@ export class KCLTypeError extends KCLError {
|
||||
'type',
|
||||
msg,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -177,6 +190,7 @@ export class KCLIoError extends KCLError {
|
||||
constructor(
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -187,6 +201,7 @@ export class KCLIoError extends KCLError {
|
||||
'io',
|
||||
msg,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -201,6 +216,7 @@ export class KCLUnexpectedError extends KCLError {
|
||||
constructor(
|
||||
msg: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -211,6 +227,7 @@ export class KCLUnexpectedError extends KCLError {
|
||||
'unexpected',
|
||||
msg,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -225,6 +242,7 @@ export class KCLValueAlreadyDefined extends KCLError {
|
||||
constructor(
|
||||
key: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -235,6 +253,7 @@ export class KCLValueAlreadyDefined extends KCLError {
|
||||
'name',
|
||||
`Key ${key} was already defined elsewhere`,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -249,6 +268,7 @@ export class KCLUndefinedValueError extends KCLError {
|
||||
constructor(
|
||||
key: string,
|
||||
sourceRange: SourceRange,
|
||||
nonFatal: CompilationError[],
|
||||
operations: Operation[],
|
||||
artifactCommands: ArtifactCommand[],
|
||||
artifactGraph: ArtifactGraph,
|
||||
@ -259,6 +279,7 @@ export class KCLUndefinedValueError extends KCLError {
|
||||
'name',
|
||||
`Key ${key} has not been defined`,
|
||||
sourceRange,
|
||||
nonFatal,
|
||||
operations,
|
||||
artifactCommands,
|
||||
artifactGraph,
|
||||
@ -286,6 +307,7 @@ export function lspDiagnosticsToKclErrors(
|
||||
[posToOffset(doc, range.start)!, posToOffset(doc, range.end)!, 0],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
defaultArtifactGraph(),
|
||||
{},
|
||||
null
|
||||
@ -311,9 +333,13 @@ export function lspDiagnosticsToKclErrors(
|
||||
export function kclErrorsToDiagnostics(
|
||||
errors: KCLError[]
|
||||
): CodeMirrorDiagnostic[] {
|
||||
return errors
|
||||
let nonFatal: CodeMirrorDiagnostic[] = []
|
||||
const errs = errors
|
||||
?.filter((err) => isTopLevelModule(err.sourceRange))
|
||||
.map((err) => {
|
||||
.map((err): CodeMirrorDiagnostic => {
|
||||
if (err.nonFatal.length > 0) {
|
||||
nonFatal = nonFatal.concat(compilationErrorsToDiagnostics(err.nonFatal))
|
||||
}
|
||||
return {
|
||||
from: err.sourceRange[0],
|
||||
to: err.sourceRange[1],
|
||||
@ -321,6 +347,7 @@ export function kclErrorsToDiagnostics(
|
||||
severity: 'error',
|
||||
}
|
||||
})
|
||||
return errs.concat(nonFatal)
|
||||
}
|
||||
|
||||
export function compilationErrorsToDiagnostics(
|
||||
|
@ -463,6 +463,7 @@ theExtrude = startSketchOn(XY)
|
||||
expect.any(Object),
|
||||
expect.any(Object),
|
||||
expect.any(Object),
|
||||
expect.any(Object),
|
||||
null
|
||||
)
|
||||
)
|
||||
|
@ -47,11 +47,11 @@ it('formats numbers with units', () => {
|
||||
describe('test errFromErrWithOutputs', () => {
|
||||
it('converts KclErrorWithOutputs to KclError', () => {
|
||||
const blob =
|
||||
'{"error":{"kind":"internal","sourceRanges":[],"msg":"Cache busted"},"operations":[],"artifactCommands":[],"artifactGraph":{"map":{}},"filenames":{},"sourceFiles":{},"defaultPlanes":null}'
|
||||
'{"error":{"kind":"internal","sourceRanges":[],"msg":"Cache busted"},"nonFatal":[],"operations":[],"artifactCommands":[],"artifactGraph":{"map":{}},"filenames":{},"sourceFiles":{},"defaultPlanes":null}'
|
||||
const error = errFromErrWithOutputs(blob)
|
||||
const errorStr = JSON.stringify(error)
|
||||
expect(errorStr).toEqual(
|
||||
'{"kind":"internal","sourceRange":[0,0,0],"msg":"Cache busted","operations":[],"artifactCommands":[],"artifactGraph":{},"filenames":{},"defaultPlanes":null}'
|
||||
'{"kind":"internal","sourceRange":[0,0,0],"msg":"Cache busted","nonFatal":[],"operations":[],"artifactCommands":[],"artifactGraph":{},"filenames":{},"defaultPlanes":null}'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -69,6 +69,7 @@ import {
|
||||
UNLABELED_ARG,
|
||||
} from '@src/lang/queryAstConstants'
|
||||
import type { NumericType } from '@rust/kcl-lib/bindings/NumericType'
|
||||
import { isTopLevelModule } from '@src/lang/util'
|
||||
|
||||
export type { ArrayExpression } from '@rust/kcl-lib/bindings/ArrayExpression'
|
||||
export type {
|
||||
@ -157,10 +158,23 @@ export function defaultSourceRange(): SourceRange {
|
||||
return [0, 0, 0]
|
||||
}
|
||||
|
||||
function firstSourceRange(error: RustKclError): SourceRange {
|
||||
return error.sourceRanges.length > 0
|
||||
? sourceRangeFromRust(error.sourceRanges[0])
|
||||
: defaultSourceRange()
|
||||
function bestSourceRange(error: RustKclError): SourceRange {
|
||||
if (error.sourceRanges.length === 0) {
|
||||
return defaultSourceRange()
|
||||
}
|
||||
|
||||
// When there's an error, the call stack is unwound, and the locations are
|
||||
// built up from deepest location to shallowest. So the shallowest call is
|
||||
// last. That's the most useful to the user.
|
||||
for (let i = error.sourceRanges.length - 1; i >= 0; i--) {
|
||||
const range = error.sourceRanges[i]
|
||||
// Skip ranges pointing into files that aren't the top-level module.
|
||||
if (isTopLevelModule(range)) {
|
||||
return sourceRangeFromRust(range)
|
||||
}
|
||||
}
|
||||
// We didn't find a top-level module range, so just use the last one.
|
||||
return sourceRangeFromRust(error.sourceRanges[error.sourceRanges.length - 1])
|
||||
}
|
||||
|
||||
const splitErrors = (
|
||||
@ -230,7 +244,8 @@ export const parse = (code: string | Error): ParseResult | Error => {
|
||||
return new KCLError(
|
||||
parsed.kind,
|
||||
parsed.msg,
|
||||
firstSourceRange(parsed),
|
||||
bestSourceRange(parsed),
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
defaultArtifactGraph(),
|
||||
@ -386,7 +401,8 @@ export const errFromErrWithOutputs = (e: any): KCLError => {
|
||||
return new KCLError(
|
||||
parsed.error.kind,
|
||||
parsed.error.msg,
|
||||
firstSourceRange(parsed.error),
|
||||
bestSourceRange(parsed.error),
|
||||
parsed.nonFatal,
|
||||
parsed.operations,
|
||||
parsed.artifactCommands,
|
||||
rustArtifactGraphToMap(parsed.artifactGraph),
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
kclSamplesManifestWithNoMultipleFiles,
|
||||
} from '@src/lib/kclSamples'
|
||||
import { getUniqueProjectName } from '@src/lib/desktopFS'
|
||||
import { IS_ML_EXPERIMENTAL, ML_EXPERIMENTAL_MESSAGE } from '@src/lib/constants'
|
||||
import { IS_ML_EXPERIMENTAL } from '@src/lib/constants'
|
||||
import toast from 'react-hot-toast'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { relevantFileExtensions } from '@src/lang/wasmUtils'
|
||||
@ -168,7 +168,6 @@ export function createApplicationCommands({
|
||||
prompt: {
|
||||
inputType: 'text',
|
||||
required: true,
|
||||
warningMessage: ML_EXPERIMENTAL_MESSAGE,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import {
|
||||
KCL_DEFAULT_DEGREE,
|
||||
KCL_DEFAULT_LENGTH,
|
||||
KCL_DEFAULT_TRANSFORM,
|
||||
ML_EXPERIMENTAL_MESSAGE,
|
||||
} from '@src/lib/constants'
|
||||
import type { components } from '@src/lib/machine-api'
|
||||
import type { Selections } from '@src/lib/selections'
|
||||
@ -964,12 +963,10 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
allowCodeSelection: true,
|
||||
},
|
||||
skip: true,
|
||||
warningMessage: ML_EXPERIMENTAL_MESSAGE,
|
||||
},
|
||||
prompt: {
|
||||
inputType: 'text',
|
||||
required: true,
|
||||
warningMessage: ML_EXPERIMENTAL_MESSAGE,
|
||||
},
|
||||
},
|
||||
},
|
||||
|