Example #1
0
 /// <summary>
 /// Creates a new BindingTarget when the method binding has succeeded.
 /// </summary>
 internal BindingTarget(string name, int actualArgumentCount, MethodTarget target, NarrowingLevel level, RestrictionInfo restrictedArgs) {
     _name = name;
     _target = target;
     _restrictedArgs = restrictedArgs;
     _level = level;
     _actualArgs = actualArgumentCount;
 }
Example #2
0
        public override bool CanConvertFrom(Type fromType, DynamicMetaObject fromArg, ParameterWrapper toParameter, NarrowingLevel level) {
            if ((fromType == typeof(List) || fromType.IsSubclassOf(typeof(List)))) {
                if (toParameter.Type.IsGenericType() &&
                    toParameter.Type.GetGenericTypeDefinition() == typeof(IList<>) &&
                    (toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false) ||
                     toParameter.ParameterInfo.IsDefined(typeof(BytesConversionNoStringAttribute), false))) {
                    return false;
                }
            } else if (fromType == typeof(string)) {
                if (toParameter.Type == typeof(IList<byte>) &&
                    !Binder.Context.PythonOptions.Python30 &&
                    toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false)) {
                    // string -> byte array, we allow this in Python 2.6
                    return true;
                }
            } else if (fromType == typeof(Bytes)) {
                if (toParameter.Type == typeof(string) &&
                    !Binder.Context.PythonOptions.Python30 &&
                    toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false)) {
                    return true;
                }
            }

            return base.CanConvertFrom(fromType, fromArg, toParameter, level);
        }
Example #3
0
        public override bool CanConvertFrom(Type fromType, DynamicMetaObject fromArgument, ParameterWrapper toParameter, NarrowingLevel level)
        {
            if (toParameter.Type == typeof(string) && (level == NarrowingLevel.Three || level == NarrowingLevel.All))
                return true;

            if (toParameter.IsParamsArray == true && typeof(IList<object>).IsAssignableFrom(fromType))
            {
                var toType = toParameter.Type.GetElementType();
                var list = (IList<object>)fromArgument.Value;
                for(var i = 0; i < list.Count; i++)
                {
                    var itm = list[i];
                    var argExp = Expression.Call(
                        Expression.Convert(fromArgument.Expression, fromArgument.LimitType),
                        (typeof(IList<object>).GetMethod("get_Item")),
                        Expression.Constant(i, typeof(int))
                    );
                    var arg = new DynamicMetaObject(
                        argExp,
                        fromArgument.Restrictions,
                        itm
                    );
                    if(!CanConvertFrom(itm.GetType(), arg, new ParameterWrapper(null, toType, null, ParameterBindingFlags.None), level))
                        return false;
                }
                return true;
            }

            return base.CanConvertFrom(fromType, fromArgument, toParameter, level);
        }
Example #4
0
        private readonly int _actualArgs;                                                 // gets the actual number of arguments provided

        /// <summary>
        /// Creates a new BindingTarget when the method binding has succeeded.
        /// </summary>
        internal BindingTarget(string name, int actualArgumentCount, MethodCandidate candidate, NarrowingLevel level, RestrictedArguments restrictedArgs) {
            _name = name;
            _candidate = candidate;
            _restrictedArgs = restrictedArgs;
            _level = level;
            _actualArgs = actualArgumentCount;
        }
Example #5
0
        private readonly int _actualArgs;                                                 // gets the actual number of arguments provided

        /// <summary>
        /// Creates a new BindingTarget when the method binding has succeeded.
        /// 
        /// OBSOLETE
        /// </summary>
        internal BindingTarget(string name, int actualArgumentCount, MethodTarget target, NarrowingLevel level, Type[] argTests) {
            _name = name;
            _target = target;
            _argTests = argTests;
            _level = level;
            _actualArgs = actualArgumentCount;
        }
Example #6
0
 public CallBinderHelper(CodeContext context, TAction action, object[] args, RuleBuilder rule, IList <MethodBase> targets, NarrowingLevel maxLevel, bool isReversedOperator)
     : this(context, action, args, rule)
 {
     _targets          = ArrayUtils.ToArray(targets);
     _reversedOperator = isReversedOperator;
     _maxLevel         = maxLevel;
 }
Example #7
0
        public bool HasConversionFrom(Type ty, NarrowingLevel allowNarrowing)
        {
            if (ty == Type)
            {
                return(true);
            }

            if (ty == None.Type)
            {
                if (_prohibitNull)
                {
                    return(false);
                }

                if (Type.IsGenericType && Type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    return(true);
                }
                return(!Type.IsValueType);
            }
            else
            {
                return(_binder.CanConvertFrom(ty, Type, allowNarrowing));
            }
        }
Example #8
0
        /// <summary>
        /// Performs binding against a set of overloaded methods using the specified arguments.  The arguments are
        /// consumed as specified by the CallSignature object.
        /// </summary>
        /// <param name="minLevel">TODO.</param>
        /// <param name="maxLevel">TODO.</param>
        /// <param name="resolver">Overload resolver.</param>
        /// <param name="targets">The methods to be called</param>
        /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param>
        /// <param name="target">The resulting binding target which can be used for producing error information.</param>
        /// <param name="name">The name of the method or null to use the name from targets.</param>
        /// <returns>A meta object which results from the call.</returns>
        public DynamicMetaObject CallMethod(DefaultOverloadResolver resolver, IList <MethodBase> targets, BindingRestrictions restrictions, string name,
                                            NarrowingLevel minLevel, NarrowingLevel maxLevel, out BindingTarget target)
        {
            ContractUtils.RequiresNotNull(resolver, nameof(resolver));
            ContractUtils.RequiresNotNullItems(targets, nameof(targets));
            ContractUtils.RequiresNotNull(restrictions, nameof(restrictions));

            // attempt to bind to an individual method
            target = resolver.ResolveOverload(name ?? GetTargetName(targets), targets, minLevel, maxLevel);

            if (target.Success)
            {
                // if we succeed make the target for the rule
                return(new DynamicMetaObject(
                           target.MakeExpression(),
                           restrictions.Merge(
                               MakeSplatTests(resolver.CallType, resolver.Signature, resolver.Arguments).
                               Merge(target.RestrictedArguments.GetAllRestrictions())
                               )
                           ));
            }

            // make an error rule
            return(MakeInvalidParametersRule(resolver, restrictions, target));
        }
Example #9
0
        private readonly int _actualArgs;                                                 // gets the actual number of arguments provided

        /// <summary>
        /// Creates a new BindingTarget when the method binding has succeeded.
        /// </summary>
        internal BindingTarget(string name, int actualArgumentCount, MethodCandidate candidate, NarrowingLevel level, RestrictedArguments restrictedArgs)
        {
            _name           = name;
            _candidate      = candidate;
            _restrictedArgs = restrictedArgs;
            _level          = level;
            _actualArgs     = actualArgumentCount;
        }
Example #10
0
 /// <summary>
 /// Creates a new BindingTarget when the method binding has succeeded
 /// </summary>
 internal BindingTarget(string name, int actualArgumentCount, MethodTarget target, NarrowingLevel level, MetaObject[] restrictedArgs)
 {
     _name           = name;
     _target         = target;
     _restrictedArgs = restrictedArgs;
     _level          = level;
     _actualArgs     = actualArgumentCount;
 }
Example #11
0
        private readonly int _actualArgs;                                                 // gets the actual number of arguments provided

        /// <summary>
        /// Creates a new BindingTarget when the method binding has succeeded
        /// </summary>
        internal BindingTarget(string name, int actualArgumentCount, MethodTarget target, NarrowingLevel level, Type[] argTests)
        {
            _name       = name;
            _target     = target;
            _argTests   = argTests;
            _level      = level;
            _actualArgs = actualArgumentCount;
        }
Example #12
0
        private readonly int[] _expectedArgs;                                             // gets the acceptable number of parameters which can be passed to the method.

        /// <summary>
        /// Creates a new BindingTarget when the method binding has succeeded.
        /// </summary>
        internal BindingTarget(string name, int actualArgumentCount, MethodCandidate candidate, NarrowingLevel level, RestrictedArguments restrictedArgs)
        {
            Name                = name;
            MethodCandidate     = candidate;
            RestrictedArguments = restrictedArgs;
            NarrowingLevel      = level;
            ActualArgumentCount = actualArgumentCount;
        }
Example #13
0
        public bool IsApplicable(Type[] types, SymbolId[] names, NarrowingLevel allowNarrowing)
        {
            if (!TryGetNormalizedArguments(types, names, out types))
            {
                return(false);
            }

            return(IsApplicable(types, allowNarrowing));
        }
Example #14
0
        internal MethodCandidate(MethodTarget target, List <ParameterWrapper> parameters)
        {
            Debug.Assert(target != null);

            _target         = target;
            _parameters     = parameters;
            _narrowingLevel = NarrowingLevel.None;
            parameters.TrimExcess();
        }
        public override bool CanConvertFrom(Type fromType, DynamicMetaObject fromArgument, ParameterWrapper toParameter, NarrowingLevel level)
        {
            if (level >= NarrowingLevel.Two)
            {
                if (toParameter.Type == typeof(string))
                    return true;
            }

            return base.CanConvertFrom(fromType, fromArgument, toParameter, level);
        }
Example #16
0
        private readonly NarrowingLevel _maxLevel;                  // the maximum narrowing level allowed

        public CallBinderHelper(CodeContext context, TAction action, object[] args, RuleBuilder rule)
            : base(context, action)
        {
            ContractUtils.RequiresNotEmpty(args, "args");

            _maxLevel = NarrowingLevel.All;
            _args     = RemoveExplicitInstanceArgument(action, args);
            _rule     = rule;
            _test     = _rule.MakeTypeTest(CompilerHelpers.GetType(Callable), 0);
        }
Example #17
0
        public override bool CanConvertFrom(Type fromType, ParameterWrapper toParameter, NarrowingLevel level) {
            if ((fromType == typeof(List) || fromType.IsSubclassOf(typeof(List))) && 
                toParameter.Type.IsGenericType && 
                toParameter.Type.GetGenericTypeDefinition() == typeof(IList<>)) {
                if (toParameter.ParameterInfo.IsDefined(typeof(ProhibitGenericListConversionAttribute), false)) {
                    return false;
                }
            }

            return base.CanConvertFrom(fromType, toParameter, level);
        }
Example #18
0
        private List <MethodCandidate> SelectTargets(CallType callType, Type[] types, SymbolId[] names)
        {
            // obsolete: this should be removed entirely:
            if (!_binder.StrictParameterCheck)
            {
                if (_targets.Count == 1 && !_binder.IsBinaryOperator && names.Length == 0)
                {
                    return(_targets);
                }
            }

            List <MethodCandidate> applicableTargets = new List <MethodCandidate>();

            foreach (MethodCandidate target in _targets)
            {
                if (target.IsApplicable(types, names, NarrowingLevel.None))
                {
                    applicableTargets.Add(target);
                }
            }

            List <MethodCandidate> result = null;

            if (TryGetApplicableTarget(callType, applicableTargets, types, out result))
            {
                return(result);
            }

            //no targets are applicable without narrowing conversions, so try those
            foreach (MethodCandidate target in _targets)
            {
                if (target.IsApplicable(types, names, NarrowingLevel.Preferred))
                {
                    applicableTargets.Add(new MethodCandidate(target, NarrowingLevel.Preferred));
                }
            }

            if (TryGetApplicableTarget(callType, applicableTargets, types, out result))
            {
                return(result);
            }

            foreach (MethodCandidate target in _targets)
            {
                NarrowingLevel nl = _binder.IsBinaryOperator ? NarrowingLevel.Operator : NarrowingLevel.All;
                if (target.IsApplicable(types, names, nl))
                {
                    applicableTargets.Add(new MethodCandidate(target, nl));
                }
            }

            return(applicableTargets);
        }
 /// <summary>
 /// Performs binding against a set of overloaded methods using the specified arguments.  All arguments 
 /// are treated as positional arguments.
 /// </summary>
 /// <param name="parameterBinder">ParameterBinder used to map arguments to parameters.</param>
 /// <param name="targets">The methods to be called</param>
 /// <param name="args">The arguments for the call</param>
 /// <param name="maxLevel">The maximum narrowing level for arguments.  The current narrowing level is flowed thorugh to the DefaultBinder.</param>
 /// <param name="minLevel">The minimum narrowing level for the arguments.  The current narrowing level is flowed thorugh to the DefaultBinder.</param>        
 /// <returns>A meta object which results from the call.</returns>
 public DynamicMetaObject CallMethod(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<DynamicMetaObject> args, NarrowingLevel minLevel, NarrowingLevel maxLevel) {
     return CallWorker(
         parameterBinder,
         targets,
         args,
         new CallSignature(args.Count),
         CallTypes.None,
         BindingRestrictions.Empty,
         minLevel,
         maxLevel,
         null
     );
 }
Example #20
0
        public bool IsApplicable(Type[] types, NarrowingLevel allowNarrowing)
        {
            Debug.Assert(types.Length == _parameters.Count);

            for (int i = 0; i < types.Length; i++)
            {
                if (!_parameters[i].HasConversionFrom(types[i], allowNarrowing))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #21
0
        internal bool IsApplicable(Type[] types, NarrowingLevel narrowingLevel, List <ConversionResult> conversionResults)
        {
            // attempt to convert each parameter
            bool res = true;

            for (int i = 0; i < types.Length; i++)
            {
                bool success = _parameters[i].HasConversionFrom(types[i], narrowingLevel);

                conversionResults.Add(new ConversionResult(types[i], _parameters[i].Type, i, !success));

                res &= success;
            }

            return(res);
        }
Example #22
0
        private static Candidate GetPreferredParameter(ParameterWrapper candidateOne, ParameterWrapper candidateTwo, MetaObject actualType)
        {
            Assert.NotNull(candidateOne, candidateTwo, actualType);

            if (candidateOne._binder.ParametersEquivalent(candidateOne, candidateTwo))
            {
                return(Candidate.Equivalent);
            }

            for (NarrowingLevel curLevel = NarrowingLevel.None; curLevel <= NarrowingLevel.All; curLevel++)
            {
                Candidate candidate = candidateOne._binder.SelectBestConversionFor(actualType.LimitType, candidateOne, candidateTwo, curLevel);
                if (candidate.Chosen())
                {
                    return(candidate);
                }
            }

            return(GetPreferredParameter(candidateOne, candidateTwo));
        }
Example #23
0
        internal bool IsApplicable(MetaObject[] objects, NarrowingLevel narrowingLevel, List <ConversionResult> conversionResults)
        {
            // attempt to convert each parameter
            bool res = true;

            for (int i = 0; i < objects.Length; i++)
            {
                /*if (objects[i].NeedsDeferral) {
                 *  conversionResults.Add(new ConversionResult(typeof(Dynamic), _parameters[i].Type, i, false));
                 * } else*/{
                    bool success = _parameters[i].HasConversionFrom(objects[i].LimitType, narrowingLevel);

                    conversionResults.Add(new ConversionResult(objects[i].LimitType, _parameters[i].Type, i, !success));

                    res &= success;
                }
            }

            return(res);
        }
Example #24
0
        public bool IsApplicable(Type[] types, SymbolId[] names, NarrowingLevel allowNarrowing)
        {
#if FULL
            foreach (ParameterWrapper pw in _parameters)
            {
                // can't bind to methods that are params dictionaries, only to their extended forms.
                if (pw.IsParamsDict)
                {
                    return(false);
                }
            }
#endif


            if (!TryGetNormalizedArguments(types, names, out types))
            {
                return(false);
            }

            return(IsApplicable(types, allowNarrowing));
        }
Example #25
0
        internal static ConversionResultKind?ToConversionResultKind(this NarrowingLevel narrowingLevel)
        {
            switch (narrowingLevel)
            {
            case NarrowingLevel.None:
                return(null);

            case NarrowingLevel.One:
                return(ConversionResultKind.ImplicitCast);

            case NarrowingLevel.Two:
                return(ConversionResultKind.ImplicitTry);

            case NarrowingLevel.Three:
                return(ConversionResultKind.ExplicitCast);

            case NarrowingLevel.All:
            default:
                return(ConversionResultKind.ExplicitTry);
            }
        }
 public override bool CanConvertFrom(Type fromType, Type toType, NarrowingLevel level)
 {
     if (fromType == toType || toType.IsAssignableFrom(fromType))
     {
         return(true);
     }
     if (toType == typeof(object) || toType == fromType)
     {
         return(true);
     }
     if (fromType == typeof(int) && toType == typeof(double))
     {
         return(true);
     }
     if (fromType == typeof(SymbolId) && toType.IsEnum)
     {
         return(true);
     }
     if (fromType == typeof(object) && level == NarrowingLevel.All)
     {
         return(true);
     }
     return(false);
 }
 public override bool CanConvertFrom(Type fromType, Type toType, NarrowingLevel level)
 {
     if (fromType == toType || toType.IsAssignableFrom(fromType))
       {
     return true;
       }
       if (toType == typeof(object) || toType == fromType)
       {
     return true;
       }
       if (fromType == typeof(int) && toType == typeof(double))
       {
     return true;
       }
       if (fromType == typeof(SymbolId) && toType.IsEnum)
       {
     return true;
       }
       if (fromType == typeof(object) && level == NarrowingLevel.All)
       {
     return true;
       }
       return false;
 }
Example #28
0
        public override Candidate SelectBestConversionFor(Type /*!*/ actualType, ParameterWrapper /*!*/ candidateOne, ParameterWrapper /*!*/ candidateTwo, NarrowingLevel level)
        {
            Type typeOne = candidateOne.Type;
            Type typeTwo = candidateTwo.Type;

            if (actualType == typeof(Null))
            {
                // if nil is passed as a block argument prefer BlockParam over missing block;
                if (typeOne == typeof(BlockParam) && typeTwo == typeof(MissingBlockParam))
                {
                    return(Candidate.One);
                }

                if (typeOne == typeof(MissingBlockParam) && typeTwo == typeof(BlockParam))
                {
                    return(Candidate.Two);
                }
            }
            else
            {
                if (actualType == typeOne && candidateOne.ProhibitNull)
                {
                    return(Candidate.One);
                }

                if (actualType == typeTwo && candidateTwo.ProhibitNull)
                {
                    return(Candidate.Two);
                }
            }

            if (actualType == typeOne)
            {
                return(Candidate.One);
            }

            if (actualType == typeTwo)
            {
                return(Candidate.Two);
            }


            return(Candidate.Equivalent);
        }
Example #29
0
 public override bool CanConvertFrom(Type/*!*/ fromType, Type/*!*/ toType, bool toNotNullable, NarrowingLevel level) {
     return Converter.CanConvertFrom(null, fromType, toType, toNotNullable, level, false, false);
 }
Example #30
0
        private Candidate GetPreferredParameter(ParameterWrapper candidateOne, ParameterWrapper candidateTwo, DynamicMetaObject arg, NarrowingLevel level) {
            Assert.NotNull(candidateOne, candidateTwo);

            if (ParametersEquivalent(candidateOne, candidateTwo)) {
                return Candidate.Equivalent;
            }

            Candidate candidate = SelectBestConversionFor(arg, candidateOne, candidateTwo, level);
            if (candidate.Chosen()) {
                return candidate;
            }

            if (CanConvertFrom(candidateTwo, candidateOne)) {
                if (CanConvertFrom(candidateOne, candidateTwo)) {
                    return Candidate.Ambiguous;
                } else {
                    return Candidate.Two;
                }
            } else if (CanConvertFrom(candidateOne, candidateTwo)) {
                return Candidate.One;
            }

            // Special additional rules to order numeric value types
            Type t1 = candidateOne.Type;
            Type t2 = candidateTwo.Type;

            Candidate preferred = PreferConvert(t1, t2);
            if (preferred.Chosen()) {
                return preferred;
            }

            preferred = PreferConvert(t2, t1).TheOther();
            if (preferred.Chosen()) {
                return preferred;
            }

            // consider the actual argument type:
            Type argType = arg.GetLimitType();
            NarrowingLevel levelOne = NarrowingLevel.None;
            while (levelOne < level && !CanConvertFrom(argType, arg, candidateOne, levelOne)) {
                if (levelOne == NarrowingLevel.All) {
                    Debug.Assert(false, "Each argument should be convertible to the corresponding parameter");
                    break;
                }
                levelOne++;
            }

            NarrowingLevel levelTwo = NarrowingLevel.None;
            while (levelTwo < level && !CanConvertFrom(argType, arg, candidateTwo, levelTwo)) {
                if (levelTwo == NarrowingLevel.All) {
                    Debug.Assert(false, "Each argument should be convertible to the corresponding parameter");
                    break;
                }
                levelTwo++;
            }

            if (levelOne < levelTwo) {
                return Candidate.One;
            } else if (levelOne > levelTwo) {
                return Candidate.Two;
            } else {
                return Candidate.Ambiguous;
            }
        }
 private int? SelectBestConversionFor(Type actualType, Type candidateOne, Type candidateTwo, NarrowingLevel level) {
     Type ret = _binder.SelectBestConversionFor(actualType, candidateOne, candidateTwo, level);
     if (ret != null) {
         if (ret == candidateOne) {
             return +1;
         } else if (ret == candidateTwo) {
             return -1;
         }
     }
     return null;
 }
        public override Candidate SelectBestConversionFor(DynamicMetaObject /*!*/ arg, ParameterWrapper /*!*/ candidateOne,
                                                          ParameterWrapper /*!*/ candidateTwo, NarrowingLevel level)
        {
            Type typeOne    = candidateOne.Type;
            Type typeTwo    = candidateTwo.Type;
            Type actualType = arg.GetLimitType();

            if (actualType == typeof(DynamicNull))
            {
                // if nil is passed as a block argument prefers BlockParam over a missing block:
                if (typeOne == typeof(BlockParam) && typeTwo == typeof(MissingBlockParam))
                {
                    Debug.Assert(!candidateOne.ProhibitNull);
                    return(Candidate.One);
                }

                if (typeOne == typeof(MissingBlockParam) && typeTwo == typeof(BlockParam))
                {
                    Debug.Assert(!candidateTwo.ProhibitNull);
                    return(Candidate.Two);
                }
            }
            else
            {
                if (typeOne == actualType)
                {
                    if (typeTwo == actualType)
                    {
                        // prefer non-nullable reference type over nullable:
                        if (!actualType.IsValueType)
                        {
                            if (candidateOne.ProhibitNull)
                            {
                                return(Candidate.One);
                            }
                            else if (candidateTwo.ProhibitNull)
                            {
                                return(Candidate.Two);
                            }
                        }
                    }
                    else
                    {
                        return(Candidate.One);
                    }
                }
                else if (typeTwo == actualType)
                {
                    return(Candidate.Two);
                }
            }

            // prefer integer type over enum:
            if (typeOne.IsEnum && Enum.GetUnderlyingType(typeOne) == typeTwo)
            {
                return(Candidate.Two);
            }

            if (typeTwo.IsEnum && Enum.GetUnderlyingType(typeTwo) == typeOne)
            {
                return(Candidate.One);
            }

            return(base.SelectBestConversionFor(arg, candidateOne, candidateTwo, level));
        }
Example #33
0
 public override bool CanConvertFrom(Type /*!*/ fromType, Type /*!*/ toType, bool toNotNullable, NarrowingLevel level)
 {
     return(Converter.CanConvertFrom(null, fromType, toType, toNotNullable, level, false, false).IsConvertible);
 }
Example #34
0
        internal static bool CanConvertFrom(Type fromType, Type toType, NarrowingLevel level)
        {
            ContractUtils.RequiresNotNull(fromType, "fromType");
            ContractUtils.RequiresNotNull(toType, "toType");

            // NarrowingLevel.Zero

            if (fromType == toType)
            {
                return(true);
            }

            //  I don't want to consider boxing before numeric conversion, else I don't get the convert-int-to-long  behavior required to select Numbers.lt(long,long) over Numbers.lt(long,Object)
            //  We also need to get the narrow-long-to-int behavior required to avoid casting in host expression calls.
            //  IronRuby and IronPython both do this here:
            //if (toType.IsAssignableFrom(fromType))
            //{
            //    return true;
            //}

            // Because long[] and ulong[] are inter-assignable, we run into problems.
            // Let's just not convert from an array of one primitive type to another.

            if (fromType.IsArray && toType.IsArray && (Util.IsPrimitiveNumeric(fromType.GetElementType()) || Util.IsPrimitiveNumeric(toType.GetElementType())))
            {
                return(false);
            }

            if (!Util.IsPrimitiveNumeric(fromType) && toType.IsAssignableFrom(fromType))
            {
                return(true);
            }

            if (fromType.IsCOMObject && toType.IsInterface)
            {
                return(true); // A COM object could be cast to any interface
            }
            if (HasImplicitNumericConversion(fromType, toType))
            {
                return(true);
            }

            // try available type conversions...
            object[] tcas = toType.GetCustomAttributes(typeof(TypeConverterAttribute), true);
            foreach (TypeConverterAttribute tca in tcas)
            {
                TypeConverter tc = GetTypeConverter(tca);

                if (tc == null)
                {
                    continue;
                }

                if (tc.CanConvertFrom(fromType))
                {
                    return(true);
                }
            }

            //!!!do user-defined implicit conversions here

            if (level == NarrowingLevel.None)
            {
                return(false);
            }


            // NarrowingLevel.One

            if (WideningIntegerConversion(fromType, toType))
            {
                return(true);
            }


            if (level == NarrowingLevel.One)
            {
                return(false);
            }


            // NarrowingLevel.Two

            if (SpecialClojureConversion(fromType, toType))
            {
                return(true);
            }

            if (DelegateType.IsAssignableFrom(toType) && typeof(IFn).IsAssignableFrom(fromType))
            {
                return(true);
            }


            if (level == NarrowingLevel.Two)
            {
                return(false);
            }


            // NarrowingLevel.Three

            if (toType == typeof(bool))
            {
                return(true);
            }


            if (Util.IsPrimitiveNumeric(toType) && Util.IsPrimitiveNumeric(fromType))
            {
                return(true);
            }

            // Handle conversions of IEnumerable<Object> or IEnumerable to IEnumerable<T> for any T
            // Similar to code in IPy's IronPython.Runtime.Converter.HasNarrowingConversion
            if (toType.IsGenericType)
            {
                Type genTo = toType.GetGenericTypeDefinition();
                if (genTo == typeof(IEnumerable <>))
                {
                    return(typeof(IEnumerable <Object>).IsAssignableFrom(fromType) || typeof(IEnumerable).IsAssignableFrom(fromType));
                }
            }

            if (level == NarrowingLevel.Three)
            {
                return(false);
            }


            // NarrowingLevel.All

            if (level < NarrowingLevel.All)
            {
                return(false);
            }

            // pick up boxing numerics here
            if (toType.IsAssignableFrom(fromType))
            {
                return(true);
            }

            // TODO: Rethink.  IPy has the following, but we get overload problems on Numbers ops
            //return HasNarrowingConversion(fromType, toType, level);

            // Handle conversions of IEnumerable<Object> or IEnumerable to IEnumerable<T> for any T
            // Similar to code in IPy's IronPython.Runtime.Converter.HasNarrowingConversion
            if (toType.IsGenericType)
            {
                Type genTo = toType.GetGenericTypeDefinition();
                if (genTo == typeof(IList <>))
                {
                    return(typeof(IList <object>).IsAssignableFrom(fromType));
                }
                else if (genTo == typeof(Nullable <>))
                {
                    if (fromType == typeof(DynamicNull) || CanConvertFrom(fromType, toType.GetGenericArguments()[0], level))
                    {
                        return(true);
                    }
                }
                else if (genTo == typeof(IDictionary <,>))
                {
                    return(typeof(IDictionary <object, object>).IsAssignableFrom(fromType));
                }
            }

            return(false);
        }
Example #35
0
        private static bool HasNarrowingConversion(Type fromType, Type toType, NarrowingLevel allowNarrowing)
        {
            if (allowNarrowing == PythonNarrowing.IndexOperator)
            {
                if (toType == CharType && fromType == StringType)
                {
                    return(true);
                }
                if (toType == StringType && fromType == CharType)
                {
                    return(true);
                }
                //if (toType == Int32Type && fromType == BigIntegerType) return true;
                //if (IsIntegral(fromType) && IsIntegral(toType)) return true;

                //Check if there is an implicit convertor defined on fromType to toType
                if (HasImplicitConversion(fromType, toType))
                {
                    return(true);
                }
            }

            if (toType == DoubleType && fromType == DecimalType)
            {
                return(true);
            }
            if (toType == SingleType && fromType == DecimalType)
            {
                return(true);
            }

            if (toType.IsArray)
            {
                return(typeof(PythonTuple).IsAssignableFrom(fromType));
            }

            if (allowNarrowing == PythonNarrowing.IndexOperator)
            {
                if (IsNumeric(fromType) && IsNumeric(toType))
                {
                    if (fromType != typeof(float) && fromType != typeof(double) && fromType != typeof(decimal) && fromType != typeof(Complex))
                    {
                        return(true);
                    }
                }
                if (fromType == typeof(bool) && IsNumeric(toType))
                {
                    return(true);
                }

                if (toType == CharType && fromType == StringType)
                {
                    return(true);
                }
                if (toType == Int32Type && fromType == BooleanType)
                {
                    return(true);
                }

                // Everything can convert to Boolean in Python
                if (toType == BooleanType)
                {
                    return(true);
                }

                if (DelegateType.IsAssignableFrom(toType) && IsPythonType(fromType))
                {
                    return(true);
                }
                if (IEnumerableType == toType && IsPythonType(fromType))
                {
                    return(true);
                }

                if (toType == typeof(IEnumerator))
                {
                    if (IsPythonType(fromType))
                    {
                        return(true);
                    }
                }
                else if (toType.IsGenericType())
                {
                    Type genTo = toType.GetGenericTypeDefinition();
                    if (genTo == IEnumerableOfTType)
                    {
                        return(IEnumerableOfObjectType.IsAssignableFrom(fromType) ||
                               IEnumerableType.IsAssignableFrom(fromType) ||
                               fromType == typeof(OldInstance));
                    }
                    else if (genTo == typeof(System.Collections.Generic.IEnumerator <>))
                    {
                        if (IsPythonType(fromType))
                        {
                            return(true);
                        }
                    }
                }
            }

            if (allowNarrowing == PythonNarrowing.All)
            {
                //__int__, __float__, __long__
                if (IsNumeric(fromType) && IsNumeric(toType))
                {
                    return(true);
                }
                if (toType == Int32Type && HasPythonProtocol(fromType, "__int__"))
                {
                    return(true);
                }
                if (toType == DoubleType && HasPythonProtocol(fromType, "__float__"))
                {
                    return(true);
                }
                if (toType == BigIntegerType && HasPythonProtocol(fromType, "__long__"))
                {
                    return(true);
                }
            }

            if (toType.IsGenericType())
            {
                Type genTo = toType.GetGenericTypeDefinition();
                if (genTo == IListOfTType)
                {
                    return(IListOfObjectType.IsAssignableFrom(fromType));
                }
                else if (genTo == NullableOfTType)
                {
                    if (fromType == typeof(DynamicNull) || CanConvertFrom(fromType, toType.GetGenericArguments()[0], allowNarrowing))
                    {
                        return(true);
                    }
                }
                else if (genTo == IDictOfTType)
                {
                    return(IDictionaryOfObjectType.IsAssignableFrom(fromType));
                }
            }

            if (fromType == BigIntegerType && toType == Int64Type)
            {
                return(true);
            }
            if (toType.IsEnum() && fromType == Enum.GetUnderlyingType(toType))
            {
                return(true);
            }

            return(false);
        }
Example #36
0
 public override bool CanConvertFrom(Type fromType, Type toType, bool toNotNullable, NarrowingLevel level)
 {
     return(toType.IsAssignableFrom(fromType));
 }
Example #37
0
        internal static bool CanConvertFrom(DynamicMetaObject fromArg, Type/*!*/ fromType, Type/*!*/ toType, bool toNotNullable,
            NarrowingLevel level, bool explicitProtocolConversions, bool implicitProtocolConversions) {
            ContractUtils.RequiresNotNull(fromType, "fromType");
            ContractUtils.RequiresNotNull(toType, "toType");

            var metaConvertible = fromArg as IConvertibleMetaObject;

            //
            // narrowing level 0:
            //

            if (toType == fromType) {
                return true;
            }

            if (fromType == typeof(DynamicNull)) {
                if (toNotNullable) {
                    return false;
                }

                if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                    return true;
                }

                if (!toType.IsValueType) {
                    // null convertible to any reference type:
                    return true;
                } else if (toType == typeof(bool)) {
                    return true;
                } else if (!ProtocolConversionAction.HasDefaultConversion(toType)) {
                    // null not convertible to a value type unless a protocol conversion is allowed:
                    return false;
                }
            }

            // blocks:
            if (fromType == typeof(MissingBlockParam)) {
                return toType == typeof(BlockParam) && !toNotNullable;
            }

            if (fromType == typeof(BlockParam) && toType == typeof(MissingBlockParam)) {
                return true;
            }

            if (toType.IsAssignableFrom(fromType)) {
                return true;
            }

            // A COM object could be cast to any interface:
            if (Utils.IsComObjectType(fromType) && toType.IsInterface) {
                return true; 
            }

            if (HasImplicitNumericConversion(fromType, toType)) {
                return true;
            }

            if (CompilerHelpers.GetImplicitConverter(fromType, toType) != null) {
                return true;
            }

            if (metaConvertible != null) {
                return metaConvertible.CanConvertTo(toType, false);
            }

            //
            // narrowing level 1:
            //

            if (level < NarrowingLevel.One) {
                return false;
            }

            if (explicitProtocolConversions && ProtocolConversionAction.HasDefaultConversion(toType)) {
                return true;
            }

            //
            // narrowing level 2:
            //

            if (level < NarrowingLevel.Two) {
                return false;
            }

            if (HasExplicitNumericConversion(fromType, toType)) {
                return true;
            }

            if (CompilerHelpers.GetExplicitConverter(fromType, toType) != null) {
                return true;
            }

            if (CompilerHelpers.HasTypeConverter(fromType, toType)) {
                return true;
            }

            if (fromType == typeof(char) && toType == typeof(string)) {
                return true;
            }

            if (toType == typeof(bool)) {
                return true;
            }

            if (metaConvertible != null) {
                return metaConvertible.CanConvertTo(toType, true);
            }

            // 
            // narrowing level 3:
            // 

            if (level < NarrowingLevel.Three) {
                return false;
            }

            if (implicitProtocolConversions && ProtocolConversionAction.HasDefaultConversion(toType)) {
                return true;
            }

            return false;
        }
Example #38
0
        internal static bool CanConvertFrom(Type fromType, Type toType, NarrowingLevel level)
        {
            ContractUtils.RequiresNotNull(fromType, "fromType");
            ContractUtils.RequiresNotNull(toType, "toType");

            // NarrowingLevel.Zero

            if (fromType == toType)
                return true;

            //  I don't want to consider boxing before numeric conversion, else I don't get the convert-int-to-long  behavior required to select Numbers.lt(long,long) over Numbers.lt(long,Object)
            //  We also need to get the narrow-long-to-int behavior required to avoid casting in host expression calls.
            //  IronRuby and IronPython both do this here:
            //if (toType.IsAssignableFrom(fromType))
            //{
            //    return true;
            //}

            // Because long[] and ulong[] are inter-assignable, we run into problems.
            // Let's just not convert from an array of one primitive type to another.

            if (fromType.IsArray && toType.IsArray && (Util.IsPrimitiveNumeric(fromType.GetElementType()) || Util.IsPrimitiveNumeric(toType.GetElementType())))
            {
                return false;
            }

            if (!Util.IsPrimitiveNumeric(fromType) && toType.IsAssignableFrom(fromType))
            {
                return true;
            }

            if (fromType.IsCOMObject && toType.IsInterface)
                return true; // A COM object could be cast to any interface

            if (HasImplicitNumericConversion(fromType, toType))
                return true;

            // try available type conversions...
            object[] tcas = toType.GetCustomAttributes(typeof(TypeConverterAttribute), true);
            foreach (TypeConverterAttribute tca in tcas)
            {
                TypeConverter tc = GetTypeConverter(tca);

                if (tc == null) continue;

                if (tc.CanConvertFrom(fromType))
                {
                    return true;
                }
            }

            //!!!do user-defined implicit conversions here

            if (level == NarrowingLevel.None)
                return false;

            // NarrowingLevel.One

            if (WideningIntegerConversion(fromType, toType))
            {
                return true;
            }

            if (level == NarrowingLevel.One)
                return false;

            // NarrowingLevel.Two

            if (SpecialClojureConversion(fromType, toType))
            {
                return true;
            }

            if (DelegateType.IsAssignableFrom(toType) && typeof(IFn).IsAssignableFrom(fromType))
                return true;

            if (level == NarrowingLevel.Two)
                return false;

            // NarrowingLevel.Three

            if (toType == typeof(bool))
            {
                return true;
            }

            if (Util.IsPrimitiveNumeric(toType) && Util.IsPrimitiveNumeric(fromType))
            {
                return true;
            }

            // Handle conversions of IEnumerable<Object> or IEnumerable to IEnumerable<T> for any T
            // Similar to code in IPy's IronPython.Runtime.Converter.HasNarrowingConversion
            if (toType.IsGenericType)
            {
                Type genTo = toType.GetGenericTypeDefinition();
                if (genTo == typeof(IEnumerable<>))
                    return typeof(IEnumerable<Object>).IsAssignableFrom(fromType) || typeof(IEnumerable).IsAssignableFrom(fromType);
            }

            if (level == NarrowingLevel.Three)
                return false;

            // NarrowingLevel.All

            if (level < NarrowingLevel.All)
            {
                return false;
            }

            // pick up boxing numerics here
            if (toType.IsAssignableFrom(fromType))
            {
                return true;
            }

            // TODO: Rethink.  IPy has the following, but we get overload problems on Numbers ops
            //return HasNarrowingConversion(fromType, toType, level);

            // Handle conversions of IEnumerable<Object> or IEnumerable to IEnumerable<T> for any T
            // Similar to code in IPy's IronPython.Runtime.Converter.HasNarrowingConversion
            if (toType.IsGenericType)
            {
                Type genTo = toType.GetGenericTypeDefinition();
                if (genTo == typeof(IList<>) )
                {
                    return typeof(IList<object>).IsAssignableFrom(fromType);
                }
                else if (genTo == typeof(Nullable<>))
                {
                    if (fromType == typeof(DynamicNull) || CanConvertFrom(fromType, toType.GetGenericArguments()[0], level))
                    {
                        return true;
                    }
                }
                else if (genTo == typeof(IDictionary<,>) )
                {
                    return typeof(IDictionary<object,object>).IsAssignableFrom(fromType);
                }
            }

            return false;
        }
Example #39
0
        private BindingTarget MakeSuccessfulBindingTarget(ApplicableCandidate result, List<ApplicableCandidate> potentialCandidates,
            NarrowingLevel level, CandidateSet targetSet) {

            return new BindingTarget(
                _methodName,
                _actualArguments.VisibleCount,
                result.Method,
                level,
                GetRestrictedArgs(result, potentialCandidates, targetSet.Arity)
            );
        }
Example #40
0
 private ApplicableCandidate SelectBestCandidate(List<ApplicableCandidate> candidates, NarrowingLevel level) {
     foreach (var candidate in candidates) {
         if (IsBest(candidate, candidates, level)) {
             return candidate;
         }
     }
     return null;
 }
Example #41
0
 /// <summary>
 /// Returns true if fromArg of type fromType can be assigned to toParameter with a conversion on given narrowing level.
 /// </summary>
 public override bool CanConvertFrom(Type /*!*/ fromType, DynamicMetaObject fromArg, ParameterWrapper /*!*/ toParameter, NarrowingLevel level)
 {
     return(Converter.CanConvertFrom(fromArg, fromType, toParameter.Type, toParameter.ProhibitNull, level,
                                     HasExplicitProtocolConversion(toParameter), _implicitProtocolConversions
                                     ));
 }
 public override bool CanConvertFrom(Type fromType, Type toType, NarrowingLevel level)
 {
     return toType.IsAssignableFrom(fromType);
 }
Example #43
0
        public static bool CanConvertFrom(Type fromType, Type toType, NarrowingLevel allowNarrowing)
        {
            ContractUtils.RequiresNotNull(fromType, "fromType");
            ContractUtils.RequiresNotNull(toType, "toType");

            if (toType == fromType)
            {
                return(true);
            }
            if (toType.IsAssignableFrom(fromType))
            {
                return(true);
            }
#if FEATURE_COM
            if (fromType.IsCOMObject && toType.IsInterface)
            {
                return(true);                                            // A COM object could be cast to any interface
            }
#endif
            if (HasImplicitNumericConversion(fromType, toType))
            {
                return(true);
            }

            // Handling the hole that Type is the only object that we 'box'
            if (toType == TypeType &&
                (typeof(PythonType).IsAssignableFrom(fromType) ||
                 typeof(TypeGroup).IsAssignableFrom(fromType)))
            {
                return(true);
            }

            // Support extensible types with simple implicit conversions to their base types
            if (typeof(Extensible <int>).IsAssignableFrom(fromType) && CanConvertFrom(Int32Type, toType, allowNarrowing))
            {
                return(true);
            }
            if (typeof(Extensible <BigInteger>).IsAssignableFrom(fromType) && CanConvertFrom(BigIntegerType, toType, allowNarrowing))
            {
                return(true);
            }
            if (typeof(ExtensibleString).IsAssignableFrom(fromType) && CanConvertFrom(StringType, toType, allowNarrowing))
            {
                return(true);
            }
            if (typeof(Extensible <double>).IsAssignableFrom(fromType) && CanConvertFrom(DoubleType, toType, allowNarrowing))
            {
                return(true);
            }
            if (typeof(Extensible <Complex>).IsAssignableFrom(fromType) && CanConvertFrom(ComplexType, toType, allowNarrowing))
            {
                return(true);
            }

#if FEATURE_CUSTOM_TYPE_DESCRIPTOR
            // try available type conversions...
            object[] tcas = toType.GetCustomAttributes(typeof(TypeConverterAttribute), true);
            foreach (TypeConverterAttribute tca in tcas)
            {
                TypeConverter tc = GetTypeConverter(tca);

                if (tc == null)
                {
                    continue;
                }

                if (tc.CanConvertFrom(fromType))
                {
                    return(true);
                }
            }
#endif

            //!!!do user-defined implicit conversions here

            if (allowNarrowing == PythonNarrowing.None)
            {
                return(false);
            }

            return(HasNarrowingConversion(fromType, toType, allowNarrowing));
        }
Example #44
0
 /// <summary>
 /// Determines if a conversion exists from fromType to toType at the specified narrowing level.
 /// toNotNullable is true if the target variable doesn't allow null values.
 /// </summary>
 public abstract bool CanConvertFrom(Type fromType, Type toType, bool toNotNullable, NarrowingLevel level);
Example #45
0
        private int?SelectBestConversionFor(Type actualType, Type candidateOne, Type candidateTwo, NarrowingLevel level)
        {
            Type ret = _binder.SelectBestConversionFor(actualType, candidateOne, candidateTwo, level);

            if (ret != null)
            {
                if (ret == candidateOne)
                {
                    return(+1);
                }
                else if (ret == candidateTwo)
                {
                    return(-1);
                }
            }
            return(null);
        }
Example #46
0
        /// <summary>
        /// Returns true if fromArg of type fromType can be assigned to toParameter with a conversion on given narrowing level.
        /// </summary>
        public override bool CanConvertFrom(Type/*!*/ fromType, DynamicMetaObject fromArg, ParameterWrapper/*!*/ toParameter, NarrowingLevel level) {
            var result = Converter.CanConvertFrom(fromArg, fromType, toParameter.Type, toParameter.ProhibitNull, level, 
                HasExplicitProtocolConversion(toParameter), _implicitProtocolConversions
            );

            if (result.Assumption != null) {
                if (_argumentAssumptions == null) {
                    _argumentAssumptions = new List<Key<int, NarrowingLevel, Ast>>();
                }

                if (_argumentAssumptions.FindIndex((k) => k.First == toParameter.ParameterInfo.Position && k.Second == level) < 0) {
                    _argumentAssumptions.Add(Key.Create(toParameter.ParameterInfo.Position, level, result.Assumption));
                }
            }

            return result.IsConvertible;
        }
        /// <summary>
        /// Returns true if fromArg of type fromType can be assigned to toParameter with a conversion on given narrowing level.
        /// </summary>
        public override bool CanConvertFrom(Type /*!*/ fromType, DynamicMetaObject fromArg, ParameterWrapper /*!*/ toParameter, NarrowingLevel level)
        {
            var result = Converter.CanConvertFrom(fromArg, fromType, toParameter.Type, toParameter.ProhibitNull, level,
                                                  HasExplicitProtocolConversion(toParameter), _implicitProtocolConversions
                                                  );

            if (result.Assumption != null)
            {
                if (_argumentAssumptions == null)
                {
                    _argumentAssumptions = new List <Key <int, NarrowingLevel, Ast> >();
                }

                if (_argumentAssumptions.FindIndex((k) => k.First == toParameter.ParameterInfo.Position && k.Second == level) < 0)
                {
                    _argumentAssumptions.Add(Key.Create(toParameter.ParameterInfo.Position, level, result.Assumption));
                }
            }

            return(result.IsConvertible);
        }
        /// <summary>
        /// Performs binding against a set of overloaded methods using the specified arguments.  The arguments are
        /// consumed as specified by the CallSignature object.
        /// </summary>
        /// <param name="minLevel">TODO.</param>
        /// <param name="maxLevel">TODO.</param>
        /// <param name="resolver">Overload resolver.</param>
        /// <param name="targets">The methods to be called</param>
        /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param>
        /// <param name="target">The resulting binding target which can be used for producing error information.</param>
        /// <param name="name">The name of the method or null to use the name from targets.</param>
        /// <returns>A meta object which results from the call.</returns>
        public DynamicMetaObject CallMethod(DefaultOverloadResolver resolver, IList<MethodBase> targets, BindingRestrictions restrictions, string name, 
            NarrowingLevel minLevel, NarrowingLevel maxLevel, out BindingTarget target) {
            ContractUtils.RequiresNotNull(resolver, "resolver");
            ContractUtils.RequiresNotNullItems(targets, "targets");
            ContractUtils.RequiresNotNull(restrictions, "restrictions");

            // attempt to bind to an individual method
            target = resolver.ResolveOverload(name ?? GetTargetName(targets), targets, minLevel, maxLevel);

            if (target.Success) {
                // if we succeed make the target for the rule
                return new DynamicMetaObject(
                    target.MakeExpression(),
                    restrictions.Merge(
                        MakeSplatTests(resolver.CallType, resolver.Signature, resolver.Arguments).
                            Merge(target.RestrictedArguments.GetAllRestrictions())
                    )
                );
            }

            // make an error rule
            return MakeInvalidParametersRule(resolver, restrictions, target);
        }
        public bool HasConversionFrom(Type ty, NarrowingLevel allowNarrowing) {
            if (ty == Type) return true;

            if (ty == None.Type) {
                if (_prohibitNull) return false;

                if (Type.IsGenericType && Type.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                    return true;
                }
                return !Type.IsValueType;
            } else {
                return _binder.CanConvertFrom(ty, Type, allowNarrowing);
            }
        }
        public override bool CanConvertFrom(Type fromType, Type toType, bool toNotNullable, NarrowingLevel level)
        {
            //
            // NarrowLevel.Zero
            //

            if (fromType == toType)
                return true;

            //  I don't want to consider boxing before numeric conversion, else I don't get the convert-int-to-long  behavior required to select Numbers.lt(long,long) over Numbers.lt(long,Object)
            //  We also need to get the narrow-long-to-int behavior required to avoid casting in host expression calls.
            //  IronRuby does this here:
            //if (toType.IsAssignableFrom(fromType))
            //{
            //    return true;
            //}
            if ( !Util.IsPrimitiveNumeric(fromType) && toType.IsAssignableFrom(fromType))
            {
                return true;
            }

            //
            // NarrowingLevel.One
            //

            if (level < NarrowingLevel.One)
            {
                return false;
            }

            if (WideningIntegerConversion(fromType, toType))
            {
                return true;
            }

            //
            // NarrowingLevel.Two
            //

            if (level < NarrowingLevel.Two)
            {
                return false;
            }

            if ( SpecialClojureConversion(fromType, toType) )
            {
                return true;
            }

            //if (fromType == typeof(char) && toType == typeof(string))
            //{
            //    return true;
            //}

            if (toType == typeof(bool))
            {
                return true;
            }

            //
            // NarrowingLevel.Three
            //

            if (level < NarrowingLevel.Three)
            {
                return false;
            }

            if ( Util.IsPrimitiveNumeric(toType) && Util.IsPrimitiveNumeric(fromType) )
            {
                return true;
            }

            //
            // NarrowingLevel.All
            //

            if (level < NarrowingLevel.All)
            {
                return false;
            }

            // pick up boxing numerics here
            if (toType.IsAssignableFrom(fromType))
            {
                return true;
            }

            return false;

            //if (level == NarrowingLevel.All)
            //{
            //    if (fromType == typeof(long))
            //    {
            //        if (toType == typeof(int) || toType == typeof(uint) || toType == typeof(short) || toType == typeof(ushort) || toType == typeof(byte) || toType == typeof(sbyte))
            //            return true;
            //    }
            //    else if (fromType == typeof(double))
            //    {
            //        if (toType == typeof(float))
            //            return true;
            //    }
            //}

            //return base.CanConvertFrom(fromType, toType, toNotNullable, level);
        }
Example #51
0
 public override bool CanConvertFrom(Type fromType, Type toType, bool toNotNullable, NarrowingLevel level) {
     return Converter.CanConvertFrom(fromType, toType, level);
 }
Example #52
0
 /// <summary>
 /// Returns true if fromArg of type fromType can be assigned to toParameter with a conversion on given narrowing level.
 /// </summary>
 public override bool CanConvertFrom(Type/*!*/ fromType, DynamicMetaObject fromArg, ParameterWrapper/*!*/ toParameter, NarrowingLevel level) {
     return Converter.CanConvertFrom(fromArg, fromType, toParameter.Type, toParameter.ProhibitNull, level, 
         HasExplicitProtocolConversion(toParameter), _implicitProtocolConversions
     );
 }
Example #53
0
        public virtual bool CanConvertFrom(Type fromType, DynamicMetaObject fromArgument, ParameterWrapper toParameter, NarrowingLevel level) {
            Assert.NotNull(fromType, toParameter);

            Type toType = toParameter.Type;

            if (fromType == typeof(DynamicNull)) {
                if (toParameter.ProhibitNull) {
                    return false;
                }

                if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                    return true;
                }

                if (!toType.IsValueType) {
                    return true;
                }
            }

            if (fromType == toType) {
                return true;
            }

            return _binder.CanConvertFrom(fromType, toType, toParameter.ProhibitNull, level);
        }
Example #54
0
        public override Candidate SelectBestConversionFor(DynamicMetaObject/*!*/ arg, ParameterWrapper/*!*/ candidateOne, 
            ParameterWrapper/*!*/ candidateTwo, NarrowingLevel level) {

            Type typeOne = candidateOne.Type;
            Type typeTwo = candidateTwo.Type;
            Type actualType = arg.GetLimitType();

            if (actualType == typeof(DynamicNull)) {
                // if nil is passed as a block argument prefers BlockParam over a missing block:
                if (typeOne == typeof(BlockParam) && typeTwo == typeof(MissingBlockParam)) {
                    Debug.Assert(!candidateOne.ProhibitNull);
                    return Candidate.One;
                }

                if (typeOne == typeof(MissingBlockParam) && typeTwo == typeof(BlockParam)) {
                    Debug.Assert(!candidateTwo.ProhibitNull);
                    return Candidate.Two;
                }
            } else {
                if (typeOne == actualType) {
                    if (typeTwo == actualType) {
                        // prefer non-nullable reference type over nullable:
                        if (!actualType.IsValueType) {
                            if (candidateOne.ProhibitNull) {
                                return Candidate.One;
                            } else if (candidateTwo.ProhibitNull) {
                                return Candidate.Two;
                            }
                        }
                    } else {
                        return Candidate.One;
                    }
                } else if (typeTwo == actualType) {
                    return Candidate.Two;
                }
            }

            // prefer integer type over enum:
            if (typeOne.IsEnum && Enum.GetUnderlyingType(typeOne) == typeTwo) {
                return Candidate.Two;
            }

            if (typeTwo.IsEnum && Enum.GetUnderlyingType(typeTwo) == typeOne) {
                return Candidate.One;
            }

            return base.SelectBestConversionFor(arg, candidateOne, candidateTwo, level);
        }
Example #55
0
        public override bool CanConvertFrom(Type fromType, DynamicMetaObject fromArg, ParameterWrapper toParameter, NarrowingLevel level)
        {
            if ((fromType == typeof(List) || fromType.IsSubclassOf(typeof(List))))
            {
                if (toParameter.Type.IsGenericType() &&
                    toParameter.Type.GetGenericTypeDefinition() == typeof(IList <>) &&
                    (toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false) ||
                     toParameter.ParameterInfo.IsDefined(typeof(BytesConversionNoStringAttribute), false)))
                {
                    return(false);
                }
            }
            else if (fromType == typeof(string))
            {
                if (toParameter.Type == typeof(IList <byte>) &&
                    !Binder.Context.PythonOptions.Python30 &&
                    toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false))
                {
                    // string -> byte array, we allow this in Python 2.6
                    return(true);
                }
            }
            else if (fromType == typeof(Bytes))
            {
                if (toParameter.Type == typeof(string) &&
                    !Binder.Context.PythonOptions.Python30 &&
                    toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false))
                {
                    return(true);
                }
            }

            return(base.CanConvertFrom(fromType, fromArg, toParameter, level));
        }
Example #56
0
 /// <summary>
 /// Selects the best (of two) candidates for conversion from actualType
 /// </summary>
 public virtual Candidate SelectBestConversionFor(DynamicMetaObject arg, ParameterWrapper candidateOne, ParameterWrapper candidateTwo, NarrowingLevel level) {
     return Candidate.Equivalent;
 }
Example #57
0
 public bool HasConversionFrom(Type fromType, NarrowingLevel level) {
     return _binder.CanConvertFrom(fromType, this, level);
 }
 public override bool CanConvertFrom(Type fromType, Type toType, bool toNotNullable, NarrowingLevel level) {
     // TODO: None -> nullable reference types?
     return toType.IsAssignableFrom(fromType);
 }
Example #59
0
 /// <summary>
 /// Determines if a conversion exists from fromType to toType at the specified narrowing level.
 /// toNotNullable is true if the target variable doesn't allow null values.
 /// </summary>
 public abstract bool CanConvertFrom(Type fromType, Type toType, bool toNotNullable, NarrowingLevel level);
Example #60
0
        internal static Convertibility CanConvertFrom(DynamicMetaObject fromArg, Type/*!*/ fromType, Type/*!*/ toType, bool toNotNullable,
            NarrowingLevel level, bool explicitProtocolConversions, bool implicitProtocolConversions)
        {
            ContractUtils.RequiresNotNull(fromType, "fromType");
            ContractUtils.RequiresNotNull(toType, "toType");

            var metaConvertible = fromArg as IConvertibleMetaObject;
            var rubyMetaConvertible = fromArg as IConvertibleRubyMetaObject;

            //
            // narrowing level 0:
            //

            if (toType == fromType) {
                return Convertibility.AlwaysConvertible;
            }

            if (fromType == typeof(DynamicNull)) {
                if (toNotNullable) {
                    return Convertibility.NotConvertible;
                }

                if (toType.IsGenericType() && toType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                    return Convertibility.AlwaysConvertible;
                }

                if (!toType.IsValueType()) {
                    // null convertible to any reference type:
                    return Convertibility.AlwaysConvertible;
                } else if (toType == typeof(bool)) {
                    return Convertibility.AlwaysConvertible;
                } else if (!ProtocolConversionAction.HasDefaultConversion(toType)) {
                    // null not convertible to a value type unless a protocol conversion is allowed:
                    return Convertibility.NotConvertible;
                }
            }

            // blocks:
            if (fromType == typeof(MissingBlockParam)) {
                return new Convertibility(toType == typeof(BlockParam) && !toNotNullable, null);
            }

            if (fromType == typeof(BlockParam) && toType == typeof(MissingBlockParam)) {
                return Convertibility.AlwaysConvertible;
            }

            if (toType.IsAssignableFrom(fromType)) {
                return Convertibility.AlwaysConvertible;
            }

            if (HasImplicitNumericConversion(fromType, toType)) {
                return Convertibility.AlwaysConvertible;
            }

            if (CompilerHelpers.GetImplicitConverter(fromType, toType) != null) {
                return Convertibility.AlwaysConvertible;
            }

            if (rubyMetaConvertible != null) {
                return rubyMetaConvertible.IsConvertibleTo(toType, false);
            } else if (metaConvertible != null) {
                return new Convertibility(metaConvertible.CanConvertTo(toType, false), null);
            }

            //
            // narrowing level 1:
            //

            if (level < NarrowingLevel.One) {
                return Convertibility.NotConvertible;
            }

            if (explicitProtocolConversions && ProtocolConversionAction.HasDefaultConversion(toType)) {
                return Convertibility.AlwaysConvertible;
            }

            //
            // narrowing level 2:
            //

            if (level < NarrowingLevel.Two) {
                return Convertibility.NotConvertible;
            }

            if (HasExplicitNumericConversion(fromType, toType)) {
                return Convertibility.AlwaysConvertible;
            }

            if (CompilerHelpers.GetExplicitConverter(fromType, toType) != null) {
                return Convertibility.AlwaysConvertible;
            }

            if (CompilerHelpers.HasTypeConverter(fromType, toType)) {
                return Convertibility.AlwaysConvertible;
            }

            if (fromType == typeof(char) && toType == typeof(string)) {
                return Convertibility.AlwaysConvertible;
            }

            if (toType == typeof(bool)) {
                return Convertibility.AlwaysConvertible;
            }

            if (rubyMetaConvertible != null) {
                return rubyMetaConvertible.IsConvertibleTo(toType, true);
            } else if (metaConvertible != null) {
                return new Convertibility(metaConvertible.CanConvertTo(toType, true), null);
            }

            //
            // narrowing level 3:
            //

            if (level < NarrowingLevel.Three) {
                return Convertibility.NotConvertible;
            }

            if (implicitProtocolConversions && ProtocolConversionAction.HasDefaultConversion(toType)) {
                return Convertibility.AlwaysConvertible;
            }

            // A COM object can potentially be converted to the given interface, but might also be not so use this only as the last resort:
            if (TypeUtils.IsComObjectType(fromType) && toType.IsInterface()) {
                return Convertibility.AlwaysConvertible;
            }

            return Convertibility.NotConvertible;
        }