forked from extern/nushell
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();
|
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();
|
||||||
|
@ -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![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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>,
|
||||||
|
@ -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)?;
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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>>>;
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user