-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rules): added rule orthodox-getter-and-setter (#49)
- Loading branch information
1 parent
f890ea6
commit a92875f
Showing
4 changed files
with
181 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
export const customRules = { | ||
rules: { | ||
'orthodox-getter-and-setter': true, | ||
'blank-lines': [ | ||
true, | ||
{ | ||
|
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,75 @@ | ||
import * as Lint from 'tslint'; | ||
import * as tsutils from 'tsutils'; | ||
import * as ts from 'typescript'; | ||
|
||
|
||
/** | ||
* Rule that enforces order getter property > setter property > private _property . | ||
*/ | ||
export class Rule extends Lint.Rules.AbstractRule { | ||
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { | ||
return this.applyWithWalker(new Walker(sourceFile, this.getOptions())); | ||
} | ||
} | ||
|
||
class Walker extends Lint.RuleWalker { | ||
visitGetAccessor(getter: ts.GetAccessorDeclaration) { | ||
if (getter.parent && tsutils.isClassDeclaration(getter.parent)) { | ||
const getterName = getter.name.getText(); | ||
|
||
const setter = getter.parent.members.find((member) => { | ||
return tsutils.isSetAccessorDeclaration(member) && member.name.getText() === getterName; | ||
}) as ts.SetAccessorDeclaration | undefined; | ||
|
||
if (setter && setter.pos < getter.pos) { | ||
this.addFailureAtNode(getter, 'Getters must be declared before setters.'); | ||
} | ||
} | ||
|
||
super.visitGetAccessor(getter); | ||
} | ||
|
||
visitSetAccessor(setter: ts.SetAccessorDeclaration) { | ||
if (setter.parent && tsutils.isClassDeclaration(setter.parent)) { | ||
const setterName = setter.name.getText(); | ||
|
||
const getter = setter.parent.members.find((member) => { | ||
return tsutils.isGetAccessorDeclaration(member) && member.name.getText() === setterName; | ||
}) as ts.GetAccessorDeclaration | undefined; | ||
|
||
if (getter && getter.pos > setter.pos) { | ||
this.addFailureAtNode(setter, 'Setters must be declared after getters.'); | ||
} | ||
} | ||
|
||
super.visitSetAccessor(setter); | ||
} | ||
|
||
visitPropertyDeclaration(property: ts.PropertyDeclaration) { | ||
const propertyName = property.name.getText(); | ||
const getterOrSetterName = propertyName.slice(1); | ||
|
||
if (propertyName.startsWith('_') && tsutils.hasModifier(property.modifiers, ts.SyntaxKind.PrivateKeyword)) { | ||
const getter = property.parent.members.find((member) => { | ||
return tsutils.isGetAccessorDeclaration(member) && member.name.getText() === getterOrSetterName; | ||
}) as ts.GetAccessorDeclaration | undefined; | ||
|
||
const setter = property.parent.members.find((member) => { | ||
return tsutils.isSetAccessorDeclaration(member) && member.name.getText() === getterOrSetterName; | ||
}) as ts.SetAccessorDeclaration | undefined; | ||
|
||
if (!getter && !setter) { | ||
this.addFailureAtNode(property, | ||
'Private property with leading underscore must be used only for getter or setter.'); | ||
} | ||
|
||
if ((getter && property.pos < getter.pos) || | ||
(setter && property && property.pos < setter.pos)) { | ||
this.addFailureAtNode(property, | ||
'Private property for getter or setter must be declared after them.'); | ||
} | ||
} | ||
|
||
super.visitPropertyDeclaration(property); | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
test/rules/orthodox-getter-and-setter/default/test.ts.lint
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,100 @@ | ||
class Test1 { | ||
get property() { | ||
return this._property; | ||
} | ||
|
||
set property(value) { | ||
this._property = value; | ||
} | ||
|
||
private _property: string; | ||
} | ||
|
||
class Test2 { | ||
set property(value) { | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
this._property = value; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
} | ||
~~~~~ [Setters must be declared after getters.] | ||
|
||
get property() { | ||
~~~~~~~~~~~~~~~~ | ||
return this._property; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
} | ||
~~~~~ [Getters must be declared before setters.] | ||
|
||
private _property: string; | ||
} | ||
|
||
class Test3 { | ||
private _property: string; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~ [Private property for getter or setter must be declared after them.] | ||
|
||
get property() { | ||
return this._property; | ||
} | ||
|
||
set property(value) { | ||
this._property = value; | ||
} | ||
} | ||
|
||
class Test4 { | ||
private _property: string; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~ [Private property for getter or setter must be declared after them.] | ||
|
||
set property(value) { | ||
this._property = value; | ||
} | ||
} | ||
|
||
class Test5 { | ||
private _property: string; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~ [Private property for getter or setter must be declared after them.] | ||
|
||
get property() { | ||
return this._property; | ||
} | ||
} | ||
|
||
class Test6 { | ||
private _property: string; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~ [Private property with leading underscore must be used only for getter or setter.] | ||
} | ||
|
||
class Test7 { | ||
set property(value) { | ||
this._property = value; | ||
} | ||
|
||
private _property: string; | ||
} | ||
|
||
class Test8 { | ||
get property() { | ||
return this._property; | ||
} | ||
|
||
private _property: string; | ||
} | ||
|
||
class Test9 { | ||
private _property: string; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~ [Private property for getter or setter must be declared after them.] | ||
|
||
set property(value) { | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
this._property = value; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
} | ||
~~~~~ [Setters must be declared after getters.] | ||
|
||
get property() { | ||
~~~~~~~~~~~~~~~~ | ||
return this._property; | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
} | ||
~~~~~ [Getters must be declared before setters.] | ||
} |
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,5 @@ | ||
{ | ||
"rules": { | ||
"orthodox-getter-and-setter": true | ||
} | ||
} |