mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 16:09:39 +00:00
AsRef<str> refactor
This commit is contained in:
@@ -5,41 +5,31 @@ use windmill_parser::asset_parser::{
|
||||
};
|
||||
use AssetUsageAccessType::*;
|
||||
|
||||
pub fn parse_assets<'a>(
|
||||
input: &'a str,
|
||||
paths_storage: &'a mut Vec<String>,
|
||||
) -> anyhow::Result<Vec<ParseAssetsResult<'a>>> {
|
||||
let ast = Suite::parse(&input, "main.py")
|
||||
pub fn parse_assets(input: &str) -> anyhow::Result<Vec<ParseAssetsResult<String>>> {
|
||||
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<ParseAssetsResult<'a>>,
|
||||
// We have to store paths separately because of lifetime concerns
|
||||
paths_storage: &'a mut Vec<String>,
|
||||
struct AssetsFinder {
|
||||
assets: Vec<ParseAssetsResult<String>>,
|
||||
}
|
||||
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(()),
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ use nom::{
|
||||
IResult, Parser,
|
||||
};
|
||||
|
||||
pub fn parse_assets<'a>(input: &'a str) -> anyhow::Result<Vec<ParseAssetsResult<'a>>> {
|
||||
pub fn parse_assets<'a>(input: &str) -> anyhow::Result<Vec<ParseAssetsResult<&str>>> {
|
||||
let mut assets = Vec::new();
|
||||
let mut remaining = input;
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn parse_assets<'a>(input: &'a str) -> anyhow::Result<Vec<ParseAssetsResult<
|
||||
Ok(merge_assets(assets))
|
||||
}
|
||||
|
||||
fn parse_asset(input: &str) -> IResult<&str, ParseAssetsResult> {
|
||||
fn parse_asset(input: &str) -> IResult<&str, ParseAssetsResult<&str>> {
|
||||
alt((
|
||||
parse_s3_object_read.map(|path| ParseAssetsResult {
|
||||
path,
|
||||
|
||||
@@ -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<String>,
|
||||
) -> anyhow::Result<Vec<ParseAssetsResult<'a>>> {
|
||||
pub fn parse_assets(code: &str) -> anyhow::Result<Vec<ParseAssetsResult<String>>> {
|
||||
let cm: Lrc<SourceMap> = 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<ParseAssetsResult<'a>>,
|
||||
// We have to store paths separately because of lifetime concerns
|
||||
paths_storage: &'a mut Vec<String>,
|
||||
struct AssetsFinder {
|
||||
assets: Vec<ParseAssetsResult<String>>,
|
||||
}
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => <Lit as VisitWith<Self>>::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(()),
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -18,20 +18,20 @@ pub enum AssetKind {
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ParseAssetsResult<'a> {
|
||||
pub struct ParseAssetsResult<S: AsRef<str>> {
|
||||
pub kind: AssetKind,
|
||||
pub path: &'a str,
|
||||
pub path: S,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub access_type: Option<AssetUsageAccessType>, // None in case of ambiguity
|
||||
}
|
||||
|
||||
pub fn merge_assets<'a>(assets: Vec<ParseAssetsResult<'a>>) -> Vec<ParseAssetsResult<'a>> {
|
||||
let mut arr: Vec<ParseAssetsResult<'a>> = vec![];
|
||||
pub fn merge_assets<S: AsRef<str>>(assets: Vec<ParseAssetsResult<S>>) -> Vec<ParseAssetsResult<S>> {
|
||||
let mut arr: Vec<ParseAssetsResult<S>> = 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<ParseAssetsResult<'a>>) -> Vec<ParseAssetsRe
|
||||
arr.push(asset);
|
||||
}
|
||||
}
|
||||
arr.sort_by_key(|a| a.path);
|
||||
arr.sort_by(|a, b| a.path.as_ref().cmp(b.path.as_ref()));
|
||||
arr
|
||||
}
|
||||
|
||||
|
||||
@@ -39,16 +39,23 @@ pub struct AssetUsage {
|
||||
pub access_type: AssetUsageAccessType,
|
||||
}
|
||||
|
||||
pub fn parse_assets<'a>(
|
||||
input: &'a str,
|
||||
pub fn parse_assets(
|
||||
input: &str,
|
||||
lang: ScriptLang,
|
||||
paths_storage: &'a mut Vec<String>,
|
||||
) -> anyhow::Result<Option<Vec<ParseAssetsResult<'a>>>> {
|
||||
) -> anyhow::Result<Option<Vec<ParseAssetsResult<String>>>> {
|
||||
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),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user