mirror of
https://github.com/nushell/nushell
synced 2024-12-28 14:03:09 +00:00
Fix comment issue and shadowing issue (#501)
This commit is contained in:
parent
aea2adc44a
commit
1d74d9c5ae
5 changed files with 80 additions and 29 deletions
|
@ -276,25 +276,18 @@ pub fn lex(
|
||||||
let mut start = curr_offset;
|
let mut start = curr_offset;
|
||||||
|
|
||||||
while let Some(input) = input.get(curr_offset) {
|
while let Some(input) = input.get(curr_offset) {
|
||||||
curr_offset += 1;
|
|
||||||
if *input == b'\n' || *input == b'\r' {
|
if *input == b'\n' || *input == b'\r' {
|
||||||
if !skip_comment {
|
if !skip_comment {
|
||||||
output.push(Token::new(
|
output.push(Token::new(
|
||||||
TokenContents::Comment,
|
TokenContents::Comment,
|
||||||
Span::new(start, curr_offset - 1),
|
Span::new(start, curr_offset),
|
||||||
));
|
|
||||||
|
|
||||||
// Adding an end of line token after a comment
|
|
||||||
// This helps during lite_parser to avoid losing a command
|
|
||||||
// in a statement
|
|
||||||
output.push(Token::new(
|
|
||||||
TokenContents::Eol,
|
|
||||||
Span::new(curr_offset - 1, curr_offset),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
start = curr_offset;
|
start = curr_offset;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
curr_offset += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if start != curr_offset && !skip_comment {
|
if start != curr_offset && !skip_comment {
|
||||||
|
|
|
@ -13,7 +13,8 @@ use crate::{
|
||||||
lex, lite_parse,
|
lex, lite_parse,
|
||||||
parser::{
|
parser::{
|
||||||
check_call, check_name, garbage, garbage_statement, parse, parse_block_expression,
|
check_call, check_name, garbage, garbage_statement, parse, parse_block_expression,
|
||||||
parse_import_pattern, parse_internal_call, parse_signature, parse_string, trim_quotes,
|
parse_import_pattern, parse_internal_call, parse_multispan_value, parse_signature,
|
||||||
|
parse_string, parse_var_with_opt_type, trim_quotes,
|
||||||
},
|
},
|
||||||
ParseError,
|
ParseError,
|
||||||
};
|
};
|
||||||
|
@ -956,28 +957,68 @@ pub fn parse_let(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(decl_id) = working_set.find_decl(b"let") {
|
if let Some(decl_id) = working_set.find_decl(b"let") {
|
||||||
let (call, call_span, err) =
|
if spans.len() >= 4 {
|
||||||
parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
// This is a bit of by-hand parsing to get around the issue where we want to parse in the reverse order
|
||||||
|
// so that the var-id created by the variable isn't visible in the expression that init it
|
||||||
|
for span in spans.iter().enumerate() {
|
||||||
|
let item = working_set.get_span_contents(*span.1);
|
||||||
|
if item == b"=" && spans.len() > (span.0 + 1) {
|
||||||
|
let mut error = None;
|
||||||
|
|
||||||
// Update the variable to the known type if we can.
|
let mut idx = span.0;
|
||||||
if err.is_none() {
|
let (rvalue, err) = parse_multispan_value(
|
||||||
let var_id = call.positional[0]
|
working_set,
|
||||||
.as_var()
|
spans,
|
||||||
.expect("internal error: expected variable");
|
&mut idx,
|
||||||
let rhs_type = call.positional[1].ty.clone();
|
&SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),
|
||||||
|
);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
if var_id != CONFIG_VARIABLE_ID {
|
let mut idx = 0;
|
||||||
working_set.set_variable_type(var_id, rhs_type);
|
let (lvalue, err) =
|
||||||
|
parse_var_with_opt_type(working_set, &spans[1..(span.0)], &mut idx);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
let var_id = lvalue.as_var();
|
||||||
|
|
||||||
|
let rhs_type = rvalue.ty.clone();
|
||||||
|
|
||||||
|
if let Some(var_id) = var_id {
|
||||||
|
if var_id != CONFIG_VARIABLE_ID {
|
||||||
|
working_set.set_variable_type(var_id, rhs_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let call = Box::new(Call {
|
||||||
|
decl_id,
|
||||||
|
head: spans[0],
|
||||||
|
positional: vec![lvalue, rvalue],
|
||||||
|
named: vec![],
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Call(call),
|
||||||
|
span: nu_protocol::span(spans),
|
||||||
|
ty: Type::Unknown,
|
||||||
|
custom_completion: None,
|
||||||
|
}])),
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let (call, _, err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
Statement::Pipeline(Pipeline {
|
||||||
expr: Expr::Call(call),
|
expressions: vec![Expression {
|
||||||
span: call_span,
|
expr: Expr::Call(call),
|
||||||
ty: Type::Unknown,
|
span: nu_protocol::span(spans),
|
||||||
custom_completion: None,
|
ty: Type::Unknown,
|
||||||
}])),
|
custom_completion: None,
|
||||||
|
}],
|
||||||
|
}),
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,7 +388,7 @@ fn calculate_end_span(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_multispan_value(
|
pub fn parse_multispan_value(
|
||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
spans_idx: &mut usize,
|
spans_idx: &mut usize,
|
||||||
|
|
|
@ -91,7 +91,7 @@ pub enum ShellError {
|
||||||
#[diagnostic(code(nu::shell::nushell_failed), url(docsrs))]
|
#[diagnostic(code(nu::shell::nushell_failed), url(docsrs))]
|
||||||
NushellFailed(String),
|
NushellFailed(String),
|
||||||
|
|
||||||
#[error("Variable not found!!!")]
|
#[error("Variable not found")]
|
||||||
#[diagnostic(code(nu::shell::variable_not_found), url(docsrs))]
|
#[diagnostic(code(nu::shell::variable_not_found), url(docsrs))]
|
||||||
VariableNotFoundAtRuntime(#[label = "variable not found"] Span),
|
VariableNotFoundAtRuntime(#[label = "variable not found"] Span),
|
||||||
|
|
||||||
|
|
17
src/tests.rs
17
src/tests.rs
|
@ -1249,3 +1249,20 @@ fn command_drop_column_1() -> TestResult {
|
||||||
fn chained_operator_typecheck() -> TestResult {
|
fn chained_operator_typecheck() -> TestResult {
|
||||||
run_test("1 != 2 && 3 != 4 && 5 != 6", "true")
|
run_test("1 != 2 && 3 != 4 && 5 != 6", "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn proper_shadow() -> TestResult {
|
||||||
|
run_test("let x = 10; let x = $x + 9; $x", "19")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn comment_multiline() -> TestResult {
|
||||||
|
run_test(
|
||||||
|
r#"def foo [] {
|
||||||
|
let x = 1 + 2 # comment
|
||||||
|
let y = 3 + 4 # another comment
|
||||||
|
$x + $y
|
||||||
|
}; foo"#,
|
||||||
|
"10",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue