namespace Mono.CSharp {
-public partial class TypeManager {
+#if GMCS_SOURCE
+ partial
+#endif
+ class TypeManager {
//
// A list of core types that the compiler requires or uses
//
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 icloneable_type;
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 string_isinterned_string;
static public MethodInfo system_type_get_type_from_handle;
static public MethodInfo bool_movenext_void;
static public MethodInfo ienumerable_getenumerator_void;
builder_to_method = null;
fields = null;
- fieldbuilders_to_fields = null;
events = null;
- priv_fields_events = null;
type_hash = null;
propertybuilder_to_property = null;
#endif
// to uncover regressions
+ AllClsTopLevelTypes = null;
cons_param_array_attribute = null;
}
public static MemberCache LookupMemberCache (Type t)
{
-#if GMCS_SOURCE && MS_COMPATIBLE
- if (t.IsGenericType && !t.IsGenericTypeDefinition)
- t = t.GetGenericTypeDefinition ();
-#endif
-
if (t is TypeBuilder) {
IMemberContainer container = builder_to_declspace [t] as IMemberContainer;
if (container != null)
+ match.Groups [2].Captures [0].Value;
}
+ // Used for error reporting to show symbolic name instead of underlying value
+ public static string CSharpEnumValue (Type t, object value)
+ {
+ Enum e = LookupDeclSpace (t) as Enum;
+ if (e == null)
+ return System.Enum.GetName (t, value);
+
+ return e.GetDefinition (value).GetSignatureForError ();
+ }
+
/// <summary>
/// Returns the signature of the method with full namespace classification
/// </summary>
ParameterData iparams = GetParameterData (mb);
string parameters = iparams.GetSignatureForError ();
- string accessor = "";
+ int accessor_end = 0;
- // 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_")) {
- accessor = mb.Name.Substring (0, 3);
+ bool is_getter = mb.Name.StartsWith ("get_");
+ bool is_setter = mb.Name.StartsWith ("set_");
+ if (is_getter || is_setter || mb.Name.StartsWith ("add_")) {
+ accessor_end = 3;
+ } else if (mb.Name.StartsWith ("remove_")) {
+ accessor_end = 6;
}
- }
- // 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));
+ sig.Append (mb.Name.Substring (accessor_end + 1));
}
} else {
if (mb.Name == ".ctor")
sig.Append (parameters);
}
- if (show_accessor && accessor.Length > 0) {
+ if (show_accessor && accessor_end > 0) {
sig.Append ('.');
- sig.Append (accessor);
+ sig.Append (mb.Name.Substring (0, accessor_end));
}
return sig.ToString ();
static public string CSharpSignature (EventInfo ei)
{
- return CSharpName (ei.DeclaringType) + '.' + ei.Name;
+ return CSharpName (ei.DeclaringType) + "." + ei.Name;
}
/// <summary>
Namespace ns = RootNamespace.Global.GetNamespace (ns_name, true);
FullNamedExpression fne = ns.Lookup (RootContext.ToplevelTypes, name, Location.Null);
Type t = fne == null ? null : fne.Type;
- if (t == null)
+ if (t == null) {
Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
+ return null;
+ }
+
+ AttributeTester.RegisterNonObsoleteType (t);
return t;
}
public static void InitCoreTypes ()
{
object_type = CoreLookupType ("System", "Object");
+ system_object_expr.Type = object_type;
value_type = CoreLookupType ("System", "ValueType");
+ system_valuetype_expr.Type = value_type;
InitEnumUnderlyingTypes ();
}
}
- 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_void_expr.Type = void_type;
system_asynccallback_expr.Type = asynccallback_type;
system_iasyncresult_expr.Type = iasyncresult_type;
- system_valuetype_expr.Type = value_type;
//
// These are only used for compare purposes
string_type, "Concat", params_object);
Type [] string_ = { string_type };
- string_isinterneted_string = GetMethod (
+ string_isinterned_string = GetMethod (
string_type, "IsInterned", string_);
Type [] runtime_type_handle = { runtime_handle_type };
MemberFilter filter, object criteria)
{
#if MS_COMPATIBLE && GMCS_SOURCE
- if (t.IsGenericType && !t.IsGenericTypeDefinition)
+ if (t.IsGenericType)
t = t.GetGenericTypeDefinition ();
#endif
if (t is TypeBuilder) {
TypeContainer tc = LookupTypeContainer (t);
if (tc.Fields != null){
- foreach (FieldMember f in tc.Fields){
+ foreach (FieldBase f in tc.Fields){
// Avoid using f.FieldBuilder: f.Define () may not yet have been invoked.
if ((f.ModFlags & Modifiers.STATIC) != 0)
continue;
return (PropertyBase)propertybuilder_to_property [pi];
}
- static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f)
+ static public void RegisterFieldBase (FieldBuilder fb, FieldBase f)
{
- if (fieldbuilders_to_fields.Contains (fb))
- return false;
-
fieldbuilders_to_fields.Add (fb, f);
- return true;
}
//
#endif
return (FieldBase) fieldbuilders_to_fields [fb];
}
-
- static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
- {
- if (events == null)
- events = new Hashtable ();
-
- if (!events.Contains (eb)) {
- events.Add (eb, new Pair (add, remove));
- }
- }
static public MethodInfo GetAddMethod (EventInfo ei)
{
if (ei is MyEventBuilder) {
- Pair pair = (Pair) events [ei];
-
- return (MethodInfo) pair.First;
+ return ((MyEventBuilder)ei).GetAddMethod (true);
}
return ei.GetAddMethod (true);
}
static public MethodInfo GetRemoveMethod (EventInfo ei)
{
if (ei is MyEventBuilder) {
- Pair pair = (Pair) events [ei];
-
- return (MethodInfo) pair.Second;
+ return ((MyEventBuilder)ei).GetRemoveMethod (true);
}
return ei.GetRemoveMethod (true);
}
- static Hashtable priv_fields_events;
-
- static public bool RegisterPrivateFieldOfEvent (EventInfo einfo, FieldBuilder builder)
+ static public void RegisterEventField (EventInfo einfo, EventField e)
{
- if (priv_fields_events == null)
- priv_fields_events = new Hashtable ();
-
- if (priv_fields_events.Contains (einfo))
- return false;
-
- priv_fields_events.Add (einfo, builder);
+ if (events == null)
+ events = new Hashtable ();
- return true;
+ events.Add (einfo, e);
}
- static public MemberInfo GetPrivateFieldOfEvent (EventInfo ei)
+ static public EventField GetEventField (EventInfo ei)
{
- if (priv_fields_events == null)
+ if (events == null)
return null;
- else
- return (MemberInfo) priv_fields_events [ei];
+
+ return (EventField) events [ei];
}
-
+
static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get,
MethodBase set, Type[] args)
{
if (tc.Fields == null)
return true;
- foreach (FieldMember field in tc.Fields) {
+ foreach (FieldBase field in tc.Fields) {
if (field.FieldBuilder == null || field.FieldBuilder.IsStatic)
continue;
public static bool IsEqual (Type a, Type b)
{
- if (a.Equals (b))
+ if (a.Equals (b)) {
+ // 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;
+
return true;
+ }
#if GMCS_SOURCE
if (a.IsGenericParameter && b.IsGenericParameter) {
BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
#if MS_COMPATIBLE
- return m;
+ return m;
#endif
if (m is ConstructorInfo) {
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
}