Skip to content

Commit

Permalink
Merge 1b77ad0 into 1470912
Browse files Browse the repository at this point in the history
  • Loading branch information
stramel committed May 13, 2021
2 parents 1470912 + 1b77ad0 commit 41a63c8
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 108 deletions.
14 changes: 4 additions & 10 deletions src/rules/attach-shadow-constructor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,17 @@ const rule: Rule.RuleModule = {
//----------------------------------------------------------------------

return {
'ClassDeclaration,ClassExpression': (node: ESTree.Node): void => {
if (
(node.type === 'ClassExpression' ||
node.type === 'ClassDeclaration') &&
isCustomElement(context, node, source.getJSDocComment(node))
) {
'ClassDeclaration,ClassExpression': (node: ESTree.Class): void => {
if (isCustomElement(context, node, source.getJSDocComment(node))) {
insideElement = true;
}
},
'ClassDeclaration,ClassExpression:exit': (): void => {
insideElement = false;
},
MethodDefinition: (node: ESTree.Node): void => {
MethodDefinition: (node: ESTree.MethodDefinition): void => {
if (
insideElement &&
node.type === 'MethodDefinition' &&
node.kind !== 'constructor' &&
node.key.type === 'Identifier' &&
node.key.name !== 'constructor'
Expand All @@ -65,10 +60,9 @@ const rule: Rule.RuleModule = {
'MethodDefinition:exit': (): void => {
insideNonConstructor = false;
},
CallExpression: (node: ESTree.Node): void => {
CallExpression: (node: ESTree.CallExpression): void => {
if (
insideNonConstructor &&
node.type === 'CallExpression' &&
node.callee.type === 'MemberExpression' &&
node.callee.object.type === 'ThisExpression' &&
node.callee.property.type === 'Identifier' &&
Expand Down
6 changes: 2 additions & 4 deletions src/rules/guard-super-call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,8 @@ const rule: Rule.RuleModule = {
//----------------------------------------------------------------------

return {
'ClassDeclaration,ClassExpression': (node: ESTree.Node): void => {
'ClassDeclaration,ClassExpression': (node: ESTree.Class): void => {
if (
(node.type === 'ClassExpression' ||
node.type === 'ClassDeclaration') &&
isCustomElement(context, node, source.getJSDocComment(node)) &&
!isNativeCustomElement(node)
) {
Expand All @@ -131,7 +129,7 @@ const rule: Rule.RuleModule = {
'ClassDeclaration,ClassExpression:exit': (): void => {
insideNonNativeElement = false;
},
MethodDefinition: (node: ESTree.Node): void => {
MethodDefinition: (node: ESTree.MethodDefinition): void => {
if (!insideNonNativeElement || !isLifecycleHook(node)) {
return;
}
Expand Down
3 changes: 1 addition & 2 deletions src/rules/no-closed-shadow-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ const rule: Rule.RuleModule = {
//----------------------------------------------------------------------

return {
CallExpression: (node: ESTree.Node): void => {
CallExpression: (node: ESTree.CallExpression): void => {
if (
node.type === 'CallExpression' &&
node.callee.type === 'MemberExpression' &&
node.callee.property.type === 'Identifier' &&
node.callee.property.name === 'attachShadow'
Expand Down
27 changes: 7 additions & 20 deletions src/rules/no-constructor-attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,17 @@ const rule: Rule.RuleModule = {
//----------------------------------------------------------------------

return {
'ClassDeclaration,ClassExpression': (node: ESTree.Node): void => {
if (
(node.type === 'ClassExpression' ||
node.type === 'ClassDeclaration') &&
isCustomElement(context, node, source.getJSDocComment(node))
) {
'ClassDeclaration,ClassExpression': (node: ESTree.Class): void => {
if (isCustomElement(context, node, source.getJSDocComment(node))) {
insideElement = true;
}
},
'ClassDeclaration,ClassExpression:exit': (): void => {
insideElement = false;
},
MethodDefinition: (node: ESTree.Node): void => {
MethodDefinition: (node: ESTree.MethodDefinition): void => {
if (
insideElement &&
node.type === 'MethodDefinition' &&
node.kind === 'constructor' &&
node.static === false &&
node.key.type === 'Identifier' &&
Expand All @@ -150,21 +145,13 @@ const rule: Rule.RuleModule = {
'MethodDefinition:exit': (): void => {
insideConstructor = false;
},
CallExpression: (node: ESTree.Node): void => {
if (
insideConstructor &&
node.type === 'CallExpression' &&
isBannedCallExpr(node)
) {
CallExpression: (node: ESTree.CallExpression): void => {
if (insideConstructor && isBannedCallExpr(node)) {
context.report({node: node, messageId: 'constructorAttrs'});
}
},
MemberExpression: (node: ESTree.Node): void => {
if (
insideConstructor &&
node.type === 'MemberExpression' &&
isBannedMember(node)
) {
MemberExpression: (node: ESTree.MemberExpression): void => {
if (insideConstructor && isBannedMember(node)) {
context.report({node: node, messageId: 'constructorAttrs'});
}
}
Expand Down
8 changes: 2 additions & 6 deletions src/rules/no-constructor-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,8 @@ const rule: Rule.RuleModule = {
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))
) {
'ClassDeclaration,ClassExpression': (node: ESTree.Class): void => {
if (isCustomElement(context, node, source.getJSDocComment(node))) {
insideElement = true;
}
},
Expand Down
3 changes: 1 addition & 2 deletions src/rules/no-invalid-element-name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ const rule: Rule.RuleModule = {
//----------------------------------------------------------------------

return {
CallExpression: (node: ESTree.Node): void => {
CallExpression: (node: ESTree.CallExpression): void => {
if (
node.type === 'CallExpression' &&
node.callee.type === 'MemberExpression' &&
((node.callee.object.type === 'MemberExpression' &&
node.callee.object.object.type === 'Identifier' &&
Expand Down
24 changes: 6 additions & 18 deletions src/rules/no-self-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,33 +83,21 @@ const rule: Rule.RuleModule = {
//----------------------------------------------------------------------

return {
'ClassDeclaration,ClassExpression': (node: ESTree.Node): void => {
if (
(node.type === 'ClassExpression' ||
node.type === 'ClassDeclaration') &&
isCustomElement(context, node, source.getJSDocComment(node))
) {
'ClassDeclaration,ClassExpression': (node: ESTree.Class): void => {
if (isCustomElement(context, node, source.getJSDocComment(node))) {
insideElement = true;
}
},
'ClassDeclaration,ClassExpression:exit': (): void => {
insideElement = false;
},
AssignmentExpression: (node: ESTree.Node): void => {
if (
insideElement &&
node.type === 'AssignmentExpression' &&
isBannedAssignmentExpr(node)
) {
AssignmentExpression: (node: ESTree.AssignmentExpression): void => {
if (insideElement && isBannedAssignmentExpr(node)) {
context.report({node: node, messageId: 'selfClass'});
}
},
CallExpression: (node: ESTree.Node): void => {
if (
insideElement &&
node.type === 'CallExpression' &&
isBannedCallExpr(node)
) {
CallExpression: (node: ESTree.CallExpression): void => {
if (insideElement && isBannedCallExpr(node)) {
context.report({node: node, messageId: 'selfClass'});
}
}
Expand Down
12 changes: 4 additions & 8 deletions src/rules/no-typos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,16 @@ const rule: Rule.RuleModule = {
//----------------------------------------------------------------------

return {
'ClassDeclaration,ClassExpression': (node: ESTree.Node): void => {
if (
(node.type === 'ClassExpression' ||
node.type === 'ClassDeclaration') &&
isCustomElement(context, node, source.getJSDocComment(node))
) {
'ClassDeclaration,ClassExpression': (node: ESTree.Class): void => {
if (isCustomElement(context, node, source.getJSDocComment(node))) {
insideElement = true;
}
},
'ClassDeclaration,ClassExpression:exit': (): void => {
insideElement = false;
},
MethodDefinition: (node: ESTree.Node): void => {
if (insideElement && node.type === 'MethodDefinition') {
MethodDefinition: (node: ESTree.MethodDefinition): void => {
if (insideElement) {
if (
node.kind === 'method' &&
!node.static &&
Expand Down
7 changes: 5 additions & 2 deletions src/test/util_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import {expect} from 'chai';
import * as ESTree from 'estree';
import {AST, Rule} from 'eslint';

const parseExpr = (expr: string): ESTree.Node => {
const parseExpr = (expr: string): ESTree.Class => {
const parsed = parse(expr, {
loc: true,
ecmaVersion: 6,
sourceType: 'module'
});
return (parsed as ESTree.Program).body[0];
return (parsed as ESTree.Program).body[0] as
| ESTree.ClassDeclaration
| ESTree.ClassExpression;
};

const mockContext = ({
Expand All @@ -21,6 +23,7 @@ describe('util', () => {
describe('isCustomElement', () => {
it('should parse direct sub classes of HTMLElement', () => {
const doc = parseExpr(`class Foo extends HTMLElement {}`);
util.isCustomElement(mockContext, doc); // Primes the cache
expect(util.isCustomElement(mockContext, doc)).to.equal(true);
});

Expand Down
58 changes: 22 additions & 36 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ export function isCustomElementDecorator(node: DecoratorNode): boolean {
* Determines if a node is an element class or not.
*
* @param {Rule.RuleContext} context ESLint rule context
* @param {ESTree.Node} node Node to test
* @param {ESTree.Class} node Node to test
* @param {AST.Token=} jsdoc JSDoc to parse
* @return {boolean}
*/
export function isCustomElement(
context: Rule.RuleContext,
node: ESTree.Node,
node: ESTree.Class,
jsdoc?: AST.Token | null
): node is ESTree.Class {
const asDecorated = node as WithDecorators<ESTree.Node>;
Expand All @@ -49,41 +49,28 @@ export function isCustomElement(
return cached;
}

if (
context.settings.wc &&
Array.isArray(context.settings.wc.elementBaseClasses)
) {
if (Array.isArray(context.settings.wc?.elementBaseClasses)) {
customElementBases.push(
...(context.settings.wc.elementBaseClasses as string[])
);
}

if (node.type === 'ClassExpression' || node.type === 'ClassDeclaration') {
if (
node.superClass &&
node.superClass.type === 'Identifier' &&
customElementBases.includes(node.superClass.name)
) {
customElementsCache.set(node, true);
return true;
}
if (
node.superClass?.type === 'Identifier' &&
customElementBases.includes(node.superClass.name)
) {
customElementsCache.set(node, true);
return true;
}

if (
jsdoc !== undefined &&
jsdoc !== null &&
jsdoc.value.includes('@customElement')
) {
customElementsCache.set(node, true);
return true;
}
if (jsdoc?.value.includes('@customElement')) {
customElementsCache.set(node, true);
return true;
}

if (
asDecorated.decorators !== undefined &&
asDecorated.decorators.some(isCustomElementDecorator)
) {
customElementsCache.set(node, true);
return true;
}
if (asDecorated.decorators?.some(isCustomElementDecorator)) {
customElementsCache.set(node, true);
return true;
}

customElementsCache.set(node, false);
Expand All @@ -93,15 +80,14 @@ export function isCustomElement(
/**
* Determines if a node is an extension of HTMLElement class or not.
*
* @param {ESTree.Node} node Node to test
* @param {ESTree.Class} node Node to test
* @return {boolean}
*/
export function isNativeCustomElement(node: ESTree.Node): node is ESTree.Class {
export function isNativeCustomElement(
node: ESTree.Class
): node is ESTree.Class {
return (
(node.type === 'ClassExpression' || node.type === 'ClassDeclaration') &&
node.superClass !== undefined &&
node.superClass !== null &&
node.superClass.type === 'Identifier' &&
node.superClass?.type === 'Identifier' &&
node.superClass.name === 'HTMLElement'
);
}

0 comments on commit 41a63c8

Please sign in to comment.