예제 #1
0
파일: Function.cs 프로젝트: akinomyoga/afh
        /// <summary>
        /// 指定した引数に最も適合するメソッドのオーバーロードを検索します
        /// </summary>
        /// <param name="arguments">引数</param>
        /// <returns>最も適合するメソッドのオーバーロード</returns>
        /// <exception cref="ArgumentException">
        /// 指定した引数に適合するメソッドのオーバーロードが見つからなかった場合に発生します。
        /// </exception>
        protected System.Reflection.MethodInfo SelectOverload(JavaScript.Array arguments)
        {
            float comp0, compat = float.NegativeInfinity;

            System.Reflection.MethodInfo m0, m = null;
            int iM = this.methods.Length;
            int w  = 0;                 //重なり

            for (int i = 0; i < iM; i++)
            {
                m0    = this.methods[i];
                comp0 = FunctionBase.ConvertParamsCompat(m0, arguments);
                if (comp0 < compat)
                {
                    continue;
                }
                if (comp0 == compat)
                {
                    w++; continue;
                }
                w      = 1;
                compat = comp0;
                m      = m0;
            }
            if (compat == float.NegativeInfinity)
            {
                throw new System.ArgumentException(OVERLOAD_NONE, "arguments");
            }
            if (w > 1)
            {
                throw new System.ArgumentException(OVERLOAD_AMBIGUOUS, "arguments");
            }
            return(m);
        }
예제 #2
0
파일: Function.cs 프로젝트: akinomyoga/afh
        /// <summary>
        /// Javascript 側で指定した引数と、指定した MethodInfo の引数の適合性を判定します
        /// </summary>
        /// <returns>
        /// 計算した適合性を返します。
        /// 引数を変換する事が出来ない場合には float.NegativeInfinity を返します
        /// </returns>
        /// <remarks>
        /// TODO: params 修飾子が付いている時、一つも要素を指定しない場合の動作を実装
        /// 1. arrParam.Length>arguments.length の判定だけでは不十分
        /// 2. 点数を低くする(params の付いた引数だけ除いた別のオーバーロードの可能性)
        /// </remarks>
        public static float ConvertParamsCompat(System.Reflection.MethodInfo m, JavaScript.Array arguments)
        {
            System.Reflection.ParameterInfo[] arrParam = m.GetParameters();
            if (arrParam.Length == 0)
            {
                return(0);
            }
            if (arrParam.Length > arguments.length)
            {
                return(float.NegativeInfinity);
            }
            int   iM = arrParam.Length;
            float r  = 0;

            for (int i = 0; i < iM; i++)
            {
                //CHECK>OK: params の入った関数を識別出来るか実際に確認する事
                if (i + 1 == iM && arrParam[iM - 1].GetCustomAttributes(typeof(System.ParamArrayAttribute), false).Length > 0)
                {
                    System.Type t = arrParam[iM - 1].ParameterType.GetElementType();
                    iM = arguments.length;
                    for (; i < iM; i++)
                    {
                        r += arguments[i].ConvertCompat(t);
                    }
                    break;
                }
                r += arguments[i].ConvertCompat(arrParam[i].ParameterType);
            }
            return(r + (arguments.length - iM) * COMPAT_OVERPARAM);
        }
예제 #3
0
파일: Function.cs 프로젝트: akinomyoga/afh
        /// <summary>
        /// Javascript 側で指定した Javascript.Array 型の引数配列を
        /// object[] 型に変換します。
        /// </summary>
        /// <param name="m">最終的に呼び出したいメソッド</param>
        /// <param name="arguments">呼び出しに用いる Javascript.Array の引数配列</param>
        /// <returns>実際に呼び出しに用いる事の出来る引数配列 object[]</returns>
        /// <remarks>
        /// 実装: ConvertParamsCompat の処理と似た処理を行うので、
        /// ConvertParamsCompat の際に System.Type[] を作って置くのも手。
        /// </remarks>
        public static object[] ConvertParams(System.Reflection.MethodInfo m, JavaScript.Array arguments)
        {
            System.Reflection.ParameterInfo[] arrParam = m.GetParameters();
            int iM = arrParam.Length;

            object[] r = new object[iM];
            for (int i = 0; i < iM; i++)
            {
                if (i + 1 == iM && arrParam[iM - 1].GetCustomAttributes(typeof(System.ParamArrayAttribute), false).Length > 0)
                {
                    //変換
                    System.Collections.ArrayList list = new System.Collections.ArrayList();
                    System.Type t = arrParam[iM - 1].ParameterType.GetElementType();
                    for (; i < arguments.length; i++)
                    {
                        list.Add(arguments[i].Convert(t));
                    }

                    r[iM - 1] = list.ToArray(t);
                }
                else
                {
                    r[i] = arguments[i].Convert(arrParam[i].ParameterType);
                }
            }
            return(r);
        }
예제 #4
0
파일: Array.cs 프로젝트: akinomyoga/afh
 /// <summary>
 /// 配列の初期化子
 /// </summary>
 /// <param name="array">配列の要素を指定します。</param>
 /// <returns>指定した引数を要素として持つ配列 Javascript.Array を返します。</returns>
 public static JavaScript.Array Construct(params JavaScript.Object[] array)
 {
     JavaScript.Array ret = new JavaScript.Array();
     foreach (JavaScript.Object o in array)
     {
         ret[ret.len++] = Global.ConvertFromManaged(o);
     }
     return(ret);
 }
예제 #5
0
        /// <summary>
        /// Object 木を辿って目的のメンバ関数を実行します
        /// </summary>
        /// <param name="index">
        /// 次に検索するべき names の位置。
        /// このメソッドを持つインスタンスが
        /// names[index] と言う名のメンバを持つ事が期待されています。
        /// </param>
        /// <param name="names">オブジェクトの系譜。<see cref="afh.Javascript.Object.TraceMember"/></param>
        /// <returns>見つかったメンバを実行した結果を返します</returns>
        /// <exception cref="Null.UndefinedException">
        /// 指定したメンバが未定義だった場合に発生します。
        /// </exception>
        public JavaScript.Object InvokeMember(int index, string[] names, JavaScript.Array arguments)
        {
            //--直接の親と key の取得
            int dest = names.Length - 2;

            JavaScript.Object parent = index <= dest?this.TraceMember(index, dest, names) : this;

            string key = names[dest + 1];

            //--Invoke
            try{
                return(((FunctionBase)parent[key]).Invoke(parent, arguments));
            }catch (System.NullReferenceException e) {
                //※: 一回目の NullReferenceException は時間がかかる
                throw new Null.UndefinedException(e);
            }catch (System.InvalidCastException e) {
                throw new System.Exception("指定したオブジェクトは関数ではありません", e);
            }catch (System.Exception e) { throw e; }
        }
예제 #6
0
파일: Function.cs 프로젝트: akinomyoga/afh
        //===========================================================
        //		Invoke
        //===========================================================
        /// <summary>
        /// 指定したオブジェクトの当該メソッドを実行します
        /// </summary>
        /// <param name="obj">オブジェクトを指定します</param>
        /// <param name="arguments">メソッドに渡す引数を指定します</param>
        /// <returns>メソッドの結果を返します</returns>
        /// <remarks>
        /// 案1: Type と Methods を保持し Invoke の命令が来たら
        /// <list>
        /// <item><description>Type と obj を照合</description></item>
        /// <item><description>引数リストの比較</description></item>
        /// <item><description>実行</description></item>
        /// </list>
        /// </remarks>
        public override JavaScript.Object Invoke(JavaScript.Object obj, JavaScript.Array arguments)
        {
            // ManagedObject 以外の時 (Javascript.Object を直接指定した場合の時) にも対応する事にする。
            //	古いコード
            //		if(!(obj is Javascript.ManagedObject))throw new System.ArgumentException(INVOKE_NOTMANAGED,"obj");
            //		object o=((Javascript.ManagedObject)obj).Value;
            object o = (obj is JavaScript.ManagedObject)?((JavaScript.ManagedObject)obj).Value:obj;

            //CHECK>×: IsSubclassOf で継承した interface も確認する事が出来るかどうか
            if (!Global.IsCastable(o.GetType(), this.type))
            {
                throw new System.ArgumentException(INVOKE_NOTSUPPORTED, "obj");
            }
            System.Reflection.MethodInfo m;
            try{
                m = this.SelectOverload(arguments);
            }catch (System.Exception e) { throw e; }
            object ret = m.Invoke(o, FunctionBase.ConvertParams(m, arguments));

            return(Global.ConvertFromManaged(ret));
        }
예제 #7
0
파일: Function.cs 프로젝트: akinomyoga/afh
 /// <summary>
 /// この関数を実行します。
 /// </summary>
 /// <param name="obj">この関数を保持する Object です。関数内からは this で参照されます</param>
 /// <param name="arguments">この関数に渡される引数の配列を設定します</param>
 /// <returns>この関数を実行した結果を返します</returns>
 public abstract JavaScript.Object Invoke(JavaScript.Object obj, JavaScript.Array arguments);