rename lint to walk; add Digest
This commit is contained in:
		@ -32,6 +32,9 @@ use crate::{
 | 
			
		||||
mod literal_value;
 | 
			
		||||
mod none;
 | 
			
		||||
 | 
			
		||||
/// Position-independent digest of the AST node.
 | 
			
		||||
pub type Digest = [u8; 32];
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Bake)]
 | 
			
		||||
#[databake(path = kcl_lib::ast::types)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
@ -41,6 +44,8 @@ pub struct Program {
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub body: Vec<BodyItem>,
 | 
			
		||||
    pub non_code_meta: NonCodeMeta,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Program {
 | 
			
		||||
@ -159,7 +164,7 @@ impl Program {
 | 
			
		||||
        RuleT: crate::lint::rule::Rule<'a>,
 | 
			
		||||
    {
 | 
			
		||||
        let v = Arc::new(Mutex::new(vec![]));
 | 
			
		||||
        crate::lint::walk(self, &|node: crate::lint::Node<'a>| {
 | 
			
		||||
        crate::walk::walk(self, &|node: crate::walk::Node<'a>| {
 | 
			
		||||
            let mut findings = v.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
 | 
			
		||||
            findings.append(&mut rule.check(node)?);
 | 
			
		||||
            Ok(true)
 | 
			
		||||
@ -171,13 +176,13 @@ impl Program {
 | 
			
		||||
    /// Walk the ast and get all the variables and tags as completion items.
 | 
			
		||||
    pub fn completion_items<'a>(&'a self) -> Result<Vec<CompletionItem>> {
 | 
			
		||||
        let completions = Arc::new(Mutex::new(vec![]));
 | 
			
		||||
        crate::lint::walk(self, &|node: crate::lint::Node<'a>| {
 | 
			
		||||
        crate::walk::walk(self, &|node: crate::walk::Node<'a>| {
 | 
			
		||||
            let mut findings = completions.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
 | 
			
		||||
            match node {
 | 
			
		||||
                crate::lint::Node::TagDeclarator(tag) => {
 | 
			
		||||
                crate::walk::Node::TagDeclarator(tag) => {
 | 
			
		||||
                    findings.push(tag.into());
 | 
			
		||||
                }
 | 
			
		||||
                crate::lint::Node::VariableDeclaration(variable) => {
 | 
			
		||||
                crate::walk::Node::VariableDeclaration(variable) => {
 | 
			
		||||
                    findings.extend::<Vec<CompletionItem>>(variable.into());
 | 
			
		||||
                }
 | 
			
		||||
                _ => {}
 | 
			
		||||
@ -255,13 +260,13 @@ impl Program {
 | 
			
		||||
    /// Returns all the lsp symbols in the program.
 | 
			
		||||
    pub fn get_lsp_symbols<'a>(&'a self, code: &str) -> Result<Vec<DocumentSymbol>> {
 | 
			
		||||
        let symbols = Arc::new(Mutex::new(vec![]));
 | 
			
		||||
        crate::lint::walk(self, &|node: crate::lint::Node<'a>| {
 | 
			
		||||
        crate::walk::walk(self, &|node: crate::walk::Node<'a>| {
 | 
			
		||||
            let mut findings = symbols.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
 | 
			
		||||
            match node {
 | 
			
		||||
                crate::lint::Node::TagDeclarator(tag) => {
 | 
			
		||||
                crate::walk::Node::TagDeclarator(tag) => {
 | 
			
		||||
                    findings.extend::<Vec<DocumentSymbol>>(tag.get_lsp_symbols(code));
 | 
			
		||||
                }
 | 
			
		||||
                crate::lint::Node::VariableDeclaration(variable) => {
 | 
			
		||||
                crate::walk::Node::VariableDeclaration(variable) => {
 | 
			
		||||
                    findings.extend::<Vec<DocumentSymbol>>(variable.get_lsp_symbols(code));
 | 
			
		||||
                }
 | 
			
		||||
                _ => {}
 | 
			
		||||
@ -888,6 +893,8 @@ pub struct NonCodeNode {
 | 
			
		||||
    pub start: usize,
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub value: NonCodeValue,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<NonCodeNode> for SourceRange {
 | 
			
		||||
@ -1021,6 +1028,8 @@ pub enum NonCodeValue {
 | 
			
		||||
pub struct NonCodeMeta {
 | 
			
		||||
    pub non_code_nodes: HashMap<usize, Vec<NonCodeNode>>,
 | 
			
		||||
    pub start: Vec<NonCodeNode>,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// implement Deserialize manually because we to force the keys of non_code_nodes to be usize
 | 
			
		||||
@ -1046,6 +1055,7 @@ impl<'de> Deserialize<'de> for NonCodeMeta {
 | 
			
		||||
        Ok(NonCodeMeta {
 | 
			
		||||
            non_code_nodes,
 | 
			
		||||
            start: helper.start,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1074,6 +1084,8 @@ pub struct ExpressionStatement {
 | 
			
		||||
    pub start: usize,
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub expression: Value,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(ExpressionStatement);
 | 
			
		||||
@ -1088,6 +1100,8 @@ pub struct CallExpression {
 | 
			
		||||
    pub callee: Identifier,
 | 
			
		||||
    pub arguments: Vec<Value>,
 | 
			
		||||
    pub optional: bool,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(CallExpression);
 | 
			
		||||
@ -1106,6 +1120,7 @@ impl CallExpression {
 | 
			
		||||
            callee: Identifier::new(name),
 | 
			
		||||
            arguments,
 | 
			
		||||
            optional: false,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1355,6 +1370,8 @@ pub struct VariableDeclaration {
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub declarations: Vec<VariableDeclarator>,
 | 
			
		||||
    pub kind: VariableKind, // Change to enum if there are specific values
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<&VariableDeclaration> for Vec<CompletionItem> {
 | 
			
		||||
@ -1400,6 +1417,7 @@ impl VariableDeclaration {
 | 
			
		||||
            end: 0,
 | 
			
		||||
            declarations,
 | 
			
		||||
            kind,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1622,6 +1640,8 @@ pub struct VariableDeclarator {
 | 
			
		||||
    pub id: Identifier,
 | 
			
		||||
    /// The value of the variable.
 | 
			
		||||
    pub init: Value,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(VariableDeclarator);
 | 
			
		||||
@ -1633,6 +1653,7 @@ impl VariableDeclarator {
 | 
			
		||||
            end: 0,
 | 
			
		||||
            id: Identifier::new(name),
 | 
			
		||||
            init,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1650,6 +1671,8 @@ pub struct Literal {
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub value: LiteralValue,
 | 
			
		||||
    pub raw: String,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(Literal);
 | 
			
		||||
@ -1661,6 +1684,7 @@ impl Literal {
 | 
			
		||||
            end: 0,
 | 
			
		||||
            raw: JValue::from(value.clone()).to_string(),
 | 
			
		||||
            value,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1721,6 +1745,8 @@ pub struct Identifier {
 | 
			
		||||
    pub start: usize,
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub name: String,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(Identifier);
 | 
			
		||||
@ -1731,6 +1757,7 @@ impl Identifier {
 | 
			
		||||
            start: 0,
 | 
			
		||||
            end: 0,
 | 
			
		||||
            name: name.to_string(),
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1759,6 +1786,8 @@ pub struct TagDeclarator {
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    #[serde(rename = "value")]
 | 
			
		||||
    pub name: String,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(TagDeclarator);
 | 
			
		||||
@ -1818,6 +1847,7 @@ impl TagDeclarator {
 | 
			
		||||
            start: 0,
 | 
			
		||||
            end: 0,
 | 
			
		||||
            name: name.to_string(),
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1880,13 +1910,19 @@ impl TagDeclarator {
 | 
			
		||||
pub struct PipeSubstitution {
 | 
			
		||||
    pub start: usize,
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(PipeSubstitution);
 | 
			
		||||
 | 
			
		||||
impl PipeSubstitution {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Self { start: 0, end: 0 }
 | 
			
		||||
        Self {
 | 
			
		||||
            start: 0,
 | 
			
		||||
            end: 0,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1910,6 +1946,8 @@ pub struct ArrayExpression {
 | 
			
		||||
    pub start: usize,
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub elements: Vec<Value>,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(ArrayExpression);
 | 
			
		||||
@ -1926,6 +1964,7 @@ impl ArrayExpression {
 | 
			
		||||
            start: 0,
 | 
			
		||||
            end: 0,
 | 
			
		||||
            elements,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2066,6 +2105,8 @@ pub struct ObjectExpression {
 | 
			
		||||
    pub start: usize,
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub properties: Vec<ObjectProperty>,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ObjectExpression {
 | 
			
		||||
@ -2074,6 +2115,7 @@ impl ObjectExpression {
 | 
			
		||||
            start: 0,
 | 
			
		||||
            end: 0,
 | 
			
		||||
            properties,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2227,6 +2269,8 @@ pub struct ObjectProperty {
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub key: Identifier,
 | 
			
		||||
    pub value: Value,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(ObjectProperty);
 | 
			
		||||
@ -2355,6 +2399,8 @@ pub struct MemberExpression {
 | 
			
		||||
    pub object: MemberObject,
 | 
			
		||||
    pub property: LiteralIdentifier,
 | 
			
		||||
    pub computed: bool,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(MemberExpression);
 | 
			
		||||
@ -2520,6 +2566,8 @@ pub struct BinaryExpression {
 | 
			
		||||
    pub operator: BinaryOperator,
 | 
			
		||||
    pub left: BinaryPart,
 | 
			
		||||
    pub right: BinaryPart,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(BinaryExpression);
 | 
			
		||||
@ -2532,6 +2580,7 @@ impl BinaryExpression {
 | 
			
		||||
            operator,
 | 
			
		||||
            left,
 | 
			
		||||
            right,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2756,6 +2805,8 @@ pub struct UnaryExpression {
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub operator: UnaryOperator,
 | 
			
		||||
    pub argument: BinaryPart,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(UnaryExpression);
 | 
			
		||||
@ -2767,6 +2818,7 @@ impl UnaryExpression {
 | 
			
		||||
            end: argument.end(),
 | 
			
		||||
            operator,
 | 
			
		||||
            argument,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2857,6 +2909,8 @@ pub struct PipeExpression {
 | 
			
		||||
    // The rest will be CallExpression, and the AST type should reflect this.
 | 
			
		||||
    pub body: Vec<Value>,
 | 
			
		||||
    pub non_code_meta: NonCodeMeta,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(PipeExpression);
 | 
			
		||||
@ -2874,6 +2928,7 @@ impl PipeExpression {
 | 
			
		||||
            end: 0,
 | 
			
		||||
            body,
 | 
			
		||||
            non_code_meta: Default::default(),
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -3070,6 +3125,8 @@ pub struct Parameter {
 | 
			
		||||
    pub type_: Option<FnArgType>,
 | 
			
		||||
    /// Is the parameter optional?
 | 
			
		||||
    pub optional: bool,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Bake)]
 | 
			
		||||
@ -3083,6 +3140,8 @@ pub struct FunctionExpression {
 | 
			
		||||
    pub body: Program,
 | 
			
		||||
    #[serde(skip)]
 | 
			
		||||
    pub return_type: Option<FnArgType>,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(FunctionExpression);
 | 
			
		||||
@ -3118,6 +3177,7 @@ impl FunctionExpression {
 | 
			
		||||
            end,
 | 
			
		||||
            params,
 | 
			
		||||
            body,
 | 
			
		||||
            digest: _,
 | 
			
		||||
            return_type: _,
 | 
			
		||||
        } = self;
 | 
			
		||||
        let mut params_required = Vec::with_capacity(params.len());
 | 
			
		||||
@ -3198,6 +3258,8 @@ pub struct ReturnStatement {
 | 
			
		||||
    pub start: usize,
 | 
			
		||||
    pub end: usize,
 | 
			
		||||
    pub argument: Value,
 | 
			
		||||
 | 
			
		||||
    pub digest: Option<Digest>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl_value_meta!(ReturnStatement);
 | 
			
		||||
@ -4931,28 +4993,34 @@ const firstExtrude = startSketchOn('XY')
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 35,
 | 
			
		||||
                            end: 40,
 | 
			
		||||
                            name: "thing".to_owned()
 | 
			
		||||
                            name: "thing".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: Some(FnArgType::Primitive(FnArgPrimitive::Number)),
 | 
			
		||||
                        optional: false
 | 
			
		||||
                        optional: false,
 | 
			
		||||
                        digest: None
 | 
			
		||||
                    },
 | 
			
		||||
                    Parameter {
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 50,
 | 
			
		||||
                            end: 56,
 | 
			
		||||
                            name: "things".to_owned()
 | 
			
		||||
                            name: "things".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: Some(FnArgType::Array(FnArgPrimitive::String)),
 | 
			
		||||
                        optional: false
 | 
			
		||||
                        optional: false,
 | 
			
		||||
                        digest: None
 | 
			
		||||
                    },
 | 
			
		||||
                    Parameter {
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 68,
 | 
			
		||||
                            end: 72,
 | 
			
		||||
                            name: "more".to_owned()
 | 
			
		||||
                            name: "more".to_owned(),
 | 
			
		||||
                            digest: None
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: Some(FnArgType::Primitive(FnArgPrimitive::String)),
 | 
			
		||||
                        optional: true
 | 
			
		||||
                        optional: true,
 | 
			
		||||
                        digest: None
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            })
 | 
			
		||||
@ -4987,28 +5055,34 @@ const firstExtrude = startSketchOn('XY')
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 18,
 | 
			
		||||
                            end: 23,
 | 
			
		||||
                            name: "thing".to_owned()
 | 
			
		||||
                            name: "thing".to_owned(),
 | 
			
		||||
                            digest: None
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: Some(FnArgType::Primitive(FnArgPrimitive::Number)),
 | 
			
		||||
                        optional: false
 | 
			
		||||
                        optional: false,
 | 
			
		||||
                        digest: None
 | 
			
		||||
                    },
 | 
			
		||||
                    Parameter {
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 33,
 | 
			
		||||
                            end: 39,
 | 
			
		||||
                            name: "things".to_owned()
 | 
			
		||||
                            name: "things".to_owned(),
 | 
			
		||||
                            digest: None
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: Some(FnArgType::Array(FnArgPrimitive::String)),
 | 
			
		||||
                        optional: false
 | 
			
		||||
                        optional: false,
 | 
			
		||||
                        digest: None
 | 
			
		||||
                    },
 | 
			
		||||
                    Parameter {
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 51,
 | 
			
		||||
                            end: 55,
 | 
			
		||||
                            name: "more".to_owned()
 | 
			
		||||
                            name: "more".to_owned(),
 | 
			
		||||
                            digest: None
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: Some(FnArgType::Primitive(FnArgPrimitive::String)),
 | 
			
		||||
                        optional: true
 | 
			
		||||
                        optional: true,
 | 
			
		||||
                        digest: None
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            })
 | 
			
		||||
@ -5101,8 +5175,10 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
 | 
			
		||||
                        end: 0,
 | 
			
		||||
                        body: Vec::new(),
 | 
			
		||||
                        non_code_meta: Default::default(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    return_type: None,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -5116,17 +5192,21 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
 | 
			
		||||
                            start: 0,
 | 
			
		||||
                            end: 0,
 | 
			
		||||
                            name: "foo".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: None,
 | 
			
		||||
                        optional: false,
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    }],
 | 
			
		||||
                    body: Program {
 | 
			
		||||
                        start: 0,
 | 
			
		||||
                        end: 0,
 | 
			
		||||
                        body: Vec::new(),
 | 
			
		||||
                        non_code_meta: Default::default(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    return_type: None,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -5140,17 +5220,21 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
 | 
			
		||||
                            start: 0,
 | 
			
		||||
                            end: 0,
 | 
			
		||||
                            name: "foo".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: None,
 | 
			
		||||
                        optional: true,
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    }],
 | 
			
		||||
                    body: Program {
 | 
			
		||||
                        start: 0,
 | 
			
		||||
                        end: 0,
 | 
			
		||||
                        body: Vec::new(),
 | 
			
		||||
                        non_code_meta: Default::default(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    return_type: None,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -5165,18 +5249,22 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
 | 
			
		||||
                                start: 0,
 | 
			
		||||
                                end: 0,
 | 
			
		||||
                                name: "foo".to_owned(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            },
 | 
			
		||||
                            type_: None,
 | 
			
		||||
                            optional: false,
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        Parameter {
 | 
			
		||||
                            identifier: Identifier {
 | 
			
		||||
                                start: 0,
 | 
			
		||||
                                end: 0,
 | 
			
		||||
                                name: "bar".to_owned(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            },
 | 
			
		||||
                            type_: None,
 | 
			
		||||
                            optional: true,
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                    ],
 | 
			
		||||
                    body: Program {
 | 
			
		||||
@ -5184,8 +5272,10 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
 | 
			
		||||
                        end: 0,
 | 
			
		||||
                        body: Vec::new(),
 | 
			
		||||
                        non_code_meta: Default::default(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    return_type: None,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
        ]
 | 
			
		||||
@ -5210,6 +5300,7 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
 | 
			
		||||
            expression,
 | 
			
		||||
            start: _,
 | 
			
		||||
            end: _,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }) = program.body.first().unwrap()
 | 
			
		||||
        else {
 | 
			
		||||
            panic!("expected a function!");
 | 
			
		||||
 | 
			
		||||
@ -668,6 +668,7 @@ impl MemoryItem {
 | 
			
		||||
                    name,
 | 
			
		||||
                    start: u.meta[0].source_range.start(),
 | 
			
		||||
                    end: u.meta[0].source_range.end(),
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
            _ => Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
@ -687,6 +688,7 @@ impl MemoryItem {
 | 
			
		||||
                        name,
 | 
			
		||||
                        start: u.meta[0].source_range.start(),
 | 
			
		||||
                        end: u.meta[0].source_range.end(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    }))
 | 
			
		||||
                } else {
 | 
			
		||||
                    Ok(None)
 | 
			
		||||
@ -2337,6 +2339,7 @@ const bracket = startSketchOn('XY')
 | 
			
		||||
                start: 0,
 | 
			
		||||
                end: 0,
 | 
			
		||||
                name: s.to_owned(),
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        fn opt_param(s: &'static str) -> Parameter {
 | 
			
		||||
@ -2344,6 +2347,7 @@ const bracket = startSketchOn('XY')
 | 
			
		||||
                identifier: ident(s),
 | 
			
		||||
                type_: None,
 | 
			
		||||
                optional: true,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        fn req_param(s: &'static str) -> Parameter {
 | 
			
		||||
@ -2351,6 +2355,7 @@ const bracket = startSketchOn('XY')
 | 
			
		||||
                identifier: ident(s),
 | 
			
		||||
                type_: None,
 | 
			
		||||
                optional: false,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        fn additional_program_memory(items: &[(String, MemoryItem)]) -> ProgramMemory {
 | 
			
		||||
@ -2434,8 +2439,10 @@ const bracket = startSketchOn('XY')
 | 
			
		||||
                    end: 0,
 | 
			
		||||
                    body: Vec::new(),
 | 
			
		||||
                    non_code_meta: Default::default(),
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
                return_type: None,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            };
 | 
			
		||||
            let actual = assign_args_to_params(func_expr, args, ProgramMemory::new());
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
 | 
			
		||||
@ -28,5 +28,6 @@ pub mod std;
 | 
			
		||||
pub mod test_server;
 | 
			
		||||
pub mod thread;
 | 
			
		||||
pub mod token;
 | 
			
		||||
pub mod walk;
 | 
			
		||||
#[cfg(target_arch = "wasm32")]
 | 
			
		||||
pub mod wasm;
 | 
			
		||||
 | 
			
		||||
@ -3,10 +3,8 @@ use anyhow::Result;
 | 
			
		||||
use crate::{
 | 
			
		||||
    ast::types::VariableDeclarator,
 | 
			
		||||
    executor::SourceRange,
 | 
			
		||||
    lint::{
 | 
			
		||||
        rule::{def_finding, Discovered, Finding},
 | 
			
		||||
        Node,
 | 
			
		||||
    },
 | 
			
		||||
    lint::rule::{def_finding, Discovered, Finding},
 | 
			
		||||
    walk::Node,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
def_finding!(
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,4 @@
 | 
			
		||||
mod ast_node;
 | 
			
		||||
mod ast_walk;
 | 
			
		||||
pub mod checks;
 | 
			
		||||
pub mod rule;
 | 
			
		||||
 | 
			
		||||
pub use ast_node::Node;
 | 
			
		||||
pub use ast_walk::walk;
 | 
			
		||||
// pub(crate) use rule::{def_finding, finding};
 | 
			
		||||
pub use rule::{Discovered, Finding};
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ use schemars::JsonSchema;
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
 | 
			
		||||
 | 
			
		||||
use crate::{executor::SourceRange, lint::Node, lsp::IntoDiagnostic};
 | 
			
		||||
use crate::{executor::SourceRange, lsp::IntoDiagnostic, walk::Node};
 | 
			
		||||
 | 
			
		||||
/// Check the provided AST for any found rule violations.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
@ -374,7 +374,7 @@ impl Backend {
 | 
			
		||||
            let token_modifiers_bitset: u32 = if let Some(ast) = self.ast_map.get(¶ms.uri.to_string()).await {
 | 
			
		||||
                let token_index = Arc::new(Mutex::new(token_type_index));
 | 
			
		||||
                let modifier_index: Arc<Mutex<u32>> = Arc::new(Mutex::new(0));
 | 
			
		||||
                crate::lint::walk(&ast, &|node: crate::lint::Node| {
 | 
			
		||||
                crate::walk::walk(&ast, &|node: crate::walk::Node| {
 | 
			
		||||
                    let node_range: SourceRange = (&node).into();
 | 
			
		||||
                    if !node_range.contains(source_range.start()) {
 | 
			
		||||
                        return Ok(true);
 | 
			
		||||
@ -394,10 +394,10 @@ impl Backend {
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    match node {
 | 
			
		||||
                        crate::lint::Node::TagDeclarator(_) => {
 | 
			
		||||
                        crate::walk::Node::TagDeclarator(_) => {
 | 
			
		||||
                            return get_modifier(SemanticTokenModifier::DEFINITION);
 | 
			
		||||
                        }
 | 
			
		||||
                        crate::lint::Node::VariableDeclarator(variable) => {
 | 
			
		||||
                        crate::walk::Node::VariableDeclarator(variable) => {
 | 
			
		||||
                            let sr: SourceRange = variable.id.clone().into();
 | 
			
		||||
                            if sr.contains(source_range.start()) {
 | 
			
		||||
                                if let Value::FunctionExpression(_) = &variable.init {
 | 
			
		||||
@ -411,7 +411,7 @@ impl Backend {
 | 
			
		||||
                                return get_modifier(SemanticTokenModifier::DECLARATION);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        crate::lint::Node::Parameter(_) => {
 | 
			
		||||
                        crate::walk::Node::Parameter(_) => {
 | 
			
		||||
                            let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
 | 
			
		||||
                            *ti = match self.get_semantic_token_type_index(SemanticTokenType::PARAMETER) {
 | 
			
		||||
                                Some(index) => index,
 | 
			
		||||
@ -419,7 +419,7 @@ impl Backend {
 | 
			
		||||
                            };
 | 
			
		||||
                            return Ok(false);
 | 
			
		||||
                        }
 | 
			
		||||
                        crate::lint::Node::MemberExpression(member_expression) => {
 | 
			
		||||
                        crate::walk::Node::MemberExpression(member_expression) => {
 | 
			
		||||
                            let sr: SourceRange = member_expression.property.clone().into();
 | 
			
		||||
                            if sr.contains(source_range.start()) {
 | 
			
		||||
                                let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
 | 
			
		||||
@ -430,7 +430,7 @@ impl Backend {
 | 
			
		||||
                                return Ok(false);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        crate::lint::Node::ObjectProperty(object_property) => {
 | 
			
		||||
                        crate::walk::Node::ObjectProperty(object_property) => {
 | 
			
		||||
                            let sr: SourceRange = object_property.key.clone().into();
 | 
			
		||||
                            if sr.contains(source_range.start()) {
 | 
			
		||||
                                let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
 | 
			
		||||
@ -441,7 +441,7 @@ impl Backend {
 | 
			
		||||
                            }
 | 
			
		||||
                            return get_modifier(SemanticTokenModifier::DECLARATION);
 | 
			
		||||
                        }
 | 
			
		||||
                        crate::lint::Node::CallExpression(call_expr) => {
 | 
			
		||||
                        crate::walk::Node::CallExpression(call_expr) => {
 | 
			
		||||
                            let sr: SourceRange = call_expr.callee.clone().into();
 | 
			
		||||
                            if sr.contains(source_range.start()) {
 | 
			
		||||
                                let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ fn evaluate(rpn: Vec<BinaryExpressionToken>) -> Result<BinaryExpression, KclErro
 | 
			
		||||
                    operator,
 | 
			
		||||
                    left,
 | 
			
		||||
                    right,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                }))
 | 
			
		||||
            }
 | 
			
		||||
            BinaryExpressionToken::Operand(o) => o,
 | 
			
		||||
@ -129,6 +130,7 @@ mod tests {
 | 
			
		||||
                end: 0,
 | 
			
		||||
                value: n.into(),
 | 
			
		||||
                raw: n.to_string(),
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }))
 | 
			
		||||
        }
 | 
			
		||||
        let tests: Vec<Vec<BinaryExpressionToken>> = vec![
 | 
			
		||||
@ -146,6 +148,7 @@ mod tests {
 | 
			
		||||
                    operator: BinaryOperator::Sub,
 | 
			
		||||
                    left: lit(1),
 | 
			
		||||
                    right: lit(5),
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                }))
 | 
			
		||||
                .into(),
 | 
			
		||||
                BinaryOperator::Pow.into(),
 | 
			
		||||
 | 
			
		||||
@ -87,6 +87,7 @@ fn non_code_node(i: TokenSlice) -> PResult<NonCodeNode> {
 | 
			
		||||
                    } else {
 | 
			
		||||
                        NonCodeValue::BlockComment { value, style }
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                }),
 | 
			
		||||
                _ => None,
 | 
			
		||||
            })
 | 
			
		||||
@ -124,6 +125,7 @@ fn non_code_node_no_leading_whitespace(i: TokenSlice) -> PResult<NonCodeNode> {
 | 
			
		||||
                start: token.start,
 | 
			
		||||
                end: token.end,
 | 
			
		||||
                value,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
@ -193,6 +195,7 @@ fn pipe_expression(i: TokenSlice) -> PResult<PipeExpression> {
 | 
			
		||||
        end: values.last().unwrap().end().max(max_noncode_end),
 | 
			
		||||
        body: values,
 | 
			
		||||
        non_code_meta,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -213,6 +216,7 @@ fn bool_value(i: TokenSlice) -> PResult<Literal> {
 | 
			
		||||
        end: token.end,
 | 
			
		||||
        value: LiteralValue::Bool(value),
 | 
			
		||||
        raw: value.to_string(),
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -242,6 +246,7 @@ pub fn string_literal(i: TokenSlice) -> PResult<Literal> {
 | 
			
		||||
        end: token.end,
 | 
			
		||||
        value,
 | 
			
		||||
        raw: token.value.clone(),
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -274,6 +279,7 @@ pub(crate) fn unsigned_number_literal(i: TokenSlice) -> PResult<Literal> {
 | 
			
		||||
        end: token.end,
 | 
			
		||||
        value,
 | 
			
		||||
        raw: token.value.clone(),
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -431,6 +437,7 @@ fn shebang(i: TokenSlice) -> PResult<NonCodeNode> {
 | 
			
		||||
        value: NonCodeValue::Shebang {
 | 
			
		||||
            value: format!("#!{}", value),
 | 
			
		||||
        },
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -452,7 +459,12 @@ fn array(i: TokenSlice) -> PResult<ArrayExpression> {
 | 
			
		||||
        .parse_next(i)?;
 | 
			
		||||
    ignore_whitespace(i);
 | 
			
		||||
    let end = close_bracket(i)?.end;
 | 
			
		||||
    Ok(ArrayExpression { start, end, elements })
 | 
			
		||||
    Ok(ArrayExpression {
 | 
			
		||||
        start,
 | 
			
		||||
        end,
 | 
			
		||||
        elements,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Parse n..m into a vec of numbers [n, n+1, ..., m]
 | 
			
		||||
@ -468,6 +480,7 @@ fn integer_range(i: TokenSlice) -> PResult<Vec<Value>> {
 | 
			
		||||
                end: token0.end,
 | 
			
		||||
                value: num.into(),
 | 
			
		||||
                raw: num.to_string(),
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }))
 | 
			
		||||
        })
 | 
			
		||||
        .collect())
 | 
			
		||||
@ -495,6 +508,7 @@ fn object_property(i: TokenSlice) -> PResult<ObjectProperty> {
 | 
			
		||||
        end: val.end(),
 | 
			
		||||
        key,
 | 
			
		||||
        value: val,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -510,7 +524,12 @@ fn object(i: TokenSlice) -> PResult<ObjectExpression> {
 | 
			
		||||
    ignore_trailing_comma(i);
 | 
			
		||||
    ignore_whitespace(i);
 | 
			
		||||
    let end = close_brace(i)?.end;
 | 
			
		||||
    Ok(ObjectExpression { start, end, properties })
 | 
			
		||||
    Ok(ObjectExpression {
 | 
			
		||||
        start,
 | 
			
		||||
        end,
 | 
			
		||||
        properties,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Parse the % symbol, used to substitute a curried argument from a |> (pipe).
 | 
			
		||||
@ -520,6 +539,7 @@ fn pipe_sub(i: TokenSlice) -> PResult<PipeSubstitution> {
 | 
			
		||||
            Ok(PipeSubstitution {
 | 
			
		||||
                start: token.start,
 | 
			
		||||
                end: token.end,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })
 | 
			
		||||
        } else {
 | 
			
		||||
            Err(KclError::Syntax(KclErrorDetails {
 | 
			
		||||
@ -559,6 +579,7 @@ fn function_expression(i: TokenSlice) -> PResult<FunctionExpression> {
 | 
			
		||||
        params,
 | 
			
		||||
        body,
 | 
			
		||||
        return_type,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -609,6 +630,7 @@ fn member_expression(i: TokenSlice) -> PResult<MemberExpression> {
 | 
			
		||||
        object: MemberObject::Identifier(Box::new(id)),
 | 
			
		||||
        computed,
 | 
			
		||||
        property,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Each remaining member wraps the current member expression inside another member expression.
 | 
			
		||||
@ -623,6 +645,7 @@ fn member_expression(i: TokenSlice) -> PResult<MemberExpression> {
 | 
			
		||||
                object: MemberObject::MemberExpression(Box::new(accumulated)),
 | 
			
		||||
                computed,
 | 
			
		||||
                property,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }
 | 
			
		||||
        }))
 | 
			
		||||
}
 | 
			
		||||
@ -769,6 +792,7 @@ pub fn function_body(i: TokenSlice) -> PResult<Program> {
 | 
			
		||||
                    start: ws_token.start,
 | 
			
		||||
                    end: ws_token.end,
 | 
			
		||||
                    value: NonCodeValue::NewLine,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                }));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@ -850,6 +874,7 @@ pub fn function_body(i: TokenSlice) -> PResult<Program> {
 | 
			
		||||
        end,
 | 
			
		||||
        body,
 | 
			
		||||
        non_code_meta,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -876,6 +901,7 @@ pub fn return_stmt(i: TokenSlice) -> PResult<ReturnStatement> {
 | 
			
		||||
        start,
 | 
			
		||||
        end: argument.end(),
 | 
			
		||||
        argument,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1013,8 +1039,10 @@ fn declaration(i: TokenSlice) -> PResult<VariableDeclaration> {
 | 
			
		||||
            end,
 | 
			
		||||
            id,
 | 
			
		||||
            init: val,
 | 
			
		||||
            digest: None,
 | 
			
		||||
        }],
 | 
			
		||||
        kind,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1027,6 +1055,7 @@ impl TryFrom<Token> for Identifier {
 | 
			
		||||
                start: token.start,
 | 
			
		||||
                end: token.end,
 | 
			
		||||
                name: token.value,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })
 | 
			
		||||
        } else {
 | 
			
		||||
            Err(KclError::Syntax(KclErrorDetails {
 | 
			
		||||
@ -1057,6 +1086,7 @@ impl TryFrom<Token> for TagDeclarator {
 | 
			
		||||
                start: token.start - 1,
 | 
			
		||||
                end: token.end,
 | 
			
		||||
                name: token.value,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })
 | 
			
		||||
        } else {
 | 
			
		||||
            Err(KclError::Syntax(KclErrorDetails {
 | 
			
		||||
@ -1133,6 +1163,7 @@ fn unary_expression(i: TokenSlice) -> PResult<UnaryExpression> {
 | 
			
		||||
        end: argument.end(),
 | 
			
		||||
        operator,
 | 
			
		||||
        argument,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1210,6 +1241,7 @@ fn expression(i: TokenSlice) -> PResult<ExpressionStatement> {
 | 
			
		||||
        start: val.start(),
 | 
			
		||||
        end: val.end(),
 | 
			
		||||
        expression: val,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1427,6 +1459,7 @@ fn parameters(i: TokenSlice) -> PResult<Vec<Parameter>> {
 | 
			
		||||
                identifier,
 | 
			
		||||
                type_,
 | 
			
		||||
                optional,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        .collect::<Result<_, _>>()
 | 
			
		||||
@ -1516,6 +1549,7 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
 | 
			
		||||
                                start: literal.start,
 | 
			
		||||
                                end: literal.end,
 | 
			
		||||
                                name: name.to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            };
 | 
			
		||||
                            let tag = tag
 | 
			
		||||
                                .into_valid_binding_name()
 | 
			
		||||
@ -1554,6 +1588,7 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
 | 
			
		||||
                                start: literal.start,
 | 
			
		||||
                                end: literal.end,
 | 
			
		||||
                                name: name.to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            };
 | 
			
		||||
 | 
			
		||||
                            // Replace the literal with the tag.
 | 
			
		||||
@ -1581,6 +1616,7 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
 | 
			
		||||
        callee: fn_name,
 | 
			
		||||
        arguments: args,
 | 
			
		||||
        optional: false,
 | 
			
		||||
        digest: None,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1757,18 +1793,24 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                            end: 33,
 | 
			
		||||
                            value: 2u32.into(),
 | 
			
		||||
                            raw: "2".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        })),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    })],
 | 
			
		||||
                    non_code_meta: NonCodeMeta {
 | 
			
		||||
                        non_code_nodes: Default::default(),
 | 
			
		||||
                        start: vec![NonCodeNode {
 | 
			
		||||
                            start: 7,
 | 
			
		||||
                            end: 25,
 | 
			
		||||
                            value: NonCodeValue::NewLine
 | 
			
		||||
                            value: NonCodeValue::NewLine,
 | 
			
		||||
                            digest: None
 | 
			
		||||
                        }],
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
                return_type: None,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
@ -1817,6 +1859,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                    value: "this is a comment".to_owned(),
 | 
			
		||||
                    style: CommentStyle::Line,
 | 
			
		||||
                },
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }],
 | 
			
		||||
            non_code_meta.start,
 | 
			
		||||
        );
 | 
			
		||||
@ -1829,11 +1872,13 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "block\n  comment".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
                NonCodeNode {
 | 
			
		||||
                    start: 82,
 | 
			
		||||
                    end: 86,
 | 
			
		||||
                    value: NonCodeValue::NewLine,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ]),
 | 
			
		||||
            non_code_meta.non_code_nodes.get(&0),
 | 
			
		||||
@ -1846,6 +1891,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                    value: "this is also a comment".to_owned(),
 | 
			
		||||
                    style: CommentStyle::Line,
 | 
			
		||||
                },
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }]),
 | 
			
		||||
            non_code_meta.non_code_nodes.get(&1),
 | 
			
		||||
        );
 | 
			
		||||
@ -1913,6 +1959,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                end: 10,
 | 
			
		||||
                value: 3u32.into(),
 | 
			
		||||
                raw: "3".to_owned(),
 | 
			
		||||
                digest: None,
 | 
			
		||||
            }))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
@ -2046,6 +2093,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "hi".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Line,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -2057,6 +2105,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "hello".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -2068,6 +2117,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "hello".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -2079,6 +2129,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "hello".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -2091,6 +2142,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "hello".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -2105,6 +2157,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "hello".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -2119,6 +2172,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "hello".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
            (
 | 
			
		||||
@ -2131,6 +2185,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        value: "block\n                    comment".to_owned(),
 | 
			
		||||
                        style: CommentStyle::Block,
 | 
			
		||||
                    },
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
        ]
 | 
			
		||||
@ -2274,18 +2329,22 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                end: 1,
 | 
			
		||||
                value: 5u32.into(),
 | 
			
		||||
                raw: "5".to_owned(),
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })),
 | 
			
		||||
            right: BinaryPart::Literal(Box::new(Literal {
 | 
			
		||||
                start: 4,
 | 
			
		||||
                end: 7,
 | 
			
		||||
                value: "a".into(),
 | 
			
		||||
                raw: r#""a""#.to_owned(),
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })),
 | 
			
		||||
            digest: None,
 | 
			
		||||
        };
 | 
			
		||||
        let expected = vec![BodyItem::ExpressionStatement(ExpressionStatement {
 | 
			
		||||
            start: 0,
 | 
			
		||||
            end: 7,
 | 
			
		||||
            expression: Value::BinaryExpression(Box::new(expr)),
 | 
			
		||||
            digest: None,
 | 
			
		||||
        })];
 | 
			
		||||
        assert_eq!(expected, actual);
 | 
			
		||||
    }
 | 
			
		||||
@ -2387,6 +2446,7 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        end: 1,
 | 
			
		||||
                        value: 5u32.into(),
 | 
			
		||||
                        raw: "5".to_string(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    })),
 | 
			
		||||
                    operator: BinaryOperator::Add,
 | 
			
		||||
                    right: BinaryPart::Literal(Box::new(Literal {
 | 
			
		||||
@ -2394,10 +2454,14 @@ const mySk1 = startSketchAt([0, 0])"#;
 | 
			
		||||
                        end: 4,
 | 
			
		||||
                        value: 6u32.into(),
 | 
			
		||||
                        raw: "6".to_string(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    })),
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                })),
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })],
 | 
			
		||||
            non_code_meta: NonCodeMeta::default(),
 | 
			
		||||
            digest: None,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        assert_eq!(result, expected_result);
 | 
			
		||||
@ -2666,9 +2730,11 @@ e
 | 
			
		||||
                        start: 0,
 | 
			
		||||
                        end: 0,
 | 
			
		||||
                        name: "a".to_owned(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    type_: None,
 | 
			
		||||
                    optional: true,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                }],
 | 
			
		||||
                true,
 | 
			
		||||
            ),
 | 
			
		||||
@ -2678,9 +2744,11 @@ e
 | 
			
		||||
                        start: 0,
 | 
			
		||||
                        end: 0,
 | 
			
		||||
                        name: "a".to_owned(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    type_: None,
 | 
			
		||||
                    optional: false,
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                }],
 | 
			
		||||
                true,
 | 
			
		||||
            ),
 | 
			
		||||
@ -2691,18 +2759,22 @@ e
 | 
			
		||||
                            start: 0,
 | 
			
		||||
                            end: 0,
 | 
			
		||||
                            name: "a".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: None,
 | 
			
		||||
                        optional: false,
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    Parameter {
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 0,
 | 
			
		||||
                            end: 0,
 | 
			
		||||
                            name: "b".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: None,
 | 
			
		||||
                        optional: true,
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                true,
 | 
			
		||||
@ -2714,18 +2786,22 @@ e
 | 
			
		||||
                            start: 0,
 | 
			
		||||
                            end: 0,
 | 
			
		||||
                            name: "a".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: None,
 | 
			
		||||
                        optional: true,
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    Parameter {
 | 
			
		||||
                        identifier: Identifier {
 | 
			
		||||
                            start: 0,
 | 
			
		||||
                            end: 0,
 | 
			
		||||
                            name: "b".to_owned(),
 | 
			
		||||
                            digest: None,
 | 
			
		||||
                        },
 | 
			
		||||
                        type_: None,
 | 
			
		||||
                        optional: false,
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                false,
 | 
			
		||||
@ -2757,6 +2833,7 @@ e
 | 
			
		||||
                        start: 6,
 | 
			
		||||
                        end: 13,
 | 
			
		||||
                        name: "myArray".to_string(),
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    },
 | 
			
		||||
                    init: Value::ArrayExpression(Box::new(ArrayExpression {
 | 
			
		||||
                        start: 16,
 | 
			
		||||
@ -2767,73 +2844,88 @@ e
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 0u32.into(),
 | 
			
		||||
                                raw: "0".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 1u32.into(),
 | 
			
		||||
                                raw: "1".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 2u32.into(),
 | 
			
		||||
                                raw: "2".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 3u32.into(),
 | 
			
		||||
                                raw: "3".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 4u32.into(),
 | 
			
		||||
                                raw: "4".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 5u32.into(),
 | 
			
		||||
                                raw: "5".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 6u32.into(),
 | 
			
		||||
                                raw: "6".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 7u32.into(),
 | 
			
		||||
                                raw: "7".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 8u32.into(),
 | 
			
		||||
                                raw: "8".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 9u32.into(),
 | 
			
		||||
                                raw: "9".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                            Value::Literal(Box::new(Literal {
 | 
			
		||||
                                start: 17,
 | 
			
		||||
                                end: 18,
 | 
			
		||||
                                value: 10u32.into(),
 | 
			
		||||
                                raw: "10".to_string(),
 | 
			
		||||
                                digest: None,
 | 
			
		||||
                            })),
 | 
			
		||||
                        ],
 | 
			
		||||
                        digest: None,
 | 
			
		||||
                    })),
 | 
			
		||||
                    digest: None,
 | 
			
		||||
                }],
 | 
			
		||||
                kind: VariableKind::Const,
 | 
			
		||||
                digest: None,
 | 
			
		||||
            })],
 | 
			
		||||
            non_code_meta: NonCodeMeta::default(),
 | 
			
		||||
            digest: None,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        assert_eq!(result, expected_result);
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ use crate::{
 | 
			
		||||
        BinaryPart, BodyItem, LiteralIdentifier, MemberExpression, MemberObject, ObjectExpression, ObjectProperty,
 | 
			
		||||
        Parameter, Program, UnaryExpression, Value, VariableDeclarator,
 | 
			
		||||
    },
 | 
			
		||||
    lint::Node,
 | 
			
		||||
    walk::Node,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Walker is implemented by things that are able to walk an AST tree to
 | 
			
		||||
							
								
								
									
										5
									
								
								src/wasm-lib/kcl/src/walk/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/wasm-lib/kcl/src/walk/mod.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
mod ast_node;
 | 
			
		||||
mod ast_walk;
 | 
			
		||||
 | 
			
		||||
pub use ast_node::Node;
 | 
			
		||||
pub use ast_walk::walk;
 | 
			
		||||
		Reference in New Issue
	
	Block a user