mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
fix(cli/repl): unterminated string literal should invalidate (#7896)
This adds the grave character to the pair matching so that template string literals trigger multi-line edits.
This commit is contained in:
parent
e432db70e9
commit
35028db5e5
2 changed files with 70 additions and 4 deletions
40
cli/repl.rs
40
cli/repl.rs
|
@ -12,7 +12,6 @@ use regex::Captures;
|
|||
use regex::Regex;
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::highlight::Highlighter;
|
||||
use rustyline::validate::MatchingBracketValidator;
|
||||
use rustyline::validate::ValidationContext;
|
||||
use rustyline::validate::ValidationResult;
|
||||
use rustyline::validate::Validator;
|
||||
|
@ -26,7 +25,6 @@ use std::sync::Mutex;
|
|||
#[derive(Completer, Helper, Hinter)]
|
||||
struct Helper {
|
||||
highlighter: LineHighlighter,
|
||||
validator: MatchingBracketValidator,
|
||||
}
|
||||
|
||||
impl Validator for Helper {
|
||||
|
@ -34,7 +32,42 @@ impl Validator for Helper {
|
|||
&self,
|
||||
ctx: &mut ValidationContext,
|
||||
) -> Result<ValidationResult, ReadlineError> {
|
||||
self.validator.validate(ctx)
|
||||
let mut stack: Vec<char> = Vec::new();
|
||||
for c in ctx.input().chars() {
|
||||
match c {
|
||||
'(' | '[' | '{' => stack.push(c),
|
||||
')' | ']' | '}' => match (stack.pop(), c) {
|
||||
(Some('('), ')') | (Some('['), ']') | (Some('{'), '}') => {}
|
||||
(Some(left), _) => {
|
||||
return Ok(ValidationResult::Invalid(Some(format!(
|
||||
"Mismatched pairs: {:?} is not properly closed",
|
||||
left
|
||||
))))
|
||||
}
|
||||
(None, c) => {
|
||||
return Ok(ValidationResult::Invalid(Some(format!(
|
||||
"Mismatched pairs: {:?} is unpaired",
|
||||
c
|
||||
))))
|
||||
}
|
||||
},
|
||||
'`' => {
|
||||
if stack.is_empty() || stack.last().unwrap() != &c {
|
||||
stack.push(c);
|
||||
} else {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if !stack.is_empty() {
|
||||
return Ok(ValidationResult::Incomplete);
|
||||
}
|
||||
|
||||
Ok(ValidationResult::Valid(None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,7 +307,6 @@ pub async fn run(
|
|||
|
||||
let helper = Helper {
|
||||
highlighter: LineHighlighter::new(),
|
||||
validator: MatchingBracketValidator::new(),
|
||||
};
|
||||
|
||||
let editor = Arc::new(Mutex::new(Editor::new()));
|
||||
|
|
|
@ -1127,6 +1127,40 @@ fn run_watch() {
|
|||
drop(t);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn repl_test_pty_multiline() {
|
||||
use std::io::Read;
|
||||
use util::pty::fork::*;
|
||||
|
||||
let tests_path = util::tests_path();
|
||||
let fork = Fork::from_ptmx().unwrap();
|
||||
if let Ok(mut master) = fork.is_parent() {
|
||||
master.write_all(b"(\n1 + 2\n)\n").unwrap();
|
||||
master.write_all(b"{\nfoo: \"foo\"\n}\n").unwrap();
|
||||
master.write_all(b"`\nfoo\n`\n").unwrap();
|
||||
master.write_all(b"close();\n").unwrap();
|
||||
|
||||
let mut output = String::new();
|
||||
master.read_to_string(&mut output).unwrap();
|
||||
|
||||
assert!(output.contains('3'));
|
||||
assert!(output.contains("{ foo: \"foo\" }"));
|
||||
assert!(output.contains("\"\\nfoo\\n\""));
|
||||
|
||||
fork.wait().unwrap();
|
||||
} else {
|
||||
util::deno_cmd()
|
||||
.current_dir(tests_path)
|
||||
.env("NO_COLOR", "1")
|
||||
.arg("repl")
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn repl_test_console_log() {
|
||||
let (out, err) = util::run_and_collect_output(
|
||||
|
|
Loading…
Add table
Reference in a new issue