From c83718a7729a27311dd50dad83f00fc716211361 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 4 Jul 2025 00:57:13 +0200 Subject: [PATCH] AsRef refactor --- .../windmill-parser-py/src/asset_parser.rs | 37 +++++++------------ .../windmill-parser-sql/src/asset_parser.rs | 4 +- .../windmill-parser-ts/src/asset_parser.rs | 37 +++++++------------ .../parsers/windmill-parser-wasm/src/lib.rs | 6 +-- .../windmill-parser/src/asset_parser.rs | 12 +++--- backend/windmill-common/src/assets.rs | 21 +++++++---- 6 files changed, 50 insertions(+), 67 deletions(-) diff --git a/backend/parsers/windmill-parser-py/src/asset_parser.rs b/backend/parsers/windmill-parser-py/src/asset_parser.rs index 9363164f8d..911258c22f 100644 --- a/backend/parsers/windmill-parser-py/src/asset_parser.rs +++ b/backend/parsers/windmill-parser-py/src/asset_parser.rs @@ -5,41 +5,31 @@ use windmill_parser::asset_parser::{ }; use AssetUsageAccessType::*; -pub fn parse_assets<'a>( - input: &'a str, - paths_storage: &'a mut Vec, -) -> anyhow::Result>> { - let ast = Suite::parse(&input, "main.py") +pub fn parse_assets(input: &str) -> anyhow::Result>> { + let ast = Suite::parse(input, "main.py") .map_err(|e| anyhow::anyhow!("Error parsing code: {}", e.to_string()))?; - let mut assets_finder = AssetsFinder { assets: vec![], paths_storage }; + let mut assets_finder = AssetsFinder { assets: vec![] }; ast.into_iter() .for_each(|stmt| assets_finder.visit_stmt(stmt)); - for (asset, path) in assets_finder - .assets - .iter_mut() - .zip(assets_finder.paths_storage.iter_mut()) - { - asset.path = path; - } Ok(merge_assets(assets_finder.assets)) } -struct AssetsFinder<'a> { - assets: Vec>, - // We have to store paths separately because of lifetime concerns - paths_storage: &'a mut Vec, +struct AssetsFinder { + assets: Vec>, } -impl<'a> Visitor for AssetsFinder<'a> { +impl Visitor for AssetsFinder { // visit_call_expr will not recurse if it detects an asset, // so this will only be called when no further context was found fn visit_expr_constant(&mut self, node: ExprConstant) { match node.value { Constant::Str(s) => { if let Some((kind, path)) = parse_asset_syntax(&s) { - self.paths_storage.push(path.to_string()); - self.assets - .push(ParseAssetsResult { kind, path: "", access_type: None }); + self.assets.push(ParseAssetsResult { + kind, + path: path.to_string(), + access_type: None, + }); } } _ => self.generic_visit_expr_constant(node), @@ -54,7 +44,7 @@ impl<'a> Visitor for AssetsFinder<'a> { } } -impl<'a> AssetsFinder<'a> { +impl AssetsFinder { fn visit_expr_call_inner(&mut self, node: &rustpython_ast::ExprCall) -> Result<(), ()> { let ident: String = node .func @@ -81,9 +71,8 @@ impl<'a> AssetsFinder<'a> { match &node.args[0] { Expr::Constant(ExprConstant { value: Constant::Str(value), .. }) => { let path = parse_asset_syntax(&value).map(|(_, p)| p).unwrap_or(&value); - self.paths_storage.push(path.to_string()); self.assets - .push(ParseAssetsResult { kind, path: "", access_type }); + .push(ParseAssetsResult { kind, path: path.to_string(), access_type }); } _ => return Err(()), }; diff --git a/backend/parsers/windmill-parser-sql/src/asset_parser.rs b/backend/parsers/windmill-parser-sql/src/asset_parser.rs index 2041a0d1f1..73b8c011ea 100644 --- a/backend/parsers/windmill-parser-sql/src/asset_parser.rs +++ b/backend/parsers/windmill-parser-sql/src/asset_parser.rs @@ -10,7 +10,7 @@ use nom::{ IResult, Parser, }; -pub fn parse_assets<'a>(input: &'a str) -> anyhow::Result>> { +pub fn parse_assets<'a>(input: &str) -> anyhow::Result>> { let mut assets = Vec::new(); let mut remaining = input; @@ -26,7 +26,7 @@ pub fn parse_assets<'a>(input: &'a str) -> anyhow::Result IResult<&str, ParseAssetsResult> { +fn parse_asset(input: &str) -> IResult<&str, ParseAssetsResult<&str>> { alt(( parse_s3_object_read.map(|path| ParseAssetsResult { path, diff --git a/backend/parsers/windmill-parser-ts/src/asset_parser.rs b/backend/parsers/windmill-parser-ts/src/asset_parser.rs index 0f8f8d09e3..7a9b053522 100644 --- a/backend/parsers/windmill-parser-ts/src/asset_parser.rs +++ b/backend/parsers/windmill-parser-ts/src/asset_parser.rs @@ -1,5 +1,5 @@ use swc_common::{sync::Lrc, FileName, SourceMap}; -use swc_ecma_ast::{CallExpr, Expr, Lit, MemberExpr, MemberProp, Str, TsLit}; +use swc_ecma_ast::{CallExpr, Expr, Lit, MemberExpr, MemberProp, Str}; use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax, TsSyntax}; use swc_ecma_visit::{Visit, VisitWith}; use windmill_parser::asset_parser::{ @@ -7,10 +7,7 @@ use windmill_parser::asset_parser::{ }; use AssetUsageAccessType::*; -pub fn parse_assets<'a>( - code: &'a str, - paths_storage: &'a mut Vec, -) -> anyhow::Result>> { +pub fn parse_assets(code: &str) -> anyhow::Result>> { let cm: Lrc = Default::default(); let fm = cm.new_source_file(FileName::Custom("main.ts".into()).into(), code.into()); let lexer = Lexer::new( @@ -35,34 +32,27 @@ pub fn parse_assets<'a>( anyhow::anyhow!("Error while parsing code, it is invalid TypeScript: {err_s}, {e:?}") })? .body; - let mut assets_finder = AssetsFinder { assets: vec![], paths_storage }; + let mut assets_finder = AssetsFinder { assets: vec![] }; assets_finder.visit_module_items(&ast); - for (asset, path) in assets_finder - .assets - .iter_mut() - .zip(assets_finder.paths_storage.iter_mut()) - { - asset.path = path; - } Ok(merge_assets(assets_finder.assets)) } -struct AssetsFinder<'a> { - assets: Vec>, - // We have to store paths separately because of lifetime concerns - paths_storage: &'a mut Vec, +struct AssetsFinder { + assets: Vec>, } -impl<'a> Visit for AssetsFinder<'a> { +impl Visit for AssetsFinder { // visit_call_expr will not recurse if it detects an asset, // so this will only be called when no further context was found fn visit_lit(&mut self, node: &swc_ecma_ast::Lit) { match node { swc_ecma_ast::Lit::Str(str) => { if let Some((kind, path)) = parse_asset_syntax(str.value.as_str()) { - self.paths_storage.push(path.to_string()); - self.assets - .push(ParseAssetsResult { kind, path: "", access_type: None }); + self.assets.push(ParseAssetsResult { + kind, + path: path.to_string(), + access_type: None, + }); } } _ => >::visit_children_with(node, self), @@ -77,7 +67,7 @@ impl<'a> Visit for AssetsFinder<'a> { } } -impl<'a> AssetsFinder<'a> { +impl AssetsFinder { fn visit_call_expr_inner(&mut self, node: &swc_ecma_ast::CallExpr) -> Result<(), ()> { let ident = match node.callee.as_expr().map(AsRef::as_ref) { Some(Expr::Ident(i)) => i.sym.as_str(), @@ -96,9 +86,8 @@ impl<'a> AssetsFinder<'a> { match node.args[0].expr.as_ref() { Expr::Lit(Lit::Str(Str { value, .. })) => { let path = parse_asset_syntax(&value).map(|(_, p)| p).unwrap_or(&value); - self.paths_storage.push(path.to_string()); self.assets - .push(ParseAssetsResult { kind, path: "", access_type }); + .push(ParseAssetsResult { kind, path: path.to_string(), access_type }); } _ => return Err(()), } diff --git a/backend/parsers/windmill-parser-wasm/src/lib.rs b/backend/parsers/windmill-parser-wasm/src/lib.rs index 67d6ddf792..e02e280abb 100644 --- a/backend/parsers/windmill-parser-wasm/src/lib.rs +++ b/backend/parsers/windmill-parser-wasm/src/lib.rs @@ -181,8 +181,7 @@ pub fn parse_assets_sql(code: &str) -> String { #[cfg(feature = "ts-parser")] #[wasm_bindgen] pub fn parse_assets_ts(code: &str) -> String { - let mut paths_storage = vec![]; - if let Ok(r) = windmill_parser_ts::parse_assets(code, &mut paths_storage) { + if let Ok(r) = windmill_parser_ts::parse_assets(code) { return serde_json::to_string(&r).unwrap(); } else { return "Invalid".to_string(); @@ -192,8 +191,7 @@ pub fn parse_assets_ts(code: &str) -> String { #[cfg(feature = "py-parser")] #[wasm_bindgen] pub fn parse_assets_py(code: &str) -> String { - let mut paths_storage = vec![]; - if let Ok(r) = windmill_parser_py::parse_assets(code, &mut paths_storage) { + if let Ok(r) = windmill_parser_py::parse_assets(code) { return serde_json::to_string(&r).unwrap(); } else { return "Invalid".to_string(); diff --git a/backend/parsers/windmill-parser/src/asset_parser.rs b/backend/parsers/windmill-parser/src/asset_parser.rs index 348ffba876..6857e8d68e 100644 --- a/backend/parsers/windmill-parser/src/asset_parser.rs +++ b/backend/parsers/windmill-parser/src/asset_parser.rs @@ -18,20 +18,20 @@ pub enum AssetKind { } #[derive(Serialize)] -pub struct ParseAssetsResult<'a> { +pub struct ParseAssetsResult> { pub kind: AssetKind, - pub path: &'a str, + pub path: S, #[serde(skip_serializing_if = "Option::is_none")] pub access_type: Option, // None in case of ambiguity } -pub fn merge_assets<'a>(assets: Vec>) -> Vec> { - let mut arr: Vec> = vec![]; +pub fn merge_assets>(assets: Vec>) -> Vec> { + let mut arr: Vec> = vec![]; for asset in assets { // Remove duplicates if let Some(existing) = arr .iter_mut() - .find(|x| x.path == asset.path && x.kind == asset.kind) + .find(|x| x.path.as_ref() == asset.path.as_ref() && x.kind == asset.kind) { // merge access types existing.access_type = match (asset.access_type, existing.access_type) { @@ -45,7 +45,7 @@ pub fn merge_assets<'a>(assets: Vec>) -> Vec( - input: &'a str, +pub fn parse_assets( + input: &str, lang: ScriptLang, - paths_storage: &'a mut Vec, -) -> anyhow::Result>>> { +) -> anyhow::Result>>> { let r = match lang { - ScriptLang::Python3 => windmill_parser_py::parse_assets(input, paths_storage), - ScriptLang::DuckDb => windmill_parser_sql::parse_assets(input), + ScriptLang::Python3 => windmill_parser_py::parse_assets(input), + ScriptLang::DuckDb => windmill_parser_sql::parse_assets(input).map(|a| { + a.iter() + .map(|a| ParseAssetsResult { + path: a.path.to_string(), + access_type: a.access_type, + kind: a.kind, + }) + .collect() + }), ScriptLang::Deno | ScriptLang::Bun | ScriptLang::Nativets => { - windmill_parser_ts::parse_assets(input, paths_storage) + windmill_parser_ts::parse_assets(input) } _ => return Ok(None), };