Skip to content

Commit 9c8203f

Browse files
a-tarasyukbradzacher
authored andcommitted
fix(eslint-plugin): [camelcase] handle optional member expr (typescript-eslint#1204)
1 parent d8b07a7 commit 9c8203f

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

packages/eslint-plugin/src/rules/camelcase.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,28 @@ export default util.createRule<Options, MessageIds>({
7272
* @private
7373
*/
7474
function isTSPropertyType(node: TSESTree.Node): boolean {
75-
if (!node.parent) {
76-
return false;
77-
}
78-
if (TS_PROPERTY_TYPES.includes(node.parent.type)) {
75+
if (TS_PROPERTY_TYPES.includes(node.type)) {
7976
return true;
8077
}
8178

82-
if (node.parent.type === AST_NODE_TYPES.AssignmentPattern) {
79+
if (node.type === AST_NODE_TYPES.AssignmentPattern) {
8380
return (
84-
node.parent.parent !== undefined &&
85-
TS_PROPERTY_TYPES.includes(node.parent.parent.type)
81+
node.parent !== undefined &&
82+
TS_PROPERTY_TYPES.includes(node.parent.type)
8683
);
8784
}
8885

8986
return false;
9087
}
9188

89+
function report(node: TSESTree.Identifier): void {
90+
context.report({
91+
node,
92+
messageId: 'notCamelCase',
93+
data: { name: node.name },
94+
});
95+
}
96+
9297
return {
9398
Identifier(node): void {
9499
/*
@@ -103,13 +108,24 @@ export default util.createRule<Options, MessageIds>({
103108
}
104109

105110
// Check TypeScript specific nodes
106-
if (isTSPropertyType(node)) {
111+
const parent = node.parent;
112+
if (parent && isTSPropertyType(parent)) {
107113
if (properties === 'always' && isUnderscored(name)) {
108-
context.report({
109-
node,
110-
messageId: 'notCamelCase',
111-
data: { name: node.name },
112-
});
114+
report(node);
115+
}
116+
117+
return;
118+
}
119+
120+
if (parent && parent.type === AST_NODE_TYPES.OptionalMemberExpression) {
121+
// Report underscored object names
122+
if (
123+
properties === 'always' &&
124+
parent.object.type === AST_NODE_TYPES.Identifier &&
125+
parent.object.name === node.name &&
126+
isUnderscored(name)
127+
) {
128+
report(node);
113129
}
114130

115131
return;

packages/eslint-plugin/tests/rules/camelcase.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ ruleTester.run('camelcase', rule, {
7979
code: 'abstract class Foo { abstract bar: number = 0; }',
8080
options: [{ properties: 'always' }],
8181
},
82+
{
83+
code: 'const foo = foo?.baz;',
84+
},
85+
{
86+
code: 'const foo = foo?.foo_bar?.foo_bar_baz;',
87+
},
88+
{
89+
code: 'const foo = foo.bar?.foo_bar_baz;',
90+
},
91+
{
92+
code: 'const foo = (foo?.bar?.baz)?.foo_bar_baz;',
93+
},
94+
{
95+
code: 'const foo = foo_bar?.foo;',
96+
options: [{ properties: 'never' }],
97+
},
8298
],
8399

84100
invalid: [
@@ -194,5 +210,33 @@ ruleTester.run('camelcase', rule, {
194210
},
195211
],
196212
},
213+
{
214+
code: 'const foo = foo_bar?.foo;',
215+
options: [{ properties: 'always' }],
216+
errors: [
217+
{
218+
messageId: 'notCamelCase',
219+
data: {
220+
name: 'foo_bar',
221+
},
222+
line: 1,
223+
column: 13,
224+
},
225+
],
226+
},
227+
{
228+
code: 'const foo = (foo_test?.bar)?.baz;',
229+
options: [{ properties: 'always' }],
230+
errors: [
231+
{
232+
messageId: 'notCamelCase',
233+
data: {
234+
name: 'foo_test',
235+
},
236+
line: 1,
237+
column: 14,
238+
},
239+
],
240+
},
197241
],
198242
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy