# callConstructor function

dynamic callConstructor (Function constr, List arguments)

## Implementation

    callConstructor(Function constr, List arguments) {
      if (arguments == null) {
        return JS('Object', 'new #()', constr);
      }

      if (JS('bool', '# instanceof Array', arguments)) {
        int argumentCount = JS('int', '#.length', arguments);
        switch (argumentCount) {
          case 0:
            return JS('Object', 'new #()', constr);

          case 1:
            var arg0 = JS('', '#[0]', arguments);
            return JS('Object', 'new #(#)', constr, arg0);

          case 2:
            var arg0 = JS('', '#[0]', arguments);
            var arg1 = JS('', '#[1]', arguments);
            return JS('Object', 'new #(#, #)', constr, arg0, arg1);

          case 3:
            var arg0 = JS('', '#[0]', arguments);
            var arg1 = JS('', '#[1]', arguments);
            var arg2 = JS('', '#[2]', arguments);
            return JS('Object', 'new #(#, #, #)', constr, arg0, arg1, arg2);

          case 4:
            var arg0 = JS('', '#[0]', arguments);
            var arg1 = JS('', '#[1]', arguments);
            var arg2 = JS('', '#[2]', arguments);
            var arg3 = JS('', '#[3]', arguments);
            return JS(
                'Object', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3);
        }
      }

      // The following code solves the problem of invoking a JavaScript
      // constructor with an unknown number arguments.
      // First bind the constructor to the argument list using bind.apply().
      // The first argument to bind() is the binding of 't', so add 'null' to
      // the arguments list passed to apply().
      // After that, use the JavaScript 'new' operator which overrides any binding
      // of 'this' with the new instance.
      var args = <dynamic>[null]..addAll(arguments);
      var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
      // Without this line, calling factoryFunction as a constructor throws
      JS('String', 'String(#)', factoryFunction);
      // This could return an UnknownJavaScriptObject, or a native
      // object for which there is an interceptor
      return JS('Object', 'new #()', factoryFunction);

      // TODO(sra): Investigate:
      //
      //     var jsObj = JS('', 'Object.create(#.prototype)', constr);
      //     JS('', '#.apply(#, #)', constr, jsObj,
      //         []..addAll(arguments.map(_convertToJS)));
      //     return _wrapToDart(jsObj);
    }