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

Commit

Permalink
fix(decorators): don't remove third party transpiled (not static) dec…
Browse files Browse the repository at this point in the history
…orators
  • Loading branch information
danbucholtz committed Apr 6, 2017
1 parent b558584 commit 3a3259a
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 22 deletions.
51 changes: 51 additions & 0 deletions src/optimization/decorators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,57 @@ var _a, _b;
const result: string = magicString.toString();
expect(result.indexOf(injectableDecorator)).toBeGreaterThan(1);
});

it('should not remove the third party decorators', () => {

const selectDecorator = `
__decorate([
select(),
__metadata("design:type", Object)
], DashPage.prototype, "user$", void 0);
`;

const knownContent = `
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Component } from '@angular/core';
import { select } from '@angular-redux/store';
var DashPage = (function () {
function DashPage() {
}
DashPage.prototype.ionViewDidLoad = function () {
var _this = this;
this.user$.subscribe(function (user) {
_this.user = user;
});
};
return DashPage;
}());
${selectDecorator}
DashPage = __decorate([
Component({
selector: 'page-dash',
templateUrl: 'dash-page.html'
}),
__metadata("design:paramtypes", [])
], DashPage);
export { DashPage };
//# sourceMappingURL=dash-page.js.map
`;

let magicString = new MagicString(knownContent);
const filePath = join(ionicAngular, 'components', 'action-sheet', 'action-sheet-component.js');
magicString = decorators.purgeTranspiledDecorators(filePath, knownContent, ionicAngular, angularDir, srcDir, magicString);
const result: string = magicString.toString();
expect(result.indexOf(selectDecorator)).toBeGreaterThan(1);
});
});

describe('addPureAnnotation', () => {
Expand Down
64 changes: 42 additions & 22 deletions src/optimization/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,32 +68,47 @@ function getTranspiledDecoratorExpressionStatements(sourceFile: SourceFile) {
if (expressionStatement && expressionStatement.expression
&& expressionStatement.expression.kind === SyntaxKind.CallExpression
&& (expressionStatement.expression as CallExpression).expression
&& ((expressionStatement.expression as CallExpression).expression as Identifier).text === '___decorate') {
&& ((expressionStatement.expression as CallExpression).expression as Identifier).text === '___decorate'
&& (expressionStatement.expression as CallExpression).arguments
&& (expressionStatement.expression as CallExpression).arguments.length > 0
&& (expressionStatement.expression as CallExpression).arguments[0].kind === SyntaxKind.ArrayLiteralExpression
&& ((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements
&& ((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements.length > 0
&& (((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements[0] as CallExpression).expression
&& (((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements[0] as CallExpression).expression.kind === SyntaxKind.Identifier
&& canRemoveDecoratorNode(((((expressionStatement.expression as CallExpression).arguments[0] as ArrayLiteralExpression).elements[0] as CallExpression).expression as Identifier).text)
) {

toReturn.push(expressionStatement);

} else if (expressionStatement && expressionStatement.expression
&& expressionStatement.expression.kind === SyntaxKind.BinaryExpression
&& (expressionStatement.expression as BinaryExpression).right
&& (expressionStatement.expression as BinaryExpression).right.kind === SyntaxKind.CallExpression
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).expression
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).expression as Identifier).text === '___decorate') {

((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments.forEach(argument => {
if (argument.kind === SyntaxKind.ArrayLiteralExpression) {
let injectableFound = false;
for (const element of (argument as ArrayLiteralExpression).elements) {
if (element.kind === SyntaxKind.CallExpression && (element as CallExpression).expression
&& ((element as CallExpression).expression as Identifier).text === 'Injectable' ) {
injectableFound = true;
break;
}
}
if (!injectableFound) {
toReturn.push(expressionStatement);
}
&& expressionStatement.expression.kind === SyntaxKind.BinaryExpression
&& (expressionStatement.expression as BinaryExpression).right
&& (expressionStatement.expression as BinaryExpression).right.kind === SyntaxKind.CallExpression
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).expression
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).expression as Identifier).text === '___decorate'
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments.length > 0
&& ((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0].kind === SyntaxKind.ArrayLiteralExpression
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements
&& (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements.length > 0 ) {

let immovableDecoratorFound = false;

// remove the last item in the array as it is always __metadata() and should not be considered here
const numElements = (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements.length - 1;
const elementsToEvaluate = (((expressionStatement.expression as BinaryExpression).right as CallExpression).arguments[0] as ArrayLiteralExpression).elements.slice(0, numElements);
for (const element of elementsToEvaluate) {
if (element.kind === SyntaxKind.CallExpression && (element as CallExpression).expression
&& !canRemoveDecoratorNode(((element as CallExpression).expression as Identifier).text)) {

immovableDecoratorFound = true;
break;
}
});
}
if (!immovableDecoratorFound) {
toReturn.push(expressionStatement);
}
}
});
return toReturn;
Expand Down Expand Up @@ -170,7 +185,9 @@ function getDecoratorsExpressionStatements(typescriptFile: SourceFile) {
const expressionStatements = findNodes(typescriptFile, typescriptFile, SyntaxKind.ExpressionStatement, false) as ExpressionStatement[];
const decoratorExpressionStatements: ExpressionStatement[] = [];
for (const expressionStatement of expressionStatements) {
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') {
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') {
decoratorExpressionStatements.push(expressionStatement);
}
}
Expand Down Expand Up @@ -248,6 +265,8 @@ function canRemoveDecoratorNode(decoratorType: string) {
return true;
} else if (decoratorType === VIEW_CHILDREN_DECORATOR) {
return true;
} else if (decoratorType === IONIC_PAGE_DECORATOR) {
return true;
}
return false;
}
Expand All @@ -265,5 +284,6 @@ export const OUTPUT_DECORATOR = 'Output';
export const PIPE_DECORATOR = 'Pipe';
export const VIEW_CHILD_DECORATOR = 'ViewChild';
export const VIEW_CHILDREN_DECORATOR = 'ViewChildren';
export const IONIC_PAGE_DECORATOR = 'IonicPage';

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

0 comments on commit 3a3259a

Please sign in to comment.