Skip to content

Commit

Permalink
Add support for matching on TypeScript accessibility modifiers.
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanrsmith committed Dec 2, 2022
1 parent f41029b commit 39bb41b
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ Members can be matched to positional slots using several criteria, including nam
- `accessorPair`: `true|false`. True to match only getters and setters that are part of a pair. i.e., only those that have both `get` and `set` methods defined.
- `static`: `true|false` to restrict the match to static or instance members.
- `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).
- `accessibility`: `"public"|"private"|"protected"` to restrict the match to members with the specified typescript accessibility modifier. **Note**: Requires `@typescript-eslint/parser`.
- `async`: `true|false` to restrict the match to async members.
- `sort`: `"alphabetical"|"none"`. Used to require a specific sorting within the slot for matched members. Defaults to `"none"`.
- `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).
Expand Down
1 change: 1 addition & 0 deletions src/rules/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const sortClassMembersSchema = [
static: { type: 'boolean' },
private: { type: 'boolean' },
async: { type: 'boolean' },
accessibility: { enum: ['public', 'private', 'protected'] },
},
additionalProperties: false,
},
Expand Down
3 changes: 3 additions & 0 deletions src/rules/sort-class-members.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ function getMemberInfo(node, sourceCode) {
let propertyType;
let async = false;
let decorators = [];
const accessibility = node.accessibility ?? 'public';

decorators =
(!!node.decorators &&
Expand Down Expand Up @@ -218,6 +219,7 @@ function getMemberInfo(node, sourceCode) {
static: node.static,
async,
private: isPrivate,
accessibility,
kind: node.kind,
propertyType,
node,
Expand Down Expand Up @@ -418,6 +420,7 @@ const comparers = [
{ property: 'static', value: 10, test: (m, s) => s.static === m.static },
{ property: 'async', value: 10, test: (m, s) => s.async === m.async },
{ property: 'private', value: 10, test: (m, s) => s.private === m.private },
{ property: 'accessibility', value: 10, test: (m, s) => s.accessibility == m.accessibility },
{ property: 'kind', value: 10, test: (m, s) => s.kind === m.kind },
{
property: 'groupByDecorator',
Expand Down
54 changes: 54 additions & 0 deletions test/rules/sort-class-members.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,24 @@ const privateRegexpOptions = [
},
];

const typescriptAccessibilityOptions = [
{
groups: {
private: [
{
accessibility: 'private',
},
],
public: [
{
accessibility: 'public',
},
],
},
order: ['[private]', 'constructor', '[public]'],
},
];

ruleTester.run('sort-class-members', rule, {
valid: [
{ code: 'class A {}', options: defaultOptions },
Expand Down Expand Up @@ -344,6 +362,18 @@ ruleTester.run('sort-class-members', rule, {
// Class expressions
{ code: 'module.exports = class A {}', options: defaultOptions },
{ code: 'class { [k: string]: any; }', parser: require.resolve('@typescript-eslint/parser') },

// TS accessibility
{
code: 'class { private a: any; constructor(){} b(){} }',
options: typescriptAccessibilityOptions,
parser: require.resolve('@typescript-eslint/parser'),
},
{
code: 'class { private a: any; constructor(){} public b(){} c(){} }',
options: typescriptAccessibilityOptions,
parser: require.resolve('@typescript-eslint/parser'),
},
],
invalid: [
{
Expand Down Expand Up @@ -832,6 +862,30 @@ ruleTester.run('sort-class-members', rule, {
options: privateRegexpOptions,
},
]),
{
code: 'class { constructor(){} private b: any; }',
output: 'class { private b: any; constructor(){} }',
errors: [
{
message: 'Expected property b to come before constructor.',
type: 'PropertyDefinition',
},
],
options: typescriptAccessibilityOptions,
parser: require.resolve('@typescript-eslint/parser'),
},
{
code: 'class { a(){} private b: any; }',
output: 'class { private b: any; a(){} }',
errors: [
{
message: 'Expected property b to come before method a.',
type: 'PropertyDefinition',
},
],
options: typescriptAccessibilityOptions,
parser: require.resolve('@typescript-eslint/parser'),
},
],
});

Expand Down

0 comments on commit 39bb41b

Please sign in to comment.