コード例 #1
0
ファイル: MethodTable.cs プロジェクト: xserve98/Mond
        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);
            }
        }
コード例 #2
0
ファイル: MondModuleBinder.cs プロジェクト: DatZach/Mond
        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);
        }
コード例 #3
0
ファイル: MondClassBinder.cs プロジェクト: foobit/Mond
        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));
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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);
        }
コード例 #6
0
ファイル: MethodTable.cs プロジェクト: xserve98/Mond
        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);
        }
コード例 #7
0
ファイル: MondClassBinder.cs プロジェクト: DatZach/Mond
        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);
        }