Пример #1
0
        /// <summary>
        /// serialization this typedefinition to binary format and
        /// send to native side
        /// </summary>
        /// <param name="writer"></param>
        internal void WriteDefinitionToStream(BinaryWriter writer)
        {
            //----------------------
            //this is our custom protocol/convention with the MiniJsBridge
            //we may change this in the future
            //eg. use json serialization/deserialization
            //----------------------

            //1. kind/flags
            writer.Write((short)this.MemberId);
            //2. member id
            writer.Write((short)0);
            //3. typename
            WriteUtf16String(this.MemberName, writer);

            //4. num of field
            int j = fields.Count;

            writer.Write((short)j);
            for (int i = 0; i < j; ++i)
            {
                JsFieldDefinition fielddef = fields[i];
                //field flags
                writer.Write((short)0);

                //*** field id -- unique field id within one type
                writer.Write((short)fielddef.MemberId);

                //field name
                WriteUtf16String(fielddef.MemberName, writer);
            }
            //------------------
            j = methods.Count;
            writer.Write((short)j);
            for (int i = 0; i < j; ++i)
            {
                JsMethodDefinition methoddef = methods[i];
                //method flags
                writer.Write((short)0);
                //id
                writer.Write((short)methoddef.MemberId);
                //method name
                WriteUtf16String(methoddef.MemberName, writer);
            }

            //property
            j = props.Count;
            writer.Write((short)j);
            for (int i = 0; i < j; ++i)
            {
                JsPropertyDefinition property = this.props[i];
                //flags
                writer.Write((short)0);
                //id
                writer.Write((short)property.MemberId);
                //name
                WriteUtf16String(property.MemberName, writer);
            }
        }
 public void AddMore(JsMethodDefinition anotherMethod)
 {
     if (_members == null)
     {
         _members = new List <JsMethodDefinition>();
         _members.Add(_onlyOneMember);
         _onlyOneMember = null;
     }
     _members.Add(anotherMethod);
 }
 public void AddMoreMember(JsMethodDefinition anotherMethod)
 {
     if (members == null)
     {
         members = new List <JsMethodDefinition>();
         members.Add(onlyOneMember);
         onlyOneMember = null;
     }
     members.Add(anotherMethod);
 }
Пример #4
0
        void EngineListener_MethodCall(int mIndex, int methodKind, IntPtr metArgs)
        {
            switch (methodKind)
            {
            case 1:
            {
                //property get
                if (mIndex == 0)
                {
                    return;
                }
                //------------------------------------------
                JsMethodDefinition getterMethod = registerProperties[mIndex].GetterMethod;

                if (getterMethod != null)
                {
                    getterMethod.InvokeMethod(new ManagedMethodArgs(this, metArgs));
                }
            }
            break;

            case 2:
            {
                //property set
                if (mIndex == 0)
                {
                    return;
                }
                //------------------------------------------
                JsMethodDefinition setterMethod = registerProperties[mIndex].SetterMethod;
                if (setterMethod != null)
                {
                    setterMethod.InvokeMethod(new ManagedMethodArgs(this, metArgs));
                }
            }
            break;

            default:
            {
                if (mIndex == 0)
                {
                    return;
                }
                JsMethodDefinition foundMet = registerMethods[mIndex];
                if (foundMet != null)
                {
                    foundMet.InvokeMethod(new ManagedMethodArgs(this, metArgs));
                }
            }
            break;
            }
        }
Пример #5
0
        internal void CollectionTypeMembers(JsTypeDefinition jsTypeDefinition)
        {
            List <JsMethodDefinition> methods = jsTypeDefinition.GetMethods();
            int j = methods.Count;

            for (int i = 0; i < j; ++i)
            {
                JsMethodDefinition met = methods[i];
                met.SetMemberId(registerMethods.Count);
                registerMethods.Add(met);
            }

            List <JsPropertyDefinition> properties = jsTypeDefinition.GetProperties();

            j = properties.Count;
            for (int i = 0; i < j; ++i)
            {
                var p = properties[i];
                p.SetMemberId(registerProperties.Count);
                registerProperties.Add(p);
            }
        }
        protected override JsTypeDefinition OnBuildRequest(Type t)
        {
            JsTypeDefinition typedefinition = new JsTypeDefinition(t.Name);
            //-------
            //only instance /public method /prop***
            Dictionary <string, JsMethodGroup> methodGroups = new Dictionary <string, JsMethodGroup>();

            foreach (MethodInfo met in GetMehodIter(t, BindingFlags.Instance | BindingFlags.Public))
            {
                var           jsMethodDef = new JsMethodDefinition(met.Name, met);
                JsMethodGroup existingGroup;
                if (!methodGroups.TryGetValue(met.Name, out existingGroup))
                {
                    //create new one
                    existingGroup = new JsMethodGroup(met.Name, jsMethodDef);
                    methodGroups.Add(met.Name, existingGroup);
                }
                else
                {
                    existingGroup.AddMoreMember(jsMethodDef);
                }
            }
            //-----------------
            foreach (JsMethodGroup metGroup in methodGroups.Values)
            {
                JsMethodDefinition selectedMethod = metGroup.GetJsMethod();
                if (selectedMethod != null)
                {
                    typedefinition.AddMember(metGroup.GetJsMethod());
                }
            }
            //-----------------
            foreach (var property in GetPropertyIter(t, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public))
            {
                typedefinition.AddMember(new JsPropertyDefinition(property.Name, property));
            }

            return(typedefinition);
        }
Пример #7
0
 public void AddMember(JsMethodDefinition methodDef)
 {
     methodDef.SetOwner(this);
     methods.Add(methodDef);
 }
            public JsMethodDefinition SelectBestMethod(Type[] inputArgTypes)
            {
                if (_onlyOneMember != null)
                {
                    return(_onlyOneMember);
                }
                //------------------------------
                //TODO: check performance here
                //TODO: review How Roslyn select best method ***
                //-----------------------------
                //best fit?

                int memberCount = _members.Count;

                int[] bestScores        = new int[memberCount];
                int   maxBestScore      = -1;
                int   candidateMaxIndex = 0;
                bool  hasOnly1Candidate = true;

                for (int m = memberCount - 1; m >= 0; --m)
                {
                    JsMethodDefinition met = _members[m];
                    int convScore          = 0;

                    for (int argNo = _argCount - 1; argNo >= 0; --argNo)
                    {
                        //pick one arg
                        Type inputArgType = inputArgTypes[argNo];
                        Type parType      = met.Parameters[argNo].ParameterType;
                        if (inputArgType == null)
                        {
                            //if input value is null
                            //special mx
                            convScore += CalculateTypeDepth(parType, typeof(object));
                        }
                        else if (parType == inputArgType)
                        {
                            //exact type
                            convScore += 255;
                        }
                        else if (IsAssignable(parType, inputArgType))
                        {
                            //assignable
                            //check inheritance depth?
                            //find conversion energy (depth)
                            convScore += CalculateTypeDepth(inputArgType, parType);
                        }
                        else
                        {
                            //can't assign
                            //can't use this method
                            convScore = -1;
                            argNo     = -1; //not check more => go next method
                        }
                    }

                    bestScores[m] = convScore; //store value , for later use ,TODO: review here
                    if (convScore > maxBestScore)
                    {
                        maxBestScore      = convScore;
                        candidateMaxIndex = m;
                        hasOnly1Candidate = true;
                    }
                    else if (convScore == maxBestScore)
                    {
                        hasOnly1Candidate = false;
                    }
                }
                //-----------------------------
                //find max best score
                //TODO: check if we have more than 1 best value
                //-----------------------------
                if (maxBestScore < 0)
                {
                    return(null);
                }
                if (hasOnly1Candidate)
                {
                    return(_members[candidateMaxIndex]);
                }
                //TODO: review ...

                //find member with max score
                JsMethodDefinition[] candidateMethods = new JsMethodDefinition[memberCount];
                int n = 0;

                for (int i = memberCount - 1; i >= 0; --i)
                {
                    if (bestScores[i] == maxBestScore)
                    {
                        candidateMethods[n] = _members[i];
                        n++;
                    }
                }

                if (n > 1)
                {
                    //more than 1 best method
                }
                else
                {
                    //only 1
                    return(candidateMethods[0]);
                }
                return(null);
            }
 public SameArgMethodList(int argCount, JsMethodDefinition onlyOneMember)
 {
     _argCount      = argCount;
     _onlyOneMember = onlyOneMember;
 }
            public virtual JsMethodDefinition GetJsMethod()
            {
                if (onlyOneMember != null)
                {
                    return(onlyOneMember);
                }
                else
                {
                    //if we have > 1 member
                    //create a 'wrapper' method for all method in this group
                    //------
                    //analyze method based on arg count and the arg type
                    //quite complex
                    //------
                    //this is a default .... resolver
                    //you can provide a special method overload resolution
                    //for each method group

                    if (sameArgNumMethodLists == null)
                    {
                        sameArgNumMethodLists = new Dictionary <int, SameArgMethodList>();
                        int j = members.Count;
                        for (int i = 0; i < j; ++i)
                        {
                            JsMethodDefinition met  = members[i];
                            ParameterInfo[]    pars = met.Parameters;
                            if (pars != null)
                            {
                                SameArgMethodList existingMethods;
                                int count = pars.Length;
                                if (!sameArgNumMethodLists.TryGetValue(count, out existingMethods))
                                {
                                    existingMethods = new SameArgMethodList(count, met);
                                    sameArgNumMethodLists.Add(count, existingMethods);
                                }
                                else
                                {
                                    existingMethods.AddMore(met);
                                }
                            }
                            else
                            {
                                //delegate base?
                                //
                                //TODO : review this again
                                return(null);
                            }
                        }
                    }
                    return(new JsMethodDefinition(this.Name, args =>
                    {
                        //how to select the best over method based on input args:
                        //this resolve at runtime=> may be slow
                        //TODO: review here again

                        //num of arg not match
                        //TODO &
                        //LIMITATION: this version dose NOT support
                        //1. default parameter
                        //2. param args
                        //invoke method
                        var thisArg = args.GetThisArg();
                        //actual input arg count
                        int actualArgCount = args.ArgCount;

                        SameArgMethodList foundMets;
                        if (!sameArgNumMethodLists.TryGetValue(actualArgCount, out foundMets))
                        {
                            //so if num of arg not match the return
                            args.SetResultUndefined(); //?
                            return;
                        }

                        //-----------
                        //select best method by checking each vars
                        //TODO: how to find  hints ?
                        //best match args
                        object[] inputArgs = new object[actualArgCount];
                        Type[] inputArgsTypes = new Type[actualArgCount];
                        for (int i = 0; i < actualArgCount; ++i)
                        {
                            object arg_v = args.GetArgAsObject(i);
                            inputArgs[i] = arg_v;
                            if (arg_v == null)
                            {
                                //review here again
                                inputArgsTypes[i] = null;//null value
                            }
                            else
                            {
                                inputArgsTypes[i] = arg_v.GetType();
                            }
                        }
                        JsMethodDefinition selectedMet = foundMets.SelectBestMethod(inputArgsTypes);
                        if (selectedMet == null)
                        {
                            //if not found
                            //TODO: review here , throw exception?
                            args.SetResultUndefined(); //?
                            return;
                        }

                        selectedMet.InvokeMethod(args);
                    }));
                }
            }
 public JsMethodGroup(string name, JsMethodDefinition firstMember)
 {
     this.Name          = name;
     this.onlyOneMember = firstMember;
 }