private bool TryMakeDefaultUnaryRule(OperatorInfo info)
        {
            switch (info.Operator)
            {
            case Operators.IsTrue:
                if (_types[0] == typeof(bool))
                {
                    _rule.Target = _rule.MakeReturn(Binder, Param0);
                    return(true);
                }
                break;

            case Operators.Negate:
                if (TypeUtils.IsArithmetic(_types[0]))
                {
                    _rule.Target = _rule.MakeReturn(Binder, Ast.Negate(Param0));
                    return(true);
                }
                break;

            case Operators.Not:
                if (TypeUtils.IsIntegerOrBool(_types[0]))
                {
                    _rule.Target = _rule.MakeReturn(Binder, Ast.Not(Param0));
                    return(true);
                }
                break;

            case Operators.Documentation:
                object[] attrs         = _types[0].GetCustomAttributes(typeof(DocumentationAttribute), true);
                string   documentation = String.Empty;

                if (attrs.Length > 0)
                {
                    documentation = ((DocumentationAttribute)attrs[0]).Documentation;
                }

                _rule.Target = _rule.MakeReturn(Binder, Ast.Constant(documentation));
                return(true);

            case Operators.MemberNames:
                if (typeof(IMembersList).IsAssignableFrom(_types[0]))
                {
                    MakeIMembersListRule();
                    return(true);
                }

                MemberInfo[] members             = _types[0].GetMembers();
                Dictionary <string, string> mems = new Dictionary <string, string>();
                foreach (MemberInfo mi in members)
                {
                    mems[mi.Name] = mi.Name;
                }

                string[] res = new string[mems.Count];
                mems.Keys.CopyTo(res, 0);
                _rule.Target = _rule.MakeReturn(Binder, Ast.Constant(res));
                return(true);

            case Operators.CallSignatures:
                MakeCallSignatureResult(CompilerHelpers.GetMethodTargets(_args[0]));
                break;

            case Operators.IsCallable:
                // IsCallable() is tightly tied to Call actions. So in general, we need the call-action providers to also
                // provide IsCallable() status.
                // This is just a rough fallback. We could also attempt to simulate the default CallBinder logic to see
                // if there are any applicable calls targets, but that would be complex (the callbinder wants the argument list,
                // which we don't have here), and still not correct.
                bool callable = false;
                if (typeof(Delegate).IsAssignableFrom(_types[0]) ||
                    typeof(MethodGroup).IsAssignableFrom(_types[0]))
                {
                    callable = true;
                }

                _rule.Target = _rule.MakeReturn(Context.LanguageContext.Binder, Ast.Constant(callable));
                return(true);
            }
            return(false);
        }
Exemplo n.º 2
0
 public DynamicMetaObject GetCallSignatures(DynamicMetaObject target)
 {
     return(MakeCallSignatureResult(CompilerHelpers.GetMethodTargets(target.LimitType), target));
 }
Exemplo n.º 3
0
        private static MetaObject TryMakeDefaultUnaryRule(OperatorInfo info, Expression codeContext, MetaObject[] args)
        {
            if (args.Length == 1)
            {
                Restrictions restrictions = Restrictions.GetTypeRestriction(args[0].Expression, args[0].LimitType).Merge(Restrictions.Combine(args));
                switch (info.Operator)
                {
                case Operators.IsTrue:
                    if (args[0].LimitType == typeof(bool))
                    {
                        return(args[0]);
                    }
                    break;

                case Operators.Negate:
                    if (TypeUtils.IsArithmetic(args[0].LimitType))
                    {
                        return(new MetaObject(
                                   Ast.Negate(args[0].Expression),
                                   restrictions
                                   ));
                    }
                    break;

                case Operators.Not:
                    if (TypeUtils.IsIntegerOrBool(args[0].LimitType))
                    {
                        return(new MetaObject(
                                   Ast.Not(args[0].Expression),
                                   restrictions
                                   ));
                    }
                    break;

                case Operators.Documentation:
                    object[] attrs         = args[0].LimitType.GetCustomAttributes(typeof(DocumentationAttribute), true);
                    string   documentation = String.Empty;

                    if (attrs.Length > 0)
                    {
                        documentation = ((DocumentationAttribute)attrs[0]).Documentation;
                    }

                    return(new MetaObject(
                               Ast.Constant(documentation),
                               restrictions
                               ));

                case Operators.MemberNames:
                    if (typeof(IMembersList).IsAssignableFrom(args[0].LimitType))
                    {
                        return(MakeIMembersListRule(codeContext, args[0]));
                    }

                    MemberInfo[] members             = args[0].LimitType.GetMembers();
                    Dictionary <string, string> mems = new Dictionary <string, string>();
                    foreach (MemberInfo mi in members)
                    {
                        mems[mi.Name] = mi.Name;
                    }

                    string[] res = new string[mems.Count];
                    mems.Keys.CopyTo(res, 0);

                    return(new MetaObject(
                               Ast.Constant(res),
                               restrictions
                               ));

                case Operators.CallSignatures:
                    return(MakeCallSignatureResult(CompilerHelpers.GetMethodTargets(args[0].LimitType), args[0]));

                case Operators.IsCallable:
                    // IsCallable() is tightly tied to Call actions. So in general, we need the call-action providers to also
                    // provide IsCallable() status.
                    // This is just a rough fallback. We could also attempt to simulate the default CallBinder logic to see
                    // if there are any applicable calls targets, but that would be complex (the callbinder wants the argument list,
                    // which we don't have here), and still not correct.
                    bool callable = false;
                    if (typeof(Delegate).IsAssignableFrom(args[0].LimitType) ||
                        typeof(MethodGroup).IsAssignableFrom(args[0].LimitType))
                    {
                        callable = true;
                    }

                    return(new MetaObject(
                               Ast.Constant(callable),
                               restrictions
                               ));
                }
            }
            return(null);
        }