Skip to content

Commit

Permalink
Deoptimize awaited expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jul 1, 2021
1 parent 5b55f99 commit 55b60aa
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 46 deletions.
30 changes: 12 additions & 18 deletions src/ast/nodes/AwaitExpression.ts
@@ -1,6 +1,5 @@
import { NormalizedTreeshakingOptions } from '../../rollup/types';
import { NO_ARGS } from '../CallOptions';
import { HasEffectsContext, InclusionContext } from '../ExecutionContext';
import { InclusionContext } from '../ExecutionContext';
import { UNKNOWN_PATH } from '../utils/PathTracker';
import ArrowFunctionExpression from './ArrowFunctionExpression';
import * as NodeType from './NodeType';
import FunctionNode from './shared/FunctionNode';
Expand All @@ -9,25 +8,15 @@ import { ExpressionNode, IncludeChildren, Node, NodeBase } from './shared/Node';
export default class AwaitExpression extends NodeBase {
argument!: ExpressionNode;
type!: NodeType.tAwaitExpression;
protected deoptimized = false;

hasEffects(context: HasEffectsContext): boolean {
const { propertyReadSideEffects } = this.context.options
.treeshake as NormalizedTreeshakingOptions;
return (
!context.ignore.returnAwaitYield ||
this.argument.hasEffects(context) ||
this.argument.hasEffectsWhenCalledAtPath(
['then'],
{ args: NO_ARGS, thisParam: null, withNew: false },
context
) ||
(propertyReadSideEffects &&
(propertyReadSideEffects === 'always' ||
this.argument.hasEffectsWhenAccessedAtPath(['then'], context)))
);
hasEffects(): boolean {
if (!this.deoptimized) this.applyDeoptimizations();
return true;
}

include(context: InclusionContext, includeChildrenRecursively: IncludeChildren): void {
if (!this.deoptimized) this.applyDeoptimizations();
if (!this.included) {
this.included = true;
checkTopLevelAwait: if (!this.context.usesTopLevelAwait) {
Expand All @@ -41,4 +30,9 @@ export default class AwaitExpression extends NodeBase {
}
this.argument.include(context, includeChildrenRecursively);
}

protected applyDeoptimizations(): void {
this.deoptimized = true;
this.argument.deoptimizePath(UNKNOWN_PATH);
}
}
18 changes: 0 additions & 18 deletions test/form/samples/async-function-effects/main.js
Expand Up @@ -77,14 +77,6 @@
return { then() {} };
})();

// removed
(async function () {
await {
then: function () {}
};
return { then() {} };
})();

(async function () {
await {
get then() {
Expand All @@ -104,16 +96,6 @@
return { then() {} };
})();

// removed
(async function () {
await {
get then() {
return () => {};
}
};
return { then() {} };
})();

(async function () {
await await {
then(resolve) {
Expand Down
10 changes: 0 additions & 10 deletions test/form/samples/ignore-property-access-side-effects/main.js
Expand Up @@ -38,13 +38,3 @@ const foo7 = (async () => ({
return () => {};
}
}))();

const foo8 = (async function () {
await {
get then() {
console.log('effect');
return () => {};
}
};
return { then() {} };
})();
10 changes: 10 additions & 0 deletions test/function/samples/track-awaited-object/_config.js
@@ -0,0 +1,10 @@
const assert = require('assert');

module.exports = {
description: 'tracks object mutations through await',
async exports(exports) {
assert.strictEqual(exports.toggled, false);
await exports.test();
assert.strictEqual(exports.toggled, true);
}
};
19 changes: 19 additions & 0 deletions test/function/samples/track-awaited-object/main.js
@@ -0,0 +1,19 @@
function fn() {
const obj = {
test() {
if (typeof obj.testfn === 'function') {
obj.testfn();
}
}
};

return obj;
}

export let toggled = false;

export const test = async function () {
const obj = await fn();
obj.testfn = () => (toggled = true);
obj.test();
};

0 comments on commit 55b60aa

Please sign in to comment.