diff --git a/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions.ts b/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions.ts index a0c263f007..60e54cd85d 100644 --- a/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions.ts +++ b/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions.ts @@ -30,7 +30,7 @@ export function getPrefixFunctionsTransformer(): ts.TransformerFactory { + const topLevelFunctions = new Set(); function cb(node: ts.Node) { // Stop recursing into this branch if it's a function expression or declaration - if (node.kind === ts.SyntaxKind.FunctionDeclaration - || node.kind === ts.SyntaxKind.FunctionExpression) { + if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) { return; } @@ -71,9 +70,24 @@ export function findTopLevelFunctions(parentNode: ts.Node): ts.Node[] { } if (noPureComment) { - if (innerNode.kind === ts.SyntaxKind.CallExpression - || innerNode.kind === ts.SyntaxKind.NewExpression) { - topLevelFunctions.push(node); + if (ts.isNewExpression(innerNode)) { + topLevelFunctions.add(node); + } else if (ts.isCallExpression(innerNode)) { + let expression: ts.Expression = innerNode.expression; + while (expression && ts.isParenthesizedExpression(expression)) { + expression = expression.expression; + } + if (expression) { + if (ts.isFunctionExpression(expression)) { + // Skip IIFE's with arguments + // This could be improved to check if there are any references to variables + if (innerNode.arguments.length === 0) { + topLevelFunctions.add(node); + } + } else { + topLevelFunctions.add(node); + } + } } } diff --git a/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions_spec.ts b/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions_spec.ts index f0e73f96d7..7bec03f54c 100644 --- a/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions_spec.ts +++ b/packages/angular_devkit/build_optimizer/src/transforms/prefix-functions_spec.ts @@ -86,7 +86,7 @@ describe('prefix-functions', () => { expect(tags.oneLine`${transform(input)}`).toEqual(tags.oneLine`${output}`); }); - it('doesn\'t adds comment when inside function declarations or expressions', () => { + it('doesn\'t add comment when inside function declarations or expressions', () => { const input = tags.stripIndent` function funcDecl() { var newClazz = Clazz(); @@ -105,5 +105,24 @@ describe('prefix-functions', () => { expect(tags.oneLine`${transform(input)}`).toEqual(tags.oneLine`${output}`); }); + + it('doesn\'t add comment to downlevel namespaces', () => { + const input = tags.stripIndent` + function MyFunction() { } + + (function (MyFunction) { + function subFunction() { } + MyFunction.subFunction = subFunction; + })(MyFunction || (MyFunctionn = {})); + + export { MyFunction }; + `; + const output = tags.stripIndent` + ${emptyImportsComment} + ${input} + `; + + expect(tags.oneLine`${transform(input)}`).toEqual(tags.oneLine`${output}`); + }); }); });