Fix string interpolation paren cases (#4410)

This commit is contained in:
JT 2022-02-10 11:09:08 -05:00 committed by GitHub
parent 5cf91cb30d
commit 2e3b2a48ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 10 deletions

View File

@ -1260,14 +1260,13 @@ pub fn parse_string_interpolation(
let mut output = vec![];
let mut mode = InterpolationMode::String;
let mut token_start = start;
let mut depth = 0;
let mut delimiter_stack = vec![];
let mut b = start;
#[allow(clippy::needless_range_loop)]
while b != end {
if contents[b - start] == b'(' && mode == InterpolationMode::String {
depth = 1;
mode = InterpolationMode::Expression;
if token_start < b {
let span = Span {
@ -1281,14 +1280,30 @@ pub fn parse_string_interpolation(
ty: Type::String,
custom_completion: None,
});
token_start = b;
}
token_start = b;
} else if contents[b - start] == b'(' && mode == InterpolationMode::Expression {
depth += 1;
} else if contents[b - start] == b')' && mode == InterpolationMode::Expression {
match depth {
0 => {}
1 => {
}
if mode == InterpolationMode::Expression {
let byte = contents[b - start];
if let Some(b'\'') = delimiter_stack.last() {
if byte == b'\'' {
delimiter_stack.pop();
}
} else if let Some(b'"') = delimiter_stack.last() {
if byte == b'"' {
delimiter_stack.pop();
}
} else if byte == b'\'' {
delimiter_stack.push(b'\'')
} else if byte == b'"' {
delimiter_stack.push(b'"');
} else if byte == b'(' {
delimiter_stack.push(b')');
} else if byte == b')' {
if let Some(b')') = delimiter_stack.last() {
delimiter_stack.pop();
}
if delimiter_stack.is_empty() {
mode = InterpolationMode::String;
if token_start < b {
@ -1303,8 +1318,8 @@ pub fn parse_string_interpolation(
}
token_start = b + 1;
continue;
}
_ => depth -= 1,
}
}
b += 1;

View File

@ -197,3 +197,18 @@ fn let_env_expressions() -> TestResult {
"done",
)
}
#[test]
fn string_interpolation_paren_test() -> TestResult {
run_test(r#"$"('(')(')')""#, "()")
}
#[test]
fn string_interpolation_paren_test2() -> TestResult {
run_test(r#"$"('(')test(')')""#, "(test)")
}
#[test]
fn string_interpolation_paren_test3() -> TestResult {
run_test(r#"$"('(')("test")test(')')""#, "(testtest)")
}