mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
build: add rule to enforce static queries (#15963)
Adds a simplified tslint rule to enforce that we've explicitly set the `static` flag on relevant queries. We don't need the more advanced functionality from the one in angular/angular, because we don't have to figure out which value is correct, only that it is set.
This commit is contained in:
committed by
Jeremy Elbourn
parent
8ab0f6336c
commit
de45fc0831
@@ -54,7 +54,7 @@ interface PeriodicElement {
|
||||
}
|
||||
|
||||
abstract class BaseTestComponent {
|
||||
@ViewChild('table') table: ElementRef;
|
||||
@ViewChild('table', {static: false}) table: ElementRef;
|
||||
|
||||
preservedValues = new Map<number, PeriodicElement>();
|
||||
|
||||
|
||||
@@ -1050,7 +1050,7 @@ class CheckboxWithTabIndex {
|
||||
<mat-checkbox></mat-checkbox>`,
|
||||
})
|
||||
class CheckboxUsingViewChild {
|
||||
@ViewChild(MatCheckbox) checkbox: MatCheckbox;
|
||||
@ViewChild(MatCheckbox, {static: false}) checkbox: MatCheckbox;
|
||||
|
||||
set isDisabled(value: boolean) {
|
||||
this.checkbox.disabled = value;
|
||||
|
||||
@@ -58,7 +58,7 @@ interface PeriodicElement {
|
||||
}
|
||||
|
||||
abstract class BaseTestComponent {
|
||||
@ViewChild('table') table: ElementRef;
|
||||
@ViewChild('table', {static: false}) table: ElementRef;
|
||||
|
||||
preservedValues = new Map<number, PeriodicElement>();
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import * as ts from 'typescript';
|
||||
import * as Lint from 'tslint';
|
||||
|
||||
/**
|
||||
* Rule which enforces that all queries are explicitly marked as static or non-static.
|
||||
*/
|
||||
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 {
|
||||
visitPropertyDeclaration(node: ts.PropertyDeclaration) {
|
||||
const childQueryDecorator = node.decorators && node.decorators.find(decorator => {
|
||||
const expression = (decorator.expression as ts.CallExpression);
|
||||
const name = expression && expression.expression.getText();
|
||||
return name === 'ViewChild' || name === 'ContentChild';
|
||||
});
|
||||
|
||||
if (childQueryDecorator) {
|
||||
const options = (childQueryDecorator.expression as ts.CallExpression).arguments[1];
|
||||
|
||||
if (!options || !ts.isObjectLiteralExpression(options) ||
|
||||
!this._getObjectProperty(options, 'static')) {
|
||||
this.addFailureAtNode(childQueryDecorator,
|
||||
'Queries have to explicitly set the `static` option.');
|
||||
}
|
||||
}
|
||||
|
||||
super.visitPropertyDeclaration(node);
|
||||
}
|
||||
|
||||
/** Gets the node of an object property by name. */
|
||||
private _getObjectProperty(node: ts.ObjectLiteralExpression, name: string) {
|
||||
return node.properties.find(property => (property.name as ts.Identifier).getText() === name);
|
||||
}
|
||||
}
|
||||
@@ -102,6 +102,7 @@
|
||||
"ng-on-changes-property-access": true,
|
||||
"rxjs-imports": true,
|
||||
"require-breaking-change-version": true,
|
||||
"static-query": true,
|
||||
"no-host-decorator-in-concrete": [
|
||||
true,
|
||||
"HostBinding",
|
||||
|
||||
Reference in New Issue
Block a user