| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -292,7 +292,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { | |||
| 292 | 292 | function getInputPreview(input, callback) { | |
| 293 | 293 | // For similar reasons as `defaultEval`, wrap expressions starting with a | |
| 294 | 294 | // curly brace with parenthesis. | |
| 295 | - if (!wrapped && input[0] === '{' && input[input.length - 1] !== ';') { | ||
| 295 | + if (!wrapped && input[0] === '{' && input[input.length - 1] !== ';' && isValidSyntax(input)) { | ||
| 296 | 296 | input = `(${input})`; | |
| 297 | 297 | wrapped = true; | |
| 298 | 298 | } | |
@@ -737,6 +737,25 @@ function setupReverseSearch(repl) { | |||
| 737 | 737 | ||
| 738 | 738 | const startsWithBraceRegExp = /^\s*{/; | |
| 739 | 739 | const endsWithSemicolonRegExp = /;\s*$/; | |
| 740 | + function isValidSyntax(input) { | ||
| 741 | + try { | ||
| 742 | + AcornParser.parse(input, { | ||
| 743 | + ecmaVersion: 'latest', | ||
| 744 | + allowAwaitOutsideFunction: true, | ||
| 745 | + }); | ||
| 746 | + return true; | ||
| 747 | + } catch { | ||
| 748 | + try { | ||
| 749 | + AcornParser.parse(`_=${input}`, { | ||
| 750 | + ecmaVersion: 'latest', | ||
| 751 | + allowAwaitOutsideFunction: true, | ||
| 752 | + }); | ||
| 753 | + return true; | ||
| 754 | + } catch { | ||
| 755 | + return false; | ||
| 756 | + } | ||
| 757 | + } | ||
| 758 | + } | ||
| 740 | 759 | ||
| 741 | 760 | /** | |
| 742 | 761 | * Checks if some provided code represents an object literal. | |
@@ -759,4 +778,5 @@ module.exports = { | |||
| 759 | 778 | setupPreview, | |
| 760 | 779 | setupReverseSearch, | |
| 761 | 780 | isObjectLiteral, | |
| 781 | + isValidSyntax, | ||
| 762 | 782 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -172,6 +172,7 @@ const { | |||
| 172 | 172 | setupPreview, | |
| 173 | 173 | setupReverseSearch, | |
| 174 | 174 | isObjectLiteral, | |
| 175 | + isValidSyntax, | ||
| 175 | 176 | } = require('internal/repl/utils'); | |
| 176 | 177 | const { | |
| 177 | 178 | constants: { | |
@@ -440,7 +441,7 @@ function REPLServer(prompt, | |||
| 440 | 441 | let awaitPromise = false; | |
| 441 | 442 | const input = code; | |
| 442 | 443 | ||
| 443 | - if (isObjectLiteral(code)) { | ||
| 444 | + if (isObjectLiteral(code) && isValidSyntax(code)) { | ||
| 444 | 445 | // Add parentheses to make sure `code` is parsed as an expression | |
| 445 | 446 | code = `(${StringPrototypeTrim(code)})\n`; | |
| 446 | 447 | wrappedCmd = true; | |
@@ -1859,6 +1860,7 @@ module.exports = { | |||
| 1859 | 1860 | REPL_MODE_SLOPPY, | |
| 1860 | 1861 | REPL_MODE_STRICT, | |
| 1861 | 1862 | Recoverable, | |
| 1863 | + isValidSyntax, | ||
| 1862 | 1864 | }; | |
| 1863 | 1865 | ||
| 1864 | 1866 | ObjectDefineProperty(module.exports, 'builtinModules', { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -157,6 +157,83 @@ async function tests(options) { | |||
| 157 | 157 | '\x1B[90m1\x1B[39m\x1B[12G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r', | |
| 158 | 158 | '\x1B[33m1\x1B[39m', | |
| 159 | 159 | ] | |
| 160 | + }, { | ||
| 161 | + input: 'aaaa', | ||
| 162 | + noPreview: 'Uncaught ReferenceError: aaaa is not defined', | ||
| 163 | + preview: [ | ||
| 164 | + 'aaaa\r', | ||
| 165 | + 'Uncaught ReferenceError: aaaa is not defined', | ||
| 166 | + ] | ||
| 167 | + }, { | ||
| 168 | + input: '/0', | ||
| 169 | + noPreview: '/0', | ||
| 170 | + preview: [ | ||
| 171 | + '/0\r', | ||
| 172 | + '/0', | ||
| 173 | + '^', | ||
| 174 | + '', | ||
| 175 | + 'Uncaught SyntaxError: Invalid regular expression: missing /', | ||
| 176 | + ] | ||
| 177 | + }, { | ||
| 178 | + input: '{})', | ||
| 179 | + noPreview: '{})', | ||
| 180 | + preview: [ | ||
| 181 | + '{})\r', | ||
| 182 | + '{})', | ||
| 183 | + ' ^', | ||
| 184 | + '', | ||
| 185 | + "Uncaught SyntaxError: Unexpected token ')'", | ||
| 186 | + ], | ||
| 187 | + }, { | ||
| 188 | + input: "{ a: '{' }", | ||
| 189 | + noPreview: "{ a: \x1B[32m'{'\x1B[39m }", | ||
| 190 | + preview: [ | ||
| 191 | + "{ a: '{' }\r", | ||
| 192 | + "{ a: \x1B[32m'{'\x1B[39m }", | ||
| 193 | + ], | ||
| 194 | + }, { | ||
| 195 | + input: "{'{':0}", | ||
| 196 | + noPreview: "{ \x1B[32m'{'\x1B[39m: \x1B[33m0\x1B[39m }", | ||
| 197 | + preview: [ | ||
| 198 | + "{'{':0}", | ||
| 199 | + "\x1B[90m{ '{': 0 }\x1B[39m\x1B[15G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r", | ||
| 200 | + "{ \x1B[32m'{'\x1B[39m: \x1B[33m0\x1B[39m }", | ||
| 201 | + ], | ||
| 202 | + }, { | ||
| 203 | + input: '{[Symbol.for("{")]: 0 }', | ||
| 204 | + noPreview: '{ [\x1B[32mSymbol({)\x1B[39m]: \x1B[33m0\x1B[39m }', | ||
| 205 | + preview: [ | ||
| 206 | + '{[Symbol.for("{")]: 0 }\r', | ||
| 207 | + '{ [\x1B[32mSymbol({)\x1B[39m]: \x1B[33m0\x1B[39m }', | ||
| 208 | + ], | ||
| 209 | + }, { | ||
| 210 | + input: '{},{}', | ||
| 211 | + noPreview: '{}', | ||
| 212 | + preview: [ | ||
| 213 | + '{},{}', | ||
| 214 | + '\x1B[90m{}\x1B[39m\x1B[13G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r', | ||
| 215 | + '{}', | ||
| 216 | + ], | ||
| 217 | + }, { | ||
| 218 | + input: '{} //', | ||
| 219 | + noPreview: 'repl > ', | ||
| 220 | + preview: [ | ||
| 221 | + '{} //\r', | ||
| 222 | + ], | ||
| 223 | + }, { | ||
| 224 | + input: '{} //;', | ||
| 225 | + noPreview: 'repl > ', | ||
| 226 | + preview: [ | ||
| 227 | + '{} //;\r', | ||
| 228 | + ], | ||
| 229 | + }, { | ||
| 230 | + input: '{throw 0}', | ||
| 231 | + noPreview: 'Uncaught \x1B[33m0\x1B[39m', | ||
| 232 | + preview: [ | ||
| 233 | + '{throw 0}', | ||
| 234 | + '\x1B[90m0\x1B[39m\x1B[17G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r', | ||
| 235 | + 'Uncaught \x1B[33m0\x1B[39m', | ||
| 236 | + ], | ||
| 160 | 237 | }]; | |
| 161 | 238 | ||
| 162 | 239 | const hasPreview = repl.terminal && | |
@@ -177,8 +254,13 @@ async function tests(options) { | |||
| 177 | 254 | assert.deepStrictEqual(lines, preview); | |
| 178 | 255 | } else { | |
| 179 | 256 | assert.ok(lines[0].includes(noPreview), lines.map(inspect)); | |
| 180 | - if (preview.length !== 1 || preview[0] !== `${input}\r`) | ||
| 181 | - assert.strictEqual(lines.length, 2); | ||
| 257 | + if (preview.length !== 1 || preview[0] !== `${input}\r`) { | ||
| 258 | + if (preview[preview.length - 1].includes('Uncaught SyntaxError')) { | ||
| 259 | + assert.strictEqual(lines.length, 5); | ||
| 260 | + } else { | ||
| 261 | + assert.strictEqual(lines.length, 2); | ||
| 262 | + } | ||
| 263 | + } | ||
| 182 | 264 | } | |
| 183 | 265 | } | |
| 184 | 266 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -328,6 +328,19 @@ const errorTests = [ | |||
| 328 | 328 | expect: '[Function (anonymous)]' | |
| 329 | 329 | }, | |
| 330 | 330 | // Multiline object | |
| 331 | + { | ||
| 332 | + send: '{}),({}', | ||
| 333 | + expect: '... ', | ||
| 334 | + }, | ||
| 335 | + { | ||
| 336 | + send: '}', | ||
| 337 | + expect: [ | ||
| 338 | + '{}),({}', | ||
| 339 | + kArrow, | ||
| 340 | + '', | ||
| 341 | + /^Uncaught SyntaxError: /, | ||
| 342 | + ] | ||
| 343 | + }, | ||
| 331 | 344 | { | |
| 332 | 345 | send: '{ a: ', | |
| 333 | 346 | expect: '... ' | |
| Back | FazBrowse Home | New Git URL |
0 commit comments