use error::MinusOneResult;
use ps::Powershell;
use ps::Powershell::{Array, Raw, Type};
use ps::Value::Str;
use rule::RuleMut;
use tree::{ControlFlow, NodeMut};
#[derive(Default)]
pub struct JoinComparison;
impl<'a> RuleMut<'a> for JoinComparison {
type Language = Powershell;
fn enter(
&mut self,
_node: &mut NodeMut<'a, Self::Language>,
_flow: ControlFlow,
) -> MinusOneResult<()> {
Ok(())
}
fn leave(
&mut self,
node: &mut NodeMut<'a, Self::Language>,
_flow: ControlFlow,
) -> MinusOneResult<()> {
let view = node.view();
if view.kind() == "comparison_expression" {
if let (Some(left_expression), Some(operator), Some(right_expression)) =
(view.child(0), view.child(1), view.child(2))
{
match (
left_expression.data(),
operator.text()?.to_lowercase().as_str(),
right_expression.data(),
) {
(Some(Array(src_array)), "-join", Some(Raw(Str(join_token)))) => {
let result = src_array
.iter()
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join(join_token);
node.set(Raw(Str(result)));
}
_ => (),
}
}
}
Ok(())
}
}
#[derive(Default)]
pub struct JoinStringMethod;
impl<'a> RuleMut<'a> for JoinStringMethod {
type Language = Powershell;
fn enter(
&mut self,
_node: &mut NodeMut<'a, Self::Language>,
_flow: ControlFlow,
) -> MinusOneResult<()> {
Ok(())
}
fn leave(
&mut self,
node: &mut NodeMut<'a, Self::Language>,
_flow: ControlFlow,
) -> MinusOneResult<()> {
let view = node.view();
if view.kind() == "invokation_expression" {
if let (
Some(primary_expression),
Some(operator),
Some(member_name),
Some(arguments_list),
) = (view.child(0), view.child(1), view.child(2), view.child(3))
{
match (
primary_expression.data(),
operator.text()?.to_lowercase().as_str(),
member_name.text()?.to_lowercase().as_str(),
) {
(Some(Type(typename)), "::", "join") if typename == "string" => {
if let Some(argument_expression_list) =
arguments_list.named_child("argument_expression_list")
{
if let (Some(arg_1), Some(arg_2)) = (
argument_expression_list.child(0),
argument_expression_list.child(2),
) {
if let (Some(Raw(Str(join_token))), Some(Array(values))) =
(arg_1.data(), arg_2.data())
{
let result = values
.iter()
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join(join_token);
node.set(Raw(Str(result)));
}
}
}
}
_ => (),
}
}
}
Ok(())
}
}
#[derive(Default)]
pub struct JoinOperator;
impl<'a> RuleMut<'a> for JoinOperator {
type Language = Powershell;
fn enter(
&mut self,
_node: &mut NodeMut<'a, Self::Language>,
_flow: ControlFlow,
) -> MinusOneResult<()> {
Ok(())
}
fn leave(
&mut self,
node: &mut NodeMut<'a, Self::Language>,
_flow: ControlFlow,
) -> MinusOneResult<()> {
let view = node.view();
if view.kind() == "expression_with_unary_operator" {
if let (Some(operator), Some(unary_expression)) = (view.child(0), view.child(1)) {
match (
operator.text()?.to_lowercase().as_str(),
unary_expression.data(),
) {
("-join", Some(Array(values))) => {
let result = values
.iter()
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join("");
node.set(Raw(Str(result)));
}
_ => (),
}
}
}
Ok(())
}
}