Skip to content

Commit

Permalink
fix: account for different scopes during path evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
vigneshshanmugam committed May 3, 2018
1 parent 663ebc3 commit b7f2d70
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 16 deletions.
14 changes: 9 additions & 5 deletions packages/babel-helper-evaluate-path/src/index.js
@@ -1,14 +1,14 @@
"use strict";

module.exports = function evaluate(path, { tdz = false } = {}) {
if (!tdz) {
return baseEvaluate(path);
}

if (path.isReferencedIdentifier()) {
return evaluateIdentifier(path);
}

if (!tdz) {
return baseEvaluate(path);
}

const state = {
confident: true
};
Expand Down Expand Up @@ -113,8 +113,12 @@ function evaluateBasedOnControlFlow(binding, refPath) {
return { shouldDeopt: true };
}

let blockParent = binding.path.scope.getBlockParent().path;
const fnParent = binding.path.getFunctionParent();
if (!fnParent) {
return { shouldDeopt: true };
}

let blockParent = binding.path.scope.getBlockParent().path;

if (blockParent === fnParent) {
if (!fnParent.isProgram()) blockParent = blockParent.get("body");
Expand Down
Expand Up @@ -976,10 +976,14 @@ module.exports = ({ types: t, traverse }) => {
} else {
path.traverse({
VariableDeclaration(varPath) {
if (!varPath.isVariableDeclaration({ kind: "var" })) return;
const { node } = varPath;

if (node.kind !== "var") {
return;
}
if (!isSameFunctionScope(varPath, path)) return;

for (const decl of varPath.node.declarations) {
for (const decl of node.declarations) {
const bindingIds = Object.keys(t.getBindingIdentifiers(decl.id));
declarators.push(
...bindingIds.map(name =>
Expand Down
14 changes: 10 additions & 4 deletions packages/babel-plugin-minify-guarded-expressions/src/index.js
@@ -1,4 +1,10 @@
"use strict";
const evaluate = require("babel-helper-evaluate-path");

function evaluateTruthy(path) {
const res = evaluate(path);
if (res.confident) return !!res.value;
}

module.exports = function({ types: t }) {
const flipExpressions = require("babel-helper-flip-expressions")(t);
Expand Down Expand Up @@ -28,28 +34,28 @@ module.exports = function({ types: t }) {
const shouldBail = !path.parentPath.isExpressionStatement();

if (node.operator === "&&") {
const leftTruthy = left.evaluateTruthy();
const leftTruthy = evaluateTruthy(left);
if (leftTruthy === false) {
// Short-circuit
path.replaceWith(node.left);
} else if (leftTruthy === true && left.isPure()) {
path.replaceWith(node.right);
} else if (
right.evaluateTruthy() === false &&
evaluateTruthy(right) === false &&
right.isPure() &&
!shouldBail
) {
path.replaceWith(node.left);
}
} else if (node.operator === "||") {
const leftTruthy = left.evaluateTruthy();
const leftTruthy = evaluateTruthy(left);
if (leftTruthy === false && left.isPure()) {
path.replaceWith(node.right);
} else if (leftTruthy === true) {
// Short-circuit
path.replaceWith(node.left);
} else if (
right.evaluateTruthy() === false &&
evaluateTruthy(right) === false &&
right.isPure() &&
!shouldBail
) {
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-plugin-minify-simplify/src/helpers.js
@@ -1,6 +1,7 @@
"use strict";

const VOID_0 = t => t.unaryExpression("void", t.numericLiteral(0), true);
const evaluate = require("babel-helper-evaluate-path");

// Types as Symbols - for comparing types
const types = {};
Expand Down Expand Up @@ -39,7 +40,7 @@ const isPatternMatchesPath = t =>
return patternValue(inputPath);
}
if (isNodeOfType(t, inputPath.node, patternValue)) return true;
const evalResult = inputPath.evaluate();
const evalResult = evaluate(inputPath);
if (!evalResult.confident || !inputPath.isPure()) return false;
return evalResult.value === patternValue;
};
Expand Down
Expand Up @@ -2,13 +2,14 @@

const h = require("./helpers");
const PatternMatch = require("./pattern-match");
const evaluate = require("babel-helper-evaluate-path");

module.exports = t => {
const OP_AND = input => input === "&&";
const OP_OR = input => input === "||";

function simplifyPatterns(path) {
// cache of path.evaluate()
// cache of evaluate(path)
const evaluateMemo = new Map();

const TRUTHY = input => {
Expand All @@ -22,7 +23,7 @@ module.exports = t => {
return true;
}
}
const evalResult = input.evaluate();
const evalResult = evaluate(input);
evaluateMemo.set(input, evalResult);
return evalResult.confident && input.isPure() && evalResult.value;
};
Expand All @@ -35,7 +36,7 @@ module.exports = t => {
return true;
}
}
const evalResult = input.evaluate();
const evalResult = evaluate(input);
evaluateMemo.set(input, evalResult);
return evalResult.confident && input.isPure() && !evalResult.value;
};
Expand Down Expand Up @@ -67,7 +68,7 @@ module.exports = t => {
if (evaluateMemo.has(left)) {
value = evaluateMemo.get(left).value;
} else {
value = left.evaluate().value;
value = evaluate(left).value;
}
path.replaceWith(result.value(t.valueToNode(value), right.node));
}
Expand Down

0 comments on commit b7f2d70

Please sign in to comment.