mirror of
https://github.com/nushell/nushell.git
synced 2024-12-23 07:30:13 +01:00
Fix condition parsing for if
This commit is contained in:
parent
2f91aca897
commit
5dd5a89775
@ -555,6 +555,69 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn first_kw_idx(
|
||||
&self,
|
||||
decl: &Declaration,
|
||||
spans: &[Span],
|
||||
spans_idx: usize,
|
||||
positional_idx: usize,
|
||||
) -> (Option<usize>, usize) {
|
||||
for idx in (positional_idx + 1)..decl.signature.num_positionals() {
|
||||
if let Some(PositionalArg {
|
||||
shape: SyntaxShape::Keyword(kw, ..),
|
||||
..
|
||||
}) = decl.signature.get_positional(idx)
|
||||
{
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for span_idx in spans_idx..spans.len() {
|
||||
let contents = self.get_span_contents(spans[span_idx]);
|
||||
|
||||
if contents == kw {
|
||||
return (Some(idx), span_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, spans.len())
|
||||
}
|
||||
|
||||
fn calculate_end_span(
|
||||
&self,
|
||||
decl: &Declaration,
|
||||
spans: &[Span],
|
||||
spans_idx: usize,
|
||||
positional_idx: usize,
|
||||
) -> usize {
|
||||
if decl.signature.rest_positional.is_some() {
|
||||
spans.len()
|
||||
} else {
|
||||
let (kw_pos, kw_idx) = self.first_kw_idx(decl, spans, spans_idx, positional_idx);
|
||||
|
||||
if let Some(kw_pos) = kw_pos {
|
||||
// We found a keyword. Keywords, once found, create a guidepost to
|
||||
// show us where the positionals will lay into the arguments. Because they're
|
||||
// keywords, they get to set this by being present
|
||||
|
||||
let positionals_between = kw_pos - positional_idx - 1;
|
||||
if positionals_between > (kw_idx - spans_idx) {
|
||||
kw_idx
|
||||
} else {
|
||||
kw_idx - positionals_between
|
||||
}
|
||||
} else {
|
||||
// Make space for the remaining require positionals, if we can
|
||||
if positional_idx < decl.signature.required_positional.len()
|
||||
&& spans.len() > (decl.signature.required_positional.len() - positional_idx - 1)
|
||||
{
|
||||
spans.len() - (decl.signature.required_positional.len() - positional_idx - 1)
|
||||
} else {
|
||||
spans.len()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn calculate_end_span(
|
||||
&self,
|
||||
decl: &Declaration,
|
||||
@ -604,20 +667,22 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
.copied()
|
||||
.expect("internal error: can't find min");
|
||||
|
||||
// println!(
|
||||
// "{:?}",
|
||||
// [
|
||||
// next_keyword_idx,
|
||||
// remainder_idx,
|
||||
// spans.len(),
|
||||
// spans_idx,
|
||||
// remainder,
|
||||
// positional_idx,
|
||||
// ]
|
||||
// );
|
||||
println!(
|
||||
"{:?}",
|
||||
[
|
||||
next_keyword_idx,
|
||||
remainder_idx,
|
||||
spans.len(),
|
||||
spans_idx,
|
||||
remainder,
|
||||
positional_idx,
|
||||
end,
|
||||
]
|
||||
);
|
||||
end
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
fn parse_multispan_value(
|
||||
&mut self,
|
||||
|
@ -248,22 +248,22 @@ impl Signature {
|
||||
}
|
||||
curr += 1;
|
||||
}
|
||||
for positional in &self.optional_positional {
|
||||
match positional.shape {
|
||||
SyntaxShape::Keyword(..) => {
|
||||
// Keywords have a required argument, so account for that
|
||||
if curr > idx {
|
||||
total += 2;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if curr > idx {
|
||||
total += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
curr += 1;
|
||||
}
|
||||
// for positional in &self.optional_positional {
|
||||
// match positional.shape {
|
||||
// SyntaxShape::Keyword(..) => {
|
||||
// // Keywords have a required argument, so account for that
|
||||
// if curr > idx {
|
||||
// total += 2;
|
||||
// }
|
||||
// }
|
||||
// _ => {
|
||||
// if curr > idx {
|
||||
// total += 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// curr += 1;
|
||||
// }
|
||||
total
|
||||
}
|
||||
|
||||
|
30
src/tests.rs
30
src/tests.rs
@ -79,6 +79,36 @@ fn if_test2() -> TestResult {
|
||||
run_test("if $false { 10 } else { 20 } ", "20")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_if() -> TestResult {
|
||||
run_test("if $true { 10 } ", "10")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_if2() -> TestResult {
|
||||
run_test("if $false { 10 } ", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_cond() -> TestResult {
|
||||
run_test("if 2 < 3 { 3 } ", "3")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_cond2() -> TestResult {
|
||||
run_test("if 2 > 3 { 3 } ", "")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_cond3() -> TestResult {
|
||||
run_test("if 2 < 3 { 5 } else { 4 } ", "5")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_cond4() -> TestResult {
|
||||
run_test("if 2 > 3 { 5 } else { 4 } ", "4")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_scope_leak1() -> TestResult {
|
||||
fail_test(
|
||||
|
Loading…
Reference in New Issue
Block a user