Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(evaluate): convert paths to nodes as path.get is slow #856

Merged
merged 1 commit into from May 17, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 23 additions & 12 deletions packages/babel-helper-evaluate-path/src/index.js
Expand Up @@ -148,18 +148,19 @@ function evaluateBasedOnControlFlow(binding, refPath) {
binding.path.scope.getProgramParent()
).path;

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

if (blockParent === fnParent && !fnParent.isProgram()) {
blockParent = blockParent.get("body");
if (blockParentPath === fnParent && !fnParent.isProgram()) {
blockParent = blockParent.body;
}

// detect Usage Outside Init Scope
const blockBody = blockParent.get("body");
const blockBody = blockParent.body;

if (
Array.isArray(blockBody) &&
!blockBody.some(stmt => stmt.isAncestor(refPath))
!blockBody.some(stmt => isAncestor(stmt, refPath))
) {
return {
shouldDeopt: true
Expand All @@ -168,8 +169,8 @@ function evaluateBasedOnControlFlow(binding, refPath) {

// Detect usage before init
const stmts = fnParent.isProgram()
? fnParent.get("body")
: fnParent.get("body").get("body");
? fnParent.node.body
: fnParent.node.body.body;

const compareResult = compareBindingAndReference({
binding,
Expand Down Expand Up @@ -199,13 +200,15 @@ function evaluateBasedOnControlFlow(binding, refPath) {
return { shouldDeopt: true };
}

let scopePath = declarator.scope.path;
const scopePath = declarator.scope.path;
let scopeNode = scopePath.node;

if (scopePath.isFunction() || scopePath.isCatchClause()) {
scopePath = scopePath.get("body");
scopeNode = scopeNode.body;
}

// Detect Usage before Init
let stmts = scopePath.get("body");
let stmts = scopeNode.body;
if (!Array.isArray(stmts)) {
stmts = [stmts];
}
Expand Down Expand Up @@ -242,11 +245,12 @@ function compareBindingAndReference({ binding, refPath, stmts }) {
};

for (const [idx, stmt] of stmts.entries()) {
if (stmt.isAncestor(binding.path)) {
if (isAncestor(stmt, binding.path)) {
state.binding = { idx };
}

for (const ref of binding.referencePaths) {
if (ref === refPath && stmt.isAncestor(ref)) {
if (ref === refPath && isAncestor(stmt, ref)) {
state.reference = {
idx,
scope: binding.path.scope === ref.scope ? "current" : "other"
Expand All @@ -265,3 +269,10 @@ function deopt(deoptPath) {
deoptPath
};
}

/**
* is nodeParent an ancestor of path
*/
function isAncestor(nodeParent, path) {
return !!path.findParent(parent => parent.node === nodeParent);
}