From e27889d62218489e7dffa8d5262ae7ca5db505d8 Mon Sep 17 00:00:00 2001 From: Cullen Walsh Date: Fri, 18 Jul 2025 19:43:50 +0000 Subject: [PATCH] [Feature] Expand detection for `sort-imports-ignore` Summary: Prior to this commit, isSortImportsIgnored() checked comments associated with the extracted ImportDirectives, and only if the comment started on line 1. This could result in a failure to suppress sorting if the comment was not next to an ImportDirective (never considered), the first import directive were embedded later in the file (line mismatch), or directives/shebangs were used (Line 1 is unavailable). With this change, the line restriction is removed, and all comments from the beginning of the file and the first statement are checked. This ensures better coverage, especially with the importOrderIgnoreHeaderComments feature stacked on this commit. Test Plan: `yarn install && yarn run test --all` --- src/preprocessors/preprocessor.ts | 6 +++++- .../__tests__/is-sort-imports-ignored.spec.ts | 21 +++++++++++++++++-- src/utils/is-sort-imports-ignored.ts | 13 +++++------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/preprocessors/preprocessor.ts b/src/preprocessors/preprocessor.ts index 8b50b651..b0062b45 100644 --- a/src/preprocessors/preprocessor.ts +++ b/src/preprocessors/preprocessor.ts @@ -3,6 +3,7 @@ import { ImportDeclaration } from '@babel/types'; import { PrettierOptions } from '../types'; import { extractASTNodes } from '../utils/extract-ast-nodes.js'; +import { getAllCommentsFromNodes } from '../utils/get-all-comments-from-nodes.js'; import { getCodeFromAst } from '../utils/get-code-from-ast.js'; import { getExperimentalParserPlugins } from '../utils/get-experimental-parser-plugins.js'; import { getSortedNodes } from '../utils/get-sorted-nodes.js'; @@ -28,6 +29,9 @@ export function preprocessor(code: string, options: PrettierOptions) { const ast = babelParser(code, parserOptions); + if (isSortImportsIgnored(ast.program.body[0]?.leadingComments ?? [])) + return code; + const { importNodes, injectIdx, @@ -36,7 +40,7 @@ export function preprocessor(code: string, options: PrettierOptions) { // short-circuit if there are no import declaration if (importNodes.length === 0) return code; - if (isSortImportsIgnored(importNodes)) return code; + if (isSortImportsIgnored(getAllCommentsFromNodes(importNodes))) return code; const allImports = getSortedNodes(importNodes, { importOrder, diff --git a/src/utils/__tests__/is-sort-imports-ignored.spec.ts b/src/utils/__tests__/is-sort-imports-ignored.spec.ts index 37deb9f8..d6c00213 100644 --- a/src/utils/__tests__/is-sort-imports-ignored.spec.ts +++ b/src/utils/__tests__/is-sort-imports-ignored.spec.ts @@ -1,5 +1,6 @@ import { expect, test } from 'vitest'; +import { getAllCommentsFromNodes } from '../get-all-comments-from-nodes'; import { getImportNodes } from '../get-import-nodes'; import { isSortImportsIgnored } from '../is-sort-imports-ignored'; @@ -12,14 +13,30 @@ const codeNotIgnored = `// second comment import z from 'z'; `; +const notIgnoreTextWithIgnoreLine = `// you need to write sort-imports-ignore +import z from 'z'; +`; + test('it should return true if specific leading comment detected', () => { const importNodes = getImportNodes(codeIgnored); - expect(isSortImportsIgnored(importNodes)).toBeTruthy(); + expect( + isSortImportsIgnored(getAllCommentsFromNodes(importNodes)), + ).toBeTruthy(); }); test('it should return false if no specific leading comment detected', () => { const importNodes = getImportNodes(codeNotIgnored); - expect(isSortImportsIgnored(importNodes)).toBeFalsy(); + expect( + isSortImportsIgnored(getAllCommentsFromNodes(importNodes)), + ).toBeFalsy(); +}); + +test('it should return false if ignore isnt on top of comment', () => { + const importNodes = getImportNodes(notIgnoreTextWithIgnoreLine); + + expect( + isSortImportsIgnored(getAllCommentsFromNodes(importNodes)), + ).toBeFalsy(); }); diff --git a/src/utils/is-sort-imports-ignored.ts b/src/utils/is-sort-imports-ignored.ts index dc294cd0..28e5fb58 100644 --- a/src/utils/is-sort-imports-ignored.ts +++ b/src/utils/is-sort-imports-ignored.ts @@ -1,12 +1,9 @@ -import { Statement } from '@babel/types'; +import { Comment } from '@babel/types'; import { sortImportsIgnoredComment } from '../constants.js'; -import { getAllCommentsFromNodes } from './get-all-comments-from-nodes.js'; -export const isSortImportsIgnored = (nodes: Statement[]) => - getAllCommentsFromNodes(nodes).some( - (comment) => - comment.loc && - comment.loc.start.line === 1 && - comment.value.includes(sortImportsIgnoredComment), +export const isSortImportsIgnored = (comments: Comment[]) => { + return comments.some((comment) => + comment.value.trimStart().startsWith(sortImportsIgnoredComment), ); +};