@angular-devkit/build-optimizer 0.800.0 → 0.800.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
*/
|
|
10
10
|
const fs_1 = require("fs");
|
|
11
11
|
const transform_javascript_1 = require("../helpers/transform-javascript");
|
|
12
|
-
const class_fold_1 = require("../transforms/class-fold");
|
|
13
12
|
const import_tslib_1 = require("../transforms/import-tslib");
|
|
14
13
|
const prefix_classes_1 = require("../transforms/prefix-classes");
|
|
15
14
|
const prefix_functions_1 = require("../transforms/prefix-functions");
|
|
@@ -86,12 +85,12 @@ function buildOptimizer(options) {
|
|
|
86
85
|
// It will mark both `require()` calls and `console.log(stuff)` as pure.
|
|
87
86
|
// We only apply it to whitelisted modules, since we know they are safe.
|
|
88
87
|
// getPrefixFunctionsTransformer needs to be before getFoldFileTransformer.
|
|
89
|
-
prefix_functions_1.getPrefixFunctionsTransformer, selectedGetScrubFileTransformer
|
|
88
|
+
prefix_functions_1.getPrefixFunctionsTransformer, selectedGetScrubFileTransformer);
|
|
90
89
|
typeCheck = true;
|
|
91
90
|
}
|
|
92
91
|
else if (scrub_file_1.testScrubFile(content)) {
|
|
93
92
|
// Always test as these require the type checker
|
|
94
|
-
getTransforms.push(selectedGetScrubFileTransformer
|
|
93
|
+
getTransforms.push(selectedGetScrubFileTransformer);
|
|
95
94
|
typeCheck = true;
|
|
96
95
|
}
|
|
97
96
|
// tests are not needed for fast path
|
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
*/
|
|
10
10
|
const ts = require("typescript");
|
|
11
11
|
const ast_utils_1 = require("../helpers/ast-utils");
|
|
12
|
+
/** @deprecated Since version 8 */
|
|
12
13
|
function getFoldFileTransformer(program) {
|
|
13
14
|
const checker = program.getTypeChecker();
|
|
14
15
|
return (context) => {
|
|
@@ -54,8 +54,10 @@ function visitBlockStatements(statements, context) {
|
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
// 'oIndex' is the original statement index; 'uIndex' is the updated statement index
|
|
57
|
-
for (let oIndex = 0, uIndex = 0; oIndex < statements.length; oIndex++, uIndex++) {
|
|
57
|
+
for (let oIndex = 0, uIndex = 0; oIndex < statements.length - 1; oIndex++, uIndex++) {
|
|
58
58
|
const currentStatement = statements[oIndex];
|
|
59
|
+
let newStatement;
|
|
60
|
+
let oldStatementsLength = 0;
|
|
59
61
|
// these can't contain an enum declaration
|
|
60
62
|
if (currentStatement.kind === ts.SyntaxKind.ImportDeclaration) {
|
|
61
63
|
continue;
|
|
@@ -65,44 +67,42 @@ function visitBlockStatements(statements, context) {
|
|
|
65
67
|
// * be a variable statement
|
|
66
68
|
// * have only one declaration
|
|
67
69
|
// * have an identifer as a declaration name
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
// ClassExpression declarations must:
|
|
71
|
+
// * not be last statement
|
|
72
|
+
// * be a variable statement
|
|
73
|
+
// * have only one declaration
|
|
74
|
+
// * have an ClassExpression or BinaryExpression and a right
|
|
75
|
+
// of kind ClassExpression as a initializer
|
|
76
|
+
if (ts.isVariableStatement(currentStatement)
|
|
70
77
|
&& currentStatement.declarationList.declarations.length === 1) {
|
|
71
78
|
const variableDeclaration = currentStatement.declarationList.declarations[0];
|
|
79
|
+
const initializer = variableDeclaration.initializer;
|
|
72
80
|
if (ts.isIdentifier(variableDeclaration.name)) {
|
|
73
81
|
const name = variableDeclaration.name.text;
|
|
74
|
-
if (!
|
|
82
|
+
if (!initializer) {
|
|
75
83
|
const iife = findTs2_3EnumIife(name, statements[oIndex + 1]);
|
|
76
84
|
if (iife) {
|
|
77
|
-
// found an enum
|
|
78
|
-
if (!updatedStatements) {
|
|
79
|
-
updatedStatements = statements.slice();
|
|
80
|
-
}
|
|
81
85
|
// update IIFE and replace variable statement and old IIFE
|
|
82
|
-
|
|
86
|
+
oldStatementsLength = 2;
|
|
87
|
+
newStatement = updateEnumIife(currentStatement, iife[0], iife[1]);
|
|
83
88
|
// skip IIFE statement
|
|
84
89
|
oIndex++;
|
|
85
|
-
continue;
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
|
-
else if (ts.isObjectLiteralExpression(
|
|
89
|
-
&&
|
|
92
|
+
else if (ts.isObjectLiteralExpression(initializer)
|
|
93
|
+
&& initializer.properties.length === 0) {
|
|
90
94
|
const enumStatements = findTs2_2EnumStatements(name, statements, oIndex + 1);
|
|
91
95
|
if (enumStatements.length > 0) {
|
|
92
|
-
// found an enum
|
|
93
|
-
if (!updatedStatements) {
|
|
94
|
-
updatedStatements = statements.slice();
|
|
95
|
-
}
|
|
96
96
|
// create wrapper and replace variable statement and enum member statements
|
|
97
|
-
|
|
97
|
+
oldStatementsLength = enumStatements.length + 1;
|
|
98
|
+
newStatement = createWrappedEnum(name, currentStatement, enumStatements, initializer);
|
|
98
99
|
// skip enum member declarations
|
|
99
100
|
oIndex += enumStatements.length;
|
|
100
|
-
continue;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
else if (ts.isObjectLiteralExpression(
|
|
104
|
-
&&
|
|
105
|
-
const literalPropertyCount =
|
|
103
|
+
else if (ts.isObjectLiteralExpression(initializer)
|
|
104
|
+
&& initializer.properties.length !== 0) {
|
|
105
|
+
const literalPropertyCount = initializer.properties.length;
|
|
106
106
|
// tsickle es2015 enums first statement is an export declaration
|
|
107
107
|
const isPotentialEnumExport = ts.isExportDeclaration(statements[oIndex + 1]);
|
|
108
108
|
if (isPotentialEnumExport) {
|
|
@@ -111,20 +111,45 @@ function visitBlockStatements(statements, context) {
|
|
|
111
111
|
}
|
|
112
112
|
const enumStatements = findEnumNameStatements(name, statements, oIndex + 1);
|
|
113
113
|
if (enumStatements.length === literalPropertyCount) {
|
|
114
|
-
// found an enum
|
|
115
|
-
if (!updatedStatements) {
|
|
116
|
-
updatedStatements = statements.slice();
|
|
117
|
-
}
|
|
118
114
|
// create wrapper and replace variable statement and enum member statements
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
oldStatementsLength = enumStatements.length + (isPotentialEnumExport ? 2 : 1);
|
|
116
|
+
newStatement = createWrappedEnum(name, currentStatement, enumStatements, initializer, isPotentialEnumExport);
|
|
121
117
|
// skip enum member declarations
|
|
122
118
|
oIndex += enumStatements.length;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else if (ts.isClassExpression(initializer)
|
|
122
|
+
|| (ts.isBinaryExpression(initializer)
|
|
123
|
+
&& ts.isClassExpression(initializer.right))) {
|
|
124
|
+
const classStatements = findClassStatements(name, statements, oIndex);
|
|
125
|
+
if (!classStatements) {
|
|
123
126
|
continue;
|
|
124
127
|
}
|
|
128
|
+
oldStatementsLength = classStatements.length;
|
|
129
|
+
newStatement = createWrappedClass(variableDeclaration, classStatements);
|
|
130
|
+
oIndex += classStatements.length - 1;
|
|
125
131
|
}
|
|
126
132
|
}
|
|
127
133
|
}
|
|
134
|
+
else if (ts.isClassDeclaration(currentStatement)) {
|
|
135
|
+
const name = currentStatement.name.text;
|
|
136
|
+
const classStatements = findClassStatements(name, statements, oIndex);
|
|
137
|
+
if (!classStatements) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
oldStatementsLength = classStatements.length;
|
|
141
|
+
newStatement = createWrappedClass(currentStatement, classStatements);
|
|
142
|
+
oIndex += classStatements.length - 1;
|
|
143
|
+
}
|
|
144
|
+
if (newStatement && newStatement.length > 0) {
|
|
145
|
+
if (!updatedStatements) {
|
|
146
|
+
updatedStatements = [...statements];
|
|
147
|
+
}
|
|
148
|
+
updatedStatements.splice(uIndex, oldStatementsLength, ...newStatement);
|
|
149
|
+
// When having more than a single new statement
|
|
150
|
+
// we need to update the update Index
|
|
151
|
+
uIndex += (newStatement ? newStatement.length - 1 : 0);
|
|
152
|
+
}
|
|
128
153
|
const result = ts.visitNode(currentStatement, visitor);
|
|
129
154
|
if (result !== currentStatement) {
|
|
130
155
|
if (!updatedStatements) {
|
|
@@ -210,7 +235,12 @@ function findTs2_3EnumIife(name, statement) {
|
|
|
210
235
|
return null;
|
|
211
236
|
}
|
|
212
237
|
const memberArgument = assignment.argumentExpression;
|
|
213
|
-
|
|
238
|
+
// String enum
|
|
239
|
+
if (ts.isStringLiteral(memberArgument)) {
|
|
240
|
+
return [callExpression, exportExpression];
|
|
241
|
+
}
|
|
242
|
+
// Non string enums
|
|
243
|
+
if (!ts.isBinaryExpression(memberArgument)
|
|
214
244
|
|| memberArgument.operatorToken.kind !== ts.SyntaxKind.FirstAssignment) {
|
|
215
245
|
return null;
|
|
216
246
|
}
|
|
@@ -307,6 +337,66 @@ function updateHostNode(hostNode, expression) {
|
|
|
307
337
|
]));
|
|
308
338
|
return outerVarStmt;
|
|
309
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* Find class expression or declaration statements.
|
|
342
|
+
*
|
|
343
|
+
* The classExpressions block to wrap in an iife must
|
|
344
|
+
* - end with an ExpressionStatement
|
|
345
|
+
* - it's expression must be a BinaryExpression
|
|
346
|
+
* - have the same name
|
|
347
|
+
*
|
|
348
|
+
* ```
|
|
349
|
+
let Foo = class Foo {};
|
|
350
|
+
Foo = __decorate([]);
|
|
351
|
+
```
|
|
352
|
+
*/
|
|
353
|
+
function findClassStatements(name, statements, statementIndex) {
|
|
354
|
+
let count = 1;
|
|
355
|
+
for (let index = statementIndex + 1; index < statements.length; ++index) {
|
|
356
|
+
const statement = statements[index];
|
|
357
|
+
if (!ts.isExpressionStatement(statement)) {
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
const expression = statement.expression;
|
|
361
|
+
if (ts.isCallExpression(expression)) {
|
|
362
|
+
// Ex:
|
|
363
|
+
// setClassMetadata(FooClass, [{}], void 0);
|
|
364
|
+
// __decorate([propDecorator()], FooClass.prototype, "propertyName", void 0);
|
|
365
|
+
// __decorate([propDecorator()], FooClass, "propertyName", void 0);
|
|
366
|
+
// __decorate$1([propDecorator()], FooClass, "propertyName", void 0);
|
|
367
|
+
const args = expression.arguments;
|
|
368
|
+
if (args.length > 2) {
|
|
369
|
+
const isReferenced = args.some(arg => {
|
|
370
|
+
const potentialIdentifier = ts.isPropertyAccessExpression(arg) ? arg.expression : arg;
|
|
371
|
+
return ts.isIdentifier(potentialIdentifier) && potentialIdentifier.text === name;
|
|
372
|
+
});
|
|
373
|
+
if (isReferenced) {
|
|
374
|
+
count++;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
else if (ts.isBinaryExpression(expression)) {
|
|
380
|
+
const node = ts.isBinaryExpression(expression.left)
|
|
381
|
+
? expression.left.left
|
|
382
|
+
: expression.left;
|
|
383
|
+
const leftExpression = ts.isPropertyAccessExpression(node)
|
|
384
|
+
// Static Properties // Ex: Foo.bar = 'value';
|
|
385
|
+
? node.expression
|
|
386
|
+
// Ex: FooClass = __decorate([Component()], FooClass);
|
|
387
|
+
: node;
|
|
388
|
+
if (ts.isIdentifier(leftExpression) && leftExpression.text === name) {
|
|
389
|
+
count++;
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
if (count > 1) {
|
|
396
|
+
return statements.slice(statementIndex, statementIndex + count);
|
|
397
|
+
}
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
310
400
|
function updateEnumIife(hostNode, iife, exportAssignment) {
|
|
311
401
|
if (!ts.isParenthesizedExpression(iife.expression)
|
|
312
402
|
|| !ts.isFunctionExpression(iife.expression.expression)) {
|
|
@@ -331,10 +421,9 @@ function updateEnumIife(hostNode, iife, exportAssignment) {
|
|
|
331
421
|
if (exportAssignment) {
|
|
332
422
|
value = ts.createBinary(exportAssignment, ts.SyntaxKind.FirstAssignment, updatedIife);
|
|
333
423
|
}
|
|
334
|
-
return updateHostNode(hostNode, value);
|
|
424
|
+
return [updateHostNode(hostNode, value)];
|
|
335
425
|
}
|
|
336
|
-
function createWrappedEnum(name, hostNode, statements, literalInitializer, addExportModifier = false) {
|
|
337
|
-
literalInitializer = literalInitializer || ts.createObjectLiteral();
|
|
426
|
+
function createWrappedEnum(name, hostNode, statements, literalInitializer = ts.createObjectLiteral(), addExportModifier = false) {
|
|
338
427
|
const node = addExportModifier
|
|
339
428
|
? ts.updateVariableStatement(hostNode, [ts.createToken(ts.SyntaxKind.ExportKeyword)], hostNode.declarationList)
|
|
340
429
|
: hostNode;
|
|
@@ -347,5 +436,27 @@ function createWrappedEnum(name, hostNode, statements, literalInitializer, addEx
|
|
|
347
436
|
...statements,
|
|
348
437
|
innerReturn,
|
|
349
438
|
]);
|
|
350
|
-
return updateHostNode(node, ast_utils_1.addPureComment(ts.createParen(iife)));
|
|
439
|
+
return [updateHostNode(node, ast_utils_1.addPureComment(ts.createParen(iife)))];
|
|
440
|
+
}
|
|
441
|
+
function createWrappedClass(hostNode, statements) {
|
|
442
|
+
const name = hostNode.name.text;
|
|
443
|
+
const updatedStatements = [...statements];
|
|
444
|
+
if (ts.isClassDeclaration(hostNode)) {
|
|
445
|
+
updatedStatements[0] = ts.createClassDeclaration(hostNode.decorators, undefined, hostNode.name, hostNode.typeParameters, hostNode.heritageClauses, hostNode.members);
|
|
446
|
+
}
|
|
447
|
+
const pureIife = ast_utils_1.addPureComment(ts.createImmediatelyInvokedArrowFunction([
|
|
448
|
+
...updatedStatements,
|
|
449
|
+
ts.createReturn(ts.createIdentifier(name)),
|
|
450
|
+
]));
|
|
451
|
+
const modifiers = hostNode.modifiers;
|
|
452
|
+
const isDefault = !!modifiers
|
|
453
|
+
&& modifiers.some(x => x.kind === ts.SyntaxKind.DefaultKeyword);
|
|
454
|
+
const newStatement = [];
|
|
455
|
+
newStatement.push(ts.createVariableStatement(isDefault ? undefined : modifiers, ts.createVariableDeclarationList([
|
|
456
|
+
ts.createVariableDeclaration(name, undefined, pureIife),
|
|
457
|
+
], ts.NodeFlags.Const)));
|
|
458
|
+
if (isDefault) {
|
|
459
|
+
newStatement.push(ts.createExportAssignment(undefined, undefined, false, ts.createIdentifier(name)));
|
|
460
|
+
}
|
|
461
|
+
return newStatement;
|
|
351
462
|
}
|