GetType() protected static method

protected static GetType ( Operand op, ITypeMapper typeMapper ) : Type
op Operand
typeMapper ITypeMapper
return IKVM.Reflection.Type
Exemplo n.º 1
0
 internal override void AssignmentHint(Operand op)
 {
     if (tHint == null)
     {
         tHint = Operand.GetType(op);
     }
 }
Exemplo n.º 2
0
        static IMemberInfo[] BitEnumSpecific(Operand[] args, ITypeMapper typeMapper)
        {
            Type t1 = Operand.GetType(args[0], typeMapper), t2 = Operand.GetType(args[1], typeMapper);

            if (t1 != t2 || t1 == null || !t1.IsEnum)                   // if both types are not the same enum, no operator can be valid
            {
                return(_stdNone);
            }

            return(new IMemberInfo[] { new StdOp(t1, t1, t1) });
        }
Exemplo n.º 3
0
        static IMemberInfo[] IncEnumSpecific(Operand[] args, ITypeMapper typeMapper)
        {
            Type t = Operand.GetType(args[0], typeMapper);

            if (t == null || !t.IsEnum)
            {
                return(_stdNone);
            }

            return(new IMemberInfo[] { new IncOp(t) });
        }
Exemplo n.º 4
0
        static IMemberInfo[] SubDelegateSpecific(Operand[] args, ITypeMapper typeMapper)
        {
            Type t1 = Operand.GetType(args[0], typeMapper), t2 = Operand.GetType(args[1], typeMapper);

            if (t1 != t2 || t1 == null || !t1.IsSubclassOf(typeMapper.MapType(typeof(Delegate))))               // if the types are not the same, no operator can be valid
            {
                return(_stdNone);
            }

            return(new IMemberInfo[] { new DelegateRemoveOp(t1) });
        }
        static IMemberInfo[] AddDelegateSpecific(Operand[] args)
        {
            Type t1 = Operand.GetType(args[0]), t2 = Operand.GetType(args[1]);

            if (t1 != t2 || t1 == null || !t1.IsSubclassOf(typeof(Delegate)))                   // if the types are not the same, no operator can be valid
            {
                return(stdNone);
            }

            return(new IMemberInfo[] { new DelegateCombineOp(t1) });
        }
        static IMemberInfo[] UnaryEnumSpecific(Operand[] args)
        {
            Type t = Operand.GetType(args[0]);

            if (t == null || !t.IsEnum)
            {
                return(stdNone);
            }

            return(new IMemberInfo[] { new StdOp(t, t) });
        }
Exemplo n.º 7
0
        static IMemberInfo[] SubEnumSpecific(Operand[] args, ITypeMapper typeMapper)
        {
            Type t1 = Operand.GetType(args[0], typeMapper), t2 = Operand.GetType(args[1], typeMapper);

            if (t1 == null || t2 == null || !t1.IsEnum || (t2.IsEnum && t2 != t1))              // if the types are not the same, no operator can be valid
            {
                return(_stdNone);
            }

            Type e = t1;
            Type u = Helpers.GetEnumEnderlyingType(e);

            return(new IMemberInfo[] { new StdOp(u, e, e), new StdOp(e, e, u) });
        }
        static IMemberInfo[] AddEnumSpecific(Operand[] args)
        {
            Type t1 = Operand.GetType(args[0]), t2 = Operand.GetType(args[1]);

            if (t1 == null || t2 == null || t1.IsEnum == t2.IsEnum)             // if none or both types are enum, no operator can be valid
            {
                return(stdNone);
            }

            Type e = t1.IsEnum ? t1 : t2;
            Type u = Enum.GetUnderlyingType(e);

            return(new IMemberInfo[] { new StdOp(e, e, u), new StdOp(e, u, e) });
        }
Exemplo n.º 9
0
        internal List <ApplicableFunction> FindUserCandidates(ITypeMapper typeMapper, params Operand[] args)
        {
            List <Type> usedTypes = new List <Type>();
            List <ApplicableFunction> candidates = null;
            string name = "op_" + MethodName;
            bool   expandedCandidates = false;

            foreach (Operand arg in args)
            {
                for (Type t = Operand.GetType(arg, typeMapper); t != null && t != typeMapper.MapType(typeof(object)) && (t.IsClass || t.IsValueType) && !usedTypes.Contains(t); t = t.IsValueType ? null : t.BaseType)
                {
                    usedTypes.Add(t);

                    OverloadResolver.FindApplicable(ref candidates, ref expandedCandidates, typeMapper.TypeInfo.Filter(typeMapper.TypeInfo.GetMethods(t), name, true, true, false), typeMapper, args);
                }
            }

            if (expandedCandidates)
            {
                OverloadResolver.RemoveExpanded(candidates);
            }

            return(candidates);
        }
Exemplo n.º 10
0
        public static Conversion GetExplicit(Operand op, Type to, bool onlyStandard, ITypeMapper typeMapper)
        {
            // try implicit
            Conversion conv = GetImplicit(op, to, onlyStandard, typeMapper);

            if (conv.IsValid)
            {
                return(conv);
            }

            Type from = Operand.GetType(op, typeMapper);

            Type fromUnderlying = Helpers.GetNullableUnderlyingType(@from);

            if (fromUnderlying == to)
            {
                return(new UnwrapNullable(typeMapper));
            }


            Type toUnderlying = Helpers.GetNullableUnderlyingType(to);

            if (toUnderlying != null && fromUnderlying != null)
            {
                var c = GetExplicit(new FakeTypedOperand(fromUnderlying), toUnderlying, onlyStandard, typeMapper);
                if (c.IsValid)
                {
                    return(new ConvertNullable(typeMapper, c));
                }
            }


            // section 6.3.2 - Standard explicit conversions
            if (onlyStandard)
            {
                if (from == null || !GetImplicit(to, @from, true, typeMapper).IsValid)
                {
                    return(new Invalid(typeMapper));
                }
            }

            TypeCode tcFrom = Type.GetTypeCode(from);
            TypeCode tcTo   = Type.GetTypeCode(to);
            byte     ct     = _convTable[(int)tcFrom][(int)tcTo];

            // section 6.2.1 - Explicit numeric conversions, 6.2.2 - Explicit enumeration conversions
            if ((from.IsPrimitive || from.IsEnum || Helpers.AreTypesEqual(from, typeof(decimal), typeMapper)) && (to.IsPrimitive || to.IsEnum || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper)))
            {
                if (ct == D)
                {
                    return(new Direct(typeMapper));                     // this can happen for conversions involving enum-s
                }
                if (ct <= E)
                {
                    if (Helpers.AreTypesEqual(from, typeof(decimal), typeMapper) || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper))
                    {
                        // decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
                        onlyStandard = false;
                    }
                    else
                    {
                        return(new Primitive(typeMapper));
                    }
                }
            }

            // section 6.2.5 - User-defined explicit conversions (details in section 6.4.4)
            if (!(onlyStandard || Helpers.AreTypesEqual(from, typeof(object), typeMapper) || Helpers.AreTypesEqual(to, typeof(object), typeMapper) || from.IsInterface || to.IsInterface ||
                  to.IsSubclassOf(from) || from.IsSubclassOf(to)))
            {
                List <UserDefined> candidates = null;
                FindCandidates(ref candidates, FindExplicitMethods(from, to, typeMapper), op, to, GetExplicit, typeMapper);

                if (candidates != null)
                {
                    if (candidates.Count == 1)
                    {
                        return(candidates[0]);
                    }

                    return(UserDefined.FindExplicit(candidates, @from, to, typeMapper));
                }
            }

            // section 6.2.3 - Explicit reference conversions, 6.2.4 - Unboxing conversions
            // TODO: not really according to spec, but mostly works
            if (!from.IsValueType && from.IsAssignableFrom(to))
            {
                if (to.IsValueType)
                {
                    return(new Unboxing(typeMapper));
                }
                else
                {
                    return(new Cast(typeMapper));
                }
            }

            return(new Invalid(typeMapper));
        }
Exemplo n.º 11
0
        // the sections mentioned in comments of this method are from C# specification v1.2
        public static Conversion GetImplicit(Operand op, Type to, bool onlyStandard, ITypeMapper typeMapper)
        {
            Type from = Operand.GetType(op, typeMapper);

            Type toUnderlying = Helpers.GetNullableUnderlyingType(to);

            if (to.Equals(from))
            {
                return(new Direct(typeMapper));
            }

            Type fromUnderlying = Helpers.GetNullableUnderlyingType(@from);

            if (toUnderlying != null)
            {
                if (fromUnderlying != null)
                {
                    Conversion c = GetImplicit(new FakeTypedOperand(fromUnderlying), toUnderlying, onlyStandard, typeMapper);
                    if (c.IsValid)
                    {
                        return(new ConvertNullable(typeMapper, c));
                    }
                }
                else
                {
                    Conversion c = GetImplicit(op, toUnderlying, onlyStandard, typeMapper);
                    if (c.IsValid)
                    {
                        return(new WrapNullable(typeMapper, c));
                    }
                }
            }

            // required for arrays created from TypeBuilder-s
            if (from != null && to.IsArray && from.IsArray)
            {
                if (to.GetArrayRank() == from.GetArrayRank())
                {
                    if (to.GetElementType().Equals(from.GetElementType()))
                    {
                        return(new Direct(typeMapper));
                    }
                }
            }

            TypeCode tcFrom = Type.GetTypeCode(from);
            TypeCode tcTo   = Type.GetTypeCode(to);
            byte     ct     = _convTable[(int)tcFrom][(int)tcTo];

            // section 6.1.2 - Implicit numeric conversions
            if (from != null && (from.IsPrimitive || Helpers.AreTypesEqual(from, typeof(decimal), typeMapper)) && (to.IsPrimitive || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper)))
            {
                if (ct <= I)
                {
                    if (Helpers.AreTypesEqual(from, typeof(decimal), typeMapper) || Helpers.AreTypesEqual(to, typeof(decimal), typeMapper))
                    {
                        // decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
                        onlyStandard = false;
                    }
                    else
                    {
                        return(new Primitive(typeMapper));
                    }
                }
            }

            IntLiteral intLit = op as IntLiteral;

            // section 6.1.3 - Implicit enumeration conversions
            if (!onlyStandard && to.IsEnum && (object)intLit != null && intLit.Value == 0)
            {
                return(new Primitive(typeMapper));
            }

            // section 6.1.4 - Implicit reference conversions
            if ((from == null || !from.IsValueType) && !to.IsValueType)
            {
                if (from == null)                 // from the null type to any reference type
                {
                    return(new Direct(typeMapper));
                }

                if (to.IsAssignableFrom(from))                  // the rest
                {
                    return(new Direct(typeMapper));
                }
            }

            if (from == null)                   // no other conversion from null type is possible
            {
                return(new Invalid(typeMapper));
            }

            // section 6.1.5 - Boxing conversions
            if (from.IsValueType)
            {
                if (to.IsAssignableFrom(from))
                {
                    return(new Boxing(typeMapper));
                }
            }

            // section 6.1.6 - Implicit constant expression conversions
            if ((object)intLit != null && Helpers.AreTypesEqual(from, typeof(int), typeMapper) && to.IsPrimitive)
            {
                int val = intLit.Value;

                switch (tcTo)
                {
                case TypeCode.SByte:
                    if (val >= sbyte.MinValue && val <= sbyte.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.Byte:
                    if (val >= byte.MinValue && val <= byte.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.Int16:
                    if (val >= short.MinValue && val <= short.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.UInt16:
                    if (val >= ushort.MinValue && val <= ushort.MaxValue)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.UInt32:
                    if (val >= 0)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;

                case TypeCode.UInt64:
                    if (val >= 0)
                    {
                        return(new Direct(typeMapper));
                    }
                    break;
                }
            }

            // section 6.1.7 - User-defined implicit conversions (details in section 6.4.3)
            if (onlyStandard || Helpers.AreTypesEqual(from, typeof(object), typeMapper) || Helpers.AreTypesEqual(to, typeof(object), typeMapper) || from.IsInterface || to.IsInterface ||
                to.IsSubclassOf(from) || from.IsSubclassOf(to))
            {
                return(new Invalid(typeMapper));  // skip not-permitted conversion attempts (section 6.4.1)
            }
            List <UserDefined> candidates = null;

            FindCandidates(ref candidates, FindImplicitMethods(from, to, typeMapper), op, to, GetImplicit, typeMapper);

            if (candidates == null)
            {
                return(new Invalid(typeMapper));
            }

            if (candidates.Count == 1)
            {
                return(candidates[0]);
            }

            return(UserDefined.FindImplicit(candidates, @from, to, typeMapper));
        }
Exemplo n.º 12
0
        public static Conversion GetExplicit(Operand op, Type to, bool onlyStandard)
        {
            // try implicit
            Conversion conv = GetImplicit(op, to, onlyStandard);

            if (conv.IsValid)
            {
                return(conv);
            }

            Type from = Operand.GetType(op);

            // section 6.3.2 - Standard explicit conversions
            if (onlyStandard)
            {
                if (from == null || !GetImplicit(to, from, true).IsValid)
                {
                    return(Invalid.Instance);
                }
            }

            TypeCode tcFrom = Type.GetTypeCode(from);
            TypeCode tcTo   = Type.GetTypeCode(to);
            byte     ct     = convTable[(int)tcFrom][(int)tcTo];

            // section 6.2.1 - Explicit numeric conversions, 6.2.2 - Explicit enumeration conversions
            if ((from.IsPrimitive || from.IsEnum || from == typeof(decimal)) && (to.IsPrimitive || to.IsEnum || to == typeof(decimal)))
            {
                if (ct == D)
                {
                    return(Direct.Instance);                    // this can happen for conversions involving enum-s
                }
                if (ct <= E)
                {
                    if (from == typeof(decimal) || to == typeof(decimal))
                    {
                        // decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
                        onlyStandard = false;
                    }
                    else
                    {
                        return(Primitive.Instance);
                    }
                }
            }

            // section 6.2.5 - User-defined explicit conversions (details in section 6.4.4)
            if (!(onlyStandard || from == typeof(object) || to == typeof(object) || from.IsInterface || to.IsInterface ||
                  to.IsSubclassOf(from) || from.IsSubclassOf(to)))
            {
                List <UserDefined> candidates = null;
                FindCandidates(ref candidates, FindExplicitMethods(from, to), op, to, GetExplicit);

                if (candidates != null)
                {
                    if (candidates.Count == 1)
                    {
                        return(candidates[0]);
                    }

                    return(UserDefined.FindExplicit(candidates, from, to));
                }
            }

            // section 6.2.3 - Explicit reference conversions, 6.2.4 - Unboxing conversions
            // TODO: not really according to spec, but mostly works
            if (!from.IsValueType && from.IsAssignableFrom(to))
            {
                if (to.IsValueType)
                {
                    return(Unboxing.Instance);
                }
                else
                {
                    return(Cast.Instance);
                }
            }

            return(Invalid.Instance);
        }
Exemplo n.º 13
0
        // the sections mentioned in comments of this method are from C# specification v1.2
        public static Conversion GetImplicit(Operand op, Type to, bool onlyStandard)
        {
            try {
                Type from = Operand.GetType(op);

                if (to.Equals(from) || to.FullName == from.FullName || to.IsGenericParameter)
                {
                    return(Direct.Instance);
                }

                // required for arrays created from TypeBuilder-s
                if (from != null && to.IsArray && from.IsArray)
                {
                    if (to.GetArrayRank() == from.GetArrayRank())
                    {
                        if (to.GetElementType().Equals(from.GetElementType()))
                        {
                            return(Direct.Instance);
                        }
                    }
                }

                TypeCode tcFrom = Type.GetTypeCode(from);
                TypeCode tcTo   = Type.GetTypeCode(to);
                byte     ct     = convTable[(int)tcFrom][(int)tcTo];

                // section 6.1.2 - Implicit numeric conversions
                if ((from != null && (from.IsPrimitive || from == typeof(decimal))) && (to.IsPrimitive || to == typeof(decimal)))
                {
                    if (ct <= I)
                    {
                        if (from == typeof(decimal) || to == typeof(decimal))
                        {
                            // decimal is handled as user-defined conversion, but as it is a standard one, always enable UDC processing
                            onlyStandard = false;
                        }
                        else
                        {
                            return(Primitive.Instance);
                        }
                    }
                }

                IntLiteral intLit = op as IntLiteral;

                // section 6.1.3 - Implicit enumeration conversions
                if (!onlyStandard && !to.IsGenericType && to.IsEnum && (object)intLit != null && intLit.Value == 0)
                {
                    return(Primitive.Instance);
                }

                // section 6.1.4 - Implicit reference conversions
                if ((from == null || !from.IsValueType) && !to.IsValueType)
                {
                    if (from == null) // from the null type to any reference type
                    {
                        return(Direct.Instance);
                    }

                    if (to.IsAssignableFrom(from) || to.IsDerivedFrom(from))    // the rest
                    {
                        return(Direct.Instance);
                    }

                    if (from.Name.StartsWith("_Frame"))
                    {
                        return(Direct.Instance);
                    }

                    if (to == typeof(Operand))
                    {
                        return(UserDefined.Cast.Instance);
                    }
                }

                if (from == null)       // no other conversion from null type is possible
                {
                    return(Invalid.Instance);
                }

                // section 6.1.5 - Boxing conversions
                if (from.IsValueType)
                {
                    if (to.IsAssignableFrom(from))
                    {
                        return(Boxing.Instance);
                    }
                }

                // section 6.1.6 - Implicit constant expression conversions
                if ((object)intLit != null && from == typeof(int) && to.IsPrimitive)
                {
                    int val = intLit.Value;

                    switch (tcTo)
                    {
                    case TypeCode.SByte:
                        if (val >= sbyte.MinValue && val <= sbyte.MaxValue)
                        {
                            return(Direct.Instance);
                        }
                        break;

                    case TypeCode.Byte:
                        if (val >= byte.MinValue && val <= byte.MaxValue)
                        {
                            return(Direct.Instance);
                        }
                        break;

                    case TypeCode.Int16:
                        if (val >= short.MinValue && val <= short.MaxValue)
                        {
                            return(Direct.Instance);
                        }
                        break;

                    case TypeCode.UInt16:
                        if (val >= ushort.MinValue && val <= ushort.MaxValue)
                        {
                            return(Direct.Instance);
                        }
                        break;

                    case TypeCode.UInt32:
                        if (val >= 0)
                        {
                            return(Direct.Instance);
                        }
                        break;

                    case TypeCode.UInt64:
                        if (val >= 0)
                        {
                            return(Primitive.Instance);
                        }
                        break;
                    }
                }
                if (from == typeof(long))
                {
                    LongLiteral longLit = op as LongLiteral;
                    if ((object)longLit != null && longLit.Value > 0)
                    {
                        return(Direct.Instance);
                    }
                }

                // section 6.1.7 - User-defined implicit conversions (details in section 6.4.3)
                if (onlyStandard || from == typeof(object) || to == typeof(object) || from.IsInterface || to.IsInterface ||
                    to.IsSubclassOf(from) || from.IsSubclassOf(to))
                {
                    return(Invalid.Instance);    // skip not-permitted conversion attempts (section 6.4.1)
                }
                List <UserDefined> candidates = null;
                FindCandidates(ref candidates, FindImplicitMethods(from, to), op, to, GetImplicit);

                if (candidates == null)
                {
                    return(Invalid.Instance);
                }

                if (candidates.Count == 1)
                {
                    return(candidates[0]);
                }

                return(UserDefined.FindImplicit(candidates, from, to));
            } catch (NotSupportedException e) {
                return(Direct.Instance); // fallback to success :)
            }
        }