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