@@ -15,16 +15,15 @@ namespace ts.OrganizeImports {
15
15
preferences : UserPreferences ,
16
16
skipDestructiveCodeActions ?: boolean
17
17
) {
18
-
19
18
const changeTracker = textChanges . ChangeTracker . fromContext ( { host, formatContext, preferences } ) ;
20
19
21
20
const coalesceAndOrganizeImports = ( importGroup : readonly ImportDeclaration [ ] ) => stableSort (
22
21
coalesceImports ( removeUnusedImports ( importGroup , sourceFile , program , skipDestructiveCodeActions ) ) ,
23
22
( s1 , s2 ) => compareImportsOrRequireStatements ( s1 , s2 ) ) ;
24
23
25
24
// All of the old ImportDeclarations in the file, in syntactic order.
26
- const topLevelImportDecls = sourceFile . statements . filter ( isImportDeclaration ) ;
27
- organizeImportsWorker ( topLevelImportDecls , coalesceAndOrganizeImports ) ;
25
+ const topLevelGroupImportDecls = groupImportsByNewlines ( sourceFile . statements . filter ( isImportDeclaration ) , host , formatContext ) ;
26
+ topLevelGroupImportDecls . forEach ( topLevelGroupImportDecl => organizeImportsWorker ( topLevelGroupImportDecl , coalesceAndOrganizeImports ) ) ;
28
27
29
28
// All of the old ExportDeclarations in the file, in syntactic order.
30
29
const topLevelExportDecls = sourceFile . statements . filter ( isExportDeclaration ) ;
@@ -33,8 +32,8 @@ namespace ts.OrganizeImports {
33
32
for ( const ambientModule of sourceFile . statements . filter ( isAmbientModule ) ) {
34
33
if ( ! ambientModule . body ) continue ;
35
34
36
- const ambientModuleImportDecls = ambientModule . body . statements . filter ( isImportDeclaration ) ;
37
- organizeImportsWorker ( ambientModuleImportDecls , coalesceAndOrganizeImports ) ;
35
+ const ambientModuleGroupImportDecls = groupImportsByNewlines ( ambientModule . body . statements . filter ( isImportDeclaration ) , host , formatContext ) ;
36
+ ambientModuleGroupImportDecls . forEach ( ambientModuleGroupImportDecl => organizeImportsWorker ( ambientModuleGroupImportDecl , coalesceAndOrganizeImports ) ) ;
38
37
39
38
const ambientModuleExportDecls = ambientModule . body . statements . filter ( isExportDeclaration ) ;
40
39
organizeImportsWorker ( ambientModuleExportDecls , coalesceExports ) ;
@@ -88,6 +87,24 @@ namespace ts.OrganizeImports {
88
87
}
89
88
}
90
89
90
+ function groupImportsByNewlines ( importDecls : ImportDeclaration [ ] , host : LanguageServiceHost , formatContext : formatting . FormatContext ) : ImportDeclaration [ ] [ ] {
91
+ const groupImports : ImportDeclaration [ ] [ ] = [ ] ;
92
+ const newLine = getNewLineOrDefaultFromHost ( host , formatContext . options ) ;
93
+ const prefixCond = `${ newLine } ${ newLine } ` ;
94
+ for ( let index = 0 , groupIndex = 0 , length = importDecls . length ; index < length ; ++ index ) {
95
+ const topLevelImportDecl = importDecls [ index ] ;
96
+ const leadingText = topLevelImportDecl . getFullText ( ) . substring ( 0 , topLevelImportDecl . getStart ( ) - topLevelImportDecl . getFullStart ( ) ) ;
97
+ if ( startsWith ( leadingText , prefixCond ) ) {
98
+ groupIndex ++ ;
99
+ }
100
+ if ( ! groupImports [ groupIndex ] ) {
101
+ groupImports [ groupIndex ] = [ ] ;
102
+ }
103
+ groupImports [ groupIndex ] . push ( topLevelImportDecl ) ;
104
+ }
105
+ return groupImports ;
106
+ }
107
+
91
108
function removeUnusedImports ( oldImports : readonly ImportDeclaration [ ] , sourceFile : SourceFile , program : Program , skipDestructiveCodeActions : boolean | undefined ) {
92
109
// As a precaution, consider unused import detection to be destructive (GH #43051)
93
110
if ( skipDestructiveCodeActions ) {
0 commit comments