Skip to content

Commit

Permalink
ci: Ban introduction of more zone-dependent code (#28711)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba authored Mar 12, 2024
1 parent 9d18c89 commit d8a3ab7
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
52 changes: 52 additions & 0 deletions tools/tslint-rules/noZoneDependenciesRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as Lint from 'tslint';
import ts from 'typescript';
import minimatch from 'minimatch';

/**
* NgZone properties that are ok to access.
*/
const allowedNgZoneProperties = new Set<string>(['run', 'runOutsideAngular']);

/** Rule to prevent adding code that depends on using zones. */
export class Rule extends Lint.Rules.TypedRule {
applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
return this.applyWithWalker(
new Walker(sourceFile, this.getOptions(), program.getTypeChecker()),
);
}
}

class Walker extends Lint.RuleWalker {
/** Whether the walker should check the current source file. */
private _enabled: boolean;

constructor(
sourceFile: ts.SourceFile,
options: Lint.IOptions,
private _typeChecker: ts.TypeChecker,
) {
super(sourceFile, options);

// Globs that are used to determine which files to lint.
const fileGlobs: string[] = options.ruleArguments[0];

// Whether the file should be checked at all.
this._enabled = !fileGlobs.some(p => minimatch(sourceFile.fileName, p));
}

override visitPropertyAccessExpression(node: ts.PropertyAccessExpression) {
if (!this._enabled) {
return;
}

const classType = this._typeChecker.getTypeAtLocation(node.expression);
const className = classType.symbol && classType.symbol.name;
const propertyName = node.name.text;

if (className === 'NgZone' && !allowedNgZoneProperties.has(propertyName)) {
this.addFailureAtNode(node, `Using NgZone.${propertyName} is not allowed.`);
}

return super.visitPropertyAccessExpression(node);
}
}
21 changes: 20 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,26 @@
],
"no-unescaped-html-tag": true,
// Ensures that all rxjs imports come only from `rxjs` and `rxjs/operators`.
"import-blacklist": [true, ["^rxjs(?!$|/operators$).*", "^@material/"]]
"import-blacklist": [true, ["^rxjs(?!$|/operators$).*", "^@material/"]],
"no-zone-dependencies": [
true,
[
// Tests may need to verify behavior with zones.
"**/*.spec.ts",
// TODO(mmalerba): following files to be cleaned up and removed from this list:
"**/cdk/a11y/focus-trap/focus-trap.ts",
"**/cdk/drag-drop/directives/drag.ts",
"**/cdk/overlay/overlay-ref.ts",
"**/cdk/table/coalesced-style-scheduler.ts",
"**/cdk/table/table.ts",
"**/material/autocomplete/autocomplete-trigger.ts",
"**/material/chips/chip.ts",
"**/material/form-field/form-field.ts",
"**/material/menu/menu.ts",
"**/material/sidenav/drawer.ts",
"**/material/tabs/paginated-tab-header.ts"
]
]
},
"linterOptions": {
"exclude": [
Expand Down

0 comments on commit d8a3ab7

Please sign in to comment.