Skip to content

Commit 7699388

Browse files
karahansl
authored andcommitted
fix(@angular-devkit/build-optimizer): fix decorator scrubbing with 2.4
1 parent 5484e03 commit 7699388

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@ export function getScrubFileTransformer(program: ts.Program): ts.TransformerFact
5656
const ngMetadata = findAngularMetadata(sf);
5757

5858
const nodes: ts.Node[] = [];
59-
ts.forEachChild(sf, (node) => {
59+
ts.forEachChild(sf, checkNodeForDecorators);
60+
61+
function checkNodeForDecorators(node: ts.Node): void {
6062
if (node.kind !== ts.SyntaxKind.ExpressionStatement) {
61-
return;
63+
// TS 2.4 nests decorators inside downleveled class IIFEs, so we
64+
// must recurse into them to find the relevant expression statements.
65+
return ts.forEachChild(node, checkNodeForDecorators);
6266
}
6367
const exprStmt = node as ts.ExpressionStatement;
6468
if (isDecoratorAssignmentExpression(exprStmt)) {
@@ -71,7 +75,7 @@ export function getScrubFileTransformer(program: ts.Program): ts.TransformerFact
7175
&& !isCtorParamsWhitelistedService(exprStmt)) {
7276
nodes.push(node);
7377
}
74-
});
78+
}
7579

7680
const visitor: ts.Visitor = (node: ts.Node): ts.Node => {
7781
// Check if node is a statement to be dropped.

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

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('scrub-file', () => {
1717
const clazz = 'var Clazz = (function () { function Clazz() { } return Clazz; }());';
1818

1919
describe('decorators', () => {
20-
it('removes Angular decorators', () => {
20+
it('removes top-level Angular decorators', () => {
2121
const output = stripIndent`
2222
import { Injectable } from '@angular/core';
2323
${clazz}
@@ -31,6 +31,26 @@ describe('scrub-file', () => {
3131
expect(oneLine`${transform(input)}`).toEqual(oneLine`${output}`);
3232
});
3333

34+
it('removes nested Angular decorators', () => {
35+
const output = stripIndent`
36+
import { Injectable } from '@angular/core';
37+
var Clazz = (function () {
38+
function Clazz() { }
39+
return Clazz;
40+
}());
41+
`;
42+
const input = stripIndent`
43+
import { Injectable } from '@angular/core';
44+
var Clazz = (function () {
45+
function Clazz() {}
46+
Clazz.decorators = [ { type: Injectable } ];
47+
return Clazz;
48+
}());
49+
`;
50+
51+
expect(oneLine`${transform(input)}`).toEqual(oneLine`${output}`);
52+
});
53+
3454
it('doesn\'t remove non Angular decorators', () => {
3555
const input = stripIndent`
3656
import { Injectable } from 'another-lib';
@@ -41,7 +61,7 @@ describe('scrub-file', () => {
4161
expect(oneLine`${transform(input)}`).toEqual(oneLine`${input}`);
4262
});
4363

44-
it('leaves non-Angulars decorators in mixed arrays', () => {
64+
it('leaves non-Angular decorators in mixed arrays', () => {
4565
const input = stripIndent`
4666
import { Injectable } from '@angular/core';
4767
import { NotInjectable } from 'another-lib';
@@ -60,7 +80,7 @@ describe('scrub-file', () => {
6080
});
6181

6282
describe('propDecorators', () => {
63-
it('removes Angular propDecorators', () => {
83+
it('removes top-level Angular propDecorators', () => {
6484
const output = stripIndent`
6585
import { Input } from '@angular/core';
6686
${clazz}
@@ -74,6 +94,26 @@ describe('scrub-file', () => {
7494
expect(oneLine`${transform(input)}`).toEqual(oneLine`${output}`);
7595
});
7696

97+
it('removes nested Angular propDecorators', () => {
98+
const output = stripIndent`
99+
import { Input } from '@angular/core';
100+
var Clazz = (function () {
101+
function Clazz() { }
102+
return Clazz;
103+
}());
104+
`;
105+
const input = stripIndent`
106+
import { Input } from '@angular/core';
107+
var Clazz = (function () {
108+
function Clazz() {}
109+
Clazz.propDecorators = { 'ngIf': [{ type: Input }] };
110+
return Clazz;
111+
}());
112+
`;
113+
114+
expect(oneLine`${transform(input)}`).toEqual(oneLine`${output}`);
115+
});
116+
77117
it('doesn\'t remove non Angular propDecorators', () => {
78118
const input = stripIndent`
79119
import { Input } from 'another-lib';
@@ -84,7 +124,7 @@ describe('scrub-file', () => {
84124
expect(oneLine`${transform(input)}`).toEqual(oneLine`${input}`);
85125
});
86126

87-
it('leaves non-Angulars propDecorators in mixed arrays', () => {
127+
it('leaves non-Angular propDecorators in mixed arrays', () => {
88128
const output = stripIndent`
89129
import { Input } from '@angular/core';
90130
import { NotInput } from 'another-lib';
@@ -121,7 +161,7 @@ describe('scrub-file', () => {
121161
expect(oneLine`${transform(input)}`).toEqual(oneLine`${output}`);
122162
});
123163

124-
it('removes non-empty constructor parameters', () => {
164+
it('removes non-empty top-level style constructor parameters', () => {
125165
const output = stripIndent`
126166
${clazz}
127167
`;
@@ -133,6 +173,26 @@ describe('scrub-file', () => {
133173
expect(oneLine`${transform(input)}`).toEqual(oneLine`${output}`);
134174
});
135175

176+
it('removes nested constructor parameters', () => {
177+
const output = stripIndent`
178+
import { Injector } from '@angular/core';
179+
var Clazz = (function () {
180+
function Clazz() { }
181+
return Clazz;
182+
}());
183+
`;
184+
const input = stripIndent`
185+
import { Injector } from '@angular/core';
186+
var Clazz = (function () {
187+
function Clazz() {}
188+
Clazz.ctorParameters = function () { return [{type: Injector}]; };
189+
return Clazz;
190+
}());
191+
`;
192+
193+
expect(oneLine`${transform(input)}`).toEqual(oneLine`${output}`);
194+
});
195+
136196
it('doesn\'t remove constructor parameters from whitelisted classes', () => {
137197
const input = stripIndent`
138198
${clazz.replace('Clazz', 'PlatformRef_')}

0 commit comments

Comments
 (0)