string GetTypeKind(Type t) { if (t.IsEnum) { return("enum"); } if (t.IsClass) { if (t.IsSubclassOf(type_multicast_delegate)) { return("delegate"); } else { return("class"); } } if (t.IsInterface) { return("interface"); } if (t.IsValueType) { return("struct"); } return("class"); }
internal static bool IsSubclassOf(Type type, Type baseClass) { #if WINRT || COREFX || PROFILE259 return(type.GetTypeInfo().IsSubclassOf(baseClass)); #else return(type.IsSubclassOf(baseClass)); #endif }
internal static bool IsSubclassOf(Type type, Type baseClass) { #if WINRT return(type.GetTypeInfo().IsSubclassOf(baseClass)); #else return(type.IsSubclassOf(baseClass)); #endif }
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) }); }
public void OutlineType() { bool first; OutlineAttributes(); o.Write(GetTypeVisibility(t)); if (t.IsClass && !t.IsSubclassOf(type_multicast_delegate)) { if (t.IsSealed) { o.Write(t.IsAbstract ? " static" : " sealed"); } else if (t.IsAbstract) { o.Write(" abstract"); } } o.Write(" "); o.Write(GetTypeKind(t)); o.Write(" "); Type [] interfaces = (Type [])Comparer.Sort(TypeGetInterfaces(t, declared_only)); Type parent = t.BaseType; if (t.IsSubclassOf(type_multicast_delegate)) { MethodInfo method; method = t.GetMethod("Invoke"); o.Write(FormatType(method.ReturnType)); o.Write(" "); o.Write(GetTypeName(t)); o.Write(" ("); OutlineParams(method.GetParameters()); o.Write(")"); WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(";"); return; } o.Write(GetTypeName(t)); if (((parent != null && parent != type_object && parent != type_value_type) || interfaces.Length != 0) && !t.IsEnum) { first = true; o.Write(" : "); if (parent != null && parent != type_object && parent != type_value_type) { o.Write(FormatType(parent)); first = false; } foreach (Type intf in interfaces) { if (!first) { o.Write(", "); } first = false; o.Write(FormatType(intf)); } } if (t.IsEnum) { Type underlyingType = t.GetEnumUnderlyingType(); if (underlyingType != type_int) { o.Write(" : {0}", FormatType(underlyingType)); } } WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(" {"); o.Indent++; if (t.IsEnum) { bool is_first = true; foreach (FieldInfo fi in t.GetFields(BindingFlags.Public | BindingFlags.Static)) { if (!is_first) { o.WriteLine(","); } is_first = false; o.Write(fi.Name); } o.WriteLine(); o.Indent--; o.WriteLine("}"); return; } first = true; foreach (ConstructorInfo ci in t.GetConstructors(DefaultFlags)) { if (!ShowMember(ci)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ci); OutlineConstructor(ci); o.WriteLine(); } first = true; foreach (MethodInfo m in Comparer.Sort(t.GetMethods(DefaultFlags))) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) != 0) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineMethod(m); o.WriteLine(); } first = true; foreach (MethodInfo m in t.GetMethods(DefaultFlags)) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) == 0) { continue; } if (!(m.Name.StartsWith("op_"))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineOperator(m); o.WriteLine(); } first = true; foreach (PropertyInfo pi in Comparer.Sort(t.GetProperties(DefaultFlags))) { if (!((pi.CanRead && ShowMember(pi.GetGetMethod(true))) || (pi.CanWrite && ShowMember(pi.GetSetMethod(true))))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(pi); OutlineProperty(pi); o.WriteLine(); } first = true; foreach (FieldInfo fi in t.GetFields(DefaultFlags)) { if (!ShowMember(fi)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(fi); OutlineField(fi); o.WriteLine(); } first = true; foreach (EventInfo ei in Comparer.Sort(t.GetEvents(DefaultFlags))) { if (!ShowMember(ei.GetAddMethod(true))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ei); OutlineEvent(ei); o.WriteLine(); } first = true; foreach (Type ntype in Comparer.Sort(t.GetNestedTypes(DefaultFlags))) { if (!ShowMember(ntype)) { continue; } if (first) { o.WriteLine(); } first = false; #if STATIC new Outline(universe, mscorlib, ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #else new Outline(ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #endif } o.Indent--; o.WriteLine("}"); }
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)); }
// 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)); }
internal static bool IsSubclassOf(Type type, Type baseClass) { #if WINRT return type.GetTypeInfo().IsSubclassOf(baseClass); #else return type.IsSubclassOf(baseClass); #endif }
private static bool IsDelegate(Type type) { // HACK non-public delegates do not get the special treatment (because they are likely to refer to // non-public types in the arg list and they're not really useful anyway) // NOTE we don't have to check in what assembly the type lives, because this is a DotNetTypeWrapper, // we know that it is a different assembly. if (!type.IsAbstract && type.IsSubclassOf(Types.MulticastDelegate) && type.IsVisible) { MethodInfo invoke = type.GetMethod("Invoke"); if (invoke != null) { foreach (ParameterInfo p in invoke.GetParameters()) { // we don't support delegates with pointer parameters if (IsPointerType(p.ParameterType)) { return false; } } return !IsPointerType(invoke.ReturnType); } } return false; }
private static bool IsAttribute(Type type) { if (!type.IsAbstract && type.IsSubclassOf(Types.Attribute) && type.IsVisible) { // // Based on the number of constructors and their arguments, we distinguish several types // of attributes: // | def ctor | single 1-arg ctor // ----------------------------------------------------------------- // complex only (i.e. Annotation{N}) | | // all optional fields/properties | X | // required "value" | | X // optional "value" | X | X // ----------------------------------------------------------------- // // TODO currently we don't support "complex only" attributes. // ConstructorInfo defCtor; ConstructorInfo singleOneArgCtor; AttributeAnnotationTypeWrapper.GetConstructors(type, out defCtor, out singleOneArgCtor); return defCtor != null || singleOneArgCtor != null; } return false; }
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); }
// 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); }
static bool IsSubclassOf(Type base_class, Type derived_class) { return(derived_class.IsSubclassOf(base_class)); }
void Initialize(Type targetType, string methodName) { if (!_delegateType.IsSubclassOf(_typeMapper.MapType(typeof(Delegate)))) { throw new ArgumentException(Properties.Messages.ErrInvalidDelegateType, "delegateType"); } IMemberInfo delegateInvocationMethod = null; foreach (IMemberInfo mi in _typeMapper.TypeInfo.GetMethods(_delegateType)) { if (mi.Name == "Invoke") { if (delegateInvocationMethod != null) { throw new ArgumentException(Properties.Messages.ErrInvalidDelegateType, "delegateType"); } delegateInvocationMethod = mi; } } if (delegateInvocationMethod == null) { throw new ArgumentException(Properties.Messages.ErrInvalidDelegateType, "delegateType"); } foreach (IMemberInfo mi in _typeMapper.TypeInfo.GetConstructors(_delegateType)) { if (mi.IsStatic) { continue; } Type[] ctorParamTypes = mi.ParameterTypes; if (ctorParamTypes.Length == 2 && ctorParamTypes[0] == _typeMapper.MapType(typeof(object)) && ctorParamTypes[1] == _typeMapper.MapType(typeof(IntPtr))) { if (_delegateConstructor != null) { throw new ArgumentException(Properties.Messages.ErrInvalidDelegateType, "delegateType"); } _delegateConstructor = (ConstructorInfo)mi.Member; } } if (_delegateConstructor == null) { throw new ArgumentException(Properties.Messages.ErrInvalidDelegateType, "delegateType"); } Type retType = delegateInvocationMethod.ReturnType; Type[] parameterTypes = delegateInvocationMethod.ParameterTypes; for ( ; targetType != null; targetType = targetType.BaseType) { foreach (IMemberInfo mi in _typeMapper.TypeInfo.Filter(_typeMapper.TypeInfo.GetMethods(targetType), methodName, false, (object)_target == null, false)) { if (mi.ReturnType == retType && ArrayUtils.Equals(mi.ParameterTypes, parameterTypes)) { if (_method == null) { _method = (MethodInfo)mi.Member; } else { throw new AmbiguousMatchException(Properties.Messages.ErrAmbiguousBinding); } } } if (_method != null) { break; } } if (_method == null) { throw new MissingMethodException(Properties.Messages.ErrMissingMethod); } }
string GetTypeKind (Type t) { if (t.IsEnum) return "enum"; if (t.IsClass) { if (t.IsSubclassOf (type_multicast_delegate)) return "delegate"; else return "class"; } if (t.IsInterface) return "interface"; if (t.IsValueType) return "struct"; return "class"; }