Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(eslint-plugin): [naming-convention] add support for #private modifier on class members #6259

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions packages/eslint-plugin/docs/rules/naming-convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ If these are provided, the identifier must start with one of the provided values
- Accepts one or array of selectors to define an option block that applies to one or multiple selectors.
- For example, if you provide `{ selector: ['function', 'variable'] }`, then it will apply the same option to variable and function nodes.
- See [Allowed Selectors, Modifiers and Types](#allowed-selectors-modifiers-and-types) below for the complete list of allowed selectors.
- `modifiers` allows you to specify which modifiers to granularly apply to, such as the accessibility (`private`/`protected`/`public`), or if the thing is `static`, etc.
- `modifiers` allows you to specify which modifiers to granularly apply to, such as the accessibility (`#private`/`private`/`protected`/`public`), or if the thing is `static`, etc.
- The name must match _all_ of the modifiers.
- For example, if you provide `{ modifiers: ['private','readonly','static'] }`, then it will only match something that is `private static readonly`, and something that is just `private` will not match.
- The following `modifiers` are allowed:
Expand All @@ -172,6 +172,7 @@ If these are provided, the identifier must start with one of the provided values
- `requiresQuotes` - matches any name that requires quotes as it is not a valid identifier (i.e. has a space, a dash, etc in it).
- `public` - matches any member that is either explicitly declared as `public`, or has no visibility modifier (i.e. implicitly public).
- `abstract`,`override`,`private`,`protected`,`readonly`,`static` - matches any member explicitly declared with the given modifier.
- `#private` - matches any member with a private identifier (an identifier that starts with `#`)
- `async` - matches any method, function, or function variable which is async via the `async` keyword (e.g. does not match functions that return promises without using `async` keyword)
- `types` allows you to specify which types to match. This option supports simple, primitive types only (`array`,`boolean`,`function`,`number`,`string`).
- The name must match _one_ of the types.
Expand Down Expand Up @@ -204,7 +205,7 @@ Individual Selectors match specific, well-defined sets. There is no overlap betw
- Allowed `modifiers`: `destructured`, `unused`.
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
- `classProperty` - matches any class property. Does not match properties that have direct function expression or arrow function expression values.
- Allowed `modifiers`: `abstract`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `modifiers`: `abstract`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `types`: `array`, `boolean`, `function`, `number`, `string`.
- `objectLiteralProperty` - matches any object literal property. Does not match properties that have direct function expression or arrow function expression values.
- Allowed `modifiers`: `public`, `requiresQuotes`.
Expand All @@ -216,7 +217,7 @@ Individual Selectors match specific, well-defined sets. There is no overlap betw
- Allowed `modifiers`: `private`, `protected`, `public`, `readonly`.
- Allowed `types`: `array`, `boolean`, `function`, `number`, `string`.
- `classMethod` - matches any class method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors.
- Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `requiresQuotes`, `static`.
- Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `requiresQuotes`, `static`.
- Allowed `types`: none.
- `objectLiteralMethod` - matches any object literal method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors.
- Allowed `modifiers`: `async`, `public`, `requiresQuotes`.
Expand Down Expand Up @@ -257,16 +258,16 @@ Group Selectors are provided for convenience, and essentially bundle up sets of
- Allowed `modifiers`: `async`, `unused`.
- Allowed `types`: none.
- `memberLike` - matches the same as `accessor`, `enumMember`, `method`, `parameterProperty`, `property`.
- Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `types`: none.
- `typeLike` - matches the same as `class`, `enum`, `interface`, `typeAlias`, `typeParameter`.
- Allowed `modifiers`: `abstract`, `unused`.
- Allowed `types`: none.
- `property` - matches the same as `classProperty`, `objectLiteralProperty`, `typeProperty`.
- Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `types`: `array`, `boolean`, `function`, `number`, `string`.
- `method` - matches the same as `classMethod`, `objectLiteralMethod`, `typeMethod`.
- Allowed `modifiers`: `abstract`, `async`, `override`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `modifiers`: `abstract`, `async`, `override`, `#private`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
- Allowed `types`: none.

## FAQ
Expand Down
27 changes: 14 additions & 13 deletions packages/eslint-plugin/src/rules/naming-convention-utils/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,33 @@ enum Modifiers {
public = 1 << 3,
protected = 1 << 4,
private = 1 << 5,
abstract = 1 << 6,
'#private' = 1 << 6,
abstract = 1 << 7,
// destructured variable
destructured = 1 << 7,
destructured = 1 << 8,
// variables declared in the top-level scope
global = 1 << 8,
global = 1 << 9,
// things that are exported
exported = 1 << 9,
exported = 1 << 10,
// things that are unused
unused = 1 << 10,
unused = 1 << 11,
// properties that require quoting
requiresQuotes = 1 << 11,
requiresQuotes = 1 << 12,
// class members that are overridden
override = 1 << 12,
override = 1 << 13,
// class methods, object function properties, or functions that are async via the `async` keyword
async = 1 << 13,
async = 1 << 14,

// make sure TypeModifiers starts at Modifiers + 1 or else sorting won't work
}
type ModifiersString = keyof typeof Modifiers;

enum TypeModifiers {
boolean = 1 << 12,
string = 1 << 13,
number = 1 << 14,
function = 1 << 15,
array = 1 << 16,
boolean = 1 << 15,
string = 1 << 16,
number = 1 << 17,
function = 1 << 18,
array = 1 << 19,
}
type TypeModifiersString = keyof typeof TypeModifiers;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
...selectorSchema('memberLike', false, [
'abstract',
'private',
'#private',
'protected',
'public',
'readonly',
Expand All @@ -201,6 +202,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
...selectorSchema('classProperty', true, [
'abstract',
'private',
'#private',
'protected',
'public',
'readonly',
Expand All @@ -226,6 +228,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
...selectorSchema('property', true, [
'abstract',
'private',
'#private',
'protected',
'public',
'readonly',
Expand All @@ -238,6 +241,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
...selectorSchema('classMethod', false, [
'abstract',
'private',
'#private',
'protected',
'public',
'requiresQuotes',
Expand All @@ -254,6 +258,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
...selectorSchema('method', false, [
'abstract',
'private',
'#private',
'protected',
'public',
'requiresQuotes',
Expand Down
4 changes: 3 additions & 1 deletion packages/eslint-plugin/src/rules/naming-convention.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ export default util.createRule<Options, MessageIds>({
| TSESTree.TSParameterProperty,
): Set<Modifiers> {
const modifiers = new Set<Modifiers>();
if (node.accessibility) {
if ('key' in node && node.key.type === AST_NODE_TYPES.PrivateIdentifier) {
modifiers.add(Modifiers['#private']);
} else if (node.accessibility) {
modifiers.add(Modifiers[node.accessibility]);
} else {
modifiers.add(Modifiers.public);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,29 @@ ruleTester.run('naming-convention', rule, {
},
],
},
{
code: `
class foo {
private someAttribute = 1;
#some_attribute = 1;

private someMethod() {}
#some_method() {}
}
`,
parserOptions,
options: [
{
selector: 'memberLike',
format: ['camelCase'],
},
{
selector: ['memberLike'],
modifiers: ['#private'],
format: ['snake_case'],
},
],
},
],
invalid: [
{
Expand Down Expand Up @@ -1972,5 +1995,89 @@ ruleTester.run('naming-convention', rule, {
},
],
},
{
code: `
class foo {
private firstPrivateField = 1;
// ❌ error
private first_private_field = 1;
// ❌ error
#secondPrivateField = 1;
#second_private_field = 1;
}
`,
parserOptions,
options: [
{
selector: 'memberLike',
format: ['camelCase'],
},
{
selector: ['memberLike'],
modifiers: ['#private'],
format: ['snake_case'],
},
],
errors: [
{
messageId: 'doesNotMatchFormat',
data: {
type: 'Class Property',
name: 'first_private_field',
formats: 'camelCase',
},
},
{
messageId: 'doesNotMatchFormat',
data: {
type: 'Class Property',
name: 'secondPrivateField',
formats: 'snake_case',
},
},
],
},
{
code: `
class foo {
private firstPrivateMethod() {}
// ❌ error
private first_private_method() {}
// ❌ error
#secondPrivateMethod() {}
#second_private_method() {}
}
`,
parserOptions,
options: [
{
selector: 'memberLike',
format: ['camelCase'],
},
{
selector: ['memberLike'],
modifiers: ['#private'],
format: ['snake_case'],
},
],
errors: [
{
messageId: 'doesNotMatchFormat',
data: {
type: 'Class Method',
name: 'first_private_method',
formats: 'camelCase',
},
},
{
messageId: 'doesNotMatchFormat',
data: {
type: 'Class Method',
name: 'secondPrivateMethod',
formats: 'snake_case',
},
},
],
},
],
});