예제 #1
0
        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);
            }
        }
예제 #2
0
        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]);
        }