Skip to content

Commit c759da1

Browse files
feat(eslint-plugin): [naming-convention] add support for "override" and "async" modifiers (#5310) (#5610)
* feat(eslint-plugin): [naming-convention] add support for "override" and "async" modifiers (#5310) * apply pr feedback ie remove test case util, split tests by type, remove abstract getter change, remove override for variable selector in docs * remove async parameter logic which is impossible Co-authored-by: Josh Goldberg <[email protected]>
1 parent 923d486 commit c759da1

File tree

5 files changed

+530
-13
lines changed

5 files changed

+530
-13
lines changed

Diff for: packages/eslint-plugin/docs/rules/naming-convention.md

+12-11
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ If these are provided, the identifier must start with one of the provided values
171171
- `unused` - matches anything that is not used.
172172
- `requiresQuotes` - matches any name that requires quotes as it is not a valid identifier (i.e. has a space, a dash, etc in it).
173173
- `public` - matches any member that is either explicitly declared as `public`, or has no visibility modifier (i.e. implicitly public).
174-
- `readonly`, `static`, `abstract`, `protected`, `private` - matches any member explicitly declared with the given modifier.
174+
- `readonly`, `static`, `abstract`, `protected`, `private`, `override` - matches any member explicitly declared with the given modifier.
175+
- `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)
175176
- `types` allows you to specify which types to match. This option supports simple, primitive types only (`boolean`, `string`, `number`, `array`, `function`).
176177
- The name must match _one_ of the types.
177178
- **_NOTE - Using this option will require that you lint with type information._**
@@ -194,16 +195,16 @@ There are two types of selectors, individual selectors, and grouped selectors.
194195
Individual Selectors match specific, well-defined sets. There is no overlap between each of the individual selectors.
195196

196197
- `variable` - matches any `var` / `let` / `const` variable name.
197-
- Allowed `modifiers`: `const`, `destructured`, `global`, `exported`, `unused`.
198+
- Allowed `modifiers`: `const`, `destructured`, `global`, `exported`, `unused`, `async`.
198199
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
199200
- `function` - matches any named function declaration or named function expression.
200-
- Allowed `modifiers`: `global`, `exported`, `unused`.
201+
- Allowed `modifiers`: `global`, `exported`, `unused`, `async`.
201202
- Allowed `types`: none.
202203
- `parameter` - matches any function parameter. Does not match parameter properties.
203204
- Allowed `modifiers`: `destructured`, `unused`.
204205
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
205206
- `classProperty` - matches any class property. Does not match properties that have direct function expression or arrow function expression values.
206-
- Allowed `modifiers`: `abstract`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`.
207+
- Allowed `modifiers`: `abstract`, `private`, `protected`, `public`, `readonly`, `requiresQuotes`, `static`, `override`.
207208
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
208209
- `objectLiteralProperty` - matches any object literal property. Does not match properties that have direct function expression or arrow function expression values.
209210
- Allowed `modifiers`: `public`, `requiresQuotes`.
@@ -215,16 +216,16 @@ Individual Selectors match specific, well-defined sets. There is no overlap betw
215216
- Allowed `modifiers`: `private`, `protected`, `public`, `readonly`.
216217
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
217218
- `classMethod` - matches any class method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors.
218-
- Allowed `modifiers`: `abstract`, `private`, `protected`, `public`, `requiresQuotes`, `static`.
219+
- Allowed `modifiers`: `abstract`, `private`, `protected`, `public`, `requiresQuotes`, `static`, `override`, `async`.
219220
- Allowed `types`: none.
220221
- `objectLiteralMethod` - matches any object literal method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors.
221-
- Allowed `modifiers`: `public`, `requiresQuotes`.
222+
- Allowed `modifiers`: `public`, `requiresQuotes`, `async`.
222223
- Allowed `types`: none.
223224
- `typeMethod` - matches any object type method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors.
224225
- Allowed `modifiers`: `public`, `requiresQuotes`.
225226
- Allowed `types`: none.
226227
- `accessor` - matches any accessor.
227-
- Allowed `modifiers`: `abstract`, `private`, `protected`, `public`, `requiresQuotes`, `static`.
228+
- Allowed `modifiers`: `abstract`, `private`, `protected`, `public`, `requiresQuotes`, `static`, `override`.
228229
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
229230
- `enumMember` - matches any enum member.
230231
- Allowed `modifiers`: `requiresQuotes`.
@@ -253,19 +254,19 @@ Group Selectors are provided for convenience, and essentially bundle up sets of
253254
- Allowed `modifiers`: all modifiers.
254255
- Allowed `types`: none.
255256
- `variableLike` - matches the same as `variable`, `function` and `parameter`.
256-
- Allowed `modifiers`: `unused`.
257+
- Allowed `modifiers`: `unused`, `async`.
257258
- Allowed `types`: none.
258259
- `memberLike` - matches the same as `property`, `parameterProperty`, `method`, `accessor`, `enumMember`.
259-
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`, `requiresQuotes`.
260+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`, `requiresQuotes`, `override`, `async`.
260261
- Allowed `types`: none.
261262
- `typeLike` - matches the same as `class`, `interface`, `typeAlias`, `enum`, `typeParameter`.
262263
- Allowed `modifiers`: `abstract`, `unused`.
263264
- Allowed `types`: none.
264265
- `property` - matches the same as `classProperty`, `objectLiteralProperty`, `typeProperty`.
265-
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`, `requiresQuotes`.
266+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`, `requiresQuotes`, `override`, `async`.
266267
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
267268
- `method` - matches the same as `classMethod`, `objectLiteralMethod`, `typeMethod`.
268-
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`, `requiresQuotes`.
269+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`, `requiresQuotes`, `override`, `async`.
269270
- Allowed `types`: none.
270271

271272
## FAQ

Diff for: packages/eslint-plugin/src/rules/naming-convention-utils/enums.ts

+4
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ enum Modifiers {
102102
unused = 1 << 10,
103103
// properties that require quoting
104104
requiresQuotes = 1 << 11,
105+
// class members that are overridden
106+
override = 1 << 12,
107+
// class methods, object function properties, or functions that are async via the `async` keyword
108+
async = 1 << 13,
105109

106110
// make sure TypeModifiers starts at Modifiers + 1 or else sorting won't work
107111
}

Diff for: packages/eslint-plugin/src/rules/naming-convention-utils/schema.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,21 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
170170
selectorsSchema(),
171171
...selectorSchema('default', false, util.getEnumNames(Modifiers)),
172172

173-
...selectorSchema('variableLike', false, ['unused']),
173+
...selectorSchema('variableLike', false, ['unused', 'async']),
174174
...selectorSchema('variable', true, [
175175
'const',
176176
'destructured',
177177
'exported',
178178
'global',
179179
'unused',
180+
'async',
181+
]),
182+
...selectorSchema('function', false, [
183+
'exported',
184+
'global',
185+
'unused',
186+
'async',
180187
]),
181-
...selectorSchema('function', false, ['exported', 'global', 'unused']),
182188
...selectorSchema('parameter', true, ['destructured', 'unused']),
183189

184190
...selectorSchema('memberLike', false, [
@@ -189,6 +195,8 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
189195
'readonly',
190196
'requiresQuotes',
191197
'static',
198+
'override',
199+
'async',
192200
]),
193201
...selectorSchema('classProperty', true, [
194202
'abstract',
@@ -198,6 +206,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
198206
'readonly',
199207
'requiresQuotes',
200208
'static',
209+
'override',
201210
]),
202211
...selectorSchema('objectLiteralProperty', true, [
203212
'public',
@@ -222,6 +231,8 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
222231
'readonly',
223232
'requiresQuotes',
224233
'static',
234+
'override',
235+
'async',
225236
]),
226237

227238
...selectorSchema('classMethod', false, [
@@ -231,10 +242,13 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
231242
'public',
232243
'requiresQuotes',
233244
'static',
245+
'override',
246+
'async',
234247
]),
235248
...selectorSchema('objectLiteralMethod', false, [
236249
'public',
237250
'requiresQuotes',
251+
'async',
238252
]),
239253
...selectorSchema('typeMethod', false, ['public', 'requiresQuotes']),
240254
...selectorSchema('method', false, [
@@ -244,6 +258,8 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
244258
'public',
245259
'requiresQuotes',
246260
'static',
261+
'override',
262+
'async',
247263
]),
248264
...selectorSchema('accessor', true, [
249265
'abstract',
@@ -252,6 +268,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
252268
'public',
253269
'requiresQuotes',
254270
'static',
271+
'override',
255272
]),
256273
...selectorSchema('enumMember', false, ['requiresQuotes']),
257274

Diff for: packages/eslint-plugin/src/rules/naming-convention.ts

+49
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ export default util.createRule<Options, MessageIds>({
138138
if ('readonly' in node && node.readonly) {
139139
modifiers.add(Modifiers.readonly);
140140
}
141+
if ('override' in node && node.override) {
142+
modifiers.add(Modifiers.override);
143+
}
141144
if (
142145
node.type === AST_NODE_TYPES.TSAbstractPropertyDefinition ||
143146
node.type === AST_NODE_TYPES.TSAbstractMethodDefinition
@@ -182,6 +185,34 @@ export default util.createRule<Options, MessageIds>({
182185
);
183186
}
184187

188+
function isAsyncMemberOrProperty(
189+
propertyOrMemberNode:
190+
| TSESTree.PropertyNonComputedName
191+
| TSESTree.TSMethodSignatureNonComputedName
192+
| TSESTree.PropertyDefinitionNonComputedName
193+
| TSESTree.TSAbstractPropertyDefinitionNonComputedName
194+
| TSESTree.MethodDefinitionNonComputedName
195+
| TSESTree.TSAbstractMethodDefinitionNonComputedName,
196+
): boolean {
197+
return Boolean(
198+
'value' in propertyOrMemberNode &&
199+
propertyOrMemberNode.value &&
200+
'async' in propertyOrMemberNode.value &&
201+
propertyOrMemberNode.value.async,
202+
);
203+
}
204+
205+
function isAsyncVariableIdentifier(id: TSESTree.Identifier): boolean {
206+
return Boolean(
207+
id.parent &&
208+
(('async' in id.parent && id.parent.async) ||
209+
('init' in id.parent &&
210+
id.parent.init &&
211+
'async' in id.parent.init &&
212+
id.parent.init.async)),
213+
);
214+
}
215+
185216
return {
186217
// #region variable
187218

@@ -219,6 +250,10 @@ export default util.createRule<Options, MessageIds>({
219250
modifiers.add(Modifiers.unused);
220251
}
221252

253+
if (isAsyncVariableIdentifier(id)) {
254+
modifiers.add(Modifiers.async);
255+
}
256+
222257
validator(id, modifiers);
223258
});
224259
},
@@ -254,6 +289,10 @@ export default util.createRule<Options, MessageIds>({
254289
modifiers.add(Modifiers.unused);
255290
}
256291

292+
if (node.async) {
293+
modifiers.add(Modifiers.async);
294+
}
295+
257296
validator(node.id, modifiers);
258297
},
259298

@@ -360,6 +399,11 @@ export default util.createRule<Options, MessageIds>({
360399
| TSESTree.TSMethodSignatureNonComputedName,
361400
): void {
362401
const modifiers = new Set<Modifiers>([Modifiers.public]);
402+
403+
if (isAsyncMemberOrProperty(node)) {
404+
modifiers.add(Modifiers.async);
405+
}
406+
363407
handleMember(validators.objectLiteralMethod, node, modifiers);
364408
},
365409

@@ -376,6 +420,11 @@ export default util.createRule<Options, MessageIds>({
376420
| TSESTree.TSAbstractMethodDefinitionNonComputedName,
377421
): void {
378422
const modifiers = getMemberModifiers(node);
423+
424+
if (isAsyncMemberOrProperty(node)) {
425+
modifiers.add(Modifiers.async);
426+
}
427+
379428
handleMember(validators.classMethod, node, modifiers);
380429
},
381430

0 commit comments

Comments
 (0)