Move from using a Block to an Arc'd Block (#3289)

This commit is contained in:
Jonathan Turner 2021-04-09 20:12:25 +12:00 committed by GitHub
parent ac070ae942
commit b791d1ab0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 81 additions and 54 deletions

View File

@ -233,7 +233,11 @@ pub fn cli(context: EvaluationContext, options: Options) -> Result<(), Box<dyn E
context.scope.enter_scope();
let (mut prompt_block, err) = nu_parser::parse(&prompt_line, 0, &context.scope);
prompt_block.set_redirect(ExternalRedirection::Stdout);
if let Some(block) =
std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut prompt_block)
{
block.set_redirect(ExternalRedirection::Stdout);
}
if err.is_some() {
context.scope.exit_scope();

View File

@ -254,6 +254,8 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
#[cfg(test)]
mod tests {
use std::sync::Arc;
use super::*;
use nu_parser::{classify_block, lex, parse_block, ParserScope};
@ -285,9 +287,9 @@ mod tests {
todo!()
}
fn add_definition(&self, _block: Block) {}
fn add_definition(&self, _block: Arc<Block>) {}
fn get_definitions(&self) -> Vec<Block> {
fn get_definitions(&self) -> Vec<Arc<Block>> {
vec![]
}

View File

@ -166,7 +166,8 @@ where
}
}
fn add_implicit_autoview(mut block: Block) -> Block {
fn add_implicit_autoview(mut block: Arc<Block>) -> Arc<Block> {
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block) {
if block.block.is_empty() {
let group = Group::new(
vec![{
@ -182,6 +183,7 @@ fn add_implicit_autoview(mut block: Block) -> Block {
);
block.push(group);
}
}
block
}

View File

@ -81,7 +81,9 @@ fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
x => x,
};
block.block.set_redirect(block_redirection);
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block.block) {
block.set_redirect(block_redirection);
}
context.scope.enter_scope();
let result = run_block(&block.block, &context, input);
context.scope.exit_scope();

View File

@ -78,7 +78,9 @@ fn with_env(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
input,
) = raw_args.process()?;
block.block.set_redirect(redirection);
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block.block) {
block.set_redirect(redirection);
}
let mut env = IndexMap::new();

View File

@ -61,7 +61,7 @@ impl Scope {
}
}
pub fn get_custom_commands_with_name(&self, name: &str) -> Option<Vec<Block>> {
pub fn get_custom_commands_with_name(&self, name: &str) -> Option<Vec<Arc<Block>>> {
let custom_commands: Vec<_> = self
.frames
.lock()
@ -307,7 +307,7 @@ impl ParserScope for Scope {
self.get_command(name).is_some()
}
fn add_definition(&self, block: Block) {
fn add_definition(&self, block: Arc<Block>) {
if let Some(frame) = self.frames.lock().last_mut() {
let name = block.params.name.clone();
frame.custom_commands.insert(name.clone(), block.clone());
@ -315,7 +315,7 @@ impl ParserScope for Scope {
}
}
fn get_definitions(&self) -> Vec<Block> {
fn get_definitions(&self) -> Vec<Arc<Block>> {
let mut blocks = vec![];
if let Some(frame) = self.frames.lock().last() {
for (_, custom_command) in &frame.custom_commands {
@ -356,7 +356,7 @@ pub struct ScopeFrame {
pub vars: IndexMap<String, Value>,
pub env: IndexMap<String, String>,
pub commands: IndexMap<String, Command>,
pub custom_commands: IndexMap<String, Block>,
pub custom_commands: IndexMap<String, Arc<Block>>,
pub aliases: IndexMap<String, Vec<Spanned<String>>>,
///Optional tag to better identify this scope frame later
pub tag: Option<String>,

View File

@ -44,7 +44,7 @@ pub trait WholeStreamCommand: Send + Sync {
// implement a WholeStreamCommand
#[allow(clippy::suspicious_else_formatting)]
impl WholeStreamCommand for Block {
impl WholeStreamCommand for Arc<Block> {
fn name(&self) -> &str {
&self.params.name
}
@ -61,7 +61,10 @@ impl WholeStreamCommand for Block {
let call_info = args.call_info.clone();
let mut block = self.clone();
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block) {
block.set_redirect(call_info.args.external_redirection);
}
let ctx = EvaluationContext::from_args(&args);
let evaluated = call_info.evaluate(&ctx)?;

View File

@ -1,4 +1,4 @@
use std::path::Path;
use std::{path::Path, sync::Arc};
use indexmap::IndexMap;
use log::trace;
@ -428,7 +428,9 @@ fn parse_invocation(
let (mut classified_block, err) = classify_block(&lite_block, scope);
scope.exit_scope();
classified_block.set_redirect(ExternalRedirection::Stdout);
if let Some(x) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut classified_block) {
x.set_redirect(ExternalRedirection::Stdout);
}
(
SpannedExpression::new(Expression::Invocation(classified_block), lite_arg.span),
@ -638,12 +640,12 @@ fn parse_interpolated_string(
let group = Group::new(pipelines, lite_arg.span);
let call = SpannedExpression {
expr: Expression::Invocation(Block::new(
expr: Expression::Invocation(Arc::new(Block::new(
Signature::new("<invocation>"),
vec![group],
IndexMap::new(),
lite_arg.span,
)),
))),
span: lite_arg.span,
};
@ -1286,7 +1288,7 @@ fn parse_positional_argument(
span,
);
let arg = SpannedExpression::new(Expression::Block(block), span);
let arg = SpannedExpression::new(Expression::Block(Arc::new(block)), span);
idx = new_idx - 1;
if error.is_none() {
@ -1329,7 +1331,7 @@ fn parse_positional_argument(
span,
);
let arg = SpannedExpression::new(Expression::Block(block), span);
let arg = SpannedExpression::new(Expression::Block(Arc::new(block)), span);
idx = new_idx - 1;
if error.is_none() {
@ -1948,7 +1950,7 @@ fn parse_alias(call: &LiteCommand, scope: &dyn ParserScope) -> Option<ParseError
pub fn classify_block(
lite_block: &LiteBlock,
scope: &dyn ParserScope,
) -> (Block, Option<ParseError>) {
) -> (Arc<Block>, Option<ParseError>) {
let mut output = Block::basic();
let mut error = None;
@ -2012,7 +2014,7 @@ pub fn classify_block(
span: Span::new(vars.0.span.start(), vars.1.span.end()),
},
SpannedExpression {
expr: Expression::Block(block),
expr: Expression::Block(Arc::new(block)),
span,
},
]);
@ -2048,21 +2050,21 @@ pub fn classify_block(
}
output.infer_params();
(output, error)
(Arc::new(output), error)
}
pub fn parse(
input: &str,
span_offset: usize,
scope: &dyn ParserScope,
) -> (Block, Option<ParseError>) {
) -> (Arc<Block>, Option<ParseError>) {
let (output, error) = lex(input, span_offset);
if error.is_some() {
return (Block::basic(), error);
return (Arc::new(Block::basic()), error);
}
let (lite_block, error) = parse_block(output);
if error.is_some() {
return (Block::basic(), error);
return (Arc::new(Block::basic()), error);
}
classify_block(&lite_block, scope)

View File

@ -1,3 +1,5 @@
use std::sync::Arc;
use crate::{
lex::tokens::LiteCommand,
parse::{classify_block, util::trim_quotes},
@ -64,8 +66,11 @@ pub(crate) fn parse_definition(call: &LiteCommand, scope: &dyn ParserScope) -> O
let (mut block, err) = classify_block(&lite_block, scope);
scope.exit_scope();
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block)
{
block.params = signature;
block.params.name = name;
}
scope.add_definition(block);
@ -100,7 +105,12 @@ pub(crate) fn parse_definition_prototype(
err = error;
}
scope.add_definition(Block::new(signature, vec![], IndexMap::new(), call.span()));
scope.add_definition(Arc::new(Block::new(
signature,
vec![],
IndexMap::new(),
call.span(),
)));
err
}

View File

@ -1,15 +1,15 @@
use nu_protocol::hir::Block;
use nu_source::Spanned;
use std::fmt::Debug;
use std::{fmt::Debug, sync::Arc};
pub trait ParserScope: Debug {
fn get_signature(&self, name: &str) -> Option<nu_protocol::Signature>;
fn has_signature(&self, name: &str) -> bool;
fn add_definition(&self, block: Block);
fn add_definition(&self, block: Arc<Block>);
fn get_definitions(&self) -> Vec<Block>;
fn get_definitions(&self) -> Vec<Arc<Block>>;
fn get_alias(&self, name: &str) -> Option<Vec<Spanned<String>>>;

View File

@ -1,7 +1,7 @@
use std::cmp::{Ord, Ordering, PartialOrd};
use std::convert::From;
use std::hash::{Hash, Hasher};
use std::path::PathBuf;
use std::{convert::From, sync::Arc};
use serde::{Deserialize, Serialize};
@ -53,14 +53,14 @@ impl InternalCommand {
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub struct ClassifiedBlock {
pub block: Block,
pub block: Arc<Block>,
// this is not a Result to make it crystal clear that these shapes
// aren't intended to be used directly with `?`
pub failed: Option<ParseError>,
}
impl ClassifiedBlock {
pub fn new(block: Block, failed: Option<ParseError>) -> ClassifiedBlock {
pub fn new(block: Arc<Block>, failed: Option<ParseError>) -> ClassifiedBlock {
ClassifiedBlock { block, failed }
}
}
@ -159,12 +159,12 @@ impl Group {
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub struct CapturedBlock {
pub block: Block,
pub block: Arc<Block>,
pub captured: Dictionary,
}
impl CapturedBlock {
pub fn new(block: Block, captured: Dictionary) -> Self {
pub fn new(block: Arc<Block>, captured: Dictionary) -> Self {
Self { block, captured }
}
}
@ -173,7 +173,7 @@ impl CapturedBlock {
pub struct Block {
pub params: Signature,
pub block: Vec<Group>,
pub definitions: IndexMap<String, Block>,
pub definitions: IndexMap<String, Arc<Block>>,
pub span: Span,
}
@ -181,7 +181,7 @@ impl Block {
pub fn new(
params: Signature,
block: Vec<Group>,
definitions: IndexMap<String, Block>,
definitions: IndexMap<String, Arc<Block>>,
span: Span,
) -> Block {
Block {
@ -632,7 +632,7 @@ pub fn duration(nanos: BigInt) -> UntaggedValue {
UntaggedValue::Primitive(Primitive::Duration(nanos))
}
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, Deserialize, Serialize)]
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Deserialize, Serialize)]
pub struct SpannedExpression {
pub expr: Expression,
pub span: Span,
@ -1026,7 +1026,7 @@ pub enum Expression {
Variable(String, Span),
Binary(Box<Binary>),
Range(Box<Range>),
Block(hir::Block),
Block(Arc<hir::Block>),
List(Vec<SpannedExpression>),
Table(Vec<SpannedExpression>, Vec<Vec<SpannedExpression>>),
Path(Box<Path>),
@ -1034,7 +1034,7 @@ pub enum Expression {
FilePath(PathBuf),
ExternalCommand(ExternalStringCommand),
Command,
Invocation(hir::Block),
Invocation(Arc<hir::Block>),
Boolean(bool),