From 4dd8f96addd8d8197f96e258749d78c2d1c443c8 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Wed, 12 Oct 2022 09:31:38 +0200 Subject: [PATCH] Ensure the initializer of a destructuring declaration is always included if the id is included (#4663) * Ensure the initializer of a destructuring declaration is always included if the id is included. * Make watch tests more resilient Ensure that new event listeners are created synchronously after a function handler --- src/ast/nodes/VariableDeclaration.ts | 13 ++++++++++++- .../samples/for-loop-parameter/_config.js | 9 +++++++++ .../samples/for-loop-parameter/main.js | 19 +++++++++++++++++++ test/watch/index.js | 9 +++++---- 4 files changed, 45 insertions(+), 5 deletions(-) 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 diff --git a/test/watch/index.js b/test/watch/index.js index e91af31ad16..e444f6b3ad2 100644 --- a/test/watch/index.js +++ b/test/watch/index.js @@ -61,10 +61,11 @@ describe('rollup.watch', () => { } }); } else { - Promise.resolve() - .then(() => wait(timeout)) // gah, this appears to be necessary to fix random errors - .then(() => next(event)) - .then(go) + wait(timeout) // gah, this appears to be necessary to fix random errors + .then(() => { + next(event); + go(); + }) .catch(error => { watcher.close(); reject(error);