Skip to content

Commit e49c926

Browse files
alan-agius4clydin
authored andcommitted
refactor(@angular-devkit/build-optimizer): refactor scrub file to use typeguards
1 parent 802d5ad commit e49c926

File tree

1 file changed

+55
-69
lines changed
  • packages/angular_devkit/build_optimizer/src/transforms

1 file changed

+55
-69
lines changed

packages/angular_devkit/build_optimizer/src/transforms/scrub-file.ts

Lines changed: 55 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function testScrubFile(content: string) {
1717
'ɵsetClassMetadata',
1818
];
1919

20-
return markers.some((marker) => content.indexOf(marker) !== -1);
20+
return markers.some((marker) => content.includes(marker));
2121
}
2222

2323
export function getScrubFileTransformer(program?: ts.Program): ts.TransformerFactory<ts.SourceFile> {
@@ -156,7 +156,7 @@ function isDecoratorAssignmentExpression(exprStmt: ts.ExpressionStatement): bool
156156
return false;
157157
}
158158
const expr = exprStmt.expression as ts.BinaryExpression;
159-
if (expr.right.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
159+
if (!ts.isArrayLiteralExpression(expr.right)) {
160160
return false;
161161
}
162162

@@ -169,28 +169,26 @@ function isDecorateAssignmentExpression(
169169
tslibImports: ts.NamespaceImport[],
170170
checker: ts.TypeChecker,
171171
): boolean {
172-
173-
if (exprStmt.expression.kind !== ts.SyntaxKind.BinaryExpression) {
172+
if (!ts.isBinaryExpression(exprStmt.expression)) {
174173
return false;
175174
}
176-
const expr = exprStmt.expression as ts.BinaryExpression;
177-
if (expr.left.kind !== ts.SyntaxKind.Identifier) {
175+
const expr = exprStmt.expression;
176+
if (!ts.isIdentifier(expr.left)) {
178177
return false;
179178
}
180-
const classIdent = expr.left as ts.Identifier;
179+
const classIdent = expr.left;
181180
let callExpr: ts.CallExpression;
182181

183-
if (expr.right.kind === ts.SyntaxKind.CallExpression) {
184-
callExpr = expr.right as ts.CallExpression;
185-
} else if (expr.right.kind === ts.SyntaxKind.BinaryExpression) {
182+
if (ts.isCallExpression(expr.right)) {
183+
callExpr = expr.right;
184+
} else if (ts.isBinaryExpression(expr.right)) {
186185
// `Clazz = Clazz_1 = __decorate([...], Clazz)` can be found when there are static property
187186
// accesses.
188-
const innerExpr = expr.right as ts.BinaryExpression;
189-
if (innerExpr.left.kind !== ts.SyntaxKind.Identifier
190-
|| innerExpr.right.kind !== ts.SyntaxKind.CallExpression) {
187+
const innerExpr = expr.right;
188+
if (!ts.isIdentifier(innerExpr.left) || !ts.isCallExpression(innerExpr.right)) {
191189
return false;
192190
}
193-
callExpr = innerExpr.right as ts.CallExpression;
191+
callExpr = innerExpr.right;
194192
} else {
195193
return false;
196194
}
@@ -202,14 +200,16 @@ function isDecorateAssignmentExpression(
202200
if (callExpr.arguments.length !== 2) {
203201
return false;
204202
}
205-
if (callExpr.arguments[1].kind !== ts.SyntaxKind.Identifier) {
203+
204+
const classArg = callExpr.arguments[1];
205+
if (!ts.isIdentifier(classArg)) {
206206
return false;
207207
}
208-
const classArg = callExpr.arguments[1] as ts.Identifier;
208+
209209
if (classIdent.text !== classArg.text) {
210210
return false;
211211
}
212-
if (callExpr.arguments[0].kind !== ts.SyntaxKind.ArrayLiteralExpression) {
212+
if (!ts.isArrayLiteralExpression(callExpr.arguments[0])) {
213213
return false;
214214
}
215215

@@ -224,20 +224,20 @@ function isAngularDecoratorExpression(
224224
checker: ts.TypeChecker,
225225
): boolean {
226226

227-
if (exprStmt.expression.kind !== ts.SyntaxKind.CallExpression) {
227+
if (!ts.isCallExpression(exprStmt.expression)) {
228228
return false;
229229
}
230-
const callExpr = exprStmt.expression as ts.CallExpression;
230+
const callExpr = exprStmt.expression;
231231
if (!isTslibHelper(callExpr, '__decorate', tslibImports, checker)) {
232232
return false;
233233
}
234234
if (callExpr.arguments.length !== 4) {
235235
return false;
236236
}
237-
if (callExpr.arguments[0].kind !== ts.SyntaxKind.ArrayLiteralExpression) {
237+
const decorateArray = callExpr.arguments[0];
238+
if (!ts.isArrayLiteralExpression(decorateArray)) {
238239
return false;
239240
}
240-
const decorateArray = callExpr.arguments[0] as ts.ArrayLiteralExpression;
241241
// Check first array entry for Angular decorators.
242242
if (decorateArray.elements.length === 0 || !ts.isCallExpression(decorateArray.elements[0])) {
243243
return false;
@@ -283,18 +283,18 @@ function isCtorParamsAssignmentExpression(exprStmt: ts.ExpressionStatement): boo
283283
}
284284

285285
function isAssignmentExpressionTo(exprStmt: ts.ExpressionStatement, name: string) {
286-
if (exprStmt.expression.kind !== ts.SyntaxKind.BinaryExpression) {
286+
if (!ts.isBinaryExpression(exprStmt.expression)) {
287287
return false;
288288
}
289-
const expr = exprStmt.expression as ts.BinaryExpression;
290-
if (expr.left.kind !== ts.SyntaxKind.PropertyAccessExpression) {
289+
const expr = exprStmt.expression;
290+
if (!ts.isPropertyAccessExpression(expr.left)) {
291291
return false;
292292
}
293-
const propAccess = expr.left as ts.PropertyAccessExpression;
293+
const propAccess = expr.left;
294294
if (propAccess.name.text !== name) {
295295
return false;
296296
}
297-
if (propAccess.expression.kind !== ts.SyntaxKind.Identifier) {
297+
if (!ts.isIdentifier(propAccess.expression)) {
298298
return false;
299299
}
300300
if (expr.operatorToken.kind !== ts.SyntaxKind.FirstAssignment) {
@@ -342,7 +342,7 @@ function isIvyPrivateCallExpression(exprStmt: ts.ExpressionStatement) {
342342
return false;
343343
}
344344

345-
if (propAccExpr.name.text != 'ɵsetClassMetadata') {
345+
if (propAccExpr.name.text !== 'ɵsetClassMetadata') {
346346
return false;
347347
}
348348

@@ -396,29 +396,25 @@ function pickDecorateNodesToRemove(
396396
const arrLiteral = expect<ts.ArrayLiteralExpression>(callExpr.arguments[0],
397397
ts.SyntaxKind.ArrayLiteralExpression);
398398

399-
if (!arrLiteral.elements.every((elem) => elem.kind === ts.SyntaxKind.CallExpression)) {
399+
if (!arrLiteral.elements.every((elem) => ts.isCallExpression(elem))) {
400400
return [];
401401
}
402402
const elements = arrLiteral.elements as ts.NodeArray<ts.CallExpression>;
403403
const ngDecoratorCalls = elements.filter((el) => {
404-
if (el.expression.kind !== ts.SyntaxKind.Identifier) {
404+
if (!ts.isIdentifier(el.expression)) {
405405
return false;
406406
}
407-
const id = el.expression as ts.Identifier;
408407

409-
return identifierIsMetadata(id, ngMetadata, checker);
408+
return identifierIsMetadata(el.expression, ngMetadata, checker);
410409
});
411410

412-
413411
// Remove __metadata calls of type 'design:paramtypes'.
414412
const metadataCalls = elements.filter((el) => {
415413
if (!isTslibHelper(el, '__metadata', tslibImports, checker)) {
416414
return false;
417415
}
418-
if (el.arguments.length < 2) {
419-
return false;
420-
}
421-
if (el.arguments[0].kind !== ts.SyntaxKind.StringLiteral) {
416+
417+
if (el.arguments.length < 2 || !ts.isStringLiteral(el.arguments[0])) {
422418
return false;
423419
}
424420

@@ -429,10 +425,8 @@ function pickDecorateNodesToRemove(
429425
if (!isTslibHelper(el, '__param', tslibImports, checker)) {
430426
return false;
431427
}
432-
if (el.arguments.length != 2) {
433-
return false;
434-
}
435-
if (el.arguments[0].kind !== ts.SyntaxKind.NumericLiteral) {
428+
429+
if (el.arguments.length !== 2 || !ts.isNumericLiteral(el.arguments[0])) {
436430
return false;
437431
}
438432

@@ -469,7 +463,7 @@ function pickPropDecorationNodesToRemove(
469463
const decorators =
470464
expect<ts.ArrayLiteralExpression>(assign.initializer,
471465
ts.SyntaxKind.ArrayLiteralExpression).elements;
472-
if (!decorators.every((el) => el.kind === ts.SyntaxKind.ObjectLiteralExpression)) {
466+
if (!decorators.every((el) => ts.isObjectLiteralExpression(el))) {
473467
return [];
474468
}
475469
const decsToRemove = decorators.filter((expression) => {
@@ -507,26 +501,25 @@ function isAngularDecorator(
507501
return false;
508502
}
509503
const assign = expect<ts.PropertyAssignment>(types[0], ts.SyntaxKind.PropertyAssignment);
510-
if (assign.initializer.kind !== ts.SyntaxKind.Identifier) {
504+
if (!ts.isIdentifier(assign.initializer)) {
511505
return false;
512506
}
513-
const id = assign.initializer as ts.Identifier;
507+
const id = assign.initializer;
514508
const res = identifierIsMetadata(id, ngMetadata, checker);
515509

516510
return res;
517511
}
518512

519513
function isTypeProperty(prop: ts.ObjectLiteralElement): boolean {
520-
if (prop.kind !== ts.SyntaxKind.PropertyAssignment) {
514+
if (!ts.isPropertyAssignment(prop)) {
521515
return false;
522516
}
523-
const assignment = prop as ts.PropertyAssignment;
524-
if (assignment.name.kind !== ts.SyntaxKind.Identifier) {
517+
518+
if (!ts.isIdentifier(prop.name)) {
525519
return false;
526520
}
527-
const name = assignment.name as ts.Identifier;
528521

529-
return name.text === 'type';
522+
return prop.name.text === 'type';
530523
}
531524

532525
// Check if an identifier is part of the known Angular Metadata.
@@ -542,30 +535,23 @@ function identifierIsMetadata(
542535

543536
return symbol
544537
.declarations
545-
.some((spec) => metadata.indexOf(spec) !== -1);
546-
}
547-
548-
// Check if an import is a tslib helper import (`import * as tslib from "tslib";`)
549-
function isTslibImport(node: ts.ImportDeclaration): boolean {
550-
return !!(node.moduleSpecifier &&
551-
node.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral &&
552-
(node.moduleSpecifier as ts.StringLiteral).text === 'tslib' &&
553-
node.importClause &&
554-
node.importClause.namedBindings &&
555-
node.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport);
538+
.some((spec) => metadata.includes(spec));
556539
}
557540

558541
// Find all namespace imports for `tslib`.
559542
function findTslibImports(node: ts.Node): ts.NamespaceImport[] {
560543
const imports: ts.NamespaceImport[] = [];
561-
ts.forEachChild(node, (child) => {
562-
if (child.kind === ts.SyntaxKind.ImportDeclaration) {
563-
const importDecl = child as ts.ImportDeclaration;
564-
if (isTslibImport(importDecl)) {
565-
const importClause = importDecl.importClause as ts.ImportClause;
566-
const namespaceImport = importClause.namedBindings as ts.NamespaceImport;
567-
imports.push(namespaceImport);
568-
}
544+
545+
ts.forEachChild(node, child => {
546+
if (
547+
ts.isImportDeclaration(child) &&
548+
child.moduleSpecifier &&
549+
ts.isStringLiteral(child.moduleSpecifier) &&
550+
child.moduleSpecifier.text === 'tslib' &&
551+
child.importClause?.namedBindings &&
552+
ts.isNamespaceImport(child.importClause.namedBindings)
553+
) {
554+
imports.push(child.importClause.namedBindings);
569555
}
570556
});
571557

@@ -585,7 +571,7 @@ function identifierIsTslib(
585571

586572
return symbol
587573
.declarations
588-
.some((spec) => tslibImports.indexOf(spec as ts.NamespaceImport) !== -1);
574+
.some((spec) => tslibImports.includes(spec as ts.NamespaceImport));
589575
}
590576

591577
// Check if a function call is a tslib helper.
@@ -595,7 +581,7 @@ function isTslibHelper(
595581
tslibImports: ts.NamespaceImport[],
596582
checker: ts.TypeChecker,
597583
) {
598-
let name;
584+
let name: string | undefined;
599585

600586
if (ts.isIdentifier(callExpr.expression)) {
601587
name = callExpr.expression.text;

0 commit comments

Comments
 (0)