Improve parameter inference for blocks (#2708)

This commit is contained in:
Jonathan Turner 2020-10-28 07:47:11 +13:00 committed by GitHub
parent ee76523507
commit 8229af7591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 21 deletions

View File

@ -82,17 +82,16 @@ pub async fn process_row(
// When we process a row, we need to know whether the block wants to have the contents of the row as // When we process a row, we need to know whether the block wants to have the contents of the row as
// a parameter to the block (so it gets assigned to a variable that can be used inside the block) or // a parameter to the block (so it gets assigned to a variable that can be used inside the block) or
// if it wants the contents as as an input stream // if it wants the contents as as an input stream
let params = block.params();
let input_stream = if !params.is_empty() { let input_stream = if !block.params.is_empty() {
InputStream::empty() InputStream::empty()
} else { } else {
once(async { Ok(input_clone) }).to_input_stream() once(async { Ok(input_clone) }).to_input_stream()
}; };
let scope = if !params.is_empty() { let scope = if !block.params.is_empty() {
// FIXME: add check for more than parameter, once that's supported // FIXME: add check for more than parameter, once that's supported
Scope::append_var(scope, params[0].clone(), input) Scope::append_var(scope, block.params[0].clone(), input)
} else { } else {
scope scope
}; };

View File

@ -603,7 +603,7 @@ fn parse_interpolated_string(
}]; }];
let call = SpannedExpression { let call = SpannedExpression {
expr: Expression::Invocation(Block::new(None, block, lite_arg.span)), expr: Expression::Invocation(Block::new(vec![], block, lite_arg.span)),
span: lite_arg.span, span: lite_arg.span,
}; };
@ -1372,8 +1372,8 @@ fn parse_positional_argument(
let span = arg.span; let span = arg.span;
let mut commands = hir::Commands::new(span); let mut commands = hir::Commands::new(span);
commands.push(ClassifiedCommand::Expr(Box::new(arg))); commands.push(ClassifiedCommand::Expr(Box::new(arg)));
let mut block = hir::Block::new(None, vec![], span);
block.push(commands); let block = hir::Block::new(vec![], vec![commands], span);
let arg = SpannedExpression::new(Expression::Block(block), span); let arg = SpannedExpression::new(Expression::Block(block), span);
@ -1768,7 +1768,7 @@ fn expand_shorthand_forms(
} }
pub fn classify_block(lite_block: &LiteBlock, registry: &dyn SignatureRegistry) -> ClassifiedBlock { pub fn classify_block(lite_block: &LiteBlock, registry: &dyn SignatureRegistry) -> ClassifiedBlock {
let mut block = Block::new(None, vec![], lite_block.span()); let mut command_list = vec![];
let mut error = None; let mut error = None;
for lite_pipeline in &lite_block.block { for lite_pipeline in &lite_block.block {
@ -1781,7 +1781,7 @@ pub fn classify_block(lite_block: &LiteBlock, registry: &dyn SignatureRegistry)
let pipeline = if let Some(vars) = vars { let pipeline = if let Some(vars) = vars {
let span = pipeline.commands.span; let span = pipeline.commands.span;
let block = hir::Block::new(None, vec![pipeline.commands.clone()], span); let block = hir::Block::new(vec![], vec![pipeline.commands.clone()], span);
let mut call = hir::Call::new( let mut call = hir::Call::new(
Box::new(SpannedExpression { Box::new(SpannedExpression {
expr: Expression::string("with-env".to_string()), expr: Expression::string("with-env".to_string()),
@ -1823,11 +1823,12 @@ pub fn classify_block(lite_block: &LiteBlock, registry: &dyn SignatureRegistry)
pipeline pipeline
}; };
block.push(pipeline.commands); command_list.push(pipeline.commands);
if error.is_none() { if error.is_none() {
error = err; error = err;
} }
} }
let block = Block::new(vec![], command_list, lite_block.span());
ClassifiedBlock::new(block, error) ClassifiedBlock::new(block, error)
} }

View File

@ -113,22 +113,26 @@ impl Commands {
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub struct Block { pub struct Block {
params: Option<Vec<String>>, pub params: Vec<String>,
pub block: Vec<Commands>, pub block: Vec<Commands>,
pub span: Span, pub span: Span,
} }
impl Block { impl Block {
pub fn new(params: Option<Vec<String>>, block: Vec<Commands>, span: Span) -> Block { pub fn new(params: Vec<String>, block: Vec<Commands>, span: Span) -> Block {
Block { let mut output = Block {
params, params,
block, block,
span, span,
} };
output.infer_params();
output
} }
pub fn push(&mut self, commands: Commands) { pub fn push(&mut self, commands: Commands) {
self.block.push(commands); self.block.push(commands);
self.infer_params();
} }
pub fn set_redirect(&mut self, external_redirection: ExternalRedirection) { pub fn set_redirect(&mut self, external_redirection: ExternalRedirection) {
@ -145,13 +149,9 @@ impl Block {
self.block.iter().any(|x| x.has_it_usage()) self.block.iter().any(|x| x.has_it_usage())
} }
pub fn params(&self) -> Vec<String> { pub fn infer_params(&mut self) {
if let Some(params) = &self.params { if self.params.is_empty() && self.has_it_usage() {
params.clone() self.params = vec!["$it".into()];
} else if self.has_it_usage() {
vec!["$it".into()]
} else {
vec![]
} }
} }
} }