From 250c2b2f4d0f89ae2e499f8932e4b0661e82226c Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Wed, 12 Oct 2022 06:23:55 +0200 Subject: [PATCH] Ensure the initializer of a destructuring declaration is always included if the id is included. --- src/ast/nodes/VariableDeclaration.ts | 13 ++++++++++++- .../samples/for-loop-parameter/_config.js | 9 +++++++++ .../samples/for-loop-parameter/main.js | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/function/samples/for-loop-parameter/_config.js create mode 100644 test/function/samples/for-loop-parameter/main.js diff --git a/src/ast/nodes/VariableDeclaration.ts b/src/ast/nodes/VariableDeclaration.ts index aa827e553d2..fafc136548c 100644 --- a/src/ast/nodes/VariableDeclaration.ts +++ b/src/ast/nodes/VariableDeclaration.ts @@ -15,8 +15,10 @@ import { import type { InclusionContext } from '../ExecutionContext'; import { EMPTY_PATH } from '../utils/PathTracker'; import type Variable from '../variables/Variable'; +import ArrayPattern from './ArrayPattern'; import Identifier, { type IdentifierWithVariable } from './Identifier'; import * as NodeType from './NodeType'; +import ObjectPattern from './ObjectPattern'; import type VariableDeclarator from './VariableDeclarator'; import type { InclusionOptions } from './shared/Expression'; import { type IncludeChildren, NodeBase } from './shared/Node'; @@ -62,8 +64,17 @@ export default class VariableDeclaration extends NodeBase { for (const declarator of this.declarations) { if (includeChildrenRecursively || declarator.shouldBeIncluded(context)) declarator.include(context, includeChildrenRecursively); + const { id, init } = declarator; if (asSingleStatement) { - declarator.id.include(context, includeChildrenRecursively); + id.include(context, includeChildrenRecursively); + } + if ( + init && + id.included && + !init.included && + (id instanceof ObjectPattern || id instanceof ArrayPattern) + ) { + init.include(context, includeChildrenRecursively); } } } diff --git a/test/function/samples/for-loop-parameter/_config.js b/test/function/samples/for-loop-parameter/_config.js new file mode 100644 index 00000000000..0c35dfd9e35 --- /dev/null +++ b/test/function/samples/for-loop-parameter/_config.js @@ -0,0 +1,9 @@ +const assert = require('assert'); + +module.exports = { + description: 'includes for-loop parameters', + exports({ checkObject, checkArray }) { + assert.strictEqual(checkObject({ foo: 1 }), 1, 'object'); + assert.strictEqual(checkArray([2]), 2, 'array'); + } +}; diff --git a/test/function/samples/for-loop-parameter/main.js b/test/function/samples/for-loop-parameter/main.js new file mode 100644 index 00000000000..c49d4c37c59 --- /dev/null +++ b/test/function/samples/for-loop-parameter/main.js @@ -0,0 +1,19 @@ +export function checkObject(p) { + return getFromObjectInLoop(p); +} + +export function checkArray(p) { + return getFromArrayInLoop(p); +} + +function getFromObjectInLoop(path) { + for (let { foo } = path;;) { + return foo; + } +} + +function getFromArrayInLoop(path) { + for (let [ foo ] = path;;) { + return foo; + } +} \ No newline at end of file