Example #1
0
        public override NeoValue Call(NeoValue[] arguments)
        {
            var pargs = new List <NeoValue>();

            foreach (var arg in arguments)
            {
                if (arg is NeoSpreadValue va)
                {
                    for (var i = 0; i < va.Array.Count; i++)
                    {
                        pargs.Add(va.Array[i]);
                    }
                }
                else
                {
                    pargs.Add(arg);
                }
            }

            var args = new object[pargs.Count];

            for (var i = 0; i < args.Length; i++)
            {
                args[i] = FFILib.FromNeo(pargs[i]);
            }

            MethodInfo method = null;

            foreach (var overload in overloads)
            {
                var parameters = overload.GetParameters();
                if (parameters.Length != args.Length)
                {
                    continue;
                }

                var same = true;
                for (var i = 0; i < args.Length; i++)
                {
                    if (args[i] == null)
                    {
                        continue;
                    }

                    if (parameters[i].ParameterType == typeof(double) && args[i] is int)
                    {
                        args[i] = (double)(int)args[i];
                    }

                    if (!parameters[i].ParameterType.IsInstanceOfType(args[i]))
                    {
                        same = false;
                        break;
                    }
                }
                if (!same)
                {
                    continue;
                }

                method = overload;
                break;
            }

            if (method == null)
            {
                throw new NeoError($"FFILib method '{name}' not found");
            }

            if (method.ReturnType == typeof(void))
            {
                method.Invoke(null, args);
                return(NeoNil.NIL);
            }
            else
            {
                return(FFILib.ToNeo(method.Invoke(null, args)));
            }
        }
Example #2
0
        private void Analyze()
        {
            Type type;

            if (Object is Type)
            {
                type = (Type)Object;
            }
            else
            {
                type = Object.GetType();
            }

            var propertyMethods = new HashSet <MethodInfo>();

            foreach (var prop in type.GetProperties())
            {
                if (prop.GetMethod != null)
                {
                    if (prop.GetMethod.IsPublic)
                    {
                        getters[prop.Name] = () => FFILib.ToNeo(prop.GetValue(Object));
                    }
                    propertyMethods.Add(prop.GetMethod);
                }

                if (prop.SetMethod != null)
                {
                    if (prop.SetMethod.IsPublic)
                    {
                        setters[prop.Name] = (value) => prop.SetValue(Object, FFILib.FromNeo(value));
                    }
                    propertyMethods.Add(prop.SetMethod);
                }
            }

            foreach (var method in type.GetMethods())
            {
                if (!method.IsPublic)
                {
                    continue;
                }
                if (propertyMethods.Contains(method))
                {
                    continue;
                }

                if (method.IsStatic)
                {
                    if (staticGetters.ContainsKey(method.Name))
                    {
                        var proxy = (FFIStaticMethodProxy)staticGetters[method.Name]();
                        proxy.AddOverload(method);
                    }
                    else
                    {
                        var proxy = new FFIStaticMethodProxy(this, method);
                        staticGetters[method.Name] = () => proxy;
                    }
                }
                else
                {
                    if (getters.ContainsKey(method.Name))
                    {
                        var proxy = (FFIMethodProxy)getters[method.Name]();
                        proxy.AddOverload(method);
                    }
                    else
                    {
                        var proxy = new FFIMethodProxy(Object, method);
                        getters[method.Name] = () => proxy;
                    }
                }
            }

            foreach (var field in type.GetFields())
            {
                if (!field.IsPublic)
                {
                    continue;
                }

                getters[field.Name] = () => FFILib.ToNeo(field.GetValue(Object));
                setters[field.Name] = (value) => field.SetValue(Object, FFILib.FromNeo(value));
            }
        }