@@ -677,7 +677,7 @@ function removeNewLineAfterImport(context, currentImport, previousImport) {
677
677
return undefined ;
678
678
}
679
679
680
- function makeNewlinesBetweenReport ( context , imported , newlinesBetweenImports , distinctGroup ) {
680
+ function makeNewlinesBetweenReport ( context , imported , newlinesBetweenImports , newlinesBetweenTypeOnlyImports , distinctGroup , isSortingTypesAmongThemselves ) {
681
681
const getNumberOfEmptyLinesBetween = ( currentImport , previousImport ) => {
682
682
const linesBetweenImports = getSourceCode ( context ) . lines . slice (
683
683
previousImport . node . loc . end . line ,
@@ -690,35 +690,78 @@ function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports, di
690
690
let previousImport = imported [ 0 ] ;
691
691
692
692
imported . slice ( 1 ) . forEach ( function ( currentImport ) {
693
- const emptyLinesBetween = getNumberOfEmptyLinesBetween ( currentImport , previousImport ) ;
694
- const isStartOfDistinctGroup = getIsStartOfDistinctGroup ( currentImport , previousImport ) ;
695
-
696
- if ( newlinesBetweenImports === 'always'
697
- || newlinesBetweenImports === 'always-and-inside-groups' ) {
698
- if ( currentImport . rank !== previousImport . rank && emptyLinesBetween === 0 ) {
699
- if ( distinctGroup || ! distinctGroup && isStartOfDistinctGroup ) {
700
- context . report ( {
701
- node : previousImport . node ,
702
- message : 'There should be at least one empty line between import groups' ,
703
- fix : fixNewLineAfterImport ( context , previousImport ) ,
704
- } ) ;
705
- }
706
- } else if ( emptyLinesBetween > 0
707
- && newlinesBetweenImports !== 'always-and-inside-groups' ) {
708
- if ( distinctGroup && currentImport . rank === previousImport . rank || ! distinctGroup && ! isStartOfDistinctGroup ) {
709
- context . report ( {
710
- node : previousImport . node ,
711
- message : 'There should be no empty line within import group' ,
712
- fix : removeNewLineAfterImport ( context , currentImport , previousImport ) ,
713
- } ) ;
693
+ const emptyLinesBetween = getNumberOfEmptyLinesBetween (
694
+ currentImport ,
695
+ previousImport
696
+ ) ;
697
+
698
+ const isStartOfDistinctGroup = getIsStartOfDistinctGroup (
699
+ currentImport ,
700
+ previousImport
701
+ ) ;
702
+
703
+ const isTypeOnlyImport = currentImport . node . importKind === 'type' ;
704
+ const isPreviousImportTypeOnlyImport = previousImport . node . importKind === 'type' ;
705
+
706
+ const isNormalImportFollowingTypeOnlyImportAndRelevant =
707
+ ! isTypeOnlyImport && isPreviousImportTypeOnlyImport && isSortingTypesAmongThemselves ;
708
+
709
+ const isTypeOnlyImportAndRelevant =
710
+ isTypeOnlyImport && isSortingTypesAmongThemselves ;
711
+
712
+ const isNotIgnored =
713
+ ( isTypeOnlyImportAndRelevant &&
714
+ newlinesBetweenTypeOnlyImports !== 'ignore' ) ||
715
+ ( ! isTypeOnlyImportAndRelevant && newlinesBetweenImports !== 'ignore' ) ;
716
+
717
+ if ( isNotIgnored ) {
718
+ const shouldAssertNewlineBetweenGroups =
719
+ ( ( isTypeOnlyImportAndRelevant || isNormalImportFollowingTypeOnlyImportAndRelevant ) &&
720
+ ( newlinesBetweenTypeOnlyImports === 'always' ||
721
+ newlinesBetweenTypeOnlyImports === 'always-and-inside-groups' ) ) ||
722
+ ( ( ! isTypeOnlyImportAndRelevant && ! isNormalImportFollowingTypeOnlyImportAndRelevant ) &&
723
+ ( newlinesBetweenImports === 'always' ||
724
+ newlinesBetweenImports === 'always-and-inside-groups' ) ) ;
725
+
726
+ const shouldAssertNoNewlineWithinGroup =
727
+ ( ( isTypeOnlyImportAndRelevant || isNormalImportFollowingTypeOnlyImportAndRelevant ) &&
728
+ ( newlinesBetweenTypeOnlyImports !== 'always-and-inside-groups' ) ) ||
729
+ ( ( ! isTypeOnlyImportAndRelevant && ! isNormalImportFollowingTypeOnlyImportAndRelevant ) &&
730
+ ( newlinesBetweenImports !== 'always-and-inside-groups' ) ) ;
731
+
732
+ const shouldAssertNoNewlineBetweenGroup =
733
+ ! isSortingTypesAmongThemselves ||
734
+ ! isNormalImportFollowingTypeOnlyImportAndRelevant ||
735
+ newlinesBetweenTypeOnlyImports === 'never' ;
736
+
737
+ if ( shouldAssertNewlineBetweenGroups ) {
738
+ if ( currentImport . rank !== previousImport . rank && emptyLinesBetween === 0 ) {
739
+ if ( distinctGroup || ! distinctGroup && isStartOfDistinctGroup ) {
740
+ context . report ( {
741
+ node : previousImport . node ,
742
+ message : 'There should be at least one empty line between import groups' ,
743
+ fix : fixNewLineAfterImport ( context , previousImport ) ,
744
+ } ) ;
745
+ }
746
+ } else if ( emptyLinesBetween > 0 && shouldAssertNoNewlineWithinGroup ) {
747
+ if (
748
+ ( distinctGroup && currentImport . rank === previousImport . rank ) ||
749
+ ( ! distinctGroup && ! isStartOfDistinctGroup )
750
+ ) {
751
+ context . report ( {
752
+ node : previousImport . node ,
753
+ message : 'There should be no empty line within import group' ,
754
+ fix : removeNewLineAfterImport ( context , currentImport , previousImport )
755
+ } ) ;
756
+ }
714
757
}
758
+ } else if ( emptyLinesBetween > 0 && shouldAssertNoNewlineBetweenGroup ) {
759
+ context . report ( {
760
+ node : previousImport . node ,
761
+ message : 'There should be no empty line between import groups' ,
762
+ fix : removeNewLineAfterImport ( context , currentImport , previousImport ) ,
763
+ } ) ;
715
764
}
716
- } else if ( emptyLinesBetween > 0 ) {
717
- context . report ( {
718
- node : previousImport . node ,
719
- message : 'There should be no empty line between import groups' ,
720
- fix : removeNewLineAfterImport ( context , currentImport , previousImport ) ,
721
- } ) ;
722
765
}
723
766
724
767
previousImport = currentImport ;
@@ -793,6 +836,14 @@ module.exports = {
793
836
'never' ,
794
837
] ,
795
838
} ,
839
+ 'newlines-between-types' : {
840
+ enum : [
841
+ 'ignore' ,
842
+ 'always' ,
843
+ 'always-and-inside-groups' ,
844
+ 'never' ,
845
+ ] ,
846
+ } ,
796
847
sortTypesAmongThemselves : {
797
848
type : 'boolean' ,
798
849
default : false ,
@@ -852,6 +903,7 @@ module.exports = {
852
903
create ( context ) {
853
904
const options = context . options [ 0 ] || { } ;
854
905
const newlinesBetweenImports = options [ 'newlines-between' ] || 'ignore' ;
906
+ const newlinesBetweenTypeOnlyImports = options [ 'newlines-between-types' ] || newlinesBetweenImports ;
855
907
const pathGroupsExcludedImportTypes = new Set ( options . pathGroupsExcludedImportTypes || [ 'builtin' , 'external' , 'object' ] ) ;
856
908
const sortTypesAmongThemselves = options . sortTypesAmongThemselves ;
857
909
@@ -1115,8 +1167,8 @@ module.exports = {
1115
1167
} ,
1116
1168
'Program:exit' ( ) {
1117
1169
importMap . forEach ( ( imported ) => {
1118
- if ( newlinesBetweenImports !== 'ignore' ) {
1119
- makeNewlinesBetweenReport ( context , imported , newlinesBetweenImports , distinctGroup ) ;
1170
+ if ( newlinesBetweenImports !== 'ignore' || newlinesBetweenTypeOnlyImports !== 'ignore' ) {
1171
+ makeNewlinesBetweenReport ( context , imported , newlinesBetweenImports , newlinesBetweenTypeOnlyImports , distinctGroup , isSortingTypesAmongThemselves ) ;
1120
1172
}
1121
1173
1122
1174
if ( alphabetize . order !== 'ignore' ) {
0 commit comments