Repository: rollup/rollup
File: src/ast/nodes/ImportDeclaration.ts (TypeScript)

Code before:
import type MagicString from 'magic-string';
import type { NodeRenderOptions, RenderOptions } from '../../utils/renderHelpers';
import type ImportAttribute from './ImportAttribute';
import type ImportDefaultSpecifier from './ImportDefaultSpecifier';
import type ImportNamespaceSpecifier from './ImportNamespaceSpecifier';
import type ImportSpecifier from './ImportSpecifier';
import type Literal from './Literal';
import type * as NodeType from './NodeType';
import { doNotDeoptimize, NodeBase, onlyIncludeSelfNoDeoptimize } from './shared/Node';

export default class ImportDeclaration extends NodeBase {
	attributes!: ImportAttribute[];
	needsBoundaries!: true;
	source!: Literal<string>;
	specifiers!: (ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier)[];
	type!: NodeType.tImportDeclaration;

	// Do not bind specifiers or attributes
	bind(): void {}

	hasEffects(): boolean {
		return false;
	}

	initialise(): void {
		super.initialise();
		this.scope.context.addImport(this);
	}

	render(code: MagicString, _options: RenderOptions, nodeRenderOptions?: NodeRenderOptions): void {
		code.remove(nodeRenderOptions!.start!, nodeRenderOptions!.end!);
	}
}

ImportDeclaration.prototype.needsBoundaries = true;
ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;


Review comment (suggestion):
`ImportDeclaration.prototype.needsBoundaries = true` is set later in this file. Declaring `needsBoundaries!: true` emits an instance field initialized to `undefined`, which shadows the prototype flag and makes `needsBoundaries` falsy at runtime. This should remain a type-only declaration (`declare needsBoundaries: true`) or be initialized to `true` as a real field.

Code after:
import type MagicString from 'magic-string';
import type { NodeRenderOptions, RenderOptions } from '../../utils/renderHelpers';
import type ImportAttribute from './ImportAttribute';
import type ImportDefaultSpecifier from './ImportDefaultSpecifier';
import type ImportNamespaceSpecifier from './ImportNamespaceSpecifier';
import type ImportSpecifier from './ImportSpecifier';
import type Literal from './Literal';
import type * as NodeType from './NodeType';
import { doNotDeoptimize, NodeBase, onlyIncludeSelfNoDeoptimize } from './shared/Node';

export default class ImportDeclaration extends NodeBase {
	declare attributes: ImportAttribute[];
	declare needsBoundaries: true;
	declare source: Literal<string>;
	declare specifiers: (ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier)[];
	declare type: NodeType.tImportDeclaration;

	// Do not bind specifiers or attributes
	bind(): void {}

	hasEffects(): boolean {
		return false;
	}

	initialise(): void {
		super.initialise();
		this.scope.context.addImport(this);
	}

	render(code: MagicString, _options: RenderOptions, nodeRenderOptions?: NodeRenderOptions): void {
		code.remove(nodeRenderOptions!.start!, nodeRenderOptions!.end!);
	}
}

ImportDeclaration.prototype.needsBoundaries = true;
ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;