diff --git a/packages/babel-traverse/src/path/family.ts b/packages/babel-traverse/src/path/family.ts index 2c98a500bfa2..83701952361b 100644 --- a/packages/babel-traverse/src/path/family.ts +++ b/packages/babel-traverse/src/path/family.ts @@ -193,11 +193,19 @@ function getStatementListCompletion( } } else if (paths.length) { // When we are in a context where `break` must not exist, we can skip linear - // search on statement lists and assume that the last statement determines - // the completion - completions = completions.concat( - _getCompletionRecords(paths[paths.length - 1], context), - ); + // search on statement lists and assume that the last + // non-variable-declaration statement determines the completion. + for (let i = paths.length - 1; i >= 0; i--) { + const pathCompletions = _getCompletionRecords(paths[i], context); + if ( + pathCompletions.length > 1 || + (pathCompletions.length === 1 && + !pathCompletions[0].path.isVariableDeclaration()) + ) { + completions = completions.concat(pathCompletions); + break; + } + } } return completions; } diff --git a/packages/babel-traverse/test/family.js b/packages/babel-traverse/test/family.js index ef5fa0fac4d8..aa295f38bae5 100644 --- a/packages/babel-traverse/test/family.js +++ b/packages/babel-traverse/test/family.js @@ -109,6 +109,44 @@ describe("path/family", function () { expect(consequentHasScope).toBe(true); }); }); + describe("getCompletionRecords", function () { + it("should skip variable declarations", function () { + const ast = parse("'foo' + 'bar'; var a = 10; let b = 20; const c = 30;"); + let records = []; + traverse(ast, { + Program(path) { + records = path.getCompletionRecords(); + }, + }); + expect(records).toHaveLength(1); + expect(records[0].node.type).toBe("ExpressionStatement"); + expect(records[0].node.expression.type).toBe("BinaryExpression"); + }); + + it("should skip variable declarations in a BlockStatement", function () { + const ast = parse("'foo' + 'bar'; { var a = 10; }"); + let records = []; + traverse(ast, { + Program(path) { + records = path.getCompletionRecords(); + }, + }); + expect(records).toHaveLength(1); + expect(records[0].node.type).toBe("ExpressionStatement"); + expect(records[0].node.expression.type).toBe("BinaryExpression"); + }); + + it("should be empty if there are only variable declarations", function () { + const ast = parse("var a = 10; let b = 20; const c = 30;"); + let records = []; + traverse(ast, { + Program(path) { + records = path.getCompletionRecords(); + }, + }); + expect(records).toHaveLength(0); + }); + }); }); function hop(o, key) {