private void visitNewWithSpread(Node spreadParent) {
    checkArgument(spreadParent.isNew());

    // Must remove callee before extracting argument groups.
    Node callee = spreadParent.removeFirstChild();
    List<Node> groups = extractSpreadGroups(spreadParent);

    // We need to generate
    // `new (Function.prototype.bind.apply(callee, [null].concat(other, args))();`.
    // `null` stands in for the 'this' arg to the contructor.
    final Node baseArrayLit;
    if (groups.get(0).isArrayLit()) {
      baseArrayLit = groups.remove(0);
    } else {
      baseArrayLit = arrayLitWithJSType();
    }
    baseArrayLit.addChildToFront(nullWithJSType());
    Node joinedGroups =
        groups.isEmpty()
            ? baseArrayLit
            : IR.call(
                    IR.getprop(baseArrayLit, IR.string("concat")).setJSType(concatFnType),
                    groups.toArray(new Node[0]))
                .setJSType(arrayType);

    if (FeatureSet.ES3.contains(compiler.getOptions().getOutputFeatureSet())) {
      // TODO(tbreisacher): Support this in ES3 too by not relying on Function.bind.
      Es6ToEs3Util.cannotConvert(
          compiler,
          spreadParent,
          "\"...\" passed to a constructor (consider using --language_out=ES5)");
    }

    // Function.prototype.bind =>
    //      function(this:function(new:[spreadParent], ...?), ...?):function(new:[spreadParent])
    // Function.prototype.bind.apply =>
    //      function(function(new:[spreadParent], ...?), !Array<?>):function(new:[spreadParent])
    Node bindApply =
        getpropInferringJSType(
            IR.getprop(
                    getpropInferringJSType(
                        IR.name("Function").setJSType(functionFunctionType), "prototype"),
                    "bind")
                .setJSType(u2uFunctionType),
            "apply");
    Node result =
        IR.newNode(
                callInferringJSType(
                    bindApply, callee, joinedGroups /* function(new:[spreadParent]) */))
            .setJSType(spreadParent.getJSType());

    result.useSourceInfoIfMissingFromForTree(spreadParent);
    spreadParent.replaceWith(result);
    compiler.reportChangeToEnclosingScope(result);
  }
private void visitNewWithSpread ( Node spreadParent ) { checkArgument ( spreadParent . isNew ( ) ) ; Node callee = spreadParent . removeFirstChild ( ) ; List < Node > groups = extractSpreadGroups ( spreadParent ) ; final Node baseArrayLit ; if ( groups . get ( 0 ) . isArrayLit ( ) ) { baseArrayLit = groups . remove ( 0 ) ; } else { baseArrayLit = arrayLitWithJSType ( ) ; } baseArrayLit . addChildToFront ( nullWithJSType ( ) ) ; Node joinedGroups = groups . isEmpty ( ) ? baseArrayLit : IR . call ( IR . getprop ( baseArrayLit , IR . string ( "concat" ) ) . setJSType ( concatFnType ) , groups . toArray ( new Node [ 0 ] ) ) . setJSType ( arrayType ) ; if ( FeatureSet . ES3 . contains ( compiler . getOptions ( ) . getOutputFeatureSet ( ) ) ) { Es6ToEs3Util . cannotConvert ( compiler , spreadParent , "\"...\" passed to a constructor (consider using --language_out=ES5)" ) ; } Node bindApply = getpropInferringJSType ( IR . getprop ( getpropInferringJSType ( IR . name ( "Function" ) . setJSType ( functionFunctionType ) , "prototype" ) , "bind" ) . setJSType ( u2uFunctionType ) , "apply" ) ; Node result = IR . newNode ( callInferringJSType ( bindApply , callee , joinedGroups ) ) . setJSType ( spreadParent . getJSType ( ) ) ; result . useSourceInfoIfMissingFromForTree ( spreadParent ) ; spreadParent . replaceWith ( result ) ; compiler . reportChangeToEnclosingScope ( result ) ; }
Processes new calls containing spreads.

<p>Example:

<pre><code>
new F(...args) =>
new Function.prototype.bind.apply(F, [].concat($jscomp.arrayFromIterable(args)))
</code></pre>