Fix to consider only @settings to not be worth preserving
This commit is contained in:
@ -1252,7 +1252,7 @@ impl std::fmt::Display for UnitType {
|
||||
|
||||
// TODO called UnitLen so as not to clash with UnitLength in settings)
|
||||
/// A unit of length.
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum UnitLen {
|
||||
@ -1334,7 +1334,7 @@ impl From<UnitLen> for kittycad_modeling_cmds::units::UnitLength {
|
||||
}
|
||||
|
||||
/// A unit of angle.
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum UnitAngle {
|
||||
|
||||
@ -301,7 +301,7 @@ impl ModuleState {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MetaSettings {
|
||||
|
||||
@ -195,6 +195,10 @@ impl Program {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_empty_or_only_settings(&self) -> bool {
|
||||
self.ast.is_empty_or_only_settings()
|
||||
}
|
||||
|
||||
pub fn lint_all(&self) -> Result<Vec<lint::Discovered>, anyhow::Error> {
|
||||
self.ast.lint_all()
|
||||
}
|
||||
|
||||
@ -346,6 +346,25 @@ impl Node<Program> {
|
||||
|
||||
Ok(new_program)
|
||||
}
|
||||
|
||||
/// Returns true if the given KCL is empty or only contains settings that
|
||||
/// would be auto-generated.
|
||||
///
|
||||
/// TODO: Don't consider comments to be empty since they will get blown away
|
||||
/// by the UI.
|
||||
pub fn is_empty_or_only_settings(&self) -> bool {
|
||||
if !self.body.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
for item in &self.inner_attrs {
|
||||
if item.name() != Some(annotations::SETTINGS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Program {
|
||||
@ -3452,6 +3471,34 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[track_caller]
|
||||
fn parse(code: &str) -> Node<Program> {
|
||||
crate::parsing::top_level_parse(code).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_or_only_settings() {
|
||||
// Empty is empty.
|
||||
assert!(parse("").is_empty_or_only_settings());
|
||||
|
||||
// Whitespace is empty.
|
||||
assert!(parse(" ").is_empty_or_only_settings());
|
||||
|
||||
// Settings are empty.
|
||||
assert!(parse(r#"@settings(defaultLengthUnit = mm)"#).is_empty_or_only_settings());
|
||||
|
||||
// Any statement is not empty.
|
||||
assert!(!parse("5").is_empty_or_only_settings());
|
||||
|
||||
// Any statement is not empty, even with settings.
|
||||
let code = r#"@settings(defaultLengthUnit = mm)
|
||||
5"#;
|
||||
assert!(!parse(code).is_empty_or_only_settings());
|
||||
|
||||
// Non-settings attributes are not empty.
|
||||
assert!(!parse("@foo").is_empty_or_only_settings());
|
||||
}
|
||||
|
||||
// We have this as a test so we can ensure it never panics with an unwrap in the server.
|
||||
#[test]
|
||||
fn test_variable_kind_to_completion() {
|
||||
|
||||
@ -269,6 +269,17 @@ pub fn change_kcl_settings(code: &str, settings_str: &str) -> Result<String, Str
|
||||
Ok(formatted)
|
||||
}
|
||||
|
||||
/// Returns true if the given KCL is empty or only contains settings that would
|
||||
/// be auto-generated.
|
||||
#[wasm_bindgen]
|
||||
pub fn is_kcl_empty_or_only_settings(program_json: &str) -> Result<JsValue, String> {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let program: Program = serde_json::from_str(program_json).map_err(|e| e.to_string())?;
|
||||
|
||||
JsValue::from_serde(&program.is_empty_or_only_settings()).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Get the version of the kcl library.
|
||||
#[wasm_bindgen]
|
||||
pub fn get_kcl_version() -> String {
|
||||
|
||||
@ -18,6 +18,7 @@ import {
|
||||
serialize_project_configuration,
|
||||
serialize_configuration,
|
||||
reloadModule,
|
||||
is_kcl_empty_or_only_settings,
|
||||
} from 'lib/wasm_lib_wrapper'
|
||||
|
||||
import { KCLError } from './errors'
|
||||
@ -609,6 +610,40 @@ export function changeKclSettings(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given KCL is empty or only contains settings that would
|
||||
* be auto-generated.
|
||||
*/
|
||||
export function isKclEmptyOrOnlySettings(
|
||||
kcl: string | Node<Program>
|
||||
): boolean | Error {
|
||||
if (kcl === '') {
|
||||
// Fast path.
|
||||
return true
|
||||
}
|
||||
|
||||
let program: Node<Program>
|
||||
if (typeof kcl === 'string') {
|
||||
const parseResult = parse(kcl)
|
||||
if (err(parseResult)) return parseResult
|
||||
if (!resultIsOk(parseResult)) {
|
||||
return new Error(`parse result had errors`, { cause: parseResult })
|
||||
}
|
||||
program = parseResult.program
|
||||
} else {
|
||||
program = kcl
|
||||
}
|
||||
|
||||
try {
|
||||
return is_kcl_empty_or_only_settings(JSON.stringify(program))
|
||||
} catch (e) {
|
||||
console.error('Caught error checking if KCL is empty', e)
|
||||
return new Error('Caught error checking if KCL is empty', {
|
||||
cause: e,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a `UnitLength` (used in settings and modeling commands) to a
|
||||
* `UnitLen` (used in execution).
|
||||
|
||||
@ -22,6 +22,7 @@ import {
|
||||
base64_decode as Base64Decode,
|
||||
kcl_settings as KclSettings,
|
||||
change_kcl_settings as ChangeKclSettings,
|
||||
is_kcl_empty_or_only_settings as IsKclEmptyOrOnlySettings,
|
||||
get_kcl_version as GetKclVersion,
|
||||
serialize_configuration as SerializeConfiguration,
|
||||
serialize_project_configuration as SerializeProjectConfiguration,
|
||||
@ -93,6 +94,11 @@ export const kcl_settings: typeof KclSettings = (...args) => {
|
||||
export const change_kcl_settings: typeof ChangeKclSettings = (...args) => {
|
||||
return getModule().change_kcl_settings(...args)
|
||||
}
|
||||
export const is_kcl_empty_or_only_settings: typeof IsKclEmptyOrOnlySettings = (
|
||||
...args
|
||||
) => {
|
||||
return getModule().is_kcl_empty_or_only_settings(...args)
|
||||
}
|
||||
export const get_kcl_version: typeof GetKclVersion = () => {
|
||||
return getModule().get_kcl_version()
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import { useFileContext } from 'hooks/useFileContext'
|
||||
import { useLspContext } from 'components/LspProvider'
|
||||
import { reportRejection } from 'lib/trap'
|
||||
import { useSettings } from 'machines/appMachine'
|
||||
import { isKclEmptyOrOnlySettings } from 'lang/wasm'
|
||||
|
||||
/**
|
||||
* Show either a welcome screen or a warning screen
|
||||
@ -21,7 +22,7 @@ import { useSettings } from 'machines/appMachine'
|
||||
*/
|
||||
export default function OnboardingIntroduction() {
|
||||
const [shouldShowWarning, setShouldShowWarning] = useState(
|
||||
codeManager.code !== '' && codeManager.code !== bracket
|
||||
!isKclEmptyOrOnlySettings(codeManager.code) && codeManager.code !== bracket
|
||||
)
|
||||
|
||||
return shouldShowWarning ? (
|
||||
|
||||
Reference in New Issue
Block a user