use nu_protocol::{
Span,
ast::{Expr, Expression, Pipeline},
};
use crate::{
ast::{call::CallExt, pipeline::PipelineExt},
context::LintContext,
};
pub mod from_after_parsed_open;
pub mod open_raw_from_to_open;
pub mod string_param_as_path;
pub struct OpenFromPattern<'a> {
pub open_expr: &'a Expression,
pub from_expr: &'a Expression,
pub filename: String,
pub format: String,
pub has_raw_flag: bool,
}
pub fn find_open_from_patterns<'a>(
pipeline: &'a Pipeline,
context: &'a LintContext,
) -> Vec<OpenFromPattern<'a>> {
pipeline
.find_command_pairs(
context,
|call, ctx| call.get_call_name(ctx) == "open",
|call, ctx| call.get_call_name(ctx).starts_with("from "),
)
.into_iter()
.filter_map(|pair| {
let from_name = pair.second.get_call_name(context);
let format = from_name.strip_prefix("from ")?;
let filename_arg = pair.first.get_first_positional_arg()?;
let filename = context.expr_text(filename_arg);
let filename_content = match &filename_arg.expr {
Expr::String(s) | Expr::RawString(s) | Expr::GlobPattern(s, _) => s.as_str(),
_ => filename,
};
let file_format = context.format_for_extension(filename_content)?;
if file_format != format {
return None;
}
let open_text = context.span_text(pair.span);
let has_raw_flag = open_text.contains("--raw") || open_text.contains("-r ");
Some(OpenFromPattern {
open_expr: &pipeline.elements[pair.first_index].expr,
from_expr: &pipeline.elements[pair.second_index].expr,
filename: filename.to_string(),
format: format.to_string(),
has_raw_flag,
})
})
.collect()
}
pub fn open_from_span(pattern: &OpenFromPattern) -> Span {
Span::new(pattern.open_expr.span.start, pattern.from_expr.span.end)
}