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))); } }
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)); } }