示例#1
0
文件: binaryop.cs 项目: ydunk/masters
        protected MethodInfo GetOperator(IReflect ir1, IReflect ir2)
        {
            if (ir1 is ClassScope)
            {
                ir1 = ((ClassScope)ir1).GetUnderlyingTypeIfEnum();
            }
            if (ir2 is ClassScope)
            {
                ir2 = ((ClassScope)ir2).GetUnderlyingTypeIfEnum();
            }
            Type t1 = ir1 is Type ? (Type)ir1 : Typeob.Object;
            Type t2 = ir2 is Type ? (Type)ir2 : Typeob.Object;

            if (this.type1 == t1 && this.type2 == t2)
            {
                return(this.operatorMeth);
            }
            this.type1        = t1;
            this.type2        = t2;
            this.operatorMeth = null;
            if (t1 == Typeob.String || Convert.IsPrimitiveNumericType(ir1) || Typeob.JSObject.IsAssignableFrom(t1))
            {
                t1 = null;
            }
            if (t2 == Typeob.String || Convert.IsPrimitiveNumericType(ir2) || Typeob.JSObject.IsAssignableFrom(t2))
            {
                t2 = null;
            }
            if (t1 == null && t2 == null)
            {
                return(null);
            }
            //One of the operands is an object of a type that might have a user defined operator.
            String name = "op_NoSuchOp";

            switch (this.operatorTok)
            {
            case JSToken.BitwiseAnd: name = "op_BitwiseAnd"; break;

            case JSToken.BitwiseOr: name = "op_BitwiseOr"; break;

            case JSToken.BitwiseXor: name = "op_ExclusiveOr"; break;

            case JSToken.Divide: name = "op_Division"; break;

            case JSToken.Equal: name = "op_Equality"; break;

            case JSToken.GreaterThan: name = "op_GreaterThan"; break;

            case JSToken.GreaterThanEqual: name = "op_GreaterThanOrEqual"; break;

            case JSToken.LeftShift: name = "op_LeftShift"; break;

            case JSToken.LessThan: name = "op_LessThan"; break;

            case JSToken.LessThanEqual: name = "op_LessThanOrEqual"; break;

            case JSToken.Minus: name = "op_Subtraction"; break;

            case JSToken.Modulo: name = "op_Modulus"; break;

            case JSToken.Multiply: name = "op_Multiply"; break;

            case JSToken.NotEqual: name = "op_Inequality"; break;

            case JSToken.Plus: name = "op_Addition"; break;

            case JSToken.RightShift: name = "op_RightShift"; break;
            }
            Type[] types = new Type[] { this.type1, this.type2 };
            if (t1 == t2)
            {
                MethodInfo op = t1.GetMethod(name, BindingFlags.Public | BindingFlags.Static, JSBinder.ob, types, null);
                if (op != null && (op.Attributes & MethodAttributes.SpecialName) != 0 && op.GetParameters().Length == 2)
                {
                    this.operatorMeth = op;
                }
            }
            else
            {
                //Search both operand types, but only if there is a possibility that they might have operators defined on them
                MethodInfo op1 = t1 == null ? null : t1.GetMethod(name, BindingFlags.Public | BindingFlags.Static, JSBinder.ob, types, null);
                MethodInfo op2 = t2 == null ? null : t2.GetMethod(name, BindingFlags.Public | BindingFlags.Static, JSBinder.ob, types, null);
                this.operatorMeth = JSBinder.SelectOperator(op1, op2, this.type1, this.type2); //Choose the better of the two
            }
            if (this.operatorMeth != null)
            {
                this.operatorMeth = new JSMethodInfo(this.operatorMeth);
            }
            return(this.operatorMeth);
        }
示例#2
0
        protected MethodInfo GetOperator(IReflect ir1, IReflect ir2)
        {
            if (ir1 is ClassScope)
            {
                ir1 = ((ClassScope)ir1).GetUnderlyingTypeIfEnum();
            }
            if (ir2 is ClassScope)
            {
                ir2 = ((ClassScope)ir2).GetUnderlyingTypeIfEnum();
            }
            Type c     = (ir1 is Type) ? ((Type)ir1) : Typeob.Object;
            Type type2 = (ir2 is Type) ? ((Type)ir2) : Typeob.Object;

            if ((this.type1 != c) || (this.type2 != type2))
            {
                this.type1        = c;
                this.type2        = type2;
                this.operatorMeth = null;
                if (((c == Typeob.String) || Microsoft.JScript.Convert.IsPrimitiveNumericType(ir1)) || Typeob.JSObject.IsAssignableFrom(c))
                {
                    c = null;
                }
                if (((type2 == Typeob.String) || Microsoft.JScript.Convert.IsPrimitiveNumericType(ir2)) || Typeob.JSObject.IsAssignableFrom(type2))
                {
                    type2 = null;
                }
                if ((c == null) && (type2 == null))
                {
                    return(null);
                }
                string name = "op_NoSuchOp";
                switch (this.operatorTok)
                {
                case JSToken.FirstBinaryOp:
                    name = "op_Addition";
                    break;

                case JSToken.Minus:
                    name = "op_Subtraction";
                    break;

                case JSToken.BitwiseOr:
                    name = "op_BitwiseOr";
                    break;

                case JSToken.BitwiseXor:
                    name = "op_ExclusiveOr";
                    break;

                case JSToken.BitwiseAnd:
                    name = "op_BitwiseAnd";
                    break;

                case JSToken.Equal:
                    name = "op_Equality";
                    break;

                case JSToken.NotEqual:
                    name = "op_Inequality";
                    break;

                case JSToken.GreaterThan:
                    name = "op_GreaterThan";
                    break;

                case JSToken.LessThan:
                    name = "op_LessThan";
                    break;

                case JSToken.LessThanEqual:
                    name = "op_LessThanOrEqual";
                    break;

                case JSToken.GreaterThanEqual:
                    name = "op_GreaterThanOrEqual";
                    break;

                case JSToken.LeftShift:
                    name = "op_LeftShift";
                    break;

                case JSToken.RightShift:
                    name = "op_RightShift";
                    break;

                case JSToken.Multiply:
                    name = "op_Multiply";
                    break;

                case JSToken.Divide:
                    name = "op_Division";
                    break;

                case JSToken.Modulo:
                    name = "op_Modulus";
                    break;
                }
                Type[] types = new Type[] { this.type1, this.type2 };
                if (c == type2)
                {
                    MethodInfo info = c.GetMethod(name, BindingFlags.Public | BindingFlags.Static, JSBinder.ob, types, null);
                    if (((info != null) && ((info.Attributes & MethodAttributes.SpecialName) != MethodAttributes.PrivateScope)) && (info.GetParameters().Length == 2))
                    {
                        this.operatorMeth = info;
                    }
                }
                else
                {
                    MethodInfo info2 = (c == null) ? null : c.GetMethod(name, BindingFlags.Public | BindingFlags.Static, JSBinder.ob, types, null);
                    MethodInfo info3 = (type2 == null) ? null : type2.GetMethod(name, BindingFlags.Public | BindingFlags.Static, JSBinder.ob, types, null);
                    this.operatorMeth = JSBinder.SelectOperator(info2, info3, this.type1, this.type2);
                }
                if (this.operatorMeth != null)
                {
                    this.operatorMeth = new JSMethodInfo(this.operatorMeth);
                }
            }
            return(this.operatorMeth);
        }