-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
200 additions
and
0 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
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,30 @@ | ||
# Disallows constructor parameters in custom elements (no-constructor-params) | ||
|
||
Ensures that custom element constructors have no parameters as they | ||
are never constructed directly but are rather constructed automatically when | ||
appended to the DOM (or via `createElement` etc). | ||
|
||
## Rule Details | ||
|
||
This rule disallows constructor parameters in custom element classes. | ||
|
||
The following patterns are considered warnings: | ||
|
||
```ts | ||
class Foo extends HTMLElement { | ||
constructor(p1, p2) {} | ||
} | ||
``` | ||
|
||
The following patterns are not warnings: | ||
|
||
```ts | ||
class Foo extends HTMLElement { | ||
constructor() {} | ||
} | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you wish to allow parameters to custom element constructors, you should not | ||
use this 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/** | ||
* @fileoverview Disallows constructor parameters in custom elements | ||
* @author James Garbutt <https://github.com/43081j> | ||
*/ | ||
|
||
import {Rule} from 'eslint'; | ||
import * as ESTree from 'estree'; | ||
import {isCustomElement} from '../util'; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
|
||
const rule: Rule.RuleModule = { | ||
meta: { | ||
docs: { | ||
description: 'Disallows constructor parameters in custom elements', | ||
url: | ||
'https://github.com/43081j/eslint-plugin-wc/blob/master/docs/rules/no-constructor-params.md' | ||
}, | ||
messages: { | ||
noParams: | ||
'Constructors must be parameterless as they are created indirectly ' + | ||
'when appended to DOM.' | ||
} | ||
}, | ||
|
||
create(context): Rule.RuleListener { | ||
// variables should be defined here | ||
const constructorQuery = | ||
'ClassBody > MethodDefinition[kind="constructor"]' + | ||
'[value.params.length > 0]'; | ||
let insideElement = false; | ||
const source = context.getSourceCode(); | ||
|
||
//---------------------------------------------------------------------- | ||
// Helpers | ||
//---------------------------------------------------------------------- | ||
const visitConstructor = (node: ESTree.MethodDefinition): void => { | ||
if (insideElement) { | ||
context.report({ | ||
node, | ||
messageId: 'noParams' | ||
}); | ||
} | ||
}; | ||
|
||
//---------------------------------------------------------------------- | ||
// Public | ||
//---------------------------------------------------------------------- | ||
|
||
return { | ||
[`ClassExpression > ${constructorQuery}`]: visitConstructor, | ||
[`ClassDeclaration > ${constructorQuery}`]: visitConstructor, | ||
'ClassDeclaration,ClassExpression': (node: ESTree.Node): void => { | ||
if ( | ||
(node.type === 'ClassExpression' || | ||
node.type === 'ClassDeclaration') && | ||
isCustomElement(context, node, source.getJSDocComment(node)) | ||
) { | ||
insideElement = true; | ||
} | ||
}, | ||
'ClassDeclaration,ClassExpression:exit': (): void => { | ||
insideElement = false; | ||
} | ||
}; | ||
} | ||
}; | ||
|
||
export default 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/** | ||
* @fileoverview Disallows constructor parameters in custom elements | ||
* @author James Garbutt <https://github.com/43081j> | ||
*/ | ||
|
||
//------------------------------------------------------------------------------ | ||
// Requirements | ||
//------------------------------------------------------------------------------ | ||
|
||
import rule from '../../rules/no-constructor-params'; | ||
import {RuleTester} from 'eslint'; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Tests | ||
//------------------------------------------------------------------------------ | ||
|
||
const ruleTester = new RuleTester({ | ||
parserOptions: { | ||
sourceType: 'module', | ||
ecmaVersion: 2015 | ||
} | ||
}); | ||
|
||
const parser = require.resolve('@typescript-eslint/parser'); | ||
|
||
ruleTester.run('no-constructor-params', rule, { | ||
valid: [ | ||
{ | ||
code: `class Foo {}` | ||
}, | ||
{ | ||
code: `class Foo extends Unknown { | ||
constructor(arg1) {} | ||
}` | ||
}, | ||
{ | ||
code: `class Foo extends HTMLElement { | ||
constructor() {} | ||
}` | ||
}, | ||
{ | ||
code: ` | ||
/** @customElement */ | ||
class Foo extends Bar { | ||
constructor() {} | ||
}` | ||
}, | ||
{ | ||
code: `@customElement('x-foo') | ||
class Foo extends Bar { | ||
constructor() {} | ||
}`, | ||
parser | ||
} | ||
], | ||
|
||
invalid: [ | ||
{ | ||
code: `class Foo extends HTMLElement { | ||
constructor(param1) {} | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noParams', | ||
line: 2, | ||
column: 9 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `/** @customElement */ | ||
class Foo extends Bar { | ||
constructor(param1) {} | ||
}`, | ||
errors: [ | ||
{ | ||
messageId: 'noParams', | ||
line: 3, | ||
column: 9 | ||
} | ||
] | ||
}, | ||
{ | ||
code: `@customElement('x-foo') | ||
class Foo extends Bar { | ||
constructor(param1) {} | ||
}`, | ||
parser, | ||
errors: [ | ||
{ | ||
messageId: 'noParams', | ||
line: 3, | ||
column: 9 | ||
} | ||
] | ||
} | ||
] | ||
}); |