Skip to content

Commit 2364b7c

Browse files
crisbetojelbourn
authored andcommitted
build: add tslint rule to disallow private setters (#12706)
Adds a tslint rule to prevent people from adding private getters since they don't contribute to the public API and they generate more ES5 code.
1 parent ba55d04 commit 2364b7c

File tree

7 files changed

+59
-19
lines changed

7 files changed

+59
-19
lines changed

src/cdk/stepper/stepper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ export class CdkStep implements OnChanges {
117117
/** Whether step is marked as completed. */
118118
@Input()
119119
get completed(): boolean {
120-
return this._customCompleted == null ? this._defaultCompleted : this._customCompleted;
120+
return this._customCompleted == null ? this._defaultCompleted() : this._customCompleted;
121121
}
122122
set completed(value: boolean) {
123123
this._customCompleted = coerceBooleanProperty(value);
124124
}
125125
private _customCompleted: boolean | null = null;
126126

127-
private get _defaultCompleted() {
127+
private _defaultCompleted() {
128128
return this.stepControl ? this.stepControl.valid && this.interacted : this.interacted;
129129
}
130130

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
250250
this.optionSelections,
251251
this.autocomplete._keyManager.tabOut.pipe(filter(() => this._overlayAttached)),
252252
this._closeKeyEventStream,
253-
this._outsideClickStream,
253+
this._getOutsideClickStream(),
254254
this._overlayRef ?
255255
this._overlayRef.detachments().pipe(filter(() => this._overlayAttached)) :
256256
observableOf()
@@ -283,7 +283,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
283283
}
284284

285285
/** Stream of clicks outside of the autocomplete panel. */
286-
private get _outsideClickStream(): Observable<any> {
286+
private _getOutsideClickStream(): Observable<any> {
287287
if (!this._document) {
288288
return observableOf(null);
289289
}

src/lib/menu/menu.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ describe('MatMenu', () => {
777777
}
778778

779779
get overlayRect() {
780-
return this.overlayPane.getBoundingClientRect();
780+
return this.getOverlayPane().getBoundingClientRect();
781781
}
782782

783783
get triggerRect() {
@@ -788,7 +788,7 @@ describe('MatMenu', () => {
788788
return overlayContainerElement.querySelector('.mat-menu-panel');
789789
}
790790

791-
private get overlayPane() {
791+
private getOverlayPane() {
792792
return overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
793793
}
794794
}

src/lib/slider/slider.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ export class MatSlider extends _MatSliderMixinBase
348348
get _trackBackgroundStyles(): { [key: string]: string } {
349349
const axis = this.vertical ? 'Y' : 'X';
350350
const scale = this.vertical ? `1, ${1 - this.percent}, 1` : `${1 - this.percent}, 1, 1`;
351-
const sign = this._invertMouseCoords ? '-' : '';
351+
const sign = this._shouldInvertMouseCoords() ? '-' : '';
352352

353353
return {
354354
// scale3d avoids some rendering issues in Chrome. See #12071.
@@ -360,7 +360,7 @@ export class MatSlider extends _MatSliderMixinBase
360360
get _trackFillStyles(): { [key: string]: string } {
361361
const axis = this.vertical ? 'Y' : 'X';
362362
const scale = this.vertical ? `1, ${this.percent}, 1` : `${this.percent}, 1, 1`;
363-
const sign = this._invertMouseCoords ? '' : '-';
363+
const sign = this._shouldInvertMouseCoords() ? '' : '-';
364364

365365
return {
366366
// scale3d avoids some rendering issues in Chrome. See #12071.
@@ -373,7 +373,7 @@ export class MatSlider extends _MatSliderMixinBase
373373
let axis = this.vertical ? 'Y' : 'X';
374374
// For a horizontal slider in RTL languages we push the ticks container off the left edge
375375
// instead of the right edge to avoid causing a horizontal scrollbar to appear.
376-
let sign = !this.vertical && this._direction == 'rtl' ? '' : '-';
376+
let sign = !this.vertical && this._getDirection() == 'rtl' ? '' : '-';
377377
let offset = this._tickIntervalPercent / 2 * 100;
378378
return {
379379
'transform': `translate${axis}(${sign}${offset}%)`
@@ -388,8 +388,8 @@ export class MatSlider extends _MatSliderMixinBase
388388
// Depending on the direction we pushed the ticks container, push the ticks the opposite
389389
// direction to re-center them but clip off the end edge. In RTL languages we need to flip the
390390
// ticks 180 degrees so we're really cutting off the end edge abd not the start.
391-
let sign = !this.vertical && this._direction == 'rtl' ? '-' : '';
392-
let rotate = !this.vertical && this._direction == 'rtl' ? ' rotate(180deg)' : '';
391+
let sign = !this.vertical && this._getDirection() == 'rtl' ? '-' : '';
392+
let rotate = !this.vertical && this._getDirection() == 'rtl' ? ' rotate(180deg)' : '';
393393
let styles: { [key: string]: string } = {
394394
'backgroundSize': backgroundSize,
395395
// Without translateZ ticks sometimes jitter as the slider moves on Chrome & Firefox.
@@ -411,7 +411,7 @@ export class MatSlider extends _MatSliderMixinBase
411411
// For a horizontal slider in RTL languages we push the thumb container off the left edge
412412
// instead of the right edge to avoid causing a horizontal scrollbar to appear.
413413
let invertOffset =
414-
(this._direction == 'rtl' && !this.vertical) ? !this._invertAxis : this._invertAxis;
414+
(this._getDirection() == 'rtl' && !this.vertical) ? !this._invertAxis : this._invertAxis;
415415
let offset = (invertOffset ? this.percent : 1 - this.percent) * 100;
416416
return {
417417
'transform': `translate${axis}(-${offset}%)`
@@ -442,12 +442,12 @@ export class MatSlider extends _MatSliderMixinBase
442442
* Whether mouse events should be converted to a slider position by calculating their distance
443443
* from the right or bottom edge of the slider as opposed to the top or left.
444444
*/
445-
private get _invertMouseCoords() {
446-
return (this._direction == 'rtl' && !this.vertical) ? !this._invertAxis : this._invertAxis;
445+
private _shouldInvertMouseCoords() {
446+
return (this._getDirection() == 'rtl' && !this.vertical) ? !this._invertAxis : this._invertAxis;
447447
}
448448

449449
/** The language direction for this slider element. */
450-
private get _direction() {
450+
private _getDirection() {
451451
return (this._dir && this._dir.value == 'rtl') ? 'rtl' : 'ltr';
452452
}
453453

@@ -597,14 +597,14 @@ export class MatSlider extends _MatSliderMixinBase
597597
// expect left to mean increment. Therefore we flip the meaning of the side arrow keys for
598598
// RTL. For inverted sliders we prefer a good a11y experience to having it "look right" for
599599
// sighted users, therefore we do not swap the meaning.
600-
this._increment(this._direction == 'rtl' ? 1 : -1);
600+
this._increment(this._getDirection() == 'rtl' ? 1 : -1);
601601
break;
602602
case UP_ARROW:
603603
this._increment(1);
604604
break;
605605
case RIGHT_ARROW:
606606
// See comment on LEFT_ARROW about the conditions under which we flip the meaning.
607-
this._increment(this._direction == 'rtl' ? -1 : 1);
607+
this._increment(this._getDirection() == 'rtl' ? -1 : 1);
608608
break;
609609
case DOWN_ARROW:
610610
this._increment(-1);
@@ -646,7 +646,7 @@ export class MatSlider extends _MatSliderMixinBase
646646
// The exact value is calculated from the event and used to find the closest snap value.
647647
let percent = this._clamp((posComponent - offset) / size);
648648

649-
if (this._invertMouseCoords) {
649+
if (this._shouldInvertMouseCoords()) {
650650
percent = 1 - percent;
651651
}
652652

tools/package-tools/build-package.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class BuildPackage {
3939
private bundler = new PackageBundler(this);
4040

4141
/** Secondary entry-points partitioned by their build depth. */
42-
private get secondaryEntryPointsByDepth(): string[][] {
42+
get secondaryEntryPointsByDepth(): string[][] {
4343
this.cacheSecondaryEntryPoints();
4444
return this._secondaryEntryPointsByDepth;
4545
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as ts from 'typescript';
2+
import * as Lint from 'tslint';
3+
import * as tsutils from 'tsutils';
4+
5+
/**
6+
* Rule that doesn't allow private getters.
7+
*/
8+
export class Rule extends Lint.Rules.AbstractRule {
9+
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
10+
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
11+
}
12+
}
13+
14+
class Walker extends Lint.RuleWalker {
15+
visitGetAccessor(getter: ts.GetAccessorDeclaration) {
16+
// Check whether the getter is private.
17+
if (!getter.modifiers || !getter.modifiers.find(m => m.kind === ts.SyntaxKind.PrivateKeyword)) {
18+
return super.visitGetAccessor(getter);
19+
}
20+
21+
// Check that it's inside a class.
22+
if (!getter.parent || !tsutils.isClassDeclaration(getter.parent)) {
23+
return super.visitGetAccessor(getter);
24+
}
25+
26+
const getterName = getter.name.getText();
27+
const setter = getter.parent.members.find(member => {
28+
return tsutils.isSetAccessorDeclaration(member) && member.name.getText() === getterName;
29+
}) as ts.SetAccessorDeclaration | undefined;
30+
31+
// Only log a failure if it doesn't have a corresponding setter.
32+
if (!setter) {
33+
this.addFailureAtNode(getter, 'Private setters generate unnecessary ' +
34+
'code. Use a function instead.');
35+
}
36+
37+
return super.visitGetAccessor(getter);
38+
}
39+
}

tslint.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"ts-loader": true,
9999
"no-exposed-todo": true,
100100
"no-import-spacing": true,
101+
"no-private-getters": true,
101102
"setters-after-getters": true,
102103
"rxjs-imports": true,
103104
"no-host-decorator-in-concrete": [

0 commit comments

Comments
 (0)