X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Ftypemanager.cs;h=7e08cc98e869e2dc961c620cfd63933cef7e337e;hb=2ce246b7a6ce1690c9c866a59b098c82442c0841;hp=3b58e641c870fdfcb98dbfcdbcd7c5585c27ab21;hpb=76716bfa3aef87dbf324016eaad111a7a4e74171;p=mono.git
diff --git a/mcs/gmcs/typemanager.cs b/mcs/gmcs/typemanager.cs
index 3b58e641c87..7e08cc98e86 100755
--- a/mcs/gmcs/typemanager.cs
+++ b/mcs/gmcs/typemanager.cs
@@ -63,48 +63,65 @@ public class TypeManager {
static public Type ienumerator_type;
static public Type ienumerable_type;
static public Type idisposable_type;
+ static public Type iconvertible_type;
static public Type default_member_type;
static public Type iasyncresult_type;
static public Type asynccallback_type;
static public Type intptr_type;
static public Type monitor_type;
static public Type runtime_field_handle_type;
+ static public Type runtime_argument_handle_type;
static public Type attribute_type;
static public Type attribute_usage_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 object obsolete_attribute_type;
- static public object conditional_attribute_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 cls_compliant_attribute_type;
+ static public Type typed_reference_type;
+ static public Type arg_iterator_type;
+ static public Type mbr_type;
+ static public Type struct_layout_attribute_type;
+ static public Type field_offset_attribute_type;
+
+ static public Type generic_ienumerator_type;
+ static public Type generic_ienumerable_type;
//
// An empty array of types
//
static public Type [] NoTypes;
+ static public TypeExpr [] NoTypeExprs;
//
// Expressions representing the internal types. Used during declaration
// definition.
//
- static public Expression system_object_expr, system_string_expr;
- static public Expression system_boolean_expr, system_decimal_expr;
- static public Expression system_single_expr, system_double_expr;
- static public Expression system_sbyte_expr, system_byte_expr;
- static public Expression system_int16_expr, system_uint16_expr;
- static public Expression system_int32_expr, system_uint32_expr;
- static public Expression system_int64_expr, system_uint64_expr;
- static public Expression system_char_expr, system_void_expr;
- static public Expression system_asynccallback_expr;
- static public Expression system_iasyncresult_expr;
+ static public TypeExpr system_object_expr, system_string_expr;
+ static public TypeExpr system_boolean_expr, system_decimal_expr;
+ static public TypeExpr system_single_expr, system_double_expr;
+ static public TypeExpr system_sbyte_expr, system_byte_expr;
+ static public TypeExpr system_int16_expr, system_uint16_expr;
+ static public TypeExpr system_int32_expr, system_uint32_expr;
+ static public TypeExpr system_int64_expr, system_uint64_expr;
+ static public TypeExpr system_char_expr, system_void_expr;
+ static public TypeExpr system_asynccallback_expr;
+ static public TypeExpr system_iasyncresult_expr;
+ static public TypeExpr system_valuetype_expr;
+ static public TypeExpr system_intptr_expr;
//
// This is only used when compiling corlib
@@ -133,7 +150,10 @@ public class TypeManager {
static public MethodInfo string_concat_string_string;
static public MethodInfo string_concat_string_string_string;
static public MethodInfo string_concat_string_string_string_string;
+ static public MethodInfo string_concat_string_dot_dot_dot;
static public MethodInfo string_concat_object_object;
+ static public MethodInfo string_concat_object_object_object;
+ static public MethodInfo string_concat_object_dot_dot_dot;
static public MethodInfo string_isinterneted_string;
static public MethodInfo system_type_get_type_from_handle;
static public MethodInfo object_getcurrent_void;
@@ -155,6 +175,7 @@ public class TypeManager {
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.
@@ -164,6 +185,7 @@ public class TypeManager {
static public ConstructorInfo void_decimal_ctor_five_args;
static public ConstructorInfo unverifiable_code_ctor;
static public ConstructorInfo invalid_operation_ctor;
+ static public ConstructorInfo default_member_ctor;
//
// Holds the Array of Assemblies that have been loaded
@@ -173,10 +195,10 @@ public class TypeManager {
static Assembly [] assemblies;
//
- // Keeps a list of module builders. We used this to do lookups
- // on the modulebuilder using GetType -- needed for arrays
+ // Keeps a list of modules. We used this to do lookups
+ // on the module using GetType -- needed for arrays
//
- static ModuleBuilder [] modules;
+ static Module [] modules;
//
// This is the type_cache from the assemblies to avoid
@@ -204,6 +226,11 @@ public class TypeManager {
//
static PtrHashtable builder_to_ifaces;
+ //
+ // Tracks the generic parameters.
+ //
+ static PtrHashtable builder_to_type_param;
+
//
// Maps MethodBase.RuntimeTypeHandle to a Type array that contains
// the arguments to the method
@@ -223,22 +250,50 @@ public class TypeManager {
static Hashtable method_internal_params;
//
- // Keeps track of attribute types
+ // Keeps track of methods
//
- static Hashtable builder_to_attr;
+ static Hashtable builder_to_method;
//
- // Keeps track of methods
+ // Contains all public types from referenced assemblies.
+ // This member is used only if CLS Compliance verification is required.
//
-
- static Hashtable builder_to_method;
+ public static Hashtable all_imported_types;
struct Signature {
public string name;
public Type [] args;
}
+ public static void CleanUp ()
+ {
+ // Lets get everything clean so that we can collect before generating code
+ assemblies = null;
+ modules = null;
+ types = null;
+ typecontainers = null;
+ user_types = null;
+ builder_to_declspace = null;
+ builder_to_ifaces = null;
+ method_arguments = null;
+ indexer_arguments = null;
+ method_internal_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;
+
+ TypeHandle.CleanUp ();
+ }
+
///
/// A filter for Findmembers that uses the Signature object to
/// extract objects
@@ -306,8 +361,10 @@ public class TypeManager {
system_void_expr = new TypeLookupExpression ("System.Void");
system_asynccallback_expr = new TypeLookupExpression ("System.AsyncCallback");
system_iasyncresult_expr = new TypeLookupExpression ("System.IAsyncResult");
+ system_valuetype_expr = new TypeLookupExpression ("System.ValueType");
+ system_intptr_expr = new TypeLookupExpression ("System.IntPtr");
}
-
+
static TypeManager ()
{
assemblies = new Assembly [0];
@@ -318,14 +375,15 @@ public class TypeManager {
typecontainers = new Hashtable ();
builder_to_declspace = new PtrHashtable ();
- builder_to_attr = new PtrHashtable ();
builder_to_method = new PtrHashtable ();
method_arguments = new PtrHashtable ();
method_internal_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 ();
@@ -344,7 +402,6 @@ public class TypeManager {
return;
}
- Location l;
tc = builder_to_declspace [t] as TypeContainer;
if (tc != null){
Report.Warning (
@@ -361,7 +418,7 @@ public class TypeManager {
types.Add (name, t);
}
- public static void AddUserType (string name, TypeBuilder t, Type [] ifaces)
+ public static void AddUserType (string name, TypeBuilder t)
{
try {
types.Add (name, t);
@@ -369,25 +426,22 @@ public class TypeManager {
HandleDuplicate (name, t);
}
user_types.Add (t);
-
- if (ifaces != null)
- builder_to_ifaces [t] = ifaces;
}
//
// This entry point is used by types that we define under the covers
//
- public static void RegisterBuilder (TypeBuilder tb, Type [] ifaces)
+ public static void RegisterBuilder (Type tb, Type [] ifaces)
{
if (ifaces != null)
builder_to_ifaces [tb] = ifaces;
}
- public static void AddUserType (string name, TypeBuilder t, TypeContainer tc, Type [] ifaces)
+ public static void AddUserType (string name, TypeBuilder t, TypeContainer tc)
{
builder_to_declspace.Add (t, tc);
typecontainers.Add (name, tc);
- AddUserType (name, t, ifaces);
+ AddUserType (name, t);
}
public static void AddDelegateType (string name, TypeBuilder t, Delegate del)
@@ -411,20 +465,20 @@ public class TypeManager {
builder_to_declspace.Add (t, en);
}
- public static void AddUserInterface (string name, TypeBuilder t, Interface i, Type [] ifaces)
+ public static void AddMethod (MethodBase builder, IMethodData method)
{
- AddUserType (name, t, ifaces);
- builder_to_declspace.Add (t, i);
+ builder_to_method.Add (builder, method);
}
- public static void AddMethod (MethodBuilder builder, MethodData method)
+ public static IMethodData GetMethod (MethodBase builder)
{
- builder_to_method.Add (builder, method);
+ return (IMethodData) builder_to_method [builder];
}
- public static void RegisterAttrType (Type t, TypeContainer tc)
+ public static void AddTypeParameter (Type t, TypeParameter tparam)
{
- builder_to_attr.Add (t, tc);
+ if (!builder_to_type_param.Contains (t))
+ builder_to_type_param.Add (t, tparam);
}
///
@@ -444,6 +498,14 @@ public class TypeManager {
{
return builder_to_declspace [t] as TypeContainer;
}
+
+ public static TypeContainer LookupGenericTypeContainer (Type t)
+ {
+ while (t.IsGenericInstance)
+ t = t.GetGenericTypeDefinition ();
+
+ return LookupTypeContainer (t);
+ }
public static IMemberContainer LookupMemberContainer (Type t)
{
@@ -453,12 +515,23 @@ public class TypeManager {
return container;
}
+ if (t is GenericTypeParameterBuilder) {
+ IMemberContainer container = builder_to_type_param [t] as IMemberContainer;
+
+ if (container != null)
+ return container;
+ }
+
return TypeHandle.GetTypeHandle (t);
}
- public static Interface LookupInterface (Type t)
+ public static TypeContainer LookupInterface (Type t)
{
- return builder_to_declspace [t] as Interface;
+ TypeContainer tc = (TypeContainer) builder_to_declspace [t];
+ if ((tc == null) || (tc.Kind != Kind.Interface))
+ return null;
+
+ return tc;
}
public static Delegate LookupDelegate (Type t)
@@ -471,9 +544,35 @@ public class TypeManager {
return builder_to_declspace [t] as Enum;
}
- public static TypeContainer LookupAttr (Type t)
+ public static Class LookupClass (Type t)
{
- return (TypeContainer) builder_to_attr [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);
}
///
@@ -481,6 +580,11 @@ public class TypeManager {
///
public static void AddAssembly (Assembly a)
{
+ foreach (Assembly assembly in assemblies) {
+ if (a == assembly)
+ return;
+ }
+
int top = assemblies.Length;
Assembly [] n = new Assembly [top + 1];
@@ -490,13 +594,18 @@ public class TypeManager {
assemblies = n;
}
+ public static Assembly [] GetAssemblies ()
+ {
+ return assemblies;
+ }
+
///
/// Registers a module builder to lookup types from
///
- public static void AddModule (ModuleBuilder mb)
+ public static void AddModule (Module mb)
{
int top = modules != null ? modules.Length : 0;
- ModuleBuilder [] n = new ModuleBuilder [top + 1];
+ Module [] n = new Module [top + 1];
if (modules != null)
modules.CopyTo (n, 0);
@@ -504,6 +613,12 @@ public class TypeManager {
modules = n;
}
+ public static Module[] Modules {
+ get {
+ return modules;
+ }
+ }
+
static Hashtable references = new Hashtable ();
//
@@ -511,22 +626,7 @@ public class TypeManager {
//
public static Type GetReferenceType (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 (references [t] == null)
- references [t] = CodeGen.ModuleBuilder.GetType (tname);
- ret = (Type) references [t];
- }
-
- return ret;
+ return t.MakeByRefType ();
}
static Hashtable pointers = new Hashtable ();
@@ -547,7 +647,7 @@ public class TypeManager {
//
if (ret == null){
if (pointers [t] == null)
- pointers [t] = CodeGen.ModuleBuilder.GetType (tname);
+ pointers [t] = CodeGen.Module.Builder.GetType (tname);
ret = (Type) pointers [t];
}
@@ -589,7 +689,7 @@ public class TypeManager {
} while (t != null);
}
- foreach (ModuleBuilder mb in modules) {
+ foreach (Module mb in modules) {
t = mb.GetType (name);
if (t != null)
return t;
@@ -622,6 +722,8 @@ public class TypeManager {
return t;
}
+ static readonly char [] dot_array = { '.' };
+
///
/// Returns the Type associated with @name, takes care of the fact that
/// reflection expects nested types to be separated from the main type
@@ -643,7 +745,8 @@ public class TypeManager {
if (negative_hits.Contains (name))
return null;
- string [] elements = name.Split ('.');
+ // 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++){
@@ -657,7 +760,7 @@ public class TypeManager {
if (t == null){
t = LookupTypeReflection (top_level_type);
if (t == null){
- negative_hits [top_level_type] = true;
+ negative_hits [top_level_type] = null;
continue;
}
}
@@ -678,12 +781,12 @@ public class TypeManager {
//Console.WriteLine ("Looking up: " + newt + " " + name);
t = LookupTypeReflection (newt);
if (t == null)
- negative_hits [name] = true;
+ negative_hits [name] = null;
else
types [name] = t;
return t;
}
- negative_hits [name] = true;
+ negative_hits [name] = null;
return null;
}
@@ -692,14 +795,13 @@ public class TypeManager {
///
public static void ComputeNamespaces ()
{
- MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces");
+ MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic);
//
// First add the assembly namespaces
//
if (assembly_get_namespaces != null){
int count = assemblies.Length;
- int total;
for (int i = 0; i < count; i++){
Assembly a = assemblies [i];
@@ -711,19 +813,35 @@ public class TypeManager {
}
}
} else {
- foreach (Assembly a in assemblies){
- foreach (Type t in a.GetTypes ()){
+ Hashtable cache = new Hashtable ();
+ cache.Add ("", null);
+ foreach (Assembly a in assemblies) {
+ foreach (Type t in a.GetExportedTypes ()) {
string ns = t.Namespace;
-
- // t.Namespace returns null for
- if (ns == ""|| ns == null)
+ if (ns == null || cache.Contains (ns))
continue;
+
Namespace.LookupNamespace (ns, true);
+ cache.Add (ns, null);
}
}
}
}
+ ///
+ /// Fills static table with exported types from all referenced assemblies.
+ /// This information is required for CLS Compliance tests.
+ ///
+ public static void LoadAllImportedTypes ()
+ {
+ all_imported_types = new Hashtable ();
+ foreach (Assembly a in assemblies) {
+ foreach (Type t in a.GetExportedTypes ()) {
+ all_imported_types [t.FullName] = t;
+ }
+ }
+ }
+
public static bool NamespaceClash (string name, Location loc)
{
if (Namespace.LookupNamespace (name, false) == null)
@@ -738,11 +856,14 @@ public class TypeManager {
///
static public string CSharpName (Type t)
{
+ if (t.FullName == null)
+ return t.Name;
+
return Regex.Replace (t.FullName,
@"^System\." +
@"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
@"Single|Double|Char|Decimal|Byte|SByte|Object|" +
- @"Boolean|String|Void)" +
+ @"Boolean|String|Void|Null)" +
@"(\W+|\b)",
new MatchEvaluator (CSharpNameMatch));
}
@@ -762,12 +883,90 @@ public class TypeManager {
+ match.Groups [2].Captures [0].Value;
}
+ ///
+ /// Returns the signature of the method with full namespace classification
+ ///
+ static public string GetFullNameSignature (MemberInfo mi)
+ {
+ return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
+ }
+
+ static public string GetFullNameSignature (MethodBase mb)
+ {
+ string name = mb.Name;
+ if (name == ".ctor")
+ name = mb.DeclaringType.Name;
+
+ if (mb.IsSpecialName) {
+ if (name.StartsWith ("get_") || name.StartsWith ("set_")) {
+ name = name.Remove (0, 4);
+ }
+
+ if (name == "Item")
+ name = "this";
+ }
+
+ return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name;
+ }
+
+ static public string GetFullName (Type t)
+ {
+ if (t.FullName == null)
+ return t.Name;
+
+ string name = t.FullName.Replace ('+', '.');
+
+ DeclSpace tc = LookupDeclSpace (t);
+ if ((tc != null) && tc.IsGeneric) {
+ TypeParameter[] tparam = tc.TypeParameters;
+
+ 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);
+ }
+ sb.Append (">");
+ return sb.ToString ();
+ } else if (t.HasGenericArguments && !t.IsGenericInstance) {
+ Type[] tparam = t.GetGenericArguments ();
+
+ 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);
+ }
+ sb.Append (">");
+ return sb.ToString ();
+ }
+
+ return name;
+ }
+
+ ///
+ /// Returns the signature of the property and indexer
+ ///
+ static public string CSharpSignature (PropertyBuilder pb, bool is_indexer)
+ {
+ if (!is_indexer) {
+ return GetFullNameSignature (pb);
+ }
+
+ MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true);
+ string signature = GetFullNameSignature (mb);
+ string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0);
+ return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg);
+ }
+
///
/// Returns the signature of the method
///
static public string CSharpSignature (MethodBase mb)
{
- string sig = "(";
+ StringBuilder sig = new StringBuilder ("(");
//
// FIXME: We should really have a single function to do
@@ -775,20 +974,28 @@ public class TypeManager {
//
ParameterData iparams = LookupParametersByBuilder (mb);
- if (iparams == null){
- ParameterInfo [] pi = mb.GetParameters ();
- iparams = new ReflectionParameters (pi);
- }
+ if (iparams == null)
+ iparams = new ReflectionParameters (mb);
+
+ // Is property
+ if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor)
+ return GetFullNameSignature (mb);
for (int i = 0; i < iparams.Count; i++) {
if (i > 0) {
- sig += ", ";
+ sig.Append (", ");
}
- sig += iparams.ParameterDesc(i);
+ sig.Append (iparams.ParameterDesc (i));
}
- sig += ")";
+ sig.Append (")");
+
+ // Is indexer
+ if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) {
+ sig.Replace ('(', '[');
+ sig.Replace (')', ']');
+ }
- return mb.DeclaringType.Name + "." + mb.Name + sig;
+ return GetFullNameSignature (mb) + sig.ToString ();
}
///
@@ -801,7 +1008,7 @@ public class TypeManager {
if (t == null){
Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
- Environment.Exit (0);
+ Environment.Exit (1);
}
return t;
@@ -811,16 +1018,19 @@ public class TypeManager {
/// Returns the MethodInfo for a method named `name' defined
/// in type `t' which takes arguments of types `args'
///
- static MethodInfo GetMethod (Type t, string name, Type [] args, bool report_errors)
+ static MethodInfo GetMethod (Type t, string name, Type [] args, bool is_private, bool report_errors)
{
MemberList list;
Signature sig;
+ BindingFlags flags = instance_and_static | BindingFlags.Public;
sig.name = name;
sig.args = args;
- list = FindMembers (t, MemberTypes.Method, instance_and_static | BindingFlags.Public,
- signature_filter, sig);
+ if (is_private)
+ flags |= BindingFlags.NonPublic;
+
+ list = FindMembers (t, MemberTypes.Method, flags, signature_filter, sig);
if (list.Count == 0) {
if (report_errors)
Report.Error (-19, "Can not find the core function `" + name + "'");
@@ -837,6 +1047,11 @@ public class TypeManager {
return mi;
}
+ static MethodInfo GetMethod (Type t, string name, Type [] args, bool report_errors)
+ {
+ return GetMethod (t, name, args, false, report_errors);
+ }
+
static MethodInfo GetMethod (Type t, string name, Type [] args)
{
return GetMethod (t, name, args, true);
@@ -913,6 +1128,7 @@ public class TypeManager {
type_type = CoreLookupType ("System.Type");
runtime_field_handle_type = CoreLookupType ("System.RuntimeFieldHandle");
+ runtime_argument_handle_type = CoreLookupType ("System.RuntimeArgumentHandle");
runtime_helpers_type = CoreLookupType ("System.Runtime.CompilerServices.RuntimeHelpers");
default_member_type = CoreLookupType ("System.Reflection.DefaultMemberAttribute");
runtime_handle_type = CoreLookupType ("System.RuntimeTypeHandle");
@@ -922,6 +1138,7 @@ public class TypeManager {
ienumerable_type = CoreLookupType ("System.Collections.IEnumerable");
idisposable_type = CoreLookupType ("System.IDisposable");
icloneable_type = CoreLookupType ("System.ICloneable");
+ iconvertible_type = CoreLookupType ("System.IConvertible");
monitor_type = CoreLookupType ("System.Threading.Monitor");
intptr_type = CoreLookupType ("System.IntPtr");
@@ -930,8 +1147,12 @@ public class TypeManager {
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");
+ 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
@@ -946,13 +1167,25 @@ public class TypeManager {
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");
//
// Attribute types
//
obsolete_attribute_type = CoreLookupType ("System.ObsoleteAttribute");
conditional_attribute_type = CoreLookupType ("System.Diagnostics.ConditionalAttribute");
+ cls_compliant_attribute_type = CoreLookupType ("System.CLSCompliantAttribute");
+ struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute");
+ field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute");
+
+ //
+ // Generic types
+ //
+ generic_ienumerator_type = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerator", 1));
+ generic_ienumerable_type = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerable", 1));
+
//
// When compiling corlib, store the "real" types here.
@@ -990,7 +1223,7 @@ public class TypeManager {
MethodInfo set_corlib_type_builders = GetMethod (
system_assemblybuilder_type, "SetCorlibTypeBuilders",
- system_4_type_arg, false);
+ system_4_type_arg, true, false);
if (set_corlib_type_builders != null) {
object[] args = new object [4];
@@ -999,12 +1232,12 @@ public class TypeManager {
args [2] = enum_type;
args [3] = void_type;
- set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+ set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
} else {
// Compatibility for an older version of the class libs.
set_corlib_type_builders = GetMethod (
system_assemblybuilder_type, "SetCorlibTypeBuilders",
- system_3_type_arg, true);
+ system_3_type_arg, true, true);
if (set_corlib_type_builders == null) {
Report.Error (-26, "Corlib compilation is not supported in Microsoft.NET due to bugs in it");
@@ -1016,9 +1249,29 @@ public class TypeManager {
args [1] = value_type;
args [2] = enum_type;
- set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+ set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
}
}
+
+ system_object_expr.Type = object_type;
+ system_string_expr.Type = string_type;
+ system_boolean_expr.Type = bool_type;
+ system_decimal_expr.Type = decimal_type;
+ system_single_expr.Type = float_type;
+ system_double_expr.Type = double_type;
+ system_sbyte_expr.Type = sbyte_type;
+ system_byte_expr.Type = byte_type;
+ system_int16_expr.Type = short_type;
+ system_uint16_expr.Type = ushort_type;
+ system_int32_expr.Type = int32_type;
+ system_uint32_expr.Type = uint32_type;
+ system_int64_expr.Type = int64_type;
+ system_uint64_expr.Type = uint64_type;
+ system_char_expr.Type = char_type;
+ system_void_expr.Type = void_type;
+ system_asynccallback_expr.Type = asynccallback_type;
+ system_iasyncresult_expr.Type = iasyncresult_type;
+ system_valuetype_expr.Type = value_type;
}
//
@@ -1038,10 +1291,19 @@ public class TypeManager {
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[]") };
+ string_concat_string_dot_dot_dot = GetMethod (
+ string_type, "Concat", params_string);
Type [] object_object = { object_type, object_type };
string_concat_object_object = GetMethod (
string_type, "Concat", object_object);
+ 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[]") };
+ string_concat_object_dot_dot_dot = GetMethod (
+ string_type, "Concat", params_object);
Type [] string_ = { string_type };
string_isinterneted_string = GetMethod (
@@ -1135,6 +1397,8 @@ public class TypeManager {
unverifiable_code_ctor = GetConstructor (
unverifiable_code_type, void_arg);
+ default_member_ctor = GetConstructor (default_member_type, string_);
+
//
// InvalidOperationException
//
@@ -1145,12 +1409,14 @@ public class TypeManager {
// Object
object_ctor = GetConstructor (object_type, void_arg);
+ // Activator
+ Type [] type_arg = { type_type };
+ activator_create_instance = GetMethod (
+ activator_type, "CreateInstance", type_arg);
}
const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
- static Hashtable type_hash = new Hashtable ();
-
///
/// This is the "old", non-cache based FindMembers() function. We cannot use
/// the cache here because there is no member name argument.
@@ -1179,6 +1445,16 @@ public class TypeManager {
if (t.IsSubclassOf (TypeManager.array_type))
return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
+ if (t is GenericTypeParameterBuilder) {
+ TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+ Timer.StartTimer (TimerType.FindMembers);
+ MemberList list = tparam.FindMembers (
+ mt, bf | BindingFlags.DeclaredOnly, filter, criteria);
+ Timer.StopTimer (TimerType.FindMembers);
+ return list;
+ }
+
//
// Since FindMembers will not lookup both static and instance
// members, we emulate this behaviour here.
@@ -1223,11 +1499,9 @@ public class TypeManager {
/// our return value will already contain all inherited members and the caller don't need
/// to check base classes and interfaces anymore.
///
- private static MemberList MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+ private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
string name, out bool used_cache)
{
- bool not_loaded_corlib = (t.Assembly == CodeGen.AssemblyBuilder);
-
//
// We have to take care of arrays specially, because GetType on
// a TypeBuilder array will return a Type, not a TypeBuilder,
@@ -1258,6 +1532,7 @@ public class TypeManager {
}
// If there is no MemberCache, we need to use the "normal" FindMembers.
+ // Note, this is a VERY uncommon route!
MemberList list;
Timer.StartTimer (TimerType.FindMembers);
@@ -1265,7 +1540,19 @@ public class TypeManager {
FilterWithClosure_delegate, name);
Timer.StopTimer (TimerType.FindMembers);
used_cache = false;
- return list;
+ return (MemberInfo []) list;
+ }
+
+ if (t is GenericTypeParameterBuilder) {
+ TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+ MemberList list;
+ Timer.StartTimer (TimerType.FindMembers);
+ list = tparam.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
+ FilterWithClosure_delegate, name);
+ Timer.StopTimer (TimerType.FindMembers);
+ used_cache = false;
+ return (MemberInfo []) list;
}
//
@@ -1290,6 +1577,11 @@ public class TypeManager {
return false;
}
+ public static bool IsBuiltinType (TypeContainer tc)
+ {
+ return IsBuiltinType (tc.TypeBuilder);
+ }
+
//
// 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.
@@ -1307,6 +1599,9 @@ public class TypeManager {
public static bool IsDelegateType (Type t)
{
+ if (t.IsGenericInstance)
+ t = t.GetGenericTypeDefinition ();
+
if (t.IsSubclassOf (TypeManager.delegate_type))
return true;
else
@@ -1315,7 +1610,7 @@ public class TypeManager {
public static bool IsEnumType (Type t)
{
- if (t == TypeManager.enum_type || t.IsSubclassOf (TypeManager.enum_type))
+ if (t.IsSubclassOf (TypeManager.enum_type))
return true;
else
return false;
@@ -1340,6 +1635,40 @@ public class TypeManager {
return ds.IsGeneric;
}
+
+ public static bool HasGenericArguments (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 ();
+ }
//
// Whether a type is unmanaged. This is used by the unsafe code (25.2)
@@ -1359,12 +1688,15 @@ public class TypeManager {
if (t is TypeBuilder){
TypeContainer tc = LookupTypeContainer (t);
+ 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 ();
@@ -1388,121 +1720,370 @@ public class TypeManager {
public static bool IsInterfaceType (Type t)
{
- Interface iface = builder_to_declspace [t] as Interface;
-
- if (iface != null)
- return true;
- else
+ TypeContainer tc = (TypeContainer) builder_to_declspace [t];
+ if (tc == null)
return false;
- }
-
- //
- // Checks whether `type' is a subclass or nested child of `parent'.
- //
- public static bool IsSubclassOrNestedChildOf (Type type, Type parent)
- {
- do {
- if ((type == parent) || type.IsSubclassOf (parent))
- return true;
-
- // Handle nested types.
- type = type.DeclaringType;
- } while (type != null);
- return false;
+ return tc.Kind == Kind.Interface;
}
- //
- // Checks whether `type' is a nested child of `parent'.
- //
- public static bool IsNestedChildOf (Type type, Type parent)
+ public static bool IsEqual (Type a, Type b)
{
- if (type == parent)
- return false;
+ if (a.Equals (b))
+ return true;
- type = type.DeclaringType;
- while (type != null) {
- if (type == parent)
- 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
+ // {
+ // void Test (Stack stack) { }
+ // }
+ //
+ // The first argument of `Test' will be the generic instance
+ // "Stack" - 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 = type.DeclaringType;
- }
+ Type[] aparams = a.GetGenericArguments ();
+ Type[] bparams = b.GetGenericArguments ();
- return false;
- }
+ if (aparams.Length != bparams.Length)
+ return false;
- //
- // Do the right thing when returning the element type of an
- // array type based on whether we are compiling corlib or not
- //
- public static Type GetElementType (Type t)
- {
- if (RootContext.StdLib)
- return t.GetElementType ();
- else
- return TypeToCoreType (t.GetElementType ());
- }
+ for (int i = 0; i < aparams.Length; i++)
+ if (!IsEqual (aparams [i], bparams [i]))
+ return false;
- ///
- /// Returns the User Defined Types
- ///
- public static ArrayList UserTypes {
- get {
- return user_types;
+ return true;
}
- }
- public static Hashtable TypeContainers {
- get {
- return typecontainers;
+ if (a.IsGenericParameter && b.IsGenericParameter) {
+ if ((a.DeclaringMethod == null) || (b.DeclaringMethod == null))
+ return false;
+ return a.GenericParameterPosition == b.GenericParameterPosition;
}
- }
- static Hashtable attr_to_allowmult;
+ if (a.IsArray && b.IsArray) {
+ if (a.GetArrayRank () != b.GetArrayRank ())
+ return false;
+ return IsEqual (a.GetElementType (), b.GetElementType ());
+ }
- public static void RegisterAttributeAllowMultiple (Type attr_type, bool allow)
- {
- if (attr_to_allowmult == null)
- attr_to_allowmult = new PtrHashtable ();
+ if (a.IsGenericInstance && b.IsGenericInstance) {
+ Type at = a.GetGenericTypeDefinition ();
+ Type bt = b.GetGenericTypeDefinition ();
- if (attr_to_allowmult.Contains (attr_type))
- return;
+ if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+ return false;
- attr_to_allowmult.Add (attr_type, allow);
-
- }
+ Type[] aargs = a.GetGenericArguments ();
+ Type[] bargs = b.GetGenericArguments ();
- public static bool AreMultipleAllowed (Type attr_type)
- {
- if (!(attr_type is TypeBuilder)) {
- System.Attribute [] attrs = System.Attribute.GetCustomAttributes (attr_type);
+ if (aargs.Length != bargs.Length)
+ return false;
- foreach (System.Attribute tmp in attrs)
- if (tmp is AttributeUsageAttribute) {
- return ((AttributeUsageAttribute) tmp).AllowMultiple;
- }
+ for (int i = 0; i < aargs.Length; i++) {
+ if (!IsEqual (aargs [i], bargs [i]))
+ return false;
+ }
- return false;
+ return true;
}
-
- if (attr_to_allowmult == null)
- return false;
- return (bool) attr_to_allowmult [attr_type];
+ return false;
}
- static Hashtable builder_to_constant;
-
- public static void RegisterConstant (FieldBuilder fb, Const c)
+ public static bool MayBecomeEqualGenericTypes (Type a, Type b)
{
- if (builder_to_constant == null)
- builder_to_constant = new PtrHashtable ();
-
- if (builder_to_constant.Contains (fb))
- return;
+ 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;
+ }
- builder_to_constant.Add (fb, c);
- }
+ //
+ // If b is a generic parameter or an actual type,
+ // they may become equal:
+ //
+ // class X : I, I
+ // class X : I, I
+ //
+ 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 : I, I>
+ // -> error because you could instanciate it as
+ // X,int>
+ //
+ // class X : I, I> -> 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)
+ {
+ TypeParameter tparam = LookupTypeParameter (type);
+ TypeParameter pparam = LookupTypeParameter (parent);
+
+ if ((tparam != null) && (pparam != null)) {
+ if (tparam == pparam)
+ return true;
+
+ return tparam.IsSubclassOf (parent);
+ }
+
+ do {
+ if (type.Equals (parent))
+ return true;
+
+ type = type.BaseType;
+ } while (type != null);
+
+ return false;
+ }
+
+ public static bool IsPrivateAccessible (Type type, Type parent)
+ {
+ if (type.Equals (parent))
+ return true;
+
+ if ((type is TypeBuilder) && type.IsGenericTypeDefinition && parent.IsGenericInstance) {
+ //
+ // `a' is a generic type definition's TypeBuilder and `b' is a
+ // generic instance of the same type.
+ //
+ // Example:
+ //
+ // class Stack
+ // {
+ // void Test (Stack stack) { }
+ // }
+ //
+ // The first argument of `Test' will be the generic instance
+ // "Stack" - which is the same type than the "Stack" TypeBuilder.
+ //
+ //
+ // We hit this via Closure.Filter() for gen-82.cs.
+ //
+ if (type != parent.GetGenericTypeDefinition ())
+ return false;
+
+ return true;
+ }
+
+ if (type.IsGenericInstance && parent.IsGenericInstance) {
+ Type tdef = type.GetGenericTypeDefinition ();
+ Type pdef = parent.GetGenericTypeDefinition ();
+
+ if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ())
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool IsFamilyAccessible (Type type, Type parent)
+ {
+ TypeParameter tparam = LookupTypeParameter (type);
+ TypeParameter pparam = LookupTypeParameter (parent);
+
+ if ((tparam != null) && (pparam != null)) {
+ if (tparam == pparam)
+ return true;
+
+ return tparam.IsSubclassOf (parent);
+ }
+
+ do {
+ if (IsEqualGenericInstance (type, parent))
+ return true;
+
+ type = type.BaseType;
+ } while (type != null);
+
+ return false;
+ }
+
+ //
+ // Checks whether `type' is a subclass or nested child of `parent'.
+ //
+ public static bool IsNestedFamilyAccessible (Type type, Type parent)
+ {
+ do {
+ if (IsFamilyAccessible (type, parent))
+ return true;
+
+ // Handle nested types.
+ type = type.DeclaringType;
+ } while (type != null);
+
+ return false;
+ }
+
+ //
+ // Checks whether `type' is a nested child of `parent'.
+ //
+ public static bool IsNestedChildOf (Type type, Type parent)
+ {
+ if (IsEqual (type, parent))
+ return false;
+
+ type = type.DeclaringType;
+ while (type != null) {
+ if (IsEqual (type, parent))
+ return true;
+
+ type = type.DeclaringType;
+ }
+
+ return false;
+ }
+
+ //
+ // Do the right thing when returning the element type of an
+ // array type based on whether we are compiling corlib or not
+ //
+ public static Type GetElementType (Type t)
+ {
+ if (RootContext.StdLib)
+ return t.GetElementType ();
+ else
+ return TypeToCoreType (t.GetElementType ());
+ }
+
+ ///
+ /// Returns the User Defined Types
+ ///
+ public static ArrayList UserTypes {
+ get {
+ return user_types;
+ }
+ }
+
+ public static Hashtable TypeContainers {
+ get {
+ return typecontainers;
+ }
+ }
+
+ static Hashtable builder_to_constant;
+
+ public static void RegisterConstant (FieldBuilder fb, Const c)
+ {
+ if (builder_to_constant == null)
+ builder_to_constant = new PtrHashtable ();
+
+ if (builder_to_constant.Contains (fb))
+ return;
+
+ builder_to_constant.Add (fb, c);
+ }
public static Const LookupConstant (FieldBuilder fb)
{
@@ -1521,15 +2102,13 @@ public class TypeManager {
/// for anything which is dynamic, and we need this in a number of places,
/// we register this information here, and use it afterwards.
///
- static public bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
+ static public void RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
{
if (args == null)
args = NoTypes;
method_arguments.Add (mb, args);
method_internal_params.Add (mb, ip);
-
- return true;
}
static public InternalParameters LookupParametersByBuilder (MethodBase mb)
@@ -1552,20 +2131,24 @@ public class TypeManager {
///
static public Type [] GetArgumentTypes (MethodBase mb)
{
- if (method_arguments.Contains (mb))
- return (Type []) method_arguments [mb];
- else {
+ object t = method_arguments [mb];
+ if (t != null)
+ return (Type []) t;
+
ParameterInfo [] pi = mb.GetParameters ();
int c = pi.Length;
- Type [] types = new Type [c];
+ Type [] types;
+ if (c == 0) {
+ types = NoTypes;
+ } else {
+ types = new Type [c];
for (int i = 0; i < c; i++)
types [i] = pi [i].ParameterType;
-
+ }
method_arguments.Add (mb, types);
return types;
}
- }
///
/// Returns the argument types for an indexer based on its PropertyInfo
@@ -1641,17 +2224,14 @@ public class TypeManager {
static Hashtable events;
- static public bool RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
+ static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
{
if (events == null)
events = new Hashtable ();
- if (events.Contains (eb))
- return false;
-
+ if (!events.Contains (eb)) {
events.Add (eb, new Pair (add, remove));
-
- return true;
+ }
}
static public MethodInfo GetAddMethod (EventInfo ei)
@@ -1660,8 +2240,8 @@ public class TypeManager {
Pair pair = (Pair) events [ei];
return (MethodInfo) pair.First;
- } else
- return ei.GetAddMethod ();
+ }
+ return ei.GetAddMethod (true);
}
static public MethodInfo GetRemoveMethod (EventInfo ei)
@@ -1670,8 +2250,8 @@ public class TypeManager {
Pair pair = (Pair) events [ei];
return (MethodInfo) pair.Second;
- } else
- return ei.GetRemoveMethod ();
+ }
+ return ei.GetRemoveMethod (true);
}
static Hashtable priv_fields_events;
@@ -1723,6 +2303,64 @@ public class TypeManager {
return true;
}
+ public static bool CheckStructCycles (TypeContainer tc, Hashtable seen)
+ {
+ Hashtable hash = new Hashtable ();
+ return CheckStructCycles (tc, seen, hash);
+ }
+
+ public static bool CheckStructCycles (TypeContainer tc, Hashtable seen,
+ Hashtable hash)
+ {
+ if ((tc.Kind != Kind.Struct) || IsBuiltinType (tc))
+ return true;
+
+ //
+ // `seen' contains all types we've already visited.
+ //
+ if (seen.Contains (tc))
+ return true;
+ seen.Add (tc, null);
+
+ if (tc.Fields == null)
+ return true;
+
+ foreach (Field field in tc.Fields) {
+ if (field.FieldBuilder.IsStatic)
+ continue;
+
+ Type ftype = field.FieldBuilder.FieldType;
+ TypeContainer ftc = LookupTypeContainer (ftype);
+ if (ftc == null)
+ continue;
+
+ if (hash.Contains (ftc)) {
+ Report.Error (523, tc.Location,
+ "Struct member `{0}.{1}' of type `{2}' " +
+ "causes a cycle in the struct layout",
+ tc.Name, field.Name, ftc.Name);
+ return false;
+ }
+
+ //
+ // `hash' contains all types in the current path.
+ //
+ hash.Add (tc, null);
+
+ bool ok = CheckStructCycles (ftc, seen, hash);
+
+ hash.Remove (tc);
+
+ if (!ok)
+ return false;
+
+ if (!seen.Contains (ftc))
+ seen.Add (ftc, null);
+ }
+
+ return true;
+ }
+
///
/// Given an array of interface types, expand and eliminate repeated ocurrences
/// of an interface.
@@ -1732,15 +2370,19 @@ public class TypeManager {
/// This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
/// be IA, IB, IC.
///
- public static Type [] ExpandInterfaces (Type [] base_interfaces)
+ public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)
{
ArrayList new_ifaces = new ArrayList ();
- foreach (Type iface in base_interfaces){
- if (!new_ifaces.Contains (iface))
- new_ifaces.Add (iface);
+ foreach (TypeExpr iface in base_interfaces){
+ Type itype = iface.ResolveType (ec);
+ if (itype == null)
+ return null;
+
+ if (!new_ifaces.Contains (itype))
+ new_ifaces.Add (itype);
- Type [] implementing = TypeManager.GetInterfaces (iface);
+ Type [] implementing = itype.GetInterfaces ();
foreach (Type imp in implementing){
if (!new_ifaces.Contains (imp))
@@ -1752,12 +2394,19 @@ public class TypeManager {
return ret;
}
+ static PtrHashtable iface_cache = new PtrHashtable ();
+
///
/// This function returns the interfaces in the type `t'. Works with
/// both types and TypeBuilders.
///
public static Type [] GetInterfaces (Type t)
{
+
+ Type [] cached = iface_cache [t] as Type [];
+ if (cached != null)
+ return cached;
+
//
// The reason for catching the Array case is that Reflection.Emit
// will not return a TypeBuilder for Array types of TypeBuilder types,
@@ -1772,24 +2421,43 @@ public class TypeManager {
t = TypeManager.array_type;
if (t is TypeBuilder){
- Type [] parent_ifaces;
+ Type[] parent_ifaces;
if (t.BaseType == null)
parent_ifaces = NoTypes;
else
parent_ifaces = GetInterfaces (t.BaseType);
- Type [] type_ifaces = (Type []) builder_to_ifaces [t];
+ Type[] 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];
+ Type[] result = new Type [parent_count + type_ifaces.Length];
parent_ifaces.CopyTo (result, 0);
type_ifaces.CopyTo (result, parent_count);
+ iface_cache [t] = result;
return result;
- } else
- return t.GetInterfaces ();
+ } else if (t is GenericTypeParameterBuilder){
+ Type[] type_ifaces = (Type []) builder_to_ifaces [t];
+ if (type_ifaces == null)
+ type_ifaces = NoTypes;
+
+ iface_cache [t] = type_ifaces;
+ return type_ifaces;
+ } else {
+ Type[] ifaces = t.GetInterfaces ();
+ iface_cache [t] = ifaces;
+ return ifaces;
+ }
+ }
+
+ //
+ // gets the interfaces that are declared explicitly on t
+ //
+ public static Type [] GetExplicitInterfaces (TypeBuilder t)
+ {
+ return (Type []) builder_to_ifaces [t];
}
///
@@ -1985,6 +2653,8 @@ public class TypeManager {
return TypeManager.object_type;
if (t == typeof (System.Type))
return TypeManager.type_type;
+ if (t == typeof (System.IntPtr))
+ return TypeManager.intptr_type;
return t;
}
}
@@ -2021,28 +2691,18 @@ public class TypeManager {
///
///
/// The default is not always `Item'. The user can change this behaviour by
- /// using the DefaultMemberAttribute in the class.
+ /// using the IndexerNameAttribute in the container.
///
/// For example, the String class indexer is named `Chars' not `Item'
///
public static string IndexerPropertyName (Type t)
{
- if (t is TypeBuilder) {
- if (t.IsInterface) {
- Interface i = LookupInterface (t);
-
- if ((i == null) || (i.IndexerName == null))
- return "Item";
-
- return i.IndexerName;
- } else {
- TypeContainer tc = LookupTypeContainer (t);
-
- if ((tc == null) || (tc.IndexerName == null))
- return "Item";
+ if (t.IsGenericInstance)
+ t = t.GetGenericTypeDefinition ();
- return tc.IndexerName;
- }
+ if (t is TypeBuilder) {
+ TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);
+ return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;
}
System.Attribute attr = System.Attribute.GetCustomAttribute (
@@ -2052,18 +2712,30 @@ public class TypeManager {
return dma.MemberName;
}
- return "Item";
+ return TypeContainer.DefaultIndexerName;
}
- public static void MakePinned (LocalBuilder builder)
- {
- //
- // FIXME: Flag the "LocalBuilder" type as being
- // pinned. Figure out API.
- //
+ static MethodInfo declare_local_method = null;
+
+ public static LocalBuilder DeclareLocalPinned (ILGenerator ig, Type t)
+ {
+ if (declare_local_method == null){
+ declare_local_method = typeof (ILGenerator).GetMethod (
+ "DeclareLocal",
+ BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
+ null,
+ new Type [] { typeof (Type), typeof (bool)},
+ null);
+ if (declare_local_method == null){
+ Report.Warning (-24, 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 (LocalBuilder) declare_local_method.Invoke (ig, new object [] { t, true });
}
-
//
// Returns whether the array of memberinfos contains the given method
//
@@ -2106,7 +2778,7 @@ public class TypeManager {
//
// The name is assumed to be the same.
//
- public static ArrayList CopyNewMethods (ArrayList target_list, MemberList new_members)
+ public static ArrayList CopyNewMethods (ArrayList target_list, IList new_members)
{
if (target_list == null){
target_list = new ArrayList ();
@@ -2130,152 +2802,95 @@ public class TypeManager {
return target_list;
}
- [Flags]
- public enum MethodFlags {
- IsObsolete = 1,
- IsObsoleteError = 1 << 1,
- ShouldIgnore = 1 << 2
- }
-
- //
- // Returns the TypeManager.MethodFlags for this method.
- // This emits an error 619 / warning 618 if the method is obsolete.
- // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
- //
- static public MethodFlags GetMethodFlags (MethodBase mb, Location loc)
+ static public bool IsGenericMethod (MethodBase mb)
{
- MethodFlags flags = 0;
-
- if (mb.DeclaringType is TypeBuilder){
- MethodData method = (MethodData) builder_to_method [mb];
- if (method == null) {
- // FIXME: implement Obsolete attribute on Property,
- // Indexer and Event.
- return 0;
- }
-
- return method.GetMethodFlags (loc);
- }
-
-#if FIXME
- if (mb.IsInflatedGeneric) {
- MethodBase generic = mb.GetGenericMethodDefinition ();
-
- return GetMethodFlags (generic, loc);
- }
-#endif
-
- object [] attrs = mb.GetCustomAttributes (true);
- foreach (object ta in attrs){
- if (!(ta is System.Attribute)){
- Console.WriteLine ("Unknown type in GetMethodFlags: " + ta);
- continue;
- }
- System.Attribute a = (System.Attribute) ta;
- if (a.TypeId == TypeManager.obsolete_attribute_type){
- ObsoleteAttribute oa = (ObsoleteAttribute) a;
-
- string method_desc = TypeManager.CSharpSignature (mb);
-
- if (oa.IsError) {
- Report.Error (619, loc, "Method `" + method_desc +
- "' is obsolete: `" + oa.Message + "'");
- return MethodFlags.IsObsoleteError;
- } else
- Report.Warning (618, loc, "Method `" + method_desc +
- "' is obsolete: `" + oa.Message + "'");
-
- flags |= MethodFlags.IsObsolete;
-
- continue;
- }
-
- //
- // Skip over conditional code.
- //
- if (a.TypeId == TypeManager.conditional_attribute_type){
- ConditionalAttribute ca = (ConditionalAttribute) a;
+ if (mb.DeclaringType is TypeBuilder) {
+ IMethodData method = (IMethodData) builder_to_method [mb];
+ if (method == null)
+ return false;
- if (RootContext.AllDefines [ca.ConditionString] == null)
- flags |= MethodFlags.ShouldIgnore;
- }
+ return method.GenericMethod != null;
}
- return flags;
+ return mb.IsGenericMethodDefinition;
}
#region MemberLookup implementation
- //
- // Name of the member
- //
- static string closure_name;
-
//
// Whether we allow private members in the result (since FindMembers
// uses NonPublic for both protected and private), we need to distinguish.
//
- static bool closure_private_ok;
-
- //
- // Who is invoking us and which type is being queried currently.
- //
- static Type closure_invocation_type;
- static Type closure_queried_type;
- static Type closure_qualifier_type;
-
- //
- // The assembly that defines the type is that is calling us
- //
- static Assembly closure_invocation_assembly;
static internal bool FilterNone (MemberInfo m, object filter_criteria)
{
return true;
}
-
- //
- // This filter filters by name + whether it is ok to include private
- // members in the search
- //
- static internal bool FilterWithClosure (MemberInfo m, object filter_criteria)
- {
- //
- // Hack: we know that the filter criteria will always be in the `closure'
- // fields.
- //
- if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
- return false;
+ internal class Closure {
+ internal bool private_ok;
- if (((closure_qualifier_type == null) || (closure_qualifier_type == closure_invocation_type)) &&
- (m.DeclaringType == closure_invocation_type))
- return true;
+ // Who is invoking us and which type is being queried currently.
+ internal Type invocation_type;
+ internal Type qualifier_type;
- //
- // Ugly: we need to find out the type of `m', and depending
- // on this, tell whether we accept or not
- //
- if (m is MethodBase){
- MethodBase mb = (MethodBase) m;
+ // The assembly that defines the type is that is calling us
+ 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;
if (ma == MethodAttributes.Private)
- return closure_private_ok || (closure_invocation_type == m.DeclaringType) ||
- IsNestedChildOf (closure_invocation_type, m.DeclaringType);
+ return private_ok ||
+ IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
+ IsNestedChildOf (invocation_type, mb.DeclaringType);
//
// FamAndAssem requires that we not only derivate, but we are on the
// same assembly.
//
if (ma == MethodAttributes.FamANDAssem){
- if (closure_invocation_assembly != mb.DeclaringType.Assembly)
+ if (invocation_assembly != mb.DeclaringType.Assembly)
return false;
}
// Assembly and FamORAssem succeed if we're in the same assembly.
if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
- if (closure_invocation_assembly == mb.DeclaringType.Assembly)
+ if (invocation_assembly == mb.DeclaringType.Assembly)
return true;
}
@@ -2285,17 +2900,18 @@ public class TypeManager {
// Family and FamANDAssem require that we derive.
if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem)){
- if (closure_invocation_type == null)
+ if (invocation_type == null)
return false;
- if (!IsSubclassOrNestedChildOf (closure_invocation_type, mb.DeclaringType))
+ if (!IsNestedFamilyAccessible (invocation_type, mb.DeclaringType))
return false;
// Although a derived class can access protected members of its base class
// it cannot do so through an instance of the base class (CS1540).
- if (!mb.IsStatic && (closure_invocation_type != closure_qualifier_type) &&
- (closure_qualifier_type != null) &&
- closure_invocation_type.IsSubclassOf (closure_qualifier_type))
+ if (!mb.IsStatic && (qualifier_type != null) &&
+ !IsEqualGenericInstance (invocation_type, qualifier_type) &&
+ TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
+ !TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
return false;
return true;
@@ -2305,26 +2921,27 @@ public class TypeManager {
return true;
}
- if (m is FieldInfo){
- FieldInfo fi = (FieldInfo) m;
+ bool Filter (FieldInfo fi, object filter_criteria)
+ {
FieldAttributes fa = fi.Attributes & FieldAttributes.FieldAccessMask;
if (fa == FieldAttributes.Private)
- return closure_private_ok || (closure_invocation_type == m.DeclaringType) ||
- IsNestedChildOf (closure_invocation_type, m.DeclaringType);
+ return private_ok ||
+ IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
+ IsNestedChildOf (invocation_type, fi.DeclaringType);
//
// FamAndAssem requires that we not only derivate, but we are on the
// same assembly.
//
if (fa == FieldAttributes.FamANDAssem){
- if (closure_invocation_assembly != fi.DeclaringType.Assembly)
+ if (invocation_assembly != fi.DeclaringType.Assembly)
return false;
}
// Assembly and FamORAssem succeed if we're in the same assembly.
if ((fa == FieldAttributes.Assembly) || (fa == FieldAttributes.FamORAssem)){
- if (closure_invocation_assembly == fi.DeclaringType.Assembly)
+ if (invocation_assembly == fi.DeclaringType.Assembly)
return true;
}
@@ -2334,17 +2951,18 @@ public class TypeManager {
// Family and FamANDAssem require that we derive.
if ((fa == FieldAttributes.Family) || (fa == FieldAttributes.FamANDAssem)){
- if (closure_invocation_type == null)
+ if (invocation_type == null)
return false;
- if (!IsSubclassOrNestedChildOf (closure_invocation_type, fi.DeclaringType))
+ if (!IsNestedFamilyAccessible (invocation_type, fi.DeclaringType))
return false;
// Although a derived class can access protected members of its base class
// it cannot do so through an instance of the base class (CS1540).
- if (!fi.IsStatic && (closure_invocation_type != closure_qualifier_type) &&
- (closure_qualifier_type != null) &&
- closure_invocation_type.IsSubclassOf (closure_qualifier_type))
+ if (!fi.IsStatic && (qualifier_type != null) &&
+ !IsEqualGenericInstance (invocation_type, qualifier_type) &&
+ TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
+ !TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
return false;
return true;
@@ -2353,16 +2971,46 @@ public class TypeManager {
// Public.
return true;
}
-
+
//
- // EventInfos and PropertyInfos, return true because they lack permission
- // informaiton, so we need to check later on the methods.
+ // This filter filters by name + whether it is ok to include private
+ // members in the search
//
- return true;
+ internal bool Filter (MemberInfo m, object filter_criteria)
+ {
+ //
+ // Hack: we know that the filter criteria will always be in the
+ // `closure' // fields.
+ //
+
+ if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
+ return false;
+
+ if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
+ (invocation_type != null) &&
+ IsPrivateAccessible (m.DeclaringType, invocation_type))
+ return true;
+
+ //
+ // Ugly: we need to find out the type of `m', and depending
+ // on this, tell whether we accept or not
+ //
+ if (m is MethodBase)
+ return Filter ((MethodBase) m, filter_criteria);
+
+ if (m is FieldInfo)
+ return Filter ((FieldInfo) m, filter_criteria);
+
+ //
+ // EventInfos and PropertyInfos, return true because they lack
+ // permission information, so we need to check later on the methods.
+ //
+ return true;
+ }
}
- static MemberFilter FilterWithClosure_delegate = new MemberFilter (FilterWithClosure);
- static MemberFilter FilterNone_delegate = new MemberFilter (FilterNone);
+ static Closure closure = new Closure ();
+ static MemberFilter FilterWithClosure_delegate = new MemberFilter (closure.Filter);
//
// Looks up a member called `name' in the `queried_type'. This lookup
@@ -2389,17 +3037,19 @@ public class TypeManager {
// is allowed to access (using the specified `qualifier_type' if given); only use
// BindingFlags.NonPublic to bypass the permission check.
//
+ // The 'almost_match' argument is used for reporting error CS1540.
+ //
// Returns an array of a single element for everything but Methods/Constructors
// that might return multiple matches.
//
public static MemberInfo [] MemberLookup (Type invocation_type, Type qualifier_type,
- Type queried_type, MemberTypes mt,
- BindingFlags original_bf, string name)
+ Type queried_type, MemberTypes mt,
+ BindingFlags original_bf, string name, IList almost_match)
{
Timer.StartTimer (TimerType.MemberLookup);
MemberInfo[] retval = RealMemberLookup (invocation_type, qualifier_type,
- queried_type, mt, original_bf, name);
+ queried_type, mt, original_bf, name, almost_match);
Timer.StopTimer (TimerType.MemberLookup);
@@ -2408,7 +3058,7 @@ public class TypeManager {
static MemberInfo [] RealMemberLookup (Type invocation_type, Type qualifier_type,
Type queried_type, MemberTypes mt,
- BindingFlags original_bf, string name)
+ BindingFlags original_bf, string name, IList almost_match)
{
BindingFlags bf = original_bf;
@@ -2418,10 +3068,10 @@ public class TypeManager {
bool skip_iface_check = true, used_cache = false;
bool always_ok_flag = false;
- closure_name = name;
- closure_invocation_type = invocation_type;
- closure_invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
- closure_qualifier_type = qualifier_type;
+ closure.invocation_type = invocation_type;
+ closure.invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
+ closure.qualifier_type = qualifier_type;
+ closure.almost_match = almost_match;
//
// If we are a nested class, we always have access to our container
@@ -2429,7 +3079,7 @@ public class TypeManager {
//
if (invocation_type != null){
string invocation_name = invocation_type.FullName;
- if (invocation_name.IndexOf ('+') != -1){
+ if ((invocation_name != null) && (invocation_name.IndexOf ('+') != -1)){
string container = queried_type.FullName + "+";
int container_length = container.Length;
@@ -2442,8 +3092,14 @@ public class TypeManager {
}
}
+ // This is from the first time we find a method
+ // in most cases, we do not actually find a method in the base class
+ // so we can just ignore it, and save the arraylist allocation
+ MemberInfo [] first_members_list = null;
+ bool use_first_members_list = false;
+
do {
- MemberList list;
+ MemberInfo [] list;
//
// `NonPublic' is lame, because it includes both protected and
@@ -2462,12 +3118,12 @@ public class TypeManager {
else
bf = original_bf;
- closure_private_ok = (original_bf & BindingFlags.NonPublic) != 0;
- closure_queried_type = current_type;
+ closure.private_ok = (original_bf & BindingFlags.NonPublic) != 0;
Timer.StopTimer (TimerType.MemberLookup);
- list = MemberLookup_FindMembers (current_type, mt, bf, name, out used_cache);
+ list = MemberLookup_FindMembers (
+ current_type, mt, bf, name, out used_cache);
Timer.StartTimer (TimerType.MemberLookup);
@@ -2498,7 +3154,7 @@ public class TypeManager {
current_type = TypeManager.object_type;
}
- if (list.Count == 0)
+ if (list.Length == 0)
continue;
//
@@ -2506,8 +3162,8 @@ public class TypeManager {
// searches, which means that our above FindMembers will
// return two copies of the same.
//
- if (list.Count == 1 && !(list [0] is MethodBase)){
- return (MemberInfo []) list;
+ if (list.Length == 1 && !(list [0] is MethodBase)){
+ return list;
}
//
@@ -2515,14 +3171,14 @@ public class TypeManager {
// name
//
if (list [0] is PropertyInfo)
- return (MemberInfo []) list;
+ return list;
//
// We found an event: the cache lookup returns both the event and
// its private field.
//
if (list [0] is EventInfo) {
- if ((list.Count == 2) && (list [1] is FieldInfo))
+ if ((list.Length == 2) && (list [1] is FieldInfo))
return new MemberInfo [] { list [0] };
// Oooops
@@ -2534,10 +3190,31 @@ public class TypeManager {
// mode.
//
- method_list = CopyNewMethods (method_list, list);
- mt &= (MemberTypes.Method | MemberTypes.Constructor);
+ if (first_members_list != null) {
+ if (use_first_members_list) {
+ method_list = CopyNewMethods (method_list, first_members_list);
+ use_first_members_list = false;
+ }
+
+ method_list = CopyNewMethods (method_list, list);
+ } else {
+ first_members_list = list;
+ use_first_members_list = true;
+
+ mt &= (MemberTypes.Method | MemberTypes.Constructor);
+ }
} while (searching);
+ if (use_first_members_list) {
+ foreach (MemberInfo mi in first_members_list) {
+ if (! (mi is MethodBase)) {
+ method_list = CopyNewMethods (method_list, first_members_list);
+ return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
+ }
+ }
+ return (MemberInfo []) first_members_list;
+ }
+
if (method_list != null && method_list.Count > 0) {
return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
}
@@ -2565,7 +3242,7 @@ public class TypeManager {
foreach (Type itype in ifaces){
MemberInfo [] x;
- x = MemberLookup (null, null, itype, mt, bf, name);
+ x = MemberLookup (null, null, itype, mt, bf, name, null);
if (x != null)
return x;
}
@@ -2573,85 +3250,30 @@ public class TypeManager {
return null;
}
- //
- // This is used to extract properties and event declarations from a type
- //
- static MemberInfo [] SpecialContainerLookup (Type t, bool is_static)
- {
- BindingFlags bf = BindingFlags.DeclaredOnly | (is_static ? BindingFlags.Static : BindingFlags.Instance);
-
- bf |= BindingFlags.Public | BindingFlags.NonPublic;
-
- if (t is TypeBuilder) {
- DeclSpace decl = (DeclSpace) builder_to_declspace [t];
-
- return (MemberInfo []) decl.FindMembers (
- MemberTypes.Property | MemberTypes.Event,
- bf, FilterNone_delegate, null);
- } else {
- return t.FindMembers (MemberTypes.Property | MemberTypes.Event,
- bf, FilterNone_delegate, null);
-
- }
- }
-
+ // Tests whether external method is really special
public static bool IsSpecialMethod (MethodBase mb)
{
- Type t = mb.DeclaringType;
-
- MemberInfo [] matches = TypeManager.SpecialContainerLookup (t, mb.IsStatic);
- if (matches == null)
- return false;
-
- foreach (MemberInfo mi in matches){
- if (mi is PropertyBuilder){
- Pair p = (Pair) properties [mi];
-
- if (p.First == mb || p.Second == mb)
- return true;
- } else if (mi is PropertyInfo){
- MethodInfo [] methods = ((PropertyInfo) mi).GetAccessors (true);
+ string name = mb.Name;
+ if (name.StartsWith ("get_") || name.StartsWith ("set_"))
+ return mb.DeclaringType.GetProperty (name.Substring (4)) != null;
- foreach (MethodInfo m in methods){
- if (m == mb)
- return true;
- }
- } else if (mi is MyEventBuilder){
- Pair p = (Pair) events [mi];
+ if (name.StartsWith ("add_"))
+ return mb.DeclaringType.GetEvent (name.Substring (4)) != null;
- if (p.First == mb || p.Second == mb)
- return true;
- } else if (mi is EventInfo){
- EventInfo ei = ((EventInfo) mi);
-
- if (ei.GetAddMethod (true) == mb)
- return true;
-
- if (ei.GetRemoveMethod (true) == mb)
- return true;
-
- if (ei.GetRaiseMethod (true) == mb)
- return true;
- }
- }
+ if (name.StartsWith ("remove_"))
+ return mb.DeclaringType.GetEvent (name.Substring (7)) != null;
- //
- // Now check if it is an operator method
- //
- string s = mb.Name;
-
- if (s.StartsWith ("op_")){
- foreach (string name in Unary.oper_names){
- if (s == name)
+ if (name.StartsWith ("op_")){
+ foreach (string oname in Unary.oper_names) {
+ if (oname == name)
return true;
}
- foreach (string name in Binary.oper_names){
- if (s == name)
+ foreach (string oname in Binary.oper_names) {
+ if (oname == name)
return true;
}
}
-
return false;
}
@@ -2683,6 +3305,11 @@ public sealed class TypeHandle : IMemberContainer {
type_hash.Add (t, handle);
return handle;
}
+
+ public static void CleanUp ()
+ {
+ type_hash = null;
+ }
///
/// Returns the TypeHandle for TypeManager.object_type.
@@ -2718,15 +3345,17 @@ public sealed class TypeHandle : IMemberContainer {
private static TypeHandle array_type = null;
private Type type;
+ private string full_name;
private bool is_interface;
private MemberCache member_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);
- this.is_interface = type.IsInterface;
+ this.is_interface = type.IsInterface || type.IsGenericParameter;
this.member_cache = new MemberCache (this);
}
@@ -2734,7 +3363,7 @@ public sealed class TypeHandle : IMemberContainer {
public string Name {
get {
- return type.FullName;
+ return full_name;
}
}
@@ -2744,7 +3373,7 @@ public sealed class TypeHandle : IMemberContainer {
}
}
- public IMemberContainer Parent {
+ public IMemberContainer ParentContainer {
get {
return BaseType;
}
@@ -2759,6 +3388,8 @@ public sealed class TypeHandle : IMemberContainer {
public MemberList GetMembers (MemberTypes mt, BindingFlags bf)
{
MemberInfo [] members;
+ if (type is GenericTypeParameterBuilder)
+ return MemberList.Empty;
if (mt == MemberTypes.Event)
members = type.GetEvents (bf | BindingFlags.DeclaredOnly);
else
@@ -2774,7 +3405,7 @@ public sealed class TypeHandle : IMemberContainer {
public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
MemberFilter filter, object criteria)
{
- return member_cache.FindMembers (mt, bf, name, filter, criteria);
+ return new MemberList (member_cache.FindMembers (mt, bf, name, filter, criteria));
}
public MemberCache MemberCache {