public Method(string name, MethodBase info) { Name = name; Info = info; var parameters = info.GetParameters(); Parameters = parameters .Select(p => new Parameter(p)) .ToList(); ValueParameters = Parameters .Where(p => p.Type == ParameterType.Value) .ToList(); MondParameterCount = ValueParameters.Count; RequiredMondParameterCount = ValueParameters.Count(p => !p.IsOptional); HasParams = Parameters.Any(p => p.Type == ParameterType.Params); if (info is MethodInfo methodInfo) { ReturnConversion = MondFunctionBinder.MakeReturnConversion(methodInfo.ReturnType); } }
public static MondValue Bind(Type type) { var moduleAttrib = type.Attribute <MondModuleAttribute>(); if (moduleAttrib == null) { throw new Exception("Type does not have the MondModule attribute"); } var moduleName = moduleAttrib.Name ?? type.Name; var result = new MondValue(MondValueType.Object); foreach (var method in type.GetMethods()) { var functionAttrib = method.Attribute <MondFunctionAttribute>(); if (functionAttrib == null) { continue; } var name = functionAttrib.Name ?? method.Name; result[name] = MondFunctionBinder.Bind(moduleName, name, method); } return(result); }
private static ClassBinding BindImpl(Type type) { var classAttrib = type.Attribute <MondClassAttribute>(); if (classAttrib == null) { throw new MondBindingException(BindingError.TypeMissingAttribute, "MondClass"); } var className = classAttrib.Name ?? type.Name; var functions = new Dictionary <string, MondInstanceFunction>(); var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); foreach (var method in MondFunctionBinder.BindInstance(className, methods, type)) { var name = method.Item1; if (functions.ContainsKey(name)) { throw new MondBindingException(BindingError.DuplicateDefinition, name); } functions[name] = method.Item2; } var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var property in properties.PropertyMethods()) { var name = property.Item1; if (functions.ContainsKey(name)) { throw new MondBindingException(BindingError.DuplicateDefinition, name); } var propertyArray = new[] { property.Item2 }; var propertyBinding = MondFunctionBinder.BindInstance(className, propertyArray, type, MondFunctionBinder.MethodType.Property, name) .FirstOrDefault(); if (propertyBinding != null) { functions[name] = propertyBinding.Item2; } } var constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); var constructor = MondFunctionBinder.BindConstructor(className, constructors); return(new ClassBinding(className, constructor, functions)); }
private static IEnumerable <Tuple <string, MondInstanceFunction> > BindImpl(Type type) { var moduleAttrib = type.Attribute <MondModuleAttribute>(); if (moduleAttrib == null) { throw new MondBindingException(BindingError.TypeMissingAttribute, "MondModule"); } var moduleName = moduleAttrib.Name ?? type.Name; var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); return(MondFunctionBinder.BindInstance(moduleName, methods)); }
private static Dictionary <string, MondFunction> BindImpl(Type type) { ModuleBinding binding; lock (Cache) { if (Cache.TryGetValue(type, out binding)) { return(binding.Functions); } } var moduleAttrib = type.Attribute <MondModuleAttribute>(); if (moduleAttrib == null) { throw new MondBindingException(BindingError.TypeMissingAttribute, "MondModule"); } var moduleName = moduleAttrib.Name ?? type.Name; var result = new Dictionary <string, MondFunction>(); var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); foreach (var method in MondFunctionBinder.BindStatic(moduleName, methods)) { var name = method.Item1; if (result.ContainsKey(name)) { throw new MondBindingException(BindingError.DuplicateDefinition, name); } result[name] = method.Item2; } var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static); foreach (var property in properties.PropertyMethods()) { var name = property.Item1; if (result.ContainsKey(name)) { throw new MondBindingException(BindingError.DuplicateDefinition, name); } var propertyArray = new[] { property.Item2 }; var propertyBinding = MondFunctionBinder.BindStatic(moduleName, propertyArray, MondFunctionBinder.MethodType.Property, name) .FirstOrDefault(); if (propertyBinding != null) { result[name] = propertyBinding.Item2; } } binding = new ModuleBinding(result); lock (Cache) Cache[type] = binding; return(result); }
public Parameter(ParameterInfo info) { Info = info; IsOptional = info.IsOptional; var paramType = info.ParameterType; if (MondFunctionBinder.TypeCheckMap.TryGetValue(paramType, out var mondTypes)) { Type = ParameterType.Value; TypeName = mondTypes[0].GetName(); if (paramType == typeof(bool)) { Priority = 10; } else if (MondFunctionBinder.NumberTypes.Contains(paramType)) { Priority = 20; } else if (paramType == typeof(string)) { Priority = 30; } Conversion = MondFunctionBinder.MakeParameterConversion(info.ParameterType); MondTypes = mondTypes; return; } if (paramType == typeof(MondValue)) { if (info.Attribute <MondInstanceAttribute>() != null) { Type = ParameterType.Instance; TypeName = "instance"; return; } Type = ParameterType.Value; TypeName = "any"; Priority = 100; MondTypes = AnyTypes; Conversion = v => v; return; } if (paramType == typeof(MondValue[]) && info.Attribute <ParamArrayAttribute>() != null) { Type = ParameterType.Params; TypeName = "..."; Priority = 75; return; } if (paramType == typeof(MondState)) { Type = ParameterType.State; TypeName = "state"; return; } MondClassAttribute mondClass; if ((mondClass = paramType.Attribute <MondClassAttribute>()) != null) { Type = ParameterType.Value; TypeName = mondClass.Name ?? paramType.Name; MondTypes = ObjectTypes; UserDataType = info.ParameterType; #if !NO_EXPRESSIONS Conversion = v => Expression.Convert(Expression.PropertyOrField(v, "UserData"), info.ParameterType); #else Conversion = v => v.UserData; #endif return; } throw new MondBindingException(BindingError.UnsupportedType, info.ParameterType); }
public static MondFunction Bind(Type type, out MondValue prototype) { var classAttrib = type.Attribute <MondClassAttribute>(); if (classAttrib == null) { throw new Exception("Type does not have the MondClass attribute"); } var className = classAttrib.Name ?? type.Name; MondFunction constructor = null; prototype = new MondValue(MondValueType.Object); foreach (var method in type.GetMethods()) { var functionAttrib = method.Attribute <MondFunctionAttribute>(); if (functionAttrib == null) { continue; } var name = functionAttrib.Name ?? method.Name; prototype[name] = MondFunctionBinder.BindInstance(className, name, type, method); } foreach (var property in type.GetProperties()) { var functionAttrib = property.Attribute <MondFunctionAttribute>(); if (functionAttrib == null) { continue; } var name = functionAttrib.Name ?? property.Name; var getMethod = property.GetGetMethod(); var setMethod = property.GetSetMethod(); if (getMethod != null && getMethod.IsPublic) { prototype["get" + name] = MondFunctionBinder.BindInstance(className, name, type, getMethod); } if (setMethod != null && setMethod.IsPublic) { prototype["set" + name] = MondFunctionBinder.BindInstance(className, name, type, setMethod); } } foreach (var ctor in type.GetConstructors()) { var constructorAttrib = ctor.Attribute <MondClassConstructorAttribute>(); if (constructorAttrib == null) { continue; } if (constructor != null) { throw new Exception("Classes can not have multiple Mond constructors"); } constructor = MondFunctionBinder.BindConstructor(className, ctor, prototype); } if (constructor == null) { throw new Exception("Classes must have one Mond constructor"); } return(constructor); }