code: function buildJSXOpeningElementAttributes(attribs, file) {
      var _props = [];
      var objs = [];
  
      var pushProps = function pushProps() {
        if (!_props.length) return;
  
        objs.push(t.objectExpression(_props));
        _props = [];
      };
  
      while (attribs.length) {
        var prop = attribs.shift();
        if (t.isJSXSpreadAttribute(prop)) {
          pushProps();
          objs.push(prop.argument);
        } else {
          _props.push(prop);
        }
      }
  
      pushProps();
  
      if (objs.length === 1) {
        // only one object
        attribs = objs[0];
      } else {
        // looks like we have multiple objects
        if (!t.isObjectExpression(objs[0])) {
          objs.unshift(t.objectExpression([]));
        }
  
        // spread it
        attribs = t.callExpression(file.addHelper("extends"), objs);
      }
  
      return attribs;
    }
docs: The logic for this is quite terse. It's because we need to
  support spread elements. We loop over all attributes,
  breaking on spreads, we then push a new object containg
  all prior attributes to an array for later processing.