namespace Mono.CSharp {
-public class TypeManager {
+public partial class TypeManager {
//
// A list of core types that the compiler requires or uses
//
static public Type delegate_type;
static public Type multicast_delegate_type;
static public Type void_type;
+ static public Type null_type;
static public Type enumeration_type;
static public Type array_type;
static public Type runtime_handle_type;
static public Type runtime_argument_handle_type;
static public Type attribute_type;
static public Type attribute_usage_type;
+ static public Type decimal_constant_attribute_type;
static public Type dllimport_type;
static public Type unverifiable_code_type;
static public Type methodimpl_attr_type;
static public Type marshal_as_attr_type;
- static public Type new_constraint_attr_type;
static public Type param_array_type;
- static public Type guid_attr_type;
static public Type void_ptr_type;
static public Type indexer_name_type;
static public Type exception_type;
- static public Type activator_type;
static public Type invalid_operation_exception_type;
static public Type not_supported_exception_type;
static public Type obsolete_attribute_type;
static public Type conditional_attribute_type;
static public Type in_attribute_type;
+ static public Type out_attribute_type;
static public Type anonymous_method_type;
static public Type cls_compliant_attribute_type;
static public Type typed_reference_type;
static public Type struct_layout_attribute_type;
static public Type field_offset_attribute_type;
static public Type security_attr_type;
+ static public Type required_attr_type;
- static public Type generic_ienumerator_type;
- static public Type generic_ienumerable_type;
+ ///
+ /// .NET 2.0
+ ///
+ static internal Type compiler_generated_attr_type;
+ static internal Type fixed_buffer_attr_type;
+ static internal Type default_charset_type;
//
// An empty array of types
static public MethodInfo int_array_get_lower_bound_int;
static public MethodInfo int_array_get_upper_bound_int;
static public MethodInfo void_array_copyto_array_int;
- static public MethodInfo activator_create_instance;
//
// The attribute constructors.
static public ConstructorInfo object_ctor;
static public ConstructorInfo cons_param_array_attribute;
static public ConstructorInfo void_decimal_ctor_five_args;
+ static public ConstructorInfo void_decimal_ctor_int_arg;
static public ConstructorInfo unverifiable_code_ctor;
- static public ConstructorInfo invalid_operation_ctor;
static public ConstructorInfo default_member_ctor;
+ static public ConstructorInfo decimal_constant_attribute_ctor;
+ static internal ConstructorInfo struct_layout_attribute_ctor;
+ static public ConstructorInfo field_offset_attribute_ctor;
+ ///
+ /// A new in C# 2.0
+ ///
+ static internal CustomAttributeBuilder compiler_generated_attr;
+ static internal ConstructorInfo fixed_buffer_attr_ctor;
+
// <remarks>
// Holds the Array of Assemblies that have been loaded
// (either because it is the default or the user used the
static PtrHashtable builder_to_declspace;
+ static PtrHashtable builder_to_member_cache;
+
// <remarks>
// Tracks the interfaces implemented by typebuilders. We only
// enter those who do implement or or more interfaces
// </remarks>
static PtrHashtable builder_to_ifaces;
- // <remarks>
- // Tracks the generic parameters.
- // </remarks>
- static PtrHashtable builder_to_type_param;
-
// <remarks>
// Maps MethodBase.RuntimeTypeHandle to a Type array that contains
// the arguments to the method
static Hashtable indexer_arguments;
// <remarks>
- // Maybe `method_arguments' should be replaced and only
- // method_internal_params should be kept?
+ // Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
// <remarks>
- static Hashtable method_internal_params;
+ static Hashtable method_params;
// <remarks>
// Keeps track of methods
// </remarks>
public static Hashtable all_imported_types;
+ static Hashtable fieldbuilders_to_fields;
+ static Hashtable fields;
+
struct Signature {
public string name;
public Type [] args;
typecontainers = null;
user_types = null;
builder_to_declspace = null;
+ builder_to_member_cache = null;
builder_to_ifaces = null;
method_arguments = null;
indexer_arguments = null;
- method_internal_params = null;
+ method_params = null;
builder_to_method = null;
- builder_to_type_param = null;
fields = null;
- references = null;
- negative_hits = null;
builder_to_constant = null;
fieldbuilders_to_fields = null;
events = null;
priv_fields_events = null;
properties = null;
+
+ type_hash = null;
+ CleanUpGenerics ();
TypeHandle.CleanUp ();
}
}
static TypeManager ()
+ {
+ Reset ();
+
+ signature_filter = new MemberFilter (SignatureFilter);
+ InitExpressionTypes ();
+ InitGenerics ();
+ }
+
+ static public void Reset ()
{
assemblies = new Assembly [0];
modules = null;
typecontainers = new Hashtable ();
builder_to_declspace = new PtrHashtable ();
+ builder_to_member_cache = new PtrHashtable ();
builder_to_method = new PtrHashtable ();
method_arguments = new PtrHashtable ();
- method_internal_params = new PtrHashtable ();
+ method_params = new PtrHashtable ();
indexer_arguments = new PtrHashtable ();
builder_to_ifaces = new PtrHashtable ();
- builder_to_type_param = new PtrHashtable ();
NoTypes = new Type [0];
NoTypeExprs = new TypeExpr [0];
- signature_filter = new MemberFilter (SignatureFilter);
- InitExpressionTypes ();
+ fieldbuilders_to_fields = new Hashtable ();
+ fields = new Hashtable ();
+ type_hash = new DoubleHash ();
}
public static void HandleDuplicate (string name, Type t)
} catch {
HandleDuplicate (name, t);
}
+
user_types.Add (t);
}
return (IMethodData) builder_to_method [builder];
}
- public static void AddTypeParameter (Type t, TypeParameter tparam)
- {
- if (!builder_to_type_param.Contains (t))
- builder_to_type_param.Add (t, tparam);
- }
-
/// <summary>
/// Returns the DeclSpace whose Type is `t' or null if there is no
/// DeclSpace for `t' (ie, the Type comes from a library)
return builder_to_declspace [t] as TypeContainer;
}
- public static TypeContainer LookupGenericTypeContainer (Type t)
- {
- while (t.IsGenericInstance)
- t = t.GetGenericTypeDefinition ();
-
- return LookupTypeContainer (t);
- }
-
- /// <summary>
- /// Fills member container from base interfaces
- /// </summary>
- public static IMemberContainer LookupInterfaceContainer (Type[] types)
- {
- if (types == null)
- return null;
-
- IMemberContainer complete = null;
- foreach (Type t in types) {
- IMemberContainer one_type_cont = null;
- if (t is TypeBuilder) {
- one_type_cont = builder_to_declspace [t] as IMemberContainer;
- } else
- one_type_cont = TypeHandle.GetTypeHandle (t);
-
- if (complete == null) {
- complete = one_type_cont;
- continue;
- }
-
- // We need to avoid including same member more than once
- foreach (DictionaryEntry de in one_type_cont.MemberCache.Members) {
- object o = complete.MemberCache.Members [de.Key];
- if (o == null) {
- complete.MemberCache.Members.Add (de.Key, de.Value);
- continue;
- }
-
- ArrayList al_old = (ArrayList)o;
- ArrayList al_new = (ArrayList)de.Value;
-
- foreach (MemberCache.CacheEntry ce in al_new) {
- bool exist = false;
- foreach (MemberCache.CacheEntry ce_old in al_old) {
- if (ce.Member == ce_old.Member) {
- exist = true;
- break;
- }
- }
- if (!exist)
- al_old.Add (ce);
- }
- }
- }
- return complete;
- }
-
- public static IMemberContainer LookupMemberContainer (Type t)
+ public static MemberCache LookupMemberCache (Type t)
{
if (t is TypeBuilder) {
IMemberContainer container = builder_to_declspace [t] as IMemberContainer;
if (container != null)
- return container;
+ return container.MemberCache;
}
if (t is GenericTypeParameterBuilder) {
IMemberContainer container = builder_to_type_param [t] as IMemberContainer;
if (container != null)
- return container;
+ return container.MemberCache;
}
- return TypeHandle.GetTypeHandle (t);
+ return TypeHandle.GetMemberCache (t);
+ }
+
+ public static MemberCache LookupBaseInterfacesCache (Type t)
+ {
+ Type [] ifaces = t.GetInterfaces ();
+
+ if (ifaces != null && ifaces.Length == 1)
+ return LookupMemberCache (ifaces [0]);
+
+ // TODO: the builder_to_member_cache should be indexed by 'ifaces', not 't'
+ MemberCache cache = builder_to_member_cache [t] as MemberCache;
+ if (cache != null)
+ return cache;
+
+ cache = new MemberCache (ifaces);
+ builder_to_member_cache.Add (t, cache);
+ return cache;
}
public static TypeContainer LookupInterface (Type t)
{
return (Class) builder_to_declspace [t];
}
-
- public static TypeParameter LookupTypeParameter (Type t)
- {
- return (TypeParameter) builder_to_type_param [t];
- }
-
- public static bool HasConstructorConstraint (Type t)
- {
- GenericConstraints gc = GetTypeParameterConstraints (t);
- if (gc == null)
- return false;
-
- return (gc.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
- }
-
- public static GenericConstraints GetTypeParameterConstraints (Type t)
- {
- if (!t.IsGenericParameter)
- throw new InvalidOperationException ();
-
- TypeParameter tparam = LookupTypeParameter (t);
- if (tparam != null)
- return tparam.GenericConstraints;
-
- return new ReflectionConstraints (t);
- }
/// <summary>
/// Registers an assembly to load types from.
}
}
- static Hashtable references = new Hashtable ();
-
+ //
+ // We use this hash for multiple kinds of constructed types:
+ //
+ // (T, "&") Given T, get T &
+ // (T, "*") Given T, get T *
+ // (T, "[]") Given T and a array dimension, get T []
+ // (T, X) Given a type T and a simple name X, get the type T+X
+ //
+ // Accessibility tests, if necessary, should be done by the user
+ //
+ static DoubleHash type_hash = new DoubleHash ();
+
//
// Gets the reference to T version of the Type (T&)
//
return t.MakeByRefType ();
}
- static Hashtable pointers = new Hashtable ();
-
//
// Gets the pointer to T version of the Type (T*)
//
public static Type GetPointerType (Type t)
{
- string tname = t.FullName + "*";
-
- Type ret = t.Assembly.GetType (tname);
-
- //
- // If the type comes from the assembly we are building
- // We need the Hashtable, because .NET 1.1 will return different instance types
- // every time we call ModuleBuilder.GetType.
- //
- if (ret == null){
- if (pointers [t] == null)
- pointers [t] = CodeGen.Module.Builder.GetType (tname);
-
- ret = (Type) pointers [t];
+ return GetConstructedType (t, "*");
+ }
+
+ public static Type GetConstructedType (Type t, string dim)
+ {
+ object ret = null;
+ if (type_hash.Lookup (t, dim, out ret))
+ return (Type) ret;
+
+ ret = t.Module.GetType (t.ToString () + dim);
+ if (ret != null) {
+ type_hash.Insert (t, dim, ret);
+ return (Type) ret;
}
- return ret;
+ if (dim == "&") {
+ ret = GetReferenceType (t);
+ type_hash.Insert (t, dim, ret);
+ return (Type) ret;
+ }
+
+ if (t.IsGenericParameter || t.IsGenericInstance) {
+ int pos = 0;
+ Type result = t;
+ while ((pos < dim.Length) && (dim [pos] == '[')) {
+ pos++;
+
+ if (dim [pos] == ']') {
+ result = result.MakeArrayType ();
+ pos++;
+
+ if (pos < dim.Length)
+ continue;
+
+ type_hash.Insert (t, dim, result);
+ return result;
+ }
+
+ int rank = 0;
+ while (dim [pos] == ',') {
+ pos++; rank++;
+ }
+
+ if ((dim [pos] != ']') || (pos != dim.Length-1))
+ break;
+
+ result = result.MakeArrayType (rank + 1);
+ type_hash.Insert (t, dim, result);
+ return result;
+ }
+ }
+
+ type_hash.Insert (t, dim, null);
+ return null;
+ }
+
+ public static Type GetNestedType (Type t, string name)
+ {
+ object ret = null;
+ if (!type_hash.Lookup (t, name, out ret)) {
+ string lookup = t.FullName + "+" + name;
+ ret = t.Module.GetType (lookup);
+ type_hash.Insert (t, name, ret);
+ }
+ return (Type) ret;
}
//
// Low-level lookup, cache-less
//
- static Type LookupTypeReflection (string name)
+ public static Type LookupTypeReflection (string name)
{
Type t;
return null;
}
- static Hashtable negative_hits = new Hashtable ();
-
- //
- // This function is used when you want to avoid the lookups, and want to go
- // directly to the source. This will use the cache.
- //
- // Notice that bypassing the cache is bad, because on Microsoft.NET runtime
- // GetType ("DynamicType[]") != GetType ("DynamicType[]"), and there is no
- // way to test things other than doing a fullname compare
- //
- public static Type LookupTypeDirect (string name)
- {
- Type t = (Type) types [name];
- if (t != null)
- return t;
-
- t = LookupTypeReflection (name);
- if (t == null)
- return null;
-
- types [name] = t;
- return t;
- }
-
- static readonly char [] dot_array = { '.' };
-
- /// <summary>
- /// Returns the Type associated with @name, takes care of the fact that
- /// reflection expects nested types to be separated from the main type
- /// with a "+" instead of a "."
- /// </summary>
- public static Type LookupType (string name)
- {
- Type t;
-
- //
- // First lookup in user defined and cached values
- //
-
- t = (Type) types [name];
- if (t != null)
- return t;
-
- // Two thirds of the failures are caught here.
- if (negative_hits.Contains (name))
- return null;
-
- // Sadly, split takes a param array, so this ends up allocating *EVERY TIME*
- string [] elements = name.Split (dot_array);
- int count = elements.Length;
-
- for (int n = 1; n <= count; n++){
- string top_level_type = String.Join (".", elements, 0, n);
-
- // One third of the failures are caught here.
- if (negative_hits.Contains (top_level_type))
- continue;
-
- t = (Type) types [top_level_type];
- if (t == null){
- t = LookupTypeReflection (top_level_type);
- if (t == null){
- negative_hits [top_level_type] = null;
- continue;
- }
- }
-
- if (count == n){
- types [name] = t;
- return t;
- }
-
- //
- // We know that System.Object does not have children, and since its the parent of
- // all the objects, it always gets probbed for inner classes.
- //
- if (top_level_type == "System.Object")
- return null;
-
- string newt = top_level_type + "+" + String.Join ("+", elements, n, count - n);
- //Console.WriteLine ("Looking up: " + newt + " " + name);
- t = LookupTypeReflection (newt);
- if (t == null)
- negative_hits [name] = null;
- else
- types [name] = t;
- return t;
- }
- negative_hits [name] = null;
- return null;
- }
-
/// <summary>
/// Computes the namespaces that we import from the assemblies we reference.
/// </summary>
{
MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic);
+ Hashtable cache = null;
+
//
// First add the assembly namespaces
//
}
}
} else {
- Hashtable cache = new Hashtable ();
+ cache = new Hashtable ();
cache.Add ("", null);
foreach (Assembly a in assemblies) {
foreach (Type t in a.GetExportedTypes ()) {
}
}
}
+
+ //
+ // Then add module namespaces
+ //
+ foreach (Module m in modules) {
+ if (m == CodeGen.Module.Builder)
+ continue;
+ if (cache == null) {
+ cache = new Hashtable ();
+ cache.Add ("", null);
+ }
+ foreach (Type t in m.GetTypes ()) {
+ string ns = t.Namespace;
+ if (ns == null || cache.Contains (ns))
+ continue;
+ Namespace.LookupNamespace (ns, true);
+ cache.Add (ns, null);
+ }
+ }
}
/// <summary>
@"Single|Double|Char|Decimal|Byte|SByte|Object|" +
@"Boolean|String|Void|Null)" +
@"(\W+|\b)",
- new MatchEvaluator (CSharpNameMatch));
+ new MatchEvaluator (CSharpNameMatch)).Replace ('+', '.');
}
+
+ static public string CSharpName (Type[] types)
+ {
+ StringBuilder sb = new StringBuilder ();
+ foreach (Type t in types) {
+ sb.Append (CSharpName (t));
+ sb.Append (',');
+ }
+ sb.Remove (sb.Length - 1, 1);
+ return sb.ToString ();
+ }
static String CSharpNameMatch (Match match)
{
/// </summary>
static public string GetFullNameSignature (MemberInfo mi)
{
- return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
+ // Unfortunately, there's no dynamic dispatch on the arguments of a function.
+ return (mi is MethodBase)
+ ? GetFullNameSignature (mi as MethodBase)
+ : mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
}
static public string GetFullNameSignature (MethodBase mb)
return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name;
}
- static public string GetFullName (Type t)
+ private static void GetFullName_recursed (StringBuilder sb, Type t, bool recursed)
{
- if (t.FullName == null)
- return t.Name;
-
- string name = t.FullName.Replace ('+', '.');
+ if (t.IsGenericParameter) {
+ sb.Append (t.Name);
+ return;
+ }
- DeclSpace tc = LookupDeclSpace (t);
- if ((tc != null) && tc.IsGeneric) {
- TypeParameter[] tparam = tc.TypeParameters;
+ if (t.DeclaringType != null) {
+ GetFullName_recursed (sb, t.DeclaringType, true);
+ sb.Append (".");
+ }
- StringBuilder sb = new StringBuilder (name);
- sb.Append ("<");
- for (int i = 0; i < tparam.Length; i++) {
- if (i > 0)
- sb.Append (",");
- sb.Append (tparam [i].Name);
+ if (!recursed) {
+ string ns = t.Namespace;
+ if ((ns != null) && (ns != "")) {
+ sb.Append (ns);
+ sb.Append (".");
}
- sb.Append (">");
- return sb.ToString ();
- } else if (t.HasGenericArguments && !t.IsGenericInstance) {
- Type[] tparam = t.GetGenericArguments ();
+ }
- StringBuilder sb = new StringBuilder (name);
+ sb.Append (SimpleName.RemoveGenericArity (t.Name));
+
+ Type[] args = GetTypeArguments (t);
+ if (args.Length > 0) {
sb.Append ("<");
- for (int i = 0; i < tparam.Length; i++) {
+ for (int i = 0; i < args.Length; i++) {
if (i > 0)
sb.Append (",");
- sb.Append (tparam [i].Name);
+ sb.Append (GetFullName (args [i]));
}
sb.Append (">");
- return sb.ToString ();
}
+ }
- return name;
+ static public string GetFullName (Type t)
+ {
+ StringBuilder sb = new StringBuilder ();
+ GetFullName_recursed (sb, t, false);
+ return sb.ToString ();
}
/// <summary>
MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true);
string signature = GetFullNameSignature (mb);
- string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0);
+ string arg = GetParameterData (mb).ParameterDesc (0);
return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg);
}
{
StringBuilder sig = new StringBuilder ("(");
- //
- // FIXME: We should really have a single function to do
- // everything instead of the following 5 line pattern
- //
- ParameterData iparams = LookupParametersByBuilder (mb);
+ ParameterData iparams = GetParameterData (mb);
- if (iparams == null)
- iparams = new ReflectionParameters (mb);
-
// Is property
if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor)
return GetFullNameSignature (mb);
return GetFullNameSignature (mb) + sig.ToString ();
}
+ public static string GetMethodName (MethodInfo m)
+ {
+ if (!IsGenericMethod (m))
+ return m.Name;
+
+ return MemberName.MakeName (m.Name, m.GetGenericArguments ().Length);
+ }
+
/// <summary>
/// Looks up a type, and aborts if it is not found. This is used
/// by types required by the compiler
/// </summary>
static Type CoreLookupType (string name)
{
- Type t = LookupTypeDirect (name);
+ Type t = null;
+ if (types.Contains (name))
+ t = (Type) types [name];
+ else
+ t = LookupTypeReflection (name);
- if (t == null){
+ if (t == null)
Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
- Environment.Exit (1);
- }
+ types [name] = t;
return t;
}
/// <summary>
/// Returns the ConstructorInfo for "args"
/// </summary>
- static ConstructorInfo GetConstructor (Type t, Type [] args)
+ public static ConstructorInfo GetConstructor (Type t, Type [] args)
{
MemberList list;
Signature sig;
dllimport_type = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute");
methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute");
marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices.MarshalAsAttribute");
- new_constraint_attr_type = CoreLookupType ("System.Runtime.CompilerServices.NewConstraintAttribute");
param_array_type = CoreLookupType ("System.ParamArrayAttribute");
in_attribute_type = CoreLookupType ("System.Runtime.InteropServices.InAttribute");
+ out_attribute_type = CoreLookupType ("System.Runtime.InteropServices.OutAttribute");
typed_reference_type = CoreLookupType ("System.TypedReference");
arg_iterator_type = CoreLookupType ("System.ArgIterator");
mbr_type = CoreLookupType ("System.MarshalByRefObject");
-
- //
- // Sigh. Remove this before the release. Wonder what versions of Mono
- // people are running.
- //
- guid_attr_type = LookupType ("System.Runtime.InteropServices.GuidAttribute");
+ decimal_constant_attribute_type = CoreLookupType ("System.Runtime.CompilerServices.DecimalConstantAttribute");
unverifiable_code_type= CoreLookupType ("System.Security.UnverifiableCodeAttribute");
indexer_name_type = CoreLookupType ("System.Runtime.CompilerServices.IndexerNameAttribute");
exception_type = CoreLookupType ("System.Exception");
- activator_type = CoreLookupType ("System.Activator");
invalid_operation_exception_type = CoreLookupType ("System.InvalidOperationException");
not_supported_exception_type = CoreLookupType ("System.NotSupportedException");
struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute");
field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute");
security_attr_type = CoreLookupType ("System.Security.Permissions.SecurityAttribute");
+ required_attr_type = CoreLookupType ("System.Runtime.CompilerServices.RequiredAttributeAttribute");
+
+ InitGenericCoreTypes ();
//
- // Generic types
+ // .NET 2.0
//
- generic_ienumerator_type = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerator", 1));
- generic_ienumerable_type = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerable", 1));
-
-
+ compiler_generated_attr_type = CoreLookupType ("System.Runtime.CompilerServices.CompilerGeneratedAttribute");
+ fixed_buffer_attr_type = CoreLookupType ("System.Runtime.CompilerServices.FixedBufferAttribute");
+ default_charset_type = CoreLookupType ("System.Runtime.InteropServices.DefaultCharSetAttribute");
//
// When compiling corlib, store the "real" types here.
//
// These are only used for compare purposes
//
anonymous_method_type = typeof (AnonymousMethod);
+ null_type = typeof (NullType);
}
//
Type [] string_string_string_string = { string_type, string_type, string_type, string_type };
string_concat_string_string_string_string = GetMethod (
string_type, "Concat", string_string_string_string);
- Type[] params_string = { TypeManager.LookupType ("System.String[]") };
+ Type[] params_string = { GetConstructedType (string_type, "[]") };
string_concat_string_dot_dot_dot = GetMethod (
string_type, "Concat", params_string);
Type [] object_object_object = { object_type, object_type, object_type };
string_concat_object_object_object = GetMethod (
string_type, "Concat", object_object_object);
- Type[] params_object = { TypeManager.LookupType ("System.Object[]") };
+ Type[] params_object = { GetConstructedType (object_type, "[]") };
string_concat_object_dot_dot_dot = GetMethod (
string_type, "Concat", params_object);
void_decimal_ctor_five_args = GetConstructor (
decimal_type, dec_arg);
+ void_decimal_ctor_int_arg = GetConstructor (decimal_type, int_arg);
+
//
// Attributes
//
- cons_param_array_attribute = GetConstructor (
- param_array_type, void_arg);
+ cons_param_array_attribute = GetConstructor (param_array_type, void_arg);
+ unverifiable_code_ctor = GetConstructor (unverifiable_code_type, void_arg);
+ default_member_ctor = GetConstructor (default_member_type, string_);
- unverifiable_code_ctor = GetConstructor (
- unverifiable_code_type, void_arg);
+ Type[] short_arg = { short_type };
+ struct_layout_attribute_ctor = GetConstructor (struct_layout_attribute_type, short_arg);
- default_member_ctor = GetConstructor (default_member_type, string_);
+ decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type []
+ { byte_type, byte_type, uint32_type, uint32_type, uint32_type } );
+
+ field_offset_attribute_ctor = GetConstructor (field_offset_attribute_type, new Type []
+ { int32_type });
//
- // InvalidOperationException
+ // .NET 2.0 types
//
- invalid_operation_ctor = GetConstructor (
- invalid_operation_exception_type, void_arg);
+ compiler_generated_attr = new CustomAttributeBuilder (
+ GetConstructor (compiler_generated_attr_type, void_arg), new object[0]);
+ Type[] type_int_arg = { type_type, int32_type };
+ fixed_buffer_attr_ctor = GetConstructor (fixed_buffer_attr_type, type_int_arg);
// Object
object_ctor = GetConstructor (object_type, void_arg);
- // Activator
- Type [] type_arg = { type_type };
- activator_create_instance = GetMethod (
- activator_type, "CreateInstance", type_arg);
+ InitGenericCodeHelpers ();
}
const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
string name, out bool used_cache)
{
+ MemberCache cache;
+
//
// We have to take care of arrays specially, because GetType on
// a TypeBuilder array will return a Type, not a TypeBuilder,
//
if (t is TypeBuilder) {
DeclSpace decl = (DeclSpace) builder_to_declspace [t];
- MemberCache cache = decl.MemberCache;
+ cache = decl.MemberCache;
//
// If this DeclSpace has a MemberCache, use it.
//
// This call will always succeed. There is exactly one TypeHandle instance per
- // type, TypeHandle.GetTypeHandle() will either return it or create a new one
- // if it didn't already exist.
+ // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return
+ // the corresponding MemberCache.
//
- TypeHandle handle = TypeHandle.GetTypeHandle (t);
+ cache = TypeHandle.GetMemberCache (t);
used_cache = true;
- return handle.MemberCache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
+ return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
}
public static bool IsBuiltinType (Type t)
// This is like IsBuiltinType, but lacks decimal_type, we should also clean up
// the pieces in the code where we use IsBuiltinType and special case decimal_type.
//
- public static bool IsCLRType (Type t)
+ public static bool IsPrimitiveType (Type t)
{
- if (t == object_type || t == int32_type || t == uint32_type ||
+ return (t == int32_type || t == uint32_type ||
t == int64_type || t == uint64_type || t == float_type || t == double_type ||
t == char_type || t == short_type || t == bool_type ||
- t == sbyte_type || t == byte_type || t == ushort_type)
- return true;
- else
- return false;
+ t == sbyte_type || t == byte_type || t == ushort_type);
}
public static bool IsDelegateType (Type t)
return false;
}
- //
- // Only a quick hack to get things moving, while real runtime support appears
- //
- public static bool IsGeneric (Type t)
- {
- DeclSpace ds = (DeclSpace) builder_to_declspace [t];
-
- return ds.IsGeneric;
- }
-
- public static bool HasGenericArguments (Type t)
+ public static bool IsNullType (Type t)
{
- return GetNumberOfTypeArguments (t) > 0;
- }
-
- public static int GetNumberOfTypeArguments (Type t)
- {
- DeclSpace tc = LookupDeclSpace (t);
- if (tc != null)
- return tc.IsGeneric ? tc.CountTypeParameters : 0;
- else
- return t.HasGenericArguments ? t.GetGenericArguments ().Length : 0;
- }
-
- public static Type[] GetTypeArguments (Type t)
- {
- DeclSpace tc = LookupDeclSpace (t);
- if (tc != null) {
- if (!tc.IsGeneric)
- throw new InvalidOperationException ();
-
- TypeParameter[] tparam = tc.TypeParameters;
- Type[] ret = new Type [tparam.Length];
- for (int i = 0; i < tparam.Length; i++) {
- ret [i] = tparam [i].Type;
- if (ret [i] == null)
- throw new InternalErrorException ();
- }
-
- return ret;
- } else
- return t.GetGenericArguments ();
+ return t == null_type;
}
//
//
public static bool IsUnmanagedType (Type t)
{
- if (IsBuiltinType (t) && t != TypeManager.string_type)
- return true;
+ // builtins that are not unmanaged types
+ if (t == TypeManager.object_type || t == TypeManager.string_type)
+ return false;
- if (IsEnumType (t))
+ if (IsBuiltinOrEnum (t))
return true;
+ // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it.
if (t.IsPointer)
return true;
- if (IsValueType (t)){
- if (t is TypeBuilder){
- TypeContainer tc = LookupTypeContainer (t);
+ // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)]
+ if (t.IsArray)
+ return false;
- if (tc.Fields != null){
- foreach (Field f in tc.Fields){
- if (f.FieldBuilder.IsStatic)
- continue;
- if (!IsUnmanagedType (f.FieldBuilder.FieldType))
- return false;
- }
- } else
- return true;
- } else {
- FieldInfo [] fields = t.GetFields ();
+ if (!IsValueType (t))
+ return false;
- foreach (FieldInfo f in fields){
- if (f.IsStatic)
- continue;
- if (!IsUnmanagedType (f.FieldType))
- return false;
+ if (t is TypeBuilder){
+ TypeContainer tc = LookupTypeContainer (t);
+ if (tc.Fields == null)
+ return true;
+ foreach (Field f in tc.Fields){
+ // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked.
+ if ((f.ModFlags & Modifiers.STATIC) != 0)
+ continue;
+ if (f.MemberType == null)
+ continue;
+ if (!IsUnmanagedType (f.MemberType)){
+ Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name);
+ return false;
}
}
return true;
}
+
+ FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
- return false;
+ foreach (FieldInfo f in fields){
+ if (!IsUnmanagedType (f.FieldType)){
+ Report.SymbolRelatedToPreviousError (f);
+ return false;
+ }
+ }
+
+ return true;
}
public static bool IsValueType (Type t)
return tc.Kind == Kind.Interface;
}
- public static bool IsEqual (Type a, Type b)
- {
- if (a.Equals (b))
- return true;
-
- if ((a is TypeBuilder) && a.IsGenericTypeDefinition && b.IsGenericInstance) {
- //
- // `a' is a generic type definition's TypeBuilder and `b' is a
- // generic instance of the same type.
- //
- // Example:
- //
- // class Stack<T>
- // {
- // void Test (Stack<T> stack) { }
- // }
- //
- // The first argument of `Test' will be the generic instance
- // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
- //
- //
- // We hit this via Closure.Filter() for gen-82.cs.
- //
- if (a != b.GetGenericTypeDefinition ())
- return false;
-
- Type[] aparams = a.GetGenericArguments ();
- Type[] bparams = b.GetGenericArguments ();
-
- if (aparams.Length != bparams.Length)
- return false;
-
- for (int i = 0; i < aparams.Length; i++)
- if (!IsEqual (aparams [i], bparams [i]))
- return false;
-
- return true;
- }
-
- if (a.IsGenericParameter && b.IsGenericParameter) {
- if ((a.DeclaringMethod == null) || (b.DeclaringMethod == null))
- return false;
- return a.GenericParameterPosition == b.GenericParameterPosition;
- }
-
- if (a.IsArray && b.IsArray) {
- if (a.GetArrayRank () != b.GetArrayRank ())
- return false;
- return IsEqual (a.GetElementType (), b.GetElementType ());
- }
-
- if (a.IsGenericInstance && b.IsGenericInstance) {
- Type at = a.GetGenericTypeDefinition ();
- Type bt = b.GetGenericTypeDefinition ();
-
- if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
- return false;
-
- Type[] aargs = a.GetGenericArguments ();
- Type[] bargs = b.GetGenericArguments ();
-
- if (aargs.Length != bargs.Length)
- return false;
-
- for (int i = 0; i < aargs.Length; i++) {
- if (!IsEqual (aargs [i], bargs [i]))
- return false;
- }
-
- return true;
- }
-
- return false;
- }
-
- public static bool MayBecomeEqualGenericTypes (Type a, Type b)
- {
- if (a.IsGenericParameter) {
- //
- // If a is an array of a's type, they may never
- // become equal.
- //
- while (b.IsArray) {
- b = b.GetElementType ();
- if (a.Equals (b))
- return false;
- }
-
- //
- // If b is a generic parameter or an actual type,
- // they may become equal:
- //
- // class X<T,U> : I<T>, I<U>
- // class X<T> : I<T>, I<float>
- //
- if (b.IsGenericParameter || !b.IsGenericInstance)
- return true;
-
- //
- // We're now comparing a type parameter with a
- // generic instance. They may become equal unless
- // the type parameter appears anywhere in the
- // generic instance:
- //
- // class X<T,U> : I<T>, I<X<U>>
- // -> error because you could instanciate it as
- // X<X<int>,int>
- //
- // class X<T> : I<T>, I<X<T>> -> ok
- //
-
- Type[] bargs = GetTypeArguments (b);
- for (int i = 0; i < bargs.Length; i++) {
- if (a.Equals (bargs [i]))
- return false;
- }
-
- return true;
- }
-
- if (b.IsGenericParameter)
- return MayBecomeEqualGenericTypes (b, a);
-
- //
- // At this point, neither a nor b are a type parameter.
- //
- // If one of them is a generic instance, let
- // MayBecomeEqualGenericInstances() compare them (if the
- // other one is not a generic instance, they can never
- // become equal).
- //
-
- if (a.IsGenericInstance || b.IsGenericInstance)
- return MayBecomeEqualGenericInstances (a, b);
-
- //
- // If both of them are arrays.
- //
-
- if (a.IsArray && b.IsArray) {
- if (a.GetArrayRank () != b.GetArrayRank ())
- return false;
-
- a = a.GetElementType ();
- b = b.GetElementType ();
-
- return MayBecomeEqualGenericTypes (a, b);
- }
-
- //
- // Ok, two ordinary types.
- //
-
- return a.Equals (b);
- }
-
- //
- // Checks whether two generic instances may become equal for some
- // particular instantiation (26.3.1).
- //
- public static bool MayBecomeEqualGenericInstances (Type a, Type b)
- {
- if (!a.IsGenericInstance || !b.IsGenericInstance)
- return false;
- if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
- return false;
-
- Type[] aargs = GetTypeArguments (a);
- Type[] bargs = GetTypeArguments (b);
-
- if (aargs.Length != bargs.Length)
- return false;
-
- for (int i = 0; i < aargs.Length; i++) {
- if (MayBecomeEqualGenericTypes (aargs [i], bargs [i]))
- return true;
- }
-
- return false;
- }
-
- public static bool IsEqualGenericInstance (Type type, Type parent)
- {
- int tcount = GetNumberOfTypeArguments (type);
- int pcount = GetNumberOfTypeArguments (parent);
-
- if (type.IsGenericInstance)
- type = type.GetGenericTypeDefinition ();
- if (parent.IsGenericInstance)
- parent = parent.GetGenericTypeDefinition ();
-
- if (tcount != pcount)
- return false;
-
- return type.Equals (parent);
- }
-
- public static bool IsSubclassOf (Type type, Type parent)
+ public static bool IsSubclassOf (Type type, Type base_type)
{
TypeParameter tparam = LookupTypeParameter (type);
- TypeParameter pparam = LookupTypeParameter (parent);
+ TypeParameter pparam = LookupTypeParameter (base_type);
if ((tparam != null) && (pparam != null)) {
if (tparam == pparam)
return true;
- return tparam.IsSubclassOf (parent);
+ return tparam.IsSubclassOf (base_type);
}
do {
- if (type.Equals (parent))
+ if (type.Equals (base_type))
return true;
type = type.BaseType;
}
if (type.IsGenericInstance && parent.IsGenericInstance) {
- Type tdef = type.GetGenericTypeDefinition ();
- Type pdef = parent.GetGenericTypeDefinition ();
-
if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ())
return false;
}
//
- // Checks whether `type' is a subclass or nested child of `parent'.
+ // Checks whether `type' is a subclass or nested child of `base_type'.
//
- public static bool IsNestedFamilyAccessible (Type type, Type parent)
+ public static bool IsNestedFamilyAccessible (Type type, Type base_type)
{
do {
- if (IsFamilyAccessible (type, parent))
+ if (IsFamilyAccessible (type, base_type))
return true;
// Handle nested types.
return TypeToCoreType (t.GetElementType ());
}
+ /// <summary>
+ /// This method is not implemented by MS runtime for dynamic types
+ /// </summary>
+ public static bool HasElementType (Type t)
+ {
+ return t.IsArray || t.IsPointer || t.IsByRef;
+ }
+
/// <summary>
/// Returns the User Defined Types
/// </summary>
args = NoTypes;
method_arguments.Add (mb, args);
- method_internal_params.Add (mb, ip);
+ method_params.Add (mb, ip);
}
- static public InternalParameters LookupParametersByBuilder (MethodBase mb)
+ static public ParameterData GetParameterData (MethodBase mb)
{
- if (! (mb is ConstructorBuilder || mb is MethodBuilder))
- return null;
-
- if (method_internal_params.Contains (mb))
- return (InternalParameters) method_internal_params [mb];
- else
- throw new Exception ("Argument for Method not registered" + mb);
+ object pd = method_params [mb];
+ if (pd == null) {
+ if (mb is MethodBuilder || mb is ConstructorBuilder)
+ throw new InternalErrorException ("Argument for Method not registered" + mb);
+
+ method_params [mb] = pd = new ReflectionParameters (mb);
+ }
+
+ return (ParameterData) pd;
}
/// <summary>
// This is a workaround the fact that GetValue is not
// supported for dynamic types
// </remarks>
- static Hashtable fields = new Hashtable ();
static public bool RegisterFieldValue (FieldBuilder fb, object value)
{
if (fields.Contains (fb))
return fields [fb];
}
- static Hashtable fieldbuilders_to_fields = new Hashtable ();
static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f)
{
if (fieldbuilders_to_fields.Contains (fb))
//
static public FieldBase GetField (FieldInfo fb)
{
+ if (fb.DeclaringType.IsGenericInstance)
+ fb = fb.Mono_GetGenericFieldDefinition ();
+
return (FieldBase) fieldbuilders_to_fields [fb];
}
if (tc.Fields == null)
return true;
- foreach (Field field in tc.Fields) {
- if (field.FieldBuilder.IsStatic)
+ foreach (FieldMember field in tc.Fields) {
+ if (field.FieldBuilder == null || field.FieldBuilder.IsStatic)
continue;
Type ftype = field.FieldBuilder.FieldType;
public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)
{
ArrayList new_ifaces = new ArrayList ();
-
+
foreach (TypeExpr iface in base_interfaces){
- Type itype = iface.ResolveType (ec);
- if (itype == null)
+ TypeExpr texpr = iface.ResolveAsTypeTerminal (ec);
+ if (texpr == null)
return null;
- if (!new_ifaces.Contains (itype))
- new_ifaces.Add (itype);
-
- Type [] implementing = itype.GetInterfaces ();
+ if (new_ifaces.Contains (texpr.Type))
+ continue;
+
+ new_ifaces.Add (texpr.Type);
+ Type [] implementing = texpr.Type.GetInterfaces ();
+
foreach (Type imp in implementing){
if (!new_ifaces.Contains (imp))
new_ifaces.Add (imp);
/// </summary>
public static Type [] GetInterfaces (Type t)
{
-
Type [] cached = iface_cache [t] as Type [];
if (cached != null)
return cached;
if (t.IsArray)
t = TypeManager.array_type;
- if (t is TypeBuilder){
- Type[] parent_ifaces;
+ if ((t is TypeBuilder) || t.IsGenericInstance) {
+ Type [] base_ifaces;
if (t.BaseType == null)
- parent_ifaces = NoTypes;
+ base_ifaces = NoTypes;
else
- parent_ifaces = GetInterfaces (t.BaseType);
- Type[] type_ifaces = (Type []) builder_to_ifaces [t];
+ base_ifaces = GetInterfaces (t.BaseType);
+ Type[] type_ifaces;
+ if (t.IsGenericInstance)
+ type_ifaces = t.GetInterfaces ();
+ else
+ type_ifaces = (Type []) builder_to_ifaces [t];
if (type_ifaces == null)
type_ifaces = NoTypes;
- int parent_count = parent_ifaces.Length;
- Type[] result = new Type [parent_count + type_ifaces.Length];
- parent_ifaces.CopyTo (result, 0);
- type_ifaces.CopyTo (result, parent_count);
+ int base_count = base_ifaces.Length;
+ Type [] result = new Type [base_count + type_ifaces.Length];
+ base_ifaces.CopyTo (result, 0);
+ type_ifaces.CopyTo (result, base_count);
iface_cache [t] = result;
return result;
// as soon as we hit a non-TypeBuiler in the interface
// chain, we could return, as the `Type.GetInterfaces'
// will return all the interfaces implement by the type
- // or its parents.
+ // or its bases.
//
do {
interfaces = GetInterfaces (t);
return (object)(convert_value.ToChar (nf_provider));
else if (conversionType.Equals (typeof (DateTime)))
return (object)(convert_value.ToDateTime (nf_provider));
- else if (conversionType.Equals (typeof (Decimal)))
+ else if (conversionType.Equals (TypeManager.decimal_type)) // typeof (Decimal)))
return (object)(convert_value.ToDecimal (nf_provider));
else if (conversionType.Equals (typeof (Double)))
return (object)(convert_value.ToDouble (nf_provider));
return TypeManager.int64_type;
case TypeCode.UInt64:
return TypeManager.uint64_type;
- case TypeCode.Single:
- return TypeManager.float_type;
- case TypeCode.Double:
- return TypeManager.double_type;
+ case TypeCode.Single:
+ return TypeManager.float_type;
+ case TypeCode.Double:
+ return TypeManager.double_type;
case TypeCode.String:
return TypeManager.string_type;
+ case TypeCode.Decimal:
+ return TypeManager.decimal_type;
default:
if (t == typeof (void))
return TypeManager.void_type;
/// </summary>
public static bool VerifyUnManaged (Type t, Location loc)
{
- if (t.IsValueType || t.IsPointer){
- //
- // FIXME: this is more complex, we actually need to
- // make sure that the type does not contain any
- // classes itself
- //
- return true;
- }
-
- if (!RootContext.StdLib && (t == TypeManager.decimal_type))
- // We need this explicit check here to make it work when
- // compiling corlib.
+ if (IsUnmanagedType (t))
return true;
Report.Error (
new Type [] { typeof (Type), typeof (bool)},
null);
if (declare_local_method == null){
- Report.Warning (-24, new Location (-1),
+ Report.Warning (-30, new Location (-1),
"This version of the runtime does not support making pinned local variables. " +
"This code may cause errors on a runtime with a moving GC");
return ig.DeclareLocal (t);
return target_list;
}
- static public bool IsGenericMethod (MethodBase mb)
- {
- if (mb.DeclaringType is TypeBuilder) {
- IMethodData method = (IMethodData) builder_to_method [mb];
- if (method == null)
- return false;
-
- return method.GenericMethod != null;
- }
-
- return mb.IsGenericMethodDefinition;
- }
-
#region MemberLookup implementation
//
internal Assembly invocation_assembly;
internal IList almost_match;
- private bool CheckValidFamilyAccess (bool is_static, MemberInfo m)
- {
- if (invocation_type == null)
- return false;
-
- if (is_static)
- return true;
-
- // A nested class has access to all the protected members visible
- // to its parent.
- if (qualifier_type != null
- && TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
- return true;
-
- if (invocation_type == m.DeclaringType
- || invocation_type.IsSubclassOf (m.DeclaringType)) {
- // Although a derived class can access protected members of
- // its base class it cannot do so through an instance of the
- // base class (CS1540).
- // => Ancestry should be: declaring_type ->* invocation_type
- // ->* qualified_type
- if (qualifier_type == null
- || qualifier_type == invocation_type
- || qualifier_type.IsSubclassOf (invocation_type))
- return true;
- }
-
- if (almost_match != null)
- almost_match.Add (m);
- return false;
- }
-
bool Filter (MethodBase mb, object filter_criteria)
{
MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
// works if we already used the cache in the first iteration of this loop.
//
// If we used the cache in any further iteration, we can still terminate the
- // loop since the cache always looks in all parent classes.
+ // loop since the cache always looks in all base classes.
//
if (used_cache)
/// There is exactly one instance of this class per type.
/// </summary>
public sealed class TypeHandle : IMemberContainer {
- public readonly TypeHandle BaseType;
+ public readonly IMemberContainer BaseType;
readonly int id = ++next_id;
static int next_id = 0;
+ static TypeHandle ()
+ {
+ Reset ();
+ }
+
/// <summary>
/// Lookup a TypeHandle instance for the given type. If the type doesn't have
/// a TypeHandle yet, a new instance of it is created. This static method
/// ensures that we'll only have one TypeHandle instance per type.
/// </summary>
- public static TypeHandle GetTypeHandle (Type t)
+ private static TypeHandle GetTypeHandle (Type t)
{
TypeHandle handle = (TypeHandle) type_hash [t];
if (handle != null)
type_hash.Add (t, handle);
return handle;
}
+
+ public static MemberCache GetMemberCache (Type t)
+ {
+ return GetTypeHandle (t).MemberCache;
+ }
public static void CleanUp ()
{
type_hash = null;
}
+ public static void Reset ()
+ {
+ type_hash = new PtrHashtable ();
+ }
+
/// <summary>
/// Returns the TypeHandle for TypeManager.object_type.
/// </summary>
}
}
- private static PtrHashtable type_hash = new PtrHashtable ();
+ private static PtrHashtable type_hash;
private static TypeHandle object_type = null;
private static TypeHandle array_type = null;
private string full_name;
private bool is_interface;
private MemberCache member_cache;
+ private MemberCache base_cache;
private TypeHandle (Type type)
{
this.type = type;
full_name = type.FullName != null ? type.FullName : type.Name;
- if (type.BaseType != null)
- BaseType = GetTypeHandle (type.BaseType);
+ if (type.BaseType != null) {
+ base_cache = TypeManager.LookupMemberCache (type.BaseType);
+ BaseType = base_cache.Container;
+ } else if (type.IsInterface)
+ base_cache = TypeManager.LookupBaseInterfacesCache (type);
this.is_interface = type.IsInterface || type.IsGenericParameter;
- this.member_cache = new MemberCache (this, true);
+ this.member_cache = new MemberCache (this);
}
// IMemberContainer methods
}
}
- public IMemberContainer ParentContainer {
+ public MemberCache BaseCache {
get {
- return BaseType;
+ return base_cache;
}
}