public void AddGlobalType(Type type) { var jsTypeName = type.GetCustomAttribute<JsNameAttribute>()?.Name ?? type.Name; var prototype = _typeConverter.GetPrototype(type); var ctors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).OrderByDescending(x => x.GetParameters().Length).ToArray(); if (ctors.Length > 0) { var jsCtor = new ClrCtor(_typeConverter, type, prototype,jsTypeName, args => { var ctor = ctors.FirstOrDefault(x => x.GetParameters().IsAppropriate(args)); if(ctor == null) throw new Exception("Appropriate constructor not found."); var ctorParameters = ctor.GetParameters(); var clrArgs = _typeConverter.ConvertParametersToClr(ctorParameters, null, args); return ctor.Invoke(clrArgs); }); _typeConverter.Engine.SetGlobalValue(jsTypeName, jsCtor); } else { //todo: fix error var jsCtor = new ClrCtor(_typeConverter, type, prototype,jsTypeName, _ => throw new Exception("Error")); _typeConverter.Engine.SetGlobalValue(jsTypeName, jsCtor); } }
public static Func <object, object[], object[]> GetParamsConverter(ClrTypeConverter ctx, ParameterInfo[] methodParameters) { if (methodParameters.Length > 0) { var lastParameter = methodParameters.Last(); //have a deal with 'param' if (lastParameter.GetCustomAttribute <ParamArrayAttribute>() != null) { return((thisObject, argumentValues) => { if (argumentValues.Length < methodParameters.Length) { return ctx.ConvertParametersToClr(methodParameters, thisObject, argumentValues); } var part1Types = methodParameters.Take(methodParameters.Length - 1).ToArray(); var clrArgumentsPart1 = ctx.ConvertParametersToClr(part1Types, thisObject, argumentValues); var part2Types = Enumerable .Repeat(typeof(object), argumentValues.Length - part1Types.Length) .ToArray(); var clrArgumentsPart2 = ctx.ConvertParametersToClr(part2Types, thisObject, argumentValues.Skip(part1Types.Length).ToArray()); var clrArguments = new object[methodParameters.Length]; Array.Copy(clrArgumentsPart1, clrArguments, clrArgumentsPart1.Length); clrArguments[clrArguments.Length - 1] = clrArgumentsPart2; return clrArguments; }); } var expands = methodParameters .Select(parameterInfo => parameterInfo.GetCustomAttribute <JsExpandArrayAttribute>() != null) .ToArray(); var hasExpands = expands.Any(x => x); if (hasExpands || methodParameters.Any(x => !x.ParameterType.IsValueType)) { return((thisObject, argumentValues) => ctx.ConvertParametersToClr(methodParameters, thisObject, argumentValues)); } //Simple case with value parameters. var converters = methodParameters.Select(x => ctx.GetConverter(x.ParameterType, x.GetDefaultValue())); return((thisObject, args) => converters.Select((c, i) => c(i < args.Length ? args[i]: null)) .ToArray()); } return((_, __) => new object[0]); }