diff --git a/lib/repl.js b/lib/repl.js index 2c952cfbf7..a7452b8ec7 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -628,7 +628,7 @@ ArrayStream.prototype.write = function() {}; const requireRE = /\brequire\s*\(['"](([\w\.\/-]+\/)?([\w\.\/-]*))/; const simpleExpressionRE = - /^\s*(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/; + /(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/; function intFilter(item) { // filters out anything not starting with A-Z, a-z, $ or _ @@ -806,7 +806,8 @@ REPLServer.prototype.complete = function(line, callback) { }); } } else { - this.eval(expr, this.context, 'repl', function(e, obj) { + const evalExpr = `try { ${expr} } catch (e) {}`; + this.eval(evalExpr, this.context, 'repl', function(e, obj) { // if (e) console.log(e); if (obj != null) { diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 0c18d8e11c..eb4e68ad18 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -3,19 +3,13 @@ var common = require('../common'); var assert = require('assert'); var repl = require('repl'); -var referenceErrors = 0; -var expectedReferenceErrors = 0; - -function getDoNotCallFunction() { - expectedReferenceErrors += 1; - return function() { - assert(false); - }; -} -process.on('exit', function() { - assert.strictEqual(referenceErrors, expectedReferenceErrors); -}); +function getNoResultsFunction() { + return common.mustCall((err, data) => { + assert.ifError(err); + assert.deepStrictEqual(data[0], []); + }); +} var works = [['inner.one'], 'inner.o']; const putIn = new common.ArrayStream(); @@ -23,13 +17,7 @@ var testMe = repl.start('', putIn); // Some errors are passed to the domain, but do not callback testMe._domain.on('error', function(err) { - // Errors come from another context, so instanceof doesn't work - var str = err.toString(); - - if (/^ReferenceError:/.test(str)) - referenceErrors++; - else - assert(false); + assert.ifError(err); }); // Tab Complete will not break in an object literal @@ -38,7 +26,7 @@ putIn.run([ 'var inner = {', 'one:1' ]); -testMe.complete('inner.o', getDoNotCallFunction()); +testMe.complete('inner.o', getNoResultsFunction()); testMe.complete('console.lo', common.mustCall(function(error, data) { assert.deepStrictEqual(data, [['console.log'], 'console.lo']); @@ -58,7 +46,7 @@ putIn.run([ '?', '{one: 1} : ' ]); -testMe.complete('inner.o', getDoNotCallFunction()); +testMe.complete('inner.o', getNoResultsFunction()); putIn.run(['.clear']); @@ -74,7 +62,7 @@ testMe.complete('inner.o', common.mustCall(function(error, data) { // When you close the function scope tab complete will not return the // locally scoped variable putIn.run(['};']); -testMe.complete('inner.o', getDoNotCallFunction()); +testMe.complete('inner.o', getNoResultsFunction()); putIn.run(['.clear']); @@ -129,7 +117,7 @@ putIn.run([ ' one:1', '};' ]); -testMe.complete('inner.o', getDoNotCallFunction()); +testMe.complete('inner.o', getNoResultsFunction()); putIn.run(['.clear']); @@ -142,7 +130,7 @@ putIn.run([ ' one:1', '};' ]); -testMe.complete('inner.o', getDoNotCallFunction()); +testMe.complete('inner.o', getNoResultsFunction()); putIn.run(['.clear']); @@ -156,7 +144,7 @@ putIn.run([ ' one:1', '};' ]); -testMe.complete('inner.o', getDoNotCallFunction()); +testMe.complete('inner.o', getNoResultsFunction()); putIn.run(['.clear']); @@ -254,6 +242,21 @@ testMe.complete('obj.', common.mustCall(function(error, data) { putIn.run(['.clear']); putIn.run(['function a() {}']); -testMe.complete('a().b.', common.mustCall((error, data) => { - assert.deepStrictEqual(data, [[], undefined]); +testMe.complete('a().b.', getNoResultsFunction()); + +// Works when prefixed with spaces +putIn.run(['.clear']); +putIn.run(['var obj = {1:"a","1a":"b",a:"b"};']); + +testMe.complete(' obj.', common.mustCall((error, data) => { + assert.strictEqual(data[0].indexOf('obj.1'), -1); + assert.strictEqual(data[0].indexOf('obj.1a'), -1); + assert.notStrictEqual(data[0].indexOf('obj.a'), -1); +})); + +// Works inside assignments +putIn.run(['.clear']); + +testMe.complete('var log = console.lo', common.mustCall((error, data) => { + assert.deepStrictEqual(data, [['console.log'], 'console.lo']); }));