From 9d664f8375856be228e4f98b8381ac934d84604b Mon Sep 17 00:00:00 2001 From: Casper Beyer Date: Tue, 20 Oct 2020 01:13:23 +0800 Subject: [PATCH] fix(cli/repl): ignore pair matching inside literals (#8037) --- cli/repl.rs | 36 +++++++++++++++++++++++++--------- cli/tests/integration_tests.rs | 16 +++++++++++++++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/cli/repl.rs b/cli/repl.rs index 3d22f8156e..9d700f76d7 100644 --- a/cli/repl.rs +++ b/cli/repl.rs @@ -33,7 +33,33 @@ impl Validator for Helper { ctx: &mut ValidationContext, ) -> Result { let mut stack: Vec = Vec::new(); + let mut literal: Option = None; + let mut escape: bool = false; + for c in ctx.input().chars() { + if escape { + escape = false; + continue; + } + + if c == '\\' { + escape = true; + continue; + } + + if let Some(v) = literal { + if c == v { + literal = None + } + + continue; + } else { + literal = match c { + '`' | '"' | '/' | '\'' => Some(c), + _ => None, + }; + } + match c { '(' | '[' | '{' => stack.push(c), ')' | ']' | '}' => match (stack.pop(), c) { @@ -51,19 +77,11 @@ impl Validator for Helper { )))) } }, - '`' => { - if stack.is_empty() || stack.last().unwrap() != &c { - stack.push(c); - } else { - stack.pop(); - } - } - _ => {} } } - if !stack.is_empty() { + if !stack.is_empty() || literal == Some('`') { return Ok(ValidationResult::Incomplete); } diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index fdf2425cd6..bbb783e0b8 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -1139,6 +1139,14 @@ fn repl_test_pty_multiline() { 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"`\n\\`\n`\n").unwrap(); + master.write_all(b"'{'\n").unwrap(); + master.write_all(b"'('\n").unwrap(); + master.write_all(b"'['\n").unwrap(); + master.write_all(b"/{/'\n").unwrap(); + master.write_all(b"/(/'\n").unwrap(); + master.write_all(b"/[/'\n").unwrap(); + master.write_all(b"console.log(\"{test1} abc {test2} def {{test3}}\".match(/{([^{].+?)}/));\n").unwrap(); master.write_all(b"close();\n").unwrap(); let mut output = String::new(); @@ -1147,6 +1155,14 @@ fn repl_test_pty_multiline() { assert!(output.contains('3')); assert!(output.contains("{ foo: \"foo\" }")); assert!(output.contains("\"\\nfoo\\n\"")); + assert!(output.contains("\"\\n`\\n\"")); + assert!(output.contains("\"{\"")); + assert!(output.contains("\"(\"")); + assert!(output.contains("\"[\"")); + assert!(output.contains("/{/")); + assert!(output.contains("/(/")); + assert!(output.contains("/{/")); + assert!(output.contains("[ \"{test1}\", \"test1\" ]")); fork.wait().unwrap(); } else {