// // From a one-dimensional array-type S[] to System.Collections.IList<T> and base // interfaces of this interface, provided there is an implicit reference conversion // from S to T. // static bool ArrayToIList (ArrayContainer array, TypeSpec list, bool isExplicit) { if (array.Rank != 1 || !list.IsGeneric) return false; var open_version = list.GetDefinition (); if ((open_version != TypeManager.generic_ilist_type) && (open_version != TypeManager.generic_icollection_type) && (open_version != TypeManager.generic_ienumerable_type)) return false; var arg_type = list.TypeArguments[0]; if (array.Element == arg_type) return true; if (isExplicit) return ExplicitReferenceConversionExists (array.Element, arg_type); if (MyEmptyExpr == null) MyEmptyExpr = new EmptyExpression (array.Element); else MyEmptyExpr.SetType (array.Element); return ImplicitReferenceConversionExists (MyEmptyExpr, arg_type); }
public static bool IsNullableType (TypeSpec t) { return generic_nullable_type == t.GetDefinition (); }
// // Checks whether `type' is a nested child of `parent'. // public static bool IsNestedChildOf (TypeSpec type, TypeSpec parent) { if (type == null) return false; type = type.GetDefinition (); // DropGenericTypeArguments (type); parent = parent.GetDefinition (); // DropGenericTypeArguments (parent); if (type == parent) return false; type = type.DeclaringType; while (type != null) { if (type.GetDefinition () == parent) return true; type = type.DeclaringType; } return false; }
/// <summary> /// Same as ImplicitStandardConversionExists except that it also looks at /// implicit user defined conversions - needed for overload resolution /// </summary> public static bool ImplicitConversionExists (ResolveContext ec, Expression expr, TypeSpec target_type) { if (ImplicitStandardConversionExists (expr, target_type)) return true; if (expr.Type == InternalType.AnonymousMethod) { if (!TypeManager.IsDelegateType (target_type) && target_type.GetDefinition () != TypeManager.expression_type) return false; AnonymousMethodExpression ame = (AnonymousMethodExpression) expr; return ame.ImplicitStandardConversionExists (ec, target_type); } if (expr.eclass == ExprClass.MethodGroup) { if (target_type.IsDelegate && RootContext.Version != LanguageVersion.ISO_1) { MethodGroupExpr mg = expr as MethodGroupExpr; if (mg != null) return DelegateCreation.ImplicitStandardConversionExists (ec, mg, target_type); } return false; } return ImplicitUserConversion (ec, expr, target_type, Location.Null) != null; }
public static TypeSpec GetUnderlyingType (TypeSpec t) { return ((EnumSpec) t.GetDefinition ()).UnderlyingType; }
TypeSpec CompatibleChecks (ResolveContext ec, TypeSpec delegate_type) { if (delegate_type.IsDelegate) return delegate_type; if (delegate_type.IsGeneric && delegate_type.GetDefinition () == TypeManager.expression_type) { delegate_type = delegate_type.TypeArguments [0]; if (delegate_type.IsDelegate) return delegate_type; ec.Report.Error (835, loc, "Cannot convert `{0}' to an expression tree of non-delegate type `{1}'", GetSignatureForError (), TypeManager.CSharpName (delegate_type)); return null; } ec.Report.Error (1660, loc, "Cannot convert `{0}' to non-delegate type `{1}'", GetSignatureForError (), TypeManager.CSharpName (delegate_type)); return null; }
// // Infers type arguments based on explicit arguments // public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, TypeSpec delegate_type) { if (!HasExplicitParameters) return false; if (!delegate_type.IsDelegate) { if (delegate_type.GetDefinition () != TypeManager.expression_type) return false; delegate_type = TypeManager.GetTypeArguments (delegate_type) [0]; if (!delegate_type.IsDelegate) return false; } AParametersCollection d_params = Delegate.GetParameters (ec.Compiler, delegate_type); if (d_params.Count != Parameters.Count) return false; for (int i = 0; i < Parameters.Count; ++i) { TypeSpec itype = d_params.Types [i]; if (!TypeManager.IsGenericParameter (itype)) { if (!TypeManager.HasElementType (itype)) continue; if (!TypeManager.IsGenericParameter (TypeManager.GetElementType (itype))) continue; } type_inference.ExactInference (Parameters.Types [i], itype); } return true; }
public bool CheckAccessLevel (TypeSpec check_type) { // TODO: Use this instead // return PartialContainer.Definition.IsAccessible (check_type); TypeSpec tb = PartialContainer.Definition; check_type = check_type.GetDefinition (); var check_attr = check_type.Modifiers & Modifiers.AccessibilityMask; switch (check_attr){ case Modifiers.PUBLIC: return true; case Modifiers.INTERNAL: return TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly); case Modifiers.PRIVATE: TypeSpec declaring = check_type.DeclaringType; return tb == declaring.GetDefinition () || TypeManager.IsNestedChildOf (tb, declaring); case Modifiers.PROTECTED: // // Only accessible to methods in current type or any subtypes // return TypeManager.IsNestedFamilyAccessible (tb, check_type.DeclaringType); case Modifiers.PROTECTED | Modifiers.INTERNAL: if (TypeManager.IsThisOrFriendAssembly (Assembly, check_type.Assembly)) return true; goto case Modifiers.PROTECTED; } throw new NotImplementedException (check_attr.ToString ()); }
// // 7.4.3.3 Better conversion from expression // Returns : 1 if a->p is better, // 2 if a->q is better, // 0 if neither is better // static int BetterExpressionConversion(ResolveContext ec, Argument a, TypeSpec p, TypeSpec q) { TypeSpec argument_type = a.Type; if (argument_type == InternalType.AnonymousMethod && RootContext.Version > LanguageVersion.ISO_2) { // // Uwrap delegate from Expression<T> // if (p.GetDefinition () == TypeManager.expression_type) { p = TypeManager.GetTypeArguments (p) [0]; } if (q.GetDefinition () == TypeManager.expression_type) { q = TypeManager.GetTypeArguments (q) [0]; } p = Delegate.GetInvokeMethod (ec.Compiler, p).ReturnType; q = Delegate.GetInvokeMethod (ec.Compiler, q).ReturnType; if (p == TypeManager.void_type && q != TypeManager.void_type) return 2; if (q == TypeManager.void_type && p != TypeManager.void_type) return 1; } else { if (argument_type == p) return 1; if (argument_type == q) return 2; } return BetterTypeConversion (ec, p, q); }
// // Lower-bound (false) or Upper-bound (true) inference based on inversed argument // int LowerBoundInference (TypeSpec u, TypeSpec v, bool inversed) { // If V is one of the unfixed type arguments int pos = IsUnfixed (v); if (pos != -1) { AddToBounds (new BoundInfo (u, inversed ? BoundKind.Upper : BoundKind.Lower), pos); return 1; } // If U is an array type var u_ac = u as ArrayContainer; if (u_ac != null) { var v_ac = v as ArrayContainer; if (v_ac != null) { if (u_ac.Rank != v_ac.Rank) return 0; if (TypeManager.IsValueType (u_ac.Element)) return ExactInference (u_ac.Element, v_ac.Element); return LowerBoundInference (u_ac.Element, v_ac.Element, inversed); } if (u_ac.Rank != 1) return 0; if (TypeManager.IsGenericType (v)) { TypeSpec g_v = v.GetDefinition (); if (g_v != TypeManager.generic_ilist_type && g_v != TypeManager.generic_icollection_type && g_v != TypeManager.generic_ienumerable_type) return 0; var v_i = TypeManager.GetTypeArguments (v) [0]; if (TypeManager.IsValueType (u_ac.Element)) return ExactInference (u_ac.Element, v_i); return LowerBoundInference (u_ac.Element, v_i); } } else if (TypeManager.IsGenericType (v)) { // // if V is a constructed type C<V1..Vk> and there is a unique type C<U1..Uk> // such that U is identical to, inherits from (directly or indirectly), // or implements (directly or indirectly) C<U1..Uk> // var u_candidates = new List<TypeSpec> (); var open_v = v.MemberDefinition; for (TypeSpec t = u; t != null; t = t.BaseType) { if (open_v == t.MemberDefinition) u_candidates.Add (t); if (t.Interfaces != null) { foreach (var iface in t.Interfaces) { if (open_v == iface.MemberDefinition) u_candidates.Add (iface); } } } TypeSpec [] unique_candidate_targs = null; TypeSpec[] ga_v = TypeManager.GetTypeArguments (v); foreach (TypeSpec u_candidate in u_candidates) { // // The unique set of types U1..Uk means that if we have an interface I<T>, // class U : I<int>, I<long> then no type inference is made when inferring // type I<T> by applying type U because T could be int or long // if (unique_candidate_targs != null) { TypeSpec[] second_unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate); if (TypeSpecComparer.Default.Equals (unique_candidate_targs, second_unique_candidate_targs)) { unique_candidate_targs = second_unique_candidate_targs; continue; } // // This should always cause type inference failure // failed = true; return 1; } unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate); } if (unique_candidate_targs != null) { var ga_open_v = open_v.TypeParameters; int score = 0; for (int i = 0; i < unique_candidate_targs.Length; ++i) { Variance variance = ga_open_v [i].Variance; TypeSpec u_i = unique_candidate_targs [i]; if (variance == Variance.None || TypeManager.IsValueType (u_i)) { if (ExactInference (u_i, ga_v [i]) == 0) ++score; } else { bool upper_bound = (variance == Variance.Contravariant && !inversed) || (variance == Variance.Covariant && inversed); if (LowerBoundInference (u_i, ga_v [i], upper_bound) == 0) ++score; } } return score; } } return 0; }
static bool HasDefaultConstructor (TypeSpec atype) { var tp = atype as TypeParameterSpec; if (tp != null) { return tp.HasSpecialConstructor || tp.HasSpecialStruct; } if (atype.IsStruct || atype.IsEnum) return true; if (atype.IsAbstract) return false; var tdef = atype.GetDefinition (); // // In some circumstances MemberCache is not yet populated and members // cannot be defined yet (recursive type new constraints) // // class A<T> where T : B<T>, new () {} // class B<T> where T : A<T>, new () {} // var tc = tdef.MemberDefinition as Class; if (tc != null) { if (tc.InstanceConstructors == null) { // Default ctor will be generated later return true; } foreach (var c in tc.InstanceConstructors) { if (c.ParameterInfo.IsEmpty) { if ((c.ModFlags & Modifiers.PUBLIC) != 0) return true; } } return false; } var found = MemberCache.FindMember (tdef, MemberFilter.Constructor (ParametersCompiled.EmptyReadOnlyParameters), BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly); return found != null && (found.Modifiers & Modifiers.PUBLIC) != 0; }
public GenericOpenTypeExpr (TypeSpec type, /*UnboundTypeArguments args,*/ Location loc) { this.type = type.GetDefinition (); this.loc = loc; }