-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: no classfield shadowing (#180)
introduces a new rule: no-classifield-shadowing
- Loading branch information
1 parent
0693199
commit 180f97d
Showing
6 changed files
with
297 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
.idea | ||
node_modules/ | ||
lib/ | ||
*.swp | ||
.nyc_output/ | ||
coverage/ | ||
coverage/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Disallows class fields with same name as static properties | ||
|
||
Class fields set with same names as static properties will not trigger updates as expected. They will overwrite | ||
accessors used for detecting changes. See https://lit.dev/msg/class-field-shadowing for more information. | ||
|
||
## Rule Details | ||
|
||
This rule disallows class fields with same name as static properties. | ||
|
||
The following patterns are considered warnings: | ||
|
||
```ts | ||
class MyEl extends LitElement { | ||
foo; | ||
|
||
static properties = { | ||
foo: {} | ||
} | ||
} | ||
``` | ||
|
||
The following patterns are not warnings: | ||
|
||
```ts | ||
class MyEl extends LitElement { | ||
static properties = { | ||
foo: {} | ||
} | ||
} | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you don't care about class fields with same name as static properties. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* @fileoverview Disallows properties shadowed as class fields | ||
* @author Michel Langeveld <https://github.com/michellangeveld> | ||
*/ | ||
|
||
import {Rule} from 'eslint'; | ||
import * as ESTree from 'estree'; | ||
import {getClassFields, getPropertyMap, isLitClass} from '../util'; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
|
||
const rule: Rule.RuleModule = { | ||
meta: { | ||
docs: { | ||
description: 'Disallows properties shadowed as class fields', | ||
recommended: true, | ||
url: 'https://github.com/43081j/eslint-plugin-lit/blob/master/docs/rules/no-classfield-shadowing.md' | ||
}, | ||
schema: [], | ||
messages: { | ||
noClassfieldShadowing: | ||
'The {{ prop }} property is a class field which has the same name as ' + | ||
'static property which could have unintended side-effects.' | ||
} | ||
}, | ||
|
||
create(context): Rule.RuleListener { | ||
return { | ||
ClassDeclaration: (node: ESTree.Class): void => { | ||
if (isLitClass(node)) { | ||
const propertyMap = getPropertyMap(node); | ||
const classMembers = getClassFields(node); | ||
|
||
for (const [prop, {key}] of propertyMap.entries()) { | ||
if (classMembers.has(prop)) { | ||
context.report({ | ||
node: key, | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop} | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
|
||
export = rule; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/** | ||
* @fileoverview Disallows properties shadowed as class field | ||
* @author Michel Langeveld <https://github.com/michellangeveld> | ||
*/ | ||
|
||
//------------------------------------------------------------------------------ | ||
// Requirements | ||
//------------------------------------------------------------------------------ | ||
|
||
import rule = require('../../rules/no-classfield-shadowing'); | ||
import {RuleTester} from 'eslint'; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Tests | ||
//------------------------------------------------------------------------------ | ||
|
||
const ruleTester = new RuleTester({ | ||
parserOptions: { | ||
sourceType: 'module', | ||
ecmaVersion: 'latest' | ||
} | ||
}); | ||
|
||
ruleTester.run('no-classfield-shadowing', rule, { | ||
valid: [ | ||
`class MyElement extends LitElement { | ||
static properties = { | ||
foo: { type: String } | ||
} | ||
}`, | ||
`class MyElement extends LitElement { | ||
foo; | ||
properties = { | ||
foo: { type: String } | ||
} | ||
}`, | ||
`class MyElement { | ||
foo; | ||
properties = { | ||
foo: { type: String } | ||
} | ||
}` | ||
], | ||
|
||
invalid: [ | ||
{ | ||
code: `class MyElement extends LitElement { | ||
foo; | ||
static properties = {foo: {}} | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop: 'foo'}, | ||
line: 3, | ||
column: 30 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `class MyElement extends LitElement { | ||
static properties = {foo: {}} | ||
foo; | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop: 'foo'}, | ||
line: 2, | ||
column: 30 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `class MyElement extends LitElement { | ||
foo; | ||
static get properties() { return { foo: {}}}; | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop: 'foo'}, | ||
line: 3, | ||
column: 44 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `class MyElement extends LitElement { | ||
static get properties() { return { foo: {}}}; | ||
foo; | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop: 'foo'}, | ||
line: 2, | ||
column: 44 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `class Foo extends A(LitElement) { | ||
foo; | ||
static properties = { foo: {} }; | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop: 'foo'}, | ||
line: 3, | ||
column: 31 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `class Foo extends A(B(LitElement)) { | ||
foo; | ||
static properties = { foo: {} }; | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop: 'foo'}, | ||
line: 3, | ||
column: 31 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `class Foo extends A(B(C(LitElement))) { | ||
foo; | ||
static properties = { foo: {} }; | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noClassfieldShadowing', | ||
data: {prop: 'foo'}, | ||
line: 3, | ||
column: 31 | ||
} | ||
] | ||
} | ||
] | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters