| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1a9771a commit d33dcf1
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -48,6 +48,8 @@ const previewOptions = { | |||
| 48 | 48 | showHidden: false | |
| 49 | 49 | }; | |
| 50 | 50 | ||
| 51 | + const REPL_MODE_STRICT = Symbol('repl-strict'); | ||
| 52 | + | ||
| 51 | 53 | // If the error is that we've unexpectedly ended the input, | |
| 52 | 54 | // then let the user try to recover by adding more input. | |
| 53 | 55 | // Note: `e` (the original exception) is not used by the current implementation, | |
@@ -136,6 +138,8 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { | |||
| 136 | 138 | let previewCompletionCounter = 0; | |
| 137 | 139 | let completionPreview = null; | |
| 138 | 140 | ||
| 141 | + let hasCompletions = false; | ||
| 142 | + | ||
| 139 | 143 | let wrapped = false; | |
| 140 | 144 | ||
| 141 | 145 | let escaped = null; | |
@@ -229,6 +233,8 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { | |||
| 229 | 233 | return; | |
| 230 | 234 | } | |
| 231 | 235 | ||
| 236 | + hasCompletions = true; | ||
| 237 | + | ||
| 232 | 238 | // If there is a common prefix to all matches, then apply that portion. | |
| 233 | 239 | const completions = rawCompletions.filter((e) => e); | |
| 234 | 240 | const prefix = commonPrefix(completions); | |
@@ -265,6 +271,12 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { | |||
| 265 | 271 | }); | |
| 266 | 272 | } | |
| 267 | 273 | ||
| 274 | + function isInStrictMode(repl) { | ||
| 275 | + return repl.replMode === REPL_MODE_STRICT || process.execArgv | ||
| 276 | + .map((e) => e.toLowerCase().replace(/_/g, '-')) | ||
| 277 | + .includes('--use-strict'); | ||
| 278 | + } | ||
| 279 | + | ||
| 268 | 280 | // This returns a code preview for arbitrary input code. | |
| 269 | 281 | function getInputPreview(input, callback) { | |
| 270 | 282 | // For similar reasons as `defaultEval`, wrap expressions starting with a | |
@@ -292,8 +304,11 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { | |||
| 292 | 304 | // may be inspected. | |
| 293 | 305 | } else if (preview.exceptionDetails && | |
| 294 | 306 | (result.className === 'EvalError' || | |
| 295 | - result.className === 'SyntaxError' || | ||
| 296 | - result.className === 'ReferenceError')) { | ||
| 307 | + result.className === 'SyntaxError' || | ||
| 308 | + // Report ReferenceError in case the strict mode is active | ||
| 309 | + // for input that has no completions. | ||
| 310 | + (result.className === 'ReferenceError' && | ||
| 311 | + (hasCompletions || !isInStrictMode(repl))))) { | ||
| 297 | 312 | callback(null, null); | |
| 298 | 313 | } else if (result.objectId) { | |
| 299 | 314 | // The writer options might change and have influence on the inspect | |
@@ -339,6 +354,8 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { | |||
| 339 | 354 | return; | |
| 340 | 355 | } | |
| 341 | 356 | ||
| 357 | + hasCompletions = false; | ||
| 358 | + | ||
| 342 | 359 | // Add the autocompletion preview. | |
| 343 | 360 | const insertPreview = false; | |
| 344 | 361 | showCompletionPreview(repl.line, insertPreview); | |
@@ -703,6 +720,8 @@ function setupReverseSearch(repl) { | |||
| 703 | 720 | } | |
| 704 | 721 | ||
| 705 | 722 | module.exports = { | |
| 723 | + REPL_MODE_SLOPPY: Symbol('repl-sloppy'), | ||
| 724 | + REPL_MODE_STRICT, | ||
| 706 | 725 | isRecoverableError, | |
| 707 | 726 | kStandaloneREPL: Symbol('kStandaloneREPL'), | |
| 708 | 727 | setupPreview, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -103,6 +103,8 @@ const experimentalREPLAwait = require('internal/options').getOptionValue( | |||
| 103 | 103 | '--experimental-repl-await' | |
| 104 | 104 | ); | |
| 105 | 105 | const { | |
| 106 | + REPL_MODE_SLOPPY, | ||
| 107 | + REPL_MODE_STRICT, | ||
| 106 | 108 | isRecoverableError, | |
| 107 | 109 | kStandaloneREPL, | |
| 108 | 110 | setupPreview, | |
@@ -363,8 +365,7 @@ function REPLServer(prompt, | |||
| 363 | 365 | } | |
| 364 | 366 | while (true) { | |
| 365 | 367 | try { | |
| 366 | - if (!/^\s*$/.test(code) && | ||
| 367 | - self.replMode === exports.REPL_MODE_STRICT) { | ||
| 368 | + if (self.replMode === exports.REPL_MODE_STRICT && !/^\s*$/.test(code)) { | ||
| 368 | 369 | // "void 0" keeps the repl from returning "use strict" as the result | |
| 369 | 370 | // value for statements and declarations that don't return a value. | |
| 370 | 371 | code = `'use strict'; void 0;\n${code}`; | |
@@ -896,8 +897,8 @@ ObjectSetPrototypeOf(REPLServer, Interface); | |||
| 896 | 897 | ||
| 897 | 898 | exports.REPLServer = REPLServer; | |
| 898 | 899 | ||
| 899 | - exports.REPL_MODE_SLOPPY = Symbol('repl-sloppy'); | ||
| 900 | - exports.REPL_MODE_STRICT = Symbol('repl-strict'); | ||
| 900 | + exports.REPL_MODE_SLOPPY = REPL_MODE_SLOPPY; | ||
| 901 | + exports.REPL_MODE_STRICT = REPL_MODE_STRICT; | ||
| 901 | 902 | ||
| 902 | 903 | // Prompt is a string to print on each line for the prompt, | |
| 903 | 904 | // source is a stream to use for I/O, defaulting to stdin/stdout. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,7 +7,8 @@ const repl = require('repl'); | |||
| 7 | 7 | const tests = [ | |
| 8 | 8 | testSloppyMode, | |
| 9 | 9 | testStrictMode, | |
| 10 | - testAutoMode | ||
| 10 | + testAutoMode, | ||
| 11 | + testStrictModeTerminal, | ||
| 11 | 12 | ]; | |
| 12 | 13 | ||
| 13 | 14 | tests.forEach(function(test) { | |
@@ -37,6 +38,18 @@ function testStrictMode() { | |||
| 37 | 38 | assert.strictEqual(cli.output.accumulator.join(''), 'undefined\n> '); | |
| 38 | 39 | } | |
| 39 | 40 | ||
| 41 | + function testStrictModeTerminal() { | ||
| 42 | + // Verify that ReferenceErrors are reported in strict mode previews. | ||
| 43 | + const cli = initRepl(repl.REPL_MODE_STRICT, { | ||
| 44 | + terminal: true | ||
| 45 | + }); | ||
| 46 | + | ||
| 47 | + cli.input.emit('data', 'xyz '); | ||
| 48 | + assert.ok( | ||
| 49 | + cli.output.accumulator.includes('\n// ReferenceError: xyz is not defined') | ||
| 50 | + ); | ||
| 51 | + } | ||
| 52 | + | ||
| 40 | 53 | function testAutoMode() { | |
| 41 | 54 | const cli = initRepl(repl.REPL_MODE_MAGIC); | |
| 42 | 55 | ||
@@ -48,7 +61,7 @@ function testAutoMode() { | |||
| 48 | 61 | assert.strictEqual(cli.output.accumulator.join(''), 'undefined\n> '); | |
| 49 | 62 | } | |
| 50 | 63 | ||
| 51 | - function initRepl(mode) { | ||
| 64 | + function initRepl(mode, options) { | ||
| 52 | 65 | const input = new Stream(); | |
| 53 | 66 | input.write = input.pause = input.resume = () => {}; | |
| 54 | 67 | input.readable = true; | |
@@ -65,6 +78,7 @@ function initRepl(mode) { | |||
| 65 | 78 | output: output, | |
| 66 | 79 | useColors: false, | |
| 67 | 80 | terminal: false, | |
| 68 | - replMode: mode | ||
| 81 | + replMode: mode, | ||
| 82 | + ...options | ||
| 69 | 83 | }); | |
| 70 | 84 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + // Previews in strict mode should indicate ReferenceErrors. | ||
| 2 | + | ||
| 3 | + 'use strict'; | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + | ||
| 7 | + common.skipIfInspectorDisabled(); | ||
| 8 | + | ||
| 9 | + if (process.argv[2] === 'child') { | ||
| 10 | + const stream = require('stream'); | ||
| 11 | + const repl = require('repl'); | ||
| 12 | + class ActionStream extends stream.Stream { | ||
| 13 | + readable = true; | ||
| 14 | + run(data) { | ||
| 15 | + this.emit('data', `${data}`); | ||
| 16 | + this.emit('keypress', '', { ctrl: true, name: 'd' }); | ||
| 17 | + } | ||
| 18 | + resume() {} | ||
| 19 | + pause() {} | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + repl.start({ | ||
| 23 | + input: new ActionStream(), | ||
| 24 | + output: new stream.Writable({ | ||
| 25 | + write(chunk, _, next) { | ||
| 26 | + console.log(chunk.toString()); | ||
| 27 | + next(); | ||
| 28 | + } | ||
| 29 | + }), | ||
| 30 | + useColors: false, | ||
| 31 | + terminal: true | ||
| 32 | + }).inputStream.run('xyz'); | ||
| 33 | + } else { | ||
| 34 | + const assert = require('assert'); | ||
| 35 | + const { spawnSync } = require('child_process'); | ||
| 36 | + | ||
| 37 | + const result = spawnSync( | ||
| 38 | + process.execPath, | ||
| 39 | + ['--use-strict', `${__filename}`, 'child'] | ||
| 40 | + ); | ||
| 41 | + | ||
| 42 | + assert.match( | ||
| 43 | + result.stdout.toString(), | ||
| 44 | + /\/\/ ReferenceError: xyz is not defined/ | ||
| 45 | + ); | ||
| 46 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments