// (C) 2001 Ximian, Inc (http://www.ximian.com)
//
//
+
+//
+// We will eventually remove the SIMPLE_SPEEDUP, and should never change
+// the behavior of the compilation. This can be removed if we rework
+// the code to get a list of namespaces available.
+//
+#define SIMPLE_SPEEDUP
+
using System;
using System.Globalization;
using System.Collections;
modules = n;
}
+ //
+ // Low-level lookup, cache-less
+ //
+ static Type LookupTypeReflection (string name)
+ {
+ Type t;
+
+ foreach (Assembly a in assemblies){
+ t = a.GetType (name);
+ if (t != null)
+ return t;
+ }
+
+ foreach (ModuleBuilder mb in modules) {
+ t = mb.GetType (name);
+ if (t != null){
+ return 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;
+ }
+
/// <summary>
- /// Returns the Type associated with @name
+ /// 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)
{
if (t != null)
return t;
- foreach (Assembly a in assemblies){
- t = a.GetType (name);
- if (t != null){
- types [name] = t;
+#if SIMPLE_SPEEDUP
+ if (negative_hits.Contains (name))
+ return null;
+#endif
+
+ //
+ // Optimization: ComposedCast will work with an existing type, and might already have the
+ // full name of the type, so the full system lookup can probably be avoided.
+ //
+
+ string [] elements = name.Split ('.');
+ int count = elements.Length;
+
+ for (int n = 1; n <= count; n++){
+ string top_level_type = String.Join (".", elements, 0, n);
+ t = (Type) types [top_level_type];
+ if (t == null){
+ t = LookupTypeReflection (top_level_type);
+ if (t == 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);
+ t = LookupTypeDirect (newt);
+ if (t != null)
+ types [newt] = t;
+ return t;
+ }
+
+#if SIMPLE_SPEEDUP
+ negative_hits [name] = true;
+#endif
+ return null;
+ }
+
+ //
+ // Returns a list of all namespaces in the assemblies and types loaded.
+ //
+ public static Hashtable GetNamespaces ()
+ {
+ Hashtable namespaces = new Hashtable ();
+
+ foreach (Assembly a in assemblies){
+ foreach (Type t in a.GetTypes ()){
+ string ns = t.Namespace;
+
+ if (namespaces.Contains (ns))
+ continue;
+ namespaces [ns] = ns;
}
}
- foreach (ModuleBuilder mb in modules) {
- t = mb.GetType (name);
- if (t != null) {
- types [name] = t;
- return t;
+ foreach (ModuleBuilder mb in modules){
+ foreach (Type t in mb.GetTypes ()){
+ string ns = t.Namespace;
+
+ if (namespaces.Contains (ns))
+ continue;
+ namespaces [ns] = ns;
}
}
-
- return null;
+ Console.WriteLine ("Namespaces: " + namespaces.Count);
+ return namespaces;
}
+ public static void GetAllTypes ()
+ {
+ Hashtable namespaces = new Hashtable ();
+
+ foreach (Assembly a in assemblies){
+ foreach (Type t in a.GetTypes ()){
+ }
+ }
+
+ foreach (ModuleBuilder mb in modules){
+ foreach (Type t in mb.GetTypes ()){
+ }
+ }
+ }
+
/// <summary>
/// Returns the C# name of a type if possible, or the full type name otherwise
/// </summary>
else
return false;
}
-
+
+ //
+ // Whether a type is unmanaged. This is used by the unsafe code (25.2)
+ //
+ public static bool IsUnmanagedType (Type t)
+ {
+ if (IsBuiltinType (t) && t != TypeManager.string_type)
+ return true;
+
+ if (IsEnumType (t))
+ return true;
+
+ if (t.IsPointer)
+ return true;
+
+ if (IsValueType (t)){
+ if (t is TypeBuilder){
+ TypeContainer tc = LookupTypeContainer (t);
+
+ foreach (Field f in tc.Fields){
+ if (f.FieldBuilder.IsStatic)
+ continue;
+ if (!IsUnmanagedType (f.FieldBuilder.FieldType))
+ return false;
+ }
+ } else {
+ FieldInfo [] fields = t.GetFields ();
+
+ foreach (FieldInfo f in fields){
+ if (f.IsStatic)
+ continue;
+ if (!IsUnmanagedType (f.FieldType))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
+ }
+
public static bool IsValueType (Type t)
{
if (t.IsSubclassOf (TypeManager.value_type))
return false;
}
+ //
+ // Checks whether `type' is a nested child of `parent'.
+ //
+ public static bool IsNestedChildOf (Type type, Type parent)
+ {
+ if ((type == parent) || type.IsSubclassOf (parent))
+ return false;
+ else
+ return IsSubclassOrNestedChildOf (type, parent);
+ }
+
/// <summary>
/// Returns the User Defined Types
/// </summary>
return true;
}
- //
- // FIXME: we need to return the accessors depending on whether
- // they are visible or not.
- //
- static public MethodInfo [] GetAccessors (PropertyInfo pi)
- {
- MethodInfo [] ret;
-
- if (pi is PropertyBuilder){
- Pair pair = (Pair) properties [pi];
-
- ret = new MethodInfo [2];
- ret [0] = (MethodInfo) pair.First;
- ret [1] = (MethodInfo) pair.Second;
-
- return ret;
- } else {
- MethodInfo [] mi = new MethodInfo [2];
-
- //
- // Why this and not pi.GetAccessors?
- // Because sometimes index 0 is the getter
- // sometimes it is 1
- //
- mi [0] = pi.GetGetMethod (true);
- mi [1] = pi.GetSetMethod (true);
-
- return mi;
- }
- }
-
- static public MethodInfo GetPropertyGetter (PropertyInfo pi)
- {
- if (pi is PropertyBuilder){
- Pair de = (Pair) properties [pi];
-
- return (MethodInfo) de.Second;
- } else
- return pi.GetSetMethod ();
- }
-
- static public MethodInfo GetPropertySetter (PropertyInfo pi)
- {
- if (pi is PropertyBuilder){
- Pair de = (Pair) properties [pi];
-
- return (MethodInfo) de.First;
- } else
- return pi.GetGetMethod ();
- }
-
/// <summary>
/// Given an array of interface types, expand and eliminate repeated ocurrences
/// of an interface.
if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
return false;
- if (closure_start_type == closure_invocation_type)
+ if ((closure_start_type == closure_invocation_type) &&
+ (m.DeclaringType == closure_invocation_type))
return true;
//
// 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 ((closure_invocation_type != closure_start_type) &&
+ if (!mb.IsStatic && (closure_invocation_type != closure_start_type) &&
closure_invocation_type.IsSubclassOf (closure_start_type))
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 ((closure_invocation_type != closure_start_type) &&
+ if (!fi.IsStatic && (closure_invocation_type != closure_start_type) &&
closure_invocation_type.IsSubclassOf (closure_start_type))
return false;
}
//
- // EventInfos and PropertyInfos, return true
+ // EventInfos and PropertyInfos, return true because they lack permission
+ // informaiton, so we need to check later on the methods.
//
return true;
}
private_ok = true;
} else
private_ok = always_ok_flag;
-
+
if (private_ok || invocation_type.IsSubclassOf (current_type))
bf = original_bf | BindingFlags.NonPublic;
} else {