예제 #1
0
 public void Add(MethodDef method)
 {
     if ((method.Attributes & MethodDefAttributes.Getter) != 0)
     {
         if (this.getMethod != null) throw new JSBindingException("Getter already defined.");
         this.getMethod = method;
     }
     else if ((method.Attributes & MethodDefAttributes.Setter) != 0)
     {
         if (this.setMethod != null) throw new JSBindingException("Setter already defined.");
         this.setMethod = method;
     }
     else throw new JSBindingException("Method must be a getter or setter.");
 }
        private void Create()
        {
            var methods = GetMethods();
            var declaringMethodNames = new HashSet<string>(methods.Select(_ => _.Name));

            var dispatchTable = new DispatchTable<MethodDef>(declaringMethodNames.Count);
            var propertyDispatchTable = new DispatchTable<PropertyDef>();

            foreach (var method in methods)
            {
                string declaringName = method.Name;
                string scriptingName = ConvertIdentifier(declaringName);
                string scriptingPropertyName = null;

                if (declaringName != scriptingName && declaringMethodNames.Contains(scriptingName))
                {
                    throw ExceptionBuilder.TypeAlreadyReservesMember(this.Type, scriptingName, declaringName);
                }

                var property = method.GetDeclaringTypeProperty();
                if (property != null)
                {
                    var declaringPropertyName = property.Name;
                    scriptingPropertyName = ConvertIdentifier(declaringPropertyName);

                    if (declaringPropertyName != scriptingPropertyName && declaringMethodNames.Contains(scriptingPropertyName))
                    {
                        throw ExceptionBuilder.TypeAlreadyReservesMember(this.Type, scriptingPropertyName, declaringPropertyName);
                    }
                }

                // method attributes
                var methodAttributes = method.IsStatic ? MethodDefAttributes.Static : MethodDefAttributes.None;

                if (property != null)
                {
                    methodAttributes |= MethodDefAttributes.Hidden;

                    if (method.IsGetterLikeSignature())
                    {
                        methodAttributes |= MethodDefAttributes.Getter;
                    }
                    else if (method.IsSetterLikeSignature())
                    {
                        methodAttributes |= MethodDefAttributes.Setter;
                    }
                }

                // put method info into a dispatch table
                // note: property accessors can't be overloaded
                var scriptableMethodInfo = dispatchTable.GetOrDefault(scriptingName);
                if (scriptableMethodInfo == null)
                {
                    scriptableMethodInfo = new MethodDef(scriptingName, methodAttributes);
                    dispatchTable.Add(scriptableMethodInfo);
                }
                scriptableMethodInfo.Add(method);

                // put property info into a property dispatch table
                if (property != null)
                {
                    var scriptablePropertyInfo = propertyDispatchTable.GetOrDefault(scriptingPropertyName);
                    if (scriptablePropertyInfo == null)
                    {
                        scriptablePropertyInfo = new PropertyDef(scriptingPropertyName);
                        propertyDispatchTable.Add(scriptablePropertyInfo);
                    }

                    scriptablePropertyInfo.Add(scriptableMethodInfo);
                }
            }

            dispatchTable.Optimize();
            propertyDispatchTable.Optimize();

            // TODO: prevent dispatch tables from modifying

            this.dispatchTable = dispatchTable;
            this.propertyDispatchTable = propertyDispatchTable;
        }
 private MethodInvokerBuilder(MethodDef methodDef)
 {
     this.def = methodDef;
 }
 public static MethodInvoker Create(MethodDef methodDef)
 {
     return new MethodInvokerBuilder(methodDef).Create();
 }
 private static string GetMethodInvokerName(MethodDef method, bool includeClassName = true)
 {
     if (includeClassName)
     {
         return string.Format("MethodInvoker:[{0}].{1}",
             method.GetMethods().First().ReflectedType.FullName,
             method.Name
             );
     }
     else
     {
         return string.Format("MethodInvoker:[].{0}",
             method.Name
             );
     }
 }