namespace Mono.CSharp {
-//#if GMCS_SOURCE
+#if GMCS_SOURCE
partial
-//#endif
+#endif
class TypeManager {
//
// A list of core types that the compiler requires or uses
#endif
// to uncover regressions
+ AllClsTopLevelTypes = null;
cons_param_array_attribute = null;
}
string parameters = iparams.GetSignatureForError ();
string accessor = "";
- // Is property
- if (mb.IsSpecialName) {
+ if (!mb.IsConstructor && TypeManager.IsSpecialMethod (mb)) {
Operator.OpType ot = Operator.GetOperatorType (mb.Name);
if (ot != Operator.OpType.TOP) {
sig.Append ("operator ");
return sig.ToString ();
}
- if (mb.Name.StartsWith ("get_") || mb.Name.StartsWith ("set_")) {
+ bool is_getter = mb.Name.StartsWith ("get_");
+ bool is_setter = mb.Name.StartsWith ("set_");
+ if (is_getter || is_setter) {
accessor = mb.Name.Substring (0, 3);
}
- }
- // Is indexer
- if (mb.IsSpecialName && !mb.IsConstructor) {
- if (iparams.Count > (mb.Name.StartsWith ("get_") ? 0 : 1)) {
+ // Is indexer
+ if (iparams.Count > (is_getter ? 0 : 1)) {
sig.Append ("this[");
- if (show_accessor) {
+ if (is_getter)
sig.Append (parameters.Substring (1, parameters.Length - 2));
- }
- else {
- int before_ret_val = parameters.LastIndexOf (',');
- if (before_ret_val < 0)
- sig.Append (parameters.Substring (1, parameters.Length - 2));
- else
- sig.Append (parameters.Substring (1, before_ret_val - 1));
- }
+ else
+ sig.Append (parameters.Substring (1, parameters.LastIndexOf (',') - 1));
sig.Append (']');
} else {
sig.Append (mb.Name.Substring (4));
static public string CSharpSignature (EventInfo ei)
{
- return CSharpName (ei.DeclaringType) + '.' + ei.Name;
+ return CSharpName (ei.DeclaringType) + "." + ei.Name;
}
/// <summary>
{
MemberCache cache;
+#if GMCS_SOURCE && MS_COMPATIBLE
+ if (t.IsGenericType && !t.IsGenericTypeDefinition)
+ t = t.GetGenericTypeDefinition();
+#endif
+
//
// If this is a dynamic type, it's always in the `builder_to_declspace' hash table
// and we can ask the DeclSpace for the MemberCache.
// a TypeBuilder array will return a Type, not a TypeBuilder,
// and we can not call FindMembers on this type.
//
- if (t == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) {
+ if (t.IsArray) { // == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) {
used_cache = true;
return TypeHandle.ArrayType.MemberCache.FindMembers (
mt, bf, name, FilterWithClosure_delegate, null);
return true;
#if MS_COMPATIBLE && GMCS_SOURCE
- if (t.IsGenericParameter)
+ if (t.IsGenericParameter || t.IsGenericType)
return false;
#endif
return t.IsEnum;
public static bool IsSubclassOf (Type type, Type base_type)
{
- // TODO: msaf
-// if (base_type.IsSealed)
-// {
-// Console.WriteLine ("Is sealed " + TypeManager.CSharpName (base_type));
-// return false;
-// }
-
TypeParameter tparam = LookupTypeParameter (type);
TypeParameter pparam = LookupTypeParameter (base_type);
public static bool IsEqual (Type a, Type b)
{
if (a.Equals (b)) {
- // MS BCL returns true even when enum types arer different
+ // MS BCL returns true even if enum types are different
if (a.BaseType == TypeManager.enum_type || b.BaseType == TypeManager.enum_type)
return a.FullName == b.FullName;
BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
+#if MS_COMPATIBLE
+ return m;
+#endif
+
if (m is ConstructorInfo) {
foreach (ConstructorInfo c in t.GetConstructors (bf))
if (c.MetadataToken == m.MetadataToken)
return null;
}
- // Tests whether external method is really special
- public static bool IsSpecialMethod (MethodBase mb)
+ const BindingFlags AllMembers = BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.Static | BindingFlags.Instance |
+ BindingFlags.DeclaredOnly;
+
+ // Currently is designed to work with external types only
+ public static PropertyInfo GetPropertyFromAccessor (MethodBase mb)
{
+ if (!mb.IsSpecialName)
+ return null;
+
string name = mb.Name;
- if (name.StartsWith ("get_") || name.StartsWith ("set_"))
- return mb.DeclaringType.GetProperty (name.Substring (4)) != null;
-
+ if (name.Length < 5)
+ return null;
+
+ if (name [3] != '_')
+ return null;
+
+ if (name.StartsWith ("get") || name.StartsWith ("set")) {
+ MemberInfo[] pi = mb.DeclaringType.FindMembers (MemberTypes.Property, AllMembers,
+ Type.FilterName, name.Substring (4));
+
+ if (pi == null)
+ return null;
+
+ // This can happen when property is indexer (it can have same name but different parameters)
+ foreach (PropertyInfo p in pi) {
+ foreach (MethodInfo p_mi in p.GetAccessors (true)) {
+ if (p_mi == mb || TypeManager.GetParameterData (p_mi).Equals (TypeManager.GetParameterData (mb)))
+ return p;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ // Currently is designed to work with external types only
+ public static MemberInfo GetEventFromAccessor (MethodBase mb)
+ {
+ if (!mb.IsSpecialName)
+ return null;
+
+ string name = mb.Name;
+ if (name.Length < 5)
+ return null;
+
if (name.StartsWith ("add_"))
- return mb.DeclaringType.GetEvent (name.Substring (4)) != null;
+ return mb.DeclaringType.GetEvent (name.Substring (4), AllMembers);
if (name.StartsWith ("remove_"))
- return mb.DeclaringType.GetEvent (name.Substring (7)) != null;
+ return mb.DeclaringType.GetEvent (name.Substring (7), AllMembers);
+ return null;
+ }
+
+ // Tests whether external method is really special
+ public static bool IsSpecialMethod (MethodBase mb)
+ {
+ if (!mb.IsSpecialName)
+ return false;
+
+ IMethodData md = TypeManager.GetMethod (mb);
+ if (md != null)
+ return (md is AbstractPropertyEventMethod || md is Operator);
+
+ PropertyInfo pi = GetPropertyFromAccessor (mb);
+ if (pi != null)
+ return IsValidProperty (pi);
+
+ if (GetEventFromAccessor (mb) != null)
+ return true;
+
+ string name = mb.Name;
if (name.StartsWith ("op_")){
foreach (string oname in Unary.oper_names) {
if (oname == name)
return false;
}
+ // Tests whether imported property is valid C# property.
+ // TODO: It seems to me that we should do a lot of sanity tests before
+ // we accept property as C# property
+ static bool IsValidProperty (PropertyInfo pi)
+ {
+ MethodInfo get_method = pi.GetGetMethod (true);
+ MethodInfo set_method = pi.GetSetMethod (true);
+ if (get_method != null && set_method != null) {
+ int g_count = get_method.GetParameters ().Length;
+ int s_count = set_method.GetParameters ().Length;
+ if (g_count + 1 != s_count)
+ return false;
+ }
+ return true;
+ }
+
#endregion
}