code: function isNotSideEffectsNode (node, visitorKeys) {
    let result = true
    new Traverser().traverse(node, {
      visitorKeys,
      enter (node, parent) {
        if (
          node.type === 'FunctionExpression' ||
          node.type === 'Identifier' ||
          node.type === 'Literal' ||
          // es2015
          node.type === 'ArrowFunctionExpression' ||
          node.type === 'TemplateElement'
        ) {
          // no side effects node
          this.skip()
        } else if (
          node.type !== 'Property' &&
          node.type !== 'ObjectExpression' &&
          node.type !== 'ArrayExpression' &&
          (node.type !== 'UnaryExpression' || ['!', '~', '+', '-', 'typeof'].indexOf(node.operator) < 0) &&
          (node.type !== 'BinaryExpression' || ALL_BINARY_OPERATORS.indexOf(node.operator) < 0) &&
          (node.type !== 'LogicalExpression' || LOGICAL_OPERATORS.indexOf(node.operator) < 0) &&
          node.type !== 'MemberExpression' &&
          node.type !== 'ConditionalExpression' &&
          // es2015
          node.type !== 'SpreadElement' &&
          node.type !== 'TemplateLiteral'
        ) {
          // Can not be sure that a node has no side effects
          result = false
          this.break()
        }
      }
    })
    return result
  }
docs: /*
  Result `true` if the node is sure that there are no side effects
  
  Currently known side effects types
  
  node.type === 'CallExpression'
  node.type === 'NewExpression'
  node.type === 'UpdateExpression'
  node.type === 'AssignmentExpression'
  node.type === 'TaggedTemplateExpression'
  node.type === 'UnaryExpression' && node.operator === 'delete'
  
  @param  {ASTNode} node target node
  @param  {Object} visitorKeys sourceCode.visitorKey
  @returns {Boolean} no side effects