Skip to content

Commit 0ef9e38

Browse files
devversionjelbourn
authored andcommitted
refactor(schematics): remove type checker for inheritance rule (#12802)
No longer depends on type checking when checking the heritage clauses of a `ClassDeclaration`.
1 parent 0df720c commit 0ef9e38

File tree

2 files changed

+45
-21
lines changed

2 files changed

+45
-21
lines changed

src/lib/schematics/update/rules/checkInheritanceRule.ts

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,59 @@
99
import {bold, green, red} from 'chalk';
1010
import {ProgramAwareRuleWalker, RuleFailure, Rules} from 'tslint';
1111
import * as ts from 'typescript';
12-
import {propertyNames} from '../material/data/property-names';
12+
import {MaterialPropertyNameData, propertyNames} from '../material/data/property-names';
1313

1414
/**
15-
* Rule that walks through every property access expression and updates properties that have
16-
* been changed in favor of the new name.
15+
* Map of classes that have been updated. Each class name maps to the according property change
16+
* data.
17+
*/
18+
const changedClassesMap = new Map<string, MaterialPropertyNameData>();
19+
20+
propertyNames.filter(data => data.whitelist && data.whitelist.classes).forEach(data => {
21+
data.whitelist.classes.forEach(name => changedClassesMap.set(name, data));
22+
});
23+
24+
/**
25+
* Rule that identifies class declarations that extend CDK or Material classes and had
26+
* a public property change.
1727
*/
1828
export class Rule extends Rules.TypedRule {
1929
applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): RuleFailure[] {
20-
return this.applyWithWalker(
21-
new CheckInheritanceWalker(sourceFile, this.getOptions(), program));
30+
return this.applyWithWalker(new Walker(sourceFile, this.getOptions(), program));
2231
}
2332
}
2433

25-
export class CheckInheritanceWalker extends ProgramAwareRuleWalker {
26-
visitClassDeclaration(declaration: ts.ClassDeclaration) {
27-
// Check if user is extending an Angular Material class whose properties have changed.
28-
const type = this.getTypeChecker().getTypeAtLocation(declaration.name);
29-
const baseTypes = this.getTypeChecker().getBaseTypes(type as ts.InterfaceType);
30-
baseTypes.forEach(t => {
31-
const propertyData = propertyNames.find(
32-
data => data.whitelist && new Set(data.whitelist.classes).has(t.symbol.name));
33-
if (propertyData) {
34-
this.addFailureAtNode(
35-
declaration,
36-
`Found class "${bold(declaration.name.text)}" which extends class` +
37-
` "${bold(t.symbol.name)}". Please note that the base class property` +
38-
` "${red(propertyData.replace)}" has changed to "${green(propertyData.replaceWith)}".` +
39-
` You may need to update your class as well`);
34+
export class Walker extends ProgramAwareRuleWalker {
35+
36+
visitClassDeclaration(node: ts.ClassDeclaration) {
37+
const baseTypes = this._determineBaseTypes(node);
38+
39+
if (!baseTypes) {
40+
return;
41+
}
42+
43+
baseTypes.forEach(typeName => {
44+
const data = changedClassesMap.get(typeName);
45+
46+
if (data) {
47+
this.addFailureAtNode(node,
48+
`Found class "${bold(node.name.text)}" which extends class ` +
49+
`"${bold(typeName)}". Please note that the base class property ` +
50+
`"${red(data.replace)}" has changed to "${green(data.replaceWith)}". ` +
51+
`You may need to update your class as well`);
4052
}
4153
});
4254
}
55+
56+
private _determineBaseTypes(node: ts.ClassDeclaration): string[] | null {
57+
if (!node.heritageClauses) {
58+
return null;
59+
}
60+
61+
return node.heritageClauses
62+
.reduce((types, clause) => types.concat(clause.types), [])
63+
.map(typeExpression => typeExpression.expression)
64+
.filter(expression => expression && ts.isIdentifier(expression))
65+
.map(identifier => identifier.text);
66+
}
4367
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
describe('material-nav-schematic', () => {});
1+
describe('Material Update Tool', () => {});

0 commit comments

Comments
 (0)