refactor: general rename/clean up rules - #754
#754refactor: general rename/clean up rules#754mgechev merged 1 commit intomgechev:mastermgechev/codelyzer:masterfrom rafaelss95:refactor/rename-rulesCopy head branch name to clipboard
Conversation
|
This will require schematics transform of We'll have to discuss the change with @alexeagle and @hansl. |
| "use-component-selector": true, | ||
| "use-host-property-decorator": true, | ||
| "use-input-property-decorator": true, | ||
| "use-lifecycle-interface": true, |
There was a problem hiding this comment.
We use this internally. Need to make sure we update g3.
| super.visitNgPipe(controller, decorator); | ||
| } | ||
|
|
||
| private validateDecorator( |
mgechev
left a comment
There was a problem hiding this comment.
Fantastic job! I reviewed half of the PR, I'll review the rest tomorrow.
|
The renames you suggest make sense. |
| private validateInterfaces(node: ClassDeclaration): void { | ||
| const declaredLifecycleInterfaces = getDeclaredLifecycleInterfaces(node); | ||
|
|
||
| for (const key of Object.keys(LIFECYCLE_INTERFACE_CONFLICT_MAPPER)) { |
There was a problem hiding this comment.
Let's drop the for loop here, we don't really need it, nor LIFECYCLE_INTERFACE_CONFLICT_MAPPER
| private validateMethods(node: ClassDeclaration): void { | ||
| const declaredLifecycleMethods = getDeclaredLifecycleMethods(node); | ||
|
|
||
| for (const key of Object.keys(LIFECYCLE_METHOD_CONFLICT_MAPPER)) { |
| } | ||
| } | ||
|
|
||
| export class ExpressionCallMetadataWalker extends NgWalker { |
There was a problem hiding this comment.
Not necessarily, however, for some reason, we export the walker's in almost all rules. I'll remove the export here and in other files in this PR.
| import { NgWalker } from './angular/ngWalker'; | ||
| import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor'; | ||
|
|
||
| const INVALID_BOX = /\[(.*)\]/; |
There was a problem hiding this comment.
/\[(.*)\]/.test('[(ngModel)]') && /\[(.*)\]/.test('([ngModel])') which seems incorrect.
There was a problem hiding this comment.
You're right, however, the previous regex (which one is different only by a question mark) was also wrong, it gave the same result for the tests you wrote above.
After investigating why the specs pass even with this wrong regex, I discovered that the ast's name just cuts the parens, so:
Test 1: <input type="text" name="foo" ([ngModel])="foo">, test with regex returns true (the ast's name is just [ngModel]);
Test 2: <div (emitter)="emitter"></div> -> test with regex returns false (ast's name is emitter);
Test 3: <input type="text" name="foo" [ngModel]="foo"> -> test with regex returns false (ast's name is ngModelChange);
Test 4: <input type="text" name="foo" [(ngModel)]="foo"> -> never call visitEvent method.
I changed the regex a bit to: /^\[(?!\()(.*)(?<!\))\]$/.
There was a problem hiding this comment.
Yes, previous regex was absolutely wrong, I noticed that. Thanks for the update!
There was a problem hiding this comment.
yes @rafaelss95 , this rule used visitEvent, what explains this behavior.
| private validateComponent(metadata: ComponentMetadata): void { | ||
| if (metadata.selector) return; | ||
|
|
||
| const failure = getFailureMessage(metadata.controller.name!.text); |
There was a problem hiding this comment.
We're very confident here. Do we know for sure that name is not going to be null?
There was a problem hiding this comment.
Hmm, to be honest, I really don't know if we can receive a null name here. It was copied from enforceComponentSelector, anyway, I'll add a check for this :)
| @@ -0,0 +1,113 @@ | ||
| import { getFailureMessage, Rule } from '../src/contextualLifecycleRule'; |
There was a problem hiding this comment.
I'd prefer to keep the previous specs. This is not very readable, it's hard to keep track what are the interfaces and the methods.
There was a problem hiding this comment.
No problem, I'll update ASAP.
| @@ -1,51 +1,46 @@ | ||
| import { lifecycleHooksMethods, LifecycleHooksMethods, Rule } from '../src/noLifeCycleCallRule'; | ||
| import { Rule } from '../src/noLifecycleCallRule'; |
There was a problem hiding this comment.
Same here. I see we've merged the template string snippets, but I have no idea what we are testing like this. Would you mind updating? Thanks 🙇🏼♂️
There was a problem hiding this comment.
No problem, I'll update ASAP.
mgechev
left a comment
There was a problem hiding this comment.
I actually had an extra hour today. Fascinating job! I love the early return refactoring and the consistency! I left a few comments. Mostly about readability of the tests.
|
Haha, thanks :) Btw, it's ready for the next round when you have time 💥 |
| | `no-unused-css` | _Experimental_ | | ||
| | `pipe-prefix` | _Experimental_ | | ||
| | `template-i18n` | _Experimental_ | | ||
| | `template-conditional-complexity` | _Experimental_ | |
| import { NgWalker } from './angular/ngWalker'; | ||
| import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor'; | ||
|
|
||
| const INVALID_BOX = /\[(.*)\]/; |
There was a problem hiding this comment.
yes @rafaelss95 , this rule used visitEvent, what explains this behavior.
wKoza
left a comment
There was a problem hiding this comment.
Great work @rafaelss95 , just some questions
| decorator: Decorator, | ||
| allowedHookMethods: ReadonlySet<LifecycleMethodKeys> | ||
| ): void { | ||
| if (!controller.name) return; |
There was a problem hiding this comment.
is It possible or it's just for not don't just after using '!' ?
There was a problem hiding this comment.
I've never seen a case where this could be null! I did it to jump the ! 😛
There was a problem hiding this comment.
@Component({...})
export default class { ... }Seems valid to me. In this case name is undefined.
There was a problem hiding this comment.
hmm, In the Angular world, I'm not sure we can omit a Type. But, @mgechev , your example is interesting:
If we create a simple class like that:
export default class { ... }and we launch ng lint, we have a big big crash [here] (https://github.com/mgechev/codelyzer/blob/master/src/propertyDecoratorBase.ts#L41) and many other places !
@mgechev , @rafaelss95 , I'm not very fan of the ! Non-Null Assertion. We cannot say that
const className = metadata.controller.name!.textis the same that
if (!controller.name) return;
const className = controllerName.text;If we accept metadata.controller.name!.text, we should not write if (!controller.name) return;
Hence my question.
So, we must keep this test, but we must also use this test everywhere and stop to use the Non-Null Assertion.
Are you agree ?
| for (const member of controller.members) { | ||
| const { name: memberName } = member; | ||
|
|
||
| if (!memberName) continue; |
There was a problem hiding this comment.
is It possible or it's just for not don't just after using '!' ?
There was a problem hiding this comment.
I've never seen a case where this could be null! I did it to jump the ! 😛
| describe('valid declaration of lifecycle hooks, using ng.hookName', () => { | ||
| it('should succeed when lifecycle hook is used with its interface', () => { | ||
| const source = ` | ||
| class ${className} implements ng.OnInit { |
There was a problem hiding this comment.
Question: using namespace is a good practice ?
There was a problem hiding this comment.
I really don't know, but I never saw someone using this in real world.
There was a problem hiding this comment.
This may have some implications in the dead code elimination, but it's fine to exist in our test cases.
|
@rafaelss95 would you resolve the merge conflict? I think we're ready to merge. |
|
@mgechev Sure! What about my three questions below the table? |
|
LGTM, the extra checks seem fine. |
|
@mgechev I was talking about the questions in the PR description (below the table) :) |
|
Oh, I was sure that I responded to these questions but it looks I didn't. Yes, it makes sense to rename the rest of the rules as well. |
|
Hey @mgechev I've updated the code and the table in OP with the new proposed names. I took a look in (almost) all the rules today and found some more rule names that can be improved:
Let me know your opinion :) |
|
@rafaelss95 let's rename the other rules as part of another PR:
Sound good. About the relative prefix, it's still not obvious what's about. Maybe we should be more explicit about it. |
Migration of the `tslint.json` file required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` file required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` file required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
@mgechev Do you have any suggestion? |
|
Let's not updated it for now. |
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
- templates-use-public/no-access-missing-member (not more exist as handled by tsc - mgechev/codelyzer#260 (comment)) - invoke-injectable (not more exist as handled by ngc - mgechev/codelyzer#260 (comment)) - use-input*/use-output*/use-host* renamed - mgechev/codelyzer#754 - "typeof-compare is deprecated. Starting from TypeScript 2.2 the compiler includes this check which makes this rule redundant"
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Migration of the `tslint.json` and `package.json` files required by the refactoring of codelyzer. For more information check this PR mgechev/codelyzer#754.
Points:
1) EnforceComponentSelector -> UseComponentSelector: I decided to rename it to make it sync with other "use" rules... let me know what do you think about it.
2) NoOutputNamedAfterStandardEventRule -> NoOutputNative: not sure if it's a good name, please don't hesitate to suggest one :)
3) TemplatesNoNegatedAsync -> TemplateNoNegatedAsync: I'm not sure renaming it is a good idea, because in addition to this rule returning some false positives, it's not useful at all (see #615 (comment))resolved in #615.4) Since we are renaming, what about those below?
pipe-impure->no-pipe-impureuse-host-property-decorator->no-host-parameter(to be sync withno-queries-parameter)use-input-property-decorator->no-inputs-parameter(to be sync withno-queries-parameter)use-output-property-decorator->no-outputs-parameter(to be sync withno-queries-parameter)Closes #653.