Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(eslint-plugin): [member-ordering] report alphabetical sorting for all groups instead of just the first failing group #8263

Merged
merged 11 commits into from Mar 6, 2024
76 changes: 72 additions & 4 deletions packages/eslint-plugin/src/rules/member-ordering.ts
Expand Up @@ -615,6 +615,59 @@ function getRank(
return getRankOrder(memberGroups, orderConfig);
}

/**
* Groups members into arrays of consecutive members with the same rank.
* If, for example, the memberSet parameter looks like the following...
* @example
* ```
* interface Foo {
* [a: string]: number;
*
* a: x;
* B: x;
* c: x;
*
* c(): void;
* B(): void;
* a(): void;
*
* (): Baz;
*
* new (): Bar;
* }
* ```
* ...the resulting array will look like: [[a, B, c], [c, B, a]].
* @param memberSet The members to be grouped.
* @param memberType The configured order of member types.
* @param supportsModifiers It'll get passed to getRank().
* @returns The array of groups of members.
*/
function groupMembersByType(
members: Member[],
memberTypes: MemberType[],
supportsModifiers: boolean,
): Member[][] {
const groupedMembers: Member[][] = [];
const memberRanks = members.map(member =>
getRank(member, memberTypes, supportsModifiers),
);
let previousRank: number | undefined = undefined;
members.forEach((member, index) => {
if (index === members.length - 1) {
return;
}
const rankOfCurrentMember = memberRanks[index];
const rankOfNextMember = memberRanks[index + 1];
if (rankOfCurrentMember === previousRank) {
groupedMembers.at(-1)?.push(member);
} else if (rankOfCurrentMember === rankOfNextMember) {
groupedMembers.push([member]);
previousRank = rankOfCurrentMember;
}
});
return groupedMembers;
}

/**
* Gets the lowest possible rank(s) higher than target.
* e.g. given the following order:
Expand Down Expand Up @@ -934,6 +987,21 @@ export default createRule<Options, MessageIds>({
let memberTypes: MemberType[] | string | undefined;
let optionalityOrder: OptionalityOrder | undefined;

/**
* It runs an alphabetic sort on the groups of the members of the class in the source code.
* @param memberSet The members in the class of the source code on which the grouping operation will be performed.
*/
const checkAlphaSortForAllMembers = (memberSet: Member[]): undefined => {
const hasAlphaSort = !!(order && order !== 'as-written');
if (hasAlphaSort && Array.isArray(memberTypes)) {
groupMembersByType(memberSet, memberTypes, supportsModifiers).forEach(
members => {
checkAlphaSort(members, order as AlphabeticalOrder);
},
);
}
};

// returns true if everything is good and false if an error was reported
const checkOrder = (memberSet: Member[]): boolean => {
const hasAlphaSort = !!(order && order !== 'as-written');
Expand All @@ -947,20 +1015,20 @@ export default createRule<Options, MessageIds>({
);

if (grouped == null) {
checkAlphaSortForAllMembers(members);
return false;
}

if (hasAlphaSort) {
return !grouped.some(
groupMember =>
!checkAlphaSort(groupMember, order as AlphabeticalOrder),
grouped.map(groupMember =>
checkAlphaSort(groupMember, order as AlphabeticalOrder),
);
}
} else if (hasAlphaSort) {
return checkAlphaSort(memberSet, order as AlphabeticalOrder);
}

return true;
return false;
};

if (Array.isArray(orderConfig)) {
Expand Down
Expand Up @@ -542,6 +542,20 @@ interface Foo {
},
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'B',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'B',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -587,6 +601,20 @@ type Foo = {
},
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'B',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'B',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -626,6 +654,20 @@ class Foo {
},
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'B',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'B',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -658,6 +700,20 @@ const foo = class Foo {
},
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'B',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'B',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down
Expand Up @@ -1856,6 +1856,20 @@ interface Foo {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -1896,6 +1910,20 @@ type Foo = {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -1930,6 +1958,20 @@ class Foo {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -1957,6 +1999,20 @@ const foo = class Foo {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -1999,6 +2055,13 @@ class Foo {
},
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'a2',
beforeMember: 'a3',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -2145,6 +2208,20 @@ class Foo {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -2290,6 +2367,20 @@ const foo = class Foo {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -2443,6 +2534,20 @@ interface Foo {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down Expand Up @@ -2603,6 +2708,20 @@ type Foo = {
{ default: { memberTypes: defaultOrder, order: 'alphabetically' } },
],
errors: [
{
messageId: 'incorrectOrder',
data: {
member: 'b',
beforeMember: 'c',
},
},
{
messageId: 'incorrectOrder',
data: {
member: 'a',
beforeMember: 'b',
},
},
{
messageId: 'incorrectGroupOrder',
data: {
Expand Down
Expand Up @@ -122,6 +122,15 @@ interface Example {
line: 10,
messageId: 'incorrectOrder',
},
{
column: 3,
data: {
beforeMember: 'B1',
member: 'a1',
},
line: 15,
messageId: 'incorrectOrder',
},
],
options: [
{
Expand Down