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

Code before:
import { EMPTY_PATH, SHARED_RECURSION_TRACKER, UNKNOWN_PATH } from '../utils/PathTracker';
import Identifier from './Identifier';
import MemberExpression from './MemberExpression';
import type * as NodeType from './NodeType';
import { Flag, isFlagSet, setFlag } from './shared/BitFlags';
import CallExpressionBase from './shared/CallExpressionBase';
import { getChainElementLiteralValueAtPath } from './shared/chainElements';
import type { ExpressionEntity, LiteralValueOrUnknown } from './shared/Expression';
import { UNKNOWN_RETURN_EXPRESSION } from './shared/Expression';
import type { ChainElement, ExpressionNode, IncludeChildren, SkippedChain } from './shared/Node';
import { INCLUDE_PARAMETERS, IS_SKIPPED_CHAIN } from './shared/Node';
import type SpreadElement from './SpreadElement';
import type Super from './Super';

export default class CallExpression
	extends CallExpressionBase
	implements DeoptimizableEntity, ChainElement
{
	declare arguments: (ExpressionNode | SpreadElement)[];
	declare callee: ExpressionNode | Super;
	declare type: NodeType.tCallExpression;
	/** Marked with #__PURE__ annotation */
	declare annotationPure?: boolean;

	private _evalWarned = false;
	private _namespaceWarned = false;

	get optional(): boolean {
		return isFlagSet(this.flags, Flag.optional);
	}
	set optional(value: boolean) {
		this.flags = setFlag(this.flags, Flag.optional, value);
	}

	bind(): void {
		super.bind();
		this.interaction = {
			args: [
				this.callee instanceof MemberExpression && !this.callee.variable
					? this.callee.object
					: null,
				...this.arguments
			],
			type: INTERACTION_CALLED,
			withNew: false
		};
	}

	getLiteralValueAtPathAsChainElement(
		path: ObjectPath,
		recursionTracker: EntityPathTracker,

Review comment (suggestion):
To reduce memory overhead, we can convert this boolean flag to a bit flag, like the optional property below.

Code after:
import { EMPTY_PATH, SHARED_RECURSION_TRACKER, UNKNOWN_PATH } from '../utils/PathTracker';
import Identifier from './Identifier';
import MemberExpression from './MemberExpression';
import type * as NodeType from './NodeType';
import { Flag, isFlagSet, setFlag } from './shared/BitFlags';
import CallExpressionBase from './shared/CallExpressionBase';
import { getChainElementLiteralValueAtPath } from './shared/chainElements';
import type { ExpressionEntity, LiteralValueOrUnknown } from './shared/Expression';
import { UNKNOWN_RETURN_EXPRESSION } from './shared/Expression';
import type { ChainElement, ExpressionNode, IncludeChildren, SkippedChain } from './shared/Node';
import { INCLUDE_PARAMETERS, IS_SKIPPED_CHAIN } from './shared/Node';
import type SpreadElement from './SpreadElement';
import type Super from './Super';

export default class CallExpression
	extends CallExpressionBase
	implements DeoptimizableEntity, ChainElement
{
	declare arguments: (ExpressionNode | SpreadElement)[];
	declare callee: ExpressionNode | Super;
	declare type: NodeType.tCallExpression;
	/** Marked with #__PURE__ annotation */
	declare annotationPure?: boolean;

	private get hasCheckedForWarnings(): boolean {
		return isFlagSet(this.flags, Flag.checkedForWarnings);
	}
	private set hasCheckedForWarnings(value: boolean) {
		this.flags = setFlag(this.flags, Flag.checkedForWarnings, value);
	}

	get optional(): boolean {
		return isFlagSet(this.flags, Flag.optional);
	}
	set optional(value: boolean) {
		this.flags = setFlag(this.flags, Flag.optional, value);
	}

	bind(): void {
		super.bind();
		this.interaction = {
			args: [
				this.callee instanceof MemberExpression && !this.callee.variable
					? this.callee.object
					: null,
				...this.arguments
			],
			type: INTERACTION_CALLED,
			withNew: false
		};
	}