@@ -22,7 +22,7 @@ namespace ts.OrganizeImports {
2222 ( s1 , s2 ) => compareImportsOrRequireStatements ( s1 , s2 ) ) ;
2323
2424 // All of the old ImportDeclarations in the file, in syntactic order.
25- const topLevelImportGroupDecls = groupImportsByNewlineContiguous ( sourceFile . statements . filter ( isImportDeclaration ) , host , formatContext ) ;
25+ const topLevelImportGroupDecls = groupImportsByNewlineContiguous ( sourceFile , sourceFile . statements . filter ( isImportDeclaration ) ) ;
2626 topLevelImportGroupDecls . forEach ( importGroupDecl => organizeImportsWorker ( importGroupDecl , coalesceAndOrganizeImports ) ) ;
2727
2828 // All of the old ExportDeclarations in the file, in syntactic order.
@@ -32,7 +32,7 @@ namespace ts.OrganizeImports {
3232 for ( const ambientModule of sourceFile . statements . filter ( isAmbientModule ) ) {
3333 if ( ! ambientModule . body ) continue ;
3434
35- const ambientModuleImportGroupDecls = groupImportsByNewlineContiguous ( ambientModule . body . statements . filter ( isImportDeclaration ) , host , formatContext ) ;
35+ const ambientModuleImportGroupDecls = groupImportsByNewlineContiguous ( sourceFile , ambientModule . body . statements . filter ( isImportDeclaration ) ) ;
3636 ambientModuleImportGroupDecls . forEach ( importGroupDecl => organizeImportsWorker ( importGroupDecl , coalesceAndOrganizeImports ) ) ;
3737
3838 const ambientModuleExportDecls = ambientModule . body . statements . filter ( isExportDeclaration ) ;
@@ -87,16 +87,11 @@ namespace ts.OrganizeImports {
8787 }
8888 }
8989
90- function groupImportsByNewlineContiguous ( importDecls : ImportDeclaration [ ] , host : LanguageServiceHost , formatContext : formatting . FormatContext ) : ImportDeclaration [ ] [ ] {
90+ function groupImportsByNewlineContiguous ( sourceFile : SourceFile , importDecls : ImportDeclaration [ ] ) : ImportDeclaration [ ] [ ] {
9191 const groupImports : ImportDeclaration [ ] [ ] = [ ] ;
92- const newLine = getNewLineOrDefaultFromHost ( host , formatContext . options ) ;
93- const prefixCond = `${ newLine } ${ newLine } ` ;
94-
9592 let groupIndex = 0 ;
96- for ( const topLevelImportDecl of importDecls ) {
97- const leadingText = topLevelImportDecl . getFullText ( ) . substring ( 0 , topLevelImportDecl . getStart ( ) - topLevelImportDecl . getFullStart ( ) ) ;
98-
99- if ( startsWith ( leadingText , prefixCond ) ) {
93+ for ( const topLevelImportDecl of importDecls ) {
94+ if ( isStartedNewGroup ( sourceFile , topLevelImportDecl ) ) {
10095 groupIndex ++ ;
10196 }
10297
@@ -110,6 +105,26 @@ namespace ts.OrganizeImports {
110105 return groupImports ;
111106 }
112107
108+ // a new group is created if an import includes at least two new line
109+ // new line from multi-line comment doesn't count
110+ function isStartedNewGroup ( sourceFile : SourceFile , topLevelImportDecl : ImportDeclaration ) {
111+ const startPos = topLevelImportDecl . getFullStart ( ) ;
112+ const endPos = topLevelImportDecl . getStart ( ) ;
113+
114+ const scanner = createScanner ( sourceFile . languageVersion , /*skipTrivia*/ false , sourceFile . languageVariant , sourceFile . text , /*onError:*/ undefined , startPos ) ;
115+
116+ let numberOfNewLines = 0 ;
117+ while ( scanner . getTokenPos ( ) < endPos ) {
118+ const tokenKind = scanner . scan ( ) ;
119+
120+ if ( tokenKind === SyntaxKind . NewLineTrivia ) {
121+ numberOfNewLines ++ ;
122+ }
123+ }
124+
125+ return numberOfNewLines >= 2 ;
126+ }
127+
113128 function removeUnusedImports ( oldImports : readonly ImportDeclaration [ ] , sourceFile : SourceFile , program : Program , skipDestructiveCodeActions : boolean | undefined ) {
114129 // As a precaution, consider unused import detection to be destructive (GH #43051)
115130 if ( skipDestructiveCodeActions ) {
0 commit comments