Skip to content

Commit 64f1468

Browse files
committed
clean up
1 parent c7c57f7 commit 64f1468

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

src/services/organizeImports.ts

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,24 @@ export function organizeImports(
101101

102102
const { comparersToTest, typeOrdersToTest } = getDetectionLists(preferences);
103103
if (typeof preferences.organizeImportsIgnoreCase === "boolean") {
104-
// if case sensitivity is specified (true/false), then use the same setting for both.
104+
// If case sensitivity is specified (true/false), then use the same setting for both.
105105
comparer.moduleSpecifierComparer = getOrganizeImportsComparer(preferences, preferences.organizeImportsIgnoreCase);
106106
comparer.namedImportComparer = comparer.moduleSpecifierComparer;
107107
}
108108
else {
109-
// otherwise, we must test for both case-sensitivity and later, type order
109+
// Otherwise, we must test for case-sensitivity. Named import case sensitivity will be tested with type order
110110
({ comparer: comparer.moduleSpecifierComparer } = detectModuleSpecifierCaseBySort(topLevelImportGroupDecls, comparersToTest));
111111
}
112112

113-
const namedImportSort = detectNamedImportOrganizationBySort(topLevelImportDecls, comparersToTest, typeOrdersToTest);
114-
if (namedImportSort) {
115-
const { namedImportComparer, typeOrder } = namedImportSort;
116-
comparer.namedImportComparer = comparer.namedImportComparer ?? namedImportComparer;
117-
comparer.typeOrder = comparer.typeOrder ?? typeOrder;
113+
if (!comparer.typeOrder) {
114+
const namedImportSort = detectNamedImportOrganizationBySort(topLevelImportDecls, comparersToTest, typeOrdersToTest);
115+
if (namedImportSort) {
116+
const { namedImportComparer, typeOrder } = namedImportSort;
117+
comparer.namedImportComparer = comparer.namedImportComparer ?? namedImportComparer;
118+
comparer.typeOrder = comparer.typeOrder ?? typeOrder;
119+
}
118120
}
121+
119122
topLevelImportGroupDecls.forEach(importGroupDecl => organizeImportsWorker(importGroupDecl, comparer));
120123

121124
// Exports are always used
@@ -211,6 +214,17 @@ export function organizeImports(
211214
}
212215
}
213216

217+
/** @internal */
218+
export function getDetectionLists(preferences: UserPreferences): { comparersToTest: Comparer<string>[]; typeOrdersToTest: TypeOrder[]; } {
219+
// Returns the possible detection outcomes, given the user's preferences. The earlier in the list, the higher the priority.
220+
return {
221+
comparersToTest: typeof preferences.organizeImportsIgnoreCase === "boolean"
222+
? [getOrganizeImportsComparer(preferences, preferences.organizeImportsIgnoreCase)]
223+
: [getOrganizeImportsComparer(preferences, /*ignoreCase*/ true), getOrganizeImportsComparer(preferences, /*ignoreCase*/ false)],
224+
typeOrdersToTest: preferences.organizeImportsTypeOrder ? [preferences.organizeImportsTypeOrder] : ["last", "inline", "first"],
225+
};
226+
}
227+
214228
function groupByNewlineContiguous<T extends ImportDeclaration | ExportDeclaration>(sourceFile: SourceFile, decls: T[]): T[][] {
215229
const scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, sourceFile.languageVariant);
216230
const group: T[][] = [];
@@ -672,6 +686,10 @@ function compareModuleSpecifiersWorker(m1: Expression | undefined, m2: Expressio
672686
comparer(name1!, name2!);
673687
}
674688

689+
function getModuleNamesFromDecls(decls: readonly AnyImportOrRequireStatement[]): string[] {
690+
return decls.map(s => getExternalModuleName(getModuleSpecifierExpression(s)) || "");
691+
}
692+
675693
function getModuleSpecifierExpression(declaration: AnyImportOrRequireStatement): Expression | undefined {
676694
switch (declaration.kind) {
677695
case SyntaxKind.ImportEqualsDeclaration:
@@ -813,15 +831,11 @@ function getTopLevelExportGroups(sourceFile: SourceFile) {
813831
return flatMap(topLevelExportGroups, exportGroupDecls => groupByNewlineContiguous(sourceFile, exportGroupDecls));
814832
}
815833

816-
function getModuleNamesFromDecls(decls: readonly AnyImportOrRequireStatement[]): string[] {
817-
return decls.map(s => getExternalModuleName(getModuleSpecifierExpression(s)) || "");
818-
}
819-
820834
/** @internal */
821835
export function detectModuleSpecifierCaseBySort(importDeclsByGroup: (readonly AnyImportOrRequireStatement[])[], comparersToTest: Comparer<string>[]) {
822836
const moduleSpecifiersByGroup: string[][] = [];
823837
importDeclsByGroup.forEach(importGroup => {
824-
// turns importDeclsByGroup into string[][] of module specifiers by group to detect sorting on module specifiers
838+
// Turns importDeclsByGroup into string[][] of module specifiers by group to detect sorting on module specifiers
825839
moduleSpecifiersByGroup.push(getModuleNamesFromDecls(importGroup));
826840
});
827841
return detectCaseSensitivityBySort(moduleSpecifiersByGroup, comparersToTest);
@@ -832,27 +846,26 @@ export type TypeOrder = "first" | "last" | "inline";
832846

833847
/** @internal */
834848
export function detectNamedImportOrganizationBySort(originalGroups: readonly ImportDeclaration[], comparersToTest: Comparer<string>[], typesToTest: TypeOrder[]): { namedImportComparer: Comparer<string>; typeOrder?: "first" | "last" | "inline"; isSorted: boolean; } | undefined {
835-
// filter for import declarations with named imports. Will be a flat array of import declarations without separations by group
849+
// Filter for import declarations with named imports. Will be a flat array of import declarations without separations by group
836850
let bothNamedImports = false;
837851
const importDeclsWithNamed = originalGroups.filter(i => {
838852
const namedImports = tryCast(i.importClause?.namedBindings, isNamedImports)?.elements;
839853
if (!namedImports?.length) return false;
840854
if (!bothNamedImports && namedImports.some(n => n.isTypeOnly) && namedImports.some(n => !n.isTypeOnly)) {
841-
// todo:improve check
842855
bothNamedImports = true;
843856
}
844857
return true;
845858
});
846859

847-
// no need for more detection if no named imports
860+
// No need for more detection, if no named imports
848861
if (importDeclsWithNamed.length === 0) return;
849862

850-
// formats the code into lists of named imports, grouped by declaration
863+
// Formats into lists of named imports, grouped by declaration
851864
const namedImportsByDecl = importDeclsWithNamed.map(importDecl => {
852865
return tryCast(importDecl.importClause?.namedBindings, isNamedImports)?.elements;
853866
}).filter(elements => elements !== undefined) as any as ImportSpecifier[][];
854867

855-
// if we don't have any import statements with both named regular and type imports, we do not need to detect a type ordering
868+
// If we don't have any import statements with both named regular and type imports, we do not need to detect a type ordering
856869
if (!bothNamedImports || typesToTest.length === 0) {
857870
const sortState = detectCaseSensitivityBySort(namedImportsByDecl.map(i => i.map(n => n.name.text)), comparersToTest);
858871
return { namedImportComparer: sortState.comparer, isSorted: sortState.isSorted };
@@ -886,20 +899,10 @@ export function detectNamedImportOrganizationBySort(originalGroups: readonly Imp
886899
return { namedImportComparer: bestComparer[bestTypeOrder], typeOrder: bestTypeOrder, isSorted: bestDiff[bestTypeOrder] === 0 };
887900
}
888901

889-
// default; hopefully never hit.....
902+
// Default behavior. It shouldn't be hit if typesToTest.length > 0
890903
return { namedImportComparer: bestComparer.last, typeOrder: "last", isSorted: bestDiff.last === 0 };
891904
}
892905

893-
/** @internal */
894-
export function getDetectionLists(preferences: UserPreferences): { comparersToTest: Comparer<string>[]; typeOrdersToTest: TypeOrder[]; } {
895-
return {
896-
comparersToTest: typeof preferences.organizeImportsIgnoreCase === "boolean"
897-
? [getOrganizeImportsComparer(preferences, preferences.organizeImportsIgnoreCase)]
898-
: [getOrganizeImportsComparer(preferences, /*ignoreCase*/ true), getOrganizeImportsComparer(preferences, /*ignoreCase*/ false)],
899-
typeOrdersToTest: preferences.organizeImportsTypeOrder ? [preferences.organizeImportsTypeOrder] : ["last", "inline", "first"],
900-
};
901-
}
902-
903906
function getSortedMeasure<T>(arr: readonly T[], comparer: Comparer<T>) {
904907
let i = 0;
905908
for (let j = 0; j < arr.length - 1; j++) {
@@ -909,9 +912,10 @@ function getSortedMeasure<T>(arr: readonly T[], comparer: Comparer<T>) {
909912
}
910913
return i;
911914
}
915+
912916
function detectCaseSensitivityBySort(originalGroups: string[][], comparersToTest: Comparer<string>[]): { comparer: Comparer<string>; isSorted: boolean; } {
913-
// each entry in originalGroups will be sorted and compared against the original entry.
914-
// the total diff of each comparison is the sum of the diffs of all groups
917+
// Each entry in originalGroups will be sorted and compared against the original entry.
918+
// The total diff of each comparison is the sum of the diffs over all groups
915919
let bestComparer;
916920
let bestDiff = Infinity;
917921

@@ -923,8 +927,6 @@ function detectCaseSensitivityBySort(originalGroups: string[][], comparersToTest
923927

924928
for (const listToSort of originalGroups) {
925929
if (listToSort.length <= 1) continue;
926-
927-
// const sortedList = sort(listToSort, curComparer) as any as string[];
928930
const diff = getSortedMeasure(listToSort, curComparer);
929931
diffOfCurrentComparer += diff;
930932
}

0 commit comments

Comments
 (0)