Example #1
0
// Walk up the print stack to deterimine if our node can come first
// in statement.
function isFirstInStatement(printStack: Array<Object>): boolean {
  let i = printStack.length - 1;
  let node = printStack[i];
  i--;
  let parent = printStack[i];
  while (i > 0) {
    if (t.isExpressionStatement(parent, { expression: node })) {
      return true;
    }

    if ((t.isCallExpression(parent, { callee: node })) ||
        (t.isSequenceExpression(parent) && parent.expressions[0] === node) ||
        (t.isMemberExpression(parent, { object: node })) ||
        (t.isConditional(parent, { test: node })) ||
        (t.isBinary(parent, { left: node })) ||
        (t.isAssignmentExpression(parent, { left: node }))) {
      node = parent;
      i--;
      parent = printStack[i];
    } else {
      return false;
    }
  }

  return false;
}
Example #2
0
export function replaceExpressionWithStatements(nodes: Array<Object>) {
  this.resync();

  let toSequenceExpression = t.toSequenceExpression(nodes, this.scope);

  if (t.isSequenceExpression(toSequenceExpression)) {
    let exprs = toSequenceExpression.expressions;

    if (exprs.length >= 2 && this.parentPath.isExpressionStatement()) {
      this._maybePopFromStatements(exprs);
    }

    // could be just one element due to the previous maybe popping
    if (exprs.length === 1) {
      this.replaceWith(exprs[0]);
    } else {
      this.replaceWith(toSequenceExpression);
    }
  } else if (toSequenceExpression) {
    this.replaceWith(toSequenceExpression);
  } else {
    let container = t.functionExpression(null, [], t.blockStatement(nodes));
    container.shadow = true;

    this.replaceWith(t.callExpression(container, []));
    this.traverse(hoistVariablesVisitor);

    // add implicit returns to all ending expression statements
    let completionRecords: Array<NodePath> = this.get("callee").getCompletionRecords();
    for (let path of completionRecords) {
      if (!path.isExpressionStatement()) continue;

      let loop = path.findParent((path) => path.isLoop());
      if (loop) {
        let callee = this.get("callee");

        let uid = callee.scope.generateDeclaredUidIdentifier("ret");
        callee.get("body").pushContainer("body", t.returnStatement(uid));

        path.get("expression").replaceWith(
          t.assignmentExpression("=", uid, path.node.expression)
        );
      } else {
        path.replaceWith(t.returnStatement(path.node.expression));
      }
    }

    return this.node;
  }
}
Example #3
0
// Walk up the print stack to deterimine if our node can come first
// in statement.
function isFirstInStatement(printStack: Array<Object>, {
    considerArrow = false,
    considerDefaultExports = false
  } = {}): boolean {
  let i = printStack.length - 1;
  let node = printStack[i];
  i--;
  let parent = printStack[i];
  while (i > 0) {
    if (t.isExpressionStatement(parent, { expression: node })) {
      return true;
    }

    if (considerDefaultExports && t.isExportDefaultDeclaration(parent, { declaration: node })) {
      return true;
    }

    if (considerArrow && t.isArrowFunctionExpression(parent, { body: node })) {
      return true;
    }

    if ((t.isCallExpression(parent, { callee: node })) ||
        (t.isSequenceExpression(parent) && parent.expressions[0] === node) ||
        (t.isMemberExpression(parent, { object: node })) ||
        (t.isConditional(parent, { test: node })) ||
        (t.isBinary(parent, { left: node })) ||
        (t.isAssignmentExpression(parent, { left: node }))) {
      node = parent;
      i--;
      parent = printStack[i];
    } else {
      return false;
    }
  }

  return false;
}