}
public bool IsArray {
- get { return this is ArrayContainer; }
+ get {
+ return Kind == MemberKind.ArrayType;
+ }
}
public bool IsAttribute {
public bool IsConstantCompatible {
get {
- if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate)) != 0)
+ if ((Kind & (MemberKind.Enum | MemberKind.Class | MemberKind.Interface | MemberKind.Delegate | MemberKind.ArrayType)) != 0)
return true;
return TypeManager.IsPrimitiveType (this) || this == TypeManager.decimal_type || this == InternalType.Dynamic;
if (!pa.IsDefined)
return Attribute.DefaultUsageAttribute;
- var aua = MemberDefinition.GetAttributeUsage (pa);
- return aua ?? Attribute.DefaultUsageAttribute;
+ AttributeUsageAttribute aua = null;
+ var type = this;
+ while (type != null) {
+ aua = type.MemberDefinition.GetAttributeUsage (pa);
+ if (aua != null)
+ break;
+
+ type = type.BaseType;
+ }
+
+ return aua;
}
public virtual Type GetMetaInfo ()
if (type1.MemberDefinition != target_type_def)
return false;
- if (!type1.IsInterface && !type1.IsDelegate)
- return false;
-
var t1_targs = type1.TypeArguments;
var t2_targs = type2.TypeArguments;
var targs_definition = target_type_def.TypeParameters;
+
+ if (!type1.IsInterface && !type1.IsDelegate) {
+ //
+ // Internal compiler variance between G<object> and G<dynamic>
+ //
+ for (int i = 0; i < targs_definition.Length; ++i) {
+ if ((t1_targs[i] != TypeManager.object_type && t1_targs[i] != InternalType.Dynamic) ||
+ (t2_targs[i] != TypeManager.object_type && t2_targs[i] != InternalType.Dynamic))
+ return false;
+ }
+
+ return true;
+ }
+
for (int i = 0; i < targs_definition.Length; ++i) {
Variance v = targs_definition[i].Variance;
if (v == Variance.None) {
return true;
}
+ static bool ContainsTypeParameter (TypeSpec tparam, TypeSpec type)
+ {
+ TypeSpec[] targs = type.TypeArguments;
+ for (int i = 0; i < targs.Length; i++) {
+ if (tparam == targs[i])
+ return true;
+
+ if (ContainsTypeParameter (tparam, targs[i]))
+ return true;
+ }
+
+ return false;
+ }
+
/// <summary>
/// Check whether `a' and `b' may become equal generic types.
/// The algorithm to do that is a little bit complicated.
// class X<T> : I<T>, I<X<T>> -> ok
//
- TypeSpec[] bargs = b.TypeArguments;
- for (int i = 0; i < bargs.Length; i++) {
- if (a.Equals (bargs[i]))
- return false;
- }
-
- return true;
+ return !ContainsTypeParameter (a, b);
}
if (b.IsGenericParameter)
state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
}
+ public override int Arity {
+ get {
+ return 0;
+ }
+ }
+
+ public override string Name {
+ get {
+ return name;
+ }
+ }
+
public override string GetSignatureForError ()
{
return name;
}
}
- public abstract class ElementTypeSpec : TypeSpec
+ public abstract class ElementTypeSpec : TypeSpec, ITypeDefinition
{
protected ElementTypeSpec (MemberKind kind, TypeSpec element, Type info)
- : base (kind, element.DeclaringType, element.MemberDefinition, info, element.Modifiers)
+ : base (kind, element.DeclaringType, null, info, element.Modifiers)
{
this.Element = element;
+
+ // Has to use its own type definition instead of just element definition to
+ // correctly identify itself for cases like x.MemberDefininition == predefined.MemberDefinition
+ this.definition = this;
+
cache = MemberCache.Empty;
}
mutated.info = null;
return mutated;
}
+
+ #region ITypeDefinition Members
+
+ System.Reflection.Assembly IMemberDefinition.Assembly {
+ get {
+ return Element.Assembly;
+ }
+ }
+
+ public string Namespace {
+ get { throw new NotImplementedException (); }
+ }
+
+ public int TypeParametersCount {
+ get {
+ return 0;
+ }
+ }
+
+ public TypeParameterSpec[] TypeParameters {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
+ public TypeSpec GetAttributeCoClass ()
+ {
+ return Element.MemberDefinition.GetAttributeCoClass ();
+ }
+
+ public string GetAttributeDefaultMember ()
+ {
+ return Element.MemberDefinition.GetAttributeDefaultMember ();
+ }
+
+ public MemberCache LoadMembers (TypeSpec declaringType)
+ {
+ return Element.MemberDefinition.LoadMembers (declaringType);
+ }
+
+ public bool IsImported {
+ get {
+ return Element.MemberDefinition.IsImported;
+ }
+ }
+
+ public string[] ConditionalConditions ()
+ {
+ return Element.MemberDefinition.ConditionalConditions ();
+ }
+
+ bool IMemberDefinition.IsNotCLSCompliant ()
+ {
+ return Element.MemberDefinition.IsNotCLSCompliant ();
+ }
+
+ public void SetIsAssigned ()
+ {
+ Element.MemberDefinition.SetIsAssigned ();
+ }
+
+ public void SetIsUsed ()
+ {
+ Element.MemberDefinition.SetIsUsed ();
+ }
+
+ #endregion
}
public class ArrayContainer : ElementTypeSpec
{
+ struct TypeRankPair : IEquatable<TypeRankPair>
+ {
+ TypeSpec ts;
+ int rank;
+
+ public TypeRankPair (TypeSpec ts, int rank)
+ {
+ this.ts = ts;
+ this.rank = rank;
+ }
+
+ public override int GetHashCode ()
+ {
+ return ts.GetHashCode () ^ rank.GetHashCode ();
+ }
+
+ #region IEquatable<Tuple<T1,T2>> Members
+
+ public bool Equals (TypeRankPair other)
+ {
+ return other.ts == ts && other.rank == rank;
+ }
+
+ #endregion
+ }
+
readonly int rank;
- static Dictionary<Tuple<TypeSpec, int>, ArrayContainer> instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+ static Dictionary<TypeRankPair, ArrayContainer> instances = new Dictionary<TypeRankPair, ArrayContainer> ();
private ArrayContainer (TypeSpec element, int rank)
- : base (MemberKind.Class, element, null)
+ : base (MemberKind.ArrayType, element, null)
{
this.rank = rank;
}
return ctor;
}
+ public System.Reflection.MethodInfo GetAddressMethod ()
+ {
+ var mb = RootContext.ToplevelTypes.Builder;
+
+ var arg_types = new Type[rank];
+ for (int i = 0; i < rank; i++)
+ arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+
+ var address = mb.GetArrayMethod (
+ GetMetaInfo (), "Address",
+ System.Reflection.CallingConventions.HasThis | System.Reflection.CallingConventions.Standard,
+ ReferenceContainer.MakeType (Element).GetMetaInfo (), arg_types);
+
+ return address;
+ }
+
public System.Reflection.MethodInfo GetGetMethod ()
{
var mb = RootContext.ToplevelTypes.Builder;
}
protected override string GetPostfixSignature()
+ {
+ return GetPostfixSignature (rank);
+ }
+
+ public static string GetPostfixSignature (int rank)
{
StringBuilder sb = new StringBuilder ();
sb.Append ("[");
public static ArrayContainer MakeType (TypeSpec element, int rank)
{
ArrayContainer ac;
- var key = Tuple.Create (element, rank);
+ var key = new TypeRankPair (element, rank);
if (!instances.TryGetValue (key, out ac)) {
ac = new ArrayContainer (element, rank) {
BaseType = TypeManager.array_type
public static void Reset ()
{
- instances = new Dictionary<Tuple<TypeSpec, int>, ArrayContainer> ();
+ instances = new Dictionary<TypeRankPair, ArrayContainer> ();
}
}