-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: general rename/clean up rules #754
Conversation
This will require schematics transform of We'll have to discuss the change with @alexeagle and @hansl. |
README.md
Outdated
"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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use this internally. Need to make sure we update g3.
src/contextualLifecycleRule.ts
Outdated
super.visitNgPipe(controller, decorator); | ||
} | ||
|
||
private validateDecorator( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job with this refactoring!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop the for loop here, we don't really need it, nor LIFECYCLE_INTERFACE_CONFLICT_MAPPER
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
private validateMethods(node: ClassDeclaration): void { | ||
const declaredLifecycleMethods = getDeclaredLifecycleMethods(node); | ||
|
||
for (const key of Object.keys(LIFECYCLE_METHOD_CONFLICT_MAPPER)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/noLifecycleCallRule.ts
Outdated
} | ||
} | ||
|
||
export class ExpressionCallMetadataWalker extends NgWalker { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to export this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/templateBananaInBoxRule.ts
Outdated
import { NgWalker } from './angular/ngWalker'; | ||
import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor'; | ||
|
||
const INVALID_BOX = /\[(.*)\]/; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/\[(.*)\]/.test('[(ngModel)]') && /\[(.*)\]/.test('([ngModel])')
which seems incorrect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, previous regex was absolutely wrong, I noticed that. Thanks for the update!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes @rafaelss95 , this rule used visitEvent
, what explains this behavior.
src/useComponentSelectorRule.ts
Outdated
private validateComponent(metadata: ComponentMetadata): void { | ||
if (metadata.selector) return; | ||
|
||
const failure = getFailureMessage(metadata.controller.name!.text); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, I'll update ASAP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 💥 |
README.md
Outdated
| `no-unused-css` | _Experimental_ | | ||
| `pipe-prefix` | _Experimental_ | | ||
| `template-i18n` | _Experimental_ | | ||
| `template-conditional-complexity` | _Experimental_ | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be careful when we'll merge this PR with #756
src/templateBananaInBoxRule.ts
Outdated
import { NgWalker } from './angular/ngWalker'; | ||
import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor'; | ||
|
||
const INVALID_BOX = /\[(.*)\]/; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes @rafaelss95 , this rule used visitEvent
, what explains this behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @rafaelss95 , just some questions
src/contextualLifecycleRule.ts
Outdated
decorator: Decorator, | ||
allowedHookMethods: ReadonlySet<LifecycleMethodKeys> | ||
): void { | ||
if (!controller.name) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is It possible or it's just for not don't just after using '!' ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never seen a case where this could be null! I did it to jump the !
😛
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Component({...})
export default class { ... }
Seems valid to me. In this case name
is undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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!.text
is 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is It possible or it's just for not don't just after using '!' ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never seen a case where this could be null! I did it to jump the !
😛
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep it.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: using namespace is a good practice ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't know, but I never saw someone using this in real world.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mgechev , what do you think about it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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-impure
use-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.