@@ -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 topLevelImportGroupDecls = groupImportsByNewlineContiguous ( sourceFile . statements . filter ( isImportDeclaration ) , host , formatContext ) ;
26
+ topLevelImportGroupDecls . forEach ( topLevelImportGroupDecl => organizeImportsWorker ( topLevelImportGroupDecl , 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 ambientModuleImportGroupDecls = groupImportsByNewlineContiguous ( ambientModule . body . statements . filter ( isImportDeclaration ) , host , formatContext ) ;
36
+ ambientModuleImportGroupDecls . forEach ( ambientModuleImportGroupDecl => organizeImportsWorker ( ambientModuleImportGroupDecl , coalesceAndOrganizeImports ) ) ;
38
37
39
38
const ambientModuleExportDecls = ambientModule . body . statements . filter ( isExportDeclaration ) ;
40
39
organizeImportsWorker ( ambientModuleExportDecls , coalesceExports ) ;
@@ -88,6 +87,31 @@ namespace ts.OrganizeImports {
88
87
}
89
88
}
90
89
90
+ function groupImportsByNewlineContiguous ( 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
+
95
+ for ( let importIndex = 0 , groupIndex = 0 , length = importDecls . length ; importIndex < length ; ++ importIndex ) {
96
+ const topLevelImportDecl = importDecls [ importIndex ] ;
97
+ const leadingText = topLevelImportDecl . getFullText ( ) . substring (
98
+ 0 ,
99
+ topLevelImportDecl . getStart ( ) - topLevelImportDecl . getFullStart ( ) ) ;
100
+
101
+ if ( startsWith ( leadingText , prefixCond ) ) {
102
+ groupIndex ++ ;
103
+ }
104
+
105
+ if ( ! groupImports [ groupIndex ] ) {
106
+ groupImports [ groupIndex ] = [ ] ;
107
+ }
108
+
109
+ groupImports [ groupIndex ] . push ( topLevelImportDecl ) ;
110
+ }
111
+
112
+ return groupImports ;
113
+ }
114
+
91
115
function removeUnusedImports ( oldImports : readonly ImportDeclaration [ ] , sourceFile : SourceFile , program : Program , skipDestructiveCodeActions : boolean | undefined ) {
92
116
// As a precaution, consider unused import detection to be destructive (GH #43051)
93
117
if ( skipDestructiveCodeActions ) {
0 commit comments