Exemple #1
0
        public static bool InEnumerable(object arg, IEnumerable set)
        {
            Require.NotNull(set, "set");

            var dictionary = set as IDictionary;

            if (dictionary != null)
            {
                return(dictionary.Contains(arg));
            }

            Type argType = null;

            if (arg != null)
            {
                argType = arg.GetType();
            }

            foreach (var item in set)
            {
                if (arg == null)
                {
                    if (item == null)
                    {
                        return(true);
                    }
                }
                else if (item != null)
                {
                    var targetType = item.GetType();

                    if (argType != targetType)
                    {
                        if (TypeUtil.CanCastImplicitely(argType, targetType, false))
                        {
                            if (Equals(TypeUtil.CastImplicitely(arg, targetType), item))
                            {
                                return(true);
                            }
                        }
                        else if (TypeUtil.CanCastImplicitely(targetType, argType, false))
                        {
                            if (Equals(arg, TypeUtil.CastImplicitely(item, argType)))
                            {
                                return(true);
                            }
                        }
                    }
                    else
                    {
                        if (Equals(arg, item))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Exemple #2
0
        private void TestArgumentType(Type parameterType, Type argumentType, bool argumentNull, ref bool match, ref bool implicitMatch)
        {
            if (
                !parameterType.IsValueType &&
                argumentNull
                )
            {
                return;
            }

            if (parameterType != argumentType)
            {
                match = false;
            }

            if (!TypeUtil.CanCastImplicitely(
                    argumentType,
                    parameterType,
                    argumentNull
                    ))
            {
                implicitMatch = false;
            }
        }
Exemple #3
0
        public override IExpression Cast(Cast cast)
        {
            if (cast.CastType == CastType.Convert)
            {
                var constant = cast.Operand as Constant;

                if (TypeUtil.CanCastImplicitely(
                        cast.Operand.Type,
                        cast.Type,
                        constant != null && constant.Value == null
                        ))
                {
                    return(new Cast(cast.Operand, cast.Type));
                }

                string methodName = null;

                switch (Type.GetTypeCode(cast.Type))
                {
                case TypeCode.Boolean: methodName = "ToBoolean"; break;

                case TypeCode.Byte: methodName = "ToByte"; break;

                case TypeCode.Char: methodName = "ToChar"; break;

                case TypeCode.DateTime: methodName = "ToDate"; break;

                case TypeCode.Decimal: methodName = "ToDecimal"; break;

                case TypeCode.Double: methodName = "ToDouble"; break;

                case TypeCode.Int32: methodName = "ToInteger"; break;

                case TypeCode.Int64: methodName = "ToLong"; break;

                case TypeCode.SByte: methodName = "ToSByte"; break;

                case TypeCode.Int16: methodName = "ToShort"; break;

                case TypeCode.Single: methodName = "ToSingle"; break;

                case TypeCode.String: methodName = "ToString"; break;

                case TypeCode.UInt32: methodName = "ToUInteger"; break;

                case TypeCode.UInt64: methodName = "ToULong"; break;

                case TypeCode.UInt16: methodName = "ToUShort"; break;
                }

                if (methodName != null)
                {
                    var method = _resolver.FindOperatorMethod(
                        methodName,
                        Array.Empty <Type>(),
                        null,
                        new[] { cast.Operand.Type }
                        );

                    Debug.Assert(method != null && method.ReturnType == cast.Type);

                    return(new MethodCall(
                               new TypeAccess(method.DeclaringType),
                               method,
                               new[]
                    {
                        cast.Operand
                    }
                               ));
                }
                else
                {
                    return(new Cast(cast.Operand, cast.Type));
                }
            }

            return(base.Cast(cast));
        }
Exemple #4
0
            public void MethodCall(MethodCall methodCall)
            {
                bool isStatic = methodCall.Operand is TypeAccess;

                if (!isStatic)
                {
                    bool emitBox       = false;
                    bool emitStoreLoad = false;

                    if (
                        (methodCall.Operand is FieldAccess || methodCall.Operand is Constant) &&
                        methodCall.Operand.Type.IsValueType &&
                        !methodCall.MethodInfo.DeclaringType.IsValueType
                        )
                    {
                        emitBox = true;
                    }
                    else if (
                        methodCall.Operand.Type.IsValueType && (
                            !(methodCall.Operand is FieldAccess) ||
                            methodCall.MethodInfo.DeclaringType.IsValueType
                            )
                        )
                    {
                        emitStoreLoad = true;
                    }

                    // Signal field access that we're using the field as a
                    // parameter.

                    _fieldAsParameter =
                        methodCall.Operand is FieldAccess &&
                        methodCall.MethodInfo.DeclaringType.IsValueType &&
                        !emitStoreLoad;

                    try
                    {
                        methodCall.Operand.Accept(this);
                    }
                    finally
                    {
                        _fieldAsParameter = false;
                    }

                    if (emitBox)
                    {
                        _il.Emit(OpCodes.Box, methodCall.Operand.Type);
                    }
                    else if (emitStoreLoad)
                    {
                        Debug.Assert(methodCall.Operand.Type == methodCall.MethodInfo.DeclaringType);

                        var builder = _il.DeclareLocal(methodCall.Operand.Type);

                        _il.Emit(OpCodes.Stloc, builder);
                        _il.Emit(OpCodes.Ldloca, builder);
                    }
                }

                var parameters = methodCall.MethodInfo.GetParameters();
                var arguments  = methodCall.Arguments;

                bool paramsMethod =
                    parameters.Length > 0 &&
                    parameters[parameters.Length - 1].GetCustomAttributes(typeof(ParamArrayAttribute), true).Length == 1;

                int mandatoryParameterCount =
                    paramsMethod
                    ? parameters.Length - 1
                    : parameters.Length;

                for (int i = 0; i < mandatoryParameterCount; i++)
                {
                    Emit(arguments[i], parameters[i].ParameterType);
                }

                if (paramsMethod)
                {
                    var  paramsType  = parameters[parameters.Length - 1].ParameterType;
                    var  elementType = paramsType.GetElementType();
                    bool emitted     = false;

                    // When the params argument is missing, a new array is issued.

                    if (arguments.Count == mandatoryParameterCount)
                    {
                        ILUtil.EmitEmptyArray(_il, elementType);
                        emitted = true;
                    }
                    else if (arguments.Count == mandatoryParameterCount + 1)
                    {
                        var lastArgument = arguments[arguments.Count - 1];

                        // Null arguments are passed blindly.
                        if (lastArgument is Constant constant && constant.Value == null)
                        {
                            ILUtil.EmitNull(_il);
                            emitted = true;
                        }
                        else
                        {
                            // So are array arguments that can be casted.

                            if (
                                lastArgument.Type.IsArray &&
                                TypeUtil.CanCastImplicitely(lastArgument.Type, paramsType, false)
                                )
                            {
                                Emit(lastArgument, paramsType);
                                emitted = true;
                            }
                        }
                    }

                    // If we didn't find a shortcut, emit the array with all
                    // arguments.

                    if (!emitted)
                    {
                        ILUtil.EmitArray(
                            _il,
                            elementType,
                            arguments.Count - mandatoryParameterCount,
                            p => Emit(arguments[mandatoryParameterCount + p], elementType)
                            );
                    }
                }
Exemple #5
0
        internal MethodInfo FindOperatorMethod(string methodName, Type[] sourceTypes, Type returnType, Type[] parameterTypes, bool[] parametersNull)
        {
            var candidates = new List <MethodInfo>();

            foreach (var sourceType in sourceTypes)
            {
                foreach (var method in sourceType.GetMethods(BindingFlags.Static | BindingFlags.Public))
                {
                    if (method.Name != methodName)
                    {
                        continue;
                    }

                    var parameters = method.GetParameters();

                    if (parameters.Length != parameterTypes.Length)
                    {
                        continue;
                    }

                    bool match         = true;
                    bool implicitMatch = true;

                    if (returnType != null)
                    {
                        match         = returnType == method.ReturnType;
                        implicitMatch = TypeUtil.CanCastImplicitely(
                            method.ReturnType, returnType, false
                            );
                    }

                    for (int i = 0; i < parameterTypes.Length; i++)
                    {
                        if (parameters[i].ParameterType != parameterTypes[i])
                        {
                            match = false;
                        }

                        if (!TypeUtil.CanCastImplicitely(
                                parameterTypes[i],
                                parameters[i].ParameterType,
                                parametersNull != null && parametersNull[i]
                                ))
                        {
                            implicitMatch = false;
                        }
                    }

                    if (match)
                    {
                        return(method);
                    }
                    if (implicitMatch)
                    {
                        candidates.Add(method);
                    }
                }
            }

            return(candidates.Count == 1 ? candidates[0] : null);
        }