mirror of
https://github.com/nushell/nushell.git
synced 2025-01-10 16:28:50 +01:00
Allow adding definitions from module into scope
This commit is contained in:
parent
9e176674a5
commit
f57f7b2def
@ -10,7 +10,7 @@ use nu_protocol::{
|
|||||||
RangeInclusion, RangeOperator, Statement,
|
RangeInclusion, RangeOperator, Statement,
|
||||||
},
|
},
|
||||||
engine::StateWorkingSet,
|
engine::StateWorkingSet,
|
||||||
span, Flag, PositionalArg, Signature, Span, SyntaxShape, Type, VarId,
|
span, DeclId, Flag, PositionalArg, Signature, Span, SyntaxShape, Type, VarId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -2653,6 +2653,9 @@ pub fn parse_module(
|
|||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
) -> (Statement, Option<ParseError>) {
|
) -> (Statement, Option<ParseError>) {
|
||||||
|
// TODO: Currently, module is closing over its parent scope (i.e., defs in the parent scope are
|
||||||
|
// visible and usable in this module's scope). We might want to disable that. How?
|
||||||
|
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
let bytes = working_set.get_span_contents(spans[0]);
|
let bytes = working_set.get_span_contents(spans[0]);
|
||||||
|
|
||||||
@ -2719,7 +2722,7 @@ pub fn parse_module(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut exports: Vec<Vec<u8>> = vec![];
|
let mut exports: Vec<(Vec<u8>, DeclId)> = vec![];
|
||||||
|
|
||||||
let block: Block = output
|
let block: Block = output
|
||||||
.block
|
.block
|
||||||
@ -2736,10 +2739,15 @@ pub fn parse_module(
|
|||||||
let (stmt, err) = parse_def(working_set, &pipeline.commands[0].parts);
|
let (stmt, err) = parse_def(working_set, &pipeline.commands[0].parts);
|
||||||
|
|
||||||
if err.is_none() {
|
if err.is_none() {
|
||||||
let def_name =
|
let decl_name =
|
||||||
working_set.get_span_contents(pipeline.commands[0].parts[1]);
|
working_set.get_span_contents(pipeline.commands[0].parts[1]);
|
||||||
|
|
||||||
|
let decl_id = working_set
|
||||||
|
.find_decl(decl_name)
|
||||||
|
.expect("internal error: failed to find added declaration");
|
||||||
|
|
||||||
// TODO: Later, we want to put this behind 'export'
|
// TODO: Later, we want to put this behind 'export'
|
||||||
exports.push(def_name.into());
|
exports.push((decl_name.into(), decl_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
(stmt, err)
|
(stmt, err)
|
||||||
@ -2825,8 +2833,10 @@ pub fn parse_use(
|
|||||||
|
|
||||||
let module_name_bytes = module_name.as_bytes().to_vec();
|
let module_name_bytes = module_name.as_bytes().to_vec();
|
||||||
|
|
||||||
let block = if let Some(block_id) = working_set.find_module(&module_name_bytes) {
|
let exports = if let Some(block_id) = working_set.find_module(&module_name_bytes) {
|
||||||
working_set.get_block(block_id)
|
// TODO: Since we don't use the Block at all, we might just as well create a separate
|
||||||
|
// Module that holds only the exports, without having Blocks in the way.
|
||||||
|
working_set.get_block(block_id).exports.clone()
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
garbage_statement(spans),
|
garbage_statement(spans),
|
||||||
@ -2834,6 +2844,10 @@ pub fn parse_use(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Extend the current scope with the module's exports
|
||||||
|
working_set.activate_overlay(exports);
|
||||||
|
|
||||||
|
// Create the Use command call
|
||||||
let use_decl_id = working_set
|
let use_decl_id = working_set
|
||||||
.find_decl(b"use")
|
.find_decl(b"use")
|
||||||
.expect("internal error: missing use command");
|
.expect("internal error: missing use command");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
use crate::Signature;
|
use crate::{Signature, DeclId};
|
||||||
|
|
||||||
use super::Statement;
|
use super::Statement;
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ use super::Statement;
|
|||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub signature: Box<Signature>,
|
pub signature: Box<Signature>,
|
||||||
pub stmts: Vec<Statement>,
|
pub stmts: Vec<Statement>,
|
||||||
pub exports: Vec<Vec<u8>>, // Assuming just defs for now
|
pub exports: Vec<(Vec<u8>, DeclId)>, // Assuming just defs for now
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
@ -50,7 +50,7 @@ impl Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_exports(self, exports: Vec<Vec<u8>>) -> Self {
|
pub fn with_exports(self, exports: Vec<(Vec<u8>, DeclId)>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
signature: self.signature,
|
signature: self.signature,
|
||||||
stmts: self.stmts,
|
stmts: self.stmts,
|
||||||
|
@ -312,6 +312,20 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
block_id
|
block_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn activate_overlay(&mut self, overlay: Vec<(Vec<u8>, DeclId)>) {
|
||||||
|
// TODO: This will overwrite all existing definitions in a scope. When we add deactivate,
|
||||||
|
// we need to re-think how make it recoverable.
|
||||||
|
let scope_frame = self
|
||||||
|
.delta
|
||||||
|
.scope
|
||||||
|
.last_mut()
|
||||||
|
.expect("internal error: missing required scope frame");
|
||||||
|
|
||||||
|
for (name, decl_id) in overlay {
|
||||||
|
scope_frame.decls.insert(name, decl_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn next_span_start(&self) -> usize {
|
pub fn next_span_start(&self) -> usize {
|
||||||
self.permanent_state.next_span_start() + self.delta.file_contents.len()
|
self.permanent_state.next_span_start() + self.delta.file_contents.len()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user