mirror of
https://github.com/nushell/nushell.git
synced 2024-11-25 09:53:43 +01:00
Move from using a Block to an Arc'd Block (#3289)
This commit is contained in:
parent
ac070ae942
commit
b791d1ab0d
@ -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();
|
||||
|
@ -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![]
|
||||
}
|
||||
|
||||
|
@ -166,21 +166,23 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn add_implicit_autoview(mut block: Block) -> Block {
|
||||
if block.block.is_empty() {
|
||||
let group = Group::new(
|
||||
vec![{
|
||||
let mut commands = Pipeline::new(block.span);
|
||||
commands.push(ClassifiedCommand::Internal(InternalCommand::new(
|
||||
"autoview".to_string(),
|
||||
block.span,
|
||||
block.span,
|
||||
)));
|
||||
commands
|
||||
}],
|
||||
block.span,
|
||||
);
|
||||
block.push(group);
|
||||
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![{
|
||||
let mut commands = Pipeline::new(block.span);
|
||||
commands.push(ClassifiedCommand::Internal(InternalCommand::new(
|
||||
"autoview".to_string(),
|
||||
block.span,
|
||||
block.span,
|
||||
)));
|
||||
commands
|
||||
}],
|
||||
block.span,
|
||||
);
|
||||
block.push(group);
|
||||
}
|
||||
}
|
||||
block
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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>,
|
||||
|
@ -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();
|
||||
block.set_redirect(call_info.args.external_redirection);
|
||||
|
||||
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)?;
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
||||
block.params = signature;
|
||||
block.params.name = name;
|
||||
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
|
||||
}
|
||||
|
@ -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>>>;
|
||||
|
||||
|
@ -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),
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user