mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-16 10:33:43 +08:00
fix(@angular-devkit/build-optimizer): don't add pure comments to tslib helpers (#15303)
Closes #15301
This commit is contained in:
parent
b3b45469f5
commit
e2bb482b44
@ -28,6 +28,7 @@ ts_library(
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/webpack",
|
||||
"@npm//source-map",
|
||||
"@npm//tslib",
|
||||
"@npm//typescript",
|
||||
],
|
||||
)
|
||||
|
@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"loader-utils": "1.2.3",
|
||||
"source-map": "0.7.3",
|
||||
"tslib": "1.10.0",
|
||||
"typescript": "3.5.3",
|
||||
"webpack-sources": "1.4.3"
|
||||
}
|
||||
|
@ -100,6 +100,44 @@ describe('build-optimizer', () => {
|
||||
expect(boOutput.emitSkipped).toEqual(false);
|
||||
});
|
||||
|
||||
it(`doesn't add pure comments to tslib helpers`, () => {
|
||||
const input = tags.stripIndent`
|
||||
class LanguageState {
|
||||
}
|
||||
|
||||
LanguageState.ctorParameters = () => [
|
||||
{ type: TranslateService },
|
||||
{ type: undefined, decorators: [{ type: Inject, args: [LANGUAGE_CONFIG,] }] }
|
||||
];
|
||||
|
||||
__decorate([
|
||||
Action(CheckLanguage),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], LanguageState.prototype, "checkLanguage", null);
|
||||
`;
|
||||
|
||||
const output = tags.oneLine`
|
||||
let LanguageState = /*@__PURE__*/ (() => {
|
||||
class LanguageState {
|
||||
}
|
||||
|
||||
__decorate([
|
||||
Action(CheckLanguage),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], LanguageState.prototype, "checkLanguage", null);
|
||||
return LanguageState;
|
||||
})();
|
||||
`;
|
||||
|
||||
const boOutput = buildOptimizer({ content: input, isSideEffectFree: true });
|
||||
expect(tags.oneLine`${boOutput.content}`).toEqual(output);
|
||||
expect(boOutput.emitSkipped).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not wrap classes which had all static properties dropped in IIFE', () => {
|
||||
const classDeclaration = tags.oneLine`
|
||||
import { Injectable } from '@angular/core';
|
||||
|
@ -5,10 +5,15 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as tslib from 'tslib';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
const pureFunctionComment = '@__PURE__';
|
||||
|
||||
// We include only exports that start with '__' because tslib helpers
|
||||
// all start with a suffix of two underscores.
|
||||
const tslibHelpers = new Set<string>(Object.keys(tslib).filter(h => h.startsWith('__')));
|
||||
|
||||
// Find all nodes from the AST in the subtree of node of SyntaxKind kind.
|
||||
export function collectDeepNodes<T extends ts.Node>(node: ts.Node, kind: ts.SyntaxKind): T[] {
|
||||
const nodes: T[] = [];
|
||||
@ -41,3 +46,7 @@ export function hasPureComment(node: ts.Node): boolean {
|
||||
|
||||
return !!leadingComment && leadingComment.some(comment => comment.text === pureFunctionComment);
|
||||
}
|
||||
|
||||
export function isHelperName(name: string): boolean {
|
||||
return tslibHelpers.has(name);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
import { isHelperName } from '../helpers/ast-utils';
|
||||
|
||||
/**
|
||||
* @deprecated From 0.9.0
|
||||
@ -89,15 +90,3 @@ function createTslibImport(
|
||||
return newNode;
|
||||
}
|
||||
}
|
||||
|
||||
function isHelperName(name: string): boolean {
|
||||
// TODO: there are more helpers than these, should we replace them all?
|
||||
const tsHelpers = [
|
||||
'__extends',
|
||||
'__decorate',
|
||||
'__metadata',
|
||||
'__param',
|
||||
];
|
||||
|
||||
return tsHelpers.indexOf(name) !== -1;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
import { addPureComment, hasPureComment } from '../helpers/ast-utils';
|
||||
import { addPureComment, hasPureComment, isHelperName } from '../helpers/ast-utils';
|
||||
|
||||
export function getPrefixFunctionsTransformer(): ts.TransformerFactory<ts.SourceFile> {
|
||||
return (context: ts.TransformationContext): ts.Transformer<ts.SourceFile> => {
|
||||
@ -44,10 +44,8 @@ export function findTopLevelFunctions(parentNode: ts.Node): Set<ts.Node> {
|
||||
// need to mark function calls inside them as pure.
|
||||
// Class static initializers in ES2015 are an exception we don't cover. They would need similar
|
||||
// processing as enums to prevent property setting from causing the class to be retained.
|
||||
if (ts.isFunctionDeclaration(node)
|
||||
|| ts.isFunctionExpression(node)
|
||||
|| ts.isClassDeclaration(node)
|
||||
|| ts.isClassExpression(node)
|
||||
if (ts.isFunctionLike(node)
|
||||
|| ts.isClassLike(node)
|
||||
|| ts.isArrowFunction(node)
|
||||
|| ts.isMethodDeclaration(node)
|
||||
) {
|
||||
@ -78,9 +76,15 @@ export function findTopLevelFunctions(parentNode: ts.Node): Set<ts.Node> {
|
||||
topLevelFunctions.add(node);
|
||||
} else if (ts.isCallExpression(innerNode)) {
|
||||
let expression: ts.Expression = innerNode.expression;
|
||||
|
||||
if (ts.isIdentifier(expression) && isHelperName(expression.text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (expression && ts.isParenthesizedExpression(expression)) {
|
||||
expression = expression.expression;
|
||||
}
|
||||
|
||||
if (expression) {
|
||||
if (ts.isFunctionExpression(expression)) {
|
||||
// Skip IIFE's with arguments
|
||||
|
@ -186,4 +186,28 @@ describe('prefix-functions', () => {
|
||||
|
||||
expect(tags.oneLine`${transform(input)}`).toEqual(tags.oneLine`${output}`);
|
||||
});
|
||||
|
||||
it(`doesn't add pure comments to tslib helpers`, () => {
|
||||
const input = tags.stripIndent`
|
||||
class LanguageState {
|
||||
|
||||
}
|
||||
|
||||
LanguageState.ctorParameters = () => [
|
||||
{ type: TranslateService },
|
||||
{ type: undefined, decorators: [{ type: Inject, args: [LANGUAGE_CONFIG,] }] }
|
||||
];
|
||||
|
||||
__decorate([
|
||||
Action(CheckLanguage),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], LanguageState.prototype, "checkLanguage", null);
|
||||
`;
|
||||
|
||||
const output = input;
|
||||
|
||||
expect(tags.oneLine`${transform(input)}`).toEqual(tags.oneLine`${output}`);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user