mirror of
https://github.com/nushell/nushell.git
synced 2025-08-13 22:48:25 +02:00
fix(parser): external argument with subexpressions (#16346)
Fixes: #16040 # Description TBH, I not a fan of this whole `parse_external_string` idea. Maybe I lack some of the background knowledge here, but I don't see why we choose not to 1. parse external arguments the same way as internal ones 2. treat them literally at runtime if necessary Tests: +1
This commit is contained in:
@ -264,6 +264,10 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
|
||||
quote_char: u8,
|
||||
escaped: bool,
|
||||
},
|
||||
Parenthesized {
|
||||
from: usize,
|
||||
depth: usize,
|
||||
},
|
||||
}
|
||||
// Find the spans of parts of the string that can be parsed as their own strings for
|
||||
// concatenation.
|
||||
@ -315,6 +319,15 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
|
||||
}
|
||||
state = State::BackTickQuote { from: index }
|
||||
}
|
||||
b'(' => {
|
||||
if index != *from {
|
||||
spans.push(make_span(*from, index))
|
||||
}
|
||||
state = State::Parenthesized {
|
||||
from: index,
|
||||
depth: 1,
|
||||
}
|
||||
}
|
||||
// Continue to consume
|
||||
_ => (),
|
||||
},
|
||||
@ -343,6 +356,18 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
|
||||
state = State::Bare { from: index + 1 };
|
||||
}
|
||||
}
|
||||
State::Parenthesized { from, depth } => {
|
||||
if ch == b')' {
|
||||
if *depth == 1 {
|
||||
spans.push(make_span(*from, index + 1));
|
||||
state = State::Bare { from: index + 1 };
|
||||
} else {
|
||||
*depth -= 1;
|
||||
}
|
||||
} else if ch == b'(' {
|
||||
*depth += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
@ -351,6 +376,7 @@ fn parse_external_string(working_set: &mut StateWorkingSet, span: Span) -> Expre
|
||||
match state {
|
||||
State::Bare { from }
|
||||
| State::Quote { from, .. }
|
||||
| State::Parenthesized { from, .. }
|
||||
| State::BackTickQuote { from, .. } => {
|
||||
if from < contents.len() {
|
||||
spans.push(make_span(from, contents.len()));
|
||||
|
@ -1027,3 +1027,12 @@ fn not_panic_with_recursive_call() {
|
||||
);
|
||||
assert!(result.status.success());
|
||||
}
|
||||
|
||||
// https://github.com/nushell/nushell/issues/16040
|
||||
#[test]
|
||||
fn external_argument_with_subexpressions() -> TestResult {
|
||||
run_test(r#"^echo foo( ('bar') | $in ++ 'baz' )"#, "foobarbaz")?;
|
||||
run_test(r#"^echo foo( 'bar' )('baz')"#, "foobarbaz")?;
|
||||
run_test(r#"^echo ")('foo')(""#, ")('foo')(")?;
|
||||
fail_test(r#"^echo foo( 'bar'"#, "Unexpected end of code")
|
||||
}
|
||||
|
Reference in New Issue
Block a user