Skip to content

Commit

Permalink
Add test cases for future optional chain dropping
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Sep 13, 2021
1 parent e7a4b72 commit 7a9e6e4
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 10 deletions.
8 changes: 3 additions & 5 deletions lib/compress/drop-side-effect-free.js
Expand Up @@ -121,9 +121,7 @@ def_drop_side_effect_free(AST_Constant, return_null);
def_drop_side_effect_free(AST_This, return_null);

def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) {
if (is_nullish(this, compressor)) {
return make_node(AST_Undefined, this);
}
if (is_nullish(this, compressor)) return this.expression;

if (!this.is_callee_pure(compressor)) {
if (this.expression.is_call_pure(compressor)) {
Expand Down Expand Up @@ -298,14 +296,14 @@ def_drop_side_effect_free(AST_Array, function (compressor, first_in_statement) {
});

def_drop_side_effect_free(AST_Dot, function (compressor, first_in_statement) {
if (is_nullish(this, compressor)) return make_node(AST_Undefined, this);
if (is_nullish(this, compressor)) return this.expression;
if (this.expression.may_throw_on_access(compressor)) return this;

return this.expression.drop_side_effect_free(compressor, first_in_statement);
});

def_drop_side_effect_free(AST_Sub, function (compressor, first_in_statement) {
if (is_nullish(this, compressor)) return make_node(AST_Undefined, this);
if (is_nullish(this, compressor)) return this.expression;
if (this.expression.may_throw_on_access(compressor)) return this;

var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
Expand Down
2 changes: 1 addition & 1 deletion lib/compress/evaluate.js
Expand Up @@ -83,7 +83,7 @@ function def_eval(node, func) {
}

// Used to propagate a nullish short-circuit signal upwards through the chain.
const nullish = Symbol("This AST_Chain is nullish");
export const nullish = Symbol("This AST_Chain is nullish");

// If the node has been successfully reduced to a constant,
// then its value is returned; otherwise the element itself
Expand Down
8 changes: 4 additions & 4 deletions lib/compress/index.js
Expand Up @@ -177,7 +177,7 @@ import {
} from "../scope.js";
import "../size.js";

import "./evaluate.js";
import { nullish } from "./evaluate.js";
import "./drop-side-effect-free.js";
import "./reduce-vars.js";
import {
Expand Down Expand Up @@ -2432,7 +2432,7 @@ def_optimize(AST_Call, function(self, compressor) {
}

var ev = self.evaluate(compressor);
if (ev !== self) {
if (ev !== self && ev !== nullish) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
Expand Down Expand Up @@ -4191,7 +4191,7 @@ def_optimize(AST_Sub, function(self, compressor) {
}
}
var ev = self.evaluate(compressor);
if (ev !== self) {
if (ev !== self && ev !== nullish) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
Expand Down Expand Up @@ -4262,7 +4262,7 @@ def_optimize(AST_Dot, function(self, compressor) {
if (sub) return sub.optimize(compressor);
}
let ev = self.evaluate(compressor);
if (ev !== self) {
if (ev !== self && ev !== nullish) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
Expand Down
109 changes: 109 additions & 0 deletions test/compress/drop-unused.js
Expand Up @@ -2930,3 +2930,112 @@ unused_null_conditional_chain: {
}
}

unused_null_conditional_chain_2: {
options = {
toplevel: true,
defaults: true,
passes: 5,
}
input: {
let i = 0;
(i++, null)?.unused;
(i++, null)?.[side_effect()];
(i++, null)?.unused.i_will_throw;
(i++, null)?.call(1);
(i++, null)?.(2);
(i++, null)?.maybe_call?.(3);
}
expect: {
}
}

unused_null_conditional_chain_3: {
options = {
toplevel: true,
defaults: true,
passes: 5,
}
input: {
(side_effect(), null)?.unused;
(side_effect(), null)?.[side_effect()];
(side_effect(), null)?.unused.i_will_throw;
(side_effect(), null)?.call(1);
(side_effect(), null)?.(2);
(side_effect(), null)?.maybe_call?.(3);
}
expect: {
// TODO: Elminate everything after ?.
(side_effect(), null)?.unused,
(side_effect(), null)?.[side_effect()],
(side_effect(), null)?.unused.i_will_throw,
(side_effect(), null)?.call(1),
(side_effect(), null)?.(2),
(side_effect(), null)?.maybe_call?.(3);
}
}

unused_null_conditional_chain_4: {
options = {
toplevel: true,
defaults: true,
passes: 5,
}
input: {
function nullish() {
side_effect();
return null;
}
nullish()?.unused;
nullish()?.[side_effect()];
nullish()?.unused.i_will_throw;
nullish()?.call(1);
nullish()?.(2);
nullish()?.maybe_call?.(3);
}
expect: {
// TODO: Elminate everything after ?.
function nullish() {
return side_effect(), null;
}
nullish()?.unused,
nullish()?.[side_effect()],
nullish()?.unused.i_will_throw,
nullish()?.call(1),
nullish()?.(2),
nullish()?.maybe_call?.(3);
}
}

unused_null_conditional_chain_5: {
options = {
toplevel: true,
defaults: true,
passes: 5,
}
input: {
export const obj = {
side_effect() {
side_effect();
return { null: null };
}
}
obj.side_effect().null?.unused;
obj.side_effect().null?.[side_effect()];
obj.side_effect().null?.unused.i_will_throw;
obj.side_effect().null?.call(1);
obj.side_effect().null?.(2);
obj.side_effect().null?.maybe_call?.(3);
}
expect: {
export const obj = {
side_effect: () => (side_effect(), {null: null})
}
// TODO: Elminate everything after ?.
obj.side_effect().null?.unused,
obj.side_effect().null?.[side_effect()],
obj.side_effect().null?.unused.i_will_throw,
obj.side_effect().null?.call(1),
obj.side_effect().null?.(2),
obj.side_effect().null?.maybe_call?.(3);
}
}

0 comments on commit 7a9e6e4

Please sign in to comment.