// Dual licensed under the terms of the MIT X11 or GNU GPL
//
// Copyright 2010 Novell, Inc
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
//
using System;
using System.Collections.Generic;
using System.Text;
+
+#if STATIC
+using MetaType = IKVM.Reflection.Type;
+using IKVM.Reflection;
+#else
+using MetaType = System.Type;
using System.Reflection;
+#endif
namespace Mono.CSharp
{
+ //
+ // Inflated or non-inflated representation of any type.
+ //
public class TypeSpec : MemberSpec
{
- protected Type info;
+ protected MetaType info;
protected MemberCache cache;
protected IList<TypeSpec> ifaces;
TypeSpec base_type;
public static readonly TypeSpec[] EmptyTypes = new TypeSpec[0];
+#if !STATIC
// Reflection Emit hacking
static readonly Type TypeBuilder;
static readonly Type GenericTypeBuilder;
if (GenericTypeBuilder == null)
GenericTypeBuilder = assembly.GetType ("System.Reflection.Emit.TypeBuilderInstantiation");
}
+#endif
- public TypeSpec (MemberKind kind, TypeSpec declaringType, ITypeDefinition definition, Type info, Modifiers modifiers)
+ public TypeSpec (MemberKind kind, TypeSpec declaringType, ITypeDefinition definition, MetaType info, Modifiers modifiers)
: base (kind, declaringType, definition, modifiers)
{
this.declaringType = declaringType;
}
}
- public virtual BuildinTypeSpec.Type BuildinType {
+ public virtual BuiltinTypeSpec.Type BuiltinType {
get {
- return BuildinTypeSpec.Type.None;
+ return BuiltinTypeSpec.Type.None;
}
}
var type = this;
do {
+ if (type.BuiltinType == BuiltinTypeSpec.Type.Attribute)
+ return true;
+
if (type.IsGeneric)
return false;
-
- if (type == TypeManager.attribute_type)
- return true;
type = type.base_type;
} while (type != null);
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;
+ switch (BuiltinType) {
+ case BuiltinTypeSpec.Type.Int:
+ case BuiltinTypeSpec.Type.UInt:
+ case BuiltinTypeSpec.Type.Long:
+ case BuiltinTypeSpec.Type.ULong:
+ case BuiltinTypeSpec.Type.Float:
+ case BuiltinTypeSpec.Type.Double:
+ case BuiltinTypeSpec.Type.Char:
+ case BuiltinTypeSpec.Type.Short:
+ case BuiltinTypeSpec.Type.Decimal:
+ case BuiltinTypeSpec.Type.Bool:
+ case BuiltinTypeSpec.Type.SByte:
+ case BuiltinTypeSpec.Type.Byte:
+ case BuiltinTypeSpec.Type.UShort:
+ case BuiltinTypeSpec.Type.Dynamic:
+ return true;
+ }
+
+ return false;
}
}
}
}
+ //
+ // Returns true for instances of Expression<T>
+ //
+ public virtual bool IsExpressionTreeType {
+ get {
+ return false;
+ }
+ set {
+ state = value ? state | StateFlags.InflatedExpressionType : state & ~StateFlags.InflatedExpressionType;
+ }
+ }
+
public bool IsEnum {
- get { return Kind == MemberKind.Enum; }
+ get {
+ return Kind == MemberKind.Enum;
+ }
+ }
+
+ //
+ // Returns true for instances of IList<T>, IEnumerable<T>, ICollection<T>
+ //
+ public virtual bool IsGenericIterateInterface {
+ get {
+ return false;
+ }
+ set {
+ state = value ? state | StateFlags.GenericIterateInterface : state & ~StateFlags.GenericIterateInterface;
+ }
+ }
+
+ //
+ // Returns true for instances of System.Threading.Tasks.Task<T>
+ //
+ public virtual bool IsGenericTask {
+ get {
+ return false;
+ }
+ set {
+ state = value ? state | StateFlags.GenericTask : state & ~StateFlags.GenericTask;
+ }
}
// TODO: Should probably do
}
public bool IsGenericParameter {
- get { return Kind == MemberKind.TypeParameter; }
+ get {
+ return Kind == MemberKind.TypeParameter;
+ }
+ }
+
+ //
+ // Returns true for instances of Nullable<T>
+ //
+ public virtual bool IsNullableType {
+ get {
+ return false;
+ }
+ set {
+ state = value ? state | StateFlags.InflatedNullableType : state & ~StateFlags.InflatedNullableType;
+ }
}
public bool IsNested {
get { return (Modifiers & Modifiers.SEALED) != 0; }
}
+ public bool IsSpecialRuntimeType {
+ get {
+ return (state & StateFlags.SpecialRuntimeType) != 0;
+ }
+ set {
+ state = value ? state | StateFlags.SpecialRuntimeType : state & ~StateFlags.SpecialRuntimeType;
+ }
+ }
+
public bool IsStruct {
get {
return Kind == MemberKind.Struct;
public bool IsTypeBuilder {
get {
+#if STATIC
+ return true;
+#else
var meta = GetMetaInfo().GetType ();
return meta == TypeBuilder || meta == GenericTypeBuilder;
+#endif
}
}
+ //
+ // Whether a type is unmanaged. This is used by the unsafe code
+ //
+ public bool IsUnmanaged {
+ get {
+ if (IsPointer)
+ return ((ElementTypeSpec) this).Element.IsUnmanaged;
+
+ var ds = MemberDefinition as TypeDefinition;
+ if (ds != null)
+ return ds.IsUnmanagedType ();
+
+ if (Kind == MemberKind.Void)
+ return true;
+
+ if (IsNested && DeclaringType.IsGenericOrParentIsGeneric)
+ return false;
+
+ return IsValueType (this);
+ }
+ }
+
+ //
+ // A cache of all type members (including nested types)
+ //
public MemberCache MemberCache {
get {
if (cache == null || (state & StateFlags.PendingMemberCacheMembers) != 0)
return false;
}
+ //
+ // Special version used during type definition
+ //
+ public bool AddInterfaceDefined (TypeSpec iface)
+ {
+ if (!AddInterface (iface))
+ return false;
+
+ //
+ // We can get into a situation where a type is inflated before
+ // its interfaces are resoved. Consider this situation
+ //
+ // class A<T> : X<A<int>>, IFoo {}
+ //
+ // When resolving base class of X`1 we inflate context type A`1
+ // All this happens before we even hit IFoo resolve. Without
+ // additional expansion any inside usage of A<T> would miss IFoo
+ // interface because it comes from early inflated TypeSpec
+ //
+ if (inflated_instances != null) {
+ foreach (var inflated in inflated_instances) {
+ inflated.Value.AddInterface (iface);
+ }
+ }
+
+ return true;
+ }
+
+ //
+ // Returns all type arguments, usefull for nested types
+ //
+ public static TypeSpec[] GetAllTypeArguments (TypeSpec type)
+ {
+ IList<TypeSpec> targs = TypeSpec.EmptyTypes;
+
+ do {
+ if (type.Arity > 0) {
+ if (targs.Count == 0) {
+ targs = type.TypeArguments;
+ } else {
+ var list = targs as List<TypeSpec> ?? new List<TypeSpec> (targs);
+ list.AddRange (type.TypeArguments);
+ targs = list;
+ }
+ }
+
+ type = type.declaringType;
+ } while (type != null);
+
+ return targs as TypeSpec[] ?? ((List<TypeSpec>) targs).ToArray ();
+ }
+
public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
{
if (Kind != MemberKind.Class)
return aua;
}
- public virtual Type GetMetaInfo ()
+ //
+ // Return metadata information used during emit to describe the type
+ //
+ public virtual MetaType GetMetaInfo ()
{
return info;
}
return this;
}
+ //
+ // Text representation of type used by documentation writer
+ //
+ public override string GetSignatureForDocumentation ()
+ {
+ StringBuilder sb = new StringBuilder ();
+ if (IsNested) {
+ sb.Append (DeclaringType.GetSignatureForDocumentation ());
+ } else {
+ sb.Append (MemberDefinition.Namespace);
+ }
+
+ if (sb.Length != 0)
+ sb.Append (".");
+
+ sb.Append (Name);
+ if (Arity > 0) {
+ if (this is InflatedTypeSpec) {
+ sb.Append ("{");
+ for (int i = 0; i < Arity; ++i) {
+ if (i > 0)
+ sb.Append (",");
+
+ sb.Append (TypeArguments[i].GetSignatureForDocumentation ());
+ }
+ sb.Append ("}");
+ } else {
+ sb.Append ("`");
+ sb.Append (Arity.ToString ());
+ }
+ }
+
+ return sb.ToString ();
+ }
+
+ public string GetExplicitNameSignatureForDocumentation ()
+ {
+ StringBuilder sb = new StringBuilder ();
+ if (IsNested) {
+ sb.Append (DeclaringType.GetExplicitNameSignatureForDocumentation ());
+ } else if (MemberDefinition.Namespace != null) {
+ sb.Append (MemberDefinition.Namespace.Replace ('.', '#'));
+ }
+
+ if (sb.Length != 0)
+ sb.Append ("#");
+
+ sb.Append (Name);
+ if (Arity > 0) {
+ sb.Append ("{");
+ for (int i = 0; i < Arity; ++i) {
+ if (i > 0)
+ sb.Append (",");
+
+ sb.Append (TypeArguments[i].GetExplicitNameSignatureForDocumentation ());
+ }
+ sb.Append ("}");
+ }
+
+ return sb.ToString ();
+ }
+
public override string GetSignatureForError ()
{
string s;
return s + Name + GetTypeNameSignature ();
}
+ public string GetSignatureForErrorIncludingAssemblyName ()
+ {
+ return string.Format ("{0} [{1}]", GetSignatureForError (), MemberDefinition.DeclaringAssembly.FullName);
+ }
+
protected virtual string GetTypeNameSignature ()
{
if (!IsGeneric)
{
var t = this;
do {
- if (t.Interfaces != null) { // TODO: Try t.iface
- foreach (TypeSpec i in t.Interfaces) {
- if (i == iface || TypeSpecComparer.IsEqual (i, iface))
+ var ifaces = t.Interfaces;
+ if (ifaces != null) {
+ for (int i = 0; i < ifaces.Count; ++i) {
+ if (TypeSpecComparer.IsEqual (ifaces[i], iface))
return true;
- if (variantly && TypeSpecComparer.Variant.IsEqual (i, iface))
+ if (variantly && TypeSpecComparer.Variant.IsEqual (ifaces[i], iface))
return true;
}
}
+ // TODO: Why is it needed when we do it during import
t = t.BaseType;
} while (t != null);
protected virtual void InitializeMemberCache (bool onlyTypes)
{
- MemberDefinition.LoadMembers (this, onlyTypes, ref cache);
+ try {
+ MemberDefinition.LoadMembers (this, onlyTypes, ref cache);
+ } catch (Exception e) {
+ throw new InternalErrorException (e, "Unexpected error when loading type `{0}'", GetSignatureForError ());
+ }
if (onlyTypes)
state |= StateFlags.PendingMemberCacheMembers;
//
// class B : A<object> {}
//
+ type = type.BaseType;
while (type != null) {
- type = type.BaseType;
if (TypeSpecComparer.IsEqual (type, baseClass))
return true;
+
+ type = type.BaseType;
}
return false;
return false;
}
+ public static bool IsReferenceType (TypeSpec t)
+ {
+ switch (t.Kind) {
+ case MemberKind.TypeParameter:
+ return ((TypeParameterSpec) t).IsReferenceType;
+ case MemberKind.Struct:
+ case MemberKind.Enum:
+ case MemberKind.Void:
+ return false;
+ case MemberKind.InternalCompilerType:
+ //
+ // Null is considered to be a reference type
+ //
+ return t == InternalType.NullLiteral || t.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
+ default:
+ return true;
+ }
+ }
+
+ public static bool IsValueType (TypeSpec t)
+ {
+ switch (t.Kind) {
+ case MemberKind.TypeParameter:
+ return ((TypeParameterSpec) t).IsValueType;
+ case MemberKind.Struct:
+ case MemberKind.Enum:
+ return true;
+ default:
+ return false;
+ }
+ }
+
public override MemberSpec InflateMember (TypeParameterInflator inflator)
{
var targs = IsGeneric ? MemberDefinition.TypeParameters : TypeSpec.EmptyTypes;
// because type parameters are same for all nested types
//
if (DeclaringType == inflator.TypeInstance) {
- return MakeGenericType (targs);
+ return MakeGenericType (inflator.Context, targs);
}
- return new InflatedTypeSpec (this, inflator.TypeInstance, targs);
+ return new InflatedTypeSpec (inflator.Context, this, inflator.TypeInstance, targs);
}
- public InflatedTypeSpec MakeGenericType (TypeSpec[] targs)
+ //
+ // Inflates current type using specific type arguments
+ //
+ public InflatedTypeSpec MakeGenericType (IModuleContext context, TypeSpec[] targs)
{
if (targs.Length == 0 && !IsNested)
throw new ArgumentException ("Empty type arguments for type " + GetSignatureForError ());
throw new InternalErrorException ("`{0}' must be type definition or nested non-inflated type to MakeGenericType",
GetSignatureForError ());
- instance = new InflatedTypeSpec (this, declaringType, targs);
+ instance = new InflatedTypeSpec (context, this, declaringType, targs);
inflated_instances.Add (targs, instance);
}
return this;
}
- public void SetMetaInfo (Type info)
+ public override List<TypeSpec> ResolveMissingDependencies ()
+ {
+ List<TypeSpec> missing = null;
+
+ if (Kind == MemberKind.MissingType) {
+ missing = new List<TypeSpec> ();
+ missing.Add (this);
+ return missing;
+ }
+
+ foreach (var targ in TypeArguments) {
+ if (targ.Kind == MemberKind.MissingType) {
+ if (missing == null)
+ missing = new List<TypeSpec> ();
+
+ missing.Add (targ);
+ }
+ }
+
+ if (Interfaces != null) {
+ foreach (var iface in Interfaces) {
+ if (iface.Kind == MemberKind.MissingType) {
+ if (missing == null)
+ missing = new List<TypeSpec> ();
+
+ missing.Add (iface);
+ }
+ }
+ }
+
+ if (MemberDefinition.TypeParametersCount > 0) {
+ foreach (var tp in MemberDefinition.TypeParameters) {
+ var tp_missing = tp.GetMissingDependencies ();
+ if (tp_missing != null) {
+ if (missing == null)
+ missing = new List<TypeSpec> ();
+
+ missing.AddRange (tp_missing);
+ }
+ }
+ }
+
+ if (missing != null || BaseType == null)
+ return missing;
+
+ return BaseType.ResolveMissingDependencies ();
+ }
+
+ public void SetMetaInfo (MetaType info)
{
if (this.info != null)
throw new InternalErrorException ("MetaInfo reset");
}
}
- public sealed class BuildinTypeSpec : TypeSpec
+ //
+ // Special version used for types which must exist in corlib or
+ // the compiler cannot work
+ //
+ public sealed class BuiltinTypeSpec : TypeSpec
{
public enum Type
{
None = 0,
- // TODO: Reorder it more carefully so we can do fast compares
- Object,
- ValueType,
- Attribute,
- Int,
- UInt,
- Long,
- ULong,
- Float,
- Double,
- Char,
- Short,
- Decimal,
- Bool,
- SByte,
- Byte,
- UShort,
- String,
- Enum,
- Delegate,
- MulticastDelegate,
- Void,
- Array,
- Type,
+ // Ordered carefully for fast compares
+ FirstPrimitive = 1,
+ Bool = 1,
+ Byte = 2,
+ SByte = 3,
+ Char = 4,
+ Short = 5,
+ UShort = 6,
+ Int = 7,
+ UInt = 8,
+ Long = 9,
+ ULong = 10,
+ Float = 11,
+ Double = 12,
+ LastPrimitive = 12,
+ Decimal = 13,
+
+ IntPtr = 14,
+ UIntPtr = 15,
+
+ Object = 16,
+ Dynamic = 17,
+ String = 18,
+ Type = 19,
+
+ ValueType = 20,
+ Enum = 21,
+ Delegate = 22,
+ MulticastDelegate = 23,
+ Array = 24,
+
IEnumerator,
IEnumerable,
IDisposable,
- IntPtr,
- UIntPtr,
- RuntimeFieldHandle,
- RuntimeTypeHandle,
Exception,
-
- Null,
- Dynamic
+ Attribute,
+ Other,
}
readonly Type type;
readonly string ns;
readonly string name;
- public BuildinTypeSpec (MemberKind kind, string ns, string name, Type buildinKind)
+ public BuiltinTypeSpec (MemberKind kind, string ns, string name, Type builtinKind)
: base (kind, null, null, null, Modifiers.PUBLIC)
{
- if (kind == MemberKind.Struct)
- modifiers |= Modifiers.SEALED;
-
- this.type = buildinKind;
+ this.type = builtinKind;
this.ns = ns;
this.name = name;
}
- public BuildinTypeSpec (string name, Type buildinKind)
- : this (MemberKind.InternalCompilerType, "", name, buildinKind)
+ public BuiltinTypeSpec (string name, Type builtinKind)
+ : this (MemberKind.InternalCompilerType, "", name, builtinKind)
{
- // Make all internal types CLS-compliant, non-obsolete
- state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
+ // Make all internal types CLS-compliant, non-obsolete, compact
+ state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected | StateFlags.MissingDependency_Undetected)) | StateFlags.CLSCompliant;
}
#region Properties
}
}
- public override BuildinTypeSpec.Type BuildinType {
+ public override BuiltinTypeSpec.Type BuiltinType {
get {
return type;
}
#endregion
+ public static bool IsPrimitiveType (TypeSpec type)
+ {
+ return type.BuiltinType >= Type.FirstPrimitive && type.BuiltinType <= Type.LastPrimitive;
+ }
+
+ public static bool IsPrimitiveTypeOrDecimal (TypeSpec type)
+ {
+ return type.BuiltinType >= Type.FirstPrimitive && type.BuiltinType <= Type.Decimal;
+ }
+
public override string GetSignatureForError ()
{
switch (Name) {
return FullName;
}
- public void SetDefinition (ITypeDefinition td, System.Type type)
+ //
+ // Returns the size of type if known, otherwise, 0
+ //
+ public static int GetSize (TypeSpec type)
+ {
+ switch (type.BuiltinType) {
+ case Type.Int:
+ case Type.UInt:
+ case Type.Float:
+ return 4;
+ case Type.Long:
+ case Type.ULong:
+ case Type.Double:
+ return 8;
+ case Type.Byte:
+ case Type.SByte:
+ case Type.Bool:
+ return 1;
+ case Type.Short:
+ case Type.Char:
+ case Type.UShort:
+ return 2;
+ case Type.Decimal:
+ return 16;
+ default:
+ return 0;
+ }
+ }
+
+ public void SetDefinition (ITypeDefinition td, MetaType type, Modifiers mod)
{
this.definition = td;
this.info = type;
+ this.modifiers |= (mod & ~Modifiers.AccessibilityMask);
}
public void SetDefinition (TypeSpec ts)
this.info = ts.GetMetaInfo ();
this.BaseType = ts.BaseType;
this.Interfaces = ts.Interfaces;
+ this.modifiers = ts.Modifiers;
}
}
+ //
+ // Various type comparers used by compiler
+ //
static class TypeSpecComparer
{
//
return ac_b != null && ac_a.Rank == ac_b.Rank && IsEqual (ac_a.Element, ac_b.Element);
}
- if (a == InternalType.Dynamic || b == InternalType.Dynamic)
- return b == TypeManager.object_type || a == TypeManager.object_type;
+ if (a.BuiltinType == BuiltinTypeSpec.Type.Dynamic || b.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+ return b.BuiltinType == BuiltinTypeSpec.Type.Object || a.BuiltinType == BuiltinTypeSpec.Type.Object;
if (a.MemberDefinition != b.MemberDefinition)
return false;
return true;
}
+ public static bool IsEqual (TypeSpec[] a, TypeSpec[] b)
+ {
+ if (a == b)
+ return true;
+
+ if (a.Length != b.Length)
+ return false;
+
+ for (int i = 0; i < a.Length; ++i) {
+ if (!IsEqual (a[i], b[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+
//
// Compares unordered arrays
//
if (!IsEqual (a.Types[i], b.Types[i]))
return false;
- const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
- if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
+ if ((a.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (b.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
return false;
}
}
for (int i = 0; i < targs_definition.Length; ++i) {
+ if (TypeSpecComparer.IsEqual (t1_targs[i], t2_targs[i]))
+ continue;
+
Variance v = targs_definition[i].Variance;
if (v == Variance.None) {
- if (t1_targs[i] == t2_targs[i])
- continue;
return false;
}
if (v == Variance.Covariant) {
- if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t1_targs[i]), t2_targs[i]))
+ if (!Convert.ImplicitReferenceConversionExists (t1_targs[i], t2_targs[i]))
return false;
- } else if (!Convert.ImplicitReferenceConversionExists (new EmptyExpression (t2_targs[i]), t1_targs[i])) {
+ } else if (!Convert.ImplicitReferenceConversionExists (t2_targs[i], t1_targs[i])) {
return false;
}
}
//
public static bool IsEqual (TypeSpec a, TypeSpec b)
{
- if (a.MemberDefinition != b.MemberDefinition)
+ if (a.MemberDefinition != b.MemberDefinition) {
+ var base_ifaces = a.Interfaces;
+ if (base_ifaces != null) {
+ foreach (var base_iface in base_ifaces) {
+ if (base_iface.Arity > 0 && IsEqual (base_iface, b))
+ return true;
+ }
+ }
+
return false;
+ }
var ta = a.TypeArguments;
var tb = b.TypeArguments;
// class X<T> : I<T>, I<float>
//
if (b.IsGenericParameter)
- return a.DeclaringType == b.DeclaringType;
+ return a != b && a.DeclaringType == b.DeclaringType;
//
// We're now comparing a type parameter with a
{
if (a == b) {
// This also rejects dynamic == dynamic
- return a.Kind != MemberKind.InternalCompilerType || a == InternalType.Dynamic;
+ return a.Kind != MemberKind.InternalCompilerType || a.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
}
- //
- // object and dynamic are considered equivalent there is an identity conversion
- // between object and dynamic, and between constructed types that are the same
- // when replacing all occurences of dynamic with object.
- //
- if (a == InternalType.Dynamic || b == InternalType.Dynamic)
- return b == TypeManager.object_type || a == TypeManager.object_type;
-
- if (a == null)
+ if (a == null || b == null)
return false;
if (a.IsArray) {
if (b_a == null)
return false;
- return IsEqual (a_a.Element, b_a.Element) && a_a.Rank == b_a.Rank;
+ return a_a.Rank == b_a.Rank && IsEqual (a_a.Element, b_a.Element);
}
- if (!a.IsGeneric || b == null || !b.IsGeneric)
+ if (!a.IsGeneric || !b.IsGeneric) {
+ //
+ // object and dynamic are considered equivalent there is an identity conversion
+ // between object and dynamic, and between constructed types that are the same
+ // when replacing all occurences of dynamic with object.
+ //
+ if (a.BuiltinType == BuiltinTypeSpec.Type.Dynamic || b.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+ return b.BuiltinType == BuiltinTypeSpec.Type.Object || a.BuiltinType == BuiltinTypeSpec.Type.Object;
+
return false;
+ }
if (a.MemberDefinition != b.MemberDefinition)
return false;
{
IAssemblyDefinition DeclaringAssembly { get; }
string Namespace { get; }
+ bool IsPartial { get; }
+ bool IsComImport { get; }
+ bool IsTypeForwarder { get; }
int TypeParametersCount { get; }
TypeParameterSpec[] TypeParameters { get; }
{
public static readonly InternalType AnonymousMethod = new InternalType ("anonymous method");
public static readonly InternalType Arglist = new InternalType ("__arglist");
- public static BuildinTypeSpec Dynamic;
public static readonly InternalType MethodGroup = new InternalType ("method group");
- public static BuildinTypeSpec Null;
+ public static readonly InternalType NullLiteral = new InternalType ("null");
public static readonly InternalType FakeInternalType = new InternalType ("<fake$type>");
+ public static readonly InternalType Namespace = new InternalType ("<namespace>");
+ public static readonly InternalType ErrorType = new InternalType ("<error>");
readonly string name;
- InternalType (string name, MemberCache cache)
- : this (name)
- {
- this.cache = cache;
- }
-
InternalType (string name)
: base (MemberKind.InternalCompilerType, null, null, null, Modifiers.PUBLIC)
{
cache = MemberCache.Empty;
// Make all internal types CLS-compliant, non-obsolete
- state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected)) | StateFlags.CLSCompliant;
+ state = (state & ~(StateFlags.CLSCompliant_Undetected | StateFlags.Obsolete_Undetected | StateFlags.MissingDependency_Undetected)) | StateFlags.CLSCompliant;
}
#region Properties
}
}
+ bool ITypeDefinition.IsComImport {
+ get {
+ return false;
+ }
+ }
+
bool IMemberDefinition.IsImported {
get {
return false;
}
}
+ bool ITypeDefinition.IsPartial {
+ get {
+ return false;
+ }
+ }
+
+ bool ITypeDefinition.IsTypeForwarder {
+ get {
+ return false;
+ }
+ }
+
public override string Name {
get {
return name;
return null;
}
- bool IMemberDefinition.IsNotCLSCompliant ()
- {
- return false;
+ bool? IMemberDefinition.CLSAttributeValue {
+ get {
+ return null;
+ }
}
void IMemberDefinition.SetIsAssigned ()
#endregion
}
+ //
+ // Common base class for composite types
+ //
public abstract class ElementTypeSpec : TypeSpec, ITypeDefinition
{
- protected ElementTypeSpec (MemberKind kind, TypeSpec element, Type info)
+ protected ElementTypeSpec (MemberKind kind, TypeSpec element, MetaType info)
: base (kind, element.DeclaringType, null, info, element.Modifiers)
{
this.Element = element;
- // Some flags can be copied directly from the element
- const StateFlags shared_flags = StateFlags.CLSCompliant | StateFlags.CLSCompliant_Undetected
- | StateFlags.Obsolete | StateFlags.Obsolete_Undetected | StateFlags.HasDynamicElement;
- state &= ~shared_flags;
- state |= (element.state & shared_flags);
+ state &= ~SharedStateFlags;
+ state |= (element.state & SharedStateFlags);
- if (element == InternalType.Dynamic)
+ if (element.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
state |= StateFlags.HasDynamicElement;
// Has to use its own type definition instead of just element definition to
public TypeSpec Element { get; private set; }
+ bool ITypeDefinition.IsComImport {
+ get {
+ return false;
+ }
+ }
+
+ bool ITypeDefinition.IsPartial {
+ get {
+ return false;
+ }
+ }
+
+ bool ITypeDefinition.IsTypeForwarder {
+ get {
+ return false;
+ }
+ }
+
public override string Name {
get {
throw new NotSupportedException ();
return null;
}
+ public override string GetSignatureForDocumentation ()
+ {
+ return Element.GetSignatureForDocumentation () + GetPostfixSignature ();
+ }
+
public override string GetSignatureForError ()
{
return Element.GetSignatureForError () + GetPostfixSignature ();
return Element.MemberDefinition.ConditionalConditions ();
}
- bool IMemberDefinition.IsNotCLSCompliant ()
- {
- return Element.MemberDefinition.IsNotCLSCompliant ();
+ bool? IMemberDefinition.CLSAttributeValue {
+ get {
+ return Element.MemberDefinition.CLSAttributeValue;
+ }
}
public void SetIsAssigned ()
public class ArrayContainer : ElementTypeSpec
{
- struct TypeRankPair : IEquatable<TypeRankPair>
+ public struct TypeRankPair : IEquatable<TypeRankPair>
{
TypeSpec ts;
int rank;
}
readonly int rank;
- static Dictionary<TypeRankPair, ArrayContainer> instances = new Dictionary<TypeRankPair, ArrayContainer> ();
+ readonly ModuleContainer module;
- private ArrayContainer (TypeSpec element, int rank)
+ private ArrayContainer (ModuleContainer module, TypeSpec element, int rank)
: base (MemberKind.ArrayType, element, null)
{
+ this.module = module;
this.rank = rank;
}
public MethodInfo GetConstructor ()
{
- var mb = RootContext.ToplevelTypes.Builder;
+ var mb = module.Builder;
- var arg_types = new Type[rank];
+ var arg_types = new MetaType[rank];
for (int i = 0; i < rank; i++)
- arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+ arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo ();
var ctor = mb.GetArrayMethod (
GetMetaInfo (), Constructor.ConstructorName,
public MethodInfo GetAddressMethod ()
{
- var mb = RootContext.ToplevelTypes.Builder;
+ var mb = module.Builder;
- var arg_types = new Type[rank];
+ var arg_types = new MetaType[rank];
for (int i = 0; i < rank; i++)
- arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+ arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo ();
var address = mb.GetArrayMethod (
GetMetaInfo (), "Address",
CallingConventions.HasThis | CallingConventions.Standard,
- ReferenceContainer.MakeType (Element).GetMetaInfo (), arg_types);
+ ReferenceContainer.MakeType (module, Element).GetMetaInfo (), arg_types);
return address;
}
public MethodInfo GetGetMethod ()
{
- var mb = RootContext.ToplevelTypes.Builder;
+ var mb = module.Builder;
- var arg_types = new Type[rank];
+ var arg_types = new MetaType[rank];
for (int i = 0; i < rank; i++)
- arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+ arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo ();
var get = mb.GetArrayMethod (
GetMetaInfo (), "Get",
public MethodInfo GetSetMethod ()
{
- var mb = RootContext.ToplevelTypes.Builder;
+ var mb = module.Builder;
- var arg_types = new Type[rank + 1];
+ var arg_types = new MetaType[rank + 1];
for (int i = 0; i < rank; i++)
- arg_types[i] = TypeManager.int32_type.GetMetaInfo ();
+ arg_types[i] = module.Compiler.BuiltinTypes.Int.GetMetaInfo ();
arg_types[rank] = Element.GetMetaInfo ();
var set = mb.GetArrayMethod (
GetMetaInfo (), "Set",
CallingConventions.HasThis | CallingConventions.Standard,
- TypeManager.void_type.GetMetaInfo (), arg_types);
+ module.Compiler.BuiltinTypes.Void.GetMetaInfo (), arg_types);
return set;
}
- public override Type GetMetaInfo ()
+ public override MetaType GetMetaInfo ()
{
if (info == null) {
if (rank == 1)
return sb.ToString ();
}
- public static ArrayContainer MakeType (TypeSpec element)
+ public override string GetSignatureForDocumentation ()
{
- return MakeType (element, 1);
+ StringBuilder sb = new StringBuilder ();
+ GetElementSignatureForDocumentation (sb);
+ return sb.ToString ();
}
- public static ArrayContainer MakeType (TypeSpec element, int rank)
+ void GetElementSignatureForDocumentation (StringBuilder sb)
+ {
+ var ac = Element as ArrayContainer;
+ if (ac == null)
+ sb.Append (Element.GetSignatureForDocumentation ());
+ else
+ ac.GetElementSignatureForDocumentation (sb);
+
+ sb.Append ("[");
+ for (int i = 1; i < rank; i++) {
+ if (i == 1)
+ sb.Append ("0:");
+
+ sb.Append (",0:");
+ }
+ sb.Append ("]");
+ }
+
+ public static ArrayContainer MakeType (ModuleContainer module, TypeSpec element)
+ {
+ return MakeType (module, element, 1);
+ }
+
+ public static ArrayContainer MakeType (ModuleContainer module, TypeSpec element, int rank)
{
ArrayContainer ac;
var key = new TypeRankPair (element, rank);
- if (!instances.TryGetValue (key, out ac)) {
- ac = new ArrayContainer (element, rank) {
- BaseType = TypeManager.array_type
+ if (!module.ArrayTypesCache.TryGetValue (key, out ac)) {
+ ac = new ArrayContainer (module, element, rank) {
+ BaseType = module.Compiler.BuiltinTypes.Array
};
- instances.Add (key, ac);
+ module.ArrayTypesCache.Add (key, ac);
}
return ac;
}
-
- public static void Reset ()
- {
- instances = new Dictionary<TypeRankPair, ArrayContainer> ();
- }
}
class ReferenceContainer : ElementTypeSpec
{
- static Dictionary<TypeSpec, ReferenceContainer> instances = new Dictionary<TypeSpec, ReferenceContainer> ();
-
private ReferenceContainer (TypeSpec element)
: base (MemberKind.Class, element, null) // TODO: Kind.Class is most likely wrong
{
}
- public override Type GetMetaInfo ()
+ public override MetaType GetMetaInfo ()
{
if (info == null) {
info = Element.GetMetaInfo ().MakeByRefType ();
return info;
}
- public static ReferenceContainer MakeType (TypeSpec element)
+ public static ReferenceContainer MakeType (ModuleContainer module, TypeSpec element)
{
ReferenceContainer pc;
- if (!instances.TryGetValue (element, out pc)) {
+ if (!module.ReferenceTypesCache.TryGetValue (element, out pc)) {
pc = new ReferenceContainer (element);
- instances.Add (element, pc);
+ module.ReferenceTypesCache.Add (element, pc);
}
return pc;
}
-
- public static void Reset ()
- {
- instances = new Dictionary<TypeSpec, ReferenceContainer> ();
- }
}
class PointerContainer : ElementTypeSpec
{
- static Dictionary<TypeSpec, PointerContainer> instances = new Dictionary<TypeSpec, PointerContainer> ();
-
private PointerContainer (TypeSpec element)
: base (MemberKind.PointerType, element, null)
{
state &= ~StateFlags.CLSCompliant_Undetected;
}
- public override Type GetMetaInfo ()
+ public override MetaType GetMetaInfo ()
{
if (info == null) {
info = Element.GetMetaInfo ().MakePointerType ();
return "*";
}
- public static PointerContainer MakeType (TypeSpec element)
+ public static PointerContainer MakeType (ModuleContainer module, TypeSpec element)
{
PointerContainer pc;
- if (!instances.TryGetValue (element, out pc)) {
+ if (!module.PointerTypesCache.TryGetValue (element, out pc)) {
pc = new PointerContainer (element);
- instances.Add (element, pc);
+ module.PointerTypesCache.Add (element, pc);
}
return pc;
}
-
- public static void Reset ()
- {
- instances = new Dictionary<TypeSpec, PointerContainer> ();
- }
}
}