Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Commit 3a3259a

Browse files
committed
fix(decorators): don't remove third party transpiled (not static) decorators
1 parent b558584 commit 3a3259a

File tree

2 files changed

+93
-22
lines changed

2 files changed

+93
-22
lines changed

src/optimization/decorators.spec.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,57 @@ var _a, _b;
12791279
const result: string = magicString.toString();
12801280
expect(result.indexOf(injectableDecorator)).toBeGreaterThan(1);
12811281
});
1282+
1283+
it('should not remove the third party decorators', () => {
1284+
1285+
const selectDecorator = `
1286+
__decorate([
1287+
select(),
1288+
__metadata("design:type", Object)
1289+
], DashPage.prototype, "user$", void 0);
1290+
`;
1291+
1292+
const knownContent = `
1293+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
1294+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1295+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1296+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1297+
return c > 3 && r && Object.defineProperty(target, key, r), r;
1298+
};
1299+
var __metadata = (this && this.__metadata) || function (k, v) {
1300+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1301+
};
1302+
import { Component } from '@angular/core';
1303+
import { select } from '@angular-redux/store';
1304+
var DashPage = (function () {
1305+
function DashPage() {
1306+
}
1307+
DashPage.prototype.ionViewDidLoad = function () {
1308+
var _this = this;
1309+
this.user$.subscribe(function (user) {
1310+
_this.user = user;
1311+
});
1312+
};
1313+
return DashPage;
1314+
}());
1315+
${selectDecorator}
1316+
DashPage = __decorate([
1317+
Component({
1318+
selector: 'page-dash',
1319+
templateUrl: 'dash-page.html'
1320+
}),
1321+
__metadata("design:paramtypes", [])
1322+
], DashPage);
1323+
export { DashPage };
1324+
//# sourceMappingURL=dash-page.js.map
1325+
`;
1326+
1327+
let magicString = new MagicString(knownContent);
1328+
const filePath = join(ionicAngular, 'components', 'action-sheet', 'action-sheet-component.js');
1329+
magicString = decorators.purgeTranspiledDecorators(filePath, knownContent, ionicAngular, angularDir, srcDir, magicString);
1330+
const result: string = magicString.toString();
1331+
expect(result.indexOf(selectDecorator)).toBeGreaterThan(1);
1332+
});
12821333
});
12831334

12841335
describe('addPureAnnotation', () => {

src/optimization/decorators.ts

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -68,32 +68,47 @@ function getTranspiledDecoratorExpressionStatements(sourceFile: SourceFile) {
6868
if (expressionStatement && expressionStatement.expression
6969
&& expressionStatement.expression.kind === SyntaxKind.CallExpression
7070
&& (expressionStatement.expression as CallExpression).expression
71-
&& ((expressionStatement.expression as CallExpression).expression as Identifier).text === '___decorate') {
71+
&& ((expressionStatement.expression as CallExpression).expression as Identifier).text === '___decorate'
72+
&& (expressionStatement.expression as CallExpression).arguments
73+
&& (expressionStatement.expression as CallExpression).arguments.length > 0
74+
&& (expressionStatement.expression as CallExpression).arguments[0].kind === SyntaxKind.ArrayLiteralExpression
75+
&& ((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements
76+
&& ((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements.length > 0
77+
&& (((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements[0] as CallExpression).expression
78+
&& (((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements[0] as CallExpression).expression.kind === SyntaxKind.Identifier
79+
&& canRemoveDecoratorNode(((((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements[0] as CallExpression).expression as Identifier).text)
80+
) {
7281

7382
toReturn.push(expressionStatement);
7483

7584
} else if (expressionStatement && expressionStatement.expression
76-
&& expressionStatement.expression.kind === SyntaxKind.BinaryExpression
77-
&& (expressionStatement.expression as BinaryExpression).right
78-
&& (expressionStatement.expression as BinaryExpression).right.kind === SyntaxKind.CallExpression
79-
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).expression
80-
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).expression as Identifier).text === '___decorate') {
81-
82-
((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments.forEach(argument => {
83-
if (argument.kind === SyntaxKind.ArrayLiteralExpression) {
84-
let injectableFound = false;
85-
for (const element of (argument as ArrayLiteralExpression).elements) {
86-
if (element.kind === SyntaxKind.CallExpression && (element as CallExpression).expression
87-
&& ((element as CallExpression).expression as Identifier).text === 'Injectable' ) {
88-
injectableFound = true;
89-
break;
90-
}
91-
}
92-
if (!injectableFound) {
93-
toReturn.push(expressionStatement);
94-
}
85+
&& expressionStatement.expression.kind === SyntaxKind.BinaryExpression
86+
&& (expressionStatement.expression as BinaryExpression).right
87+
&& (expressionStatement.expression as BinaryExpression).right.kind === SyntaxKind.CallExpression
88+
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).expression
89+
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).expression as Identifier).text === '___decorate'
90+
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments
91+
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments.length > 0
92+
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0].kind === SyntaxKind.ArrayLiteralExpression
93+
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements
94+
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements.length > 0 ) {
95+
96+
let immovableDecoratorFound = false;
97+
98+
// remove the last item in the array as it is always __metadata() and should not be considered here
99+
const numElements = (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements.length - 1;
100+
const elementsToEvaluate = (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements.slice(0, numElements);
101+
for (const element of elementsToEvaluate) {
102+
if (element.kind === SyntaxKind.CallExpression && (element as CallExpression).expression
103+
&& !canRemoveDecoratorNode(((element as CallExpression).expression as Identifier).text)) {
104+
105+
immovableDecoratorFound = true;
106+
break;
95107
}
96-
});
108+
}
109+
if (!immovableDecoratorFound) {
110+
toReturn.push(expressionStatement);
111+
}
97112
}
98113
});
99114
return toReturn;
@@ -170,7 +185,9 @@ function getDecoratorsExpressionStatements(typescriptFile: SourceFile) {
170185
const expressionStatements = findNodes(typescriptFile, typescriptFile, SyntaxKind.ExpressionStatement, false) as ExpressionStatement[];
171186
const decoratorExpressionStatements: ExpressionStatement[] = [];
172187
for (const expressionStatement of expressionStatements) {
173-
if (expressionStatement.expression && (expressionStatement.expression as BinaryExpression).left && ((expressionStatement.expression as BinaryExpression).left as PropertyAccessExpression).name && ((expressionStatement.expression as BinaryExpression).left as PropertyAccessExpression).name.text === 'decorators') {
188+
if (expressionStatement.expression && (expressionStatement.expression as BinaryExpression).left
189+
&& ((expressionStatement.expression as BinaryExpression).left as PropertyAccessExpression).name
190+
&& ((expressionStatement.expression as BinaryExpression).left as PropertyAccessExpression).name.text === 'decorators') {
174191
decoratorExpressionStatements.push(expressionStatement);
175192
}
176193
}
@@ -248,6 +265,8 @@ function canRemoveDecoratorNode(decoratorType: string) {
248265
return true;
249266
} else if (decoratorType === VIEW_CHILDREN_DECORATOR) {
250267
return true;
268+
} else if (decoratorType === IONIC_PAGE_DECORATOR) {
269+
return true;
251270
}
252271
return false;
253272
}
@@ -265,5 +284,6 @@ export const OUTPUT_DECORATOR = 'Output';
265284
export const PIPE_DECORATOR = 'Pipe';
266285
export const VIEW_CHILD_DECORATOR = 'ViewChild';
267286
export const VIEW_CHILDREN_DECORATOR = 'ViewChildren';
287+
export const IONIC_PAGE_DECORATOR = 'IonicPage';
268288

269289
export const PURE_ANNOTATION = ' /*#__PURE__*/';

0 commit comments

Comments
 (0)