mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 16:33:37 +01:00
Hopefully speedup startup (#8913)
# Description Trying a few different things to hopefully speedup startup a bit. I'm seeing some improvement on my box for the profiles I have, but the data I'm seeing is noisy. - Remove allocations in a few places where we created vec's but could use iterators - Pre-allocate space for blocks based on the lite block - Removed a few extra clones # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
parent
06996d8c7f
commit
32f098d91d
@ -179,11 +179,7 @@ impl Completer for VariableCompletion {
|
|||||||
let mut removed_overlays = vec![];
|
let mut removed_overlays = vec![];
|
||||||
// Working set scope vars
|
// Working set scope vars
|
||||||
for scope_frame in working_set.delta.scope.iter().rev() {
|
for scope_frame in working_set.delta.scope.iter().rev() {
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
for v in &overlay_frame.vars {
|
for v in &overlay_frame.vars {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
@ -204,12 +200,7 @@ impl Completer for VariableCompletion {
|
|||||||
|
|
||||||
// Permanent state vars
|
// Permanent state vars
|
||||||
// for scope in &self.engine_state.scope {
|
// for scope in &self.engine_state.scope {
|
||||||
for overlay_frame in self
|
for overlay_frame in self.engine_state.active_overlays(&removed_overlays).rev() {
|
||||||
.engine_state
|
|
||||||
.active_overlays(&removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
for v in &overlay_frame.vars {
|
for v in &overlay_frame.vars {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
|
@ -232,6 +232,17 @@ pub fn parse_for(working_set: &mut StateWorkingSet, spans: &[Span]) -> Expressio
|
|||||||
let decl = working_set.get_decl(decl_id);
|
let decl = working_set.get_decl(decl_id);
|
||||||
let sig = decl.signature();
|
let sig = decl.signature();
|
||||||
|
|
||||||
|
let starting_error_count = working_set.parse_errors.len();
|
||||||
|
check_call(working_set, call_span, &sig, &call);
|
||||||
|
if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") {
|
||||||
|
return Expression {
|
||||||
|
expr: Expr::Call(call),
|
||||||
|
span: call_span,
|
||||||
|
ty: output,
|
||||||
|
custom_completion: None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Let's get our block and make sure it has the right signature
|
// Let's get our block and make sure it has the right signature
|
||||||
if let Some(arg) = call.positional_nth(2) {
|
if let Some(arg) = call.positional_nth(2) {
|
||||||
match arg {
|
match arg {
|
||||||
@ -245,23 +256,12 @@ pub fn parse_for(working_set: &mut StateWorkingSet, spans: &[Span]) -> Expressio
|
|||||||
} => {
|
} => {
|
||||||
let block = working_set.get_block_mut(*block_id);
|
let block = working_set.get_block_mut(*block_id);
|
||||||
|
|
||||||
block.signature = Box::new(sig.clone());
|
block.signature = Box::new(sig);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let starting_error_count = working_set.parse_errors.len();
|
|
||||||
check_call(working_set, call_span, &sig, &call);
|
|
||||||
if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") {
|
|
||||||
return Expression {
|
|
||||||
expr: Expr::Call(call),
|
|
||||||
span: call_span,
|
|
||||||
ty: output,
|
|
||||||
custom_completion: None,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
(call, call_span)
|
(call, call_span)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1403,85 +1403,87 @@ pub fn parse_module_block(
|
|||||||
|
|
||||||
let mut module = Module::from_span(module_name.to_vec(), span);
|
let mut module = Module::from_span(module_name.to_vec(), span);
|
||||||
|
|
||||||
let block: Block = output
|
let mut block = Block::new_with_capacity(output.block.len());
|
||||||
.block
|
|
||||||
.iter()
|
|
||||||
.map(|pipeline| {
|
|
||||||
if pipeline.commands.len() == 1 {
|
|
||||||
match &pipeline.commands[0] {
|
|
||||||
LiteElement::Command(_, command) => {
|
|
||||||
let name = working_set.get_span_contents(command.parts[0]);
|
|
||||||
|
|
||||||
match name {
|
for pipeline in output.block.iter() {
|
||||||
b"def" | b"def-env" => {
|
if pipeline.commands.len() == 1 {
|
||||||
parse_def(
|
match &pipeline.commands[0] {
|
||||||
working_set,
|
LiteElement::Command(_, command) => {
|
||||||
command,
|
let name = working_set.get_span_contents(command.parts[0]);
|
||||||
None, // using commands named as the module locally is OK
|
|
||||||
)
|
|
||||||
}
|
|
||||||
b"extern" => parse_extern(working_set, command, None),
|
|
||||||
b"alias" => {
|
|
||||||
parse_alias(
|
|
||||||
working_set,
|
|
||||||
command,
|
|
||||||
None, // using aliases named as the module locally is OK
|
|
||||||
)
|
|
||||||
}
|
|
||||||
b"use" => {
|
|
||||||
let (pipeline, _) = parse_use(working_set, &command.parts);
|
|
||||||
|
|
||||||
pipeline
|
match name {
|
||||||
}
|
b"def" | b"def-env" => {
|
||||||
b"export" => {
|
block.pipelines.push(parse_def(
|
||||||
let (pipe, exportables) =
|
working_set,
|
||||||
parse_export_in_module(working_set, command, module_name);
|
command,
|
||||||
|
None, // using commands named as the module locally is OK
|
||||||
|
))
|
||||||
|
}
|
||||||
|
b"extern" => block
|
||||||
|
.pipelines
|
||||||
|
.push(parse_extern(working_set, command, None)),
|
||||||
|
b"alias" => {
|
||||||
|
block.pipelines.push(parse_alias(
|
||||||
|
working_set,
|
||||||
|
command,
|
||||||
|
None, // using aliases named as the module locally is OK
|
||||||
|
))
|
||||||
|
}
|
||||||
|
b"use" => {
|
||||||
|
let (pipeline, _) = parse_use(working_set, &command.parts);
|
||||||
|
|
||||||
for exportable in exportables {
|
block.pipelines.push(pipeline)
|
||||||
match exportable {
|
}
|
||||||
Exportable::Decl { name, id } => {
|
b"export" => {
|
||||||
if &name == b"main" {
|
let (pipe, exportables) =
|
||||||
module.main = Some(id);
|
parse_export_in_module(working_set, command, module_name);
|
||||||
} else {
|
|
||||||
module.add_decl(name, id);
|
for exportable in exportables {
|
||||||
}
|
match exportable {
|
||||||
|
Exportable::Decl { name, id } => {
|
||||||
|
if &name == b"main" {
|
||||||
|
module.main = Some(id);
|
||||||
|
} else {
|
||||||
|
module.add_decl(name, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe
|
|
||||||
}
|
}
|
||||||
b"export-env" => {
|
|
||||||
let (pipe, maybe_env_block) =
|
|
||||||
parse_export_env(working_set, &command.parts);
|
|
||||||
|
|
||||||
if let Some(block_id) = maybe_env_block {
|
block.pipelines.push(pipe)
|
||||||
module.add_env_block(block_id);
|
}
|
||||||
}
|
b"export-env" => {
|
||||||
|
let (pipe, maybe_env_block) =
|
||||||
|
parse_export_env(working_set, &command.parts);
|
||||||
|
|
||||||
pipe
|
if let Some(block_id) = maybe_env_block {
|
||||||
|
module.add_env_block(block_id);
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
working_set.error(ParseError::ExpectedKeyword(
|
|
||||||
"def or export keyword".into(),
|
|
||||||
command.parts[0],
|
|
||||||
));
|
|
||||||
|
|
||||||
garbage_pipeline(&command.parts)
|
block.pipelines.push(pipe)
|
||||||
}
|
}
|
||||||
|
_ => {
|
||||||
|
working_set.error(ParseError::ExpectedKeyword(
|
||||||
|
"def or export keyword".into(),
|
||||||
|
command.parts[0],
|
||||||
|
));
|
||||||
|
|
||||||
|
block.pipelines.push(garbage_pipeline(&command.parts))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LiteElement::Redirection(_, _, command) => garbage_pipeline(&command.parts),
|
|
||||||
LiteElement::SeparateRedirection {
|
|
||||||
out: (_, command), ..
|
|
||||||
} => garbage_pipeline(&command.parts),
|
|
||||||
}
|
}
|
||||||
} else {
|
LiteElement::Redirection(_, _, command) => {
|
||||||
working_set.error(ParseError::Expected("not a pipeline".into(), span));
|
block.pipelines.push(garbage_pipeline(&command.parts))
|
||||||
garbage_pipeline(&[span])
|
}
|
||||||
|
LiteElement::SeparateRedirection {
|
||||||
|
out: (_, command), ..
|
||||||
|
} => block.pipelines.push(garbage_pipeline(&command.parts)),
|
||||||
}
|
}
|
||||||
})
|
} else {
|
||||||
.into();
|
working_set.error(ParseError::Expected("not a pipeline".into(), span));
|
||||||
|
block.pipelines.push(garbage_pipeline(&[span]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
working_set.exit_scope();
|
working_set.exit_scope();
|
||||||
|
|
||||||
|
@ -2145,7 +2145,12 @@ pub fn parse_datetime(working_set: &mut StateWorkingSet, span: Span) -> Expressi
|
|||||||
|
|
||||||
let bytes = working_set.get_span_contents(span);
|
let bytes = working_set.get_span_contents(span);
|
||||||
|
|
||||||
if bytes.is_empty() || !bytes[0].is_ascii_digit() {
|
if bytes.len() < 5
|
||||||
|
|| !bytes[0].is_ascii_digit()
|
||||||
|
|| !bytes[1].is_ascii_digit()
|
||||||
|
|| !bytes[2].is_ascii_digit()
|
||||||
|
|| !bytes[3].is_ascii_digit()
|
||||||
|
{
|
||||||
working_set.error(ParseError::Expected("datetime".into(), span));
|
working_set.error(ParseError::Expected("datetime".into(), span));
|
||||||
return garbage(span);
|
return garbage(span);
|
||||||
}
|
}
|
||||||
@ -2450,6 +2455,10 @@ pub fn unescape_string(bytes: &[u8], span: Span) -> (Vec<u8>, Option<ParseError>
|
|||||||
|
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
|
|
||||||
|
if !bytes.contains(&b'\\') {
|
||||||
|
return (bytes.to_vec(), None);
|
||||||
|
}
|
||||||
|
|
||||||
'us_loop: while idx < bytes.len() {
|
'us_loop: while idx < bytes.len() {
|
||||||
if bytes[idx] == b'\\' {
|
if bytes[idx] == b'\\' {
|
||||||
// We're in an escape
|
// We're in an escape
|
||||||
@ -4523,7 +4532,6 @@ pub fn parse_value(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
working_set.error(ParseError::Expected("any shape".into(), span));
|
working_set.error(ParseError::Expected("any shape".into(), span));
|
||||||
|
|
||||||
garbage(span)
|
garbage(span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5217,132 +5225,127 @@ pub fn parse_block(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let block: Block = lite_block
|
let mut block = Block::new_with_capacity(lite_block.block.len());
|
||||||
.block
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, pipeline)| {
|
|
||||||
if pipeline.commands.len() > 1 {
|
|
||||||
let mut output = pipeline
|
|
||||||
.commands
|
|
||||||
.iter()
|
|
||||||
.map(|command| match command {
|
|
||||||
LiteElement::Command(span, command) => {
|
|
||||||
trace!("parsing: pipeline element: command");
|
|
||||||
let expr =
|
|
||||||
parse_expression(working_set, &command.parts, is_subexpression);
|
|
||||||
working_set.type_scope.add_type(expr.ty.clone());
|
|
||||||
|
|
||||||
PipelineElement::Expression(*span, expr)
|
for (idx, pipeline) in lite_block.block.iter().enumerate() {
|
||||||
}
|
if pipeline.commands.len() > 1 {
|
||||||
LiteElement::Redirection(span, redirection, command) => {
|
let mut output = pipeline
|
||||||
trace!("parsing: pipeline element: redirection");
|
.commands
|
||||||
let expr = parse_string(working_set, command.parts[0]);
|
.iter()
|
||||||
|
.map(|command| match command {
|
||||||
|
LiteElement::Command(span, command) => {
|
||||||
|
trace!("parsing: pipeline element: command");
|
||||||
|
let expr = parse_expression(working_set, &command.parts, is_subexpression);
|
||||||
|
working_set.type_scope.add_type(expr.ty.clone());
|
||||||
|
|
||||||
working_set.type_scope.add_type(expr.ty.clone());
|
PipelineElement::Expression(*span, expr)
|
||||||
|
}
|
||||||
|
LiteElement::Redirection(span, redirection, command) => {
|
||||||
|
trace!("parsing: pipeline element: redirection");
|
||||||
|
let expr = parse_string(working_set, command.parts[0]);
|
||||||
|
|
||||||
PipelineElement::Redirection(*span, redirection.clone(), expr)
|
working_set.type_scope.add_type(expr.ty.clone());
|
||||||
}
|
|
||||||
LiteElement::SeparateRedirection {
|
|
||||||
out: (out_span, out_command),
|
|
||||||
err: (err_span, err_command),
|
|
||||||
} => {
|
|
||||||
trace!("parsing: pipeline element: separate redirection");
|
|
||||||
let out_expr = parse_string(working_set, out_command.parts[0]);
|
|
||||||
|
|
||||||
working_set.type_scope.add_type(out_expr.ty.clone());
|
PipelineElement::Redirection(*span, redirection.clone(), expr)
|
||||||
|
}
|
||||||
|
LiteElement::SeparateRedirection {
|
||||||
|
out: (out_span, out_command),
|
||||||
|
err: (err_span, err_command),
|
||||||
|
} => {
|
||||||
|
trace!("parsing: pipeline element: separate redirection");
|
||||||
|
let out_expr = parse_string(working_set, out_command.parts[0]);
|
||||||
|
|
||||||
let err_expr = parse_string(working_set, err_command.parts[0]);
|
working_set.type_scope.add_type(out_expr.ty.clone());
|
||||||
|
|
||||||
working_set.type_scope.add_type(err_expr.ty.clone());
|
let err_expr = parse_string(working_set, err_command.parts[0]);
|
||||||
|
|
||||||
PipelineElement::SeparateRedirection {
|
working_set.type_scope.add_type(err_expr.ty.clone());
|
||||||
out: (*out_span, out_expr),
|
|
||||||
err: (*err_span, err_expr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<PipelineElement>>();
|
|
||||||
|
|
||||||
if is_subexpression {
|
PipelineElement::SeparateRedirection {
|
||||||
for element in output.iter_mut().skip(1) {
|
out: (*out_span, out_expr),
|
||||||
if element.has_in_variable(working_set) {
|
err: (*err_span, err_expr),
|
||||||
*element = wrap_element_with_collect(working_set, element);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
})
|
||||||
for element in output.iter_mut() {
|
.collect::<Vec<PipelineElement>>();
|
||||||
if element.has_in_variable(working_set) {
|
|
||||||
*element = wrap_element_with_collect(working_set, element);
|
if is_subexpression {
|
||||||
}
|
for element in output.iter_mut().skip(1) {
|
||||||
|
if element.has_in_variable(working_set) {
|
||||||
|
*element = wrap_element_with_collect(working_set, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline { elements: output }
|
|
||||||
} else {
|
} else {
|
||||||
match &pipeline.commands[0] {
|
for element in output.iter_mut() {
|
||||||
LiteElement::Command(_, command)
|
if element.has_in_variable(working_set) {
|
||||||
| LiteElement::Redirection(_, _, command)
|
*element = wrap_element_with_collect(working_set, element);
|
||||||
| LiteElement::SeparateRedirection {
|
}
|
||||||
out: (_, command), ..
|
}
|
||||||
} => {
|
}
|
||||||
let mut pipeline =
|
|
||||||
parse_builtin_commands(working_set, command, is_subexpression);
|
|
||||||
|
|
||||||
if idx == 0 {
|
block.pipelines.push(Pipeline { elements: output })
|
||||||
if let Some(let_decl_id) = working_set.find_decl(b"let", &Type::Any) {
|
} else {
|
||||||
if let Some(let_env_decl_id) =
|
match &pipeline.commands[0] {
|
||||||
working_set.find_decl(b"let-env", &Type::Any)
|
LiteElement::Command(_, command)
|
||||||
{
|
| LiteElement::Redirection(_, _, command)
|
||||||
for element in pipeline.elements.iter_mut() {
|
| LiteElement::SeparateRedirection {
|
||||||
if let PipelineElement::Expression(
|
out: (_, command), ..
|
||||||
_,
|
} => {
|
||||||
Expression {
|
let mut pipeline =
|
||||||
expr: Expr::Call(call),
|
parse_builtin_commands(working_set, command, is_subexpression);
|
||||||
..
|
|
||||||
},
|
if idx == 0 {
|
||||||
) = element
|
if let Some(let_decl_id) = working_set.find_decl(b"let", &Type::Any) {
|
||||||
|
if let Some(let_env_decl_id) =
|
||||||
|
working_set.find_decl(b"let-env", &Type::Any)
|
||||||
|
{
|
||||||
|
for element in pipeline.elements.iter_mut() {
|
||||||
|
if let PipelineElement::Expression(
|
||||||
|
_,
|
||||||
|
Expression {
|
||||||
|
expr: Expr::Call(call),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
) = element
|
||||||
|
{
|
||||||
|
if call.decl_id == let_decl_id
|
||||||
|
|| call.decl_id == let_env_decl_id
|
||||||
{
|
{
|
||||||
if call.decl_id == let_decl_id
|
// Do an expansion
|
||||||
|| call.decl_id == let_env_decl_id
|
if let Some(Expression {
|
||||||
|
expr: Expr::Keyword(_, _, expr),
|
||||||
|
..
|
||||||
|
}) = call.positional_iter_mut().nth(1)
|
||||||
{
|
{
|
||||||
// Do an expansion
|
if expr.has_in_variable(working_set) {
|
||||||
if let Some(Expression {
|
*expr = Box::new(wrap_expr_with_collect(
|
||||||
expr: Expr::Keyword(_, _, expr),
|
working_set,
|
||||||
..
|
expr,
|
||||||
}) = call.positional_iter_mut().nth(1)
|
));
|
||||||
{
|
|
||||||
if expr.has_in_variable(working_set) {
|
|
||||||
*expr = Box::new(wrap_expr_with_collect(
|
|
||||||
working_set,
|
|
||||||
expr,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
} else if element.has_in_variable(working_set)
|
|
||||||
&& !is_subexpression
|
|
||||||
{
|
|
||||||
*element =
|
|
||||||
wrap_element_with_collect(working_set, element);
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
} else if element.has_in_variable(working_set)
|
} else if element.has_in_variable(working_set)
|
||||||
&& !is_subexpression
|
&& !is_subexpression
|
||||||
{
|
{
|
||||||
*element =
|
*element =
|
||||||
wrap_element_with_collect(working_set, element);
|
wrap_element_with_collect(working_set, element);
|
||||||
}
|
}
|
||||||
|
} else if element.has_in_variable(working_set)
|
||||||
|
&& !is_subexpression
|
||||||
|
{
|
||||||
|
*element = wrap_element_with_collect(working_set, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block.pipelines.push(pipeline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.into();
|
}
|
||||||
|
|
||||||
if scoped {
|
if scoped {
|
||||||
working_set.exit_scope();
|
working_set.exit_scope();
|
||||||
@ -5663,6 +5666,7 @@ pub fn discover_captures_in_expr(
|
|||||||
)?;
|
)?;
|
||||||
results
|
results
|
||||||
};
|
};
|
||||||
|
|
||||||
seen_blocks.insert(*block_id, results.clone());
|
seen_blocks.insert(*block_id, results.clone());
|
||||||
for (var_id, span) in results.into_iter() {
|
for (var_id, span) in results.into_iter() {
|
||||||
if !seen.contains(&var_id) {
|
if !seen.contains(&var_id) {
|
||||||
|
@ -55,6 +55,17 @@ impl Block {
|
|||||||
recursive: None,
|
recursive: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_with_capacity(capacity: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
signature: Box::new(Signature::new("")),
|
||||||
|
pipelines: Vec::with_capacity(capacity),
|
||||||
|
captures: vec![],
|
||||||
|
redirect_env: false,
|
||||||
|
span: None,
|
||||||
|
recursive: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<T> for Block
|
impl<T> From<T> for Block
|
||||||
|
@ -323,27 +323,39 @@ impl EngineState {
|
|||||||
.any(|(overlay_name, _)| name == overlay_name)
|
.any(|(overlay_name, _)| name == overlay_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_overlay_ids(&self, removed_overlays: &[Vec<u8>]) -> Vec<OverlayId> {
|
pub fn active_overlay_ids<'a, 'b>(
|
||||||
|
&'b self,
|
||||||
|
removed_overlays: &'a [Vec<u8>],
|
||||||
|
) -> impl DoubleEndedIterator<Item = &OverlayId> + 'a
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
self.scope
|
self.scope
|
||||||
.active_overlays
|
.active_overlays
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|id| !removed_overlays.contains(self.get_overlay_name(**id)))
|
.filter(|id| !removed_overlays.contains(self.get_overlay_name(**id)))
|
||||||
.copied()
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_overlays(&self, removed_overlays: &[Vec<u8>]) -> Vec<&OverlayFrame> {
|
pub fn active_overlays<'a, 'b>(
|
||||||
|
&'b self,
|
||||||
|
removed_overlays: &'a [Vec<u8>],
|
||||||
|
) -> impl DoubleEndedIterator<Item = &OverlayFrame> + 'a
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
self.active_overlay_ids(removed_overlays)
|
self.active_overlay_ids(removed_overlays)
|
||||||
.iter()
|
|
||||||
.map(|id| self.get_overlay(*id))
|
.map(|id| self.get_overlay(*id))
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_overlay_names(&self, removed_overlays: &[Vec<u8>]) -> Vec<&Vec<u8>> {
|
pub fn active_overlay_names<'a, 'b>(
|
||||||
|
&'b self,
|
||||||
|
removed_overlays: &'a [Vec<u8>],
|
||||||
|
) -> impl DoubleEndedIterator<Item = &Vec<u8>> + 'a
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
self.active_overlay_ids(removed_overlays)
|
self.active_overlay_ids(removed_overlays)
|
||||||
.iter()
|
|
||||||
.map(|id| self.get_overlay_name(*id))
|
.map(|id| self.get_overlay_name(*id))
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translate overlay IDs from other to IDs in self
|
/// Translate overlay IDs from other to IDs in self
|
||||||
@ -587,7 +599,7 @@ impl EngineState {
|
|||||||
pub fn find_decl(&self, name: &[u8], removed_overlays: &[Vec<u8>]) -> Option<DeclId> {
|
pub fn find_decl(&self, name: &[u8], removed_overlays: &[Vec<u8>]) -> Option<DeclId> {
|
||||||
let mut visibility: Visibility = Visibility::new();
|
let mut visibility: Visibility = Visibility::new();
|
||||||
|
|
||||||
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
|
for overlay_frame in self.active_overlays(removed_overlays).rev() {
|
||||||
visibility.append(&overlay_frame.visibility);
|
visibility.append(&overlay_frame.visibility);
|
||||||
|
|
||||||
if let Some(decl_id) = overlay_frame.get_decl(name, &Type::Any) {
|
if let Some(decl_id) = overlay_frame.get_decl(name, &Type::Any) {
|
||||||
@ -603,7 +615,7 @@ impl EngineState {
|
|||||||
pub fn find_decl_name(&self, decl_id: DeclId, removed_overlays: &[Vec<u8>]) -> Option<&[u8]> {
|
pub fn find_decl_name(&self, decl_id: DeclId, removed_overlays: &[Vec<u8>]) -> Option<&[u8]> {
|
||||||
let mut visibility: Visibility = Visibility::new();
|
let mut visibility: Visibility = Visibility::new();
|
||||||
|
|
||||||
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
|
for overlay_frame in self.active_overlays(removed_overlays).rev() {
|
||||||
visibility.append(&overlay_frame.visibility);
|
visibility.append(&overlay_frame.visibility);
|
||||||
|
|
||||||
if visibility.is_decl_id_visible(&decl_id) {
|
if visibility.is_decl_id_visible(&decl_id) {
|
||||||
@ -640,7 +652,7 @@ impl EngineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_module(&self, name: &[u8], removed_overlays: &[Vec<u8>]) -> Option<ModuleId> {
|
pub fn find_module(&self, name: &[u8], removed_overlays: &[Vec<u8>]) -> Option<ModuleId> {
|
||||||
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
|
for overlay_frame in self.active_overlays(removed_overlays).rev() {
|
||||||
if let Some(module_id) = overlay_frame.modules.get(name) {
|
if let Some(module_id) = overlay_frame.modules.get(name) {
|
||||||
return Some(*module_id);
|
return Some(*module_id);
|
||||||
}
|
}
|
||||||
@ -654,7 +666,7 @@ impl EngineState {
|
|||||||
decl_name: &[u8],
|
decl_name: &[u8],
|
||||||
removed_overlays: &[Vec<u8>],
|
removed_overlays: &[Vec<u8>],
|
||||||
) -> Option<&[u8]> {
|
) -> Option<&[u8]> {
|
||||||
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
|
for overlay_frame in self.active_overlays(removed_overlays).rev() {
|
||||||
for (module_name, module_id) in overlay_frame.modules.iter() {
|
for (module_name, module_id) in overlay_frame.modules.iter() {
|
||||||
let module = self.get_module(*module_id);
|
let module = self.get_module(*module_id);
|
||||||
if module.has_decl(decl_name) {
|
if module.has_decl(decl_name) {
|
||||||
@ -680,7 +692,7 @@ impl EngineState {
|
|||||||
) -> Vec<(Vec<u8>, Option<String>)> {
|
) -> Vec<(Vec<u8>, Option<String>)> {
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
|
||||||
for overlay_frame in self.active_overlays(&[]).iter().rev() {
|
for overlay_frame in self.active_overlays(&[]).rev() {
|
||||||
for decl in &overlay_frame.decls {
|
for decl in &overlay_frame.decls {
|
||||||
if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(&decl.0 .0) {
|
if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(&decl.0 .0) {
|
||||||
let command = self.get_decl(*decl.1);
|
let command = self.get_decl(*decl.1);
|
||||||
@ -693,7 +705,7 @@ impl EngineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_constant(&self, var_id: VarId, removed_overlays: &[Vec<u8>]) -> Option<&Value> {
|
pub fn find_constant(&self, var_id: VarId, removed_overlays: &[Vec<u8>]) -> Option<&Value> {
|
||||||
for overlay_frame in self.active_overlays(removed_overlays).iter().rev() {
|
for overlay_frame in self.active_overlays(removed_overlays).rev() {
|
||||||
if let Some(val) = overlay_frame.constants.get(&var_id) {
|
if let Some(val) = overlay_frame.constants.get(&var_id) {
|
||||||
return Some(val);
|
return Some(val);
|
||||||
}
|
}
|
||||||
@ -1236,7 +1248,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
for scope_frame in self.delta.scope.iter_mut().rev() {
|
for scope_frame in self.delta.scope.iter_mut().rev() {
|
||||||
for overlay_id in scope_frame
|
for overlay_id in scope_frame
|
||||||
.active_overlay_ids(&mut removed_overlays)
|
.active_overlay_ids(&mut removed_overlays)
|
||||||
.iter_mut()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
let overlay_frame = scope_frame.get_overlay_mut(*overlay_id);
|
let overlay_frame = scope_frame.get_overlay_mut(*overlay_id);
|
||||||
@ -1258,7 +1270,6 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
for overlay_frame in self
|
for overlay_frame in self
|
||||||
.permanent_state
|
.permanent_state
|
||||||
.active_overlays(&removed_overlays)
|
.active_overlays(&removed_overlays)
|
||||||
.iter()
|
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
visibility.append(&overlay_frame.visibility);
|
visibility.append(&overlay_frame.visibility);
|
||||||
@ -1417,11 +1428,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
return Some(*decl_id);
|
return Some(*decl_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
if let Some(decl_id) = overlay_frame.predecls.get(name) {
|
if let Some(decl_id) = overlay_frame.predecls.get(name) {
|
||||||
return Some(*decl_id);
|
return Some(*decl_id);
|
||||||
}
|
}
|
||||||
@ -1444,11 +1451,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check overlay in delta
|
// check overlay in delta
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
visibility.append(&overlay_frame.visibility);
|
visibility.append(&overlay_frame.visibility);
|
||||||
|
|
||||||
if let Some(decl_id) = overlay_frame.predecls.get(name) {
|
if let Some(decl_id) = overlay_frame.predecls.get(name) {
|
||||||
@ -1469,7 +1472,6 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
for overlay_frame in self
|
for overlay_frame in self
|
||||||
.permanent_state
|
.permanent_state
|
||||||
.active_overlays(&removed_overlays)
|
.active_overlays(&removed_overlays)
|
||||||
.iter()
|
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
visibility.append(&overlay_frame.visibility);
|
visibility.append(&overlay_frame.visibility);
|
||||||
@ -1488,11 +1490,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
let mut removed_overlays = vec![];
|
let mut removed_overlays = vec![];
|
||||||
|
|
||||||
for scope_frame in self.delta.scope.iter().rev() {
|
for scope_frame in self.delta.scope.iter().rev() {
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
if let Some(module_id) = overlay_frame.modules.get(name) {
|
if let Some(module_id) = overlay_frame.modules.get(name) {
|
||||||
return Some(*module_id);
|
return Some(*module_id);
|
||||||
}
|
}
|
||||||
@ -1502,7 +1500,6 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
for overlay_frame in self
|
for overlay_frame in self
|
||||||
.permanent_state
|
.permanent_state
|
||||||
.active_overlays(&removed_overlays)
|
.active_overlays(&removed_overlays)
|
||||||
.iter()
|
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
if let Some(module_id) = overlay_frame.modules.get(name) {
|
if let Some(module_id) = overlay_frame.modules.get(name) {
|
||||||
@ -1517,11 +1514,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
let mut removed_overlays = vec![];
|
let mut removed_overlays = vec![];
|
||||||
|
|
||||||
for scope_frame in self.delta.scope.iter().rev() {
|
for scope_frame in self.delta.scope.iter().rev() {
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
for decl in &overlay_frame.decls {
|
for decl in &overlay_frame.decls {
|
||||||
if decl.0 .0.starts_with(name) {
|
if decl.0 .0.starts_with(name) {
|
||||||
return true;
|
return true;
|
||||||
@ -1533,7 +1526,6 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
for overlay_frame in self
|
for overlay_frame in self
|
||||||
.permanent_state
|
.permanent_state
|
||||||
.active_overlays(&removed_overlays)
|
.active_overlays(&removed_overlays)
|
||||||
.iter()
|
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
for decl in &overlay_frame.decls {
|
for decl in &overlay_frame.decls {
|
||||||
@ -1555,11 +1547,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
let mut removed_overlays = vec![];
|
let mut removed_overlays = vec![];
|
||||||
|
|
||||||
for scope_frame in self.delta.scope.iter().rev() {
|
for scope_frame in self.delta.scope.iter().rev() {
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
if let Some(var_id) = overlay_frame.vars.get(name) {
|
if let Some(var_id) = overlay_frame.vars.get(name) {
|
||||||
return Some(*var_id);
|
return Some(*var_id);
|
||||||
}
|
}
|
||||||
@ -1569,7 +1557,6 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
for overlay_frame in self
|
for overlay_frame in self
|
||||||
.permanent_state
|
.permanent_state
|
||||||
.active_overlays(&removed_overlays)
|
.active_overlays(&removed_overlays)
|
||||||
.iter()
|
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
if let Some(var_id) = overlay_frame.vars.get(name) {
|
if let Some(var_id) = overlay_frame.vars.get(name) {
|
||||||
@ -1584,11 +1571,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
let mut removed_overlays = vec![];
|
let mut removed_overlays = vec![];
|
||||||
|
|
||||||
for scope_frame in self.delta.scope.iter().rev().take(1) {
|
for scope_frame in self.delta.scope.iter().rev().take(1) {
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
if let Some(var_id) = overlay_frame.vars.get(name) {
|
if let Some(var_id) = overlay_frame.vars.get(name) {
|
||||||
return Some(*var_id);
|
return Some(*var_id);
|
||||||
}
|
}
|
||||||
@ -1662,11 +1645,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
let mut removed_overlays = vec![];
|
let mut removed_overlays = vec![];
|
||||||
|
|
||||||
for scope_frame in self.delta.scope.iter().rev() {
|
for scope_frame in self.delta.scope.iter().rev() {
|
||||||
for overlay_frame in scope_frame
|
for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() {
|
||||||
.active_overlays(&mut removed_overlays)
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
{
|
|
||||||
if let Some(val) = overlay_frame.constants.get(&var_id) {
|
if let Some(val) = overlay_frame.constants.get(&var_id) {
|
||||||
return Some(val);
|
return Some(val);
|
||||||
}
|
}
|
||||||
@ -1835,7 +1814,6 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
for scope_frame in self.delta.scope.iter().rev() {
|
for scope_frame in self.delta.scope.iter().rev() {
|
||||||
if let Some(last_overlay) = scope_frame
|
if let Some(last_overlay) = scope_frame
|
||||||
.active_overlays(&mut removed_overlays)
|
.active_overlays(&mut removed_overlays)
|
||||||
.iter()
|
|
||||||
.rev()
|
.rev()
|
||||||
.last()
|
.last()
|
||||||
{
|
{
|
||||||
|
@ -115,11 +115,16 @@ impl ScopeFrame {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_overlays(&self, removed_overlays: &mut Vec<Vec<u8>>) -> Vec<&OverlayFrame> {
|
pub fn active_overlays<'a, 'b>(
|
||||||
|
&'b self,
|
||||||
|
removed_overlays: &'a mut Vec<Vec<u8>>,
|
||||||
|
) -> impl DoubleEndedIterator<Item = &OverlayFrame> + 'a
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
self.active_overlay_ids(removed_overlays)
|
self.active_overlay_ids(removed_overlays)
|
||||||
.iter()
|
.into_iter()
|
||||||
.map(|id| self.get_overlay(*id))
|
.map(|id| self.get_overlay(id))
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_overlay_names(&self, removed_overlays: &mut Vec<Vec<u8>>) -> Vec<&Vec<u8>> {
|
pub fn active_overlay_names(&self, removed_overlays: &mut Vec<Vec<u8>>) -> Vec<&Vec<u8>> {
|
||||||
|
Loading…
Reference in New Issue
Block a user