Skip to content

Commit 4b0d4b3

Browse files
authored
Add support for abstract, override and readonly (#83)
Add support for matching by TypeScript abstract, override and readonly modifiers
1 parent f457afa commit 4b0d4b3

File tree

4 files changed

+80
-0
lines changed

4 files changed

+80
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ Members can be matched to positional slots using several criteria, including nam
105105
- `static`: `true|false` to restrict the match to static or instance members.
106106
- `private`: `true|false` to restrict the match to [private members](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields). **Note**: Private members currently require a custom parser like [babel-eslint](https://github.com/babel/babel-eslint).
107107
- `accessibility`: `"public"|"private"|"protected"` to restrict the match to members with the specified typescript accessibility modifier. **Note**: Requires `@typescript-eslint/parser`.
108+
- `abstract`: `true|false` to restrict the match to members with typescript `abstract` keyword.
109+
- `override`: `true|false` to restrict the match to members with typescript `override` keyword.
110+
- `readonly`: `true|false` to restrict the match to members with typescript `readonly` keyword.
108111
- `async`: `true|false` to restrict the match to async members.
109112
- `sort`: `"alphabetical"|"none"`. Used to require a specific sorting within the slot for matched members. Defaults to `"none"`.
110113
- `groupByDecorator`: a string used to group properties with the same decorator name (e.g. `observable` for `@observable`). Can be used together with `sort`. **Note**: Decorators are a Stage 2 proposal and require a custom parser like [babel-eslint](https://github.com/babel/babel-eslint).

src/rules/schema.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ export const sortClassMembersSchema = [
4040
private: { type: 'boolean' },
4141
async: { type: 'boolean' },
4242
accessibility: { enum: ['public', 'private', 'protected'] },
43+
abstract: { type: 'boolean' },
44+
override: { type: 'boolean' },
45+
readonly: { type: 'boolean' },
4346
},
4447
additionalProperties: false,
4548
},

src/rules/sort-class-members.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ function getMemberInfo(node, sourceCode) {
176176
let async = false;
177177
let decorators = [];
178178
const accessibility = node.accessibility ?? 'public';
179+
const abstract =
180+
node.type === 'TSAbstractAccessorProperty' ||
181+
node.type === 'TSAbstractPropertyDefinition' ||
182+
node.type === 'TSAbstractMethodDefinition';
179183

180184
decorators =
181185
(!!node.decorators &&
@@ -217,6 +221,9 @@ function getMemberInfo(node, sourceCode) {
217221
type,
218222
decorators,
219223
static: node.static,
224+
abstract,
225+
override: node.override,
226+
readonly: !!node.readonly,
220227
async,
221228
private: isPrivate,
222229
accessibility,
@@ -421,6 +428,9 @@ const comparers = [
421428
{ property: 'async', value: 10, test: (m, s) => s.async === m.async },
422429
{ property: 'private', value: 10, test: (m, s) => s.private === m.private },
423430
{ property: 'accessibility', value: 10, test: (m, s) => s.accessibility == m.accessibility },
431+
{ property: 'abstract', value: 10, test: (m, s) => s.abstract == m.abstract },
432+
{ property: 'override', value: 10, test: (m, s) => s.override == m.override },
433+
{ property: 'readonly', value: 10, test: (m, s) => s.readonly == m.readonly },
424434
{ property: 'kind', value: 10, test: (m, s) => s.kind === m.kind },
425435
{
426436
property: 'groupByDecorator',

test/rules/sort-class-members.spec.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,29 @@ const typescriptAccessibilityOptions = [
254254
},
255255
];
256256

257+
const typescriptKeywordsOptions = [
258+
{
259+
groups: {
260+
abstract: [
261+
{
262+
abstract: true,
263+
},
264+
],
265+
override: [
266+
{
267+
override: true,
268+
},
269+
],
270+
readonly: [
271+
{
272+
readonly: true,
273+
},
274+
],
275+
},
276+
order: ['[override]', '[readonly]', '[abstract]'],
277+
},
278+
];
279+
257280
ruleTester.run('sort-class-members', rule, {
258281
valid: [
259282
{ code: 'class A {}', options: defaultOptions },
@@ -374,6 +397,11 @@ ruleTester.run('sort-class-members', rule, {
374397
options: typescriptAccessibilityOptions,
375398
parser: require.resolve('@typescript-eslint/parser'),
376399
},
400+
{
401+
code: 'class { override a: any; readonly b = true; abstract c: () => {} }',
402+
options: typescriptKeywordsOptions,
403+
parser: require.resolve('@typescript-eslint/parser'),
404+
},
377405
],
378406
invalid: [
379407
{
@@ -886,6 +914,42 @@ ruleTester.run('sort-class-members', rule, {
886914
options: typescriptAccessibilityOptions,
887915
parser: require.resolve('@typescript-eslint/parser'),
888916
},
917+
{
918+
code: 'class { abstract a; override b; }',
919+
output: 'class { override b; abstract a; }',
920+
errors: [
921+
{
922+
message: 'Expected property b to come before method a.',
923+
type: 'PropertyDefinition',
924+
},
925+
],
926+
options: typescriptKeywordsOptions,
927+
parser: require.resolve('@typescript-eslint/parser'),
928+
},
929+
{
930+
code: 'class { readonly a; override b; }',
931+
output: 'class { override b; readonly a; }',
932+
errors: [
933+
{
934+
message: 'Expected property b to come before property a.',
935+
type: 'PropertyDefinition',
936+
},
937+
],
938+
options: typescriptKeywordsOptions,
939+
parser: require.resolve('@typescript-eslint/parser'),
940+
},
941+
{
942+
code: 'class { abstract a(); readonly b; }',
943+
output: 'class { readonly b; abstract a(); }',
944+
errors: [
945+
{
946+
message: 'Expected property b to come before method a.',
947+
type: 'PropertyDefinition',
948+
},
949+
],
950+
options: typescriptKeywordsOptions,
951+
parser: require.resolve('@typescript-eslint/parser'),
952+
},
889953
],
890954
});
891955

0 commit comments

Comments
 (0)