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

Code before:
	doNotDeoptimize,
	type ExpressionNode,
	type IncludeChildren,
	NodeBase,
	onlyIncludeSelfNoDeoptimize
} from './shared/Node';

// The header ends at the first non-white-space after "default"
function getDeclarationStart(code: string, start: number): number {
	return findNonWhiteSpace(code, findFirstOccurrenceOutsideComment(code, 'default', start) + 7);
}

function getFunctionIdInsertPosition(code: string, start: number): number {
	const declarationEnd =
		findFirstOccurrenceOutsideComment(code, 'function', start) + 'function'.length;
	code = code.slice(declarationEnd, findFirstOccurrenceOutsideComment(code, '(', declarationEnd));
	const generatorStarPos = findFirstOccurrenceOutsideComment(code, '*');
	if (generatorStarPos === -1) {
		return declarationEnd;
	}
	return declarationEnd + generatorStarPos + 1;
}

export default class ExportDefaultDeclaration extends NodeBase {
	declaration!: FunctionDeclaration | ClassDeclaration | ExpressionNode;
	needsBoundaries!: true;
	scope!: ModuleScope;
	type!: NodeType.tExportDefaultDeclaration;
	variable!: ExportDefaultVariable;

	private declarationName!: string | undefined;

	bind(): void {
		super.bind();
		const name = this.declarationName || this.scope.context.getModuleName();
		// Check if there's already a variable with the same name in the scope. This
		// can cause inconsistencies when using the cache.
		this.variable.name = this.scope.variables.get(name) ? `${name}_default` : name;
	}

	include(context: InclusionContext, includeChildrenRecursively: IncludeChildren): void {
		this.included = true;
		this.declaration.include(context, includeChildrenRecursively);
		if (includeChildrenRecursively) {
			this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
		}
	}

	includePath(path: ObjectPath, context: InclusionContext): void {
		this.included = true;
		this.declaration.includePath(path, context);

Review comment (suggestion):
`ExportDefaultDeclaration.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 `declare needsBoundaries: true` or be initialized to `true` as a real field.
```suggestion
	declare needsBoundaries: true;
```

Code after:
	doNotDeoptimize,
	type ExpressionNode,
	type IncludeChildren,
	NodeBase,
	onlyIncludeSelfNoDeoptimize
} from './shared/Node';

// The header ends at the first non-white-space after "default"
function getDeclarationStart(code: string, start: number): number {
	return findNonWhiteSpace(code, findFirstOccurrenceOutsideComment(code, 'default', start) + 7);
}

function getFunctionIdInsertPosition(code: string, start: number): number {
	const declarationEnd =
		findFirstOccurrenceOutsideComment(code, 'function', start) + 'function'.length;
	code = code.slice(declarationEnd, findFirstOccurrenceOutsideComment(code, '(', declarationEnd));
	const generatorStarPos = findFirstOccurrenceOutsideComment(code, '*');
	if (generatorStarPos === -1) {
		return declarationEnd;
	}
	return declarationEnd + generatorStarPos + 1;
}

export default class ExportDefaultDeclaration extends NodeBase {
	declare declaration: FunctionDeclaration | ClassDeclaration | ExpressionNode;
	declare needsBoundaries: true;
	declare scope: ModuleScope;
	declare type: NodeType.tExportDefaultDeclaration;
	declare variable: ExportDefaultVariable;

	declare private declarationName: string | undefined;

	bind(): void {
		super.bind();
		const name = this.declarationName || this.scope.context.getModuleName();
		// Check if there's already a variable with the same name in the scope. This
		// can cause inconsistencies when using the cache.
		this.variable.name = this.scope.variables.get(name) ? `${name}_default` : name;
	}

	include(context: InclusionContext, includeChildrenRecursively: IncludeChildren): void {
		this.included = true;
		this.declaration.include(context, includeChildrenRecursively);
		if (includeChildrenRecursively) {
			this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
		}
	}

	includePath(path: ObjectPath, context: InclusionContext): void {
		this.included = true;
		this.declaration.includePath(path, context);