Skip to content

Commit 5afa43a

Browse files
committed
fix: ensure consolidateIslands overrides both newlines-between and newlines-between-types when in conflict
1 parent 630ffef commit 5afa43a

File tree

3 files changed

+188
-11
lines changed

3 files changed

+188
-11
lines changed

docs/rules/order.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -738,16 +738,18 @@ When set to `"inside-groups"`, this ensures imports spanning multiple lines are
738738
>
739739
> When all of the following are true:
740740
>
741-
> - `consolidateIslands` is set to `"inside-groups"`
742-
> - [`newlines-between`][20] is set to `"always-and-inside-groups"`
743-
> - [`newlines-between-types`][27] is set to `"never"`
744741
> - [`sortTypesGroup`][7] is set to `true`
742+
> - `consolidateIslands` is set to `"inside-groups"`
743+
> - [`newlines-between`][20] is set to `"always-and-inside-groups"` when [`newlines-between-types`][27] is set to `"never"` (or vice-versa)
745744
>
746-
> Then [`newlines-between-types`][27] will yield to `consolidateIslands` and allow new lines to separate multi-line imports and a single new line to separate all [type-only imports][6] from all normal imports. Other than that, [`newlines-between-types: "never"`][27] functions as described.
745+
> Then [`newlines-between`][20]/[`newlines-between-types`][27] will yield to
746+
> `consolidateIslands` and allow new lines to separate multi-line imports
747+
> regardless of the `"never"` setting.
747748
>
748-
> This configuration is useful to keep type-only imports stacked tightly
749-
> together at the bottom of your import block to preserve space while still
750-
> logically organizing normal imports for quick and pleasant reference.
749+
> This configuration is useful, for instance, to keep single-line type-only
750+
> imports stacked tightly together at the bottom of your import block to
751+
> preserve space while still logically organizing normal imports for quick and
752+
> pleasant reference.
751753
752754
#### Example
753755

src/rules/order.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ function removeNewLineAfterImport(context, currentImport, previousImport) {
691691
return undefined;
692692
}
693693

694-
function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports, newlinesBetweenTypeOnlyImports_, distinctGroup, isSortingTypesGroup, isConsolidatingSpaceBetweenImports) {
694+
function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports_, newlinesBetweenTypeOnlyImports_, distinctGroup, isSortingTypesGroup, isConsolidatingSpaceBetweenImports) {
695695
const getNumberOfEmptyLinesBetween = (currentImport, previousImport) => {
696696
const linesBetweenImports = getSourceCode(context).lines.slice(
697697
previousImport.node.loc.end.line,
@@ -721,14 +721,23 @@ function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports, ne
721721

722722
const isTypeOnlyImportAndRelevant = isTypeOnlyImport && isSortingTypesGroup;
723723

724+
// In the special case where newlinesBetweenImports and consolidateIslands
725+
// want the opposite thing, consolidateIslands wins
726+
const newlinesBetweenImports = isSortingTypesGroup
727+
&& isConsolidatingSpaceBetweenImports
728+
&& (previousImport.isMultiline || currentImport.isMultiline)
729+
&& newlinesBetweenImports_ === 'never'
730+
? 'always-and-inside-groups'
731+
: newlinesBetweenImports_;
732+
724733
// In the special case where newlinesBetweenTypeOnlyImports and
725734
// consolidateIslands want the opposite thing, consolidateIslands wins
726-
const newlinesBetweenTypeOnlyImports = newlinesBetweenTypeOnlyImports_ === 'never'
735+
const newlinesBetweenTypeOnlyImports = isSortingTypesGroup
727736
&& isConsolidatingSpaceBetweenImports
728-
&& isSortingTypesGroup
729737
&& (isNormalImportNextToTypeOnlyImportAndRelevant
730738
|| previousImport.isMultiline
731739
|| currentImport.isMultiline)
740+
&& newlinesBetweenTypeOnlyImports_ === 'never'
732741
? 'always-and-inside-groups'
733742
: newlinesBetweenTypeOnlyImports_;
734743

tests/src/rules/order.js

+167-1
Original file line numberDiff line numberDiff line change
@@ -4158,7 +4158,7 @@ context('TypeScript', function () {
41584158
},
41594159
],
41604160
}),
4161-
// Ensure consolidateOptions: 'inside-groups', newlines-between: 'always-and-inside-groups', and newlines-between-types: 'never' do not fight for dominance
4161+
// Ensure consolidateIslands: 'inside-groups', newlines-between: 'always-and-inside-groups', and newlines-between-types: 'never' do not fight for dominance
41624162
test({
41634163
code: `
41644164
import makeVanillaYargs from 'yargs/yargs';
@@ -4228,6 +4228,172 @@ context('TypeScript', function () {
42284228
},
42294229
],
42304230
}),
4231+
// Ensure consolidateIslands: 'inside-groups', newlines-between: 'never', and newlines-between-types: 'always-and-inside-groups' do not fight for dominance
4232+
test({
4233+
code: `
4234+
import makeVanillaYargs from 'yargs/yargs';
4235+
import { createDebugLogger } from 'multiverse+rejoinder';
4236+
import { globalDebuggerNamespace } from 'rootverse+bfe:src/constant.ts';
4237+
import { ErrorMessage, type KeyValueEntry } from 'rootverse+bfe:src/error.ts';
4238+
import { $artificiallyInvoked } from 'rootverse+bfe:src/symbols.ts';
4239+
4240+
import type {
4241+
Entries,
4242+
LiteralUnion,
4243+
OmitIndexSignature,
4244+
Promisable,
4245+
StringKeyOf
4246+
} from 'type-fest';
4247+
`,
4248+
...parserConfig,
4249+
options: [
4250+
{
4251+
alphabetize: {
4252+
order: 'asc',
4253+
orderImportKind: 'asc',
4254+
caseInsensitive: true,
4255+
},
4256+
named: {
4257+
enabled: true,
4258+
types: 'types-last',
4259+
},
4260+
groups: [
4261+
'builtin',
4262+
'external',
4263+
'internal',
4264+
['parent', 'sibling', 'index'],
4265+
['object', 'type'],
4266+
],
4267+
pathGroups: [
4268+
{
4269+
pattern: 'multiverse{*,*/**}',
4270+
group: 'external',
4271+
position: 'after',
4272+
},
4273+
{
4274+
pattern: 'rootverse{*,*/**}',
4275+
group: 'external',
4276+
position: 'after',
4277+
},
4278+
{
4279+
pattern: 'universe{*,*/**}',
4280+
group: 'external',
4281+
position: 'after',
4282+
},
4283+
],
4284+
distinctGroup: true,
4285+
pathGroupsExcludedImportTypes: ['builtin', 'object'],
4286+
'newlines-between': 'never',
4287+
'newlines-between-types': 'always-and-inside-groups',
4288+
sortTypesGroup: true,
4289+
consolidateIslands: 'inside-groups',
4290+
},
4291+
],
4292+
}),
4293+
test({
4294+
code: `
4295+
import c from 'Bar';
4296+
import d from 'bar';
4297+
4298+
import {
4299+
aa,
4300+
bb,
4301+
cc,
4302+
dd,
4303+
ee,
4304+
ff,
4305+
gg
4306+
} from 'baz';
4307+
4308+
import {
4309+
hh,
4310+
ii,
4311+
jj,
4312+
kk,
4313+
ll,
4314+
mm,
4315+
nn
4316+
} from 'fizz';
4317+
4318+
import a from 'foo';
4319+
import b from 'dirA/bar';
4320+
import index from './';
4321+
4322+
import type { AA,
4323+
BB, CC } from 'abc';
4324+
4325+
import type { Z } from 'fizz';
4326+
4327+
import type {
4328+
A,
4329+
B
4330+
} from 'foo';
4331+
4332+
import type { C2 } from 'dirB/Bar';
4333+
4334+
import type {
4335+
D2,
4336+
X2,
4337+
Y2
4338+
} from 'dirB/bar';
4339+
4340+
import type { E2 } from 'dirB/baz';
4341+
4342+
import type { C3 } from 'dirC/Bar';
4343+
4344+
import type {
4345+
D3,
4346+
X3,
4347+
Y3
4348+
} from 'dirC/bar';
4349+
4350+
import type { E3 } from 'dirC/baz';
4351+
import type { F3 } from 'dirC/caz';
4352+
4353+
import type { C1 } from 'dirA/Bar';
4354+
4355+
import type {
4356+
D1,
4357+
X1,
4358+
Y1
4359+
} from 'dirA/bar';
4360+
4361+
import type { E1 } from 'dirA/baz';
4362+
4363+
import type { F } from './index.js';
4364+
4365+
import type { G } from './aaa.js';
4366+
import type { H } from './bbb';
4367+
`,
4368+
...parserConfig,
4369+
options: [
4370+
{
4371+
alphabetize: { order: 'asc' },
4372+
groups: ['external', 'internal', 'index', 'type'],
4373+
pathGroups: [
4374+
{
4375+
pattern: 'dirA/**',
4376+
group: 'internal',
4377+
position: 'after',
4378+
},
4379+
{
4380+
pattern: 'dirB/**',
4381+
group: 'internal',
4382+
position: 'before',
4383+
},
4384+
{
4385+
pattern: 'dirC/**',
4386+
group: 'internal',
4387+
},
4388+
],
4389+
'newlines-between': 'never',
4390+
'newlines-between-types': 'always-and-inside-groups',
4391+
pathGroupsExcludedImportTypes: [],
4392+
sortTypesGroup: true,
4393+
consolidateIslands: 'inside-groups',
4394+
},
4395+
],
4396+
}),
42314397
test({
42324398
code: `
42334399
import assert from 'assert';

0 commit comments

Comments
 (0)