/**
 * Determines whether a node represents a function, i.e. `->` or `=>`.
 *
 * @param {Object} node
 * @returns {boolean}
 */
export function isFunction(node) {
  return node.type === 'Function' || node.type === 'BoundFunction';
}

/**
 * Determines whether a node represents a `for` loop.
 *
 * @param {Object} node
 * @returns {boolean}
 */
export function isForLoop(node) {
  return node.type === 'ForIn' || node.type === 'ForOf';
}

/**
 * Determines whether a node represents a `while` loop.
 *
 * @param {Object} node
 * @returns {boolean}
 */
export function isWhile(node) {
  return node.type === 'While';
}

/**
 * Determines whether a node is the true-part or false-part of a conditional.
 *
 * @param {Object} node
 * @returns {boolean}
 */
export function isConsequentOrAlternate(node) {
  const { parentNode } = node;
  return parentNode.type === 'Conditional' && (
    parentNode.consequent === node ||
    parentNode.alternate === node
  );
}

/**
 * @param {Object} node
 * @returns {boolean}
 */
export function isBinaryOperator(node) {
  switch (node.type) {
    case 'BitAndOp':
    case 'BitOrOp':
    case 'DivideOp':
    case 'EQOp':
    case 'GTEOp':
    case 'GTOp':
    case 'InOp':
    case 'InstanceofOp':
    case 'LTEOp':
    case 'LTOp':
    case 'LogicalAndOp':
    case 'LogicalOrOp':
    case 'MultiplyOp':
    case 'NEQOp':
    case 'OfOp':
    case 'PlusOp':
    case 'RemOp':
    case 'SubtractOp':
      return true;

    default:
      return false;
  }
}

/**
 * @param {Object} node
 * @returns {boolean}
 */
export function isCall(node) {
  switch (node && node.type) {
    case 'FunctionApplication':
    case 'NewOp':
      return true;

    default:
      return false;
  }
}

/**
 * @param {Object} node
 * @returns {boolean}
 */
export function isCallArgument(node) {
  if (node && isCall(node.parentNode)) {
    return node.parentNode.arguments.indexOf(node) >= 0;
  } else {
    return false;
  }
}

/**
 * @param {Object} node
 * @returns {boolean}
 */
export function isShorthandThisObjectMember(node) {
  return node.type === 'ObjectInitialiserMember' && /^@\w+$/.test(node.raw);
}

/**
 * @param {Object} node
 * @returns {boolean}
 */
export function isStaticMethod(node) {
  if (node.type !== 'AssignOp') {
    return false;
  }

  if (!node.parentNode.parentNode || node.parentNode.parentNode.type !== 'Class') {
    return false;
  }

  const { assignee } = node;

  if (assignee.type !== 'MemberAccessOp') {
    return false;
  }

  if (node.expression.type !== 'Function') {
    return false;
  }

  return assignee.expression.type === 'This' || (
    assignee.expression.type === 'Identifier' &&
    assignee.expression.data === node.parentNode.parentNode.name.data
  );
}

@@ -87,32 +87,64 @@
 m %7BObject%7D node%0A
+ * @param %7Bboolean=%7D allowBound%0A
  * @returns %7Bboo
@@ -180,24 +180,41 @@
 unction(node
+, allowBound=true
 ) %7B%0A  return
@@ -237,24 +237,39 @@
 Function' %7C%7C
+ (allowBound &&
  node.type =
@@ -286,16 +286,724 @@
 unction'
+);%0A%7D%0A%0A/**%0A * Determines  whether a node is the body of a function.%0A *%0A * @example%0A *%0A *   -%3E 1  # the literal %601%60 is the function body%0A *%0A *   -%3E%0A *     2   # the block containing %602%60 as a statement is the function body%0A *%0A * @param node%0A * @param %7Bboolean=%7D allowBound%0A * @returns %7Bboolean%7D%0A */%0Aexport function isFunctionBody(node, allowBound=true) %7B%0A  const %7B parentNode %7D = node;%0A%0A  if (!parentNode) %7B%0A    return false;%0A  %7D%0A%0A  return isFunction(parentNode, allowBound) && parentNode.body === node;%0A%7D%0A%0A/**%0A * Determines whether the node is a conditional (i.e. %60if%60 or %60unless%60).%0A *%0A * @param %7BObject%7D node%0A * @returns %7Bboolean%7D%0A */%0Aexport function isConditional(node) %7B%0A  return node.type === 'Conditional'
 ;%0A%7D%0A%0A/**
@@ -1606,16 +1606,30 @@
   return
+ parentNode &&
  parentN

Add more type checking methods.