Skip to content

Commit 75c4d78

Browse files
authored
Support PropertyDefinition (sindresorhus#1127)
1 parent 18d1ac2 commit 75c4d78

File tree

6 files changed

+56
-20
lines changed

6 files changed

+56
-20
lines changed

rules/custom-error-definition.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,15 @@ const isAssignmentExpression = (node, name) => {
5454
return lhs.property.name === name;
5555
};
5656

57-
const isClassProperty = (node, name) => {
58-
if (node.type !== 'ClassProperty' || node.computed) {
57+
const isPropertyDefinition = (node, name) => {
58+
const {type, computed, key} = node;
59+
if (type !== 'PropertyDefinition' && type !== 'ClassProperty') {
5960
return false;
6061
}
6162

62-
const {key} = node;
63+
if (computed) {
64+
return false;
65+
}
6366

6467
if (key.type !== 'Identifier') {
6568
return false;
@@ -144,7 +147,7 @@ const customErrorDefinition = (context, node) => {
144147

145148
const nameExpression = constructorBody.find(x => isAssignmentExpression(x, 'name'));
146149
if (!nameExpression) {
147-
const nameProperty = body.find(node => isClassProperty(node, 'name'));
150+
const nameProperty = body.find(node => isPropertyDefinition(node, 'name'));
148151

149152
if (!nameProperty || !nameProperty.value || nameProperty.value.value !== name) {
150153
context.report({

rules/no-static-only-class.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@ const isDeclarationOfExportDefaultDeclaration = node =>
2323
node.parent.type === 'ExportDefaultDeclaration' &&
2424
node.parent.declaration === node;
2525

26+
// https://github.com/estree/estree/blob/master/stage3/class-features.md#propertydefinition
27+
const isPropertyDefinition = node => node.type === 'PropertyDefinition' ||
28+
// Legacy node type
29+
node.type === 'ClassProperty';
30+
const isMethodDefinition = node => node.type === 'MethodDefinition';
31+
2632
function isStaticMember(node) {
2733
const {
28-
type,
2934
private: isPrivate,
3035
static: isStatic,
3136
declare: isDeclare,
@@ -37,7 +42,7 @@ function isStaticMember(node) {
3742

3843
// Avoid matching unexpected node. For example: https://github.com/tc39/proposal-class-static-block
3944
/* istanbul ignore next */
40-
if (type !== 'ClassProperty' && type !== 'MethodDefinition') {
45+
if (!isPropertyDefinition(node) && !isMethodDefinition(node)) {
4146
return false;
4247
}
4348

@@ -60,8 +65,6 @@ function isStaticMember(node) {
6065
}
6166

6267
function * switchClassMemberToObjectProperty(node, sourceCode, fixer) {
63-
const {type} = node;
64-
6568
const staticToken = sourceCode.getFirstToken(node);
6669
assertToken(staticToken, {
6770
expected: [
@@ -75,12 +78,12 @@ function * switchClassMemberToObjectProperty(node, sourceCode, fixer) {
7578
yield fixer.remove(staticToken);
7679
yield removeSpacesAfter(staticToken, sourceCode, fixer);
7780

78-
const maybeSemicolonToken = type === 'ClassProperty' ?
81+
const maybeSemicolonToken = isPropertyDefinition(node) ?
7982
sourceCode.getLastToken(node) :
8083
sourceCode.getTokenAfter(node);
8184
const hasSemicolonToken = isSemicolonToken(maybeSemicolonToken);
8285

83-
if (type === 'ClassProperty') {
86+
if (isPropertyDefinition(node)) {
8487
const {key, value} = node;
8588

8689
if (value) {
@@ -132,11 +135,11 @@ function switchClassToObject(node, sourceCode) {
132135

133136
for (const node of body.body) {
134137
if (
135-
node.type === 'ClassProperty' &&
138+
isPropertyDefinition(node) &&
136139
(
137140
node.typeAnnotation ||
138-
// This is a stupid way to check if `value` of `ClassProperty` uses `this`
139-
(node.value && sourceCode.getText(node).includes('this'))
141+
// This is a stupid way to check if `value` of `PropertyDefinition` uses `this`
142+
(node.value && sourceCode.getText(node.value).includes('this'))
140143
)
141144
) {
142145
return;

rules/prevent-abbreviations.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ const shouldReportIdentifierAsProperty = identifier => {
538538
}
539539

540540
if (
541-
identifier.parent.type === 'ClassProperty' &&
541+
(identifier.parent.type === 'ClassProperty' || identifier.parent.type === 'PropertyDefinition') &&
542542
identifier.parent.key === identifier &&
543543
!identifier.parent.computed
544544
) {

test/custom-error-definition.mjs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,28 @@ runTest.babel({
504504
}
505505
`,
506506
errors: [invalidNameError('ValidationError')]
507+
},
508+
// `computed`
509+
{
510+
code: outdent`
511+
const name = 'computed-name';
512+
class FooError extends Error {
513+
[name] = 'FooError';
514+
constructor(message) {
515+
super(message);
516+
}
517+
}
518+
`,
519+
output: outdent`
520+
const name = 'computed-name';
521+
class FooError extends Error {
522+
[name] = 'FooError';
523+
constructor(message) {
524+
super(message);
525+
}
526+
}
527+
`,
528+
errors: [invalidNameError('FooError')]
507529
}
508530
]
509531
});

test/no-static-only-class.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,12 @@ test.typescript({
175175
static b = this.a;
176176
}
177177
`),
178+
// `this` in `key` should fixable
179+
{
180+
code: 'class A {static [this.a] = 1}',
181+
output: 'const A = {[this.a] : 1,};',
182+
errors: 1
183+
},
178184
// This case should be fixable, but we simply check code of value includes `this`
179185
noFixingCase(outdent`
180186
class A {

test/utils/test.mjs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ class Tester {
4545
testerOptions.parserOptions = testerOptions.parserOptions || {};
4646
testerOptions.parserOptions.babelOptions = testerOptions.parserOptions.babelOptions || {};
4747
testerOptions.parserOptions.babelOptions.parserOpts = testerOptions.parserOptions.babelOptions.parserOpts || {};
48-
testerOptions.parserOptions.babelOptions.parserOpts.plugins = testerOptions.parserOptions.babelOptions.parserOpts.plugins || [];
48+
let babelPlugins = testerOptions.parserOptions.babelOptions.parserOpts.plugins || [];
49+
babelPlugins = [
50+
['estree', {classFeatures: true}],
51+
'jsx',
52+
'classProperties',
53+
...babelPlugins
54+
];
4955

5056
return this.runTest({
5157
...tests,
@@ -62,11 +68,7 @@ class Tester {
6268
...testerOptions.parserOptions.babelOptions,
6369
parserOpts: {
6470
...testerOptions.parserOptions.babelOptions.parserOpts,
65-
plugins: [
66-
'jsx',
67-
'classProperties',
68-
...testerOptions.parserOptions.babelOptions.parserOpts.plugins
69-
]
71+
plugins: babelPlugins
7072
}
7173
}
7274
}

0 commit comments

Comments
 (0)