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(); context.scope.enter_scope();
let (mut prompt_block, err) = nu_parser::parse(&prompt_line, 0, &context.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() { if err.is_some() {
context.scope.exit_scope(); context.scope.exit_scope();

View File

@ -254,6 +254,8 @@ pub fn completion_location(line: &str, block: &Block, pos: usize) -> Vec<Complet
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::Arc;
use super::*; use super::*;
use nu_parser::{classify_block, lex, parse_block, ParserScope}; use nu_parser::{classify_block, lex, parse_block, ParserScope};
@ -285,9 +287,9 @@ mod tests {
todo!() 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![] 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() { if block.block.is_empty() {
let group = Group::new( let group = Group::new(
vec![{ vec![{
@ -182,6 +183,7 @@ fn add_implicit_autoview(mut block: Block) -> Block {
); );
block.push(group); block.push(group);
} }
}
block block
} }

View File

@ -81,7 +81,9 @@ fn do_(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
x => x, 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(); context.scope.enter_scope();
let result = run_block(&block.block, &context, input); let result = run_block(&block.block, &context, input);
context.scope.exit_scope(); context.scope.exit_scope();

View File

@ -78,7 +78,9 @@ fn with_env(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
input, input,
) = raw_args.process()?; ) = 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(); 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 let custom_commands: Vec<_> = self
.frames .frames
.lock() .lock()
@ -307,7 +307,7 @@ impl ParserScope for Scope {
self.get_command(name).is_some() 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() { if let Some(frame) = self.frames.lock().last_mut() {
let name = block.params.name.clone(); let name = block.params.name.clone();
frame.custom_commands.insert(name.clone(), block.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![]; let mut blocks = vec![];
if let Some(frame) = self.frames.lock().last() { if let Some(frame) = self.frames.lock().last() {
for (_, custom_command) in &frame.custom_commands { for (_, custom_command) in &frame.custom_commands {
@ -356,7 +356,7 @@ pub struct ScopeFrame {
pub vars: IndexMap<String, Value>, pub vars: IndexMap<String, Value>,
pub env: IndexMap<String, String>, pub env: IndexMap<String, String>,
pub commands: IndexMap<String, Command>, 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>>>, pub aliases: IndexMap<String, Vec<Spanned<String>>>,
///Optional tag to better identify this scope frame later ///Optional tag to better identify this scope frame later
pub tag: Option<String>, pub tag: Option<String>,

View File

@ -44,7 +44,7 @@ pub trait WholeStreamCommand: Send + Sync {
// implement a WholeStreamCommand // implement a WholeStreamCommand
#[allow(clippy::suspicious_else_formatting)] #[allow(clippy::suspicious_else_formatting)]
impl WholeStreamCommand for Block { impl WholeStreamCommand for Arc<Block> {
fn name(&self) -> &str { fn name(&self) -> &str {
&self.params.name &self.params.name
} }
@ -61,7 +61,10 @@ impl WholeStreamCommand for Block {
let call_info = args.call_info.clone(); let call_info = args.call_info.clone();
let mut block = self.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); block.set_redirect(call_info.args.external_redirection);
}
let ctx = EvaluationContext::from_args(&args); let ctx = EvaluationContext::from_args(&args);
let evaluated = call_info.evaluate(&ctx)?; 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 indexmap::IndexMap;
use log::trace; use log::trace;
@ -428,7 +428,9 @@ fn parse_invocation(
let (mut classified_block, err) = classify_block(&lite_block, scope); let (mut classified_block, err) = classify_block(&lite_block, scope);
scope.exit_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), 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 group = Group::new(pipelines, lite_arg.span);
let call = SpannedExpression { let call = SpannedExpression {
expr: Expression::Invocation(Block::new( expr: Expression::Invocation(Arc::new(Block::new(
Signature::new("<invocation>"), Signature::new("<invocation>"),
vec![group], vec![group],
IndexMap::new(), IndexMap::new(),
lite_arg.span, lite_arg.span,
)), ))),
span: lite_arg.span, span: lite_arg.span,
}; };
@ -1286,7 +1288,7 @@ fn parse_positional_argument(
span, span,
); );
let arg = SpannedExpression::new(Expression::Block(block), span); let arg = SpannedExpression::new(Expression::Block(Arc::new(block)), span);
idx = new_idx - 1; idx = new_idx - 1;
if error.is_none() { if error.is_none() {
@ -1329,7 +1331,7 @@ fn parse_positional_argument(
span, span,
); );
let arg = SpannedExpression::new(Expression::Block(block), span); let arg = SpannedExpression::new(Expression::Block(Arc::new(block)), span);
idx = new_idx - 1; idx = new_idx - 1;
if error.is_none() { if error.is_none() {
@ -1948,7 +1950,7 @@ fn parse_alias(call: &LiteCommand, scope: &dyn ParserScope) -> Option<ParseError
pub fn classify_block( pub fn classify_block(
lite_block: &LiteBlock, lite_block: &LiteBlock,
scope: &dyn ParserScope, scope: &dyn ParserScope,
) -> (Block, Option<ParseError>) { ) -> (Arc<Block>, Option<ParseError>) {
let mut output = Block::basic(); let mut output = Block::basic();
let mut error = None; let mut error = None;
@ -2012,7 +2014,7 @@ pub fn classify_block(
span: Span::new(vars.0.span.start(), vars.1.span.end()), span: Span::new(vars.0.span.start(), vars.1.span.end()),
}, },
SpannedExpression { SpannedExpression {
expr: Expression::Block(block), expr: Expression::Block(Arc::new(block)),
span, span,
}, },
]); ]);
@ -2048,21 +2050,21 @@ pub fn classify_block(
} }
output.infer_params(); output.infer_params();
(output, error) (Arc::new(output), error)
} }
pub fn parse( pub fn parse(
input: &str, input: &str,
span_offset: usize, span_offset: usize,
scope: &dyn ParserScope, scope: &dyn ParserScope,
) -> (Block, Option<ParseError>) { ) -> (Arc<Block>, Option<ParseError>) {
let (output, error) = lex(input, span_offset); let (output, error) = lex(input, span_offset);
if error.is_some() { if error.is_some() {
return (Block::basic(), error); return (Arc::new(Block::basic()), error);
} }
let (lite_block, error) = parse_block(output); let (lite_block, error) = parse_block(output);
if error.is_some() { if error.is_some() {
return (Block::basic(), error); return (Arc::new(Block::basic()), error);
} }
classify_block(&lite_block, scope) classify_block(&lite_block, scope)

View File

@ -1,3 +1,5 @@
use std::sync::Arc;
use crate::{ use crate::{
lex::tokens::LiteCommand, lex::tokens::LiteCommand,
parse::{classify_block, util::trim_quotes}, 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); let (mut block, err) = classify_block(&lite_block, scope);
scope.exit_scope(); scope.exit_scope();
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block)
{
block.params = signature; block.params = signature;
block.params.name = name; block.params.name = name;
}
scope.add_definition(block); scope.add_definition(block);
@ -100,7 +105,12 @@ pub(crate) fn parse_definition_prototype(
err = error; 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 err
} }

View File

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

View File

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