// Ravi Pratap (ravi@ximian.com)
// Marek Safar (marek.safar@seznam.cz)
//
-// Licensed under the terms of the GNU GPL
-//
-// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// Dual licensed under the terms of the MIT X11 or GNU GPL
//
+// Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+// Copyright 2003-2008 Novell, Inc.
//
//
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
-using System.Text.RegularExpressions;
using System.Runtime.CompilerServices;
using System.Diagnostics;
static public Type decimal_constant_attribute_type;
static public Type dllimport_type;
static public Type methodimpl_attr_type;
+#if !NET_2_0
static public Type marshal_as_attr_type;
+#endif
static public Type param_array_type;
static public Type void_ptr_type;
static public Type indexer_name_type;
static internal Type fixed_buffer_attr_type;
static internal Type default_charset_type;
static internal Type type_forwarder_attr_type;
- static public Type activator_type;
+ static internal Type isvolatile_type;
static public Type generic_ilist_type;
static public Type generic_icollection_type;
static public Type generic_ienumerator_type;
//
// These methods are called by code generated by the compiler
//
- static public MethodInfo string_isinterned_string;
+ static public FieldInfo string_empty;
static public MethodInfo system_type_get_type_from_handle;
static public MethodInfo bool_movenext_void;
static public MethodInfo void_dispose_void;
static public MethodInfo void_monitor_enter_object;
static public MethodInfo void_monitor_exit_object;
static public MethodInfo void_initializearray_array_fieldhandle;
- static public MethodInfo int_getlength_int;
static public MethodInfo delegate_combine_delegate_delegate;
static public MethodInfo delegate_remove_delegate_delegate;
static public MethodInfo int_get_offset_to_string_data;
static public MethodInfo int_interlocked_compare_exchange;
static public PropertyInfo ienumerator_getcurrent;
public static MethodInfo methodbase_get_type_from_handle;
+ public static MethodInfo methodbase_get_type_from_handle_generic;
+ public static MethodInfo fieldinfo_get_field_from_handle;
static public MethodInfo activator_create_instance;
//
static public CustomAttributeBuilder param_array_attr;
static CustomAttributeBuilder compiler_generated_attr;
+ static CustomAttributeBuilder debugger_hidden_attr;
// C# 2.0
static internal ConstructorInfo fixed_buffer_attr_ctor;
+ static internal CustomAttributeBuilder unsafe_value_type_attr;
// C# 3.0
static internal CustomAttributeBuilder extension_attribute_attr;
// </remarks>
static PtrHashtable builder_to_ifaces;
- // <remarks>
- // Maps PropertyBuilder to a Type array that contains
- // the arguments to the indexer
- // </remarks>
- static Hashtable indexer_arguments;
-
// <remarks>
// Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
// <remarks>
builder_to_member_cache = null;
builder_to_ifaces = null;
builder_to_type_param = null;
- indexer_arguments = null;
method_params = null;
builder_to_method = null;
builder_to_type_param = new PtrHashtable ();
method_params = new PtrHashtable ();
method_overrides = new PtrHashtable ();
- indexer_arguments = new PtrHashtable ();
builder_to_ifaces = new PtrHashtable ();
fieldbuilders_to_fields = new Hashtable ();
assembly_internals_vis_attrs = new PtrHashtable ();
// TODO: I am really bored by all this static stuff
- string_isinterned_string =
system_type_get_type_from_handle =
bool_movenext_void =
void_dispose_void =
void_monitor_enter_object =
void_monitor_exit_object =
void_initializearray_array_fieldhandle =
- int_getlength_int =
delegate_combine_delegate_delegate =
delegate_remove_delegate_delegate =
int_get_offset_to_string_data =
int_interlocked_compare_exchange =
methodbase_get_type_from_handle =
+ methodbase_get_type_from_handle_generic =
+ fieldinfo_get_field_from_handle =
activator_create_instance = null;
ienumerator_getcurrent = null;
param_array_attr =
compiler_generated_attr =
+ unsafe_value_type_attr =
extension_attribute_attr = null;
+
+ isvolatile_type = null;
// to uncover regressions
AllClsTopLevelTypes = null;
return compiler_generated_attr;
}
+ public static CustomAttributeBuilder GetDebuggerHiddenAttribute (Location loc)
+ {
+ if (debugger_hidden_attr != null)
+ return debugger_hidden_attr;
+
+ Type t = TypeManager.CoreLookupType (
+ "System.Diagnostics", "DebuggerHiddenAttribute", Kind.Class, true);
+
+ // TODO: it cannot be null
+ if (t == null)
+ return null;
+
+ debugger_hidden_attr = new CustomAttributeBuilder (
+ GetPredefinedConstructor (t, loc, Type.EmptyTypes), new object[0]);
+
+ return debugger_hidden_attr;
+ }
+
public static Type GetNestedType (Type t, string name)
{
object ret = null;
if (t == typeof (ArglistParameter))
return "__arglist";
- if (t == typeof (AnonymousMethod))
+ if (t == typeof (AnonymousMethodBody))
return "anonymous method";
- return CSharpName (GetFullName (t));
- }
+ if (t == null)
+ return "internal error";
+
+ return CSharpName (GetFullName (t), t);
+ }
+
+ static readonly char [] elements = new char [] { '*', '[' };
+
+ public static string CSharpName (string name, Type type)
+ {
+ if (name.Length > 10) {
+ string s;
+ switch (name) {
+ case "System.Int32": s = "int"; break;
+ case "System.Int64": s = "long"; break;
+ case "System.String": s = "string"; break;
+ case "System.Boolean": s = "bool"; break;
+ case "System.Void": s = "void"; break;
+ case "System.Object": s = "object"; break;
+ case "System.UInt32": s = "uint"; break;
+ case "System.Int16": s = "short"; break;
+ case "System.UInt16": s = "ushort"; break;
+ case "System.UInt64": s = "ulong"; break;
+ case "System.Single": s = "float"; break;
+ case "System.Double": s = "double"; break;
+ case "System.Decimal": s = "decimal"; break;
+ case "System.Char": s = "char"; break;
+ case "System.Byte": s = "byte"; break;
+ case "System.SByte": s = "sbyte"; break;
+ default: s = null; break;
+ }
- public static string CSharpName (string name)
- {
- if (name.StartsWith (AnonymousTypeClass.ClassNamePrefix))
- return AnonymousTypeClass.SignatureForError;
-
- return Regex.Replace (name,
- @"^System\." +
- @"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
- @"Single|Double|Char|Decimal|Byte|SByte|Object|" +
- @"Boolean|String|Void|Null)" +
- @"(\W+|\b)",
- new MatchEvaluator (CSharpNameMatch)).Replace ('+', '.');
+ if (s != null) {
+ //
+ // Predefined names can come from mscorlib only
+ //
+ if (type == null || type.Module.Name == "mscorlib.dll" || !RootContext.StdLib)
+ return s;
+
+ return name;
+ }
+
+ int idx = name.IndexOfAny (elements, 10);
+ if (idx > 0)
+ return CSharpName (name.Substring (0, idx), type) + name.Substring (idx);
+ }
+
+ if (name [0] == AnonymousTypeClass.ClassNamePrefix [0] && name.StartsWith (AnonymousTypeClass.ClassNamePrefix))
+ return AnonymousTypeClass.SignatureForError;
+
+ return name.Replace ('+', '.');
}
static public string CSharpName (Type[] types)
}
return sb.ToString ();
}
-
- static String CSharpNameMatch (Match match)
- {
- string s = match.Groups [1].Captures [0].Value;
- return s.ToLower ().
- Replace ("int32", "int").
- Replace ("uint32", "uint").
- Replace ("int16", "short").
- Replace ("uint16", "ushort").
- Replace ("int64", "long").
- Replace ("uint64", "ulong").
- Replace ("single", "float").
- Replace ("boolean", "bool")
- + 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)
- {
- t = DropGenericTypeArguments (t);
- Enum e = LookupDeclSpace (t) as Enum;
- if (e == null)
- return System.Enum.GetName (t, value);
-
- return e.GetDefinition (value).GetSignatureForError ();
- }
-
- /// <summary>
+ /// <summary>
/// Returns the signature of the method with full namespace classification
/// </summary>
static public string GetFullNameSignature (MemberInfo mi)
StringBuilder sig = new StringBuilder (CSharpName (mb.DeclaringType));
sig.Append ('.');
- ParameterData iparams = GetParameterData (mb);
+ AParametersCollection iparams = GetParameterData (mb);
string parameters = iparams.GetSignatureForError ();
int accessor_end = 0;
if (!mb.IsConstructor && TypeManager.IsSpecialMethod (mb)) {
- Operator.OpType ot = Operator.GetOperatorType (mb.Name);
- if (ot != Operator.OpType.TOP) {
- sig.Append ("operator ");
- sig.Append (Operator.GetName (ot));
+ string op_name = Operator.GetName (mb.Name);
+ if (op_name != null) {
+ if (op_name == "explicit" || op_name == "implicit") {
+ sig.Append (op_name);
+ sig.Append (" operator ");
+ sig.Append (CSharpName (((MethodInfo)mb).ReturnType));
+ } else {
+ sig.Append ("operator ");
+ sig.Append (op_name);
+ }
sig.Append (parameters);
return sig.ToString ();
}
if (mb == null)
continue;
- ParameterData pd = TypeManager.GetParameterData (mb);
+ AParametersCollection pd = TypeManager.GetParameterData (mb);
if (IsEqual (pd.Types, args))
return member;
}
//
public static void InitOptionalCoreTypes ()
{
+ 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;
+
+ //
+ // These are only used for compare purposes
+ //
+ anonymous_method_type = typeof (AnonymousMethodBody);
+ null_type = typeof (NullLiteral);
+
void_ptr_type = GetPointerType (void_type);
char_ptr_type = GetPointerType (char_type);
+ //
+ // Initialize InternalsVisibleTo as the very first optional type. Otherwise we would populate
+ // types cache with incorrect accessiblity when any of optional types is internal.
+ //
+ internals_visible_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute", Kind.Class, false);
+
runtime_argument_handle_type = CoreLookupType ("System", "RuntimeArgumentHandle", Kind.Struct, false);
asynccallback_type = CoreLookupType ("System", "AsyncCallback", Kind.Delegate, false);
iasyncresult_type = CoreLookupType ("System", "IAsyncResult", Kind.Interface, false);
if (obsolete_attribute_type != null) {
Class c = TypeManager.LookupClass (obsolete_attribute_type);
if (c != null)
- c.DefineMembers ();
+ c.Define ();
}
dllimport_type = CoreLookupType ("System.Runtime.InteropServices", "DllImportAttribute", Kind.Class, false);
methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "MethodImplAttribute", Kind.Class, false);
+#if !NET_2_0
marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices", "MarshalAsAttribute", Kind.Class, false);
+#endif
in_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "InAttribute", Kind.Class, false);
indexer_name_type = CoreLookupType ("System.Runtime.CompilerServices", "IndexerNameAttribute", Kind.Class, false);
conditional_attribute_type = CoreLookupType ("System.Diagnostics", "ConditionalAttribute", Kind.Class, false);
comimport_attr_type = CoreLookupType ("System.Runtime.InteropServices", "ComImportAttribute", Kind.Class, false);
coclass_attr_type = CoreLookupType ("System.Runtime.InteropServices", "CoClassAttribute", Kind.Class, false);
attribute_usage_type = CoreLookupType ("System", "AttributeUsageAttribute", Kind.Class, false);
- internals_visible_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute", Kind.Class, false);
default_parameter_value_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "DefaultParameterValueAttribute", Kind.Class, false);
// New in .NET 2.0
TypeManager.CSharpName (system_4_type_arg));
}
}
-
- 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;
-
- //
- // These are only used for compare purposes
- //
- anonymous_method_type = typeof (AnonymousMethod);
- null_type = typeof (NullLiteral);
}
const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
return false;
#endif
- if (t == TypeManager.delegate_type)
+ if (t == TypeManager.delegate_type || t == TypeManager.multicast_delegate_type)
return false;
t = DropGenericTypeArguments (t);
return retval;
}
-
+
+ //
+ // Null is considered to be a reference type
+ //
public static bool IsReferenceType (Type t)
{
if (TypeManager.IsGenericParameter (t)) {
return constraints.IsReferenceType;
}
- if (t == TypeManager.null_type)
- return false;
-
return !t.IsValueType;
}
return false;
}
+ public static bool IsSpecialType (Type t)
+ {
+ return t == arg_iterator_type || t == typed_reference_type;
+ }
+
//
// Checks whether `extern_type' is friend of the output assembly
//
return is_friend;
}
+#if GMCS_SOURCE
static bool CompareKeyTokens (byte [] token1, byte [] token2)
{
for (int i = 0; i < token1.Length; i++)
return true;
}
-#if GMCS_SOURCE
static void Error_FriendAccessNameNotMatching (string other_name)
{
- Report.Error (281, "Friend access was granted to `" + other_name +
- "', but the output assembly is named `" + CodeGen.Assembly.Name.FullName +
- "'. Try adding a reference to `" + other_name +
- "' or change the output assembly name to match it");
+ Report.Error (281,
+ "Friend access was granted to `{0}', but the output assembly is named `{1}'. Try adding a reference to `{0}' or change the output assembly name to match it",
+ other_name, CodeGen.Assembly.Name.FullName);
}
#endif
return e.UnderlyingType;
// TODO: cache it ?
- FieldInfo fi = GetPredefinedField (t, Enum.UnderlyingValueField, Location.Null);
+ FieldInfo fi = GetPredefinedField (t, Enum.UnderlyingValueField, Location.Null, Type.EmptyTypes);
if (fi == null)
return TypeManager.int32_type;
/// for anything which is dynamic, and we need this in a number of places,
/// we register this information here, and use it afterwards.
/// </remarks>
- static public void RegisterMethod (MethodBase mb, Parameters ip)
+ static public void RegisterMethod (MethodBase mb, AParametersCollection ip)
{
method_params.Add (mb, ip);
}
+
+ static public void RegisterIndexer (PropertyBuilder pb, AParametersCollection p)
+ {
+ method_params.Add (pb, p);
+ }
- static public ParameterData GetParameterData (MethodBase mb)
+ static public AParametersCollection GetParameterData (MethodBase mb)
{
- ParameterData pd = (ParameterData)method_params [mb];
+ AParametersCollection pd = (AParametersCollection) method_params [mb];
if (pd == null) {
#if MS_COMPATIBLE
if (mb.IsGenericMethod && !mb.IsGenericMethodDefinition) {
MethodInfo mi = ((MethodInfo) mb).GetGenericMethodDefinition ();
pd = GetParameterData (mi);
+ /*
if (mi.IsGenericMethod)
pd = pd.InflateTypes (mi.GetGenericArguments (), mb.GetGenericArguments ());
else
pd = pd.InflateTypes (mi.DeclaringType.GetGenericArguments (), mb.GetGenericArguments ());
+ */
method_params.Add (mb, pd);
return pd;
}
throw new InternalErrorException ("Parameters are not registered for method `{0}'",
TypeManager.CSharpName (mb.DeclaringType) + "." + mb.Name);
}
+
+ pd = ParametersCollection.Create (mb);
+#else
+ MethodBase generic = TypeManager.DropGenericMethodArguments (mb);
+ if (generic != mb) {
+ pd = TypeManager.GetParameterData (generic);
+ pd = ParametersCollection.Create (pd, mb);
+ } else {
+ pd = ParametersCollection.Create (mb);
+ }
#endif
- pd = new ReflectionParameters (mb);
method_params.Add (mb, pd);
}
return pd;
}
- public static ParameterData GetDelegateParameters (Type t)
+ public static AParametersCollection GetParameterData (PropertyInfo pi)
+ {
+ AParametersCollection pd = (AParametersCollection)method_params [pi];
+ if (pd == null) {
+ if (pi is PropertyBuilder)
+ return Parameters.EmptyReadOnlyParameters;
+
+ ParameterInfo [] p = pi.GetIndexParameters ();
+ if (p == null)
+ return Parameters.EmptyReadOnlyParameters;
+
+ pd = ParametersCollection.Create (p, null);
+ method_params.Add (pi, pd);
+ }
+
+ return pd;
+ }
+
+ public static AParametersCollection GetDelegateParameters (Type t)
{
Delegate d = builder_to_declspace [t] as Delegate;
if (d != null)
return (MethodBase) method_overrides [m];
}
- /// <summary>
- /// Returns the argument types for an indexer based on its PropertyInfo
- ///
- /// For dynamic indexers, we use the compiler provided types, for
- /// indexers from existing assemblies we load them from GetParameters,
- /// and insert them into the cache
- /// </summary>
- static public Type [] GetArgumentTypes (PropertyInfo indexer)
- {
- if (indexer_arguments.Contains (indexer))
- return (Type []) indexer_arguments [indexer];
- else if (indexer is PropertyBuilder)
- // If we're a PropertyBuilder and not in the
- // `indexer_arguments' hash, then we're a property and
- // not an indexer.
- return Type.EmptyTypes;
- else {
- ParameterInfo [] pi = indexer.GetIndexParameters ();
- // Property, not an indexer.
- if (pi == null)
- return Type.EmptyTypes;
- int c = pi.Length;
- Type [] types = new Type [c];
-
- for (int i = 0; i < c; i++)
- types [i] = pi [i].ParameterType;
-
- indexer_arguments.Add (indexer, types);
- return types;
- }
- }
-
public static void RegisterConstant (FieldInfo fb, IConstant ic)
{
fields.Add (fb, ic);
return (EventField) events [ei];
}
- static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get,
- MethodBase set, Type[] args)
- {
- indexer_arguments.Add (pb, args);
-
- return true;
- }
-
public static bool CheckStructCycles (TypeContainer tc, Hashtable seen)
{
Hashtable hash = new Hashtable ();
//
// Returns whether the array of memberinfos contains the given method
//
- public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method)
+ public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method, bool ignoreDeclType)
{
Type [] new_args = TypeManager.GetParameterData (new_method).Types;
foreach (MethodBase method in array) {
+ if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
+ continue;
+
if (method.Name != new_method.Name)
continue;
foreach (MemberInfo mi in new_members){
MethodBase new_method = (MethodBase) mi;
- if (!ArrayContainsMethod (target_array, new_method))
+ if (!ArrayContainsMethod (target_array, new_method, true))
target_list.Add (new_method);
}
return target_list;
if (a.BaseType == TypeManager.enum_type || b.BaseType == TypeManager.enum_type)
return a.FullName == b.FullName;
+ // Some types are never equal
+ if (a == TypeManager.null_type || a == TypeManager.anonymous_method_type)
+ return false;
+
return true;
}
public static bool IsEqual (Type[] a, Type[] b)
{
- if (a.Length != b.Length)
+ if (a == null || b == null || a.Length != b.Length)
return false;
for (int i = 0; i < a.Length; ++i) {
+ if (a [i] == null || b [i] == null) {
+ if (a [i] == b [i])
+ continue;
+
+ return false;
+ }
+
if (!IsEqual (a [i], b [i]))
return false;
}
return true;
string name = mb.Name;
- if (name.StartsWith ("op_")){
- foreach (string oname in Unary.oper_names) {
- if (oname == name)
- return true;
- }
+ if (name.StartsWith ("op_"))
+ return Operator.GetName (name) != null;
- foreach (string oname in Binary.oper_names) {
- if (oname == name)
- return true;
- }
- }
return false;
}
{
MethodInfo get_method = pi.GetGetMethod (true);
MethodInfo set_method = pi.GetSetMethod (true);
+ int g_count = 0;
+ int s_count = 0;
if (get_method != null && set_method != null) {
- int g_count = get_method.GetParameters ().Length;
- int s_count = set_method.GetParameters ().Length;
+ g_count = get_method.GetParameters ().Length;
+ s_count = set_method.GetParameters ().Length;
if (g_count + 1 != s_count)
return false;
+ } else if (get_method != null) {
+ g_count = get_method.GetParameters ().Length;
+ } else if (set_method != null) {
+ s_count = set_method.GetParameters ().Length;
}
+
+ //
+ // DefaultMemberName and indexer name has to match to identify valid C# indexer
+ //
+ if ((s_count > 1 || g_count > 0) && TypeManager.default_member_type != null) {
+ object[] o = pi.DeclaringType.GetCustomAttributes (TypeManager.default_member_type, false);
+ if (o.Length == 0)
+ return false;
+
+ DefaultMemberAttribute dma = (DefaultMemberAttribute) o [0];
+ if (dma.MemberName != pi.Name)
+ return false;
+ if (get_method != null && "get_" + dma.MemberName != get_method.Name)
+ return false;
+ if (set_method != null && "set_" + dma.MemberName != set_method.Name)
+ return false;
+ }
+
return true;
}