Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions src/tsco-cli/source-code/source-code-analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,37 @@ export class SourceCodeAnalyzer
return elements;
}

/**
* Extracts trailing comments at the end of the file.
* These are comments that appear after the last syntax node and are attached to the EndOfFileToken.
* This ensures commented-out code at the end of files is preserved during reorganization.
*
* @param sourceFile The TypeScript source file to analyze
* @returns The trailing comments text, or null if there are no trailing comments
*/
public static getFileTrailer(sourceFile: ts.SourceFile)
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method should have an explicit return type annotation. Add : string | null to match the documented return type in the JSDoc.

Suggested change
public static getFileTrailer(sourceFile: ts.SourceFile)
public static getFileTrailer(sourceFile: ts.SourceFile): string | null

Copilot uses AI. Check for mistakes.
{
// Get trailing comments from the EndOfFileToken
const children = sourceFile.getChildren(sourceFile);
const eofToken = children.find(node => node.kind === ts.SyntaxKind.EndOfFileToken);

if (eofToken)
{
const fullText = sourceFile.getFullText();
const commentRanges = ts.getLeadingCommentRanges(fullText, eofToken.pos);

if (commentRanges && commentRanges.length > 0)
{
const start = commentRanges[0].pos;
const end = commentRanges[commentRanges.length - 1].end;

return fullText.substring(start, end);
}
}

return null;
}

public static hasReference(sourceFile: ts.SourceFile, identifier: string)
{
return sourceFile.getChildren(sourceFile).some(node => this.findReference(node, sourceFile, identifier));
Expand Down
3 changes: 2 additions & 1 deletion src/tsco-cli/source-code/source-code-organizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ export class SourceCodeOrganizer

const sourceFile = ts.createSourceFile(sourceCodeFilePath, sourceCodeWithoutRegions.toString(), ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
const elements = SourceCodeAnalyzer.getNodes(sourceFile, configuration);
const fileTrailer = SourceCodeAnalyzer.getFileTrailer(sourceFile);
const topLevelGroups = await this.organizeModuleMembers(elements, configuration, sourceFile, sourceCodeFilePath); // TODO: move this to module node

return SourceCodePrinter.print(fileHeader, topLevelGroups, configuration).toString();
return SourceCodePrinter.print(fileHeader, topLevelGroups, fileTrailer, configuration).toString();
}
catch (error)
{
Expand Down
16 changes: 14 additions & 2 deletions src/tsco-cli/source-code/source-code-printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class SourceCodePrinter
{
// #region Public Static Methods (1)

public static print(fileHeader: string | null, nodeGroups: ElementNodeGroup[], configuration: Configuration)
public static print(fileHeader: string | null, nodeGroups: ElementNodeGroup[], fileTrailer: string | null, configuration: Configuration)
{
const printedSourceCode = this.printNodeGroups(nodeGroups, configuration);

Expand All @@ -42,9 +42,21 @@ export class SourceCodePrinter
printedSourceCode.removeConsecutiveEmptyLines();
printedSourceCode.trim();

if (printedSourceCode.length > 0)
const hasContent = printedSourceCode.length > 0;
const hasTrailer = fileTrailer && fileTrailer.length > 0;
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hasTrailer check is redundant because fileTrailer.length > 0 already returns false for null/undefined values due to short-circuit evaluation. Consider simplifying to const hasTrailer = !!fileTrailer && fileTrailer.length > 0; for clarity, or use optional chaining: const hasTrailer = (fileTrailer?.length ?? 0) > 0;.

Suggested change
const hasTrailer = fileTrailer && fileTrailer.length > 0;
const hasTrailer = (fileTrailer?.length ?? 0) > 0;

Copilot uses AI. Check for mistakes.

if (hasContent)
{
printedSourceCode.addNewLineAfter();
if (hasTrailer)
{
printedSourceCode.addNewLineAfter();
}
}

if (hasTrailer)
{
printedSourceCode.addAfter(fileTrailer);
}

return printedSourceCode;
Expand Down